Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add some tests for sqlite3_load_extension(). (CVS 3239) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
402a77c43d4e4dcd2e1197cfaaa2ed51 |
User & Date: | danielk1977 2006-06-14 10:38:03.000 |
Context
2006-06-14
| ||
10:47 | Fix typo in test8.c. (CVS 3240) (check-in: 75be7d4988 user: danielk1977 tags: trunk) | |
10:38 | Add some tests for sqlite3_load_extension(). (CVS 3239) (check-in: 402a77c43d user: danielk1977 tags: trunk) | |
08:48 | Add tests for the new MATCH operator. (CVS 3238) (check-in: b4024c394d user: danielk1977 tags: trunk) | |
Changes
Changes to Makefile.linux-gcc.
︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #### Tools used to build a static library. # AR = ar cr #AR = /opt/mingw/bin/i386-mingw32-ar cr RANLIB = ranlib #RANLIB = /opt/mingw/bin/i386-mingw32-ranlib #### Extra compiler options needed for programs that use the TCL library. # #TCL_FLAGS = #TCL_FLAGS = -DSTATIC_BUILD=1 TCL_FLAGS = -I/home/drh/tcltk/8.4linux #TCL_FLAGS = -I/home/drh/tcltk/8.4win -DSTATIC_BUILD=1 | > > > > > > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #### Tools used to build a static library. # AR = ar cr #AR = /opt/mingw/bin/i386-mingw32-ar cr RANLIB = ranlib #RANLIB = /opt/mingw/bin/i386-mingw32-ranlib MKSHLIB = gcc -shared SO = so SHPREFIX = lib # SO = dll # SHPREFIX = #### Extra compiler options needed for programs that use the TCL library. # #TCL_FLAGS = #TCL_FLAGS = -DSTATIC_BUILD=1 TCL_FLAGS = -I/home/drh/tcltk/8.4linux #TCL_FLAGS = -I/home/drh/tcltk/8.4win -DSTATIC_BUILD=1 |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
395 396 397 398 399 400 401 402 403 404 405 406 407 408 | -e 's,",\\",g' \ -e 's,^,",' \ -e 's,$$,\\n",' \ $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h $(TCCX) $(TCL_FLAGS) -DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_DEBUG=1 -o \ sqlite3_analyzer$(EXE) $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) # Rules used to build documentation # arch.html: $(TOP)/www/arch.tcl tclsh $(TOP)/www/arch.tcl >arch.html autoinc.html: $(TOP)/www/autoinc.tcl | > > > > > > > | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | -e 's,",\\",g' \ -e 's,^,",' \ -e 's,$$,\\n",' \ $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h $(TCCX) $(TCL_FLAGS) -DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_DEBUG=1 -o \ sqlite3_analyzer$(EXE) $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO) $(TEST_EXTENSION): $(TOP)/src/test_loadext.c $(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION) extensiontest: testfixture$(EXE) $(TEST_EXTENSION) ./testfixture$(EXE) $(TOP)/test/loadext.test # Rules used to build documentation # arch.html: $(TOP)/www/arch.tcl tclsh $(TOP)/www/arch.tcl >arch.html autoinc.html: $(TOP)/www/autoinc.tcl |
︙ | ︙ |
Changes to src/loadext.c.
︙ | ︙ | |||
229 230 231 232 233 234 235 | ){ #ifdef SQLITE_LIBRARY_TYPE SQLITE_LIBRARY_TYPE handle; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); char *zErrmsg = 0; SQLITE_LIBRARY_TYPE *aHandle; | < < < < < < < < < < | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | ){ #ifdef SQLITE_LIBRARY_TYPE SQLITE_LIBRARY_TYPE handle; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); char *zErrmsg = 0; SQLITE_LIBRARY_TYPE *aHandle; if( zProc==0 ){ int i, j, n; char *z; char zBuf[200]; n = strlen(zFile); for(i=n-1; i>0 && zFile[i-1]!='/'; i--){} for(j=i; zFile[j] && zFile[j]!='.'; j++){} |
︙ | ︙ | |||
290 291 292 293 294 295 296 297 298 299 300 301 302 303 | if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); } sqlite3_free(zErrmsg); SQLITE_CLOSE_LIBRARY(handle); return SQLITE_ERROR; } ((SQLITE_LIBRARY_TYPE*)db->aExtension)[db->nExtension-1] = handle; return SQLITE_OK; #else if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("extension loading is disabled"); } return SQLITE_ERROR; | > > > > > > > > > > > > > | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); } sqlite3_free(zErrmsg); SQLITE_CLOSE_LIBRARY(handle); return SQLITE_ERROR; } /* Append the new shared library handle to the db->aExtension array. */ db->nExtension++; aHandle = sqliteMalloc(sizeof(handle)*db->nExtension); if( aHandle==0 ){ return SQLITE_NOMEM; } if( db->nExtension>0 ){ memcpy(aHandle, db->aExtension, sizeof(handle)*(db->nExtension-1)); } sqliteFree(db->aExtension); db->aExtension = aHandle; ((SQLITE_LIBRARY_TYPE*)db->aExtension)[db->nExtension-1] = handle; return SQLITE_OK; #else if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("extension loading is disabled"); } return SQLITE_ERROR; |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.211 2006/06/14 10:38:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 | Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(primarykey)); Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(autoincrement)); Tcl_SetObjResult(interp, pRet); return TCL_OK; } #endif /* ** Usage: sqlite_abort ** ** Shutdown the process immediately. This is not a clean shutdown. ** This command is used to test the recoverability of a database in ** the event of a program crash. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 | Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(primarykey)); Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(autoincrement)); Tcl_SetObjResult(interp, pRet); return TCL_OK; } #endif /* ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC? */ static int test_load_extension( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ Tcl_CmdInfo cmdInfo; sqlite3 *db; int rc; char *zDb; char *zFile; char *zProc = 0; char *zErr = 0; if( objc!=4 && objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE FILE ?PROC?"); return TCL_ERROR; } zDb = Tcl_GetString(objv[1]); zFile = Tcl_GetString(objv[2]); if( objc==4 ){ zProc = Tcl_GetString(objv[3]); } /* Extract the C database handle from the Tcl command name */ if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){ Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0); return TCL_ERROR; } db = ((struct SqliteDb*)cmdInfo.objClientData)->db; assert(db); /* Call the underlying C function. If an error occurs, set rc to ** TCL_ERROR and load any error string into the interpreter. If no ** error occurs, set rc to TCL_OK. */ rc = sqlite3_load_extension(db, zFile, zProc, &zErr); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, zErr ? zErr : "", TCL_VOLATILE); rc = TCL_ERROR; }else{ rc = TCL_OK; } sqlite3_free(zErr); return rc; } /* ** Usage: sqlite_abort ** ** Shutdown the process immediately. This is not a clean shutdown. ** This command is used to test the recoverability of a database in ** the event of a program crash. |
︙ | ︙ | |||
3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 | #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; int i; extern int sqlite3_os_trace; extern int sqlite3_where_trace; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; | > > > | 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 | #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION { "sqlite3_load_extension", test_load_extension, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; int i; extern int sqlite3_os_trace; extern int sqlite3_where_trace; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; |
︙ | ︙ |
Added src/test_loadext.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* ** 2006 June 14 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Test extension for testing the sqlite3_load_extension() function. ** ** $Id: test_loadext.c,v 1.1 2006/06/14 10:38:03 danielk1977 Exp $ */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 /* ** The half() SQL function returns half of its input value. */ static void halfFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ sqlite3_result_double(context, 0.5*sqlite3_value_double(argv[0])); } /* ** Extension load function. */ int testloadext_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi); sqlite3_create_function(db, "half", 1, SQLITE_ANY, 0, halfFunc, 0, 0); return 0; } /* ** Another extension entry point. This one always fails. */ int testbrokenext_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ char *zErr; SQLITE_EXTENSION_INIT2(pApi); zErr = sqlite3_mprintf("broken!"); *pzErrMsg = zErr; return 1; } |
Added test/loadext.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | # 2006 July 14 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is in-memory database backend. # # $Id: loadext.test,v 1.1 2006/06/14 10:38:03 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl if {$::tcl_platform(platform) eq "windows"} { set testextension testloadext.dll } else { set testextension libtestloadext.so } if {![file exists $testextension]} { puts "Skipping loadext tests: Test extension not built..." finish_test return } # Test that loading the extension produces the expected results - adding # the half() function to the specified database handle. # do_test loadext-1.1 { catchsql { SELECT half(1.0); } } {1 {no such function: half}} do_test loadext-1.2 { sqlite3_load_extension db $testextension catchsql { SELECT half(1.0); } } {0 0.5} # Test that a second database connection (db2) can load the extension also. # do_test loadext-1.3 { sqlite3 db2 test.db catchsql { SELECT half(1.0); } db2 } {1 {no such function: half}} do_test loadext-1.4 { sqlite3_load_extension db2 $testextension catchsql { SELECT half(1.0); } db2 } {0 0.5} # Close the first database connection. Then check that the second database # can still use the half() function without a problem. # do_test loadext-1.5 { db close catchsql { SELECT half(1.0); } db2 } {0 0.5} db2 close sqlite3 db test.db # Try to load an extension for which the file does not exist. # do_test loadext-2.1 { set rc [catch { sqlite3_load_extension db "xx${testextension}" } msg] list $rc $msg } [list 1 [subst -nocommands \ {unable to open shared library [xx${testextension}]} ]] # Try to load an extension for which the file is not a shared object # do_test loadext-2.2 { set fd [open "xx${testextension}" w] puts $fd blah close $fd set rc [catch { sqlite3_load_extension db "xx${testextension}" } msg] list $rc $msg } [list 1 [subst -nocommands \ {unable to open shared library [xx${testextension}]} ]] # Try to load an extension for which the file is present but the # entry point is not. # do_test loadext-2.3 { set rc [catch { sqlite3_load_extension db $testextension icecream } msg] list $rc $msg } [list 1 [subst -nocommands \ {no entry point [icecream] in shared library [$testextension]} ]] # Try to load an extension for which the entry point fails (returns non-zero) # do_test loadext-2.4 { set rc [catch { sqlite3_load_extension db $testextension testbrokenext_init } msg] list $rc $msg } {1 {error during initialization: broken!}} finish_test |
Changes to test/quick.test.
1 2 3 4 5 6 7 8 | # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file runs all tests. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file runs all tests. # # $Id: quick.test,v 1.44 2006/06/14 10:38:03 danielk1977 Exp $ proc lshift {lvar} { upvar $lvar l set ret [lindex $l 0] set l [lrange $l 1 end] return $ret } |
︙ | ︙ | |||
39 40 41 42 43 44 45 46 47 48 49 50 51 52 | btree2.test btree3.test btree4.test btree5.test btree6.test corrupt.test crash.test malloc.test malloc2.test malloc3.test memleak.test misuse.test quick.test | > | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | btree2.test btree3.test btree4.test btree5.test btree6.test corrupt.test crash.test loadext.test malloc.test malloc2.test malloc3.test memleak.test misuse.test quick.test |
︙ | ︙ |