diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 2426c1dc51..5214296e35 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -14,26 +14,26 @@ #include "fts5Int.h" #include -typedef struct SnippetPhrase SnippetPhrase; -typedef struct SnippetIter SnippetIter; +typedef struct SnipPhrase SnipPhrase; +typedef struct SnipIter SnipIter; typedef struct SnippetCtx SnippetCtx; -struct SnippetPhrase { +struct SnipPhrase { u64 mask; /* Current mask */ int nToken; /* Tokens in this phrase */ int i; /* Current offset in phrase poslist */ i64 iPos; /* Next position in phrase (-ve -> EOF) */ }; -struct SnippetIter { +struct SnipIter { i64 iLast; /* Last token position of current snippet */ int nScore; /* Score of current snippet */ const Fts5ExtensionApi *pApi; Fts5Context *pFts; - u64 szmask; /* Mask used to on SnippetPhrase.mask */ + u64 szmask; /* Mask used to on SnipPhrase.mask */ int nPhrase; /* Number of phrases */ - SnippetPhrase aPhrase[0]; /* Array of size nPhrase */ + SnipPhrase aPhrase[0]; /* Array of size nPhrase */ }; struct SnippetCtx { @@ -71,13 +71,13 @@ static int fts5SnippetCallback( /* ** Set pIter->nScore to the score for the current entry. */ -static void fts5SnippetCalculateScore(SnippetIter *pIter){ +static void fts5SnippetCalculateScore(SnipIter *pIter){ int i; int nScore = 0; assert( pIter->iLast>=0 ); for(i=0; inPhrase; i++){ - SnippetPhrase *p = &pIter->aPhrase[i]; + SnipPhrase *p = &pIter->aPhrase[i]; u64 mask = p->mask; if( mask ){ u64 j; @@ -94,21 +94,21 @@ static void fts5SnippetCalculateScore(SnippetIter *pIter){ /* ** Allocate a new snippet iter. */ -static int fts5SnippetIterNew( +static int fts5SnipIterNew( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ int nToken, /* Number of tokens in snippets */ - SnippetIter **ppIter /* OUT: New object */ + SnipIter **ppIter /* OUT: New object */ ){ int i; /* Counter variable */ - SnippetIter *pIter; /* New iterator object */ + SnipIter *pIter; /* New iterator object */ int nByte; /* Bytes of space to allocate */ int nPhrase; /* Number of phrases in query */ *ppIter = 0; nPhrase = pApi->xPhraseCount(pFts); - nByte = sizeof(SnippetIter) + nPhrase * sizeof(SnippetPhrase); - pIter = (SnippetIter*)sqlite3_malloc(nByte); + nByte = sizeof(SnipIter) + nPhrase * sizeof(SnipPhrase); + pIter = (SnipIter*)sqlite3_malloc(nByte); if( pIter==0 ) return SQLITE_NOMEM; memset(pIter, 0, nByte); @@ -129,16 +129,16 @@ static int fts5SnippetIterNew( /* ** Set the iterator to point to the first candidate snippet. */ -static void fts5SnippetIterFirst(SnippetIter *pIter){ +static void fts5SnipIterFirst(SnipIter *pIter){ const Fts5ExtensionApi *pApi = pIter->pApi; Fts5Context *pFts = pIter->pFts; int i; /* Used to iterate through phrases */ - SnippetPhrase *pMin = 0; /* Phrase with first match */ + SnipPhrase *pMin = 0; /* Phrase with first match */ - memset(pIter->aPhrase, 0, sizeof(SnippetPhrase) * pIter->nPhrase); + memset(pIter->aPhrase, 0, sizeof(SnipPhrase) * pIter->nPhrase); for(i=0; inPhrase; i++){ - SnippetPhrase *p = &pIter->aPhrase[i]; + SnipPhrase *p = &pIter->aPhrase[i]; p->nToken = pApi->xPhraseSize(pFts, i); pApi->xPoslist(pFts, i, &p->i, &p->iPos); if( p->iPos>=0 && (pMin==0 || p->iPosiPos) ){ @@ -156,26 +156,26 @@ static void fts5SnippetIterFirst(SnippetIter *pIter){ /* ** Advance the snippet iterator to the next candidate snippet. */ -static void fts5SnippetIterNext(SnippetIter *pIter){ +static void fts5SnipIterNext(SnipIter *pIter){ const Fts5ExtensionApi *pApi = pIter->pApi; Fts5Context *pFts = pIter->pFts; int nPhrase = pIter->nPhrase; int i; /* Used to iterate through phrases */ - SnippetPhrase *pMin = 0; + SnipPhrase *pMin = 0; for(i=0; iaPhrase[i]; + SnipPhrase *p = &pIter->aPhrase[i]; if( p->iPos>=0 && (pMin==0 || p->iPosiPos) ) pMin = p; } if( pMin==0 ){ - /* pMin==0 indicates that the SnippetIter is at EOF. */ + /* pMin==0 indicates that the SnipIter is at EOF. */ pIter->iLast = -1; }else{ i64 nShift = pMin->iPos - pIter->iLast; assert( nShift>=0 ); for(i=0; iaPhrase[i]; + SnipPhrase *p = &pIter->aPhrase[i]; if( nShift>=63 ){ p->mask = 0; }else{ @@ -191,7 +191,7 @@ static void fts5SnippetIterNext(SnippetIter *pIter){ } } -static void fts5SnippetIterFree(SnippetIter *pIter){ +static void fts5SnipIterFree(SnipIter *pIter){ if( pIter ){ sqlite3_free(pIter); } @@ -200,7 +200,7 @@ static void fts5SnippetIterFree(SnippetIter *pIter){ static int fts5SnippetText( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ - SnippetIter *pIter, /* Snippet to write to buffer */ + SnipIter *pIter, /* Snippet to write to buffer */ int nToken, /* Size of desired snippet in tokens */ const char *zStart, const char *zFinal, @@ -299,7 +299,7 @@ static int fts5SnippetText( /* Check if this is the first token of any phrase match. */ int ip; for(ip=0; ipnPhrase; ip++){ - SnippetPhrase *pPhrase = &pIter->aPhrase[ip]; + SnipPhrase *pPhrase = &pIter->aPhrase[ip]; u64 m = (1 << (iLast - i - pPhrase->nToken + 1)); if( i<=iLast && (pPhrase->mask & m) ){ @@ -368,7 +368,7 @@ static void fts5SnippetFunction( int nToken = -15; int nAbs; int rc; - SnippetIter *pIter = 0; + SnipIter *pIter = 0; if( nVal>=1 ) zStart = (const char*)sqlite3_value_text(apVal[0]); if( nVal>=2 ) zFinal = (const char*)sqlite3_value_text(apVal[1]); @@ -379,20 +379,20 @@ static void fts5SnippetFunction( } nAbs = nToken * (nToken<0 ? -1 : 1); - rc = fts5SnippetIterNew(pApi, pFts, nAbs, &pIter); + rc = fts5SnipIterNew(pApi, pFts, nAbs, &pIter); if( rc==SQLITE_OK ){ Fts5Buffer buf; /* Result buffer */ int nBestScore = 0; /* Score of best snippet found */ - for(fts5SnippetIterFirst(pIter); + for(fts5SnipIterFirst(pIter); pIter->iLast>=0; - fts5SnippetIterNext(pIter) + fts5SnipIterNext(pIter) ){ if( pIter->nScore>nBestScore ) nBestScore = pIter->nScore; } - for(fts5SnippetIterFirst(pIter); + for(fts5SnipIterFirst(pIter); pIter->iLast>=0; - fts5SnippetIterNext(pIter) + fts5SnipIterNext(pIter) ){ if( pIter->nScore==nBestScore ) break; } @@ -405,7 +405,7 @@ static void fts5SnippetFunction( sqlite3_free(buf.p); } - fts5SnippetIterFree(pIter); + fts5SnipIterFree(pIter); if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pCtx, rc); } diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index bbcbc5e0e5..5bed69def3 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -113,7 +113,7 @@ static char *fts5Strdup(const char *z){ return sqlite3_mprintf("%s", z); } -void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module**); +void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**); /* ** Allocate an instance of the default tokenizer ("simple") at @@ -121,7 +121,7 @@ void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module**); ** code if an error occurs. */ static int fts5ConfigDefaultTokenizer(Fts5Config *pConfig){ - sqlite3_tokenizer_module *pMod; /* Tokenizer module "simple" */ + const sqlite3_tokenizer_module *pMod; /* Tokenizer module "simple" */ sqlite3_tokenizer *pTokenizer; /* Tokenizer instance */ int rc; /* Return code */ diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index ab9b307bc2..2fd7f63f76 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -997,7 +997,7 @@ i64 sqlite3Fts5ExprRowid(Fts5Expr *p){ ** It is the responsibility of the caller to eventually free the returned ** buffer using sqlite3_free(). If an OOM error occurs, NULL is returned. */ -static char *fts5Strdup(const char *pIn, int nIn){ +static char *fts5Strndup(const char *pIn, int nIn){ char *zRet = (char*)sqlite3_malloc(nIn+1); if( zRet ){ memcpy(zRet, pIn, nIn); @@ -1007,7 +1007,7 @@ static char *fts5Strdup(const char *pIn, int nIn){ } static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){ - *pz = fts5Strdup(pToken->p, pToken->n); + *pz = fts5Strndup(pToken->p, pToken->n); if( *pz==0 ) return SQLITE_NOMEM; return SQLITE_OK; } @@ -1115,7 +1115,7 @@ static int fts5ParseTokenize( pTerm = &pPhrase->aTerm[pPhrase->nTerm++]; memset(pTerm, 0, sizeof(Fts5ExprTerm)); - pTerm->zTerm = fts5Strdup(pToken, nToken); + pTerm->zTerm = fts5Strndup(pToken, nToken); return pTerm->zTerm ? SQLITE_OK : SQLITE_NOMEM; } diff --git a/main.mk b/main.mk index a1582fb6dc..1a75c39827 100644 --- a/main.mk +++ b/main.mk @@ -224,6 +224,18 @@ SRC += \ $(TOP)/ext/rtree/rtree.h \ $(TOP)/ext/rtree/rtree.c +SRC += \ + $(TOP)/ext/fts5/fts5.h \ + $(TOP)/ext/fts5/fts5Int.h \ + $(TOP)/ext/fts5/fts5_aux.c \ + $(TOP)/ext/fts5/fts5_buffer.c \ + $(TOP)/ext/fts5/fts5.c \ + $(TOP)/ext/fts5/fts5_config.c \ + $(TOP)/ext/fts5/fts5_expr.c \ + $(TOP)/ext/fts5/fts5_index.c \ + fts5parse.c \ + $(TOP)/ext/fts5/fts5_storage.c + # Generated source code files # @@ -684,6 +696,9 @@ wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.o $(TCC) -I. -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB) +loadfts: $(TOP)/tool/loadfts.c libsqlite3.a + $(TCC) $(TOP)/tool/loadfts.c libsqlite3.a -o loadfts $(THREADLIB) + # This target will fail if the SQLite amalgamation contains any exported # symbols that do not begin with "sqlite3_". It is run as part of the # releasetest.tcl script. diff --git a/manifest b/manifest index 84cd1f32f8..36de4c8844 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sand\sfixes\sfor\sbm25()\sfunction. -D 2014-07-26T18:38:51.294 +C Add\sthe\s"loadfts"\sprogram,\sfor\sperformance\stesting\sthe\sloading\sof\sdata\sinto\sfts3/fts4/fts5\stables. +D 2014-07-28T20:14:02.001 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in b03432313a3aad96c706f8164fb9f5307eaf19f5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -106,10 +106,10 @@ F ext/fts3/unicode/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368 F ext/fts5/fts5.c 1496aff16dd9b0a013d14b6c8cf5b7df8c170abe F ext/fts5/fts5.h 8ace10d5b249a3baa983c79e7a1306d2a79cfd6a F ext/fts5/fts5Int.h 92fb9c4f759674ef569aebc338f363e167a8933c -F ext/fts5/fts5_aux.c 78adc5db0ff4d6834df220ba6b3caa351d98b971 +F ext/fts5/fts5_aux.c 243156c197384e17983d6a3ed149fa2270b5bb85 F ext/fts5/fts5_buffer.c 248c61ac9fec001602efc72a45704f3b8d367c00 -F ext/fts5/fts5_config.c 94f1b4cb4de6a7cd5780c14adb0198e289df8cef -F ext/fts5/fts5_expr.c 65c1918002f2ec1755e4c0c28bf007659409fbd8 +F ext/fts5/fts5_config.c 2138741013e189724b5d40ea7af0f48952a44916 +F ext/fts5/fts5_expr.c e426baa54b9473cb31b8d891d7d1b923bfb5d017 F ext/fts5/fts5_index.c 68d2d41b5c6d2f8838c3d6ebdc8b242718b8e997 F ext/fts5/fts5_storage.c 2866e7e1de9dc851756c3a9c76b6e1d75e0facb7 F ext/fts5/fts5parse.y 777da8e5819f75c217982c79c29d014c293acac9 @@ -156,7 +156,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk cffc02a30f1af82d35410674f70a0286587add81 +F main.mk 8118631727a27fa88eb38a07ac3b86ecb86e9eb0 F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -1158,6 +1158,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 3ff0fec22f92dfb54e62eeb48772eddffdbeb0d6 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc +F tool/loadfts.c 3bdd46090112c84df44a4fbae740af3836108b3f F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670 @@ -1165,7 +1166,7 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 1712d3d71256ca1f297046619c89e77a4d7c8f6d -F tool/mksqlite3c.tcl ba274df71f5e6534b0a913c7c48eabfcbd0934b6 +F tool/mksqlite3c.tcl becaa9d5617dfe137e73dddda9dab8f58bc71e8c F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12 F tool/mksqlite3internalh.tcl b6514145a7d5321b47e64e19b8116cc44f973eb1 F tool/mkvsix.tcl 52a4c613707ac34ae9c226e5ccc69cb948556105 @@ -1196,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c4d50428ab97f77e6721c4f8d03eaaf3ea91f3eb -R 3301ccb2b839356242606883792ca77e +P 71d32f53e81921e43c933cc968cb1c18d83fe1e0 +R 378763b2640fc19d9f72a0522c9f77b1 U dan -Z 456b4a2f1abc554b124e25c35490489e +Z 3cf4ed481646bab9077300595c244e00 diff --git a/manifest.uuid b/manifest.uuid index 17caf8ac8b..2f2c34352f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71d32f53e81921e43c933cc968cb1c18d83fe1e0 \ No newline at end of file +770b9540c19ad1e3d24adff382332bf032065efd \ No newline at end of file diff --git a/tool/loadfts.c b/tool/loadfts.c new file mode 100644 index 0000000000..18bd355a4d --- /dev/null +++ b/tool/loadfts.c @@ -0,0 +1,204 @@ +/* +** 2013-06-10 +** +** 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. +** +************************************************************************* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "sqlite3.h" + +/* +** Implementation of the "readtext(X)" SQL function. The entire content +** of the file named X is read and returned as a TEXT value. It is assumed +** the file contains UTF-8 text. NULL is returned if the file does not +** exist or is unreadable. +*/ +static void readfileFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zName; + FILE *in; + long nIn; + void *pBuf; + + zName = (const char*)sqlite3_value_text(argv[0]); + if( zName==0 ) return; + in = fopen(zName, "rb"); + if( in==0 ) return; + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc( nIn ); + if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ + sqlite3_result_text(context, pBuf, nIn, sqlite3_free); + }else{ + sqlite3_free(pBuf); + } + fclose(in); +} + +/* +** Print usage text for this program and exit. +*/ +static void showHelp(const char *zArgv0){ + printf("\n" +"Usage: %s SWITCHES... DB\n" +"\n" +" This program opens the database named on the command line and attempts to\n" +" create an FTS table named \"fts\" with a single column. If successful, it\n" +" recursively traverses the directory named by the -dir option and inserts\n" +" the contents of each file into the fts table. All files are assumed to\n" +" contain UTF-8 text.\n" +"\n" +"Switches are:\n" +" -fts [345] FTS version to use (default=5)\n" +" -idx [01] Create a mapping from filename to rowid (default=0)\n" +" -dir Root of directory tree to load data from (default=.)\n" +, zArgv0 +); + exit(1); +} + +/* +** Exit with a message based on the argument and the current value of errno. +*/ +static void error_out(const char *zText){ + fprintf(stderr, "%s: %s\n", zText, strerror(errno)); + exit(-1); +} + +/* +** Exit with a message based on the first argument and the error message +** currently stored in database handle db. +*/ +static void sqlite_error_out(const char *zText, sqlite3 *db){ + fprintf(stderr, "%s: %s\n", zText, sqlite3_errmsg(db)); + exit(-1); +} + +/* +** Context object for visit_file(). +*/ +typedef struct VisitContext VisitContext; +struct VisitContext { + sqlite3 *db; /* Database handle */ + sqlite3_stmt *pInsert; /* INSERT INTO fts VALUES(readtext(:1)) */ +}; + +/* +** Callback used with traverse(). The first argument points to an object +** of type VisitContext. This function inserts the contents of the text +** file zPath into the FTS table. +*/ +void visit_file(void *pCtx, const char *zPath){ + int rc; + VisitContext *p = (VisitContext*)pCtx; + /* printf("%s\n", zPath); */ + sqlite3_bind_text(p->pInsert, 1, zPath, -1, SQLITE_STATIC); + sqlite3_step(p->pInsert); + rc = sqlite3_reset(p->pInsert); + if( rc!=SQLITE_OK ) sqlite_error_out("insert", p->db); +} + +/* +** Recursively traverse directory zDir. For each file that is not a +** directory, invoke the supplied callback with its path. +*/ +static void traverse( + const char *zDir, /* Directory to traverse */ + void *pCtx, /* First argument passed to callback */ + void (*xCallback)(void*, const char *zPath) +){ + DIR *d; + struct dirent *e; + + d = opendir(zDir); + if( d==0 ) error_out("opendir()"); + + for(e=readdir(d); e; e=readdir(d)){ + if( strcmp(e->d_name, ".")==0 || strcmp(e->d_name, "..")==0 ) continue; + char *zPath = sqlite3_mprintf("%s/%s", zDir, e->d_name); + if (e->d_type & DT_DIR) { + traverse(zPath, pCtx, xCallback); + }else{ + xCallback(pCtx, zPath); + } + sqlite3_free(zPath); + } + + closedir(d); +} + +int main(int argc, char **argv){ + int iFts = 5; /* Value of -fts option */ + int bMap = 0; /* True to create mapping table */ + const char *zDir = "."; /* Directory to scan */ + int i; + int rc; + sqlite3 *db; + char *zSql; + VisitContext sCtx; + + if( argc % 2 ) showHelp(argv[0]); + + for(i=1; i<(argc-1); i+=2){ + char *zOpt = argv[i]; + char *zArg = argv[i+1]; + if( strcmp(zOpt, "-fts")==0 ){ + iFts = atoi(zArg); + if( iFts!=3 && iFts!=4 && iFts!= 5) showHelp(argv[0]); + } + else if( strcmp(zOpt, "-idx")==0 ){ + bMap = atoi(zArg); + if( bMap!=0 && bMap!=1 ) showHelp(argv[0]); + } + else if( strcmp(zOpt, "-dir")==0 ){ + zDir = zArg; + } + } + + /* Open the database file */ + rc = sqlite3_open(argv[argc-1], &db); + if( rc!=SQLITE_OK ) sqlite_error_out("sqlite3_open()", db); + + rc = sqlite3_create_function(db, "readtext", 1, SQLITE_UTF8, 0, + readfileFunc, 0, 0); + if( rc!=SQLITE_OK ) sqlite_error_out("sqlite3_create_function()", db); + + /* Create the FTS table */ + zSql = sqlite3_mprintf("CREATE VIRTUAL TABLE fts USING fts%d(content)", iFts); + rc = sqlite3_exec(db, zSql, 0, 0, 0); + if( rc!=SQLITE_OK ) sqlite_error_out("sqlite3_exec(1)", db); + sqlite3_free(zSql); + + /* Compile the INSERT statement to write data to the FTS table. */ + memset(&sCtx, 0, sizeof(VisitContext)); + sCtx.db = db; + rc = sqlite3_prepare_v2(db, + "INSERT INTO fts VALUES(readtext(?))", -1, &sCtx.pInsert, 0 + ); + if( rc!=SQLITE_OK ) sqlite_error_out("sqlite3_prepare_v2(1)", db); + + /* Load all files in the directory hierarchy into the FTS table. */ + traverse(zDir, (void*)&sCtx, visit_file); + + /* Clean up and exit. */ + sqlite3_finalize(sCtx.pInsert); + sqlite3_close(db); + return 0; +} diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 64207727be..0d3120ce1a 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -97,6 +97,8 @@ foreach hdr { fts3Int.h fts3_hash.h fts3_tokenizer.h + fts5.h + fts5Int.h hash.h hwtime.h keywordhash.h @@ -328,6 +330,15 @@ foreach file { fts3_unicode.c fts3_unicode2.c + fts5_aux.c + fts5_buffer.c + fts5.c + fts5_config.c + fts5_expr.c + fts5_index.c + fts5parse.c + fts5_storage.c + rtree.c icu.c fts3_icu.c