/ Check-in [a85fc877]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the new experimental sqlite3_auto_extension() API. (CVS 3362)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a85fc877eb8c92bbb79ac9b7fa91fb362f37cdf7
User & Date: drh 2006-08-23 20:07:21
Context
2006-08-23
23:58
A first implementation of a full-text search module for SQLite. (CVS 3363) check-in: b0d8e0d3 user: adamd tags: trunk
20:07
Add the new experimental sqlite3_auto_extension() API. (CVS 3362) check-in: a85fc877 user: drh tags: trunk
2006-08-22
23:53
Add argc as a default global to match standard tcl environment. (CVS 3361) check-in: 53315409 user: shess tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.in.

204
205
206
207
208
209
210

211
212
213
214
215
216
217
  $(TOP)/src/test2.c \
  $(TOP)/src/test3.c \
  $(TOP)/src/test4.c \
  $(TOP)/src/test5.c \
  $(TOP)/src/test6.c \
  $(TOP)/src/test7.c \
  $(TOP)/src/test8.c \

  $(TOP)/src/test_async.c \
  $(TOP)/src/test_md5.c \
  $(TOP)/src/test_schema.c \
  $(TOP)/src/test_server.c \
  $(TOP)/src/test_tclvar.c \
  $(TOP)/src/utf.c \
  $(TOP)/src/util.c \







>







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  $(TOP)/src/test2.c \
  $(TOP)/src/test3.c \
  $(TOP)/src/test4.c \
  $(TOP)/src/test5.c \
  $(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 \
  $(TOP)/src/test_server.c \
  $(TOP)/src/test_tclvar.c \
  $(TOP)/src/utf.c \
  $(TOP)/src/util.c \

Changes to main.mk.

137
138
139
140
141
142
143

144
145
146
147
148
149
150
  $(TOP)/src/test2.c \
  $(TOP)/src/test3.c \
  $(TOP)/src/test4.c \
  $(TOP)/src/test5.c \
  $(TOP)/src/test6.c \
  $(TOP)/src/test7.c \
  $(TOP)/src/test8.c \

  $(TOP)/src/test_async.c \
  $(TOP)/src/test_md5.c \
  $(TOP)/src/test_schema.c \
  $(TOP)/src/test_server.c \
  $(TOP)/src/test_tclvar.c \
  $(TOP)/src/utf.c \
  $(TOP)/src/util.c \







>







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  $(TOP)/src/test2.c \
  $(TOP)/src/test3.c \
  $(TOP)/src/test4.c \
  $(TOP)/src/test5.c \
  $(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 \
  $(TOP)/src/test_server.c \
  $(TOP)/src/test_tclvar.c \
  $(TOP)/src/utf.c \
  $(TOP)/src/util.c \

Changes to src/loadext.c.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
...
347
348
349
350
351
352
353
354

















































































355
** the SQLite library.
*/
#ifndef SQLITE_OMIT_LOAD_EXTENSION

#define SQLITE_CORE 1  /* Disable the API redefinition in sqlite3ext.h */
#include "sqlite3ext.h"
#include "sqliteInt.h"

#include <string.h>
#include <ctype.h>

/*
** Some API routines are omitted when various features are
** excluded from a build of SQLite.  Substitute a NULL pointer
** for any missing APIs.
................................................................................
**
** Extensions that use newer APIs should first call the
** sqlite3_libversion_number() to make sure that the API they
** intend to use is supported by the library.  Extensions should
** also check to make sure that the pointer to the function is
** not NULL before calling it.
*/
const sqlite3_api_routines sqlite3_api = {
  sqlite3_aggregate_context,
  sqlite3_aggregate_count,
  sqlite3_bind_blob,
  sqlite3_bind_double,
  sqlite3_bind_int,
  sqlite3_bind_int64,
  sqlite3_bind_null,
................................................................................
  if( xInit==0 ){
    if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]",
                                   zProc, zFile);
    }
    SQLITE_CLOSE_LIBRARY(handle);
    return SQLITE_ERROR;
  }else if( xInit(db, &zErrmsg, &sqlite3_api) ){
    if( pzErrMsg ){
      *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
    }
    sqlite3_free(zErrmsg);
    SQLITE_CLOSE_LIBRARY(handle);
    return SQLITE_ERROR;
  }
................................................................................
  if( onoff ){
    db->flags |= SQLITE_LoadExtension;
  }else{
    db->flags &= ~SQLITE_LoadExtension;
  }
  return SQLITE_OK;
}


















































































