2525
2626#include < sqlite3.h>
2727#include < sqlite3_android.h>
28- # include < string.h >
28+
2929#include < utils/Log.h>
3030#include < utils/threads.h>
3131#include < utils/List.h>
3232#include < utils/Errors.h>
33+
3334#include < ctype.h>
3435
3536#include < stdio.h>
3637#include < sys/types.h>
37- #include < string.h>
3838#include < sys/ioctl.h>
3939
4040#include < unicode/utypes.h>
@@ -277,7 +277,13 @@ void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
277277 err = sqlite3_open_v2 (path8, &handle, sqliteFlags, NULL );
278278 if (err != SQLITE_OK) {
279279 LOGE (" sqlite3_open_v2(\" %s\" , &handle, %d, NULL) failed\n " , path8, sqliteFlags);
280- throw_sqlite3_exception (env, handle);
280+ throw_sqlite3_exception_errcode (env, err, " Could not open database" );
281+ goto done;
282+ }
283+
284+ // Check that the database is really read/write when that is what we asked for.
285+ if ((sqliteFlags & SQLITE_OPEN_READWRITE) && sqlite3_db_readonly (handle, NULL )) {
286+ throw_sqlite3_exception (env, handle, " Could not open the database in read/write mode." );
281287 goto done;
282288 }
283289
@@ -290,7 +296,7 @@ void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
290296 err = sqlite3_busy_timeout (handle, 1000 /* ms */ );
291297 if (err != SQLITE_OK) {
292298 LOGE (" sqlite3_busy_timeout(handle, 1000) failed for \" %s\"\n " , path8);
293- throw_sqlite3_exception (env, handle);
299+ throw_sqlite3_exception (env, handle, " Could not set busy timeout " );
294300 goto done;
295301 }
296302
@@ -299,7 +305,7 @@ void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
299305 err = sqlite3_prepare_v2 (handle, integritySql, -1 , &statement, NULL );
300306 if (err != SQLITE_OK) {
301307 LOGE (" sqlite_prepare_v2(handle, \" %s\" ) failed for \" %s\"\n " , integritySql, path8);
302- throw_sqlite3_exception (env, handle);
308+ throw_sqlite3_exception (env, handle, " sqlite_prepare_v2(handle, \" pragma integrity_check(1); \" ) failed " );
303309 goto done;
304310 }
305311
@@ -321,7 +327,7 @@ void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
321327
322328 err = register_android_functions (handle, UTF16_STORAGE);
323329 if (err) {
324- throw_sqlite3_exception (env, handle);
330+ throw_sqlite3_exception (env, handle, " Could not register Android SQL functions. " );
325331 goto done;
326332 }
327333
@@ -396,8 +402,8 @@ static void dbclose(JNIEnv* env, jobject object)
396402 env->SetIntField (object, offset_db_handle, 0 );
397403 } else {
398404 // This can happen if sub-objects aren't closed first. Make sure the caller knows.
399- throw_sqlite3_exception (env, handle);
400405 LOGE (" sqlite3_close(%p) failed: %d\n " , handle, result);
406+ throw_sqlite3_exception (env, handle, " sqlite3_close() failed" );
401407 }
402408 }
403409}
@@ -498,7 +504,7 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString,
498504 err = sqlite3_exec (handle, createSql, NULL , NULL , NULL );
499505 if (err != SQLITE_OK) {
500506 LOGE (" CREATE TABLE " ANDROID_TABLE " failed\n " );
501- throw_sqlite3_exception (env, handle);
507+ throw_sqlite3_exception (env, handle, " create locale table failed " );
502508 goto done;
503509 }
504510 }
@@ -508,7 +514,7 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString,
508514 err = sqlite3_get_table (handle, selectSql, &meta, &rowCount, &colCount, NULL );
509515 if (err != SQLITE_OK) {
510516 LOGE (" SELECT locale FROM " ANDROID_TABLE " failed\n " );
511- throw_sqlite3_exception (env, handle);
517+ throw_sqlite3_exception (env, handle, " select locale failed " );
512518 goto done;
513519 }
514520
@@ -525,66 +531,66 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString,
525531 // read-only database, so we're going to have to put up with whatever we got
526532 // For registering new index. Not for modifing the read-only database.
527533 err = register_localized_collators (handle, locale8, UTF16_STORAGE);
528- if (err != SQLITE_OK) throw_sqlite3_exception (env, handle);
534+ if (err != SQLITE_OK) throw_sqlite3_exception (env, handle, " register localized collators failed " );
529535 goto done;
530536 }
531537
532538 // need to update android_metadata and indexes atomically, so use a transaction...
533539 err = sqlite3_exec (handle, " BEGIN TRANSACTION" , NULL , NULL , NULL );
534540 if (err != SQLITE_OK) {
535541 LOGE (" BEGIN TRANSACTION failed setting locale\n " );
536- throw_sqlite3_exception (env, handle);
542+ throw_sqlite3_exception (env, handle, " BEGIN TRANSACTION failed setting locale " );
537543 goto done;
538544 }
539545
540546 err = register_localized_collators (handle, locale8, UTF16_STORAGE);
541547 if (err != SQLITE_OK) {
542548 LOGE (" register_localized_collators() failed setting locale\n " );
543- throw_sqlite3_exception (env, handle);
549+ throw_sqlite3_exception (env, handle, " register_localized_collators() failed setting locale " );
544550 goto rollback;
545551 }
546552
547553 err = sqlite3_exec (handle, " DELETE FROM " ANDROID_TABLE, NULL , NULL , NULL );
548554 if (err != SQLITE_OK) {
549555 LOGE (" DELETE failed setting locale\n " );
550- throw_sqlite3_exception (env, handle);
556+ throw_sqlite3_exception (env, handle, " DELETE failed setting locale " );
551557 goto rollback;
552558 }
553559
554560 static const char *sql = " INSERT INTO " ANDROID_TABLE " (locale) VALUES(?);" ;
555561 err = sqlite3_prepare_v2 (handle, sql, -1 , &stmt, NULL );
556562 if (err != SQLITE_OK) {
557563 LOGE (" sqlite3_prepare_v2(\" %s\" ) failed\n " , sql);
558- throw_sqlite3_exception (env, handle);
564+ throw_sqlite3_exception (env, handle, " sqlite3_prepare_v2() failed setting locale " );
559565 goto rollback;
560566 }
561567
562568 err = sqlite3_bind_text (stmt, 1 , locale8, -1 , SQLITE_TRANSIENT);
563569 if (err != SQLITE_OK) {
564570 LOGE (" sqlite3_bind_text() failed setting locale\n " );
565- throw_sqlite3_exception (env, handle);
571+ throw_sqlite3_exception (env, handle, " sqlite3_bind_text() failed setting locale " );
566572 goto rollback;
567573 }
568574
569575 err = sqlite3_step (stmt);
570576 if (err != SQLITE_OK && err != SQLITE_DONE) {
571577 LOGE (" sqlite3_step(\" %s\" ) failed setting locale\n " , sql);
572- throw_sqlite3_exception (env, handle);
578+ throw_sqlite3_exception (env, handle, " sqlite3_step() failed setting locale " );
573579 goto rollback;
574580 }
575581
576582 err = sqlite3_exec (handle, " REINDEX LOCALIZED" , NULL , NULL , NULL );
577583 if (err != SQLITE_OK) {
578584 LOGE (" REINDEX LOCALIZED failed\n " );
579- throw_sqlite3_exception (env, handle);
585+ throw_sqlite3_exception (env, handle, " REINDEX LOCALIZED failed " );
580586 goto rollback;
581587 }
582588
583589 // all done, yay!
584590 err = sqlite3_exec (handle, " COMMIT TRANSACTION" , NULL , NULL , NULL );
585591 if (err != SQLITE_OK) {
586592 LOGE (" COMMIT TRANSACTION failed setting locale\n " );
587- throw_sqlite3_exception (env, handle);
593+ throw_sqlite3_exception (env, handle, " COMMIT TRANSACTION failed setting locale " );
588594 goto done;
589595 }
590596
0 commit comments