Hello All,
This patch adds a complete seach mechanism for wikis, tickets, checkins, and
code. This functionality is only available if you are logged in.
diff -rup ../fossil-src-20100318142033/src/db.c ./src/db.c
--- ../fossil-src-20100318142033/src/db.c 2010-03-18 10:20:53.000000000
-0400
+++ ./src/db.c 2010-05-20 18:00:46.681326571 -0400
@@ -1041,6 +1041,79 @@ static void db_sql_user(
}
/*
+** Make the content_get function available within a SQL query.
+*/
+static void db_sql_content_get(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int rid;
+ Blob content;
+
+ if( argc != 1 ) return;
+ rid = sqlite3_value_int(argv[0]);
+ content_get(rid, &content);
+ sqlite3_result_text(context, blob_str(&content), -1, SQLITE_TRANSIENT);
+}
+
+/*
+** Retrieve the most recent revision ID of a file prior to a given DATETIME.
+** If the DATETIME is given as 0, then find the most recent RID.
+*/
+static void db_sql_get_file_rid(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *fnid;
+ const unsigned char *datetime;
+ int rid;
+ Stmt q;
+
+ if ( argc != 2 ) return;
+ fnid = sqlite3_value_text(argv[0]);
+ datetime = sqlite3_value_text(argv[1]);
+
+ if (strcmp((const char*)datetime, "0") == 0){
+ db_prepare(&q, "SELECT fid FROM mlink WHERE fnid=%Q and mid= "
+ "(SELECT objid FROM (SELECT objid, mtime FROM event WHERE
objid IN "
+ "(SELECT mid FROM mlink WHERE fnid=%Q) "
+ "ORDER BY mtime DESC) LIMIT 1);", fnid, fnid);
+
+ db_step(&q);
+ rid = db_column_int(&q, 0);
+ sqlite3_result_int(context, rid);
+ }
+}
+
+/*
+** Retrieve the most recent revision ID of a wiki entry prior to a given
DATETIME.
+** If the DATETIME is given as 0, then find the most recent RID.
+*/
+static void db_sql_get_wiki_rid(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *tagid;
+ const unsigned char *datetime;
+ int rid;
+ Stmt q;
+
+ if ( argc != 2 ) return;
+ tagid = sqlite3_value_text(argv[0]);
+ datetime = sqlite3_value_text(argv[1]);
+
+ if (strcmp((const char*)datetime, "0") == 0){
+ db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%Q ORDER BY mtime DESC
LIMIT 1", tagid);
+ db_step(&q);
+ rid = db_column_int(&q, 0);
+ sqlite3_result_int(context, rid);
+ }
+}
+
+/*
** Implement the cgi() SQL function. cgi() takes a an argument which is
** a name of CGI query parameter. The value of that parameter is returned,
** if available. optional second argument will be returned if the first
@@ -1156,9 +1229,10 @@ LOCAL void db_connection_init(void){
sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
- sqlite3_create_function(
- g.db, "file_is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0
- );
+ sqlite3_create_function(g.db, "content_get", 1, SQLITE_ANY, 0,
db_sql_content_get, 0, 0);
+ sqlite3_create_function(g.db, "get_file_rid", 2, SQLITE_ANY, 0,
db_sql_get_file_rid, 0, 0);
+ sqlite3_create_function(g.db, "get_wiki_rid", 2, SQLITE_ANY, 0,
db_sql_get_wiki_rid, 0, 0);
+ sqlite3_create_function(g.db, "file_is_selected", 1, SQLITE_UTF8, 0,
file_is_selected,0,0);
if( g.fSqlTrace ){
sqlite3_trace(g.db, db_sql_trace, 0);
}
Only in ./src: fossil_patch
diff -rup ../fossil-src-20100318142033/src/search.c ./src/search.c
--- ../fossil-src-20100318142033/src/search.c 2010-03-18 10:20:53.000000000
-0400
+++ ./src/search.c 2010-05-20 16:03:31.584325769 -0400
@@ -172,6 +172,104 @@ void search_sql_setup(Search *p){
}
/*
+** WEBPAGE: search
+** URL: /search
+*/
+void search(void){
+ const char *zType;
+ const char *zSrchType;
+ const char *zTitle;
+ const char *zContent;
+ const char *zSrch;
+ const char *zUuid;
+ const char *zRid;
+ char zrn[4];
+ char zshUuid[10];
+ int zScore;
+ int zSrchTypeFlag;
+
+ Search *zSrchpat;
+ Stmt q;
+
+ zSrch = PD("search", "");
+ zSrchType = PD("type", "");
+ zSrchpat = search_init(zSrch);
+ search_sql_setup(zSrchpat);
+
+ login_check_credentials();
+
+ if( !g.okHistory ){ login_needed(); return; }
+
+ db_prepare(&q, "SELECT type, rid, title, content, score(content) AS score
FROM "
+ "
"
+ "(SELECT 'checkin' AS type, objid AS rid, coalesce(ecomment,
comment) AS title, "
+ "coalesce(ecomment, comment) AS content FROM event WHERE
type='ci' UNION ALL "
+ "SELECT 'code' AS type, rid, title, content FROM "
+ "(SELECT title, rid, content_get(rid) as content FROM "
+ "(SELECT name AS title, get_file_rid(fnid, '0') AS rid FROM "
+ "(SELECT name, fnid FROM filename))) UNION ALL "
+ "
"
+ "SELECT 'ticket' AS type, tkt_uuid AS rid, title,
coalesce(title, comment) AS content FROM ticket UNION ALL "
+ "SELECT 'wiki' AS type, rid, SUBSTR(title, 6) AS title,
content_get(rid) as content FROM "
+ "(SELECT tagname AS title, get_wiki_rid(tagid, '0') AS rid
FROM "
+ "(SELECT tagname, tagid FROM tag WHERE tagname LIKE
'wiki-%%')))"
+ "ORDER BY score DESC;");
+
+ zSrchTypeFlag = 0;
+ if (strcmp(zSrchType, "code") == 0)
+ zSrchTypeFlag = 1;
+ else if (strcmp(zSrchType, "tickets") == 0)
+ zSrchTypeFlag = 2;
+ else if (strcmp(zSrchType, "checkins") == 0)
+ zSrchTypeFlag = 3;
+ else if (strcmp(zSrchType, "wiki") == 0)
+ zSrchTypeFlag = 4;
+
+ style_header("Search");
+ style_submenu_element("Code", "Code", "search?search=%T&type=code", zSrch);
+ style_submenu_element("Tickets", "Tickets", "search?search=%T&type=tickets",
zSrch);
+ style_submenu_element("Checkins", "Checkins",
"search?search=%T&type=checkins", zSrch);
+ style_submenu_element("Wiki", "Wiki", "search?search=%T&type=wiki", zSrch);
+ @ <table border=1>
+ @ <tr><td>link</td><td>relevance</td><td>title</td><td>type</td></tr>
+ while (db_step(&q) == SQLITE_ROW){
+ zType = db_column_text(&q, 0);
+ zRid = db_column_text(&q, 1);
+ zTitle = db_column_text(&q, 2);
+ zContent = db_column_text(&q, 3);
+ zScore = db_column_int(&q, 4);
+
+ sprintf(zrn, "%i", zScore);
+ if (zScore > 0){
+ if (strcmp(zType, "code") == 0 && (zSrchTypeFlag == 0 || zSrchTypeFlag
== 1)){
+ zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%h", zRid);
+ strncpy(zshUuid, zUuid, 10);
+ @ <tr><td><a
href='/artifact?name=%h(zUuid)'>%h(zshUuid)</a></td><td>%h(zrn)</td>
+ @ <td>%h(zTitle)</td><td>%h(zType)</td></tr>
+ }
+ else if (strcmp(zType, "ticket") == 0 && (zSrchTypeFlag == 0 ||
zSrchTypeFlag == 2)){
+ strncpy(zshUuid, zRid, 10);
+ @ <tr><td><a
href='/tktview?name=%h(zRid)'>%h(zshUuid)</a></td><td>%h(zrn)</td>
+ @ <td>%h(zTitle)</td><td>%h(zType)</td></tr>
+ }
+ else if (strcmp(zType, "checkin") == 0 && (zSrchTypeFlag == 0 ||
zSrchTypeFlag == 3)){
+ zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%h", zRid);
+ strncpy(zshUuid, zUuid, 10);
+ @ <tr><td><a href='info/%h(zUuid)'>%h(zshUuid)</a></td><td>%h(zrn)</td>
+ @ <td>%h(zTitle)</td><td>%h(zType)</td></tr>
+ }
+ else if (strcmp(zType, "wiki") == 0 && (zSrchTypeFlag == 0 ||
zSrchTypeFlag == 4)){
+ @ <tr><td><a
href='/wiki?name=%h(zTitle)'>%h(zTitle)</a></td><td>%h(zrn)</td>
+ @ <td>%h(zTitle)</td><td>%h(zType)</td></tr>
+ }
+ }
+ }
+ @ </table>
+ db_finalize(&q);
+ style_footer();
+}
+
+/*
** Testing the search function.
**
** COMMAND: search
diff -rup ../fossil-src-20100318142033/src/skins.c ./src/skins.c
--- ../fossil-src-20100318142033/src/skins.c 2010-03-18 10:20:53.000000000
-0400
+++ ./src/skins.c 2010-05-20 17:41:23.931389012 -0400
@@ -81,8 +81,13 @@ static const char zBuiltinSkin1[] =
@ width: 100%;
@ }
@
-@ /* The main menu bar that appears at the top of the page beneath
-@ ** the header */
+@ /* The search bar displayed at the top of the page */
+@ div.search {
+@ float: right;
+@ margin: 2px 5px 2px 0px;
+@ }
+@
+@ /* The main menu bar that appears at the top of the page beneath */
@ div.mainmenu {
@ padding: 5px 10px 5px 10px;
@ font-size: 0.9em;
@@ -183,6 +188,17 @@ static const char zBuiltinSkin1[] =
@ }
@ </th1></nobr></div>
@ </div>
+@
+@ <th1>
+@ if {[hascap h]} {
+@ html "<div class='search'>"
+@ html " <form action='/search' method='post'>"
+@ html " <input type='text' name='search' size=20/>"
+@ html " <input type='submit' value='Search'/>"
+@ html " </form>"
+@ html "</div>"
+@ }
+@ </th1>
@ <div class="mainmenu"><th1>
@ html "<a href=''$baseurl$index_page''>Home</a> "
@ if {[anycap jor]} {
diff -rup ../fossil-src-20100318142033/src/style.c ./src/style.c
--- ../fossil-src-20100318142033/src/style.c 2010-03-18 10:20:53.000000000
-0400
+++ ./src/style.c 2010-05-20 14:46:08.318326496 -0400
@@ -208,6 +208,16 @@ const char zDefaultHeader[] =
@ }
@ </th1></nobr></div>
@ </div>
+@ <th1>
+@ if {[hascap h]} {
+@ html "<div class='search'>"
+@ html " <form action='/search' method='post'>"
+@ html " <input type='text' name='search' size=20/>"
+@ html " <input type='submit' value='Search'/>"
+@ html " </form>"
+@ html "</div>"
+@ }
+@ </th1>
@ <div class="mainmenu"><th1>
@ html "<a href='$baseurl$index_page'>Home</a> "
@ if {[anycap jor]} {
@@ -299,6 +309,12 @@ const char zDefaultCSS[] =
@ width: 100%;
@ }
@
+@ /* The search bar displayed at the top of the page */
+@ div.search {
+@ float: right;
+@ margin: 2px 5px 2px 0px;
+@ }
+@
@ /* The main menu bar that appears at the top of the page beneath
@ ** the header */
@ div.mainmenu {
Only in ./src: testfile.txt
Only in ./tools/cvs2fossil/doc: license
Only in ./tools/cvs2fossil/doc: readme
_______________________________________________
fossil-users mailing list
[email protected]
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users