mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
JNI: implement AutoCloseable for the sqlite3 and sqlite3_stmt classes, and adjust a few tests to use it. Override Object.finalize() for sqlite3 class but not sqlite3_stmt (where it triggers a JVM crash for as-yet-unknown reasons).
FossilOrigin-Name: b633d8bbdbd43464ee03058c273e5188117b9538ed5d5148a1a3851e4adf6410
This commit is contained in:
@ -404,50 +404,52 @@ public class Tester1 implements Runnable {
|
||||
}
|
||||
|
||||
private void testBindFetchInt64(){
|
||||
sqlite3 db = createNewDb();
|
||||
execSql(db, "CREATE TABLE t(a)");
|
||||
sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);");
|
||||
long total1 = 0;
|
||||
for(long i = 0xffffffff; i < 0xffffffff + 3; ++i ){
|
||||
total1 += i;
|
||||
sqlite3_bind_int64(stmt, 1, i);
|
||||
sqlite3_step(stmt);
|
||||
sqlite3_reset(stmt);
|
||||
try (sqlite3 db = createNewDb()){
|
||||
execSql(db, "CREATE TABLE t(a)");
|
||||
sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);");
|
||||
long total1 = 0;
|
||||
for(long i = 0xffffffff; i < 0xffffffff + 3; ++i ){
|
||||
total1 += i;
|
||||
sqlite3_bind_int64(stmt, 1, i);
|
||||
sqlite3_step(stmt);
|
||||
sqlite3_reset(stmt);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;");
|
||||
long total2 = 0;
|
||||
while( SQLITE_ROW == sqlite3_step(stmt) ){
|
||||
total2 += sqlite3_column_int64(stmt, 0);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
affirm(total1 == total2);
|
||||
//sqlite3_close_v2(db);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;");
|
||||
long total2 = 0;
|
||||
while( SQLITE_ROW == sqlite3_step(stmt) ){
|
||||
total2 += sqlite3_column_int64(stmt, 0);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
affirm(total1 == total2);
|
||||
sqlite3_close_v2(db);
|
||||
}
|
||||
|
||||
private void testBindFetchDouble(){
|
||||
sqlite3 db = createNewDb();
|
||||
execSql(db, "CREATE TABLE t(a)");
|
||||
sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);");
|
||||
double total1 = 0;
|
||||
for(double i = 1.5; i < 5.0; i = i + 1.0 ){
|
||||
total1 += i;
|
||||
sqlite3_bind_double(stmt, 1, i);
|
||||
sqlite3_step(stmt);
|
||||
sqlite3_reset(stmt);
|
||||
try (sqlite3 db = createNewDb()){
|
||||
execSql(db, "CREATE TABLE t(a)");
|
||||
sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);");
|
||||
double total1 = 0;
|
||||
for(double i = 1.5; i < 5.0; i = i + 1.0 ){
|
||||
total1 += i;
|
||||
sqlite3_bind_double(stmt, 1, i);
|
||||
sqlite3_step(stmt);
|
||||
sqlite3_reset(stmt);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;");
|
||||
double total2 = 0;
|
||||
int counter = 0;
|
||||
while( SQLITE_ROW == sqlite3_step(stmt) ){
|
||||
++counter;
|
||||
total2 += sqlite3_column_double(stmt, 0);
|
||||
}
|
||||
affirm(4 == counter);
|
||||
sqlite3_finalize(stmt);
|
||||
affirm(total2<=total1+0.01 && total2>=total1-0.01);
|
||||
//sqlite3_close_v2(db);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;");
|
||||
double total2 = 0;
|
||||
int counter = 0;
|
||||
while( SQLITE_ROW == sqlite3_step(stmt) ){
|
||||
++counter;
|
||||
total2 += sqlite3_column_double(stmt, 0);
|
||||
}
|
||||
affirm(4 == counter);
|
||||
sqlite3_finalize(stmt);
|
||||
affirm(total2<=total1+0.01 && total2>=total1-0.01);
|
||||
sqlite3_close_v2(db);
|
||||
}
|
||||
|
||||
private void testBindFetchText(){
|
||||
@ -491,20 +493,25 @@ public class Tester1 implements Runnable {
|
||||
affirm(3 == n);
|
||||
affirm("w😃rldhell🤩!🤩".equals(sbuf.toString()));
|
||||
|
||||
stmt = prepare(db, "SELECT ?, ?");
|
||||
rc = sqlite3_bind_text(stmt, 1, "");
|
||||
affirm( 0==rc );
|
||||
rc = sqlite3_bind_text(stmt, 2, (String)null);
|
||||
affirm( 0==rc );
|
||||
rc = sqlite3_step(stmt);
|
||||
affirm( SQLITE_ROW==rc );
|
||||
byte[] colBa = sqlite3_column_text(stmt, 0);
|
||||
affirm( 0==colBa.length );
|
||||
colBa = sqlite3_column_text(stmt, 1);
|
||||
affirm( null==colBa );
|
||||
sqlite3_finalize(stmt);
|
||||
try( sqlite3_stmt stmt2 = prepare(db, "SELECT ?, ?") ){
|
||||
rc = sqlite3_bind_text(stmt2, 1, "");
|
||||
affirm( 0==rc );
|
||||
rc = sqlite3_bind_text(stmt2, 2, (String)null);
|
||||
affirm( 0==rc );
|
||||
rc = sqlite3_step(stmt2);
|
||||
affirm( SQLITE_ROW==rc );
|
||||
byte[] colBa = sqlite3_column_text(stmt2, 0);
|
||||
affirm( 0==colBa.length );
|
||||
colBa = sqlite3_column_text(stmt2, 1);
|
||||
affirm( null==colBa );
|
||||
//sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
sqlite3_close_v2(db);
|
||||
if(true){
|
||||
sqlite3_close_v2(db);
|
||||
}else{
|
||||
// Let the Object.finalize() override deal with it.
|
||||
}
|
||||
}
|
||||
|
||||
private void testBindFetchBlob(){
|
||||
|
@ -19,19 +19,30 @@ package org.sqlite.jni;
|
||||
simply provide a type-safe way to communicate it between Java
|
||||
and C via JNI.
|
||||
*/
|
||||
public final class sqlite3 extends NativePointerHolder<sqlite3> {
|
||||
public final class sqlite3 extends NativePointerHolder<sqlite3>
|
||||
implements AutoCloseable {
|
||||
|
||||
// Only invoked from JNI
|
||||
private sqlite3(){}
|
||||
|
||||
public String toString(){
|
||||
long ptr = getNativePointer();
|
||||
final long ptr = getNativePointer();
|
||||
if( 0==ptr ){
|
||||
return sqlite3.class.getSimpleName()+"@null";
|
||||
}
|
||||
String fn = SQLite3Jni.sqlite3_db_filename(this, "main");
|
||||
final String fn = SQLite3Jni.sqlite3_db_filename(this, "main");
|
||||
return sqlite3.class.getSimpleName()
|
||||
+"@"+String.format("0x%08x",ptr)
|
||||
+"["+((null == fn) ? "<unnamed>" : fn)+"]"
|
||||
;
|
||||
}
|
||||
|
||||
@Override protected void finalize(){
|
||||
//System.out.println(this+".finalize()");
|
||||
SQLite3Jni.sqlite3_close_v2(this);
|
||||
}
|
||||
|
||||
@Override public void close(){
|
||||
SQLite3Jni.sqlite3_close_v2(this);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,17 @@ package org.sqlite.jni;
|
||||
simply provide a type-safe way to communicate it between Java and C
|
||||
via JNI.
|
||||
*/
|
||||
public final class sqlite3_stmt extends NativePointerHolder<sqlite3_stmt> {
|
||||
public final class sqlite3_stmt extends NativePointerHolder<sqlite3_stmt>
|
||||
implements AutoCloseable {
|
||||
// Only invoked from JNI.
|
||||
private sqlite3_stmt(){}
|
||||
|
||||
//For as-yet-unknown reasons, this triggers a JVM crash.
|
||||
//@Override protected void finalize(){
|
||||
// SQLite3Jni.sqlite3_finalize(this);
|
||||
//}
|
||||
|
||||
@Override public void close(){
|
||||
SQLite3Jni.sqlite3_finalize(this);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user