]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the new experimental sqlite3_auto_extension() API. (CVS 3362)
authordrh <drh@noemail.net>
Wed, 23 Aug 2006 20:07:20 +0000 (20:07 +0000)
committerdrh <drh@noemail.net>
Wed, 23 Aug 2006 20:07:20 +0000 (20:07 +0000)
FossilOrigin-Name: a85fc877eb8c92bbb79ac9b7fa91fb362f37cdf7

12 files changed:
Makefile.in
main.mk
manifest
manifest.uuid
src/loadext.c
src/main.c
src/sqlite.h.in
src/sqliteInt.h
src/tclsqlite.c
src/test_autoext.c [new file with mode: 0644]
test/loadext.test
test/loadext2.test [new file with mode: 0644]

index de84ca63924db1127e4692d16a1af61744808b3a..6e4a7b797da32a877d6e5550690dd786704cd025 100644 (file)
@@ -208,6 +208,7 @@ TESTSRC = \
   $(TOP)/src/test6.c \
   $(TOP)/src/test7.c \
   $(TOP)/src/test8.c \
+  $(TOP)/src/test_autoext.c \
   $(TOP)/src/test_async.c \
   $(TOP)/src/test_md5.c \
   $(TOP)/src/test_schema.c \
diff --git a/main.mk b/main.mk
index 8bf95af7a80702193b3de3118a8a3bb717e20aef..291f5a5acd17792fd62c9085e9feddcedd5a722f 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -141,6 +141,7 @@ TESTSRC = \
   $(TOP)/src/test6.c \
   $(TOP)/src/test7.c \
   $(TOP)/src/test8.c \
+  $(TOP)/src/test_autoext.c \
   $(TOP)/src/test_async.c \
   $(TOP)/src/test_md5.c \
   $(TOP)/src/test_schema.c \
index bb3019c64a8a00e7ddf41e69aec18f002cc0fc9e..9d1f1d1ffaf37e99f9d65b92238ba10356235086 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,6 +1,6 @@
-C Add\sargc\sas\sa\sdefault\sglobal\sto\smatch\sstandard\stcl\senvironment.\s(CVS\s3361)
-D 2006-08-22T23:53:46
-F Makefile.in 986db66b0239b460fc118e7d2fa88b45b26c444e
+C Add\sthe\snew\sexperimental\ssqlite3_auto_extension()\sAPI.\s(CVS\s3362)
+D 2006-08-23T20:07:21
+F Makefile.in 8e7f9ecebab2c6e0f3db20ff129a8f9405ab64f8
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
 F VERSION ef6abd4b2095b0f378b428ed251e16f0213fcf3f
@@ -21,7 +21,7 @@ F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
-F main.mk bfa218fe52af316390bb344f8660241d90f277dd
+F main.mk 22a0c92f24ffc377c41ac9d7d63ae3cbb813e532
 F mkdll.sh 919df5efde876194e3102c6ebc60657d38949909
 F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
 F mkopcodeh.awk cde995d269aa06c94adbf6455bea0acedb913fa5
@@ -50,8 +50,8 @@ F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
 F src/insert.c 63f01d3f4e0ba7ed171934a24aece2191824faec
 F src/legacy.c 10e01a902d7f2c872c7922fedf19a2df70935857
-F src/loadext.c 040853b36adf535bba6a2e9f5d921422a4394baf
-F src/main.c 3690d4a440c0bfba7b4816d52869e17b9adccb58
+F src/loadext.c 7a41142266dd2570fedf00108e1772047f98a673
+F src/main.c 96ab5f29fe903aa8a28f6e1463a3b8245bf1c416
 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
 F src/os.c 59f05de8c5777c34876607114a2fbe55ae578235
 F src/os.h 3fd6a022bafd620fdfd779a51dccb42f31c97f75
@@ -74,11 +74,11 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
 F src/select.c 0d4724930a1f34c747105ed1802fa4af0d8eb519
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c bc41feffb59676885368b7be5104e7d65ddb55d3
-F src/sqlite.h.in 432848ac7f8d7e6fea727668acccec62bdd86cc4
+F src/sqlite.h.in 181d04022bcf63a6e8a9111848940512344f41ab
 F src/sqlite3ext.h 11a046b3519c4b9b7709e6d6a95c3a36366f684a
-F src/sqliteInt.h 85975cbb95777f619fd76f1ba728022f13321e1b
+F src/sqliteInt.h 325a2d45be2b22c1e21ad649e0a898c74eaec7de
 F src/table.c d8817f43a6c6bf139487db161760b9e1e02da3f1
