Index: third_party/sqlite/src/ext/fts5/fts5_tcl.c |
diff --git a/third_party/sqlite/src/ext/fts5/fts5_tcl.c b/third_party/sqlite/src/ext/fts5/fts5_tcl.c |
index b470c557d32890a0adfdeb02c596e98e63ef6a73..5fe690f6b7a9afda9534ad09160d978aa64eef7d 100644 |
--- a/third_party/sqlite/src/ext/fts5/fts5_tcl.c |
+++ b/third_party/sqlite/src/ext/fts5/fts5_tcl.c |
@@ -14,7 +14,14 @@ |
#ifdef SQLITE_TEST |
-#include <tcl.h> |
+#if defined(INCLUDE_SQLITE_TCL_H) |
+# include "sqlite_tcl.h" |
+#else |
+# include "tcl.h" |
+# ifndef SQLITE_TCLAPI |
+# define SQLITE_TCLAPI |
+# endif |
+#endif |
#ifdef SQLITE_ENABLE_FTS5 |
@@ -23,7 +30,8 @@ |
#include <assert.h> |
extern int sqlite3_fts5_may_be_corrupt; |
-extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *); |
+extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*); |
+extern int sqlite3Fts5TestRegisterTok(sqlite3*, fts5_api*); |
/************************************************************************* |
** This is a copy of the first part of the SqliteDb structure in |
@@ -77,7 +85,7 @@ static int f5tResultToErrorCode(const char *zRes){ |
return SQLITE_ERROR; |
} |
-static int f5tDbAndApi( |
+static int SQLITE_TCLAPI f5tDbAndApi( |
Tcl_Interp *interp, |
Tcl_Obj *pObj, |
sqlite3 **ppDb, |
@@ -163,7 +171,7 @@ static int xTokenizeCb( |
return rc; |
} |
-static int xF5tApi(void*, Tcl_Interp*, int, Tcl_Obj *CONST []); |
+static int SQLITE_TCLAPI xF5tApi(void*, Tcl_Interp*, int, Tcl_Obj *CONST []); |
static int xQueryPhraseCb( |
const Fts5ExtensionApi *pApi, |
@@ -208,7 +216,7 @@ static void xSetAuxdataDestructor(void *p){ |
** |
** Description... |
*/ |
-static int xF5tApi( |
+static int SQLITE_TCLAPI xF5tApi( |
void * clientData, |
Tcl_Interp *interp, |
int objc, |
@@ -235,6 +243,8 @@ static int xF5tApi( |
{ "xGetAuxdata", 1, "CLEAR" }, /* 13 */ |
{ "xSetAuxdataInt", 1, "INTEGER" }, /* 14 */ |
{ "xGetAuxdataInt", 1, "CLEAR" }, /* 15 */ |
+ { "xPhraseForeach", 4, "IPHRASE COLVAR OFFVAR SCRIPT" }, /* 16 */ |
+ { "xPhraseColumnForeach", 3, "IPHRASE COLVAR SCRIPT" }, /* 17 */ |
{ 0, 0, 0} |
}; |
@@ -431,6 +441,66 @@ static int xF5tApi( |
break; |
} |
+ CASE(16, "xPhraseForeach") { |
+ int iPhrase; |
+ int iCol; |
+ int iOff; |
+ const char *zColvar; |
+ const char *zOffvar; |
+ Tcl_Obj *pScript = objv[5]; |
+ Fts5PhraseIter iter; |
+ |
+ if( Tcl_GetIntFromObj(interp, objv[2], &iPhrase) ) return TCL_ERROR; |
+ zColvar = Tcl_GetString(objv[3]); |
+ zOffvar = Tcl_GetString(objv[4]); |
+ |
+ rc = p->pApi->xPhraseFirst(p->pFts, iPhrase, &iter, &iCol, &iOff); |
+ if( rc!=SQLITE_OK ){ |
+ Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
+ return TCL_ERROR; |
+ } |
+ for( ;iCol>=0; p->pApi->xPhraseNext(p->pFts, &iter, &iCol, &iOff) ){ |
+ Tcl_SetVar2Ex(interp, zColvar, 0, Tcl_NewIntObj(iCol), 0); |
+ Tcl_SetVar2Ex(interp, zOffvar, 0, Tcl_NewIntObj(iOff), 0); |
+ rc = Tcl_EvalObjEx(interp, pScript, 0); |
+ if( rc==TCL_CONTINUE ) rc = TCL_OK; |
+ if( rc!=TCL_OK ){ |
+ if( rc==TCL_BREAK ) rc = TCL_OK; |
+ break; |
+ } |
+ } |
+ |
+ break; |
+ } |
+ |
+ CASE(17, "xPhraseColumnForeach") { |
+ int iPhrase; |
+ int iCol; |
+ const char *zColvar; |
+ Tcl_Obj *pScript = objv[4]; |
+ Fts5PhraseIter iter; |
+ |
+ if( Tcl_GetIntFromObj(interp, objv[2], &iPhrase) ) return TCL_ERROR; |
+ zColvar = Tcl_GetString(objv[3]); |
+ |
+ rc = p->pApi->xPhraseFirstColumn(p->pFts, iPhrase, &iter, &iCol); |
+ if( rc!=SQLITE_OK ){ |
+ Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); |
+ return TCL_ERROR; |
+ } |
+ for( ; iCol>=0; p->pApi->xPhraseNextColumn(p->pFts, &iter, &iCol)){ |
+ Tcl_SetVar2Ex(interp, zColvar, 0, Tcl_NewIntObj(iCol), 0); |
+ rc = Tcl_EvalObjEx(interp, pScript, 0); |
+ if( rc==TCL_CONTINUE ) rc = TCL_OK; |
+ if( rc!=TCL_OK ){ |
+ if( rc==TCL_BREAK ) rc = TCL_OK; |
+ break; |
+ } |
+ } |
+ |
+ break; |
+ } |
+ |
default: |
assert( 0 ); |
break; |
@@ -539,7 +609,7 @@ static void xF5tDestroy(void *pCtx){ |
** |
** Description... |
*/ |
-static int f5tCreateFunction( |
+static int SQLITE_TCLAPI f5tCreateFunction( |
void * clientData, |
Tcl_Interp *interp, |
int objc, |
@@ -609,7 +679,7 @@ static int xTokenizeCb2( |
** |
** Description... |
*/ |
-static int f5tTokenize( |
+static int SQLITE_TCLAPI f5tTokenize( |
void * clientData, |
Tcl_Interp *interp, |
int objc, |
@@ -815,7 +885,7 @@ static int f5tTokenizerTokenize( |
/* |
** sqlite3_fts5_token ?-colocated? TEXT START END |
*/ |
-static int f5tTokenizerReturn( |
+static int SQLITE_TCLAPI f5tTokenizerReturn( |
void * clientData, |
Tcl_Interp *interp, |
int objc, |
@@ -886,7 +956,7 @@ static void f5tDelTokenizer(void *pCtx){ |
** SCRIPT2 should invoke the [sqlite3_fts5_token] command once for each |
** token within the tokenized text. |
*/ |
-static int f5tCreateTokenizer( |
+static int SQLITE_TCLAPI f5tCreateTokenizer( |
ClientData clientData, |
Tcl_Interp *interp, |
int objc, |
@@ -929,7 +999,7 @@ static int f5tCreateTokenizer( |
return TCL_OK; |
} |
-static void xF5tFree(ClientData clientData){ |
+static void SQLITE_TCLAPI xF5tFree(ClientData clientData){ |
ckfree(clientData); |
} |
@@ -938,7 +1008,7 @@ static void xF5tFree(ClientData clientData){ |
** |
** Set or clear the global "may-be-corrupt" flag. Return the old value. |
*/ |
-static int f5tMayBeCorrupt( |
+static int SQLITE_TCLAPI f5tMayBeCorrupt( |
void * clientData, |
Tcl_Interp *interp, |
int objc, |
@@ -970,7 +1040,7 @@ static unsigned int f5t_fts5HashKey(int nSlot, const char *p, int n){ |
return (h % nSlot); |
} |
-static int f5tTokenHash( |
+static int SQLITE_TCLAPI f5tTokenHash( |
void * clientData, |
Tcl_Interp *interp, |
int objc, |
@@ -995,7 +1065,7 @@ static int f5tTokenHash( |
return TCL_OK; |
} |
-static int f5tRegisterMatchinfo( |
+static int SQLITE_TCLAPI f5tRegisterMatchinfo( |
void * clientData, |
Tcl_Interp *interp, |
int objc, |
@@ -1020,6 +1090,32 @@ static int f5tRegisterMatchinfo( |
return TCL_OK; |
} |
+static int SQLITE_TCLAPI f5tRegisterTok( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ int rc; |
+ sqlite3 *db = 0; |
+ fts5_api *pApi = 0; |
+ |
+ if( objc!=2 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
+ return TCL_ERROR; |
+ } |
+ if( f5tDbAndApi(interp, objv[1], &db, &pApi) ){ |
+ return TCL_ERROR; |
+ } |
+ |
+ rc = sqlite3Fts5TestRegisterTok(db, pApi); |
+ if( rc!=SQLITE_OK ){ |
+ Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE); |
+ return TCL_ERROR; |
+ } |
+ return TCL_OK; |
+} |
+ |
/* |
** Entry point. |
*/ |
@@ -1035,7 +1131,8 @@ int Fts5tcl_Init(Tcl_Interp *interp){ |
{ "sqlite3_fts5_create_function", f5tCreateFunction, 0 }, |
{ "sqlite3_fts5_may_be_corrupt", f5tMayBeCorrupt, 0 }, |
{ "sqlite3_fts5_token_hash", f5tTokenHash, 0 }, |
- { "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 } |
+ { "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 }, |
+ { "sqlite3_fts5_register_fts5tokenize", f5tRegisterTok, 0 } |
}; |
int i; |
F5tTokenizerContext *pContext; |