SQLite Android Bindings
Check-in [71351f6267]
Not logged in

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

Overview
Comment:Fix a resource leak in SQLiteConnection.nativeExecuteForCursorWindow().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | api-level-15
Files: files | file ages | folders
SHA1:71351f6267818789a7699aa3ec23899acf07ffa4
User & Date: dan 2014-06-18 10:14:46
Context
2014-11-05
19:19
Merge latest fixes with this branch. check-in: 60e268f5be user: dan tags: api-level-15
2014-06-18
10:14
Fix a resource leak in SQLiteConnection.nativeExecuteForCursorWindow(). check-in: 71351f6267 user: dan tags: api-level-15
10:11
Fix a resource leak in SQLiteConnection.nativeExecuteForCursorWindow(). check-in: 3558b4d73c user: dan tags: trunk
2014-06-11
19:10
Merge trunk with this branch. check-in: 7fbe992d8f user: dan tags: api-level-15
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to jni/sqlite/android_database_SQLiteConnection.cpp.

   673    673           break;
   674    674         }
   675    675   
   676    676         case SQLITE_TEXT: {
   677    677           const char *zVal = (const char*)sqlite3_column_text(pStmt, i);
   678    678           jstring val = pEnv->NewStringUTF(zVal);
   679    679           bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTSTRING].id, val, iRow, i);
          680  +        pEnv->DeleteLocalRef(val);
   680    681           break;
   681    682         }
   682    683   
   683    684         default: {
   684    685           assert( sqlite3_column_type(pStmt, i)==SQLITE_BLOB );
   685         -
   686    686           const jbyte *p = (const jbyte*)sqlite3_column_blob(pStmt, i);
   687    687           int n = sqlite3_column_bytes(pStmt, i);
   688         -
   689    688           jbyteArray val = pEnv->NewByteArray(n);
   690    689           pEnv->SetByteArrayRegion(val, 0, n, p);
   691    690           bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTBLOB].id, val, iRow, i);
          691  +        pEnv->DeleteLocalRef(val);
   692    692           break;
   693    693         }
   694    694       }
   695    695   
   696    696       if( bOk==0 ){
   697    697         pEnv->CallVoidMethod(win, aMethod[CW_FREELASTROW].id);
   698    698       }

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

   166    166         test_result("thread_test_2", res, "concurrent");
   167    167       }
   168    168     }
   169    169   
   170    170     /*
   171    171     ** Use a Cursor to loop through the results of a SELECT query.
   172    172     */
          173  +  public void csr_test_2() throws Exception {
          174  +    SQLiteDatabase.deleteDatabase(DB_PATH);
          175  +    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
          176  +    String res = "";
          177  +    String expect = "";
          178  +    int i;
          179  +    int nRow = 0;
          180  +
          181  +    db.execSQL("CREATE TABLE t1(x)");
          182  +    db.execSQL("BEGIN");
          183  +    for(i=0; i<1000; i++){
          184  +      db.execSQL("INSERT INTO t1 VALUES ('one'), ('two'), ('three')");
          185  +      expect += ".one.two.three";
          186  +    }
          187  +    db.execSQL("COMMIT");
          188  +    Cursor c = db.rawQuery("SELECT x FROM t1", null);
          189  +    if( c!=null ){
          190  +      boolean bRes;
          191  +      for(bRes=c.moveToFirst(); bRes; bRes=c.moveToNext()){
          192  +        String x = c.getString(0);
          193  +        res = res + "." + x;
          194  +      }
          195  +    }else{
          196  +      test_warning("csr_test_1", "c==NULL");
          197  +    }
          198  +    test_result("csr_test_2.1", res, expect);
          199  +
          200  +    db.execSQL("BEGIN");
          201  +    for(i=0; i<1000; i++){
          202  +      db.execSQL("INSERT INTO t1 VALUES (X'123456'), (X'789ABC'), (X'DEF012')");
          203  +      db.execSQL("INSERT INTO t1 VALUES (45), (46), (47)");
          204  +      db.execSQL("INSERT INTO t1 VALUES (8.1), (8.2), (8.3)");
          205  +      db.execSQL("INSERT INTO t1 VALUES (NULL), (NULL), (NULL)");
          206  +    }
          207  +    db.execSQL("COMMIT");
          208  +
          209  +    c = db.rawQuery("SELECT x FROM t1", null);
          210  +    if( c!=null ){
          211  +      boolean bRes;
          212  +      for(bRes=c.moveToFirst(); bRes; bRes=c.moveToNext()) nRow++;
          213  +    }else{
          214  +      test_warning("csr_test_1", "c==NULL");
          215  +    }
          216  +    test_result("csr_test_2.2", "" + nRow, "15000");
          217  +
          218  +    db.close();
          219  +  }
          220  +
   173    221     public void csr_test_1() throws Exception {
   174    222       SQLiteDatabase.deleteDatabase(DB_PATH);
   175    223       SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
   176    224       String res = "";
   177    225   
   178    226       db.execSQL("CREATE TABLE t1(x)");
   179    227       db.execSQL("INSERT INTO t1 VALUES ('one'), ('two'), ('three')");
................................................................................
   307    355       myTV.setText("");
   308    356       myNErr = 0;
   309    357       myNTest = 0;
   310    358   
   311    359       try {
   312    360         report_version();
   313    361         csr_test_1();
          362  +      csr_test_2();
   314    363         thread_test_1();
   315    364         thread_test_2(); 
   316    365         see_test_1();
   317    366         see_test_2();
   318    367   
   319    368         myTV.append("\n" + myNErr + " errors from " + myNTest + " tests\n");
   320    369       } catch(Exception e) {