SQLite Android Bindings
Check-in [20f8872529]
Not logged in

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

Overview
Comment:Fix a problem in the handling of supplementary unicode characters.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:20f8872529890bbfc96bb82c2cad98f507c9e389
User & Date: dan 2015-03-03 15:38:09
Context
2015-04-04
08:19
Update this code to support 64-bit pointers. See also: https://android.googlesource.com/platform/frameworks/base.git/+/738702d28ab7e0e89e3c6e18fd46cc1361917eb9 check-in: 3e4327dc6e user: dan tags: trunk
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-12-04
16:49
Add the requirement to call 'System.loadLibrary("sqliteX");' to the docs. check-in: 89b2225ad2 user: dan tags: trunk
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();