7
7
8
8
import java .util .Locale ;
9
9
10
+ import net .sqlcipher .DatabaseErrorHandler ;
10
11
import net .sqlcipher .database .SQLiteDatabase ;
11
12
import net .sqlcipher .database .SQLiteException ;
12
13
import net .zetetic .ZeteticApplication ;
@@ -29,12 +30,12 @@ public TestResult run() {
29
30
@ Override
30
31
public boolean execute (SQLiteDatabase null_database_ignored ) {
31
32
32
- File testDatabasePath = ZeteticApplication .getInstance ().getDatabasePath ("closed-db-test.db" );
33
+ File closedDatabasePath = ZeteticApplication .getInstance ().getDatabasePath ("closed-db-test.db" );
33
34
34
35
boolean status = false ;
35
36
36
37
try {
37
- SQLiteDatabase database = SQLiteDatabase .openOrCreateDatabase (testDatabasePath , "" , null );
38
+ SQLiteDatabase database = SQLiteDatabase .openOrCreateDatabase (closedDatabasePath , "" , null );
38
39
39
40
database .close ();
40
41
@@ -45,7 +46,58 @@ public boolean execute(SQLiteDatabase null_database_ignored) {
45
46
return false ;
46
47
}
47
48
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 ();
49
101
}
50
102
51
103
return status ;
@@ -257,9 +309,8 @@ boolean execute_closed_database_tests(SQLiteDatabase database) {
257
309
Log .v (ZeteticApplication .TAG , "SQLiteDatabase.markTableSyncable(String, String) did throw exception on closed database OK" , e );
258
310
}
259
311
260
- // TBD SQLiteDatabase.markTableSyncable(String, String, String) does NOT throw exception on closed database:
261
312
try {
262
- // NOTE: does not (yet) throw an exception on a closed database:
313
+ // [should] throw an exception on a closed database:
263
314
database .markTableSyncable ("aa" , "bb" , "cc" );
264
315
265
316
// ...
@@ -297,6 +348,10 @@ boolean execute_closed_database_tests(SQLiteDatabase database) {
297
348
database .setLockingEnabled (false );
298
349
database .setLockingEnabled (true );
299
350
351
+ database .inTransaction ();
352
+ database .isDbLockedByCurrentThread ();
353
+ database .isDbLockedByOtherThreads ();
354
+
300
355
database .close ();
301
356
302
357
database .isReadOnly ();
0 commit comments