blob: d1cfe4264a04effe38ffca348d2c3002cba12047 [file] [log] [blame]
Sunny Goyal6f709362015-12-17 17:09:36 -08001package 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 /**
Sunny Goyal6f709362015-12-17 17:09:36 -080032 * @see SQLiteDatabase#delete(String, String, String[])
33 */
34 public void delete(String whereClause, String[] whereArgs) {
35 if (mIgnoreWrites) {
36 return;
37 }
38 try {
39 mOpenHelper.getWritableDatabase().delete(mTableName, 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#insertWithOnConflict(String, String, ContentValues, int)
49 */
50 public void insertOrReplace(ContentValues values) {
51 if (mIgnoreWrites) {
52 return;
53 }
54 try {
55 mOpenHelper.getWritableDatabase().insertWithOnConflict(
56 mTableName, null, values, SQLiteDatabase.CONFLICT_REPLACE);
57 } catch (SQLiteFullException e) {
58 onDiskFull(e);
59 } catch (SQLiteException e) {
60 Log.d(TAG, "Ignoring sqlite exception", e);
61 }
62 }
63
64 private void onDiskFull(SQLiteFullException e) {
65 Log.e(TAG, "Disk full, all write operations will be ignored", e);
66 mIgnoreWrites = true;
67 }
68
69 /**
70 * @see SQLiteDatabase#query(String, String[], String, String[], String, String, String)
71 */
72 public Cursor query(String[] columns, String selection, String[] selectionArgs) {
73 return mOpenHelper.getReadableDatabase().query(
74 mTableName, columns, selection, selectionArgs, null, null, null);
75 }
76
77 protected abstract void onCreateTable(SQLiteDatabase db);
78
79 /**
80 * A private inner class to prevent direct DB access.
81 */
82 private class MySQLiteOpenHelper extends SQLiteOpenHelper {
83
84 public MySQLiteOpenHelper(Context context, String name, int version) {
Sunny Goyalbf67f3b2016-03-15 15:30:11 -070085 super(new NoLocaleSqliteContext(context), name, null, version);
Sunny Goyal6f709362015-12-17 17:09:36 -080086 }
87
88 @Override
89 public void onCreate(SQLiteDatabase db) {
90 onCreateTable(db);
91 }
92
93 @Override
94 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
95 if (oldVersion != newVersion) {
96 clearDB(db);
97 }
98 }
99
100 @Override
101 public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
102 if (oldVersion != newVersion) {
103 clearDB(db);
104 }
105 }
106
107 private void clearDB(SQLiteDatabase db) {
108 db.execSQL("DROP TABLE IF EXISTS " + mTableName);
109 onCreate(db);
110 }
111 }
112}