package com.mediamonks.googleflip.data.database; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.support.annotation.NonNull; import com.mediamonks.googleflip.BuildConfig; import com.mediamonks.googleflip.data.vo.LevelResultVO; import com.mediamonks.googleflip.data.vo.LevelVO; import nl.qbusict.cupboard.CupboardBuilder; import nl.qbusict.cupboard.CupboardFactory; import temple.core.database.EmptyCursor; import static nl.qbusict.cupboard.CupboardFactory.cupboard; /** * Data provider, storing levels and results */ public class DataProvider extends ContentProvider { private static final String TAG = DataProvider.class.getSimpleName(); public static final String PROVIDER_AUTHORITY = BuildConfig.APPLICATION_ID + ".provider"; public static final String BASE_LEVEL = "level"; public static final String BASE_LEVEL_RESULT = "levelresult"; private static final int LEVEL_INDEX = 0; private static final int LEVEL_RESULT_INDEX = 1; private static final Object LOCK = new Object(); private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { CupboardBuilder instance = new CupboardBuilder(); instance.useAnnotations(); CupboardFactory.setCupboard(instance.build()); cupboard().register(LevelVO.class); cupboard().register(LevelResultVO.class); sMatcher.addURI(PROVIDER_AUTHORITY, BASE_LEVEL, LEVEL_INDEX); sMatcher.addURI(PROVIDER_AUTHORITY, BASE_LEVEL_RESULT, LEVEL_RESULT_INDEX); } private DatabaseHelper _databaseHelper; @Override public boolean onCreate() { return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { synchronized (LOCK) { try { final SQLiteDatabase db = getDatabaseHelper().getReadableDatabase(); Class<?> tableClass = getTableClass(uri); Cursor cursor = cupboard().withDatabase(db) .query(tableClass) .withProjection(projection) .withSelection(selection, selectionArgs) .orderBy(sortOrder) .getCursor(); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } catch (Exception error) { EmptyCursor cursor = new EmptyCursor(); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } } } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { synchronized (LOCK) { final SQLiteDatabase db = getDatabaseHelper().getWritableDatabase(); final Class<?> tableClass = getTableClass(uri); long id = db.insertWithOnConflict(cupboard().withEntity(tableClass).getTable(), null, values, SQLiteDatabase.CONFLICT_REPLACE); notifyChange(uri); return ContentUris.withAppendedId(uri, id); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { synchronized (LOCK) { final SQLiteDatabase db = getDatabaseHelper().getWritableDatabase(); final Class<?> tableClass = getTableClass(uri); final int rowsDeleted = cupboard().withDatabase(db).delete(tableClass, selection, selectionArgs); notifyChange(uri); return rowsDeleted; } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { synchronized (LOCK) { final SQLiteDatabase db = getDatabaseHelper().getWritableDatabase(); final Class<?> tableClass = getTableClass(uri); final int rowsUpdated = cupboard().withDatabase(db).update(tableClass, values, selection, selectionArgs); notifyChange(uri); return rowsUpdated; } } @Override public int bulkInsert(Uri uri, @NonNull ContentValues[] values) { synchronized (LOCK) { SQLiteDatabase db = getDatabaseHelper().getWritableDatabase(); final String table = getTableString(uri); db.beginTransaction(); int rowsInserted = 0; try { for (ContentValues value : values) { db.insertWithOnConflict(table, null, value, SQLiteDatabase.CONFLICT_REPLACE); rowsInserted++; } db.setTransactionSuccessful(); } catch (Exception e) { e.printStackTrace(); rowsInserted = -1; } finally { db.endTransaction(); if (rowsInserted > 0) { notifyChange(uri); } } return rowsInserted; } } private DatabaseHelper getDatabaseHelper() { if (_databaseHelper == null) { _databaseHelper = new DatabaseHelper(getContext()); } return _databaseHelper; } private Class<?> getTableClass(Uri uri) { switch (sMatcher.match(uri)) { case LEVEL_INDEX: return LevelVO.class; case LEVEL_RESULT_INDEX: return LevelResultVO.class; default: throw new IllegalArgumentException("Unknown URI: " + uri); } } private void notifyChange(final Uri uri) { getContext().getContentResolver().notifyChange(uri, null); } private String getTableString(Uri uri) { return cupboard().getTable(getTableClass(uri)); } }