OSDN Git Service

Better handling of DB corruption in SQLiteDatabase.open()
authorMakoto Onuki <omakoto@google.com>
Fri, 1 Feb 2019 20:54:55 +0000 (12:54 -0800)
committerMakoto Onuki <omakoto@google.com>
Fri, 1 Feb 2019 20:54:55 +0000 (12:54 -0800)
Bug: 123750718
Test: manual test with test code
Change-Id: I80a9d35f7ad6589b3de0a506780cfe956295dcda

core/java/android/database/sqlite/SQLiteConnection.java
core/java/android/database/sqlite/SQLiteDatabase.java
core/java/android/database/sqlite/SQLiteDatabaseCorruptException.java

index 20505ca..3c8e236 100644 (file)
@@ -448,6 +448,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
             } finally {
                 execute(success ? "COMMIT" : "ROLLBACK", null, null);
             }
+        } catch (SQLiteException ex) {
+            throw ex;
         } catch (RuntimeException ex) {
             throw new SQLiteException("Failed to change locale for db '" + mConfiguration.label
                     + "' to '" + newLocale + "'.", ex);
index a1b0803..ae456af 100644 (file)
@@ -890,9 +890,14 @@ public final class SQLiteDatabase extends SQLiteClosable {
         try {
             try {
                 openInner();
-            } catch (SQLiteDatabaseCorruptException ex) {
-                onCorruption();
-                openInner();
+            } catch (RuntimeException ex) {
+                if (SQLiteDatabaseCorruptException.isCorruptException(ex)) {
+                    Log.e(TAG, "Database corruption detected in open()", ex);
+                    onCorruption();
+                    openInner();
+                } else {
+                    throw ex;
+                }
             }
         } catch (SQLiteException ex) {
             Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
index 73b6c0c..488ef46 100644 (file)
@@ -25,4 +25,20 @@ public class SQLiteDatabaseCorruptException extends SQLiteException {
     public SQLiteDatabaseCorruptException(String error) {
         super(error);
     }
+
+    /**
+     * @return true if a given {@link Throwable} or any of its inner causes is of
+     * {@link SQLiteDatabaseCorruptException}.
+     *
+     * @hide
+     */
+    public static boolean isCorruptException(Throwable th) {
+        while (th != null) {
+            if (th instanceof SQLiteDatabaseCorruptException) {
+                return true;
+            }
+            th = th.getCause();
+        }
+        return false;
+    }
 }