diff options
author | Vasu Nori <vnori@google.com> | 2010-08-25 16:29:02 -0700 |
---|---|---|
committer | Vasu Nori <vnori@google.com> | 2010-08-30 10:28:47 -0700 |
commit | bfe1dc27944c80dcb81f0eb313987999ecd7b6fa (patch) | |
tree | 94e93c704bbae9419a56d75b6b8cba98ea6e4e09 /core/java | |
parent | 178e1d0a59c12f2876a6630ebb400aa1d098833a (diff) | |
download | frameworks_base-bfe1dc27944c80dcb81f0eb313987999ecd7b6fa.zip frameworks_base-bfe1dc27944c80dcb81f0eb313987999ecd7b6fa.tar.gz frameworks_base-bfe1dc27944c80dcb81f0eb313987999ecd7b6fa.tar.bz2 |
fix isIntegrityCheck() & add a sample impl class and test for DatabaseErrorHandler
fixed a bug in SQLiteDatabase.isDatabaseIntegrityOk()
and added a new class to demonstrate use of
android.database.DatabaseErrorHandler
and a bunch of nits
Change-Id: Ia81870853fa3bd84074637f6d823a9fd22b66c7e
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/database/sqlite/SQLiteDatabase.java | 38 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteMisuseException.java | 12 |
2 files changed, 34 insertions, 16 deletions
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index b83d5ad..0137ea6 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -39,7 +39,6 @@ import dalvik.system.BlockGuard; import java.io.File; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -273,7 +272,7 @@ public class SQLiteDatabase extends SQLiteClosable { * invoked. * * this cache has an upper limit of mMaxSqlCacheSize (settable by calling the method - * (@link setMaxSqlCacheSize(int)}). + * (@link #setMaxSqlCacheSize(int)}). */ // default statement-cache size per database connection ( = instance of this class) private int mMaxSqlCacheSize = 25; @@ -903,8 +902,7 @@ public class SQLiteDatabase extends SQLiteClosable { public interface CursorFactory { /** * See - * {@link SQLiteCursor#SQLiteCursor(SQLiteDatabase, SQLiteCursorDriver, - * String, SQLiteQuery)}. + * {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}. */ public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable, @@ -2080,7 +2078,7 @@ public class SQLiteDatabase extends SQLiteClosable { */ if (++mCacheFullWarnings == MAX_WARNINGS_ON_CACHESIZE_CONDITION) { Log.w(TAG, "Reached MAX size for compiled-sql statement cache for database " + - getPath() + ". Consider increasing cachesize."); + getPath() + ". Use setMaxSqlCacheSize() to increase cachesize. "); } } /* add the given SQLiteCompiledSql compiledStatement to cache. @@ -2142,7 +2140,7 @@ public class SQLiteDatabase extends SQLiteClosable { * * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE}) * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE} or - * > the value set with previous setMaxSqlCacheSize() call. + * the value set with previous setMaxSqlCacheSize() call. */ public synchronized void setMaxSqlCacheSize(int cacheSize) { if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) { @@ -2342,10 +2340,12 @@ public class SQLiteDatabase extends SQLiteClosable { /* package */ SQLiteDatabase getDbConnection(String sql) { verifyDbIsOpen(); - // this method should always be called with main database connection handle - // NEVER with pooled database connection handle + // this method should always be called with main database connection handle. + // the only time when it is called with pooled database connection handle is + // corruption occurs while trying to open a pooled database connection handle. + // in that case, simply return 'this' handle if (isPooledConnection()) { - throw new IllegalStateException("incorrect database connection handle"); + return this; } // use the current connection handle if @@ -2504,12 +2504,18 @@ public class SQLiteDatabase extends SQLiteClosable { */ public boolean isDatabaseIntegrityOk() { verifyDbIsOpen(); - ArrayList<Pair<String, String>> attachedDbs = getAttachedDbs(); - if (attachedDbs == null) { - throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " + - "be retrieved. probably because the database is closed"); + ArrayList<Pair<String, String>> attachedDbs = null; + try { + attachedDbs = getAttachedDbs(); + if (attachedDbs == null) { + throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " + + "be retrieved. probably because the database is closed"); + } + } catch (SQLiteException e) { + // can't get attachedDb list. do integrity check on the main database + attachedDbs = new ArrayList<Pair<String, String>>(); + attachedDbs.add(new Pair<String, String>("main", this.mPath)); } - boolean isDatabaseCorrupt = false; for (int i = 0; i < attachedDbs.size(); i++) { Pair<String, String> p = attachedDbs.get(i); SQLiteStatement prog = null; @@ -2518,14 +2524,14 @@ public class SQLiteDatabase extends SQLiteClosable { String rslt = prog.simpleQueryForString(); if (!rslt.equalsIgnoreCase("ok")) { // integrity_checker failed on main or attached databases - isDatabaseCorrupt = true; Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt); + return false; } } finally { if (prog != null) prog.close(); } } - return isDatabaseCorrupt; + return true; } /** diff --git a/core/java/android/database/sqlite/SQLiteMisuseException.java b/core/java/android/database/sqlite/SQLiteMisuseException.java index 685f3ea..546ec08 100644 --- a/core/java/android/database/sqlite/SQLiteMisuseException.java +++ b/core/java/android/database/sqlite/SQLiteMisuseException.java @@ -16,6 +16,18 @@ package android.database.sqlite; +/** + * This error can occur if the application creates a SQLiteStatement object and allows multiple + * threads in the application use it at the same time. + * Sqlite returns this error if bind and execute methods on this object occur at the same time + * from multiple threads, like so: + * thread # 1: in execute() method of the SQLiteStatement object + * while thread # 2: is in bind..() on the same object. + *</p> + * FIX this by NEVER sharing the same SQLiteStatement object between threads. + * Create a local instance of the SQLiteStatement whenever it is needed, use it and close it ASAP. + * NEVER make it globally available. + */ public class SQLiteMisuseException extends SQLiteException { public SQLiteMisuseException() {} |