/* ** There are also two SQL user functions registered: ** ** rank() ** erank() ** ** rank() interprets the return value of the FTS3 matchinfo() function and ** returns a score for the match (a real number). The higher the score, the ** more relevant the document is considered. This is used to order query ** results when the user searchs the database. The rank() function takes ** (nCol+1) arguments, where nCol is the number of columns in the FTS3 ** table. The first argument is the return value of matchinfo(). The ** second argument is the number of tokens in column 0 of the current FTS3 ** table row. The third argument is the number of tokens in column 1, and ** so on. ** ** Function erank() is called in exactly the same way as rank(). Instead ** of returning a score, it returns an HTML formatted table containing ** data that may be used to understand how the score for the current row ** was calculated. */ #include #include #include #include #include #include "sqlite3.h" typedef unsigned int u32; typedef unsigned char u8; typedef sqlite3_uint64 u64; /* ** Implementation of search result ranking function. */ static void rankfunc(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ u32 *aMatchinfo; double score = 0.0; int iCol; int iPhrase; int nCol; int nPhrase; int isExplain = sqlite3_user_data(pCtx); char *zExplain = 0; if( nVal==0 ) goto wna; aMatchinfo = (u32 *)sqlite3_value_blob(apVal[0]); nPhrase = aMatchinfo[0]; nCol = aMatchinfo[1]; if( nVal!=nCol+1 ) goto wna; if( isExplain ) zExplain = sqlite3_mprintf(""); for(iCol=0; iCol
%d.( ", zExplain, iCol); } for(iPhrase=0; iPhrase = %.4f", zExplain, nToken, colscore); } } if( isExplain ){ sqlite3_result_text(pCtx, sqlite3_mprintf( "%z
= %.4f
", zExplain, score ), -1, sqlite3_free); }else{ sqlite3_result_double(pCtx, score); } return; wna: sqlite3_result_error(pCtx,"wrong number of arguments to function rank()",-1); } int Sqlite3_Init(Tcl_Interp *interp); static int initDb(sqlite3 *db, char **pzErr, void *p){ sqlite3_create_function(db, "rank",-1, SQLITE_UTF8, 0, rankfunc,0,0); sqlite3_create_function(db, "erank", -1, SQLITE_UTF8, (void*)1, rankfunc,0,0); } static int AppInit(Tcl_Interp *interp) { int rc; rc = Sqlite3_Init(interp); if( rc!=TCL_OK ) return rc; sqlite3_auto_extension(initDb); return TCL_OK; } int main(int argc, char *argv[]) { Tcl_Main(argc, argv, AppInit); return 0; }