1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Add incremental blob I/O support to JNI wrapper1.

FossilOrigin-Name: 7f1c76fe930d69a0274f70fa7b7e68e0db6226b731a065fa57d0936c8400ffb0
This commit is contained in:
stephan
2023-11-05 04:20:04 +00:00
parent 546db3f14a
commit ed99e7493a
5 changed files with 110 additions and 11 deletions

View File

@ -1633,7 +1633,7 @@ public class Tester1 implements Runnable {
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
b = sqlite3_blob_open(db, "main", "t", "a", b = sqlite3_blob_open(db, "main", "t", "a",
sqlite3_last_insert_rowid(db), 1); sqlite3_last_insert_rowid(db), 0);
affirm( null!=b ); affirm( null!=b );
rc = sqlite3_blob_reopen(b, 2); rc = sqlite3_blob_reopen(b, 2);
affirm( 0==rc ); affirm( 0==rc );

View File

@ -17,6 +17,7 @@ import org.sqlite.jni.capi.CApi;
import org.sqlite.jni.capi.sqlite3; import org.sqlite.jni.capi.sqlite3;
import org.sqlite.jni.capi.sqlite3_stmt; import org.sqlite.jni.capi.sqlite3_stmt;
import org.sqlite.jni.capi.sqlite3_backup; import org.sqlite.jni.capi.sqlite3_backup;
import org.sqlite.jni.capi.sqlite3_blob;
import org.sqlite.jni.capi.OutputPointer; import org.sqlite.jni.capi.OutputPointer;
/** /**
@ -473,7 +474,7 @@ public final class Sqlite implements AutoCloseable {
if( 0!=rc ){ if( 0!=rc ){
if( CApi.SQLITE_NOMEM==rc ){ if( CApi.SQLITE_NOMEM==rc ){
throw new OutOfMemoryError(); throw new OutOfMemoryError();
}else if( null==db || 0==CApi.sqlite3_errcode(db)){ }else if( null==db || 0==CApi.sqlite3_errcode(db) ){
throw new SqliteException(rc); throw new SqliteException(rc);
}else{ }else{
throw new SqliteException(db); throw new SqliteException(db);
@ -1630,4 +1631,76 @@ public final class Sqlite implements AutoCloseable {
checkRc( CApi.sqlite3_set_authorizer( thisDb(), ac ) ); checkRc( CApi.sqlite3_set_authorizer( thisDb(), ac ) );
} }
/**
Object type for use with blobOpen()
*/
public final class Blob implements AutoCloseable {
private Sqlite db;
private sqlite3_blob b;
Blob(Sqlite db, sqlite3_blob b){
this.db = db;
this.b = b;
}
/**
Analog to sqlite3_blob_close().
*/
@Override public void close(){
if( null!=b ){
CApi.sqlite3_blob_close(b);
b = null;
db = null;
}
}
/**
Analog to sqlite3_blob_reopen() but throws on error.
*/
public void reopen(long newRowId){
db.checkRc( CApi.sqlite3_blob_reopen(b, newRowId) );
}
/**
Analog to sqlite3_blob_write() but throws on error.
*/
public void write( byte[] bytes, int atOffset ){
db.checkRc( CApi.sqlite3_blob_write(b, bytes, atOffset) );
}
/**
Analog to sqlite3_blob_read() but throws on error.
*/
public void read( byte[] dest, int atOffset ){
db.checkRc( CApi.sqlite3_blob_read(b, dest, atOffset) );
}
/**
Analog to sqlite3_blob_bytes().
*/
public int bytes(){
return CApi.sqlite3_blob_bytes(b);
}
}
/**
Analog to sqlite3_blob_open(). Returns a Blob object for the
given database, table, column, and rowid. The blob is opened for
read-write mode if writeable is true, else it is read-only.
The returned object must eventually be freed, before this
database is closed, by either arranging for it to be auto-closed
or calling its close() method.
Throws on error.
*/
public Blob blobOpen(String dbName, String tableName, String columnName,
long iRow, boolean writeable){
final OutputPointer.sqlite3_blob out = new OutputPointer.sqlite3_blob();
checkRc(
CApi.sqlite3_blob_open(thisDb(), dbName, tableName, columnName,
iRow, writeable ? 1 : 0, out)
);
return new Blob(this, out.take());
}
} }

View File

