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

More docs for the Java side of the JNI bindings.

FossilOrigin-Name: d8e9bcee96b90d56701f7907a8bd48853211caf757e1aa8decc7ed25eece6770
This commit is contained in:
stephan
2023-08-01 10:19:05 +00:00
parent e209d144c3
commit ed77e13f05
5 changed files with 70 additions and 25 deletions

View File

@ -2520,7 +2520,7 @@ JDECL(void,1do_1something_1for_1developer)(JENV_JSELF){
S3Global.metrics.envCacheMisses,
S3Global.metrics.envCacheHits);
puts("UDF calls:");
#define UDF(T) printf("\t%-8s = %u\n", #T, S3Global.metrics.udf.n##T)
#define UDF(T) printf("\t%-8s = %u\n", "x" #T, S3Global.metrics.udf.n##T)
UDF(Func); UDF(Step); UDF(Final); UDF(Value); UDF(Inverse);
#undef UDF
printf("xDestroy calls across all callback types: %u\n",

View File

@ -17,22 +17,29 @@ package org.sqlite.jni;
SQLFunction is used in conjunction with the
sqlite3_create_function() JNI-bound API to give that native code
access to the callback functions needed in order to implement SQL
functions in Java. This class is not used by itself: see the
inner classes Scalar, Aggregate<T>, and Window<T>.
functions in Java.
This class is not used by itself, but is a marker base class. The
three UDF types are modelled by the inner classes Scalar,
Aggregate<T>, and Window<T>. Most simply, clients may create
anonymous classes from those to implement UDFs. Clients are free to
create their own classes for use with UDFs, so long as they conform
to the public interfaces defined by those three classes. The JNI
layer only actively relies on the SQLFunction base class.
*/
public abstract class SQLFunction {
/**
ContextMap is a helper for use with aggregate and window
functions, to help them manage their accumulator state across
calls to the UDF's callbacks.
PerContextState assists aggregate and window functions in
managinga their accumulator state across calls to the UDF's
callbacks.
If a given aggregate or window function is called multiple times
in a single SQL statement, e.g. SELECT MYFUNC(A), MYFUNC(B)...,
then the clients need some way of knowing which call is which so
that they can map their state between their various UDF callbacks
and reset it (if needed) via xFinal(). This class takes care of
such mappings.
and reset it via xFinal(). This class takes care of such
mappings.
This class works by mapping
sqlite3_context.getAggregateContext() to a single piece of
@ -42,9 +49,10 @@ public abstract class SQLFunction {
This class is a helper providing commonly-needed functionality -
it is not required for use with aggregate or window functions.
Client UDFs are free to perform such mappings using custom
approaches.
approaches. The provided Aggregate<T> and Window<T> classes
use this.
*/
public static final class ContextMap<T> {
public static final class PerContextState<T> {
private final java.util.Map<Long,ValueHolder<T>> map
= new java.util.HashMap<>();
@ -76,8 +84,8 @@ public abstract class SQLFunction {
associated with cx.getAggregateContext() from the map and
returns it, returning null if no other UDF method has been
called to set up such a mapping. The latter condition will be
the case if an aggregate is used in a statement which has no
result rows.
the case if a UDF is used in a statement which has no result
rows.
*/
public T takeAggregateState(sqlite3_context cx){
final ValueHolder<T> h = map.remove(cx.getAggregateContext());
@ -87,7 +95,10 @@ public abstract class SQLFunction {
//! Subclass for creating scalar functions.
public static abstract class Scalar extends SQLFunction {
//! As for the xFunc() argument of the C API's sqlite3_create_function()
public abstract void xFunc(sqlite3_context cx, sqlite3_value[] args);
/**
Optionally override to be notified when the UDF is finalized by
SQLite.
@ -102,20 +113,42 @@ public abstract class SQLFunction {
takeAggregateState() methods.
*/
public static abstract class Aggregate<T> extends SQLFunction {
//! As for the xStep() argument of the C API's sqlite3_create_function()
public abstract void xStep(sqlite3_context cx, sqlite3_value[] args);
//! As for the xFinal() argument of the C API's sqlite3_create_function()
public abstract void xFinal(sqlite3_context cx);
//! @see Scalar#xDestroy()
/**
Optionally override to be notified when the UDF is finalized by
SQLite.
*/
public void xDestroy() {}
private final ContextMap<T> map = new ContextMap<>();
//! Per-invocation state for the UDF.
private final PerContextState<T> map = new PerContextState<>();
//! @see ContextMap<T>#getAggregateState()
/**
To be called from the implementation's xStep() method, as well
as the xValue() and xInverse() methods of the Window<T>
subclass, to fetch the current per-call UDF state. On the
first call to this method for any given sqlite3_context
argument, the context is set to the given initial value. On all other
calls, the 2nd argument is ignored.
@see PerContextState<T>#takeAggregateState()
*/
protected final ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
return map.getAggregateState(cx, initialValue);
}
//! @see ContextMap<T>#takeAggregateState()
/**
To be called from the implementation's xFinal() method to fetch
the final state of the UDF and remove its mapping.
@see PerContextState<T>#takeAggregateState()
*/
protected final T takeAggregateState(sqlite3_context cx){
return map.takeAggregateState(cx);
}
@ -129,7 +162,11 @@ public abstract class SQLFunction {
invocation-specific state.
*/
public static abstract class Window<T> extends Aggregate<T> {
//! As for the xInverse() argument of the C API's sqlite3_create_window_function()
public abstract void xInverse(sqlite3_context cx, sqlite3_value[] args);
//! As for the xValue() argument of the C API's sqlite3_create_window_function()
public abstract void xValue(sqlite3_context cx);
}
}

View File

@ -288,6 +288,14 @@ public final class SQLite3Jni {
int eTextRep,
@NotNull Collation col);
/**
The Java counterpart to the C-native sqlite3_create_function(),
sqlite3_create_function_v2(), and
sqlite3_create_window_function(). Which one it behaves like
depends on which methods the final argument implements. See
SQLFunction's inner classes (Scalar, Aggregate<T>, and Window<T>)
for details.
*/
public static native int sqlite3_create_function(@NotNull sqlite3 db,
@NotNull String functionName,
int nArg, int eTextRep,