• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.launcher3.util;
2 
3 import android.content.ContentValues;
4 import android.content.Context;
5 import android.database.Cursor;
6 import android.database.sqlite.SQLiteDatabase;
7 import android.database.sqlite.SQLiteException;
8 import android.database.sqlite.SQLiteFullException;
9 import android.database.sqlite.SQLiteOpenHelper;
10 import android.util.Log;
11 
12 import com.android.launcher3.Utilities;
13 import com.android.launcher3.config.ProviderConfig;
14 
15 /**
16  * An extension of {@link SQLiteOpenHelper} with utility methods for a single table cache DB.
17  * Any exception during write operations are ignored, and any version change causes a DB reset.
18  */
19 public abstract class SQLiteCacheHelper {
20     private static final String TAG = "SQLiteCacheHelper";
21 
22     private static final boolean NO_ICON_CACHE = ProviderConfig.IS_DOGFOOD_BUILD &&
23             Utilities.isPropertyEnabled(LogConfig.MEMORY_ONLY_ICON_CACHE);
24 
25     private final String mTableName;
26     private final MySQLiteOpenHelper mOpenHelper;
27 
28     private boolean mIgnoreWrites;
29 
SQLiteCacheHelper(Context context, String name, int version, String tableName)30     public SQLiteCacheHelper(Context context, String name, int version, String tableName) {
31         if (NO_ICON_CACHE) {
32             name = null;
33         }
34         mTableName = tableName;
35         mOpenHelper = new MySQLiteOpenHelper(context, name, version);
36 
37         mIgnoreWrites = false;
38     }
39 
40     /**
41      * @see SQLiteDatabase#delete(String, String, String[])
42      */
delete(String whereClause, String[] whereArgs)43     public void delete(String whereClause, String[] whereArgs) {
44         if (mIgnoreWrites) {
45             return;
46         }
47         try {
48             mOpenHelper.getWritableDatabase().delete(mTableName, whereClause, whereArgs);
49         } catch (SQLiteFullException e) {
50             onDiskFull(e);
51         } catch (SQLiteException e) {
52             Log.d(TAG, "Ignoring sqlite exception", e);
53         }
54     }
55 
56     /**
57      * @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
58      */
insertOrReplace(ContentValues values)59     public void insertOrReplace(ContentValues values) {
60         if (mIgnoreWrites) {
61             return;
62         }
63         try {
64             mOpenHelper.getWritableDatabase().insertWithOnConflict(
65                     mTableName, null, values, SQLiteDatabase.CONFLICT_REPLACE);
66         } catch (SQLiteFullException e) {
67             onDiskFull(e);
68         } catch (SQLiteException e) {
69             Log.d(TAG, "Ignoring sqlite exception", e);
70         }
71     }
72 
onDiskFull(SQLiteFullException e)73     private void onDiskFull(SQLiteFullException e) {
74         Log.e(TAG, "Disk full, all write operations will be ignored", e);
75         mIgnoreWrites = true;
76     }
77 
78     /**
79      * @see SQLiteDatabase#query(String, String[], String, String[], String, String, String)
80      */
query(String[] columns, String selection, String[] selectionArgs)81     public Cursor query(String[] columns, String selection, String[] selectionArgs) {
82         return mOpenHelper.getReadableDatabase().query(
83                 mTableName, columns, selection, selectionArgs, null, null, null);
84     }
85 
clear()86     public void clear() {
87         mOpenHelper.clearDB(mOpenHelper.getWritableDatabase());
88     }
89 
onCreateTable(SQLiteDatabase db)90     protected abstract void onCreateTable(SQLiteDatabase db);
91 
92     /**
93      * A private inner class to prevent direct DB access.
94      */
95     private class MySQLiteOpenHelper extends SQLiteOpenHelper {
96 
MySQLiteOpenHelper(Context context, String name, int version)97         public MySQLiteOpenHelper(Context context, String name, int version) {
98             super(new NoLocaleSqliteContext(context), name, null, version);
99         }
100 
101         @Override
onCreate(SQLiteDatabase db)102         public void onCreate(SQLiteDatabase db) {
103             onCreateTable(db);
104         }
105 
106         @Override
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)107         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
108             if (oldVersion != newVersion) {
109                 clearDB(db);
110             }
111         }
112 
113         @Override
onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)114         public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
115             if (oldVersion != newVersion) {
116                 clearDB(db);
117             }
118         }
119 
clearDB(SQLiteDatabase db)120         private void clearDB(SQLiteDatabase db) {
121             db.execSQL("DROP TABLE IF EXISTS " + mTableName);
122             onCreate(db);
123         }
124     }
125 }
126