#endif /* SQLITE_OMIT_LOAD_EXTENSION */







>







 







|







 







|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
** the SQLite library.
*/
#ifndef SQLITE_OMIT_LOAD_EXTENSION

#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>

/*
** Some API routines are omitted when various features are
** excluded from a build of SQLite.  Substitute a NULL pointer
** for any missing APIs.
................................................................................
**
** Extensions that use newer APIs should first call the
** sqlite3_libversion_number() to make sure that the API they
** intend to use is supported by the library.  Extensions should
** also check to make sure that the pointer to the function is
** not NULL before calling it.
*/
const sqlite3_api_routines sqlite3_apis = {
  sqlite3_aggregate_context,
  sqlite3_aggregate_count,
  sqlite3_bind_blob,
  sqlite3_bind_double,
  sqlite3_bind_int,
  sqlite3_bind_int64,
  sqlite3_bind_null,
................................................................................
  if( xInit==0 ){
    if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]",
                                   zProc, zFile);
    }
    SQLITE_CLOSE_LIBRARY(handle);
    return SQLITE_ERROR;
  }else if( xInit(db, &zErrmsg, &sqlite3_apis) ){
    if( pzErrMsg ){
      *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
    }
    sqlite3_free(zErrmsg);
    SQLITE_CLOSE_LIBRARY(handle);
    return SQLITE_ERROR;
  }
................................................................................
  if( onoff ){
    db->flags |= SQLITE_LoadExtension;
  }else{
    db->flags &= ~SQLITE_LoadExtension;
  }
  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 */

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
907
908
909
910
911
912
913





914
915
916
917
918
919
920
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** 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 $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
  ** is accessed.
  */
  if( !sqlite3MallocFailed() ){
    sqlite3RegisterBuiltinFunctions(db);
    sqlite3Error(db, SQLITE_OK, 0);
  }
  db->magic = SQLITE_MAGIC_OPEN;






opendb_out:
  if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
    sqlite3_close(db);
    db = 0;
  }
  *ppDb = db;







|







 







>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.355 2006/08/23 20:07:22 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
  ** is accessed.
  */
  if( !sqlite3MallocFailed() ){
    sqlite3RegisterBuiltinFunctions(db);
    sqlite3Error(db, SQLITE_OK, 0);
  }
  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);
    db = 0;
  }
  *ppDb = db;

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1512
1513
1514
1515
1516
1517
1518




































1519
1520
1521
1522
1523
1524
1525
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** 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 $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** API is provided to turn the extension loading mechanism on and
** off.  It is off by default.  See ticket #1863.
**
** Call this routine with onoff==1 to turn extension loading on
** and call it with onoff==0 to turn it back off again.
*/
int sqlite3_enable_load_extension(sqlite3 *db, int onoff);





































/*
****** EXPERIMENTAL - subject to change without notice **************
**
** The interface to the virtual-table mechanism is currently considered
** to be experimental.  The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.188 2006/08/23 20:07:22 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** API is provided to turn the extension loading mechanism on and
** off.  It is off by default.  See ticket #1863.
**
** Call this routine with onoff==1 to turn extension loading on
** and call it with onoff==0 to turn it back off again.
*/
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 **************
**
** The interface to the virtual-table mechanism is currently considered
** to be experimental.  The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1817
1818
1819
1820
1821
1822
1823

1824
1825

1826
1827
1828
1829
1830
1831
1832
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.523 2006/07/26 13:43:31 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
int sqlite3MallocFailed(void);
void sqlite3FailedMalloc(void);
void sqlite3AbortOtherActiveVdbes(sqlite3 *, Vdbe *);
int sqlite3OpenTempDatabase(Parse *);

#ifndef SQLITE_OMIT_LOAD_EXTENSION
  void sqlite3CloseExtensions(sqlite3*);

#else
# define sqlite3CloseExtensions(X)

#endif

#ifndef SQLITE_OMIT_SHARED_CACHE
  void sqlite3TableLock(Parse *, int, int, u8, const char *);
#else
  #define sqlite3TableLock(v,w,x,y,z)
#endif







|







 







>


>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.524 2006/08/23 20:07:22 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
int sqlite3MallocFailed(void);
void sqlite3FailedMalloc(void);
void sqlite3AbortOtherActiveVdbes(sqlite3 *, Vdbe *);
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
  void sqlite3TableLock(Parse *, int, int, u8, const char *);
#else
  #define sqlite3TableLock(v,w,x,y,z)
#endif

Changes to src/tclsqlite.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
....
2196
2197
2198
2199
2200
2201
2202

