Bind the remaining Fts5ExtensionApi methods to JNI, noting that all are completely untested because the higher-level bits needed to do so are still missing.

FossilOrigin-Name: 23383c1dfd240ce47f504dd5c3402c9a31f166fbde5bb72d91309a5655074b33
This commit is contained in:
stephan 2023-08-05 00:40:28 +00:00
parent cc8202b646
commit 0c179dd5b4
6 changed files with 447 additions and 43 deletions

View File

@ -346,6 +346,11 @@ struct JNIEnvCacheLine {
#ifdef SQLITE_ENABLE_FTS5
jobject jFtsExt /* Global ref to Java singleton for the
Fts5ExtensionApi instance. */;
struct {
jclass klazz;
jfieldID fidA;
jfieldID fidB;
} jPhraseIter;
#endif
#if 0
/* TODO: refactor this cache as a linked list with malloc()'d entries,
@ -368,17 +373,18 @@ static void NphCacheLine_clear(JNIEnv * const env, NphCacheLine * const p){
static void JNIEnvCacheLine_clear(JNIEnvCacheLine * const p){
JNIEnv * const env = p->env;
int i;
if(env){
int i;
UNREF_G(p->globalClassObj);
UNREF_G(p->globalClassLong);
#ifdef SQLITE_ENABLE_FTS5
UNREF_G(p->jFtsExt);
UNREF_G(p->jPhraseIter.klazz);
#endif
i = 0;
for( ; i < NphCache_SIZE; ++i){
for( i = 0; i < NphCache_SIZE; ++i ){
NphCacheLine_clear(env, &p->nph[i]);
}
memset(p, 0, sizeof(JNIEnvCacheLine));
}
}
@ -387,7 +393,6 @@ static void JNIEnvCache_clear(JNIEnvCache * const p){
for( ; i < p->used; ++i ){
JNIEnvCacheLine_clear( &p->lines[i] );
}
memset(p, 0, sizeof(JNIEnvCache));
}
/** State for various hook callbacks. */
@ -419,9 +424,6 @@ struct PerDbStateJni {
it would be a different instance (and maybe even a
different class) than the one the user may expect
to receive. */;
#ifdef SQLITE_ENABLE_FTS5
jobject jFtsApi /* global ref to fts5_api object for the db. */;
#endif
JniHookState busyHandler;
JniHookState collation;
JniHookState collationNeeded;
@ -771,9 +773,7 @@ static void JniHookState_unref(JNIEnv * const env, JniHookState * const s, int d
}
UNREF_G(s->jObj);
UNREF_G(s->klazz);
s->jObj = 0;
s->klazz = 0;
s->midCallback = 0;
memset(s, 0, sizeof(*s));
}
/**
@ -805,9 +805,6 @@ static void PerDbStateJni_set_aside(PerDbStateJni * const s){
UNHOOK(busyHandler, 1);
#undef UNHOOK
UNREF_G(s->jDb);
#ifdef SQLITE_ENABLE_FTS5
UNREF_G(s->jFtsApi);
#endif
memset(s, 0, sizeof(PerDbStateJni));
s->pNext = S3Global.perDb.aFree;
if(s->pNext) s->pNext->pPrev = s;
@ -1029,7 +1026,9 @@ static int CollationState_xCompare(void *pArg, int nLhs, const void *lhs,
jbyteArray jbaRhs = jbaLhs ? (*env)->NewByteArray(env, (jint)nRhs) : NULL;
//MARKER(("native xCompare nLhs=%d nRhs=%d\n", nLhs, nRhs));
if(!jbaRhs){
(*env)->FatalError(env, "Out of memory. Cannot allocate arrays for collation.");
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
return 0;
//(*env)->FatalError(env, "Out of memory. Cannot allocate arrays for collation.");
}
(*env)->SetByteArrayRegion(env, jbaLhs, 0, (jint)nLhs, (const jbyte*)lhs);
(*env)->SetByteArrayRegion(env, jbaRhs, 0, (jint)nRhs, (const jbyte*)rhs);
@ -2713,6 +2712,43 @@ JDECLFts(jint,xColumnTotalSize)(JENV_JSELF,jobject jCtx, jint iCol, jobject jOut
return (jint)rc;
}
typedef struct s3jni_fts5AuxData s3jni_fts5AuxData;
struct s3jni_fts5AuxData {
JNIEnv *env;
jobject jObj;
};
static void s3jni_fts5AuxData_xDestroy(void *x){
if(x){
s3jni_fts5AuxData * const p = x;
if(p->jObj){
JNIEnv *env = p->env;
s3jni_call_xDestroy(env, p->jObj, 0);
UNREF_G(p->jObj);
}
sqlite3_free(x);
}
}
JDECLFts(jobject,xGetAuxdata)(JENV_JSELF,jobject jCtx, jboolean bClear){
Fts5ExtDecl;
jobject rv = 0;
s3jni_fts5AuxData * const pAux = fext->xGetAuxdata(PtrGet_Fts5Context(jCtx), bClear);
if(pAux){
if(bClear){
if( pAux->jObj ){
rv = REF_L(pAux->jObj);
UNREF_G(pAux->jObj);
}
/* Note that we do not call xDestroy() in this case. */
sqlite3_free(pAux);
}else{
rv = pAux->jObj;
}
}
return rv;
}
JDECLFts(jint,xInst)(JENV_JSELF,jobject jCtx, jint iIdx, jobject jOutPhrase,
jobject jOutCol, jobject jOutOff){
Fts5ExtDecl;
@ -2739,11 +2775,172 @@ JDECLFts(jint,xPhraseCount)(JENV_JSELF,jobject jCtx){
return (jint)fext->xPhraseCount(PtrGet_Fts5Context(jCtx));
}
/**
Initializes jc->jPhraseIter if it needed it.
*/
static void s3jni_phraseIter_init(JNIEnv *const env, JNIEnvCacheLine * const jc,
jobject jIter){
if(!jc->jPhraseIter.klazz){
jclass klazz = (*env)->GetObjectClass(env, jIter);
EXCEPTION_IS_FATAL("Cannot get class of Fts5PhraseIter object.");
jc->jPhraseIter.klazz = REF_G(klazz);
jc->jPhraseIter.fidA = (*env)->GetFieldID(env, klazz, "a", "J");
EXCEPTION_IS_FATAL("Cannot get Fts5PhraseIter.a field.");
jc->jPhraseIter.fidB = (*env)->GetFieldID(env, klazz, "a", "J");
EXCEPTION_IS_FATAL("Cannot get Fts5PhraseIter.b field.");
}
}
/* Copy the 'a' and 'b' fields from pSrc to Fts5PhraseIter object jIter. */
static void s3jni_phraseIter_NToJ(JNIEnv *const env, JNIEnvCacheLine const * const jc,
Fts5PhraseIter const * const pSrc,
jobject jIter){
assert(jc->jPhraseIter.klazz);
(*env)->SetLongField(env, jIter, jc->jPhraseIter.fidA, (jlong)pSrc->a);
EXCEPTION_IS_FATAL("Cannot set Fts5PhraseIter.a field.");
(*env)->SetLongField(env, jIter, jc->jPhraseIter.fidB, (jlong)pSrc->b);
EXCEPTION_IS_FATAL("Cannot set Fts5PhraseIter.b field.");
}
/* Copy the 'a' and 'b' fields from Fts5PhraseIter object jIter to pDest. */
static void s3jni_phraseIter_JToN(JNIEnv *const env, JNIEnvCacheLine const * const jc,
jobject jIter, Fts5PhraseIter * const pDest){
assert(jc->jPhraseIter.klazz);
pDest->a =
(const unsigned char *)(*env)->GetLongField(env, jIter, jc->jPhraseIter.fidA);
EXCEPTION_IS_FATAL("Cannot get Fts5PhraseIter.a field.");
pDest->b =
(const unsigned char *)(*env)->GetLongField(env, jIter, jc->jPhraseIter.fidB);
EXCEPTION_IS_FATAL("Cannot get Fts5PhraseIter.b field.");
}
JDECLFts(jint,xPhraseFirst)(JENV_JSELF,jobject jCtx, jint iPhrase,
jobject jIter, jobject jOutCol,
jobject jOutOff){
Fts5ExtDecl;
JNIEnvCacheLine * const jc = S3Global_env_cache(env);
Fts5PhraseIter iter;
int rc, iCol = 0, iOff = 0;
s3jni_phraseIter_init(env, jc, jIter);
rc = fext->xPhraseFirst(PtrGet_Fts5Context(jCtx), (int)iPhrase,
&iter, &iCol, &iOff);
if( 0==rc ){
setOutputInt32(env, jOutCol, iCol);
setOutputInt32(env, jOutOff, iOff);
s3jni_phraseIter_NToJ(env, jc, &iter, jIter);
}
return rc;
}
JDECLFts(jint,xPhraseFirstColumn)(JENV_JSELF,jobject jCtx, jint iPhrase,
jobject jIter, jobject jOutCol){
Fts5ExtDecl;
JNIEnvCacheLine * const jc = S3Global_env_cache(env);
Fts5PhraseIter iter;
int rc, iCol = 0;
s3jni_phraseIter_init(env, jc, jIter);
rc = fext->xPhraseFirstColumn(PtrGet_Fts5Context(jCtx), (int)iPhrase,
&iter, &iCol);
if( 0==rc ){
setOutputInt32(env, jOutCol, iCol);
s3jni_phraseIter_NToJ(env, jc, &iter, jIter);
}
return rc;
}
JDECLFts(void,xPhraseNext)(JENV_JSELF,jobject jCtx, jobject jIter,
jobject jOutCol, jobject jOutOff){
Fts5ExtDecl;
JNIEnvCacheLine * const jc = S3Global_env_cache(env);
Fts5PhraseIter iter;
int iCol = 0, iOff = 0;
if(!jc->jPhraseIter.klazz) return /*SQLITE_MISUSE*/;
s3jni_phraseIter_JToN(env, jc, jIter, &iter);
fext->xPhraseNext(PtrGet_Fts5Context(jCtx),
&iter, &iCol, &iOff);
setOutputInt32(env, jOutCol, iCol);
setOutputInt32(env, jOutOff, iOff);
s3jni_phraseIter_NToJ(env, jc, &iter, jIter);
}
JDECLFts(void,xPhraseNextColumn)(JENV_JSELF,jobject jCtx, jobject jIter,
jobject jOutCol){
Fts5ExtDecl;
JNIEnvCacheLine * const jc = S3Global_env_cache(env);
Fts5PhraseIter iter;
int iCol = 0;
if(!jc->jPhraseIter.klazz) return /*SQLITE_MISUSE*/;
s3jni_phraseIter_JToN(env, jc, jIter, &iter);
fext->xPhraseNextColumn(PtrGet_Fts5Context(jCtx), &iter, &iCol);
setOutputInt32(env, jOutCol, iCol);
s3jni_phraseIter_NToJ(env, jc, &iter, jIter);
}
JDECLFts(jint,xPhraseSize)(JENV_JSELF,jobject jCtx, jint iPhrase){
Fts5ExtDecl;
return (jint)fext->xPhraseSize(PtrGet_Fts5Context(jCtx), (int)iPhrase);
}
/**
State for use with xQueryPhrase() and xTokenize().
*/
struct s3jni_xQueryPhraseState {
JNIEnv *env;
Fts5ExtensionApi const * fext;
JNIEnvCacheLine const * jc;
jmethodID midCallback;
jobject jCallback;
jobject jFcx;
/* State for xTokenize() */
struct {
const char * zPrev;
int nPrev;
jbyteArray jba;
} tok;
};
static int s3jni_xQueryPhrase(const Fts5ExtensionApi *xapi,
Fts5Context * pFcx, void *pData){
/* TODO: confirm that the Fts5Context passed to this function is
guaranteed to be the same one passed to xQueryPhrase(). If it's
not, we'll have to create a new wrapper object on every call. */
struct s3jni_xQueryPhraseState const * s = pData;
JNIEnv * const env = s->env;
int rc = (int)(*env)->CallIntMethod(env, s->jCallback, s->midCallback,
s->jc->jFtsExt, s->jFcx);
IFTHREW{
EXCEPTION_WARN_CALLBACK_THREW("xQueryPhrase callback");
EXCEPTION_CLEAR;
rc = SQLITE_ERROR;
}
return rc;
}
JDECLFts(jint,xQueryPhrase)(JENV_JSELF,jobject jFcx, jint iPhrase,
jobject jCallback){
Fts5ExtDecl;
JNIEnvCacheLine * const jc = S3Global_env_cache(env);
struct s3jni_xQueryPhraseState s;
jclass klazz = jCallback ? (*env)->GetObjectClass(env, jCallback) : NULL;
if( !klazz ){
EXCEPTION_CLEAR;
return SQLITE_MISUSE;
}
s.env = env;
s.jc = jc;
s.jCallback = jCallback;
s.jFcx = jFcx;
s.fext = fext;
s.midCallback = (*env)->GetMethodID(env, klazz, "xCallback",
"(Lorg.sqlite.jni.Fts5ExtensionApi;"
"Lorg.sqlite.jni.Fts5Context;)I");
EXCEPTION_IS_FATAL("Could not extract xQueryPhraseCallback.xCallback method.");
return (jint)fext->xQueryPhrase(PtrGet_Fts5Context(jFcx), iPhrase, &s,
s3jni_xQueryPhrase);
}
JDECLFts(jint,xRowCount)(JENV_JSELF,jobject jCtx, jobject jOut64){
Fts5ExtDecl;
sqlite3_int64 nOut = 0;
@ -2757,6 +2954,98 @@ JDECLFts(jlong,xRowid)(JENV_JSELF,jobject jCtx){
return (jlong)fext->xRowid(PtrGet_Fts5Context(jCtx));
}
JDECLFts(int,xSetAuxdata)(JENV_JSELF,jobject jCtx, jobject jAux){
Fts5ExtDecl;
int rc;
s3jni_fts5AuxData * pAux;
pAux = sqlite3_malloc(sizeof(*pAux));
if(!pAux){
if(jAux){
// Emulate how xSetAuxdata() behaves when it cannot alloc
// its auxdata wrapper.
s3jni_call_xDestroy(env, jAux, 0);
}
return SQLITE_NOMEM;
}
pAux->env = env;
pAux->jObj = REF_G(jAux);
rc = fext->xSetAuxdata(PtrGet_Fts5Context(jCtx), pAux,
s3jni_fts5AuxData_xDestroy);
return rc;
}
/**
xToken() imp for xTokenize().
TODO: hold on to the byte array and avoid initializing
it if passed the same (z,nZ) as a previous call.
*/
static int s3jni_xTokenize_xToken(void *p, int tFlags, const char* z,
int nZ, int iStart, int iEnd){
int rc;
struct s3jni_xQueryPhraseState * const s = p;
JNIEnv * const env = s->env;
jbyteArray jba;
if( s->tok.zPrev == z && s->tok.nPrev == nZ ){
jba = s->tok.jba;
}else{
if(s->tok.jba){
UNREF_L(s->tok.jba);
}
s->tok.zPrev = z;
s->tok.nPrev = nZ;
s->tok.jba = (*env)->NewByteArray(env, (jint)nZ);
if( !s->tok.jba ) return SQLITE_NOMEM;
jba = s->tok.jba;
(*env)->SetByteArrayRegion(env, jba, 0, (jint)nZ, (const jbyte*)z);
}
rc = (int)(*env)->CallIntMethod(env, s->jCallback, s->midCallback,
(jint)tFlags, jba, (jint)iStart,
(jint)iEnd);
return rc;
}
JDECLFts(jint,xTokenize)(JENV_JSELF,jobject jFcx, jbyteArray jbaText,
jobject jCallback){
Fts5ExtDecl;
JNIEnvCacheLine * const jc = S3Global_env_cache(env);
struct s3jni_xQueryPhraseState s;
int rc;
jbyte * const pText = JBA_TOC(jbaText);
jsize nText = (*env)->GetArrayLength(env, jbaText);
jclass const klazz = jCallback ? (*env)->GetObjectClass(env, jCallback) : NULL;
if( !klazz ){
EXCEPTION_CLEAR;
JBA_RELEASE(jbaText, pText);
return SQLITE_MISUSE;
}
memset(&s, 0, sizeof(s));
s.env = env;
s.jc = jc;
s.jCallback = jCallback;
s.jFcx = jFcx;
s.fext = fext;
s.midCallback = (*env)->GetMethodID(env, klazz, "xToken", "(I[BII)I");
IFTHREW {
EXCEPTION_REPORT;
EXCEPTION_CLEAR;
JBA_RELEASE(jbaText, pText);
return SQLITE_ERROR;
}
s.tok.jba = REF_L(jbaText);
s.tok.zPrev = (const char *)pText;
s.tok.nPrev = (int)nText;
rc = fext->xTokenize(PtrGet_Fts5Context(jFcx),
(const char *)pText, (int)nText,
&s, s3jni_xTokenize_xToken);
if(s.tok.jba){
assert( s.tok.zPrev );
UNREF_L(s.tok.jba);
}
JBA_RELEASE(jbaText, pText);
return (jint)rc;
}
#endif /* SQLITE_ENABLE_FTS5 */
////////////////////////////////////////////////////////////////////////

View File

@ -1664,6 +1664,14 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xColumnText
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xColumnTotalSize
(JNIEnv *, jobject, jobject, jint, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xGetAuxdata
* Signature: (Lorg/sqlite/jni/Fts5Context;Z)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xGetAuxdata
(JNIEnv *, jobject, jobject, jboolean);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xInst
@ -1688,6 +1696,38 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xInstCount
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseCount
(JNIEnv *, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseFirst
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseFirst
(JNIEnv *, jobject, jobject, jint, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseFirstColumn
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseFirstColumn
(JNIEnv *, jobject, jobject, jint, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseNext
* Signature: (Lorg/sqlite/jni/Fts5Context;Lorg/sqlite/jni/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseNext
(JNIEnv *, jobject, jobject, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseNextColumn
* Signature: (Lorg/sqlite/jni/Fts5Context;Lorg/sqlite/jni/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseNextColumn
(JNIEnv *, jobject, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseSize
@ -1696,6 +1736,14 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseCount
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseSize
(JNIEnv *, jobject, jobject, jint);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xQueryPhrase
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/Fts5ExtensionApi/xQueryPhraseCallback;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xQueryPhrase
(JNIEnv *, jobject, jobject, jint, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xRowCount
@ -1712,6 +1760,22 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xRowCount
JNIEXPORT jlong JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xRowid
(JNIEnv *, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xSetAuxdata
* Signature: (Lorg/sqlite/jni/Fts5Context;Ljava/lang/Object;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xSetAuxdata
(JNIEnv *, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xTokenize
* Signature: (Lorg/sqlite/jni/Fts5Context;[BLorg/sqlite/jni/Fts5ExtensionApi/xTokenizeCallback;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xTokenize
(JNIEnv *, jobject, jobject, jbyteArray, jobject);
#ifdef __cplusplus
}
#endif

View File

@ -15,6 +15,8 @@ package org.sqlite.jni;
import java.nio.charset.StandardCharsets;
/**
COMPLETELY UNTESTED.
FAR FROM COMPLETE and the feasibility of binding this to Java
is still undetermined. This might be removed.
@ -25,6 +27,17 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
private Fts5ExtensionApi(){}
private int iVersion;
//! Callback type for use with xTokenize().
public static interface xTokenizeCallback {
int xToken(int tFlags, byte txt[], int iStart, int iEnd);
}
public static interface xQueryPhraseCallback {
int xCallback(Fts5ExtensionApi fapi, Fts5Context cx);
}
/**
Returns a singleton instance of this class.
*/
public static native Fts5ExtensionApi getInstance();
public native int xColumnCount(@NotNull Fts5Context fcx);
@ -43,6 +56,7 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
}
public native int xColumnTotalSize(@NotNull Fts5Context fcx, int iCol,
@NotNull OutputPointer.Int64 pnToken);
public native Object xGetAuxdata(@NotNull Fts5Context cx, boolean clearIt);
public native int xInst(@NotNull Fts5Context cx, int iIdx,
@NotNull OutputPointer.Int32 piPhrase,
@NotNull OutputPointer.Int32 piCol,
@ -50,30 +64,42 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
public native int xInstCount(@NotNull Fts5Context fcx,
@NotNull OutputPointer.Int32 pnInst);
public native int xPhraseCount(@NotNull Fts5Context fcx);
public native int xPhraseFirst(@NotNull Fts5Context cx, int iPhrase,
@NotNull Fts5PhraseIter iter,
@NotNull OutputPointer.Int32 iCol,
@NotNull OutputPointer.Int32 iOff);
public native int xPhraseFirstColumn(@NotNull Fts5Context cx, int iPhrase,
@NotNull Fts5PhraseIter iter,
@NotNull OutputPointer.Int32 iCol);
public native void xPhraseNext(@NotNull Fts5Context cx,
@NotNull Fts5PhraseIter iter,
@NotNull OutputPointer.Int32 iCol,
@NotNull OutputPointer.Int32 iOff);
public native void xPhraseNextColumn(@NotNull Fts5Context cx,
@NotNull Fts5PhraseIter iter,
@NotNull OutputPointer.Int32 iCol);
public native int xPhraseSize(@NotNull Fts5Context fcx, int iPhrase);
public native int xQueryPhrase(@NotNull Fts5Context cx, int iPhrase,
@NotNull xQueryPhraseCallback callback);
public native int xRowCount(@NotNull Fts5Context fcx,
@NotNull OutputPointer.Int64 nRow);
public native long xRowid(@NotNull Fts5Context cx);
/**************************************************************
/* Note that this impl lacks the xDelete() callback
argument. Instead, if pAux has an xDestroy() method, it is called
if the FTS5 API finalizes the aux state (including if allocation
of storage for the auxdata fails). Any reference to pAux held by
the JNI layer will be relinquished regardless of whther pAux has
an xDestroy() method. */
public native int xSetAuxdata(@NotNull Fts5Context cx, @Nullable Object pAux);
public native int xTokenize(@NotNull Fts5Context cx, @NotNull byte pText[],
@NotNull xTokenizeCallback callback);
/**************************************************************
void *(*xUserData)(Fts5Context*);
int (*xTokenize)(Fts5Context*,
const char *pText, int nText,
void *pCtx,
int (*xToken)(void*, int, const char*, int, int, int)
);
int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
);
int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
void *(*xGetAuxdata)(Fts5Context*, int bClear);
int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
**************************************************************/
}

View File

@ -0,0 +1,24 @@
/*
** 2023-08-04
**
** 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 JNI bindings for the sqlite3 C API.
*/
package org.sqlite.jni;
/**
A wrapper for C-level Fts5PhraseIter. They are only modified and
inspected by native-level code.
*/
public final class Fts5PhraseIter extends NativePointerHolder<Fts5PhraseIter> {
//! Updated and used only by native code.
private long a;
private long b;
}

View File

@ -1,5 +1,5 @@
C More\swork\son\sthe\sJNI\sbinding\sof\sfts5\scustomization\s(still\sa\slong\sways\sto\sgo).
D 2023-08-04T15:38:59.701
C Bind\sthe\sremaining\sFts5ExtensionApi\smethods\sto\sJNI,\snoting\sthat\sall\sare\scompletely\suntested\sbecause\sthe\shigher-level\sbits\sneeded\sto\sdo\sso\sare\sstill\smissing.
D 2023-08-05T00:40:28.312
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -232,15 +232,16 @@ F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
F ext/jni/GNUmakefile 83f8f1c5a76714b3034815631587336c9b5bb345a325bde118a6909e2f18b16f
F ext/jni/README.md 6ff7e1f4100dee980434a6ee37a199b653bceec62e233a6e2ccde6e7ae0c58bf
F ext/jni/src/c/sqlite3-jni.c e8bbc4773c06b25696efb7a714736b1598fd70234a536ba6e4c27dd698ecd087
F ext/jni/src/c/sqlite3-jni.h c67b4299e349c364b2f13787d629b59c1690c9d2834d3daa6913eb8609bee9a7
F ext/jni/src/c/sqlite3-jni.c c4255b2371189c347734883a80bf9adf656e42f9fdd2c6507599da6b373d244a
F ext/jni/src/c/sqlite3-jni.h 0dc116afb5b310c18052666e7047a9dc0085684aeaa9a88fd5449eaba0a04969
F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c
F ext/jni/src/org/sqlite/jni/Collation.java 8dffbb00938007ad0967b2ab424d3c908413af1bbd3d212b9c9899910f1218d1
F ext/jni/src/org/sqlite/jni/CollationNeeded.java ebc7cd96d46a70daa76016a308e80f70a3f21d3282787c8d139aa840fdcb1bd7
F ext/jni/src/org/sqlite/jni/CommitHook.java 87c6a8e5138c61a8eeff018fe16d23f29219150239746032687f245938baca1a
F ext/jni/src/org/sqlite/jni/Fts5Context.java 0a5a02047a6a1dd3e4a38b0e542a8dd2de365033ba30e6ae019a676305959890
F ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java 46fe8ebff4c42cc10259026cf37f77ebe82ba38fa961b49c012c0def3eb97925
F ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java c041113c13b3a256f9692180ff2e9389c77236d63ab8a96ed204508f1b6ec52b
F ext/jni/src/org/sqlite/jni/Fts5Function.java 65cde7151e441fee012250a5e03277de7babcd11a0c308a832b7940574259bcc
F ext/jni/src/org/sqlite/jni/Fts5PhraseIter.java 6642beda341c0b1b46af4e2d7f6f9ab03a7aede43277b2c92859176d6bce3be9
F ext/jni/src/org/sqlite/jni/NativePointerHolder.java 9c5d901cce4f7e57c3d623f4e2476f9f79a8eed6e51b2a603f37866018e040ee
F ext/jni/src/org/sqlite/jni/OutputPointer.java d37636dd3b82097792dae9c8c255b135153845407cdbc6689f15c475850d6c93
F ext/jni/src/org/sqlite/jni/ProgressHandler.java 5979450e996416d28543f1d42634d308439565a99332a8bd84e424af667116cc
@ -2076,8 +2077,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 63e7bbe3d5fcfb531f9d7fa88398c1191570e69b5d11adcb9c5e64b8345b4e6c
R c11e6bcae8d215f11cf9225821fd3c49
P 1a246fd21657f5bb13eeacc4059894ab787ea9a3c45bd9bdd3030a66643d2fef
R 74dda0d2a3a66f022caa42d0cdc0fd8a
U stephan
Z 8cab7db6e5db86ab7543a142f8069f36
Z d7f1bdf30cf8c990e32f56e6e1648277
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
1a246fd21657f5bb13eeacc4059894ab787ea9a3c45bd9bdd3030a66643d2fef
23383c1dfd240ce47f504dd5c3402c9a31f166fbde5bb72d91309a5655074b33