xref: /sqlite-3.40.0/src/test_init.c (revision 7617e4a8)
1e1ab2193Sdan /*
2e1ab2193Sdan ** 2009 August 17
3e1ab2193Sdan **
4e1ab2193Sdan ** The author disclaims copyright to this source code.  In place of
5e1ab2193Sdan ** a legal notice, here is a blessing:
6e1ab2193Sdan **
7e1ab2193Sdan **    May you do good and not evil.
8e1ab2193Sdan **    May you find forgiveness for yourself and forgive others.
9e1ab2193Sdan **    May you share freely, never taking more than you give.
10e1ab2193Sdan **
11e1ab2193Sdan *************************************************************************
12e1ab2193Sdan **
13e1ab2193Sdan ** The code in this file is used for testing SQLite. It is not part of
14e1ab2193Sdan ** the source code used in production systems.
15e1ab2193Sdan **
16e1ab2193Sdan ** Specifically, this file tests the effect of errors while initializing
17e1ab2193Sdan ** the various pluggable sub-systems from within sqlite3_initialize().
18e1ab2193Sdan ** If an error occurs in sqlite3_initialize() the following should be
19e1ab2193Sdan ** true:
20e1ab2193Sdan **
21e1ab2193Sdan **   1) An error code is returned to the user, and
22e1ab2193Sdan **   2) A subsequent call to sqlite3_shutdown() calls the shutdown method
23e1ab2193Sdan **      of those subsystems that were initialized, and
24e1ab2193Sdan **   3) A subsequent call to sqlite3_initialize() attempts to initialize
25e1ab2193Sdan **      the remaining, uninitialized, subsystems.
26e1ab2193Sdan */
27e1ab2193Sdan 
28e1ab2193Sdan #include "sqliteInt.h"
29e1ab2193Sdan #include <string.h>
3052b1dbb5Smistachkin #if defined(INCLUDE_SQLITE_TCL_H)
3152b1dbb5Smistachkin #  include "sqlite_tcl.h"
3252b1dbb5Smistachkin #else
3352b1dbb5Smistachkin #  include "tcl.h"
3452b1dbb5Smistachkin #endif
35e1ab2193Sdan 
36e1ab2193Sdan static struct Wrapped {
3722e21ff4Sdan   sqlite3_pcache_methods2 pcache;
38e1ab2193Sdan   sqlite3_mem_methods     mem;
39e1ab2193Sdan   sqlite3_mutex_methods   mutex;
40e1ab2193Sdan 
41e1ab2193Sdan   int mem_init;                /* True if mem subsystem is initalized */
42e1ab2193Sdan   int mem_fail;                /* True to fail mem subsystem inialization */
43e1ab2193Sdan   int mutex_init;              /* True if mutex subsystem is initalized */
44e1ab2193Sdan   int mutex_fail;              /* True to fail mutex subsystem inialization */
45e1ab2193Sdan   int pcache_init;             /* True if pcache subsystem is initalized */
46e1ab2193Sdan   int pcache_fail;             /* True to fail pcache subsystem inialization */
47e1ab2193Sdan } wrapped;
48e1ab2193Sdan 
wrMemInit(void * pAppData)49e1ab2193Sdan static int wrMemInit(void *pAppData){
50e1ab2193Sdan   int rc;
51e1ab2193Sdan   if( wrapped.mem_fail ){
52e1ab2193Sdan     rc = SQLITE_ERROR;
53e1ab2193Sdan   }else{
54e1ab2193Sdan     rc = wrapped.mem.xInit(wrapped.mem.pAppData);
55e1ab2193Sdan   }
56e1ab2193Sdan   if( rc==SQLITE_OK ){
57e1ab2193Sdan     wrapped.mem_init = 1;
58e1ab2193Sdan   }
59e1ab2193Sdan   return rc;
60e1ab2193Sdan }
wrMemShutdown(void * pAppData)61e1ab2193Sdan static void wrMemShutdown(void *pAppData){
62e1ab2193Sdan   wrapped.mem.xShutdown(wrapped.mem.pAppData);
63e1ab2193Sdan   wrapped.mem_init = 0;
64e1ab2193Sdan }
wrMemMalloc(int n)65e1ab2193Sdan static void *wrMemMalloc(int n)           {return wrapped.mem.xMalloc(n);}
wrMemFree(void * p)66e1ab2193Sdan static void wrMemFree(void *p)            {wrapped.mem.xFree(p);}
wrMemRealloc(void * p,int n)67e1ab2193Sdan static void *wrMemRealloc(void *p, int n) {return wrapped.mem.xRealloc(p, n);}
wrMemSize(void * p)68e1ab2193Sdan static int wrMemSize(void *p)             {return wrapped.mem.xSize(p);}
wrMemRoundup(int n)69e1ab2193Sdan static int wrMemRoundup(int n)            {return wrapped.mem.xRoundup(n);}
70e1ab2193Sdan 
71e1ab2193Sdan 
wrMutexInit(void)72e1ab2193Sdan static int wrMutexInit(void){
73e1ab2193Sdan   int rc;
74e1ab2193Sdan   if( wrapped.mutex_fail ){
75e1ab2193Sdan     rc = SQLITE_ERROR;
76e1ab2193Sdan   }else{
77e1ab2193Sdan     rc = wrapped.mutex.xMutexInit();
78e1ab2193Sdan   }
79e1ab2193Sdan   if( rc==SQLITE_OK ){
80e1ab2193Sdan     wrapped.mutex_init = 1;
81e1ab2193Sdan   }
82e1ab2193Sdan   return rc;
83e1ab2193Sdan }
wrMutexEnd(void)84e1ab2193Sdan static int wrMutexEnd(void){
85e1ab2193Sdan   wrapped.mutex.xMutexEnd();
86e1ab2193Sdan   wrapped.mutex_init = 0;
87e1ab2193Sdan   return SQLITE_OK;
88e1ab2193Sdan }
wrMutexAlloc(int e)89e1ab2193Sdan static sqlite3_mutex *wrMutexAlloc(int e){
90e1ab2193Sdan   return wrapped.mutex.xMutexAlloc(e);
91e1ab2193Sdan }
wrMutexFree(sqlite3_mutex * p)92e1ab2193Sdan static void wrMutexFree(sqlite3_mutex *p){
93e1ab2193Sdan   wrapped.mutex.xMutexFree(p);
94e1ab2193Sdan }
wrMutexEnter(sqlite3_mutex * p)95e1ab2193Sdan static void wrMutexEnter(sqlite3_mutex *p){
96e1ab2193Sdan   wrapped.mutex.xMutexEnter(p);
97e1ab2193Sdan }
wrMutexTry(sqlite3_mutex * p)98e1ab2193Sdan static int wrMutexTry(sqlite3_mutex *p){
99e1ab2193Sdan   return wrapped.mutex.xMutexTry(p);
100e1ab2193Sdan }
wrMutexLeave(sqlite3_mutex * p)101e1ab2193Sdan static void wrMutexLeave(sqlite3_mutex *p){
102e1ab2193Sdan   wrapped.mutex.xMutexLeave(p);
103e1ab2193Sdan }
wrMutexHeld(sqlite3_mutex * p)104e1ab2193Sdan static int wrMutexHeld(sqlite3_mutex *p){
105e1ab2193Sdan   return wrapped.mutex.xMutexHeld(p);
106e1ab2193Sdan }
wrMutexNotheld(sqlite3_mutex * p)107e1ab2193Sdan static int wrMutexNotheld(sqlite3_mutex *p){
108e1ab2193Sdan   return wrapped.mutex.xMutexNotheld(p);
109e1ab2193Sdan }
110e1ab2193Sdan 
111e1ab2193Sdan 
112e1ab2193Sdan 
wrPCacheInit(void * pArg)113e1ab2193Sdan static int wrPCacheInit(void *pArg){
114e1ab2193Sdan   int rc;
115e1ab2193Sdan   if( wrapped.pcache_fail ){
116e1ab2193Sdan     rc = SQLITE_ERROR;
117e1ab2193Sdan   }else{
118e1ab2193Sdan     rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
119e1ab2193Sdan   }
120e1ab2193Sdan   if( rc==SQLITE_OK ){
121e1ab2193Sdan     wrapped.pcache_init = 1;
122e1ab2193Sdan   }
123e1ab2193Sdan   return rc;
124e1ab2193Sdan }
wrPCacheShutdown(void * pArg)125e1ab2193Sdan static void wrPCacheShutdown(void *pArg){
126e1ab2193Sdan   wrapped.pcache.xShutdown(wrapped.pcache.pArg);
127e1ab2193Sdan   wrapped.pcache_init = 0;
128e1ab2193Sdan }
129e1ab2193Sdan 
wrPCacheCreate(int a,int b,int c)13022e21ff4Sdan static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){
13122e21ff4Sdan   return wrapped.pcache.xCreate(a, b, c);
132e1ab2193Sdan }
wrPCacheCachesize(sqlite3_pcache * p,int n)133e1ab2193Sdan static void wrPCacheCachesize(sqlite3_pcache *p, int n){
134e1ab2193Sdan   wrapped.pcache.xCachesize(p, n);
135e1ab2193Sdan }
wrPCachePagecount(sqlite3_pcache * p)136e1ab2193Sdan static int wrPCachePagecount(sqlite3_pcache *p){
137e1ab2193Sdan   return wrapped.pcache.xPagecount(p);
138e1ab2193Sdan }
wrPCacheFetch(sqlite3_pcache * p,unsigned a,int b)13922e21ff4Sdan static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
140e1ab2193Sdan   return wrapped.pcache.xFetch(p, a, b);
141e1ab2193Sdan }
wrPCacheUnpin(sqlite3_pcache * p,sqlite3_pcache_page * a,int b)14222e21ff4Sdan static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){
143e1ab2193Sdan   wrapped.pcache.xUnpin(p, a, b);
144e1ab2193Sdan }
wrPCacheRekey(sqlite3_pcache * p,sqlite3_pcache_page * a,unsigned b,unsigned c)14522e21ff4Sdan static void wrPCacheRekey(
14622e21ff4Sdan   sqlite3_pcache *p,
14722e21ff4Sdan   sqlite3_pcache_page *a,
14822e21ff4Sdan   unsigned b,
14922e21ff4Sdan   unsigned c
15022e21ff4Sdan ){
151e1ab2193Sdan   wrapped.pcache.xRekey(p, a, b, c);
152e1ab2193Sdan }
wrPCacheTruncate(sqlite3_pcache * p,unsigned a)153e1ab2193Sdan static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
154e1ab2193Sdan   wrapped.pcache.xTruncate(p, a);
155e1ab2193Sdan }
wrPCacheDestroy(sqlite3_pcache * p)156e1ab2193Sdan static void wrPCacheDestroy(sqlite3_pcache *p){
157e1ab2193Sdan   wrapped.pcache.xDestroy(p);
158e1ab2193Sdan }
159e1ab2193Sdan 
installInitWrappers(void)160e1ab2193Sdan static void installInitWrappers(void){
161e1ab2193Sdan   sqlite3_mutex_methods mutexmethods = {
162e1ab2193Sdan     wrMutexInit,  wrMutexEnd,   wrMutexAlloc,
163e1ab2193Sdan     wrMutexFree,  wrMutexEnter, wrMutexTry,
164e1ab2193Sdan     wrMutexLeave, wrMutexHeld,  wrMutexNotheld
165e1ab2193Sdan   };
16622e21ff4Sdan   sqlite3_pcache_methods2 pcachemethods = {
16781ef0f97Sdrh     1, 0,
168e1ab2193Sdan     wrPCacheInit,      wrPCacheShutdown,  wrPCacheCreate,
169e1ab2193Sdan     wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
170e1ab2193Sdan     wrPCacheUnpin,     wrPCacheRekey,     wrPCacheTruncate,
171e1ab2193Sdan     wrPCacheDestroy
172e1ab2193Sdan   };
173e1ab2193Sdan   sqlite3_mem_methods memmethods = {
174e1ab2193Sdan     wrMemMalloc,   wrMemFree,    wrMemRealloc,
175e1ab2193Sdan     wrMemSize,     wrMemRoundup, wrMemInit,
176e1ab2193Sdan     wrMemShutdown,
177e1ab2193Sdan     0
178e1ab2193Sdan   };
179e1ab2193Sdan 
180e1ab2193Sdan   memset(&wrapped, 0, sizeof(wrapped));
181e1ab2193Sdan 
182e1ab2193Sdan   sqlite3_shutdown();
183e1ab2193Sdan   sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
184e1ab2193Sdan   sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
18522e21ff4Sdan   sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache);
186e1ab2193Sdan   sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
187e1ab2193Sdan   sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
18822e21ff4Sdan   sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods);
189e1ab2193Sdan }
190e1ab2193Sdan 
init_wrapper_install(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv[])191*7617e4a8Smistachkin static int SQLITE_TCLAPI init_wrapper_install(
192e1ab2193Sdan   ClientData clientData, /* Unused */
193e1ab2193Sdan   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
194e1ab2193Sdan   int objc,              /* Number of arguments */
195e1ab2193Sdan   Tcl_Obj *CONST objv[]  /* Command arguments */
196e1ab2193Sdan ){
197e1ab2193Sdan   int i;
198e1ab2193Sdan   installInitWrappers();
199e1ab2193Sdan   for(i=1; i<objc; i++){
200e1ab2193Sdan     char *z = Tcl_GetString(objv[i]);
201e1ab2193Sdan     if( strcmp(z, "mem")==0 ){
202e1ab2193Sdan       wrapped.mem_fail = 1;
203e1ab2193Sdan     }else if( strcmp(z, "mutex")==0 ){
204e1ab2193Sdan       wrapped.mutex_fail = 1;
205e1ab2193Sdan     }else if( strcmp(z, "pcache")==0 ){
206e1ab2193Sdan       wrapped.pcache_fail = 1;
207e1ab2193Sdan     }else{
208e1ab2193Sdan       Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"");
209e1ab2193Sdan       return TCL_ERROR;
210e1ab2193Sdan     }
211e1ab2193Sdan   }
212e1ab2193Sdan   return TCL_OK;
213e1ab2193Sdan }
214e1ab2193Sdan 
init_wrapper_uninstall(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv[])215*7617e4a8Smistachkin static int SQLITE_TCLAPI init_wrapper_uninstall(
216e1ab2193Sdan   ClientData clientData, /* Unused */
217e1ab2193Sdan   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
218e1ab2193Sdan   int objc,              /* Number of arguments */
219e1ab2193Sdan   Tcl_Obj *CONST objv[]  /* Command arguments */
220e1ab2193Sdan ){
221e1ab2193Sdan   if( objc!=1 ){
222e1ab2193Sdan     Tcl_WrongNumArgs(interp, 1, objv, "");
223e1ab2193Sdan     return TCL_ERROR;
224e1ab2193Sdan   }
225e1ab2193Sdan 
226e1ab2193Sdan   sqlite3_shutdown();
227e1ab2193Sdan   sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
228e1ab2193Sdan   sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
22922e21ff4Sdan   sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache);
230e1ab2193Sdan   return TCL_OK;
231e1ab2193Sdan }
232e1ab2193Sdan 
init_wrapper_clear(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv[])233*7617e4a8Smistachkin static int SQLITE_TCLAPI init_wrapper_clear(
234e1ab2193Sdan   ClientData clientData, /* Unused */
235e1ab2193Sdan   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
236e1ab2193Sdan   int objc,              /* Number of arguments */
237e1ab2193Sdan   Tcl_Obj *CONST objv[]  /* Command arguments */
238e1ab2193Sdan ){
239e1ab2193Sdan   if( objc!=1 ){
240e1ab2193Sdan     Tcl_WrongNumArgs(interp, 1, objv, "");
241e1ab2193Sdan     return TCL_ERROR;
242e1ab2193Sdan   }
243e1ab2193Sdan 
244e1ab2193Sdan   wrapped.mem_fail = 0;
245e1ab2193Sdan   wrapped.mutex_fail = 0;
246e1ab2193Sdan   wrapped.pcache_fail = 0;
247e1ab2193Sdan   return TCL_OK;
248e1ab2193Sdan }
249e1ab2193Sdan 
init_wrapper_query(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv[])250*7617e4a8Smistachkin static int SQLITE_TCLAPI init_wrapper_query(
251e1ab2193Sdan   ClientData clientData, /* Unused */
252e1ab2193Sdan   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
253e1ab2193Sdan   int objc,              /* Number of arguments */
254e1ab2193Sdan   Tcl_Obj *CONST objv[]  /* Command arguments */
255e1ab2193Sdan ){
256e1ab2193Sdan   Tcl_Obj *pRet;
257e1ab2193Sdan 
258e1ab2193Sdan   if( objc!=1 ){
259e1ab2193Sdan     Tcl_WrongNumArgs(interp, 1, objv, "");
260e1ab2193Sdan     return TCL_ERROR;
261e1ab2193Sdan   }
262e1ab2193Sdan 
263e1ab2193Sdan   pRet = Tcl_NewObj();
264e1ab2193Sdan   if( wrapped.mutex_init ){
265e1ab2193Sdan     Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mutex", -1));
266e1ab2193Sdan   }
267e1ab2193Sdan   if( wrapped.mem_init ){
268e1ab2193Sdan     Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mem", -1));
269e1ab2193Sdan   }
270e1ab2193Sdan   if( wrapped.pcache_init ){
271e1ab2193Sdan     Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("pcache", -1));
272e1ab2193Sdan   }
273e1ab2193Sdan 
274e1ab2193Sdan   Tcl_SetObjResult(interp, pRet);
275e1ab2193Sdan   return TCL_OK;
276e1ab2193Sdan }
277e1ab2193Sdan 
Sqlitetest_init_Init(Tcl_Interp * interp)278e1ab2193Sdan int Sqlitetest_init_Init(Tcl_Interp *interp){
279e1ab2193Sdan   static struct {
280e1ab2193Sdan      char *zName;
281e1ab2193Sdan      Tcl_ObjCmdProc *xProc;
282e1ab2193Sdan   } aObjCmd[] = {
283e1ab2193Sdan     {"init_wrapper_install",   init_wrapper_install},
284e1ab2193Sdan     {"init_wrapper_query",     init_wrapper_query  },
285e1ab2193Sdan     {"init_wrapper_uninstall", init_wrapper_uninstall},
286e1ab2193Sdan     {"init_wrapper_clear",     init_wrapper_clear}
287e1ab2193Sdan   };
288e1ab2193Sdan   int i;
289e1ab2193Sdan 
290e1ab2193Sdan   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
291e1ab2193Sdan     Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
292e1ab2193Sdan   }
293e1ab2193Sdan 
294e1ab2193Sdan   return TCL_OK;
295e1ab2193Sdan }
296