2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214

2215
2216
2217
2218
2219
2220
2221
**    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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.166 2006/08/22 23:53:46 shess Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
................................................................................
    }
    zConflict = Tcl_GetStringFromObj(objv[2], 0);
    zTable = Tcl_GetStringFromObj(objv[3], 0);
    zFile = Tcl_GetStringFromObj(objv[4], 0);
    nSep = strlen(zSep);
    nNull = strlen(zNull);
    if( nSep==0 ){
      Tcl_AppendResult(interp, "Error: non-null separator required for copy", 0);
      return TCL_ERROR;
    }
    if(sqlite3StrICmp(zConflict, "rollback") != 0 &&
       sqlite3StrICmp(zConflict, "abort"   ) != 0 &&
       sqlite3StrICmp(zConflict, "fail"    ) != 0 &&
       sqlite3StrICmp(zConflict, "ignore"  ) != 0 &&
       sqlite3StrICmp(zConflict, "replace" ) != 0 ) {
................................................................................
    extern int Sqlitetest7_Init(Tcl_Interp*);
    extern int Sqlitetest8_Init(Tcl_Interp*);
    extern int Md5_Init(Tcl_Interp*);
    extern int Sqlitetestsse_Init(Tcl_Interp*);
    extern int Sqlitetestasync_Init(Tcl_Interp*);
    extern int Sqlitetesttclvar_Init(Tcl_Interp*);
    extern int Sqlitetestschema_Init(Tcl_Interp*);


    Sqlitetest1_Init(interp);
    Sqlitetest2_Init(interp);
    Sqlitetest3_Init(interp);
    Sqlitetest4_Init(interp);
    Sqlitetest5_Init(interp);
    Sqlitetest6_Init(interp);
    Sqlitetest7_Init(interp);
    Sqlitetest8_Init(interp);
    Sqlitetestasync_Init(interp);
    Sqlitetesttclvar_Init(interp);
    Sqlitetestschema_Init(interp);

    Md5_Init(interp);
#ifdef SQLITE_SSE
    Sqlitetestsse_Init(interp);
#endif
  }
#endif
  if( argc>=2 || TCLSH==2 ){







|







 







|







 







>












>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
....
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
**    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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $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 */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
................................................................................
    }
    zConflict = Tcl_GetStringFromObj(objv[2], 0);
    zTable = Tcl_GetStringFromObj(objv[3], 0);
    zFile = Tcl_GetStringFromObj(objv[4], 0);
    nSep = strlen(zSep);
    nNull = strlen(zNull);
    if( nSep==0 ){
      Tcl_AppendResult(interp,"Error: non-null separator required for copy",0);
      return TCL_ERROR;
    }
    if(sqlite3StrICmp(zConflict, "rollback") != 0 &&
       sqlite3StrICmp(zConflict, "abort"   ) != 0 &&
       sqlite3StrICmp(zConflict, "fail"    ) != 0 &&
       sqlite3StrICmp(zConflict, "ignore"  ) != 0 &&
       sqlite3StrICmp(zConflict, "replace" ) != 0 ) {
................................................................................
    extern int Sqlitetest7_Init(Tcl_Interp*);
    extern int Sqlitetest8_Init(Tcl_Interp*);
    extern int Md5_Init(Tcl_Interp*);
    extern int Sqlitetestsse_Init(Tcl_Interp*);
    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);
    Sqlitetest3_Init(interp);
    Sqlitetest4_Init(interp);
    Sqlitetest5_Init(interp);
    Sqlitetest6_Init(interp);
    Sqlitetest7_Init(interp);
    Sqlitetest8_Init(interp);
    Sqlitetestasync_Init(interp);
    Sqlitetesttclvar_Init(interp);
    Sqlitetestschema_Init(interp);
    Sqlitetest_autoext_Init(interp);
    Md5_Init(interp);
#ifdef SQLITE_SSE
    Sqlitetestsse_Init(interp);
#endif
  }
#endif
  if( argc>=2 || TCLSH==2 ){

Added src/test_autoext.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
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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;
}

Changes to test/loadext.test.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
#    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.7 2006/07/06 17:08:48 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# The name of the test extension varies by operating system.
#
if {$::tcl_platform(platform) eq "windows"} {







|

|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
#    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 extension loading.
#
# $Id: loadext.test,v 1.8 2006/08/23 20:07:22 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# The name of the test extension varies by operating system.
#
if {$::tcl_platform(platform) eq "windows"} {

Added test/loadext2.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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