package org.microg.networklocation.database; import java.util.Arrays; import android.content.Context; import android.database.Cursor; import android.database.sqlite.*; import android.util.Log; import org.microg.networklocation.data.LocationSpec; import org.microg.networklocation.data.PropSpec; import org.microg.networklocation.MainService; public class LocationDatabase { private static final String TAG = "nlp.LocationDatabase"; private static final String FILE_NAME = "v2loc.db"; private static final int DB_VERSION = 1; private static final String COL_IDENT = "ident"; private static final String COL_LATITUDE = "latitude"; private static final String COL_LONGITUDE = "longitude"; private static final String COL_ALTITUDE = "altitude"; private static final String COL_ACCURACY = "accuracy"; private static final String COL_BOOLS = "bools"; private static final String TABLE_LOCATION = "locations"; private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_LOCATION + "(" + COL_IDENT + " BLOB PRIMARY KEY, " + COL_LATITUDE + " REAL, " + COL_LONGITUDE + " REAL, " + COL_ALTITUDE + " REAL, " + COL_ACCURACY + " REAL, " + COL_BOOLS + " INTEGER)"; private static final String INSERT_INTO = "INSERT INTO " + TABLE_LOCATION + "(" + COL_IDENT + "," + COL_LATITUDE + "," + COL_LONGITUDE + "," + COL_ALTITUDE + "," + COL_ACCURACY + "," + COL_BOOLS + ") VALUES(?,?,?,?,?,?)"; private static final String[] DEFAULT_QUERY_SELECT = {COL_LATITUDE, COL_LONGITUDE, COL_ALTITUDE, COL_ACCURACY, COL_BOOLS}; private OpenHelper openHelper; private boolean enabled = false; public LocationDatabase(Context context) { openHelper = new OpenHelper(context); } public <T extends PropSpec> LocationSpec<T> get(T propSpec) { LocationSpec<T> locationSpec = get(propSpec.getIdentBlob()); if (locationSpec != null) { locationSpec.setSource(propSpec); } return locationSpec; } public void enable() { this.enabled = true; } private <T extends PropSpec> LocationSpec<T> get(final byte[] identBlob) { LocationSpec<T> locationSpec = null; if (enabled) { final SQLiteDatabase db = openHelper.getReadableDatabase(); Cursor cursor = db.queryWithFactory(new SQLiteDatabase.CursorFactory() { @Override public Cursor newCursor(SQLiteDatabase database, SQLiteCursorDriver sqLiteCursorDriver, String s, SQLiteQuery sqLiteQuery) { sqLiteQuery.bindBlob(1, identBlob); return new SQLiteCursor(db, sqLiteCursorDriver, s, sqLiteQuery); } }, false, TABLE_LOCATION, DEFAULT_QUERY_SELECT, COL_IDENT + "=?", null, null, null, null, null); try { if (cursor.moveToNext()) { double latitude = cursor.getDouble(0); double longitude = cursor.getDouble(1); double altitude = cursor.getDouble(2); double accuracy = cursor.getDouble(3); int bools = cursor.getInt(4); locationSpec = new LocationSpec<T>(latitude, longitude, accuracy, altitude, bools); } if (cursor.moveToNext()) { Log.e(TAG, "Result not unique"); } } finally { cursor.close(); } } if (MainService.DEBUG) Log.d(TAG, "retrieved identBlob=" + Arrays.toString(identBlob) + ", locationSpec=" + locationSpec); return locationSpec; } private <T extends PropSpec> void insert(byte[] identBlob, LocationSpec<T> locationSpec) { SQLiteStatement statement = openHelper.getWritableDatabase().compileStatement(INSERT_INTO); statement.bindBlob(1, identBlob); statement.bindDouble(2, locationSpec.getLatitude()); statement.bindDouble(3, locationSpec.getLongitude()); statement.bindDouble(4, locationSpec.getAltitude()); statement.bindDouble(5, locationSpec.getAccuracy()); statement.bindLong(6, locationSpec.getBools()); try { statement.executeInsert(); if (MainService.DEBUG) Log.d(TAG, "inserted identBlob=" + Arrays.toString(identBlob) + ", locationSpec=" + locationSpec); } catch (Exception e) { Log.w(TAG, e); } finally { statement.close(); } } public <T extends PropSpec> void put(LocationSpec<T> locationSpec) { // TODO update if exists! insert(locationSpec.getSource().getIdentBlob(), locationSpec); } private class OpenHelper extends SQLiteOpenHelper { private OpenHelper(Context context) { super(context, FILE_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase database) { database.execSQL(CREATE_TABLE); } @Override public void onUpgrade(SQLiteDatabase database, int i, int i2) { throw new RuntimeException("Cannot upgrade database from " + i + " to " + i2); } } }