package net.cmikavac.autowol.data; import java.util.List; import net.cmikavac.autowol.models.DeviceModel; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DbProvider extends DbConfiguration { private SQLiteDatabase mDb; private DbHelper mDbHelper; private DbMapper mDbMapper; /** * Constructor. * @param context Context entity. */ public DbProvider(Context context) { mDbHelper = new DbHelper(context); mDbMapper = new DbMapper(); } /** * Opens the database connection. * @return DbProvider entity. */ public DbProvider open() { mDb = mDbHelper.getWritableDatabase(); return this; } /** * Closes the database connection. */ public void close() { mDbHelper.close(); } /** * Maps content values from DeviceModel entity and inserts a new device record into DB. * @param device DeviceModel entity to insert. * @return Row Id of the newly inserted record. */ public long insertDevice(DeviceModel device) { ContentValues values = setContentValues(device); return mDb.insert(DATABASE_TABLE, null, values); } /** * Gets a device record from DB and maps it to DeviceModel entity. * @param id Device record Id of the record to fetch. * @return DeviceModel entity. */ public DeviceModel getDevice(long id) { String where = KEY_ROWID + "=" + id; Cursor cursor = mDb.query(true, DATABASE_TABLE, ALL_KEYS, where, null, null, null, null, null); if (cursor != null) { cursor.moveToFirst(); } DeviceModel device = mDbMapper.mapDevice(cursor); cursor.close(); return device; } /** * Gets all device records from DB and maps them to a list of DeviceModel entities. * @return A list of DeviceModel entities. */ public List<DeviceModel> getAllDevices() { Cursor cursor = mDb.query(true, DATABASE_TABLE, ALL_KEYS, null, null, null, null, null, null); if (cursor != null) { cursor.moveToFirst(); } List<DeviceModel> devices = mDbMapper.mapDevices(cursor); cursor.close(); return devices; } /** * Gets device records from DB by SSID and maps them to a list of DeviceModel entities. * @param ssid Device SSID for filtering. * @return A list of DeviceModel entities. */ public List<DeviceModel> getDevicesBySSID(String ssid) { String where = KEY_SSID + "='" + ssid + "'"; Cursor cursor = mDb.query(true, DATABASE_TABLE, ALL_KEYS, where, null, null, null, null, null); if (cursor != null) { cursor.moveToFirst(); } List<DeviceModel> devices = mDbMapper.mapDevices(cursor); cursor.close(); return devices; } /** * Updates a device record in DB. * @param device DeviceModel entitiy to update. * @return Device updated? */ public boolean updateDevice(DeviceModel device) { String where = KEY_ROWID + "=" + device.getId(); ContentValues newValues = setContentValues(device); return mDb.update(DATABASE_TABLE, newValues, where, null) != 0; } /** * Updates device records last_disconnected fields filtered by SSID. * @param ssid Device SSID for filtering. * @param currentTimeInMillis Current time in milliseconds (value to be updated). * @return Number of rows updated. */ public int updateDevicesLastDisconnected(String ssid, Long currentTimeInMillis) { String where = KEY_SSID + "='" + ssid + "'"; ContentValues newValues = new ContentValues(); newValues.put(KEY_LAST_DISCONNECTED, currentTimeInMillis); return mDb.update(DATABASE_TABLE, newValues, where, null); } /** * Removes device record from DB. * @param rowId Id of the record to remove. * @return Record removed? */ public boolean deleteDevice(long rowId) { String where = KEY_ROWID + "=" + rowId; return mDb.delete(DATABASE_TABLE, where, null) != 0; } /** * Sets content values for DeviceModel entity. * @param device DeviceModel entity to map to ContentValues. * @return ConentValues entity. */ private ContentValues setContentValues(DeviceModel device) { ContentValues values = new ContentValues(); values.put(KEY_NAME, device.getName()); values.put(KEY_MAC, device.getMac()); values.put(KEY_HOST, device.getHost()); values.put(KEY_BROADCAST, device.getBroadcast()); values.put(KEY_PORT, device.getPort()); values.put(KEY_SSID, device.getSSID()); values.put(KEY_QUIET_FROM, device.getQuietHoursFrom()); values.put(KEY_QUIET_TO, device.getQuietHoursTo()); values.put(KEY_IDLE_TIME, device.getIdleTime()); return values; } ///////////////////////////////////////////////////////////////////// // DB Helper class ///////////////////////////////////////////////////////////////////// /** * Handles database creation and upgrading. * Used to handle low-level database access. */ private static class DbHelper extends SQLiteOpenHelper { DbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } /** * Array of patches to be applied on DB upgrade. */ private static final Patch[] PATCHES = new Patch[] { new Patch() { public void apply(SQLiteDatabase db) { Log.d("DB UPDATE", "Applying DB v1.1 patch"); db.execSQL(DATABASE_PATCH_SQL_V1_1); }}, new Patch() { public void apply(SQLiteDatabase db) { Log.d("DB UPDATE", "Beginning transaction"); db.beginTransaction(); Log.d("DB UPDATE", "Applying DB v2.1 patch"); db.execSQL(DATABASE_PATCH_SQL_V2_1); Log.d("DB UPDATE", "Applying DB v2.2 patch"); db.execSQL(DATABASE_PATCH_SQL_V2_2); Log.d("DB UPDATE", "Applying DB v2.3 patch"); db.execSQL(DATABASE_PATCH_SQL_V2_3); Log.d("DB UPDATE", "Applying DB v2.4 patch"); db.execSQL(DATABASE_PATCH_SQL_V2_4); Log.d("DB UPDATE", "Transaction successful"); db.setTransactionSuccessful(); Log.d("DB UPDATE", "Ending transaction"); db.endTransaction(); }} }; /** * Creates an empty SQL table for the application. * @param db SQLiteDatabase entity. */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE_SQL); } /** * On DB version changed, drops existing table and creates a new one. * @param db SQLiteDatabase entity. * @param oldVersion Old DB version number. * @param newVersion New DB version number. */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.d(TAG, "Upgrading application's database from version " + oldVersion + " to " + newVersion); for (int i = oldVersion; i < newVersion; i++) { PATCHES[i].apply(db); } } /** * @see http://www.greenmoonsoftware.com/2012/02/sqlite-schema-migration-in-android/ */ private static class Patch { public void apply(SQLiteDatabase db) {} //public void revert(SQLiteDatabase db) {} // not needed ATM } } }