--- /dev/null
+/*
+** 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);
+ }
+ }
+}
-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
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
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
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
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.