77
88import java .util .Locale ;
99
10+ import net .sqlcipher .DatabaseErrorHandler ;
1011import net .sqlcipher .database .SQLiteDatabase ;
1112import net .sqlcipher .database .SQLiteException ;
1213import net .zetetic .ZeteticApplication ;
@@ -29,12 +30,12 @@ public TestResult run() {
2930 @ Override
3031 public boolean execute (SQLiteDatabase null_database_ignored ) {
3132
32- File testDatabasePath = ZeteticApplication .getInstance ().getDatabasePath ("closed-db-test.db" );
33+ File closedDatabasePath = ZeteticApplication .getInstance ().getDatabasePath ("closed-db-test.db" );
3334
3435 boolean status = false ;
3536
3637 try {
37- SQLiteDatabase database = SQLiteDatabase .openOrCreateDatabase (testDatabasePath , "" , null );
38+ SQLiteDatabase database = SQLiteDatabase .openOrCreateDatabase (closedDatabasePath , "" , null );
3839
3940 database .close ();
4041
@@ -45,7 +46,58 @@ public boolean execute(SQLiteDatabase null_database_ignored) {
4546 return false ;
4647 }
4748 finally {
48- testDatabasePath .delete ();
49+ closedDatabasePath .delete ();
50+ }
51+
52+ if (!status ) return false ;
53+
54+ status = false ;
55+
56+ final File corruptDatabase = ZeteticApplication .getInstance ().getDatabasePath ("corrupt.db" );
57+
58+ // run closed database tests again in custom DatabaseErrorHandler:
59+ try {
60+ ZeteticApplication .getInstance ().extractAssetToDatabaseDirectory ("corrupt.db" );
61+
62+ // ugly trick from: http://stackoverflow.com/questions/5977735/setting-outer-variable-from-anonymous-inner-class
63+ final boolean [] inner_status_slot = new boolean [1 ];
64+
65+ // on a database object that was NEVER actually opened (due to a corrupt database file):
66+ SQLiteDatabase database = SQLiteDatabase .openDatabase (corruptDatabase .getPath (), "" , null , SQLiteDatabase .CREATE_IF_NECESSARY , null , new DatabaseErrorHandler () {
67+ @ Override
68+ public void onCorruption (SQLiteDatabase db ) {
69+ try {
70+ inner_status_slot [0 ] = execute_closed_database_tests (db );
71+ } catch (Exception ex ) {
72+ // Uncaught exception (not expected):
73+ Log .e (TAG , "UNEXPECTED EXCEPTION" , ex );
74+ }
75+
76+ try {
77+ corruptDatabase .delete ();
78+ } catch (Exception ex ) {
79+ // Uncaught exception (not expected):
80+ Log .e (TAG , "UNEXPECTED EXCEPTION" , ex );
81+ }
82+ }
83+ });
84+
85+ status = inner_status_slot [0 ];
86+
87+ // NOTE: database not expected to be null, but double-check:
88+ if (database == null ) {
89+ Log .e (TAG , "ERROR: got null database object" );
90+ return false ;
91+ }
92+
93+ database .close ();
94+ } catch (Exception ex ) {
95+ // Uncaught exception (not expected):
96+ Log .e (TAG , "UNEXPECTED EXCEPTION" , ex );
97+ return false ;
98+ }
99+ finally {
100+ corruptDatabase .delete ();
49101 }
50102
51103 return status ;
@@ -257,9 +309,8 @@ boolean execute_closed_database_tests(SQLiteDatabase database) {
257309 Log .v (ZeteticApplication .TAG , "SQLiteDatabase.markTableSyncable(String, String) did throw exception on closed database OK" , e );
258310 }
259311
260- // TBD SQLiteDatabase.markTableSyncable(String, String, String) does NOT throw exception on closed database:
261312 try {
262- // NOTE: does not (yet) throw an exception on a closed database:
313+ // [should] throw an exception on a closed database:
263314 database .markTableSyncable ("aa" , "bb" , "cc" );
264315
265316 // ...
@@ -297,6 +348,10 @@ boolean execute_closed_database_tests(SQLiteDatabase database) {
297348 database .setLockingEnabled (false );
298349 database .setLockingEnabled (true );
299350
351+ database .inTransaction ();
352+ database .isDbLockedByCurrentThread ();
353+ database .isDbLockedByOtherThreads ();
354+
300355 database .close ();
301356
302357 database .isReadOnly ();
0 commit comments