Description
I encountered this error one time when testing the changes in #175:
E/AndroidRuntime( 6187): FATAL EXCEPTION: Thread-41325
E/AndroidRuntime( 6187): Process: net.zetetic, PID: 6187
E/AndroidRuntime( 6187): net.sqlcipher.database.SQLiteMisuseException: library routine called out of sequence: , while compiling: select count(*) from t1;
E/AndroidRuntime( 6187): at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
E/AndroidRuntime( 6187): at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
E/AndroidRuntime( 6187): at net.sqlcipher.database.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
E/AndroidRuntime( 6187): at net.sqlcipher.database.SQLiteProgram.<init>(SQLiteProgram.java:103)
E/AndroidRuntime( 6187): at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:49)
E/AndroidRuntime( 6187): at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
E/AndroidRuntime( 6187): at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1447)
E/AndroidRuntime( 6187): at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1416)
E/AndroidRuntime( 6187): at net.zetetic.tests.MultiThreadReadWriteTest$Reader.getCurrentTableCount(MultiThreadReadWriteTest.java:118)
E/AndroidRuntime( 6187): at net.zetetic.tests.MultiThreadReadWriteTest$Reader.run(MultiThreadReadWriteTest.java:94)
E/AndroidRuntime( 6187): at java.lang.Thread.run(Thread.java:818)
W/ActivityManager( 946): Force finishing activity net.zetetic/.TestSuiteActivity
Second test round with the changes in #175 passed OK. I am very suspicious that this is an intermittent problem lurking in the library, and/or perhaps in the test.
This is caused by attempting to call sqlite3_prepare16_v2()
[in net_sqlcipher_database_SQLiteCompiledSql.cpp
] with a sqite3 handle that is closed or invalid. For reference: http://stackoverflow.com/questions/8372871/library-routine-called-out-of-sequence-sqlite3-prepare-v2create-table
The solution is to check that the database connection is open and valid before attempting to prepare (compile) the statement in native code. By "database connection", I am not sure yet whether this means that we should simply verify that the Java SQLiteDatabase is in the open state or that we should also check the internal db handle. I hope it will be enough to simply check the state of the SQLiteDatabase object.