SQLite Android Bindings
Check-in [530b9f3aef]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge fix for supplementary unicode characters with this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | api-level-15
Files: files | file ages | folders
SHA1:530b9f3aef3d0ad612b945803cd3fa5fd7c17fef
User & Date: dan 2015-03-03 15:42:12
Context
2015-04-04
08:23
Apply the 64-bit pointer fix to this branch. check-in: 2aa724ae34 user: dan tags: api-level-15
2015-03-03
15:42
Merge fix for supplementary unicode characters with this branch. check-in: 530b9f3aef user: dan tags: api-level-15
15:38
Fix a problem in the handling of supplementary unicode characters. check-in: 20f8872529 user: dan tags: trunk
2014-11-05
19:19
Merge latest fixes with this branch. check-in: 60e268f5be user: dan tags: api-level-15
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to jni/sqlite/android_database_SQLiteConnection.cpp.

670
671
672
673
674
675
676
677

678
679
680
681
682
683
684
685
      case SQLITE_FLOAT: {
        jdouble val = sqlite3_column_double(pStmt, i);
        bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTDOUBLE].id, val, iRow, i);
        break;
      }

      case SQLITE_TEXT: {
        const char *zVal = (const char*)sqlite3_column_text(pStmt, i);

        jstring val = pEnv->NewStringUTF(zVal);
        bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTSTRING].id, val, iRow, i);
        pEnv->DeleteLocalRef(val);
        break;
      }

      default: {
        assert( sqlite3_column_type(pStmt, i)==SQLITE_BLOB );







|
>
|







670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
      case SQLITE_FLOAT: {
        jdouble val = sqlite3_column_double(pStmt, i);
        bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTDOUBLE].id, val, iRow, i);
        break;
      }

      case SQLITE_TEXT: {
        jchar *pStr = (jchar*)sqlite3_column_text16(pStmt, i);
        int nStr = sqlite3_column_bytes16(pStmt, i) / sizeof(jchar);
        jstring val = pEnv->NewString(pStr, nStr);
        bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTSTRING].id, val, iRow, i);
        pEnv->DeleteLocalRef(val);
        break;
      }

      default: {
        assert( sqlite3_column_type(pStmt, i)==SQLITE_BLOB );

Changes to src/org/sqlite/app/customsqlite/CustomSqlite.java.

213
214
215
216
217
218
219













220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
...
253
254
255
256
257
258
259
260




261

262
263
264
265
266
267

268

269
270



271
272
273
274
275
276
277
...
368
369
370
371
372
373
374

375
376
377
378
379
380
381
    }else{
      test_warning("csr_test_1", "c==NULL");
    }
    test_result("csr_test_2.2", "" + nRow, "15000");

    db.close();
  }














  public void csr_test_1() throws Exception {
    SQLiteDatabase.deleteDatabase(DB_PATH);
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
    String res = "";

    db.execSQL("CREATE TABLE t1(x)");
    db.execSQL("INSERT INTO t1 VALUES ('one'), ('two'), ('three')");
    
    Cursor c = db.rawQuery("SELECT x FROM t1", null);
    if( c!=null ){
      boolean bRes;
      for(bRes=c.moveToFirst(); bRes; bRes=c.moveToNext()){
        String x = c.getString(0);
        res = res + "." + x;
      }
    }else{
      test_warning("csr_test_1", "c==NULL");
    }
    test_result("csr_test_1.1", res, ".one.two.three");

    db.close();
    test_result("csr_test_1.2", db_is_encrypted(), "unencrypted");
  }


  public void stmt_jrnl_test_1() throws Exception {
    SQLiteDatabase.deleteDatabase(DB_PATH);
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
    String res = "";

    db.execSQL("CREATE TABLE t1(x, y UNIQUE)");
................................................................................
      db.execSQL("INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3)");
      db.execSQL("UPDATE t1 SET y=y+3");
    db.execSQL("COMMIT");
    db.close();
    test_result("stmt_jrnl_test_1.1", "did not crash", "did not crash");
  }

  public String string_from_t1_x(SQLiteDatabase db){




    String res = "";


    Cursor c = db.rawQuery("SELECT x FROM t1", null);
    boolean bRes;
    for(bRes=c.moveToFirst(); bRes; bRes=c.moveToNext()){
      String x = c.getString(0);
      res = res + "." + x;

    }


    return res;



  }

  /*
  ** If this is a SEE build, check that encrypted databases work.
  */
  public void see_test_1() throws Exception {
    if( !SQLiteDatabase.hasCodec() ) return;
................................................................................

    myTV.setText("");
    myNErr = 0;
    myNTest = 0;

    try {
      report_version();

      csr_test_1();
      csr_test_2();
      thread_test_1();
      thread_test_2(); 
      see_test_1();
      see_test_2();
      stmt_jrnl_test_1();







>
>
>
>
>
>
>
>
>
>
>
>
>









|
<
<
<
<
<
<
<
<
<





<







 







<
>
>
>
>

>

<
<
<
<
|
>
|
>
|
<
>
>
>







 







>







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242









243
244
245
246
247

248
249
250
251
252
253
254
...
256
257
258
259
260
261
262

263
264
265
266
267
268
269




270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
    }else{
      test_warning("csr_test_1", "c==NULL");
    }
    test_result("csr_test_2.2", "" + nRow, "15000");

    db.close();
  }

  public String string_from_t1_x(SQLiteDatabase db){
    String res = "";

    Cursor c = db.rawQuery("SELECT x FROM t1", null);
    boolean bRes;
    for(bRes=c.moveToFirst(); bRes; bRes=c.moveToNext()){
      String x = c.getString(0);
      res = res + "." + x;
    }

    return res;
  }

  public void csr_test_1() throws Exception {
    SQLiteDatabase.deleteDatabase(DB_PATH);
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
    String res = "";

    db.execSQL("CREATE TABLE t1(x)");
    db.execSQL("INSERT INTO t1 VALUES ('one'), ('two'), ('three')");
    
    res = string_from_t1_x(db);









    test_result("csr_test_1.1", res, ".one.two.three");

    db.close();
    test_result("csr_test_1.2", db_is_encrypted(), "unencrypted");
  }


  public void stmt_jrnl_test_1() throws Exception {
    SQLiteDatabase.deleteDatabase(DB_PATH);
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
    String res = "";

    db.execSQL("CREATE TABLE t1(x, y UNIQUE)");
................................................................................
      db.execSQL("INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3)");
      db.execSQL("UPDATE t1 SET y=y+3");
    db.execSQL("COMMIT");
    db.close();
    test_result("stmt_jrnl_test_1.1", "did not crash", "did not crash");
  }



  public void supp_char_test_1() throws Exception {
    SQLiteDatabase.deleteDatabase(DB_PATH);
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
    String res = "";
    String smiley = new String( Character.toChars(0x10000) );





    db.execSQL("CREATE TABLE t1(x)");
    db.execSQL("INSERT INTO t1 VALUES ('a" + smiley + "b')");

    res = string_from_t1_x(db);
    

    test_result("supp_char_test1." + smiley, res, ".a" + smiley + "b");

    db.close();
  }

  /*
  ** If this is a SEE build, check that encrypted databases work.
  */
  public void see_test_1() throws Exception {
    if( !SQLiteDatabase.hasCodec() ) return;
................................................................................

    myTV.setText("");
    myNErr = 0;
    myNTest = 0;

    try {
      report_version();
      supp_char_test_1();
      csr_test_1();
      csr_test_2();
      thread_test_1();
      thread_test_2(); 
      see_test_1();
      see_test_2();
      stmt_jrnl_test_1();

Changes to www/index.wiki.

65
66
67
68
69
70
71














72
73
74
75
76
77
78
  the jni/ directory (including the custom SQLite version) to shared libraries
  that will be deployed to the device along with the application. Assuming
  it is successful, unless you modify the sources or makefiles within the
  jni/ directory structure, you should not need to run "ndk-build" again.

<h3>Application Programming</h3>















<p>
  The classes that make up the built-in Android SQLite interface reside in
  the "android.database.sqlite" namespace. This interface provides all of
  the same classes, except within the "org.sqlite.database.sqlite" namespace.
  This means that to modify an application to use the custom version of 
  SQLite, all that is usually required is to replace all occurrences
  "android.database.sqlite" within the source code with







>
>
>
>
>
>
>
>
>
>
>
>
>
>







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  the jni/ directory (including the custom SQLite version) to shared libraries
  that will be deployed to the device along with the application. Assuming
  it is successful, unless you modify the sources or makefiles within the
  jni/ directory structure, you should not need to run "ndk-build" again.

<h3>Application Programming</h3>

<p>
  Before using any SQLite related methods or objects, the shared library
  compiled using the ndk must be loaded into the application using the
  following code:

<verbatim>
  System.loadLibrary("sqliteX");
</verbatim>

<p>
  One way to ensure that the shared library is loaded early enough is
  to add it to a "static" block within the declaration of the application's
  main Activity class.

<p>
  The classes that make up the built-in Android SQLite interface reside in
  the "android.database.sqlite" namespace. This interface provides all of
  the same classes, except within the "org.sqlite.database.sqlite" namespace.
  This means that to modify an application to use the custom version of 
  SQLite, all that is usually required is to replace all occurrences
  "android.database.sqlite" within the source code with