package com.evancharlton.mileage.provider;
import com.evancharlton.mileage.provider.tables.CacheTable;
import com.evancharlton.mileage.provider.tables.ContentTable;
import com.evancharlton.mileage.provider.tables.FieldsTable;
import com.evancharlton.mileage.provider.tables.FillupsFieldsTable;
import com.evancharlton.mileage.provider.tables.FillupsTable;
import com.evancharlton.mileage.provider.tables.ServiceIntervalTemplatesTable;
import com.evancharlton.mileage.provider.tables.ServiceIntervalsTable;
import com.evancharlton.mileage.provider.tables.VehicleTypesTable;
import com.evancharlton.mileage.provider.tables.VehiclesTable;
import com.evancharlton.mileage.services.AutomaticBackupService;
import com.evancharlton.mileage.util.Debugger;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
import java.util.ArrayList;
/**
* Exposed URIs:
* <ul>
* <li>fillups/</li>
* <li>fillups/#</li>
* <li>fillups/fields</li>
* <li>fillups/fields/#</li>
* <li>fillups/field/#</li>
* <li>fields/</li>
* <li>fields/#</li>
* <li>vehicles/</li>
* <li>vehicles/#</li>
* <li>vehicles/types/</li>
* <li>vehicles/types/#</li>
* <li>intervals/</li>
* <li>intervals/#</li>
* <li>intervals/templates</li>
* <li>intervals/templates/#</li>
* <li>cache</li>
* <li>cache/*</li>
* </ul>
*/
public class FillUpsProvider extends ContentProvider {
public static final String AUTHORITY = "com.evancharlton.mileage";
public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
public static final int DATABASE_VERSION = 6;
public static final ArrayList<ContentTable> TABLES = new ArrayList<ContentTable>();
private static final SparseIntArray LOOKUP = new SparseIntArray();
public static final String DATABASE_NAME = "mileage.db";
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
private static final String TAG = "FillupsProvider";
private DatabaseHelper mDatabaseHelper;
static {
TABLES.add(new FillupsTable());
TABLES.add(new FillupsFieldsTable());
TABLES.add(new FieldsTable());
TABLES.add(new VehiclesTable());
TABLES.add(new VehicleTypesTable());
TABLES.add(new ServiceIntervalsTable());
TABLES.add(new ServiceIntervalTemplatesTable());
TABLES.add(new CacheTable());
for (ContentTable table : TABLES) {
table.registerUris();
}
}
public static void registerUri(ContentTable table, String path, int code) {
// TODO(3.1) - Could this code be auto-generated?
URI_MATCHER.addURI(AUTHORITY, path, code);
int position = TABLES.indexOf(table);
if (position < 0) {
TABLES.add(table);
position = TABLES.size() - 1;
}
LOOKUP.put(code, position);
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "Creating database");
for (ContentTable table : TABLES) {
try {
String sql = table.create();
if (sql != null) {
db.execSQL(sql);
}
} catch (IllegalArgumentException e) {
Log.e("DatabaseHelper", "Could not create table", e);
} catch (IllegalAccessException e) {
Log.e("DatabaseHelper", "Could not create table", e);
}
}
initTables(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, final int oldVersion, final int newVersion) {
DatabaseUpgrader.upgradeDatabase(db);
}
}
public static void initTables(SQLiteDatabase db) {
for (ContentTable table : TABLES) {
String[] init = table.init(false);
if (init != null) {
for (String sql : init) {
db.execSQL(sql);
}
}
}
}
@Override
public boolean onCreate() {
mDatabaseHelper = new DatabaseHelper(getContext());
URI_MATCHER.addURI(AUTHORITY, "reset/", 0);
return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
Debugger.checkQueryOnUiThread(getContext());
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
int count = -1;
final int type = URI_MATCHER.match(uri);
int position = LOOKUP.get(type, -1);
if (position >= 0) {
count = TABLES.get(position).delete(db, uri, selection, selectionArgs);
}
if (count < 0) {
throw new IllegalArgumentException("Unknown URI: " + uri);
}
notifyListeners(uri);
return count;
}
@Override
public String getType(Uri uri) {
final int type = URI_MATCHER.match(uri);
if (type == 0) {
// TODO(3.1) - Figure this out.
// mDatabaseHelper.close();
// mDatabaseHelper.getReadableDatabase();
// Log.d(TAG, "Database closed!");
return null;
}
String result = null;
for (ContentTable table : TABLES) {
result = table.getType(type);
if (result != null) {
return result;
}
}
throw new IllegalArgumentException("Unknown URI: " + uri);
}
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
Debugger.checkQueryOnUiThread(getContext());
final int match = URI_MATCHER.match(uri);
long newId = -1L;
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
int position = LOOKUP.get(match, -1);
if (position >= 0) {
newId = TABLES.get(position).insert(match, db, initialValues);
if (newId >= 0) {
uri = ContentUris.withAppendedId(uri, newId);
notifyListeners(uri);
}
return uri;
}
throw new IllegalArgumentException("Unknown URI: " + uri);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Debugger.checkQueryOnUiThread(getContext());
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
final int match = URI_MATCHER.match(uri);
boolean changed = false;
ContentTable queryTable = null;
int position = LOOKUP.get(match, -1);
if (position >= 0) {
ContentTable table = TABLES.get(position);
changed = table.query(match, uri, qb, getContext(), projection);
if (changed) {
queryTable = table;
}
}
// TODO(3.1) - Clean this up
if (!changed) {
throw new IllegalArgumentException("Unknown URI: " + uri);
}
if (projection == null) {
projection = queryTable.getProjection();
}
String orderBy =
TextUtils.isEmpty(sortOrder) ? queryTable.getDefaultSortOrder() : sortOrder;
SQLiteDatabase db;
try {
db = mDatabaseHelper.getReadableDatabase();
} catch (SQLiteException e) {
db = mDatabaseHelper.getWritableDatabase();
}
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
Debugger.checkQueryOnUiThread(getContext());
final int match = URI_MATCHER.match(uri);
int position = LOOKUP.get(match, -1);
if (position >= 0) {
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
int count =
TABLES.get(position).update(match, db, uri, values, selection, selectionArgs);
if (count >= 0) {
notifyListeners(uri);
}
return count;
}
throw new IllegalArgumentException("Unknown URI: " + uri);
}
private void notifyListeners(final Uri uri) {
Context context = getContext();
context.getContentResolver().notifyChange(uri, null);
AutomaticBackupService.run(context);
}
}