@ -912,6 +912,32 @@ public class Tester2 implements Runnable {
db.close(); db.close();
} }
private void testBlobOpen(){
final Sqlite db = openDb();
execSql(db, "CREATE TABLE T(a BLOB);"
+"INSERT INTO t(rowid,a) VALUES(1, 'def'),(2, 'XYZ');"
);
Sqlite.Blob b = db.blobOpen("main", "t", "a",
db.lastInsertRowId(), true);
affirm( 3==b.bytes() );
b.write(new byte[] {100, 101, 102 /*"DEF"*/}, 0);
b.close();
Sqlite.Stmt stmt = db.prepare("SELECT length(a), a FROM t ORDER BY a");
affirm( stmt.step() );
affirm( 3 == stmt.columnInt(0) );
affirm( "def".equals(stmt.columnText16(1)) );
stmt.finalizeStmt();
b = db.blobOpen("main", "t", "a", db.lastInsertRowId(), false);
b.reopen(2);
final byte[] tgt = new byte[3];
b.read( tgt, 0 );
affirm( 100==tgt[0] && 101==tgt[1] && 102==tgt[2], "DEF" );
b.close();
db.close();
}
private void runTests(boolean fromThread) throws Exception { private void runTests(boolean fromThread) throws Exception {
List<java.lang.reflect.Method> mlist = testMethods; List<java.lang.reflect.Method> mlist = testMethods;
affirm( null!=mlist ); affirm( null!=mlist );

View File

@ -1,5 +1,5 @@
C JNI\swrapper1\snormalizeSql()\snow\sthrows\sUnsupportedOperationException,\sinstead\sof\sreturning\snull,\sif\sbuilt\swithout\sSQLITE_ENABLE_NORMALIZE.\sRemove\sSQLITE_PREPARE_NORMALIZE\sfrom\sthe\sJNI\sinterface\sbecause\sit's\sa\slegacy\sno-op. C Add\sincremental\sblob\sI/O\ssupport\sto\sJNI\swrapper1.
D 2023-11-05T03:37:33.975 D 2023-11-05T04:20:04.320
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -269,7 +269,7 @@ F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 0d1e9afc9ff8a2adb94a155b72385
F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 09bee15aa0eedac68d767ae21d9a6a62a31ade59182a3ccbf036d6463d9e30b1 F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 09bee15aa0eedac68d767ae21d9a6a62a31ade59182a3ccbf036d6463d9e30b1
F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615 F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615
F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff2260daa7ce305ff9b5fafd64153a7a28e9d8f000a815f F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff2260daa7ce305ff9b5fafd64153a7a28e9d8f000a815f
F ext/jni/src/org/sqlite/jni/capi/Tester1.java f931370e0beb121390c31747a019690a7cf0927120396862d2a02f75a66bf89c F ext/jni/src/org/sqlite/jni/capi/Tester1.java 2898e38cf5ee568a93e760fa9b84f448acb58138d0fca18d146e80a1da7c45fc
F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723 F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723
F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java c8bdf7848e6599115d601bcc9427ff902cb33129b9be32870ac6808e04b6ae56 F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java c8bdf7848e6599115d601bcc9427ff902cb33129b9be32870ac6808e04b6ae56
F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 22d365746a78c5cd7ae10c39444eb7bbf1a819aad4bb7eb77b1edc47773a3950 F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 22d365746a78c5cd7ae10c39444eb7bbf1a819aad4bb7eb77b1edc47773a3950
@ -296,9 +296,9 @@ F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe
F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483 F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483
F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 43c43adfb7866098aadaaca1620028a6ec82d5193149970019b1cce9eb59fb03 F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 43c43adfb7866098aadaaca1620028a6ec82d5193149970019b1cce9eb59fb03
F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 2833afdb9af5c1949bb35f4c926a5351fba9d1cdf0996864caa7b47827a346c7 F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 2833afdb9af5c1949bb35f4c926a5351fba9d1cdf0996864caa7b47827a346c7
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java fbdb8d6643ac1f32c4ffdb76a2ee4580edd0b1935d8d13ad7f581a702635313b F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java 6a310fe422d0daf79f7841c9b341f64d843ca7e85ef31829530623a81ecd25fa
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 982538ddb4c0719ef87dfa664cd137b09890b546029a7477810bd64d4c47ee35 F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 982538ddb4c0719ef87dfa664cd137b09890b546029a7477810bd64d4c47ee35
F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java 199b9fb56e06f808d5856494ca8840e9004ff939f27c7c6fda9a60858144f95d F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java a944fd0a9047a51a5074bffd707452d80cf06e715ebc78b541480ee98629fb93
F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java 7b89a7391f771692c5b83b0a5b86266abe8d59f1c77d7a0eccc9b79f259d79af F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java 7b89a7391f771692c5b83b0a5b86266abe8d59f1c77d7a0eccc9b79f259d79af
F ext/jni/src/org/sqlite/jni/wrapper1/WindowFunction.java c7d1452f9ff26175b3c19bbf273116cc2846610af68e01756d755f037fe7319f F ext/jni/src/org/sqlite/jni/wrapper1/WindowFunction.java c7d1452f9ff26175b3c19bbf273116cc2846610af68e01756d755f037fe7319f
F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745 F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745
@ -2142,8 +2142,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 773f9873865b5277a6a682c4695f216bfe1ec05ed5e5a2a70aaa451934ba2dc0 P d081a126697e214082f3b203f23ea63510080e5c2aac1d8badc9e6e4bfea7c95
R ea6cc7dea8e7673dad2d1e0c776c92af R d10239966e7198eb47ba47ac2878d98e
U stephan U stephan
Z d4fc1a1c9c9dbb69dd1ef9b20d8e37f3 Z e8e87bde5ba89e299cdcc353d989a2b2
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
d081a126697e214082f3b203f23ea63510080e5c2aac1d8badc9e6e4bfea7c95 7f1c76fe930d69a0274f70fa7b7e68e0db6226b731a065fa57d0936c8400ffb0