Merge sqlite-release(3.44.2) into prerelease-integration
[sqlcipher.git] / src / test_init.c
blob400ab9a2bf20b77d00b96bbfc6bab37064b4fbe9
1 /*
2 ** 2009 August 17
3 **
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
6 **
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
19 ** true:
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"
29 #include <string.h>
30 #if defined(INCLUDE_SQLITE_TCL_H)
31 # include "sqlite_tcl.h"
32 #else
33 # include "tcl.h"
34 #endif
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 */
47 } wrapped;
49 static int wrMemInit(void *pAppData){
50 int rc;
51 if( wrapped.mem_fail ){
52 rc = SQLITE_ERROR;
53 }else{
54 rc = wrapped.mem.xInit(wrapped.mem.pAppData);
56 if( rc==SQLITE_OK ){
57 wrapped.mem_init = 1;
59 return rc;
61 static void wrMemShutdown(void *pAppData){
62 wrapped.mem.xShutdown(wrapped.mem.pAppData);
63 wrapped.mem_init = 0;
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){
73 int rc;
74 if( wrapped.mutex_fail ){
75 rc = SQLITE_ERROR;
76 }else{
77 rc = wrapped.mutex.xMutexInit();
79 if( rc==SQLITE_OK ){
80 wrapped.mutex_init = 1;
82 return rc;
84 static int wrMutexEnd(void){
85 wrapped.mutex.xMutexEnd();
86 wrapped.mutex_init = 0;
87 return SQLITE_OK;
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){
114 int rc;
115 if( wrapped.pcache_fail ){
116 rc = SQLITE_ERROR;
117 }else{
118 rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
120 if( rc==SQLITE_OK ){
121 wrapped.pcache_init = 1;
123 return rc;
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(
146 sqlite3_pcache *p,
147 sqlite3_pcache_page *a,
148 unsigned b,
149 unsigned c
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 = {
167 1, 0,
168 wrPCacheInit, wrPCacheShutdown, wrPCacheCreate,
169 wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
170 wrPCacheUnpin, wrPCacheRekey, wrPCacheTruncate,
171 wrPCacheDestroy
173 sqlite3_mem_methods memmethods = {
174 wrMemMalloc, wrMemFree, wrMemRealloc,
175 wrMemSize, wrMemRoundup, wrMemInit,
176 wrMemShutdown,
180 memset(&wrapped, 0, sizeof(wrapped));
182 sqlite3_shutdown();
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 */
197 int i;
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;
207 }else{
208 Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"");
209 return TCL_ERROR;
212 return TCL_OK;
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 */
221 if( objc!=1 ){
222 Tcl_WrongNumArgs(interp, 1, objv, "");
223 return TCL_ERROR;
226 sqlite3_shutdown();
227 sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
228 sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
229 sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache);
230 return TCL_OK;
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 */
239 if( objc!=1 ){
240 Tcl_WrongNumArgs(interp, 1, objv, "");
241 return TCL_ERROR;
244 wrapped.mem_fail = 0;
245 wrapped.mutex_fail = 0;
246 wrapped.pcache_fail = 0;
247 return TCL_OK;
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 */
256 Tcl_Obj *pRet;
258 if( objc!=1 ){
259 Tcl_WrongNumArgs(interp, 1, objv, "");
260 return TCL_ERROR;
263 pRet = Tcl_NewObj();
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);
275 return TCL_OK;
278 int Sqlitetest_init_Init(Tcl_Interp *interp){
279 static struct {
280 char *zName;
281 Tcl_ObjCmdProc *xProc;
282 } aObjCmd[] = {
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}
288 int i;
290 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
291 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
294 return TCL_OK;