Fossil SCM
Restrict indexed search according to the search flags. Fix the generation of the index for wiki pages. Fix db_multi_exec() so that it aborts with a sensible message following a syntax error.
Commit
780117d2239e21d64d2010e366864cb77ddc6418
Parent
786a3632a8e0d10…
2 files changed
+3
-2
+38
-11
M
src/db.c
+3
-2
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -547,12 +547,13 @@ | ||
| 547 | 547 | va_end(ap); |
| 548 | 548 | z = blob_str(&sql); |
| 549 | 549 | while( rc==SQLITE_OK && z[0] ){ |
| 550 | 550 | pStmt = 0; |
| 551 | 551 | rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd); |
| 552 | - if( rc!=SQLITE_OK ) break; | |
| 553 | - if( pStmt ){ | |
| 552 | + if( rc ){ | |
| 553 | + db_err("%s: {%s}", sqlite3_errmsg(g.db), z); | |
| 554 | + }else if( pStmt ){ | |
| 554 | 555 | db.nPrepare++; |
| 555 | 556 | while( sqlite3_step(pStmt)==SQLITE_ROW ){} |
| 556 | 557 | rc = sqlite3_finalize(pStmt); |
| 557 | 558 | if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z); |
| 558 | 559 | } |
| 559 | 560 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -547,12 +547,13 @@ | |
| 547 | va_end(ap); |
| 548 | z = blob_str(&sql); |
| 549 | while( rc==SQLITE_OK && z[0] ){ |
| 550 | pStmt = 0; |
| 551 | rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd); |
| 552 | if( rc!=SQLITE_OK ) break; |
| 553 | if( pStmt ){ |
| 554 | db.nPrepare++; |
| 555 | while( sqlite3_step(pStmt)==SQLITE_ROW ){} |
| 556 | rc = sqlite3_finalize(pStmt); |
| 557 | if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z); |
| 558 | } |
| 559 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -547,12 +547,13 @@ | |
| 547 | va_end(ap); |
| 548 | z = blob_str(&sql); |
| 549 | while( rc==SQLITE_OK && z[0] ){ |
| 550 | pStmt = 0; |
| 551 | rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd); |
| 552 | if( rc ){ |
| 553 | db_err("%s: {%s}", sqlite3_errmsg(g.db), z); |
| 554 | }else if( pStmt ){ |
| 555 | db.nPrepare++; |
| 556 | while( sqlite3_step(pStmt)==SQLITE_ROW ){} |
| 557 | rc = sqlite3_finalize(pStmt); |
| 558 | if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z); |
| 559 | } |
| 560 |
+38
-11
| --- src/search.c | ||
| +++ src/search.c | ||
| @@ -734,13 +734,16 @@ | ||
| 734 | 734 | */ |
| 735 | 735 | static void search_indexed( |
| 736 | 736 | const char *zPattern, /* The query pattern */ |
| 737 | 737 | unsigned int srchFlags /* What to search over */ |
| 738 | 738 | ){ |
| 739 | + Blob sql; | |
| 740 | + if( srchFlags==0 ) return; | |
| 739 | 741 | sqlite3_create_function(g.db, "rank", 1, SQLITE_UTF8, 0, |
| 740 | 742 | search_rank_sqlfunc, 0, 0); |
| 741 | - db_multi_exec( | |
| 743 | + blob_init(&sql, 0, 0); | |
| 744 | + blob_appendf(&sql, | |
| 742 | 745 | "INSERT INTO x(label,url,score,date,snip) " |
| 743 | 746 | " SELECT ftsdocs.label," |
| 744 | 747 | " ftsdocs.url," |
| 745 | 748 | " rank(matchinfo(ftsidx,'pcsx'))," |
| 746 | 749 | " datetime(ftsdocs.mtime)," |
| @@ -748,10 +751,28 @@ | ||
| 748 | 751 | " FROM ftsidx, ftsdocs" |
| 749 | 752 | " WHERE ftsidx MATCH %Q" |
| 750 | 753 | " AND ftsdocs.rowid=ftsidx.docid", |
| 751 | 754 | zPattern |
| 752 | 755 | ); |
| 756 | + if( srchFlags!=SRCH_ALL ){ | |
| 757 | + const char *zSep = " AND ("; | |
| 758 | + static const struct { unsigned m; char c; } aMask[] = { | |
| 759 | + { SRCH_CKIN, 'c' }, | |
| 760 | + { SRCH_DOC, 'd' }, | |
| 761 | + { SRCH_TKT, 't' }, | |
| 762 | + { SRCH_WIKI, 'w' }, | |
| 763 | + }; | |
| 764 | + int i; | |
| 765 | + for(i=0; i<ArraySize(aMask); i++){ | |
| 766 | + if( srchFlags & aMask[i].m ){ | |
| 767 | + blob_appendf(&sql, "%sftsdocs.type='%c'", zSep, aMask[i].c); | |
| 768 | + zSep = " OR "; | |
| 769 | + } | |
| 770 | + } | |
| 771 | + blob_append(&sql,")",1); | |
| 772 | + } | |
| 773 | + db_multi_exec("%s",blob_str(&sql)/*safe-for-%s*/); | |
| 753 | 774 | #if SEARCH_DEBUG_RANK |
| 754 | 775 | db_multi_exec("UPDATE x SET label=printf('%%s (score=%%s)',label,score)"); |
| 755 | 776 | #endif |
| 756 | 777 | } |
| 757 | 778 | |
| @@ -778,11 +799,11 @@ | ||
| 778 | 799 | "CREATE TEMP TABLE x(label,url,score,date,snip);" |
| 779 | 800 | ); |
| 780 | 801 | if( !search_index_exists() ){ |
| 781 | 802 | search_fullscan(zPattern, srchFlags); |
| 782 | 803 | }else{ |
| 783 | - search_update_index(); | |
| 804 | + search_update_index(srchFlags); | |
| 784 | 805 | search_indexed(zPattern, srchFlags); |
| 785 | 806 | } |
| 786 | 807 | db_prepare(&q, "SELECT url, snip, label" |
| 787 | 808 | " FROM x" |
| 788 | 809 | " ORDER BY score DESC, date DESC;"); |
| @@ -1221,38 +1242,44 @@ | ||
| 1221 | 1242 | */ |
| 1222 | 1243 | static void search_update_wiki_index(void){ |
| 1223 | 1244 | db_multi_exec( |
| 1224 | 1245 | "INSERT INTO ftsidx(docid,stext)" |
| 1225 | 1246 | " SELECT rowid, stext('w',rid,NULL) FROM ftsdocs" |
| 1226 | - " WHERE type='t' AND NOT idxed;" | |
| 1247 | + " WHERE type='w' AND NOT idxed;" | |
| 1227 | 1248 | ); |
| 1228 | 1249 | if( db_changes()==0 ) return; |
| 1229 | 1250 | db_multi_exec( |
| 1230 | 1251 | "REPLACE INTO ftsdocs(rowid,idxed,type,rid,name,label,url,mtime)" |
| 1231 | 1252 | " SELECT ftsdocs.rowid, 1, 'w', ftsdocs.rid, ftsdocs.name," |
| 1232 | - " 'Wiki: '||tsdocs.name)," | |
| 1253 | + " 'Wiki: '||ftsdocs.name," | |
| 1233 | 1254 | " '/wiki?name='||urlencode(ftsdocs.name)," |
| 1234 | 1255 | " tagxref.mtime" |
| 1235 | 1256 | " FROM ftsdocs, tagxref" |
| 1236 | - " WHERE ftsdocs.type='t' AND NOT ftsdocs.idxed" | |
| 1257 | + " WHERE ftsdocs.type='w' AND NOT ftsdocs.idxed" | |
| 1237 | 1258 | " AND tagxref.rid=ftsdocs.rid" |
| 1238 | 1259 | ); |
| 1239 | 1260 | } |
| 1240 | 1261 | |
| 1241 | 1262 | /* |
| 1242 | 1263 | ** Deal with all of the unindexed entries in the FTSDOCS table - that |
| 1243 | 1264 | ** is to say, all the entries with FTSDOCS.IDXED=0. Add them to the |
| 1244 | 1265 | ** index. |
| 1245 | 1266 | */ |
| 1246 | -void search_update_index(void){ | |
| 1267 | +void search_update_index(unsigned int srchFlags){ | |
| 1247 | 1268 | if( !search_index_exists() ) return; |
| 1248 | 1269 | if( !db_exists("SELECT 1 FROM ftsdocs WHERE NOT idxed") ) return; |
| 1249 | 1270 | search_sql_setup(g.db); |
| 1250 | - search_update_doc_index(); | |
| 1251 | - search_update_checkin_index(); | |
| 1252 | - search_update_ticket_index(); | |
| 1253 | - search_update_wiki_index(); | |
| 1271 | + if( srchFlags & (SRCH_CKIN|SRCH_DOC) ){ | |
| 1272 | + search_update_doc_index(); | |
| 1273 | + search_update_checkin_index(); | |
| 1274 | + } | |
| 1275 | + if( srchFlags & SRCH_TKT ){ | |
| 1276 | + search_update_ticket_index(); | |
| 1277 | + } | |
| 1278 | + if( srchFlags & SRCH_WIKI ){ | |
| 1279 | + search_update_wiki_index(); | |
| 1280 | + } | |
| 1254 | 1281 | } |
| 1255 | 1282 | |
| 1256 | 1283 | /* |
| 1257 | 1284 | ** COMMAND: test-fts |
| 1258 | 1285 | */ |
| @@ -1321,12 +1348,12 @@ | ||
| 1321 | 1348 | } |
| 1322 | 1349 | db_finalize(&q); |
| 1323 | 1350 | break; |
| 1324 | 1351 | } |
| 1325 | 1352 | case 7: { assert( fossil_strncmp(zSubCmd, "update", n)==0 ); |
| 1326 | - search_update_index(); | |
| 1353 | + search_update_index(SRCH_ALL); | |
| 1327 | 1354 | break; |
| 1328 | 1355 | } |
| 1329 | 1356 | |
| 1330 | 1357 | } |
| 1331 | 1358 | db_end_transaction(0); |
| 1332 | 1359 | } |
| 1333 | 1360 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -734,13 +734,16 @@ | |
| 734 | */ |
| 735 | static void search_indexed( |
| 736 | const char *zPattern, /* The query pattern */ |
| 737 | unsigned int srchFlags /* What to search over */ |
| 738 | ){ |
| 739 | sqlite3_create_function(g.db, "rank", 1, SQLITE_UTF8, 0, |
| 740 | search_rank_sqlfunc, 0, 0); |
| 741 | db_multi_exec( |
| 742 | "INSERT INTO x(label,url,score,date,snip) " |
| 743 | " SELECT ftsdocs.label," |
| 744 | " ftsdocs.url," |
| 745 | " rank(matchinfo(ftsidx,'pcsx'))," |
| 746 | " datetime(ftsdocs.mtime)," |
| @@ -748,10 +751,28 @@ | |
| 748 | " FROM ftsidx, ftsdocs" |
| 749 | " WHERE ftsidx MATCH %Q" |
| 750 | " AND ftsdocs.rowid=ftsidx.docid", |
| 751 | zPattern |
| 752 | ); |
| 753 | #if SEARCH_DEBUG_RANK |
| 754 | db_multi_exec("UPDATE x SET label=printf('%%s (score=%%s)',label,score)"); |
| 755 | #endif |
| 756 | } |
| 757 | |
| @@ -778,11 +799,11 @@ | |
| 778 | "CREATE TEMP TABLE x(label,url,score,date,snip);" |
| 779 | ); |
| 780 | if( !search_index_exists() ){ |
| 781 | search_fullscan(zPattern, srchFlags); |
| 782 | }else{ |
| 783 | search_update_index(); |
| 784 | search_indexed(zPattern, srchFlags); |
| 785 | } |
| 786 | db_prepare(&q, "SELECT url, snip, label" |
| 787 | " FROM x" |
| 788 | " ORDER BY score DESC, date DESC;"); |
| @@ -1221,38 +1242,44 @@ | |
| 1221 | */ |
| 1222 | static void search_update_wiki_index(void){ |
| 1223 | db_multi_exec( |
| 1224 | "INSERT INTO ftsidx(docid,stext)" |
| 1225 | " SELECT rowid, stext('w',rid,NULL) FROM ftsdocs" |
| 1226 | " WHERE type='t' AND NOT idxed;" |
| 1227 | ); |
| 1228 | if( db_changes()==0 ) return; |
| 1229 | db_multi_exec( |
| 1230 | "REPLACE INTO ftsdocs(rowid,idxed,type,rid,name,label,url,mtime)" |
| 1231 | " SELECT ftsdocs.rowid, 1, 'w', ftsdocs.rid, ftsdocs.name," |
| 1232 | " 'Wiki: '||tsdocs.name)," |
| 1233 | " '/wiki?name='||urlencode(ftsdocs.name)," |
| 1234 | " tagxref.mtime" |
| 1235 | " FROM ftsdocs, tagxref" |
| 1236 | " WHERE ftsdocs.type='t' AND NOT ftsdocs.idxed" |
| 1237 | " AND tagxref.rid=ftsdocs.rid" |
| 1238 | ); |
| 1239 | } |
| 1240 | |
| 1241 | /* |
| 1242 | ** Deal with all of the unindexed entries in the FTSDOCS table - that |
| 1243 | ** is to say, all the entries with FTSDOCS.IDXED=0. Add them to the |
| 1244 | ** index. |
| 1245 | */ |
| 1246 | void search_update_index(void){ |
| 1247 | if( !search_index_exists() ) return; |
| 1248 | if( !db_exists("SELECT 1 FROM ftsdocs WHERE NOT idxed") ) return; |
| 1249 | search_sql_setup(g.db); |
| 1250 | search_update_doc_index(); |
| 1251 | search_update_checkin_index(); |
| 1252 | search_update_ticket_index(); |
| 1253 | search_update_wiki_index(); |
| 1254 | } |
| 1255 | |
| 1256 | /* |
| 1257 | ** COMMAND: test-fts |
| 1258 | */ |
| @@ -1321,12 +1348,12 @@ | |
| 1321 | } |
| 1322 | db_finalize(&q); |
| 1323 | break; |
| 1324 | } |
| 1325 | case 7: { assert( fossil_strncmp(zSubCmd, "update", n)==0 ); |
| 1326 | search_update_index(); |
| 1327 | break; |
| 1328 | } |
| 1329 | |
| 1330 | } |
| 1331 | db_end_transaction(0); |
| 1332 | } |
| 1333 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -734,13 +734,16 @@ | |
| 734 | */ |
| 735 | static void search_indexed( |
| 736 | const char *zPattern, /* The query pattern */ |
| 737 | unsigned int srchFlags /* What to search over */ |
| 738 | ){ |
| 739 | Blob sql; |
| 740 | if( srchFlags==0 ) return; |
| 741 | sqlite3_create_function(g.db, "rank", 1, SQLITE_UTF8, 0, |
| 742 | search_rank_sqlfunc, 0, 0); |
| 743 | blob_init(&sql, 0, 0); |
| 744 | blob_appendf(&sql, |
| 745 | "INSERT INTO x(label,url,score,date,snip) " |
| 746 | " SELECT ftsdocs.label," |
| 747 | " ftsdocs.url," |
| 748 | " rank(matchinfo(ftsidx,'pcsx'))," |
| 749 | " datetime(ftsdocs.mtime)," |
| @@ -748,10 +751,28 @@ | |
| 751 | " FROM ftsidx, ftsdocs" |
| 752 | " WHERE ftsidx MATCH %Q" |
| 753 | " AND ftsdocs.rowid=ftsidx.docid", |
| 754 | zPattern |
| 755 | ); |
| 756 | if( srchFlags!=SRCH_ALL ){ |
| 757 | const char *zSep = " AND ("; |
| 758 | static const struct { unsigned m; char c; } aMask[] = { |
| 759 | { SRCH_CKIN, 'c' }, |
| 760 | { SRCH_DOC, 'd' }, |
| 761 | { SRCH_TKT, 't' }, |
| 762 | { SRCH_WIKI, 'w' }, |
| 763 | }; |
| 764 | int i; |
| 765 | for(i=0; i<ArraySize(aMask); i++){ |
| 766 | if( srchFlags & aMask[i].m ){ |
| 767 | blob_appendf(&sql, "%sftsdocs.type='%c'", zSep, aMask[i].c); |
| 768 | zSep = " OR "; |
| 769 | } |
| 770 | } |
| 771 | blob_append(&sql,")",1); |
| 772 | } |
| 773 | db_multi_exec("%s",blob_str(&sql)/*safe-for-%s*/); |
| 774 | #if SEARCH_DEBUG_RANK |
| 775 | db_multi_exec("UPDATE x SET label=printf('%%s (score=%%s)',label,score)"); |
| 776 | #endif |
| 777 | } |
| 778 | |
| @@ -778,11 +799,11 @@ | |
| 799 | "CREATE TEMP TABLE x(label,url,score,date,snip);" |
| 800 | ); |
| 801 | if( !search_index_exists() ){ |
| 802 | search_fullscan(zPattern, srchFlags); |
| 803 | }else{ |
| 804 | search_update_index(srchFlags); |
| 805 | search_indexed(zPattern, srchFlags); |
| 806 | } |
| 807 | db_prepare(&q, "SELECT url, snip, label" |
| 808 | " FROM x" |
| 809 | " ORDER BY score DESC, date DESC;"); |
| @@ -1221,38 +1242,44 @@ | |
| 1242 | */ |
| 1243 | static void search_update_wiki_index(void){ |
| 1244 | db_multi_exec( |
| 1245 | "INSERT INTO ftsidx(docid,stext)" |
| 1246 | " SELECT rowid, stext('w',rid,NULL) FROM ftsdocs" |
| 1247 | " WHERE type='w' AND NOT idxed;" |
| 1248 | ); |
| 1249 | if( db_changes()==0 ) return; |
| 1250 | db_multi_exec( |
| 1251 | "REPLACE INTO ftsdocs(rowid,idxed,type,rid,name,label,url,mtime)" |
| 1252 | " SELECT ftsdocs.rowid, 1, 'w', ftsdocs.rid, ftsdocs.name," |
| 1253 | " 'Wiki: '||ftsdocs.name," |
| 1254 | " '/wiki?name='||urlencode(ftsdocs.name)," |
| 1255 | " tagxref.mtime" |
| 1256 | " FROM ftsdocs, tagxref" |
| 1257 | " WHERE ftsdocs.type='w' AND NOT ftsdocs.idxed" |
| 1258 | " AND tagxref.rid=ftsdocs.rid" |
| 1259 | ); |
| 1260 | } |
| 1261 | |
| 1262 | /* |
| 1263 | ** Deal with all of the unindexed entries in the FTSDOCS table - that |
| 1264 | ** is to say, all the entries with FTSDOCS.IDXED=0. Add them to the |
| 1265 | ** index. |
| 1266 | */ |
| 1267 | void search_update_index(unsigned int srchFlags){ |
| 1268 | if( !search_index_exists() ) return; |
| 1269 | if( !db_exists("SELECT 1 FROM ftsdocs WHERE NOT idxed") ) return; |
| 1270 | search_sql_setup(g.db); |
| 1271 | if( srchFlags & (SRCH_CKIN|SRCH_DOC) ){ |
| 1272 | search_update_doc_index(); |
| 1273 | search_update_checkin_index(); |
| 1274 | } |
| 1275 | if( srchFlags & SRCH_TKT ){ |
| 1276 | search_update_ticket_index(); |
| 1277 | } |
| 1278 | if( srchFlags & SRCH_WIKI ){ |
| 1279 | search_update_wiki_index(); |
| 1280 | } |
| 1281 | } |
| 1282 | |
| 1283 | /* |
| 1284 | ** COMMAND: test-fts |
| 1285 | */ |
| @@ -1321,12 +1348,12 @@ | |
| 1348 | } |
| 1349 | db_finalize(&q); |
| 1350 | break; |
| 1351 | } |
| 1352 | case 7: { assert( fossil_strncmp(zSubCmd, "update", n)==0 ); |
| 1353 | search_update_index(SRCH_ALL); |
| 1354 | break; |
| 1355 | } |
| 1356 | |
| 1357 | } |
| 1358 | db_end_transaction(0); |
| 1359 | } |
| 1360 |