-F src/tclsqlite.c 7eb16876ab49d267a28a9ba0fdb84f5639e0949e
+F src/tclsqlite.c 61342fafe17a49e3e613f3b4703b41cab3bf824d
 F src/test1.c 535294d7f21a4127082c4f7a57f225482df9cc36
 F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
 F src/test3.c 85135c09560c48bdb0a23c9b890ab405486b8ec9
@@ -88,6 +88,7 @@ F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
 F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
 F src/test8.c 56d891ac9a37d1e1e941d9da7307e8d757a7b8e1
 F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3
+F src/test_autoext.c bbb70bc1c83bd273cf59908ca9b486ae5df55a59
 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
 F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
 F src/test_schema.c 8b2aaa9136edf3187a51166849c2de0aaaa27ce5
@@ -198,7 +199,8 @@ F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
 F test/laststmtchanges.test 19a6d0c11f7a31dc45465b495f7b845a62cbec17
 F test/like.test 5f7d76574752a9101cac13372c8a85999d0d91e6
 F test/limit.test 2a87b9cb2165abb49ca0ddcf5cb43cf24074581f
-F test/loadext.test 6e4ecf99ec26334768c63b4322177b5e147f006a
+F test/loadext.test bee44cf7c6d54c5a46650bb2a1b0d778bcd34034
+F test/loadext2.test 4472af96306b127b378a1b2026fe15ed5863f9cf
 F test/lock.test 6825aea0b5885578b1b63a3b178803842c4ee9f1
 F test/lock2.test d83ba79d3c4fffdb5b926c7d8ca7a36c34288a55
 F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
@@ -379,7 +381,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 7f152f9f3a647d30874f2da46ce93a1e31ea7cf3
-R cba7bc9ab66dad7b20373ff0d772e84a
-U shess
-Z 305d02f352f76b62ef3fbc17bad7eb56
+P 533154099c9fe1238705eea03aba388dd71dc35e
+R 6e117482355c04ea4130650a5df55269
+U drh
+Z 4fd4520cd0f576a9a4485f55b2ce4752
index be9908aa1af091f367a018317181d1e03186c719..994196aae61a95204418d454b38bde4ab8a1566d 100644 (file)
@@ -1 +1 @@
-533154099c9fe1238705eea03aba388dd71dc35e
\ No newline at end of file
+a85fc877eb8c92bbb79ac9b7fa91fb362f37cdf7
\ No newline at end of file
index 60ec053cfbec34b675b3712fdf4655869f74974c..81f6856d52f279eb52d71ab1dafe93aa566ce4af 100644 (file)
@@ -17,6 +17,7 @@
 #define SQLITE_CORE 1  /* Disable the API redefinition in sqlite3ext.h */
 #include "sqlite3ext.h"
 #include "sqliteInt.h"
+#include "os.h"
 #include <string.h>
 #include <ctype.h>
 
@@ -89,7 +90,7 @@
 ** also check to make sure that the pointer to the function is
 ** not NULL before calling it.
 */
-const sqlite3_api_routines sqlite3_api = {
+const sqlite3_api_routines sqlite3_apis = {
   sqlite3_aggregate_context,
   sqlite3_aggregate_count,
   sqlite3_bind_blob,
@@ -294,7 +295,7 @@ int sqlite3_load_extension(
     }
     SQLITE_CLOSE_LIBRARY(handle);
     return SQLITE_ERROR;
-  }else if( xInit(db, &zErrmsg, &sqlite3_api) ){
+  }else if( xInit(db, &zErrmsg, &sqlite3_apis) ){
     if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
     }
@@ -352,4 +353,85 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
   return SQLITE_OK;
 }
 
