4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 *************************************************************************
13 ** The code in this file is used for testing SQLite. It is not part of
14 ** the source code used in production systems.
16 ** Specifically, this file tests the effect of errors while initializing
17 ** the various pluggable sub-systems from within sqlite3_initialize().
18 ** If an error occurs in sqlite3_initialize() the following should be
21 ** 1) An error code is returned to the user, and
22 ** 2) A subsequent call to sqlite3_shutdown() calls the shutdown method
23 ** of those subsystems that were initialized, and
24 ** 3) A subsequent call to sqlite3_initialize() attempts to initialize
25 ** the remaining, uninitialized, subsystems.
28 #include "sqliteInt.h"
30 #if defined(INCLUDE_SQLITE_TCL_H)
31 # include "sqlite_tcl.h"
36 static struct Wrapped
{
37 sqlite3_pcache_methods2 pcache
;
38 sqlite3_mem_methods mem
;
39 sqlite3_mutex_methods mutex
;
41 int mem_init
; /* True if mem subsystem is initialized */
42 int mem_fail
; /* True to fail mem subsystem initialization */
43 int mutex_init
; /* True if mutex subsystem is initialized */
44 int mutex_fail
; /* True to fail mutex subsystem initialization */
45 int pcache_init
; /* True if pcache subsystem is initialized */
46 int pcache_fail
; /* True to fail pcache subsystem initialization */
49 static int wrMemInit(void *pAppData
){
51 if( wrapped
.mem_fail
){
54 rc
= wrapped
.mem
.xInit(wrapped
.mem
.pAppData
);
61 static void wrMemShutdown(void *pAppData
){
62 wrapped
.mem
.xShutdown(wrapped
.mem
.pAppData
);
65 static void *wrMemMalloc(int n
) {return wrapped
.mem
.xMalloc(n
);}
66 static void wrMemFree(void *p
) {wrapped
.mem
.xFree(p
);}
67 static void *wrMemRealloc(void *p
, int n
) {return wrapped
.mem
.xRealloc(p
, n
);}
68 static int wrMemSize(void *p
) {return wrapped
.mem
.xSize(p
);}
69 static int wrMemRoundup(int n
) {return wrapped
.mem
.xRoundup(n
);}
72 static int wrMutexInit(void){
74 if( wrapped
.mutex_fail
){
77 rc
= wrapped
.mutex
.xMutexInit();
80 wrapped
.mutex_init
= 1;
84 static int wrMutexEnd(void){
85 wrapped
.mutex
.xMutexEnd();
86 wrapped
.mutex_init
= 0;
89 static sqlite3_mutex
*wrMutexAlloc(int e
){
90 return wrapped
.mutex
.xMutexAlloc(e
);
92 static void wrMutexFree(sqlite3_mutex
*p
){
93 wrapped
.mutex
.xMutexFree(p
);
95 static void wrMutexEnter(sqlite3_mutex
*p
){
96 wrapped
.mutex
.xMutexEnter(p
);
98 static int wrMutexTry(sqlite3_mutex
*p
){
99 return wrapped
.mutex
.xMutexTry(p
);
101 static void wrMutexLeave(sqlite3_mutex
*p
){
102 wrapped
.mutex
.xMutexLeave(p
);
104 static int wrMutexHeld(sqlite3_mutex
*p
){
105 return wrapped
.mutex
.xMutexHeld(p
);
107 static int wrMutexNotheld(sqlite3_mutex
*p
){
108 return wrapped
.mutex
.xMutexNotheld(p
);
113 static int wrPCacheInit(void *pArg
){
115 if( wrapped
.pcache_fail
){
118 rc
= wrapped
.pcache
.xInit(wrapped
.pcache
.pArg
);
121 wrapped
.pcache_init
= 1;
125 static void wrPCacheShutdown(void *pArg
){
126 wrapped
.pcache
.xShutdown(wrapped
.pcache
.pArg
);
127 wrapped
.pcache_init
= 0;
130 static sqlite3_pcache
*wrPCacheCreate(int a
, int b
, int c
){
131 return wrapped
.pcache
.xCreate(a
, b
, c
);
133 static void wrPCacheCachesize(sqlite3_pcache
*p
, int n
){
134 wrapped
.pcache
.xCachesize(p
, n
);
136 static int wrPCachePagecount(sqlite3_pcache
*p
){
137 return wrapped
.pcache
.xPagecount(p
);
139 static sqlite3_pcache_page
*wrPCacheFetch(sqlite3_pcache
*p
, unsigned a
, int b
){
140 return wrapped
.pcache
.xFetch(p
, a
, b
);
142 static void wrPCacheUnpin(sqlite3_pcache
*p
, sqlite3_pcache_page
*a
, int b
){
143 wrapped
.pcache
.xUnpin(p
, a
, b
);
145 static void wrPCacheRekey(
147 sqlite3_pcache_page
*a
,
151 wrapped
.pcache
.xRekey(p
, a
, b
, c
);
153 static void wrPCacheTruncate(sqlite3_pcache
*p
, unsigned a
){
154 wrapped
.pcache
.xTruncate(p
, a
);
156 static void wrPCacheDestroy(sqlite3_pcache
*p
){
157 wrapped
.pcache
.xDestroy(p
);
160 static void installInitWrappers(void){
161 sqlite3_mutex_methods mutexmethods
= {
162 wrMutexInit
, wrMutexEnd
, wrMutexAlloc
,
163 wrMutexFree
, wrMutexEnter
, wrMutexTry
,
164 wrMutexLeave
, wrMutexHeld
, wrMutexNotheld
166 sqlite3_pcache_methods2 pcachemethods
= {
168 wrPCacheInit
, wrPCacheShutdown
, wrPCacheCreate
,
169 wrPCacheCachesize
, wrPCachePagecount
, wrPCacheFetch
,
170 wrPCacheUnpin
, wrPCacheRekey
, wrPCacheTruncate
,
173 sqlite3_mem_methods memmethods
= {
174 wrMemMalloc
, wrMemFree
, wrMemRealloc
,
175 wrMemSize
, wrMemRoundup
, wrMemInit
,
180 memset(&wrapped
, 0, sizeof(wrapped
));
183 sqlite3_config(SQLITE_CONFIG_GETMUTEX
, &wrapped
.mutex
);
184 sqlite3_config(SQLITE_CONFIG_GETMALLOC
, &wrapped
.mem
);
185 sqlite3_config(SQLITE_CONFIG_GETPCACHE2
, &wrapped
.pcache
);
186 sqlite3_config(SQLITE_CONFIG_MUTEX
, &mutexmethods
);
187 sqlite3_config(SQLITE_CONFIG_MALLOC
, &memmethods
);
188 sqlite3_config(SQLITE_CONFIG_PCACHE2
, &pcachemethods
);
191 static int SQLITE_TCLAPI
init_wrapper_install(
192 ClientData clientData
, /* Unused */
193 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
194 int objc
, /* Number of arguments */
195 Tcl_Obj
*CONST objv
[] /* Command arguments */
198 installInitWrappers();
199 for(i
=1; i
<objc
; i
++){
200 char *z
= Tcl_GetString(objv
[i
]);
201 if( strcmp(z
, "mem")==0 ){
202 wrapped
.mem_fail
= 1;
203 }else if( strcmp(z
, "mutex")==0 ){
204 wrapped
.mutex_fail
= 1;
205 }else if( strcmp(z
, "pcache")==0 ){
206 wrapped
.pcache_fail
= 1;
208 Tcl_AppendResult(interp
, "Unknown argument: \"", z
, "\"");
215 static int SQLITE_TCLAPI
init_wrapper_uninstall(
216 ClientData clientData
, /* Unused */
217 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
218 int objc
, /* Number of arguments */
219 Tcl_Obj
*CONST objv
[] /* Command arguments */
222 Tcl_WrongNumArgs(interp
, 1, objv
, "");
227 sqlite3_config(SQLITE_CONFIG_MUTEX
, &wrapped
.mutex
);
228 sqlite3_config(SQLITE_CONFIG_MALLOC
, &wrapped
.mem
);
229 sqlite3_config(SQLITE_CONFIG_PCACHE2
, &wrapped
.pcache
);
233 static int SQLITE_TCLAPI
init_wrapper_clear(
234 ClientData clientData
, /* Unused */
235 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
236 int objc
, /* Number of arguments */
237 Tcl_Obj
*CONST objv
[] /* Command arguments */
240 Tcl_WrongNumArgs(interp
, 1, objv
, "");
244 wrapped
.mem_fail
= 0;
245 wrapped
.mutex_fail
= 0;
246 wrapped
.pcache_fail
= 0;
250 static int SQLITE_TCLAPI
init_wrapper_query(
251 ClientData clientData
, /* Unused */
252 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
253 int objc
, /* Number of arguments */
254 Tcl_Obj
*CONST objv
[] /* Command arguments */
259 Tcl_WrongNumArgs(interp
, 1, objv
, "");
264 if( wrapped
.mutex_init
){
265 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("mutex", -1));
267 if( wrapped
.mem_init
){
268 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("mem", -1));
270 if( wrapped
.pcache_init
){
271 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("pcache", -1));
274 Tcl_SetObjResult(interp
, pRet
);
278 int Sqlitetest_init_Init(Tcl_Interp
*interp
){
281 Tcl_ObjCmdProc
*xProc
;
283 {"init_wrapper_install", init_wrapper_install
},
284 {"init_wrapper_query", init_wrapper_query
},
285 {"init_wrapper_uninstall", init_wrapper_uninstall
},
286 {"init_wrapper_clear", init_wrapper_clear
}
290 for(i
=0; i
<sizeof(aObjCmd
)/sizeof(aObjCmd
[0]); i
++){
291 Tcl_CreateObjCommand(interp
, aObjCmd
[i
].zName
, aObjCmd
[i
].xProc
, 0, 0);