Fossil SCM
Add search for help pages.
Commit
f0b960898e10afb060df33258e65d6a4d16e142ac1f2efb3b1e030f01457663a
Parent
a402dd2a888d6d7…
2 files changed
+15
+40
-5
+15
| --- src/dispatch.c | ||
| +++ src/dispatch.c | ||
| @@ -818,13 +818,16 @@ | ||
| 818 | 818 | ** plaintext Show the help within <pre>...</pre>, as if it were |
| 819 | 819 | ** displayed using the "fossil help" command. |
| 820 | 820 | ** |
| 821 | 821 | ** raw Show the raw help text without any formatting. |
| 822 | 822 | ** (Used for debugging.) |
| 823 | +** | |
| 824 | +** s=PATTERN Search help pages for PATTERN. | |
| 823 | 825 | */ |
| 824 | 826 | void help_page(void){ |
| 825 | 827 | const char *zCmd = P("cmd"); |
| 828 | + const char *zPattern = P("s"); | |
| 826 | 829 | |
| 827 | 830 | if( zCmd==0 ) zCmd = P("name"); |
| 828 | 831 | cgi_check_for_malice(); |
| 829 | 832 | if( zCmd && *zCmd ){ |
| 830 | 833 | int rc; |
| @@ -867,16 +870,28 @@ | ||
| 867 | 870 | @ <div class="helpPage"> |
| 868 | 871 | help_to_html(pCmd->zHelp, cgi_output_blob()); |
| 869 | 872 | @ </div> |
| 870 | 873 | } |
| 871 | 874 | } |
| 875 | + }else if( zPattern && *zPattern ){ | |
| 876 | + login_check_credentials(); | |
| 877 | + style_set_current_feature("help"); | |
| 878 | + style_header("Help Search"); | |
| 879 | + search_screen(SRCH_HELP, 0); | |
| 880 | + style_finish_page(); | |
| 872 | 881 | }else{ |
| 873 | 882 | int i; |
| 874 | 883 | unsigned char occHelp[FOSSIL_MX_CMDIDX] = {0}; /* Help str occurrences */ |
| 875 | 884 | int bktHelp[FOSSIL_MX_CMDIDX][MX_HELP_DUP] = {{0}};/* Help str->commands */ |
| 876 | 885 | style_header("Help"); |
| 877 | 886 | |
| 887 | + if( search_restrict(SRCH_HELP)!=0 ){ | |
| 888 | + @ <form action='%R/help' method='GET' style='text-align:center'> | |
| 889 | + @ <input type="text" name="s" size="40" autofocus> | |
| 890 | + @ <input type="submit" value="Search Help Pages"> | |
| 891 | + @ </form> | |
| 892 | + } | |
| 878 | 893 | @ <a name='commands'></a> |
| 879 | 894 | @ <h1>Available commands:</h1> |
| 880 | 895 | @ <div class="columns" style="column-width: 12ex;"> |
| 881 | 896 | @ <ul> |
| 882 | 897 | /* Fill in help string buckets */ |
| 883 | 898 |
| --- src/dispatch.c | |
| +++ src/dispatch.c | |
| @@ -818,13 +818,16 @@ | |
| 818 | ** plaintext Show the help within <pre>...</pre>, as if it were |
| 819 | ** displayed using the "fossil help" command. |
| 820 | ** |
| 821 | ** raw Show the raw help text without any formatting. |
| 822 | ** (Used for debugging.) |
| 823 | */ |
| 824 | void help_page(void){ |
| 825 | const char *zCmd = P("cmd"); |
| 826 | |
| 827 | if( zCmd==0 ) zCmd = P("name"); |
| 828 | cgi_check_for_malice(); |
| 829 | if( zCmd && *zCmd ){ |
| 830 | int rc; |
| @@ -867,16 +870,28 @@ | |
| 867 | @ <div class="helpPage"> |
| 868 | help_to_html(pCmd->zHelp, cgi_output_blob()); |
| 869 | @ </div> |
| 870 | } |
| 871 | } |
| 872 | }else{ |
| 873 | int i; |
| 874 | unsigned char occHelp[FOSSIL_MX_CMDIDX] = {0}; /* Help str occurrences */ |
| 875 | int bktHelp[FOSSIL_MX_CMDIDX][MX_HELP_DUP] = {{0}};/* Help str->commands */ |
| 876 | style_header("Help"); |
| 877 | |
| 878 | @ <a name='commands'></a> |
| 879 | @ <h1>Available commands:</h1> |
| 880 | @ <div class="columns" style="column-width: 12ex;"> |
| 881 | @ <ul> |
| 882 | /* Fill in help string buckets */ |
| 883 |
| --- src/dispatch.c | |
| +++ src/dispatch.c | |
| @@ -818,13 +818,16 @@ | |
| 818 | ** plaintext Show the help within <pre>...</pre>, as if it were |
| 819 | ** displayed using the "fossil help" command. |
| 820 | ** |
| 821 | ** raw Show the raw help text without any formatting. |
| 822 | ** (Used for debugging.) |
| 823 | ** |
| 824 | ** s=PATTERN Search help pages for PATTERN. |
| 825 | */ |
| 826 | void help_page(void){ |
| 827 | const char *zCmd = P("cmd"); |
| 828 | const char *zPattern = P("s"); |
| 829 | |
| 830 | if( zCmd==0 ) zCmd = P("name"); |
| 831 | cgi_check_for_malice(); |
| 832 | if( zCmd && *zCmd ){ |
| 833 | int rc; |
| @@ -867,16 +870,28 @@ | |
| 870 | @ <div class="helpPage"> |
| 871 | help_to_html(pCmd->zHelp, cgi_output_blob()); |
| 872 | @ </div> |
| 873 | } |
| 874 | } |
| 875 | }else if( zPattern && *zPattern ){ |
| 876 | login_check_credentials(); |
| 877 | style_set_current_feature("help"); |
| 878 | style_header("Help Search"); |
| 879 | search_screen(SRCH_HELP, 0); |
| 880 | style_finish_page(); |
| 881 | }else{ |
| 882 | int i; |
| 883 | unsigned char occHelp[FOSSIL_MX_CMDIDX] = {0}; /* Help str occurrences */ |
| 884 | int bktHelp[FOSSIL_MX_CMDIDX][MX_HELP_DUP] = {{0}};/* Help str->commands */ |
| 885 | style_header("Help"); |
| 886 | |
| 887 | if( search_restrict(SRCH_HELP)!=0 ){ |
| 888 | @ <form action='%R/help' method='GET' style='text-align:center'> |
| 889 | @ <input type="text" name="s" size="40" autofocus> |
| 890 | @ <input type="submit" value="Search Help Pages"> |
| 891 | @ </form> |
| 892 | } |
| 893 | @ <a name='commands'></a> |
| 894 | @ <h1>Available commands:</h1> |
| 895 | @ <div class="columns" style="column-width: 12ex;"> |
| 896 | @ <ul> |
| 897 | /* Fill in help string buckets */ |
| 898 |
+40
-5
| --- src/search.c | ||
| +++ src/search.c | ||
| @@ -541,10 +541,11 @@ | ||
| 541 | 541 | */ |
| 542 | 542 | void search_sql_setup(sqlite3 *db){ |
| 543 | 543 | static int once = 0; |
| 544 | 544 | static const int enc = SQLITE_UTF8|SQLITE_INNOCUOUS; |
| 545 | 545 | if( once++ ) return; |
| 546 | + helptext_vtab_register(g.db); | |
| 546 | 547 | sqlite3_create_function(db, "search_match", -1, enc, 0, |
| 547 | 548 | search_match_sqlfunc, 0, 0); |
| 548 | 549 | sqlite3_create_function(db, "search_score", 0, enc, 0, |
| 549 | 550 | search_score_sqlfunc, 0, 0); |
| 550 | 551 | sqlite3_create_function(db, "search_snippet", 0, enc, 0, |
| @@ -653,11 +654,12 @@ | ||
| 653 | 654 | #define SRCH_DOC 0x0002 /* Search over embedded documents */ |
| 654 | 655 | #define SRCH_TKT 0x0004 /* Search over tickets */ |
| 655 | 656 | #define SRCH_WIKI 0x0008 /* Search over wiki */ |
| 656 | 657 | #define SRCH_TECHNOTE 0x0010 /* Search over tech notes */ |
| 657 | 658 | #define SRCH_FORUM 0x0020 /* Search over forum messages */ |
| 658 | -#define SRCH_ALL 0x003f /* Search over everything */ | |
| 659 | +#define SRCH_HELP 0x0040 /* Search over help pages */ | |
| 660 | +#define SRCH_ALL 0x007f /* Search over everything */ | |
| 659 | 661 | #endif |
| 660 | 662 | |
| 661 | 663 | /* |
| 662 | 664 | ** Remove bits from srchFlags which are disallowed by either the |
| 663 | 665 | ** current server configuration or by user permissions. Return |
| @@ -671,16 +673,18 @@ | ||
| 671 | 673 | { SRCH_DOC, "search-doc" }, |
| 672 | 674 | { SRCH_TKT, "search-tkt" }, |
| 673 | 675 | { SRCH_WIKI, "search-wiki" }, |
| 674 | 676 | { SRCH_TECHNOTE, "search-technote" }, |
| 675 | 677 | { SRCH_FORUM, "search-forum" }, |
| 678 | + { SRCH_HELP, "search-help" }, | |
| 676 | 679 | }; |
| 677 | 680 | int i; |
| 678 | 681 | if( g.perm.Read==0 ) srchFlags &= ~(SRCH_CKIN|SRCH_DOC|SRCH_TECHNOTE); |
| 679 | 682 | if( g.perm.RdTkt==0 ) srchFlags &= ~(SRCH_TKT); |
| 680 | 683 | if( g.perm.RdWiki==0 ) srchFlags &= ~(SRCH_WIKI); |
| 681 | 684 | if( g.perm.RdForum==0) srchFlags &= ~(SRCH_FORUM); |
| 685 | + /* No restrictions on SRCH_HELP. */ | |
| 682 | 686 | for(i=0; i<count(aSetng); i++){ |
| 683 | 687 | unsigned int m = aSetng[i].m; |
| 684 | 688 | if( (srchFlags & m)==0 ) continue; |
| 685 | 689 | if( ((knownGood|knownBad) & m)!=0 ) continue; |
| 686 | 690 | if( db_get_boolean(aSetng[i].zKey,0) ){ |
| @@ -824,10 +828,23 @@ | ||
| 824 | 828 | " search_snippet()" |
| 825 | 829 | " FROM event JOIN blob on event.objid=blob.rid" |
| 826 | 830 | " WHERE search_match('',body('f',rid,NULL));" |
| 827 | 831 | ); |
| 828 | 832 | } |
| 833 | + if( (srchFlags & SRCH_HELP)!=0 ){ | |
| 834 | + db_multi_exec( | |
| 835 | + "INSERT INTO x(label,url,score,id,date,snip)" | |
| 836 | + " SELECT name," | |
| 837 | + " '/help?cmd='||name," | |
| 838 | + " search_score()," | |
| 839 | + " 'h'||rowid," | |
| 840 | + " datetime(now())," | |
| 841 | + " search_snippet()" | |
| 842 | + " FROM helptext" | |
| 843 | + " WHERE search_match(name,helptext);" | |
| 844 | + ); | |
| 845 | + } | |
| 829 | 846 | } |
| 830 | 847 | |
| 831 | 848 | /* |
| 832 | 849 | ** Number of significant bits in a u32 |
| 833 | 850 | */ |
| @@ -922,11 +939,12 @@ | ||
| 922 | 939 | ){ |
| 923 | 940 | Blob sql; |
| 924 | 941 | char *zPat = mprintf("%s",zPattern); |
| 925 | 942 | int i; |
| 926 | 943 | static const char *zSnippetCall; |
| 927 | - if( srchFlags==0 ) return; | |
| 944 | + if( srchFlags&SRCH_HELP ) search_fullscan(zPattern, SRCH_HELP); | |
| 945 | + if( (srchFlags&~(SRCH_HELP))==0 ) return; | |
| 928 | 946 | sqlite3_create_function(g.db, "rank", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, |
| 929 | 947 | search_rank_sqlfunc, 0, 0); |
| 930 | 948 | for(i=0; zPat[i]; i++){ |
| 931 | 949 | if( (zPat[i]&0x80)==0 && !fossil_isalnum(zPat[i]) ) zPat[i] = ' '; |
| 932 | 950 | } |
| @@ -1131,10 +1149,11 @@ | ||
| 1131 | 1149 | case SRCH_DOC: zType = " Docs"; zClass = "Doc"; break; |
| 1132 | 1150 | case SRCH_TKT: zType = " Tickets"; zClass = "Tkt"; break; |
| 1133 | 1151 | case SRCH_WIKI: zType = " Wiki"; zClass = "Wiki"; break; |
| 1134 | 1152 | case SRCH_TECHNOTE: zType = " Tech Notes"; zClass = "Note"; break; |
| 1135 | 1153 | case SRCH_FORUM: zType = " Forum"; zClass = "Frm"; break; |
| 1154 | + case SRCH_HELP: zType = " Help"; zClass = "Help"; break; | |
| 1136 | 1155 | } |
| 1137 | 1156 | if( srchFlags==0 ){ |
| 1138 | 1157 | if( mFlags & 0x02 ) return 0; |
| 1139 | 1158 | zDisable1 = " disabled"; |
| 1140 | 1159 | zDisable2 = " disabled"; |
| @@ -1158,10 +1177,11 @@ | ||
| 1158 | 1177 | { "d", "Docs", SRCH_DOC }, |
| 1159 | 1178 | { "t", "Tickets", SRCH_TKT }, |
| 1160 | 1179 | { "w", "Wiki", SRCH_WIKI }, |
| 1161 | 1180 | { "e", "Tech Notes", SRCH_TECHNOTE }, |
| 1162 | 1181 | { "f", "Forum", SRCH_FORUM }, |
| 1182 | + { "h", "Help", SRCH_HELP }, | |
| 1163 | 1183 | }; |
| 1164 | 1184 | const char *zY = PD("y","all"); |
| 1165 | 1185 | unsigned newFlags = srchFlags; |
| 1166 | 1186 | int i; |
| 1167 | 1187 | @ <select size='1' name='y'> |
| @@ -1431,10 +1451,23 @@ | ||
| 1431 | 1451 | append_all_ticket_fields(pOut, &q2, -1); |
| 1432 | 1452 | } |
| 1433 | 1453 | db_reset(&q2); |
| 1434 | 1454 | } |
| 1435 | 1455 | break; |
| 1456 | + } | |
| 1457 | + case 'h': { /* Help pages */ | |
| 1458 | + static Stmt q; | |
| 1459 | + db_static_prepare(&q, | |
| 1460 | + "SELECT name,helptext FROM helptext WHERE rowid=:x"); | |
| 1461 | + db_bind_int(&q, ":x", rid); | |
| 1462 | + if( db_step(&q)==SQLITE_ROW ){ | |
| 1463 | + db_column_blob(&q, 0, pOut); | |
| 1464 | + blob_append(pOut, "\n", 1); | |
| 1465 | + db_column_blob(&q, 1, pOut); | |
| 1466 | + } | |
| 1467 | + db_reset(&q); | |
| 1468 | + break; | |
| 1436 | 1469 | } |
| 1437 | 1470 | } |
| 1438 | 1471 | } |
| 1439 | 1472 | |
| 1440 | 1473 | /* |
| @@ -1955,10 +1988,11 @@ | ||
| 1955 | 1988 | search_update_technote_index(); |
| 1956 | 1989 | } |
| 1957 | 1990 | if( srchFlags & SRCH_FORUM ){ |
| 1958 | 1991 | search_update_forum_index(); |
| 1959 | 1992 | } |
| 1993 | + /* SRCH_HELP does not use FTSDOCS. */ | |
| 1960 | 1994 | db_protect_pop(); |
| 1961 | 1995 | } |
| 1962 | 1996 | |
| 1963 | 1997 | /* |
| 1964 | 1998 | ** Construct, prepopulate, and then update the full-text index. |
| @@ -1983,15 +2017,15 @@ | ||
| 1983 | 2017 | ** reindex Rebuild the search index. This is a no-op if |
| 1984 | 2018 | ** index search is disabled |
| 1985 | 2019 | ** |
| 1986 | 2020 | ** index (on|off) Turn the search index on or off |
| 1987 | 2021 | ** |
| 1988 | -** enable cdtwef Enable various kinds of search. c=Check-ins, | |
| 2022 | +** enable cdtwefh Enable various kinds of search. c=Check-ins, | |
| 1989 | 2023 | ** d=Documents, t=Tickets, w=Wiki, e=Tech Notes, |
| 1990 | -** f=Forum. | |
| 2024 | +** f=Forum, h=Help. | |
| 1991 | 2025 | ** |
| 1992 | -** disable cdtwef Disable various kinds of search | |
| 2026 | +** disable cdtwefh Disable various kinds of search | |
| 1993 | 2027 | ** |
| 1994 | 2028 | ** tokenizer VALUE Select a tokenizer for indexed search. VALUE |
| 1995 | 2029 | ** may be one of (porter, on, off, trigram, unicode61), |
| 1996 | 2030 | ** and "on" is equivalent to "porter". Unindexed |
| 1997 | 2031 | ** search never uses tokenization or stemming. |
| @@ -2019,10 +2053,11 @@ | ||
| 2019 | 2053 | { "search-doc", "document search:", "d" }, |
| 2020 | 2054 | { "search-tkt", "ticket search:", "t" }, |
| 2021 | 2055 | { "search-wiki", "wiki search:", "w" }, |
| 2022 | 2056 | { "search-technote", "tech note search:", "e" }, |
| 2023 | 2057 | { "search-forum", "forum search:", "f" }, |
| 2058 | + { "search-help", "help search:", "h" }, | |
| 2024 | 2059 | }; |
| 2025 | 2060 | char *zSubCmd = 0; |
| 2026 | 2061 | int i, j, n; |
| 2027 | 2062 | int iCmd = 0; |
| 2028 | 2063 | int iAction = 0; |
| 2029 | 2064 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -541,10 +541,11 @@ | |
| 541 | */ |
| 542 | void search_sql_setup(sqlite3 *db){ |
| 543 | static int once = 0; |
| 544 | static const int enc = SQLITE_UTF8|SQLITE_INNOCUOUS; |
| 545 | if( once++ ) return; |
| 546 | sqlite3_create_function(db, "search_match", -1, enc, 0, |
| 547 | search_match_sqlfunc, 0, 0); |
| 548 | sqlite3_create_function(db, "search_score", 0, enc, 0, |
| 549 | search_score_sqlfunc, 0, 0); |
| 550 | sqlite3_create_function(db, "search_snippet", 0, enc, 0, |
| @@ -653,11 +654,12 @@ | |
| 653 | #define SRCH_DOC 0x0002 /* Search over embedded documents */ |
| 654 | #define SRCH_TKT 0x0004 /* Search over tickets */ |
| 655 | #define SRCH_WIKI 0x0008 /* Search over wiki */ |
| 656 | #define SRCH_TECHNOTE 0x0010 /* Search over tech notes */ |
| 657 | #define SRCH_FORUM 0x0020 /* Search over forum messages */ |
| 658 | #define SRCH_ALL 0x003f /* Search over everything */ |
| 659 | #endif |
| 660 | |
| 661 | /* |
| 662 | ** Remove bits from srchFlags which are disallowed by either the |
| 663 | ** current server configuration or by user permissions. Return |
| @@ -671,16 +673,18 @@ | |
| 671 | { SRCH_DOC, "search-doc" }, |
| 672 | { SRCH_TKT, "search-tkt" }, |
| 673 | { SRCH_WIKI, "search-wiki" }, |
| 674 | { SRCH_TECHNOTE, "search-technote" }, |
| 675 | { SRCH_FORUM, "search-forum" }, |
| 676 | }; |
| 677 | int i; |
| 678 | if( g.perm.Read==0 ) srchFlags &= ~(SRCH_CKIN|SRCH_DOC|SRCH_TECHNOTE); |
| 679 | if( g.perm.RdTkt==0 ) srchFlags &= ~(SRCH_TKT); |
| 680 | if( g.perm.RdWiki==0 ) srchFlags &= ~(SRCH_WIKI); |
| 681 | if( g.perm.RdForum==0) srchFlags &= ~(SRCH_FORUM); |
| 682 | for(i=0; i<count(aSetng); i++){ |
| 683 | unsigned int m = aSetng[i].m; |
| 684 | if( (srchFlags & m)==0 ) continue; |
| 685 | if( ((knownGood|knownBad) & m)!=0 ) continue; |
| 686 | if( db_get_boolean(aSetng[i].zKey,0) ){ |
| @@ -824,10 +828,23 @@ | |
| 824 | " search_snippet()" |
| 825 | " FROM event JOIN blob on event.objid=blob.rid" |
| 826 | " WHERE search_match('',body('f',rid,NULL));" |
| 827 | ); |
| 828 | } |
| 829 | } |
| 830 | |
| 831 | /* |
| 832 | ** Number of significant bits in a u32 |
| 833 | */ |
| @@ -922,11 +939,12 @@ | |
| 922 | ){ |
| 923 | Blob sql; |
| 924 | char *zPat = mprintf("%s",zPattern); |
| 925 | int i; |
| 926 | static const char *zSnippetCall; |
| 927 | if( srchFlags==0 ) return; |
| 928 | sqlite3_create_function(g.db, "rank", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, |
| 929 | search_rank_sqlfunc, 0, 0); |
| 930 | for(i=0; zPat[i]; i++){ |
| 931 | if( (zPat[i]&0x80)==0 && !fossil_isalnum(zPat[i]) ) zPat[i] = ' '; |
| 932 | } |
| @@ -1131,10 +1149,11 @@ | |
| 1131 | case SRCH_DOC: zType = " Docs"; zClass = "Doc"; break; |
| 1132 | case SRCH_TKT: zType = " Tickets"; zClass = "Tkt"; break; |
| 1133 | case SRCH_WIKI: zType = " Wiki"; zClass = "Wiki"; break; |
| 1134 | case SRCH_TECHNOTE: zType = " Tech Notes"; zClass = "Note"; break; |
| 1135 | case SRCH_FORUM: zType = " Forum"; zClass = "Frm"; break; |
| 1136 | } |
| 1137 | if( srchFlags==0 ){ |
| 1138 | if( mFlags & 0x02 ) return 0; |
| 1139 | zDisable1 = " disabled"; |
| 1140 | zDisable2 = " disabled"; |
| @@ -1158,10 +1177,11 @@ | |
| 1158 | { "d", "Docs", SRCH_DOC }, |
| 1159 | { "t", "Tickets", SRCH_TKT }, |
| 1160 | { "w", "Wiki", SRCH_WIKI }, |
| 1161 | { "e", "Tech Notes", SRCH_TECHNOTE }, |
| 1162 | { "f", "Forum", SRCH_FORUM }, |
| 1163 | }; |
| 1164 | const char *zY = PD("y","all"); |
| 1165 | unsigned newFlags = srchFlags; |
| 1166 | int i; |
| 1167 | @ <select size='1' name='y'> |
| @@ -1431,10 +1451,23 @@ | |
| 1431 | append_all_ticket_fields(pOut, &q2, -1); |
| 1432 | } |
| 1433 | db_reset(&q2); |
| 1434 | } |
| 1435 | break; |
| 1436 | } |
| 1437 | } |
| 1438 | } |
| 1439 | |
| 1440 | /* |
| @@ -1955,10 +1988,11 @@ | |
| 1955 | search_update_technote_index(); |
| 1956 | } |
| 1957 | if( srchFlags & SRCH_FORUM ){ |
| 1958 | search_update_forum_index(); |
| 1959 | } |
| 1960 | db_protect_pop(); |
| 1961 | } |
| 1962 | |
| 1963 | /* |
| 1964 | ** Construct, prepopulate, and then update the full-text index. |
| @@ -1983,15 +2017,15 @@ | |
| 1983 | ** reindex Rebuild the search index. This is a no-op if |
| 1984 | ** index search is disabled |
| 1985 | ** |
| 1986 | ** index (on|off) Turn the search index on or off |
| 1987 | ** |
| 1988 | ** enable cdtwef Enable various kinds of search. c=Check-ins, |
| 1989 | ** d=Documents, t=Tickets, w=Wiki, e=Tech Notes, |
| 1990 | ** f=Forum. |
| 1991 | ** |
| 1992 | ** disable cdtwef Disable various kinds of search |
| 1993 | ** |
| 1994 | ** tokenizer VALUE Select a tokenizer for indexed search. VALUE |
| 1995 | ** may be one of (porter, on, off, trigram, unicode61), |
| 1996 | ** and "on" is equivalent to "porter". Unindexed |
| 1997 | ** search never uses tokenization or stemming. |
| @@ -2019,10 +2053,11 @@ | |
| 2019 | { "search-doc", "document search:", "d" }, |
| 2020 | { "search-tkt", "ticket search:", "t" }, |
| 2021 | { "search-wiki", "wiki search:", "w" }, |
| 2022 | { "search-technote", "tech note search:", "e" }, |
| 2023 | { "search-forum", "forum search:", "f" }, |
| 2024 | }; |
| 2025 | char *zSubCmd = 0; |
| 2026 | int i, j, n; |
| 2027 | int iCmd = 0; |
| 2028 | int iAction = 0; |
| 2029 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -541,10 +541,11 @@ | |
| 541 | */ |
| 542 | void search_sql_setup(sqlite3 *db){ |
| 543 | static int once = 0; |
| 544 | static const int enc = SQLITE_UTF8|SQLITE_INNOCUOUS; |
| 545 | if( once++ ) return; |
| 546 | helptext_vtab_register(g.db); |
| 547 | sqlite3_create_function(db, "search_match", -1, enc, 0, |
| 548 | search_match_sqlfunc, 0, 0); |
| 549 | sqlite3_create_function(db, "search_score", 0, enc, 0, |
| 550 | search_score_sqlfunc, 0, 0); |
| 551 | sqlite3_create_function(db, "search_snippet", 0, enc, 0, |
| @@ -653,11 +654,12 @@ | |
| 654 | #define SRCH_DOC 0x0002 /* Search over embedded documents */ |
| 655 | #define SRCH_TKT 0x0004 /* Search over tickets */ |
| 656 | #define SRCH_WIKI 0x0008 /* Search over wiki */ |
| 657 | #define SRCH_TECHNOTE 0x0010 /* Search over tech notes */ |
| 658 | #define SRCH_FORUM 0x0020 /* Search over forum messages */ |
| 659 | #define SRCH_HELP 0x0040 /* Search over help pages */ |
| 660 | #define SRCH_ALL 0x007f /* Search over everything */ |
| 661 | #endif |
| 662 | |
| 663 | /* |
| 664 | ** Remove bits from srchFlags which are disallowed by either the |
| 665 | ** current server configuration or by user permissions. Return |
| @@ -671,16 +673,18 @@ | |
| 673 | { SRCH_DOC, "search-doc" }, |
| 674 | { SRCH_TKT, "search-tkt" }, |
| 675 | { SRCH_WIKI, "search-wiki" }, |
| 676 | { SRCH_TECHNOTE, "search-technote" }, |
| 677 | { SRCH_FORUM, "search-forum" }, |
| 678 | { SRCH_HELP, "search-help" }, |
| 679 | }; |
| 680 | int i; |
| 681 | if( g.perm.Read==0 ) srchFlags &= ~(SRCH_CKIN|SRCH_DOC|SRCH_TECHNOTE); |
| 682 | if( g.perm.RdTkt==0 ) srchFlags &= ~(SRCH_TKT); |
| 683 | if( g.perm.RdWiki==0 ) srchFlags &= ~(SRCH_WIKI); |
| 684 | if( g.perm.RdForum==0) srchFlags &= ~(SRCH_FORUM); |
| 685 | /* No restrictions on SRCH_HELP. */ |
| 686 | for(i=0; i<count(aSetng); i++){ |
| 687 | unsigned int m = aSetng[i].m; |
| 688 | if( (srchFlags & m)==0 ) continue; |
| 689 | if( ((knownGood|knownBad) & m)!=0 ) continue; |
| 690 | if( db_get_boolean(aSetng[i].zKey,0) ){ |
| @@ -824,10 +828,23 @@ | |
| 828 | " search_snippet()" |
| 829 | " FROM event JOIN blob on event.objid=blob.rid" |
| 830 | " WHERE search_match('',body('f',rid,NULL));" |
| 831 | ); |
| 832 | } |
| 833 | if( (srchFlags & SRCH_HELP)!=0 ){ |
| 834 | db_multi_exec( |
| 835 | "INSERT INTO x(label,url,score,id,date,snip)" |
| 836 | " SELECT name," |
| 837 | " '/help?cmd='||name," |
| 838 | " search_score()," |
| 839 | " 'h'||rowid," |
| 840 | " datetime(now())," |
| 841 | " search_snippet()" |
| 842 | " FROM helptext" |
| 843 | " WHERE search_match(name,helptext);" |
| 844 | ); |
| 845 | } |
| 846 | } |
| 847 | |
| 848 | /* |
| 849 | ** Number of significant bits in a u32 |
| 850 | */ |
| @@ -922,11 +939,12 @@ | |
| 939 | ){ |
| 940 | Blob sql; |
| 941 | char *zPat = mprintf("%s",zPattern); |
| 942 | int i; |
| 943 | static const char *zSnippetCall; |
| 944 | if( srchFlags&SRCH_HELP ) search_fullscan(zPattern, SRCH_HELP); |
| 945 | if( (srchFlags&~(SRCH_HELP))==0 ) return; |
| 946 | sqlite3_create_function(g.db, "rank", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, |
| 947 | search_rank_sqlfunc, 0, 0); |
| 948 | for(i=0; zPat[i]; i++){ |
| 949 | if( (zPat[i]&0x80)==0 && !fossil_isalnum(zPat[i]) ) zPat[i] = ' '; |
| 950 | } |
| @@ -1131,10 +1149,11 @@ | |
| 1149 | case SRCH_DOC: zType = " Docs"; zClass = "Doc"; break; |
| 1150 | case SRCH_TKT: zType = " Tickets"; zClass = "Tkt"; break; |
| 1151 | case SRCH_WIKI: zType = " Wiki"; zClass = "Wiki"; break; |
| 1152 | case SRCH_TECHNOTE: zType = " Tech Notes"; zClass = "Note"; break; |
| 1153 | case SRCH_FORUM: zType = " Forum"; zClass = "Frm"; break; |
| 1154 | case SRCH_HELP: zType = " Help"; zClass = "Help"; break; |
| 1155 | } |
| 1156 | if( srchFlags==0 ){ |
| 1157 | if( mFlags & 0x02 ) return 0; |
| 1158 | zDisable1 = " disabled"; |
| 1159 | zDisable2 = " disabled"; |
| @@ -1158,10 +1177,11 @@ | |
| 1177 | { "d", "Docs", SRCH_DOC }, |
| 1178 | { "t", "Tickets", SRCH_TKT }, |
| 1179 | { "w", "Wiki", SRCH_WIKI }, |
| 1180 | { "e", "Tech Notes", SRCH_TECHNOTE }, |
| 1181 | { "f", "Forum", SRCH_FORUM }, |
| 1182 | { "h", "Help", SRCH_HELP }, |
| 1183 | }; |
| 1184 | const char *zY = PD("y","all"); |
| 1185 | unsigned newFlags = srchFlags; |
| 1186 | int i; |
| 1187 | @ <select size='1' name='y'> |
| @@ -1431,10 +1451,23 @@ | |
| 1451 | append_all_ticket_fields(pOut, &q2, -1); |
| 1452 | } |
| 1453 | db_reset(&q2); |
| 1454 | } |
| 1455 | break; |
| 1456 | } |
| 1457 | case 'h': { /* Help pages */ |
| 1458 | static Stmt q; |
| 1459 | db_static_prepare(&q, |
| 1460 | "SELECT name,helptext FROM helptext WHERE rowid=:x"); |
| 1461 | db_bind_int(&q, ":x", rid); |
| 1462 | if( db_step(&q)==SQLITE_ROW ){ |
| 1463 | db_column_blob(&q, 0, pOut); |
| 1464 | blob_append(pOut, "\n", 1); |
| 1465 | db_column_blob(&q, 1, pOut); |
| 1466 | } |
| 1467 | db_reset(&q); |
| 1468 | break; |
| 1469 | } |
| 1470 | } |
| 1471 | } |
| 1472 | |
| 1473 | /* |
| @@ -1955,10 +1988,11 @@ | |
| 1988 | search_update_technote_index(); |
| 1989 | } |
| 1990 | if( srchFlags & SRCH_FORUM ){ |
| 1991 | search_update_forum_index(); |
| 1992 | } |
| 1993 | /* SRCH_HELP does not use FTSDOCS. */ |
| 1994 | db_protect_pop(); |
| 1995 | } |
| 1996 | |
| 1997 | /* |
| 1998 | ** Construct, prepopulate, and then update the full-text index. |
| @@ -1983,15 +2017,15 @@ | |
| 2017 | ** reindex Rebuild the search index. This is a no-op if |
| 2018 | ** index search is disabled |
| 2019 | ** |
| 2020 | ** index (on|off) Turn the search index on or off |
| 2021 | ** |
| 2022 | ** enable cdtwefh Enable various kinds of search. c=Check-ins, |
| 2023 | ** d=Documents, t=Tickets, w=Wiki, e=Tech Notes, |
| 2024 | ** f=Forum, h=Help. |
| 2025 | ** |
| 2026 | ** disable cdtwefh Disable various kinds of search |
| 2027 | ** |
| 2028 | ** tokenizer VALUE Select a tokenizer for indexed search. VALUE |
| 2029 | ** may be one of (porter, on, off, trigram, unicode61), |
| 2030 | ** and "on" is equivalent to "porter". Unindexed |
| 2031 | ** search never uses tokenization or stemming. |
| @@ -2019,10 +2053,11 @@ | |
| 2053 | { "search-doc", "document search:", "d" }, |
| 2054 | { "search-tkt", "ticket search:", "t" }, |
| 2055 | { "search-wiki", "wiki search:", "w" }, |
| 2056 | { "search-technote", "tech note search:", "e" }, |
| 2057 | { "search-forum", "forum search:", "f" }, |
| 2058 | { "search-help", "help search:", "h" }, |
| 2059 | }; |
| 2060 | char *zSubCmd = 0; |
| 2061 | int i, j, n; |
| 2062 | int iCmd = 0; |
| 2063 | int iAction = 0; |
| 2064 |