+/*
+** A list of automatically loaded extensions.
+**
+** This list is shared across threads, so be sure to hold the
+** mutex while accessing or changing it.
+*/
+static int nAutoExtension = 0;
+static void **aAutoExtension = 0;
+
+
+/*
+** Register a statically linked extension that is automatically
+** loaded by every new database connection.
+*/
+int sqlite3_auto_extension(void *xInit){
+  int i;
+  int rc = SQLITE_OK;
+  sqlite3OsEnterMutex();
+  for(i=0; i<nAutoExtension; i++){
+    if( aAutoExtension[i]==xInit ) break;
+  }
+  if( i==nAutoExtension ){
+    nAutoExtension++;
+    aAutoExtension = sqlite3Realloc( aAutoExtension,
+                                     nAutoExtension*sizeof(aAutoExtension[0]) );
+    if( aAutoExtension==0 ){
+      nAutoExtension = 0;
+      rc = SQLITE_NOMEM;
+    }else{
+      aAutoExtension[nAutoExtension-1] = xInit;
+    }
+  }
+  sqlite3OsLeaveMutex();  
+  return rc;
+}
+
+/*
+** Reset the automatic extension loading mechanism.
+*/
+void sqlite3_reset_auto_extension(void){
+  sqlite3OsEnterMutex();
+  sqliteFree(aAutoExtension);
+  aAutoExtension = 0;
+  nAutoExtension = 0;
+  sqlite3OsLeaveMutex();
+}
+
+/*
+** Load all automatic extensions.
+*/
+int sqlite3AutoLoadExtensions(sqlite3 *db){
+  int i;
+  int go = 1;
+  int rc = SQLITE_OK;
+  int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
+
+  if( nAutoExtension==0 ){
+    /* Common case: early out without every having to acquire a mutex */
+    return SQLITE_OK;
+  }
+  for(i=0; go; i++){
+    char *zErrmsg = 0;
+    sqlite3OsEnterMutex();
+    if( i>=nAutoExtension ){
+      xInit = 0;
+      go = 0;
+    }else{
+      xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
+              aAutoExtension[i];
+    }
+    sqlite3OsLeaveMutex();
+    if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){
+      sqlite3Error(db, SQLITE_ERROR,
+            "automatic extension loading failed: %s", zErrmsg);
+      go = 0;
+      rc = SQLITE_ERROR;
+    }
+  }
+  return rc;
+}
+
 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
index a65b937cb1a841370723f1ce168fe817b02ee400..c9b997dabce9d129ec6a2c5bf62dbcdcae0de9ab 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.354 2006/07/30 20:50:45 drh Exp $
+** $Id: main.c,v 1.355 2006/08/23 20:07:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -912,6 +912,11 @@ static int openDatabase(
   }
   db->magic = SQLITE_MAGIC_OPEN;
 
+  /* Load automatic extensions - extensions that have been registered
+  ** using the sqlite3_automatic_extension() API.
+  */
+  sqlite3AutoLoadExtensions(db);
+
 opendb_out:
   if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
     sqlite3_close(db);
