| package com.android.launcher3.util; |
| |
| import android.content.ContentValues; |
| import android.content.Context; |
| import android.database.Cursor; |
| import android.database.sqlite.SQLiteDatabase; |
| import android.database.sqlite.SQLiteException; |
| import android.database.sqlite.SQLiteFullException; |
| import android.database.sqlite.SQLiteOpenHelper; |
| import android.util.Log; |
| |
| /** |
| * An extension of {@link SQLiteOpenHelper} with utility methods for a single table cache DB. |
| * Any exception during write operations are ignored, and any version change causes a DB reset. |
| */ |
| public abstract class SQLiteCacheHelper { |
| private static final String TAG = "SQLiteCacheHelper"; |
| |
| private final String mTableName; |
| private final MySQLiteOpenHelper mOpenHelper; |
| |
| private boolean mIgnoreWrites; |
| |
| public SQLiteCacheHelper(Context context, String name, int version, String tableName) { |
| mTableName = tableName; |
| mOpenHelper = new MySQLiteOpenHelper(context, name, version); |
| |
| mIgnoreWrites = false; |
| } |
| |
| /** |
| * @see SQLiteDatabase#update(String, ContentValues, String, String[]) |
| */ |
| public void update(ContentValues values, String whereClause, String[] whereArgs) { |
| if (mIgnoreWrites) { |
| return; |
| } |
| try { |
| mOpenHelper.getWritableDatabase().update(mTableName, values, whereClause, whereArgs); |
| } catch (SQLiteFullException e) { |
| onDiskFull(e); |
| } catch (SQLiteException e) { |
| Log.d(TAG, "Ignoring sqlite exception", e); |
| } |
| } |
| |
| /** |
| * @see SQLiteDatabase#delete(String, String, String[]) |
| */ |
| public void delete(String whereClause, String[] whereArgs) { |
| if (mIgnoreWrites) { |
| return; |
| } |
| try { |
| mOpenHelper.getWritableDatabase().delete(mTableName, whereClause, whereArgs); |
| } catch (SQLiteFullException e) { |
| onDiskFull(e); |
| } catch (SQLiteException e) { |
| Log.d(TAG, "Ignoring sqlite exception", e); |
| } |
| } |
| |
| /** |
| * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int) |
| */ |
| public void insertOrReplace(ContentValues values) { |
| if (mIgnoreWrites) { |
| return; |
| } |
| try { |
| mOpenHelper.getWritableDatabase().insertWithOnConflict( |
| mTableName, null, values, SQLiteDatabase.CONFLICT_REPLACE); |
| } catch (SQLiteFullException e) { |
| onDiskFull(e); |
| } catch (SQLiteException e) { |
| Log.d(TAG, "Ignoring sqlite exception", e); |
| } |
| } |
| |
| private void onDiskFull(SQLiteFullException e) { |
| Log.e(TAG, "Disk full, all write operations will be ignored", e); |
| mIgnoreWrites = true; |
| } |
| |
| /** |
| * @see SQLiteDatabase#query(String, String[], String, String[], String, String, String) |
| */ |
| public Cursor query(String[] columns, String selection, String[] selectionArgs) { |
| return mOpenHelper.getReadableDatabase().query( |
| mTableName, columns, selection, selectionArgs, null, null, null); |
| } |
| |
| protected abstract void onCreateTable(SQLiteDatabase db); |
| |
| /** |
| * A private inner class to prevent direct DB access. |
| */ |
| private class MySQLiteOpenHelper extends SQLiteOpenHelper { |
| |
| public MySQLiteOpenHelper(Context context, String name, int version) { |
| super(new NoLocaleSqliteContext(context), name, null, version); |
| } |
| |
| @Override |
| public void onCreate(SQLiteDatabase db) { |
| onCreateTable(db); |
| } |
| |
| @Override |
| public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { |
| if (oldVersion != newVersion) { |
| clearDB(db); |
| } |
| } |
| |
| @Override |
| public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { |
| if (oldVersion != newVersion) { |
| clearDB(db); |
| } |
| } |
| |
| private void clearDB(SQLiteDatabase db) { |
| db.execSQL("DROP TABLE IF EXISTS " + mTableName); |
| onCreate(db); |
| } |
| } |
| } |