JNI doc additions.

FossilOrigin-Name: 0c7ac34f30e1f7e35a2ac4e5e55e5f24857b24afa81a7abecba60f1c9c68b9ff
This commit is contained in:
stephan
2023-08-19 12:32:00 +00:00
parent 187da43379
commit bfa486d5fc
4 changed files with 62 additions and 60 deletions
+1 -2
View File
@@ -273,8 +273,7 @@ package.jar.in := $(abspath $(dir.src)/jar.in)
CLEAN_FILES += $(package.jar.in)
$(package.jar.in): $(MAKEFILE) $(CLASS_FILES.main)
cd $(dir.src); ls -1 org/sqlite/jni/*.java org/sqlite/jni/*.class > $@
@ls -la $@
@echo "To use this jar you will need the -Djava.library.path=DIR/WITH/libsqlite3-jni.so flag."
@echo "To use this jar you will need the -Djava.library.path=DIR/CONTAINING/libsqlite3-jni.so flag."
@echo "e.g. java -jar $@ -Djava.library.path=bld"
$(package.jar): $(CLASS_FILES) $(MAKEFILE) $(package.jar.in)
+53 -50
View File
@@ -15,7 +15,10 @@ Technical support is available in the forum:
> **FOREWARNING:** this subproject is very much in development and
subject to any number of changes. Please do not rely on any
information about its API until this disclaimer is removed.
information about its API until this disclaimer is removed. The JNI
bindgins released with version 3.43 are a "tech preview" and 3.44
will be "final," at which point strong backward compatibility
guarantees will apply.
Project goals/requirements:
@@ -40,13 +43,30 @@ Non-goals:
- Creation of high-level OO wrapper APIs. Clients are free to create
them off of the C-style API.
Hello World
-----------------------------------------------------------------------
Significant TODOs
========================================================================
```java
import org.sqlite.jni.*;
import static org.sqlite.jni.SQLite3Jni;
...
OutputPointer.sqlite3 out = new OutputPointer.sqlite3();
int rc = sqlite3_open(":memory:", out);
final sqlite3 db = out.take();
if( 0 != rc ){
if( null != db ){
System.out.print("Error opening db: "+sqlite3_errmsg(db));
sqlite3_close(db);
}else{
System.out.print("Error opening db: rc="+rc);
}
... handle error ...
}
- Lots of APIs left to bind. Most "day-to-day" functionality is already
in place and is believed to work well.
... use db ...
sqlite3_close_v2(db);
```
Building
========================================================================
@@ -59,55 +79,33 @@ The canonical builds assumes a Linux-like environment and requires:
Put simply:
```
```console
$ export JAVA_HOME=/path/to/jdk/root
$ make
$ make test
$ make clean
```
The jar distribution can be created with `make jar`.
<a id='1to1ish'></a>
One-to-One(-ish) Mapping to C
========================================================================
This JNI binding aims to provide as close to a 1-to-1 experience with
the C API as cross-language semantics allow. Exceptions are
necessarily made where cross-language semantics do not allow a 1-to-1,
and judiciously made where a 1-to-1 mapping would be unduly cumbersome
to use in Java.
the C API as cross-language semantics allow. Changes are necessarily
made where cross-language semantics do not allow a 1-to-1, and
judiciously made where a 1-to-1 mapping would be unduly cumbersome to
use in Java.
Golden Rule: _Never_ Throw from Callbacks
Golden Rule: _Never_ Throw from Callbacks (Unless...)
------------------------------------------------------------------------
JNI bindings which accept client-defined functions _must never throw
exceptions_ unless _very explicitly documented_ as being
throw-safe. Exceptions are generally reserved for higher-level
bindings which are constructed to specifically deal with them and
ensure that they do not leak C-level resources. Some of the JNI
bindings are provided as Java functions which expect this rule to
always hold.
UTF-8(-ish)
------------------------------------------------------------------------
SQLite internally uses UTF-8 encoding, whereas Java natively uses
UTF-16. Java JNI has routines for converting to and from UTF-8, _but_
Java uses what its docs call "[modified UTF-8][modutf8]." Care must be
taken when converting Java strings to UTF-8 to ensure that the proper
conversion is performed. In short,
`String.getBytes(StandardCharsets.UTF_8)` performs the proper
conversion in Java, and there is no JNI C API for that conversion
(JNI's `NewStringUTF()` returns MUTF-8).
Known consequences and limitations of this discrepancy include:
- Names of databases, tables, and collations must not contain
characters which differ in MUTF-8 and UTF-8, or certain APIs will
mis-translate them on their way between languages. APIs which
transfer other client-side data to Java take extra care to
convert the data at the cost of performance.
[modutf8]: https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8
Client-defined callbacks _must never throw exceptions_ unless _very
explicitly documented_ as being throw-safe. Exceptions are generally
reserved for higher-level bindings which are constructed to
specifically deal with them and ensure that they do not leak C-level
resources.
Unwieldy Constructs are Re-mapped
@@ -125,7 +123,7 @@ A prime example of where interface changes for Java are necessary for
usability is [registration of a custom
collation](https://sqlite.org/c3ref/create_collation.html):
```
```c
// C:
int sqlite3_create_collation(sqlite3 * db, const char * name, int eTextRep,
void *pUserData,
@@ -144,7 +142,7 @@ passed that object as their first argument. That data is passed around
bind that part as-is to Java, the result would be awkward to use (^Yes,
we tried this.):
```
```java
// Java:
int sqlite3_create_collation(sqlite3 db, String name, int eTextRep,
Object pUserData, xCompareType xCompare);
@@ -159,7 +157,7 @@ for callbacks and (B) having their internal state provided separately,
which is ill-fitting in Java. For the sake of usability, C APIs which
follow that pattern use a slightly different Java interface:
```
```java
int sqlite3_create_collation(sqlite3 db, String name, int eTextRep,
Collation collation);
```
@@ -168,7 +166,7 @@ Where the `Collation` class has an abstract `xCompare()` method and
no-op `xDestroy()` method which can be overridden if needed, leading to
a much more Java-esque usage:
```
```java
int rc = sqlite3_create_collation(db, "mycollation", SQLITE_UTF8, new Collation(){
// Required comparison function:
@@ -187,8 +185,8 @@ int rc = sqlite3_create_collation(db, "mycollation", SQLITE_UTF8, new Collation(
Noting that:
- It is still possible to bind in call-scope-local state via closures,
if desired.
- It is possible to bind in call-scope-local state via closures, if
desired, as opposed to packing it into the Collation object.
- No capabilities of the C API are lost or unduly obscured via the
above API reshaping, so power users need not make any compromises.
@@ -199,6 +197,7 @@ Noting that:
overriding the `xDestroy()` method effectively gives it v2
semantics.
### User-defined SQL Functions (a.k.a. UDFs)
The [`sqlite3_create_function()`](https://sqlite.org/c3ref/create_function.html)
@@ -206,12 +205,13 @@ family of APIs make heavy use of function pointers to provide
client-defined callbacks, necessitating interface changes in the JNI
binding. The Java API has only one core function-registration function:
```
```java
int sqlite3_create_function(sqlite3 db, String funcName, int nArgs,
int encoding, SQLFunction func);
```
> Design question: does the encoding argument serve any purpose in JS?
> Design question: does the encoding argument serve any purpose in
Java? That's as-yet undetermined. If not, it will be removed.
`SQLFunction` is not used directly, but is instead instantiated via
one of its three subclasses:
@@ -229,5 +229,8 @@ Search [`Tester1.java`](/file/ext/jni/src/org/sqlite/jni/Tester1.java) for
Reminder: see the disclaimer at the top of this document regarding the
in-flux nature of this API.
[jsrc]: /file/
[www]: https://sqlite.org
### And so on...
Various APIs which accept callbacks, e.g. `sqlite3_trace_v2()` and
`sqlite3_update_hook()`, use interfaces similar to those shown above.
+7 -7
View File
@@ -1,5 +1,5 @@
C JNI\stest\scode\scleanups.
D 2023-08-19T11:52:36.349
C JNI\sdoc\sadditions.
D 2023-08-19T12:32:00.131
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -231,8 +231,8 @@ 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 4217266579b74499708d0b9fd7de598d67cc1992646518596ec83f134c3e2d85
F ext/jni/README.md 7a614a2fa6c561205f7a53fd8626cf93a7b5711ff454fc1814517f796df398eb
F ext/jni/GNUmakefile ace719d6d7025a0a454b7c661de2beef9a0e819535ad0ce0742034da8ff8d27f
F ext/jni/README.md 975b35173debbbf3a4ab7166e14d2ffa2bacff9b6850414f09cc919805e81ba4
F ext/jni/jar-dist.make 9a03d10dbb5a74c724bfec4b76fd9e4c9865cbbc858d731cb48f38ac897d73a3
F ext/jni/src/c/sqlite3-jni.c 8608cb36223d6bc64e8ddd9296b6d63a4fc54efaf8dbc3ea7e5eca81f4801d42
F ext/jni/src/c/sqlite3-jni.h f10d2f38720687c70ecdd5e44f6e8db98efee2caa05fc86b2d9e0c76e6cc0a18
@@ -2091,8 +2091,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 1cecb9e0383aa78c491f9ba88c831a88b4b2d40ceef1b87be494b6ddc0789e41
R a49c27c6a99f3ab466acd799b27c01cf
P e202b6e69da8cced114d027cf2e91a04dfdd50b601b3274214783f7d750c558c
R 109361c70c87f2804d75b9c237ee841f
U stephan
Z a181fae7a989c6647ffb5b92efaaa712
Z 56d27110aeccda606f4b75566f7a0870
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
e202b6e69da8cced114d027cf2e91a04dfdd50b601b3274214783f7d750c558c
0c7ac34f30e1f7e35a2ac4e5e55e5f24857b24afa81a7abecba60f1c9c68b9ff