index 70cb8ddecf0f54d48da886e30cd71b0167f469dd..7a32e972fd01367297c7abb31de46104f752e1ca 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.187 2006/07/08 18:09:15 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.188 2006/08/23 20:07:22 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -1517,6 +1517,42 @@ int sqlite3_load_extension(
 */
 int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 
+/*
+****** EXPERIMENTAL - subject to change without notice **************
+**
+** Register an extension entry point that is automatically invoked
+** whenever a new database connection is opened.
+**
+** This API can be invoked at program startup in order to register
+** one or more statically linked extensions that will be available
+** to all new database connections.
+**
+** Duplicate extensions are detected so calling this routine multiple
+** times with the same extension is harmless.
+**
+** This routine stores a pointer to the extension in an array
+** that is obtained from malloc().  If you run a memory leak
+** checker on your program and it reports a leak because of this
+** array, then invoke sqlite3_automatic_extension_reset() prior
+** to shutdown to free the memory.
+**
+** Automatic extensions apply across all threads.
+*/
+int sqlite3_auto_extension(void *xEntryPoint);
+
+
+/*
+****** EXPERIMENTAL - subject to change without notice **************
+**
+** Disable all previously registered automatic extensions.  This
+** routine undoes the effect of all prior sqlite3_automatic_extension()
+** calls.
+**
+** This call disabled automatic extensions in all threads.
+*/
+void sqlite3_reset_auto_extension(void);
+
+
 /*
 ****** EXPERIMENTAL - subject to change without notice **************
 **
index a8a3ce1098fce4d851d31fe4ff67957a0bbf761b..bf571ca90054d0c98af6034bf1a0fd581502a4b6 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.523 2006/07/26 13:43:31 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.524 2006/08/23 20:07:22 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1821,8 +1821,10 @@ int sqlite3OpenTempDatabase(Parse *);
 
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
   void sqlite3CloseExtensions(sqlite3*);
+  int sqlite3AutoLoadExtensions(sqlite3*);
 #else
 # define sqlite3CloseExtensions(X)
+# define sqlite3AutoLoadExtensions(X)  SQLITE_OK
 #endif
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
index c79b942d7292d6a3b0ec8277c98c40a1e94cff2d..5bc6d122c0e71fa0f5199039254087fb40e4befd 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.166 2006/08/22 23:53:46 shess Exp $
+** $Id: tclsqlite.c,v 1.167 2006/08/23 20:07:22 drh Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -1035,7 +1035,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     nSep = strlen(zSep);
     nNull = strlen(zNull);
     if( nSep==0 ){
-      Tcl_AppendResult(interp, "Error: non-null separator required for copy", 0);
+      Tcl_AppendResult(interp,"Error: non-null separator required for copy",0);
       return TCL_ERROR;
     }
     if(sqlite3StrICmp(zConflict, "rollback") != 0 &&
@@ -2200,6 +2200,7 @@ int TCLSH_MAIN(int argc, char **argv){
     extern int Sqlitetestasync_Init(Tcl_Interp*);
     extern int Sqlitetesttclvar_Init(Tcl_Interp*);
     extern int Sqlitetestschema_Init(Tcl_Interp*);
+    extern int Sqlitetest_autoext_Init(Tcl_Interp*);
 
     Sqlitetest1_Init(interp);
     Sqlitetest2_Init(interp);
@@ -2212,6 +2213,7 @@ int TCLSH_MAIN(int argc, char **argv){
     Sqlitetestasync_Init(interp);
     Sqlitetesttclvar_Init(interp);
     Sqlitetestschema_Init(interp);
+    Sqlitetest_autoext_Init(interp);
     Md5_Init(interp);
 #ifdef SQLITE_SSE
     Sqlitetestsse_Init(interp);
diff --git a/src/test_autoext.c b/src/test_autoext.c
new file mode 100644 (file)
index 0000000..08b8eec
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+** 2006 August 23
+**
+** 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_auto_extension() function.
+**
+** $Id: test_autoext.c,v 1.1 2006/08/23 20:07:22 drh Exp $
+*/
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+#include "tcl.h"
+#include "sqlite3ext.h"
+static SQLITE_EXTENSION_INIT1
+
+/*
+** The sqr() SQL function returns the square of its input value.
+*/
+static void sqrFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  double r = sqlite3_value_double(argv[0]);
+  sqlite3_result_double(context, r*r);
+}
+
+/*
+** This is the entry point to register the extension for the sqr() function.
+*/
+static int sqr_init(
+  sqlite3 *db, 
+  char **pzErrMsg, 
+  const sqlite3_api_routines *pApi
+){
+  SQLITE_EXTENSION_INIT2(pApi);
+  sqlite3_create_function(db, "sqr", 1, SQLITE_ANY, 0, sqrFunc, 0, 0);
+  return 0;
+}
+
+/*
+** The cube() SQL function returns the cube of its input value.
+*/
+static void cubeFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  double r = sqlite3_value_double(argv[0]);
+  sqlite3_result_double(context, r*r*r);
+}
+
+/*
+** This is the entry point to register the extension for the cube() function.
+*/
+static int cube_init(
+  sqlite3 *db, 
+  char **pzErrMsg, 
+  const sqlite3_api_routines *pApi
+){
+  SQLITE_EXTENSION_INIT2(pApi);
+  sqlite3_create_function(db, "cube", 1, SQLITE_ANY, 0, cubeFunc, 0, 0);
+  return 0;
+}
+
+/*
+** This is a broken extension entry point
+*/
+static int broken_init(
+  sqlite3 *db, 
+  char **pzErrMsg, 
+  const sqlite3_api_routines *pApi
+){
+  char *zErr;
+  SQLITE_EXTENSION_INIT2(pApi);
+  zErr = sqlite3_mprintf("broken autoext!");
+  *pzErrMsg = zErr;
+  return 1;
+}
+
+/*
+** tclcmd:   sqlite3_auto_extension_sqr
+**
+** Register the "sqr" extension to be loaded automatically.
+*/
+static int autoExtSqrObjCmd(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  sqlite3_auto_extension((void*)sqr_init);
+  return SQLITE_OK;
+}
+
+/*
+** tclcmd:   sqlite3_auto_extension_cube
+**
+** Register the "cube" extension to be loaded automatically.
+*/
+static int autoExtCubeObjCmd(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  sqlite3_auto_extension((void*)cube_init);
+  return SQLITE_OK;
+}
+
+/*
+** tclcmd:   sqlite3_auto_extension_broken
+**
+** Register the broken extension to be loaded automatically.
+*/
+static int autoExtBrokenObjCmd(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  sqlite3_auto_extension((void*)broken_init);
+  return SQLITE_OK;
+}
+
+/*
+** tclcmd:   sqlite3_reset_auto_extension
+**
+** Reset all auto-extensions
+*/
+static int resetAutoExtObjCmd(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  sqlite3_reset_auto_extension();
+  return SQLITE_OK;
+}
+
+
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+
+/*
+** This procedure registers the TCL procs defined in this file.
+*/
+int Sqlitetest_autoext_Init(Tcl_Interp *interp){
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+  Tcl_CreateObjCommand(interp, "sqlite3_auto_extension_sqr",
+          autoExtSqrObjCmd, 0, 0);
+  Tcl_CreateObjCommand(interp, "sqlite3_auto_extension_cube",
+          autoExtCubeObjCmd, 0, 0);
+  Tcl_CreateObjCommand(interp, "sqlite3_auto_extension_broken",
+          autoExtBrokenObjCmd, 0, 0);
+  Tcl_CreateObjCommand(interp, "sqlite3_reset_auto_extension",
+          resetAutoExtObjCmd, 0, 0);
+#endif
+  return TCL_OK;
+}
index 46f71260ed13e0aa65c7c4e84bacc0d5776ff9d6..1990d8c46a4d8903f7eaa28c46d93424421fa641 100644 (file)
@@ -9,9 +9,9 @@
 #
 #***********************************************************************
 # This file implements regression tests for SQLite library.  The
