#include #include #include /** A simple example of writing a custom SQL function for sqlite3. It provides results of a so-called Fudge-dice roll. Fudge dice (dF) are used by the Fudge roleplaying system (http://fudgerpg.com). Call it with 0, 1 or 2 arguments: 0 args: same as calling dF(4). 1 arg: arg1 is an integer telling how many dice to roll. 2 args: arg2 is any value. The TYPE of the value is used to dynamically set the return type. If arg2 is an INTEGER (the default) or DOUBLE then a number of the appropriate type is returned to the caller via sqlite_result_xxx(context,...). If arg2 is a string then a description showing the results of each die roll of the set, plus the total, is sent back. You may bind this function to your db by calling something like: sqlite3_create_function( myDb, "dF",-1,SQLITE_ANY,0,sqlite_func_dF,0, 0 ); Author: stephan at s11n dot net License: Public Domain */ void sqlite_func_dF( sqlite3_context *context, int argc, sqlite3_value **argv ) { static bool seeded = false; if( !seeded && (seeded=true) ) { srand( time(NULL) ); } if( argc > 2 ) { sqlite3_result_error( context, "dF() function requires 0, 1, or 2 arguments: (0==roll 4dF and return int), (1==roll [ARG0]dF and return int), (2=roll [ARG0]dF and return result as TYPEOF(ARG1))", -1 ); return; } int count = 0; int returnT = (argc<2) ? SQLITE_INTEGER : sqlite3_value_type(argv[1]); if( 0 == argc ) { count = 4; } else { count = sqlite3_value_int(argv[0]); } if( count < 1 ) count = 4; int reti = 0; std::ostringstream rets; if( SQLITE_TEXT == returnT ) { rets << count << "dF: "; } { int rnd; char marker; while( count-- ) { rnd = rand() % 3 - 1; if( SQLITE_TEXT == returnT ) { marker = ((0==rnd) ? '0' : ((1==rnd) ? '+' : '-')); rets << marker << ' '; } reti += rnd; } } if( SQLITE_TEXT == returnT ) { rets << " = "<