| ︙ | | | ︙ | |
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
int nTerm; /* Number of search terms */
struct srchTerm { /* For each search term */
char *z; /* Text */
int n; /* length */
} a[SEARCH_MAX_TERM];
/* Snippet controls */
char *zPattern; /* The search pattern */
char *zMarkBegin; /* Start of a match */
char *zMarkEnd; /* End of a match */
char *zMarkGap; /* A gap between two matches */
unsigned fSrchFlg; /* Flags */
int iScore; /* Score of the last match attempt */
Blob snip; /* Snippet for the most recent match */
};
|
|
|
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
int nTerm; /* Number of search terms */
struct srchTerm { /* For each search term */
char *z; /* Text */
int n; /* length */
} a[SEARCH_MAX_TERM];
/* Snippet controls */
char *zPattern; /* The search pattern */
char *zMarkBegin; /* Start of a match */
char *zMarkEnd; /* End of a match */
char *zMarkGap; /* A gap between two matches */
unsigned fSrchFlg; /* Flags */
int iScore; /* Score of the last match attempt */
Blob snip; /* Snippet for the most recent match */
};
|
| ︙ | | | ︙ | |
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
}
/*
** Compile a search pattern
*/
Search *search_init(
const char *zPattern, /* The search pattern */
const char *zMarkBegin, /* Start of a match */
const char *zMarkEnd, /* End of a match */
const char *zMarkGap, /* A gap between two matches */
unsigned fSrchFlg /* Flags */
){
Search *p;
char *z;
int i;
|
|
|
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
}
/*
** Compile a search pattern
*/
Search *search_init(
const char *zPattern, /* The search pattern */
const char *zMarkBegin, /* Start of a match */
const char *zMarkEnd, /* End of a match */
const char *zMarkGap, /* A gap between two matches */
unsigned fSrchFlg /* Flags */
){
Search *p;
char *z;
int i;
|
| ︙ | | | ︙ | |
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
}
while( ISALNUM(zDoc[i]) ){ i++; }
if( zDoc[i]==0 ) break;
}
}
/* Finished search all documents.
** Every term must be seen or else the score is zero
*/
score = 1;
for(j=0; j<p->nTerm; j++) score *= anMatch[j];
blob_reset(&p->snip);
p->iScore = score;
if( score==0 ) return score;
|
|
|
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
}
while( ISALNUM(zDoc[i]) ){ i++; }
if( zDoc[i]==0 ) break;
}
}
/* Finished search all documents.
** Every term must be seen or else the score is zero
*/
score = 1;
for(j=0; j<p->nTerm; j++) score *= anMatch[j];
blob_reset(&p->snip);
p->iScore = score;
if( score==0 ) return score;
|
| ︙ | | | ︙ | |
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
if( wantGap ) blob_append(&p->snip, p->zMarkGap, -1);
return score;
}
/*
** COMMAND: test-match
**
** Usage: fossil test-match SEARCHSTRING FILE1 FILE2 ...
*/
void test_match_cmd(void){
Search *p;
int i;
Blob x;
int score;
char *zDoc;
|
|
|
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
if( wantGap ) blob_append(&p->snip, p->zMarkGap, -1);
return score;
}
/*
** COMMAND: test-match
**
** Usage: fossil test-match SEARCHSTRING FILE1 FILE2 ...
*/
void test_match_cmd(void){
Search *p;
int i;
Blob x;
int score;
char *zDoc;
|
| ︙ | | | ︙ | |
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
sqlite3_result_text(context, blob_str(&gSearch.snip), -1, fossil_free);
blob_init(&gSearch.snip, 0, 0);
}
}
/*
** This is an SQLite function that computes the searchable text.
** It is a wrapper around the search_stext() routine. See the
** search_stext() routine for further detail.
*/
static void search_stext_sqlfunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
|
|
|
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
sqlite3_result_text(context, blob_str(&gSearch.snip), -1, fossil_free);
blob_init(&gSearch.snip, 0, 0);
}
}
/*
** This is an SQLite function that computes the searchable text.
** It is a wrapper around the search_stext() routine. See the
** search_stext() routine for further detail.
*/
static void search_stext_sqlfunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
|
| ︙ | | | ︙ | |
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
|
db_multi_exec("UPDATE x SET label=printf('%%s (score=%%s)',label,score)");
#endif
}
/*
** If z[] is of the form "<mark>TEXT</mark>" where TEXT contains
** no white-space or punctuation, then return the length of the mark.
** If
*/
static int isSnippetMark(const char *z){
int n;
if( strncmp(z,"<mark>",6)!=0 ) return 0;
n = 6;
while( fossil_isalnum(z[n]) ) n++;
if( strncmp(&z[n],"</mark>",7)!=0 ) return 0;
return n+7;
}
/*
** Return a copy of zSnip (in memory obtained from fossil_malloc()) that
** has all "<" characters, other than those on <mark> and </mark>,
** converted into "<". This is similar to htmlize() except that
** <mark> and </mark> are preserved.
*/
static char *cleanSnippet(const char *zSnip){
int i;
int n = 0;
char *z;
|
<
|
|
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
|
db_multi_exec("UPDATE x SET label=printf('%%s (score=%%s)',label,score)");
#endif
}
/*
** If z[] is of the form "<mark>TEXT</mark>" where TEXT contains
** no white-space or punctuation, then return the length of the mark.
*/
static int isSnippetMark(const char *z){
int n;
if( strncmp(z,"<mark>",6)!=0 ) return 0;
n = 6;
while( fossil_isalnum(z[n]) ) n++;
if( strncmp(&z[n],"</mark>",7)!=0 ) return 0;
return n+7;
}
/*
** Return a copy of zSnip (in memory obtained from fossil_malloc()) that
** has all "<" characters, other than those on <mark> and </mark>,
** converted into "<". This is similar to htmlize() except that
** <mark> and </mark> are preserved.
*/
static char *cleanSnippet(const char *zSnip){
int i;
int n = 0;
char *z;
|
| ︙ | | | ︙ | |
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
|
search_stext(g.argv[2][0], atoi(g.argv[3]), g.argv[4], &out);
fossil_print("%s\n",blob_str(&out));
blob_reset(&out);
}
/* The schema for the full-text index
*/
static const char zFtsSchema[] =
@ -- One entry for each possible search result
@ CREATE TABLE IF NOT EXISTS "%w".ftsdocs(
@ rowid INTEGER PRIMARY KEY, -- Maps to the ftsidx.docid
@ type CHAR(1), -- Type of document
@ rid INTEGER, -- BLOB.RID or TAG.TAGID for the document
@ name TEXT, -- Additional document description
@ idxed BOOLEAN, -- True if currently in the index
|
|
|
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
|
search_stext(g.argv[2][0], atoi(g.argv[3]), g.argv[4], &out);
fossil_print("%s\n",blob_str(&out));
blob_reset(&out);
}
/* The schema for the full-text index
*/
static const char zFtsSchema[] =
@ -- One entry for each possible search result
@ CREATE TABLE IF NOT EXISTS "%w".ftsdocs(
@ rowid INTEGER PRIMARY KEY, -- Maps to the ftsidx.docid
@ type CHAR(1), -- Type of document
@ rid INTEGER, -- BLOB.RID or TAG.TAGID for the document
@ name TEXT, -- Additional document description
@ idxed BOOLEAN, -- True if currently in the index
|
| ︙ | | | ︙ | |
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
|
);
}
}
}
/*
** If the doc-glob and doc-br settings are valid for document search
** and if the latest check-in on doc-br is in the unindexed set of
** check-ins, then update all 'd' entries in FTSDOCS that have
** changed.
*/
static void search_update_doc_index(void){
const char *zDocBr = db_get("doc-branch","trunk");
int ckid = zDocBr ? symbolic_name_to_rid(zDocBr,"ci") : 0;
double rTime;
|
|
|
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
|
);
}
}
}
/*
** If the doc-glob and doc-br settings are valid for document search
** and if the latest check-in on doc-br is in the unindexed set of
** check-ins, then update all 'd' entries in FTSDOCS that have
** changed.
*/
static void search_update_doc_index(void){
const char *zDocBr = db_get("doc-branch","trunk");
int ckid = zDocBr ? symbolic_name_to_rid(zDocBr,"ci") : 0;
double rTime;
|
| ︙ | | | ︙ | |
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
|
);
db_multi_exec(
"UPDATE ftsdocs SET idxed=1 WHERE type='d' AND NOT idxed"
);
}
/*
** Deal with all of the unindexed 'c' terms in FTSDOCS
*/
static void search_update_checkin_index(void){
db_multi_exec(
"INSERT INTO ftsidx(docid,stext)"
" SELECT rowid, stext('c',rid,NULL) FROM ftsdocs"
" WHERE type='c' AND NOT idxed;"
);
|
|
|
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
|
);
db_multi_exec(
"UPDATE ftsdocs SET idxed=1 WHERE type='d' AND NOT idxed"
);
}
/*
** Deal with all of the unindexed 'c' terms in FTSDOCS
*/
static void search_update_checkin_index(void){
db_multi_exec(
"INSERT INTO ftsidx(docid,stext)"
" SELECT rowid, stext('c',rid,NULL) FROM ftsdocs"
" WHERE type='c' AND NOT idxed;"
);
|
| ︙ | | | ︙ | |
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
|
" WHERE ftsdocs.type='c' AND NOT ftsdocs.idxed"
" AND event.objid=ftsdocs.rid"
" AND blob.rid=ftsdocs.rid"
);
}
/*
** Deal with all of the unindexed 't' terms in FTSDOCS
*/
static void search_update_ticket_index(void){
db_multi_exec(
"INSERT INTO ftsidx(docid,stext)"
" SELECT rowid, stext('t',rid,NULL) FROM ftsdocs"
" WHERE type='t' AND NOT idxed;"
);
|
|
|
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
|
" WHERE ftsdocs.type='c' AND NOT ftsdocs.idxed"
" AND event.objid=ftsdocs.rid"
" AND blob.rid=ftsdocs.rid"
);
}
/*
** Deal with all of the unindexed 't' terms in FTSDOCS
*/
static void search_update_ticket_index(void){
db_multi_exec(
"INSERT INTO ftsidx(docid,stext)"
" SELECT rowid, stext('t',rid,NULL) FROM ftsdocs"
" WHERE type='t' AND NOT idxed;"
);
|
| ︙ | | | ︙ | |
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
|
" FROM ftsdocs, ticket"
" WHERE ftsdocs.type='t' AND NOT ftsdocs.idxed"
" AND ticket.tkt_id=ftsdocs.rid"
);
}
/*
** Deal with all of the unindexed 'w' terms in FTSDOCS
*/
static void search_update_wiki_index(void){
db_multi_exec(
"INSERT INTO ftsidx(docid,stext)"
" SELECT rowid, stext('w',rid,NULL) FROM ftsdocs"
" WHERE type='w' AND NOT idxed;"
);
|
|
|
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
|
" FROM ftsdocs, ticket"
" WHERE ftsdocs.type='t' AND NOT ftsdocs.idxed"
" AND ticket.tkt_id=ftsdocs.rid"
);
}
/*
** Deal with all of the unindexed 'w' terms in FTSDOCS
*/
static void search_update_wiki_index(void){
db_multi_exec(
"INSERT INTO ftsidx(docid,stext)"
" SELECT rowid, stext('w',rid,NULL) FROM ftsdocs"
" WHERE type='w' AND NOT idxed;"
);
|
| ︙ | | | ︙ | |
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
|
}
if( iAction>=2 ){
search_rebuild_index();
}
/* Always show the status before ending */
for(i=0; i<ArraySize(aSetng); i++){
fossil_print("%-16s %s\n", aSetng[i].zName,
db_get_boolean(aSetng[i].zSetting,0) ? "on" : "off");
}
if( search_index_exists() ){
fossil_print("%-16s enabled\n", "full-text index:");
fossil_print("%-16s %d\n", "documents:",
db_int(0, "SELECT count(*) FROM ftsdocs"));
}else{
fossil_print("%-16s disabled\n", "full-text index:");
}
db_end_transaction(0);
}
|
|
|
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
|
}
if( iAction>=2 ){
search_rebuild_index();
}
/* Always show the status before ending */
for(i=0; i<ArraySize(aSetng); i++){
fossil_print("%-16s %s\n", aSetng[i].zName,
db_get_boolean(aSetng[i].zSetting,0) ? "on" : "off");
}
if( search_index_exists() ){
fossil_print("%-16s enabled\n", "full-text index:");
fossil_print("%-16s %d\n", "documents:",
db_int(0, "SELECT count(*) FROM ftsdocs"));
}else{
fossil_print("%-16s disabled\n", "full-text index:");
}
db_end_transaction(0);
}
|