-# focus of this script is in-memory database backend.
+# focus of this script is extension loading.
 #
-# $Id: loadext.test,v 1.7 2006/07/06 17:08:48 drh Exp $
+# $Id: loadext.test,v 1.8 2006/08/23 20:07:22 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
diff --git a/test/loadext2.test b/test/loadext2.test
new file mode 100644 (file)
index 0000000..d692cde
--- /dev/null
@@ -0,0 +1,139 @@
+# 2006 August 23
+#
+# 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 automatic extension loading and the
+# sqlite3_auto_extension() API.
+#
+# $Id: loadext2.test,v 1.1 2006/08/23 20:07:22 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Only run these tests if the approriate APIs are defined
+# in the system under test.
+#
+if {[info command sqlite3_auto_extension_sqr]==""} {
+  finish_test
+  return
+}
+
+
+# None of the extension are loaded by default.
+#
+do_test loadext2-1.1 {
+  catchsql {
+    SELECT sqr(2)
+  }
+} {1 {no such function: sqr}}
+do_test loadext2-1.2 {
+  catchsql {
+    SELECT cube(2)
+  }
+} {1 {no such function: cube}}
+
+# Register auto-loaders.  Still functions do not exist.
+#
+do_test loadext2-1.3 {
+  sqlite3_auto_extension_sqr
+  sqlite3_auto_extension_cube
+  catchsql {
+    SELECT sqr(2)
+  }
+} {1 {no such function: sqr}}
+do_test loadext2-1.4 {
+  catchsql {
+    SELECT cube(2)
+  }
+} {1 {no such function: cube}}
+
+
+# Functions do exist in a new database connection
+#
+do_test loadext2-1.5 {
+  sqlite3 db test.db
+  catchsql {
+    SELECT sqr(2)
+  }
+} {0 4.0}
+do_test loadext2-1.6 {
+  catchsql {
+    SELECT cube(2)
+  }
+} {0 8.0}
+
+
+# Reset extension auto loading.  Existing extensions still exist.
+#
+do_test loadext2-1.7 {
+  sqlite3_reset_auto_extension
+  catchsql {
+    SELECT sqr(2)
+  }
+} {0 4.0}
+do_test loadext2-1.8 {
+  catchsql {
+    SELECT cube(2)
+  }
+} {0 8.0}
+
+
+# Register only the sqr() function.
+#
+do_test loadext2-1.9 {
+  sqlite3_auto_extension_sqr
+  sqlite3 db test.db
+  catchsql {
+    SELECT sqr(2)
+  }
+} {0 4.0}
+do_test loadext2-1.10 {
+  catchsql {
+    SELECT cube(2)
+  }
+} {1 {no such function: cube}}
+
+# Register only the cube() function.
+#
+do_test loadext2-1.11 {
+  sqlite3_reset_auto_extension
+  sqlite3_auto_extension_cube
+  sqlite3 db test.db
+  catchsql {
+    SELECT sqr(2)
+  }
+} {1 {no such function: sqr}}
+do_test loadext2-1.12 {
+  catchsql {
+    SELECT cube(2)
+  }
+} {0 8.0}
+
+# Register a broken entry point.
+#
+do_test loadext2-1.13 {
+  sqlite3_auto_extension_broken
+  set rc [catch {sqlite3 db test.db} errmsg]
+  lappend rc $errmsg
+} {1 {automatic extension loading failed: broken autoext!}}
+do_test loadext2-1.14 {
+  catchsql {
+    SELECT sqr(2)
+  }
+} {1 {no such function: sqr}}
+do_test loadext2-1.15 {
+  catchsql {
+    SELECT cube(2)
+  }
+} {0 8.0}
+
+
+sqlite3_reset_auto_extension
+finish_test