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