25
25
26
26
#include < sqlite3.h>
27
27
#include < sqlite3_android.h>
28
- # include < string.h >
28
+
29
29
#include < utils/Log.h>
30
30
#include < utils/threads.h>
31
31
#include < utils/List.h>
32
32
#include < utils/Errors.h>
33
+
33
34
#include < ctype.h>
34
35
35
36
#include < stdio.h>
36
37
#include < sys/types.h>
37
- #include < string.h>
38
38
#include < sys/ioctl.h>
39
39
40
40
#include < unicode/utypes.h>
@@ -277,7 +277,13 @@ void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
277
277
err = sqlite3_open_v2 (path8, &handle, sqliteFlags, NULL );
278
278
if (err != SQLITE_OK) {
279
279
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." );
281
287
goto done;
282
288
}
283
289
@@ -290,7 +296,7 @@ void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
290
296
err = sqlite3_busy_timeout (handle, 1000 /* ms */ );
291
297
if (err != SQLITE_OK) {
292
298
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 " );
294
300
goto done;
295
301
}
296
302
@@ -299,7 +305,7 @@ void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
299
305
err = sqlite3_prepare_v2 (handle, integritySql, -1 , &statement, NULL );
300
306
if (err != SQLITE_OK) {
301
307
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 " );
303
309
goto done;
304
310
}
305
311
@@ -321,7 +327,7 @@ void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
321
327
322
328
err = register_android_functions (handle, UTF16_STORAGE);
323
329
if (err) {
324
- throw_sqlite3_exception (env, handle);
330
+ throw_sqlite3_exception (env, handle, " Could not register Android SQL functions. " );
325
331
goto done;
326
332
}
327
333
@@ -396,8 +402,8 @@ static void dbclose(JNIEnv* env, jobject object)
396
402
env->SetIntField (object, offset_db_handle, 0 );
397
403
} else {
398
404
// This can happen if sub-objects aren't closed first. Make sure the caller knows.
399
- throw_sqlite3_exception (env, handle);
400
405
LOGE (" sqlite3_close(%p) failed: %d\n " , handle, result);
406
+ throw_sqlite3_exception (env, handle, " sqlite3_close() failed" );
401
407
}
402
408
}
403
409
}
@@ -498,7 +504,7 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString,
498
504
err = sqlite3_exec (handle, createSql, NULL , NULL , NULL );
499
505
if (err != SQLITE_OK) {
500
506
LOGE (" CREATE TABLE " ANDROID_TABLE " failed\n " );
501
- throw_sqlite3_exception (env, handle);
507
+ throw_sqlite3_exception (env, handle, " create locale table failed " );
502
508
goto done;
503
509
}
504
510
}
@@ -508,7 +514,7 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString,
508
514
err = sqlite3_get_table (handle, selectSql, &meta, &rowCount, &colCount, NULL );
509
515
if (err != SQLITE_OK) {
510
516
LOGE (" SELECT locale FROM " ANDROID_TABLE " failed\n " );
511
- throw_sqlite3_exception (env, handle);
517
+ throw_sqlite3_exception (env, handle, " select locale failed " );
512
518
goto done;
513
519
}
514
520
@@ -525,66 +531,66 @@ static void native_setLocale(JNIEnv* env, jobject object, jstring localeString,
525
531
// read-only database, so we're going to have to put up with whatever we got
526
532
// For registering new index. Not for modifing the read-only database.
527
533
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 " );
529
535
goto done;
530
536
}
531
537
532
538
// need to update android_metadata and indexes atomically, so use a transaction...
533
539
err = sqlite3_exec (handle, " BEGIN TRANSACTION" , NULL , NULL , NULL );
534
540
if (err != SQLITE_OK) {
535
541
LOGE (" BEGIN TRANSACTION failed setting locale\n " );
536
- throw_sqlite3_exception (env, handle);
542
+ throw_sqlite3_exception (env, handle, " BEGIN TRANSACTION failed setting locale " );
537
543
goto done;
538
544
}
539
545
540
546
err = register_localized_collators (handle, locale8, UTF16_STORAGE);
541
547
if (err != SQLITE_OK) {
542
548
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 " );
544
550
goto rollback;
545
551
}
546
552
547
553
err = sqlite3_exec (handle, " DELETE FROM " ANDROID_TABLE, NULL , NULL , NULL );
548
554
if (err != SQLITE_OK) {
549
555
LOGE (" DELETE failed setting locale\n " );
550
- throw_sqlite3_exception (env, handle);
556
+ throw_sqlite3_exception (env, handle, " DELETE failed setting locale " );
551
557
goto rollback;
552
558
}
553
559
554
560
static const char *sql = " INSERT INTO " ANDROID_TABLE " (locale) VALUES(?);" ;
555
561
err = sqlite3_prepare_v2 (handle, sql, -1 , &stmt, NULL );
556
562
if (err != SQLITE_OK) {
557
563
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 " );
559
565
goto rollback;
560
566
}
561
567
562
568
err = sqlite3_bind_text (stmt, 1 , locale8, -1 , SQLITE_TRANSIENT);
563
569
if (err != SQLITE_OK) {
564
570
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 " );
566
572
goto rollback;
567
573
}
568
574
569
575
err = sqlite3_step (stmt);
570
576
if (err != SQLITE_OK && err != SQLITE_DONE) {
571
577
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 " );
573
579
goto rollback;
574
580
}
575
581
576
582
err = sqlite3_exec (handle, " REINDEX LOCALIZED" , NULL , NULL , NULL );
577
583
if (err != SQLITE_OK) {
578
584
LOGE (" REINDEX LOCALIZED failed\n " );
579
- throw_sqlite3_exception (env, handle);
585
+ throw_sqlite3_exception (env, handle, " REINDEX LOCALIZED failed " );
580
586
goto rollback;
581
587
}
582
588
583
589
// all done, yay!
584
590
err = sqlite3_exec (handle, " COMMIT TRANSACTION" , NULL , NULL , NULL );
585
591
if (err != SQLITE_OK) {
586
592
LOGE (" COMMIT TRANSACTION failed setting locale\n " );
587
- throw_sqlite3_exception (env, handle);
593
+ throw_sqlite3_exception (env, handle, " COMMIT TRANSACTION failed setting locale " );
588
594
goto done;
589
595
}
590
596
0 commit comments