15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2009 August 17
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The code in this file is used for testing SQLite. It is not part of
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the source code used in production systems.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Specifically, this file tests the effect of errors while initializing
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the various pluggable sub-systems from within sqlite3_initialize().
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If an error occurs in sqlite3_initialize() the following should be
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** true:
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   1) An error code is returned to the user, and
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   2) A subsequent call to sqlite3_shutdown() calls the shutdown method
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      of those subsystems that were initialized, and
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   3) A subsequent call to sqlite3_initialize() attempts to initialize
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      the remaining, uninitialized, subsystems.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <tcl.h>
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct Wrapped {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_pcache_methods pcache;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mem_methods    mem;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_methods  mutex;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mem_init;                /* True if mem subsystem is initalized */
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mem_fail;                /* True to fail mem subsystem inialization */
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mutex_init;              /* True if mutex subsystem is initalized */
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mutex_fail;              /* True to fail mutex subsystem inialization */
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pcache_init;             /* True if pcache subsystem is initalized */
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pcache_fail;             /* True to fail pcache subsystem inialization */
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} wrapped;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrMemInit(void *pAppData){
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( wrapped.mem_fail ){
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = SQLITE_ERROR;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = wrapped.mem.xInit(wrapped.mem.pAppData);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrapped.mem_init = 1;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrMemShutdown(void *pAppData){
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mem.xShutdown(wrapped.mem.pAppData);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mem_init = 0;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *wrMemMalloc(int n)           {return wrapped.mem.xMalloc(n);}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrMemFree(void *p)            {wrapped.mem.xFree(p);}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *wrMemRealloc(void *p, int n) {return wrapped.mem.xRealloc(p, n);}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrMemSize(void *p)             {return wrapped.mem.xSize(p);}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrMemRoundup(int n)            {return wrapped.mem.xRoundup(n);}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrMutexInit(void){
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( wrapped.mutex_fail ){
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = SQLITE_ERROR;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = wrapped.mutex.xMutexInit();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrapped.mutex_init = 1;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrMutexEnd(void){
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mutex.xMutexEnd();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mutex_init = 0;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SQLITE_OK;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_mutex *wrMutexAlloc(int e){
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return wrapped.mutex.xMutexAlloc(e);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrMutexFree(sqlite3_mutex *p){
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mutex.xMutexFree(p);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrMutexEnter(sqlite3_mutex *p){
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mutex.xMutexEnter(p);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrMutexTry(sqlite3_mutex *p){
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return wrapped.mutex.xMutexTry(p);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrMutexLeave(sqlite3_mutex *p){
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mutex.xMutexLeave(p);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrMutexHeld(sqlite3_mutex *p){
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return wrapped.mutex.xMutexHeld(p);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrMutexNotheld(sqlite3_mutex *p){
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return wrapped.mutex.xMutexNotheld(p);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrPCacheInit(void *pArg){
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( wrapped.pcache_fail ){
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = SQLITE_ERROR;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrapped.pcache_init = 1;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrPCacheShutdown(void *pArg){
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.pcache.xShutdown(wrapped.pcache.pArg);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.pcache_init = 0;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_pcache *wrPCacheCreate(int a, int b){
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return wrapped.pcache.xCreate(a, b);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrPCacheCachesize(sqlite3_pcache *p, int n){
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.pcache.xCachesize(p, n);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wrPCachePagecount(sqlite3_pcache *p){
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return wrapped.pcache.xPagecount(p);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return wrapped.pcache.xFetch(p, a, b);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrPCacheUnpin(sqlite3_pcache *p, void *a, int b){
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.pcache.xUnpin(p, a, b);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrPCacheRekey(sqlite3_pcache *p, void *a, unsigned b, unsigned c){
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.pcache.xRekey(p, a, b, c);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.pcache.xTruncate(p, a);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wrPCacheDestroy(sqlite3_pcache *p){
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.pcache.xDestroy(p);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void installInitWrappers(void){
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_methods mutexmethods = {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrMutexInit,  wrMutexEnd,   wrMutexAlloc,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrMutexFree,  wrMutexEnter, wrMutexTry,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrMutexLeave, wrMutexHeld,  wrMutexNotheld
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_pcache_methods pcachemethods = {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrPCacheInit,      wrPCacheShutdown,  wrPCacheCreate,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrPCacheUnpin,     wrPCacheRekey,     wrPCacheTruncate,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrPCacheDestroy
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mem_methods memmethods = {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrMemMalloc,   wrMemFree,    wrMemRealloc,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrMemSize,     wrMemRoundup, wrMemInit,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrMemShutdown,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&wrapped, 0, sizeof(wrapped));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_shutdown();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_GETPCACHE, &wrapped.pcache);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_PCACHE, &pcachemethods);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int init_wrapper_install(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientData clientData, /* Unused */
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,              /* Number of arguments */
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]  /* Command arguments */
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  installInitWrappers();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=1; i<objc; i++){
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *z = Tcl_GetString(objv[i]);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( strcmp(z, "mem")==0 ){
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wrapped.mem_fail = 1;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else if( strcmp(z, "mutex")==0 ){
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wrapped.mutex_fail = 1;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else if( strcmp(z, "pcache")==0 ){
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wrapped.pcache_fail = 1;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"");
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TCL_ERROR;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int init_wrapper_uninstall(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientData clientData, /* Unused */
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,              /* Number of arguments */
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]  /* Command arguments */
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&wrapped, 0, sizeof(&wrapped));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_shutdown();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_config(SQLITE_CONFIG_PCACHE, &wrapped.pcache);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int init_wrapper_clear(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientData clientData, /* Unused */
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,              /* Number of arguments */
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]  /* Command arguments */
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mem_fail = 0;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.mutex_fail = 0;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wrapped.pcache_fail = 0;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int init_wrapper_query(
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientData clientData, /* Unused */
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,              /* Number of arguments */
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]  /* Command arguments */
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *pRet;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pRet = Tcl_NewObj();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( wrapped.mutex_init ){
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mutex", -1));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( wrapped.mem_init ){
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mem", -1));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( wrapped.pcache_init ){
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("pcache", -1));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, pRet);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest_init_Init(Tcl_Interp *interp){
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static struct {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     char *zName;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     Tcl_ObjCmdProc *xProc;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aObjCmd[] = {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"init_wrapper_install",   init_wrapper_install},
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"init_wrapper_query",     init_wrapper_query  },
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"init_wrapper_uninstall", init_wrapper_uninstall},
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"init_wrapper_clear",     init_wrapper_clear}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
288