JNI: initial draft (untested - requires more infrastructure first) of a UDF argument/result-handling interface which completely hides the C-style API from the client.
FossilOrigin-Name: 43b10a5cf9cb8be53d62914f340d533e60a70bf4caa8b9b91c0f867fa0f70493
This commit is contained in:
parent
7e540e5a2c
commit
f2d7e961d9
@ -113,6 +113,7 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/annotation/%,\
|
||||
sqlite3_stmt.java \
|
||||
sqlite3_value.java \
|
||||
) $(patsubst %,$(dir.src.jni)/wrapper1/%,\
|
||||
SqlFunction.java \
|
||||
Sqlite.java \
|
||||
SqliteException.java \
|
||||
)
|
||||
|
@ -1635,7 +1635,8 @@ public final class CApi {
|
||||
public static void sqlite3_result_text16(
|
||||
@NotNull sqlite3_context cx, @Nullable byte[] utf16
|
||||
){
|
||||
sqlite3_result_text64(cx, utf16, utf16.length, SQLITE_UTF16);
|
||||
if(null == utf16) sqlite3_result_null(cx);
|
||||
else sqlite3_result_text64(cx, utf16, utf16.length, SQLITE_UTF16);
|
||||
}
|
||||
|
||||
public static void sqlite3_result_text16(
|
||||
|
153
ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java
Normal file
153
ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
** 2023-10-16
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the wrapper1 interface for sqlite3.
|
||||
*/
|
||||
package org.sqlite.jni.wrapper1;
|
||||
import org.sqlite.jni.capi.CApi;
|
||||
import org.sqlite.jni.annotation.*;
|
||||
import org.sqlite.jni.capi.sqlite3_context;
|
||||
import org.sqlite.jni.capi.sqlite3_value;
|
||||
|
||||
/**
|
||||
EXPERIMENTAL/INCOMPLETE/UNTESTED
|
||||
*/
|
||||
public interface SqlFunction {
|
||||
|
||||
/**
|
||||
EXPERIMENTAL/INCOMPLETE/UNTESTED. An attempt at hiding UDF-side
|
||||
uses of the sqlite3_context and sqlite3_value classes from a
|
||||
high-level wrapper. This level of indirection requires more than
|
||||
twice as much Java code (in this API, not client-side) as using
|
||||
the lower-level API. Client-side it's roughly the same amount of
|
||||
code.
|
||||
*/
|
||||
public final static class Arguments implements Iterable<SqlFunction.Arguments.Arg>{
|
||||
private final sqlite3_context cx;
|
||||
private final sqlite3_value args[];
|
||||
|
||||
/**
|
||||
Must be passed the context and arguments for the UDF call this
|
||||
object is wrapping.
|
||||
*/
|
||||
Arguments(@NotNull sqlite3_context cx, @NotNull sqlite3_value args[]){
|
||||
this.cx = cx;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
Wrapper for a single SqlFunction argument. Primarily intended
|
||||
for eventual use with the Arguments class's Iterable interface.
|
||||
*/
|
||||
public final static class Arg {
|
||||
private final Arguments a;
|
||||
private final int ndx;
|
||||
/* Only for use by the Arguments class. */
|
||||
private Arg(@NotNull Arguments a, int ndx){
|
||||
this.a = a;
|
||||
this.ndx = ndx;
|
||||
}
|
||||
/** Returns this argument's index in its parent argument list. */
|
||||
public int getIndex(){return ndx;}
|
||||
|
||||
public int getInt(){return a.getInt(ndx);}
|
||||
public long getInt64(){return a.getInt64(ndx);}
|
||||
public double getDouble(){return a.getDouble(ndx);}
|
||||
public byte[] getBlob(){return a.getBlob(ndx);}
|
||||
public byte[] getText(){return a.getText(ndx);}
|
||||
public String getText16(){return a.getText16(ndx);}
|
||||
public int getBytes(){return a.getBytes(ndx);}
|
||||
public int getBytes16(){return a.getBytes16(ndx);}
|
||||
public Object getObject(){return a.getObject(ndx);}
|
||||
public <T> T getObjectCasted(Class<T> type){ return a.getObjectCasted(ndx, type); }
|
||||
public int getType(){return a.getType(ndx);}
|
||||
public Object getAuxData(){return a.getAuxData(ndx);}
|
||||
public void setAuxData(Object o){a.setAuxData(ndx, o);}
|
||||
}
|
||||
|
||||
//! Untested!
|
||||
@Override
|
||||
public java.util.Iterator<SqlFunction.Arguments.Arg> iterator(){
|
||||
Arg[] proxies = new Arg[args.length];
|
||||
for( int i = 0; i < args.length; ++i ){
|
||||
proxies[i] = new Arg(this, i);
|
||||
}
|
||||
return java.util.Arrays.stream(proxies).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the sqlite3_value at the given argument index or throws
|
||||
an IllegalArgumentException exception if ndx is out of range.
|
||||
*/
|
||||
private sqlite3_value valueAt(int ndx){
|
||||
if(ndx<0 || ndx>=args.length){
|
||||
throw new IllegalArgumentException(
|
||||
"SQL function argument index "+ndx+" is out of range."
|
||||
);
|
||||
}
|
||||
return args[ndx];
|
||||
}
|
||||
|
||||
public int getArgCount(){ return args.length; }
|
||||
|
||||
public int getInt(int arg){return CApi.sqlite3_value_int(valueAt(arg));}
|
||||
public long getInt64(int arg){return CApi.sqlite3_value_int64(valueAt(arg));}
|
||||
public double getDouble(int arg){return CApi.sqlite3_value_double(valueAt(arg));}
|
||||
public byte[] getBlob(int arg){return CApi.sqlite3_value_blob(valueAt(arg));}
|
||||
public byte[] getText(int arg){return CApi.sqlite3_value_text(valueAt(arg));}
|
||||
public String getText16(int arg){return CApi.sqlite3_value_text16(valueAt(arg));}
|
||||
public int getBytes(int arg){return CApi.sqlite3_value_bytes(valueAt(arg));}
|
||||
public int getBytes16(int arg){return CApi.sqlite3_value_bytes16(valueAt(arg));}
|
||||
public Object getObject(int arg){return CApi.sqlite3_value_java_object(valueAt(arg));}
|
||||
public <T> T getObjectCasted(int arg, Class<T> type){
|
||||
return CApi.sqlite3_value_java_casted(valueAt(arg), type);
|
||||
}
|
||||
|
||||
public int getType(int arg){return CApi.sqlite3_value_type(valueAt(arg));}
|
||||
|
||||
public void resultInt(int v){ CApi.sqlite3_result_int(cx, v); }
|
||||
public void resultInt64(long v){ CApi.sqlite3_result_int64(cx, v); }
|
||||
public void resultDouble(double v){ CApi.sqlite3_result_double(cx, v); }
|
||||
public void resultError(String msg){CApi.sqlite3_result_error(cx, msg);}
|
||||
public void resultError(Exception e){CApi.sqlite3_result_error(cx, e);}
|
||||
public void resultErrorTooBig(){CApi.sqlite3_result_error_toobig(cx);}
|
||||
public void resultErrorCode(int rc){CApi.sqlite3_result_error_code(cx, rc);}
|
||||
public void resultObject(Object o){CApi.sqlite3_result_java_object(cx, o);}
|
||||
public void resultArg(int argNdx){CApi.sqlite3_result_value(cx, valueAt(argNdx));}
|
||||
public void resultZeroBlob(long n){
|
||||
// Throw on error? If n is too big,
|
||||
// sqlite3_result_error_toobig() is automatically called.
|
||||
CApi.sqlite3_result_zeroblob64(cx, n);
|
||||
}
|
||||
|
||||
public void resultBlob(byte[] blob){CApi.sqlite3_result_blob(cx, blob);}
|
||||
public void resultText(byte[] utf8){CApi.sqlite3_result_text(cx, utf8);}
|
||||
public void resultText(String txt){CApi.sqlite3_result_text(cx, txt);}
|
||||
public void resultText16(byte[] utf16){CApi.sqlite3_result_text16(cx, utf16);}
|
||||
public void resultText16(String txt){CApi.sqlite3_result_text16(cx, txt);}
|
||||
|
||||
public void setAuxData(int arg, Object o){
|
||||
/* From the API docs: https://www.sqlite.org/c3ref/get_auxdata.html
|
||||
|
||||
The value of the N parameter to these interfaces should be
|
||||
non-negative. Future enhancements may make use of negative N
|
||||
values to define new kinds of function caching behavior.
|
||||
*/
|
||||
valueAt(arg);
|
||||
CApi.sqlite3_set_auxdata(cx, arg, o);
|
||||
}
|
||||
|
||||
public Object getAuxData(int arg){
|
||||
valueAt(arg);
|
||||
return CApi.sqlite3_get_auxdata(cx, arg);
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the JNI bindings for the sqlite3 C API.
|
||||
** This file is part of the wrapper1 interface for sqlite3.
|
||||
*/
|
||||
package org.sqlite.jni.wrapper1;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file is part of the JNI bindings for the sqlite3 C API.
|
||||
** This file is part of the wrapper1 interface for sqlite3.
|
||||
*/
|
||||
package org.sqlite.jni.wrapper1;
|
||||
import static org.sqlite.jni.capi.CApi.*;
|
||||
@ -54,7 +54,7 @@ public final class SqliteException extends java.lang.RuntimeException {
|
||||
a failed db-open operation, and the place(s) where that can
|
||||
happen are inside this library, not client-level code.
|
||||
*/
|
||||
public SqliteException(sqlite3 db){
|
||||
SqliteException(sqlite3 db){
|
||||
super(sqlite3_errmsg(db));
|
||||
errCode = sqlite3_errcode(db);
|
||||
xerrCode = sqlite3_extended_errcode(db);
|
||||
@ -63,8 +63,8 @@ public final class SqliteException extends java.lang.RuntimeException {
|
||||
}
|
||||
|
||||
/**
|
||||
Records the current error state of db (which must not be null and must
|
||||
refer to an open database) then closes it.
|
||||
Records the current error state of db (which must not be null and
|
||||
must refer to an open database).
|
||||
*/
|
||||
public SqliteException(Sqlite db){
|
||||
this(db.nativeHandle());
|
||||
|
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C JNI:\scleanups\sin\sTester2\sand\supdate\sthe\sjar\smakefile\starget\sto\saccount\sfor\s[9fcdf96adca2].
|
||||
D 2023-10-16T10:38:34.125
|
||||
C JNI:\sinitial\sdraft\s(untested\s-\srequires\smore\sinfrastructure\sfirst)\sof\sa\sUDF\sargument/result-handling\sinterface\swhich\scompletely\shides\sthe\sC-style\sAPI\sfrom\sthe\sclient.
|
||||
D 2023-10-16T13:04:42.394
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -235,7 +235,7 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
|
||||
F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
|
||||
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
|
||||
F ext/jni/GNUmakefile bf7dbc177903a180aaa45540483d49185abb5e032c08773a36eb7983281b7ab0
|
||||
F ext/jni/GNUmakefile 069399d471af948a4293e79135907a8d58daa09e59b4cc1b9cc1a5124c87f589
|
||||
F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4
|
||||
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
|
||||
F ext/jni/src/c/sqlite3-jni.c 8d32ca0598a11370a9e92a6d111f38934c225056b42b13512175acf6e37eed4c
|
||||
@ -248,7 +248,7 @@ F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java bc29e986c866c2ddbbb9f93
|
||||
F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java 7ed409d5449684616cc924534e22ff6b07d361f12ad904b69ecb10e0568a8013
|
||||
F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759
|
||||
F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca
|
||||
F ext/jni/src/org/sqlite/jni/capi/CApi.java 82993492793fd946e2b9b9a244fe5ac39647292b449cac7453ea49031c00f517
|
||||
F ext/jni/src/org/sqlite/jni/capi/CApi.java 5d754b4bb57852d006ad046b2860eb23ba406f800846460b26beee5172df4fc3
|
||||
F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 0bfd6e56e8265c2f05c9207665707285534d78f8466ef0e0430c65677f00943d
|
||||
F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a
|
||||
F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java f81cf10b79c52f9b2e9247d523d29ae48863935f60420eae35f257c38c80ce95
|
||||
@ -289,8 +289,9 @@ F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java a8e88c3783d21cec51b0748568a96653
|
||||
F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 9e2b954d210d572552b28aca523b272fae14bd41e318921b22f65b728d5bf978
|
||||
F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 92bdaa3893bd684533004d64ade23d329843f809cd0d0f4f1a2856da6e6b4d90
|
||||
F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java f05ee6c52b039bb5b65e49ac90710f58cbfc95e13e5a8d46a7fe5106d5819dad
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 039f6f858cd6a0f59a41f0823d638959d8f47e7098dd469c486988494d651896
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 40a9f4f8a7a72b90b12baa82d26ba16376a5758009739b069c1863201770e816
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java 2bc90edc4c25225e018ed600b5eff43ba0485be85db08f8b6b35246372fdac20
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 1386f7b753134fc12253ce2fbbc448ba8c970567fac01a3356cb672e14408d73
|
||||
F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java aee8301f92256ab8572043cf5de2a35afda057d2a6ff09970a2f84a90305471e
|
||||
F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745
|
||||
F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
|
||||
@ -2128,8 +2129,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 9fcdf96adca25cc2d2f4b75ec4eea94254fb9671c5ba63b88213d7f62dedff1b
|
||||
R 376c33c5d6d18c40ea3627a195e8192d
|
||||
P abc82bf4b800dde1b6e6172c7be816edb391fdbed5dbd2749f54623fdf3bf8e6
|
||||
R 287c21329f3772a974832101be3bffee
|
||||
U stephan
|
||||
Z 0f3f56205e0babb2af321d2f9efdae5a
|
||||
Z a4e77b564ffa0b3970c5e65a1253c53d
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
abc82bf4b800dde1b6e6172c7be816edb391fdbed5dbd2749f54623fdf3bf8e6
|
||||
43b10a5cf9cb8be53d62914f340d533e60a70bf4caa8b9b91c0f867fa0f70493
|
Loading…
Reference in New Issue
Block a user