replace use of sqlite3StrICmp with public sqlite3_stricmp API
[sqlcipher.git] / ext / rbu / test_rbu.c
blob6d04bfe8ccfa99651ad293877df2da625d490fab
1 /*
2 ** 2015 February 16
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 *************************************************************************
14 #include "sqlite3.h"
16 #if defined(SQLITE_TEST)
17 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
19 #include "sqlite3rbu.h"
20 #if defined(INCLUDE_SQLITE_TCL_H)
21 # include "sqlite_tcl.h"
22 #else
23 # include "tcl.h"
24 # ifndef SQLITE_TCLAPI
25 # define SQLITE_TCLAPI
26 # endif
27 #endif
28 #include <assert.h>
30 /* From main.c */
31 extern const char *sqlite3ErrName(int);
32 extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
34 void test_rbu_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){
35 Tcl_Interp *interp = (Tcl_Interp*)sqlite3_user_data(pCtx);
36 Tcl_Obj *pScript;
37 int i;
39 pScript = Tcl_NewObj();
40 Tcl_IncrRefCount(pScript);
41 Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj("rbu_delta", -1));
42 for(i=0; i<nArg; i++){
43 sqlite3_value *pIn = apVal[i];
44 const char *z = (const char*)sqlite3_value_text(pIn);
45 Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(z, -1));
48 if( TCL_OK==Tcl_EvalObjEx(interp, pScript, TCL_GLOBAL_ONLY) ){
49 const char *z = Tcl_GetStringResult(interp);
50 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
51 }else{
52 Tcl_BackgroundError(interp);
55 Tcl_DecrRefCount(pScript);
59 static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
60 ClientData clientData,
61 Tcl_Interp *interp,
62 int objc,
63 Tcl_Obj *CONST objv[]
65 int ret = TCL_OK;
66 sqlite3rbu *pRbu = (sqlite3rbu*)clientData;
67 struct RbuCmd {
68 const char *zName;
69 int nArg;
70 const char *zUsage;
71 } aCmd[] = {
72 {"step", 2, ""}, /* 0 */
73 {"close", 2, ""}, /* 1 */
74 {"create_rbu_delta", 2, ""}, /* 2 */
75 {"savestate", 2, ""}, /* 3 */
76 {"dbMain_eval", 3, "SQL"}, /* 4 */
77 {"bp_progress", 2, ""}, /* 5 */
78 {"db", 3, "RBU"}, /* 6 */
79 {"state", 2, ""}, /* 7 */
80 {"progress", 2, ""}, /* 8 */
81 {"close_no_error", 2, ""}, /* 9 */
82 {"temp_size_limit", 3, "LIMIT"}, /* 10 */
83 {"temp_size", 2, ""}, /* 11 */
84 {"dbRbu_eval", 3, "SQL"}, /* 12 */
85 {0,0,0}
87 int iCmd;
89 if( objc<2 ){
90 Tcl_WrongNumArgs(interp, 1, objv, "METHOD");
91 return TCL_ERROR;
93 ret = Tcl_GetIndexFromObjStruct(
94 interp, objv[1], aCmd, sizeof(aCmd[0]), "method", 0, &iCmd
96 if( ret ) return TCL_ERROR;
97 if( objc!=aCmd[iCmd].nArg ){
98 Tcl_WrongNumArgs(interp, 1, objv, aCmd[iCmd].zUsage);
99 return TCL_ERROR;
102 switch( iCmd ){
103 case 0: /* step */ {
104 int rc = sqlite3rbu_step(pRbu);
105 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
106 break;
109 case 9: /* close_no_error */
110 case 1: /* close */ {
111 char *zErrmsg = 0;
112 int rc;
113 Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
114 if( iCmd==1 ){
115 rc = sqlite3rbu_close(pRbu, &zErrmsg);
116 }else{
117 rc = sqlite3rbu_close(pRbu, 0);
119 if( rc==SQLITE_OK || rc==SQLITE_DONE ){
120 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
121 assert( zErrmsg==0 );
122 }else{
123 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
124 if( zErrmsg ){
125 Tcl_AppendResult(interp, " - ", zErrmsg, 0);
126 sqlite3_free(zErrmsg);
128 ret = TCL_ERROR;
130 break;
133 case 2: /* create_rbu_delta */ {
134 sqlite3 *db = sqlite3rbu_db(pRbu, 0);
135 int rc = sqlite3_create_function(
136 db, "rbu_delta", -1, SQLITE_UTF8, (void*)interp, test_rbu_delta, 0, 0
138 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
139 ret = (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
140 break;
143 case 3: /* savestate */ {
144 int rc = sqlite3rbu_savestate(pRbu);
145 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
146 ret = (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
147 break;
150 case 12: /* dbRbu_eval */
151 case 4: /* dbMain_eval */ {
152 sqlite3 *db = sqlite3rbu_db(pRbu, (iCmd==12));
153 int rc = sqlite3_exec(db, Tcl_GetString(objv[2]), 0, 0, 0);
154 if( rc!=SQLITE_OK ){
155 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(db), -1));
156 ret = TCL_ERROR;
158 break;
161 case 5: /* bp_progress */ {
162 int one, two;
163 Tcl_Obj *pObj;
164 sqlite3rbu_bp_progress(pRbu, &one, &two);
166 pObj = Tcl_NewObj();
167 Tcl_ListObjAppendElement(interp, pObj, Tcl_NewIntObj(one));
168 Tcl_ListObjAppendElement(interp, pObj, Tcl_NewIntObj(two));
169 Tcl_SetObjResult(interp, pObj);
170 break;
173 case 6: /* db */ {
174 int bArg;
175 if( Tcl_GetBooleanFromObj(interp, objv[2], &bArg) ){
176 ret = TCL_ERROR;
177 }else{
178 char zBuf[50];
179 sqlite3 *db = sqlite3rbu_db(pRbu, bArg);
180 if( sqlite3TestMakePointerStr(interp, zBuf, (void*)db) ){
181 ret = TCL_ERROR;
182 }else{
183 Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
186 break;
188 case 7: /* state */ {
189 const char *aRes[] = { 0, "oal", "move", "checkpoint", "done", "error" };
190 int eState = sqlite3rbu_state(pRbu);
191 assert( eState>0 && eState<=5 );
192 Tcl_SetResult(interp, (char*)aRes[eState], TCL_STATIC);
193 break;
195 case 8: /* progress */ {
196 sqlite3_int64 nStep = sqlite3rbu_progress(pRbu);
197 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nStep));
198 break;
201 case 10: /* temp_size_limit */ {
202 sqlite3_int64 nLimit;
203 if( Tcl_GetWideIntFromObj(interp, objv[2], &nLimit) ){
204 ret = TCL_ERROR;
205 }else{
206 nLimit = sqlite3rbu_temp_size_limit(pRbu, nLimit);
207 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nLimit));
209 break;
211 case 11: /* temp_size */ {
212 sqlite3_int64 sz = sqlite3rbu_temp_size(pRbu);
213 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sz));
214 break;
217 default: /* seems unlikely */
218 assert( !"cannot happen" );
219 break;
222 return ret;
226 ** Tclcmd: sqlite3rbu CMD <target-db> <rbu-db> ?<state-db>?
228 static int SQLITE_TCLAPI test_sqlite3rbu(
229 ClientData clientData,
230 Tcl_Interp *interp,
231 int objc,
232 Tcl_Obj *CONST objv[]
234 sqlite3rbu *pRbu = 0;
235 const char *zCmd;
236 const char *zTarget;
237 const char *zRbu;
238 const char *zStateDb = 0;
240 if( objc!=4 && objc!=5 ){
241 Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB RBU-DB ?STATE-DB?");
242 return TCL_ERROR;
244 zCmd = Tcl_GetString(objv[1]);
245 zTarget = Tcl_GetString(objv[2]);
246 zRbu = Tcl_GetString(objv[3]);
247 if( objc==5 ) zStateDb = Tcl_GetString(objv[4]);
249 pRbu = sqlite3rbu_open(zTarget, zRbu, zStateDb);
250 Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
251 Tcl_SetObjResult(interp, objv[1]);
252 return TCL_OK;
256 ** Tclcmd: sqlite3rbu_vacuum CMD <target-db> <state-db>
258 static int SQLITE_TCLAPI test_sqlite3rbu_vacuum(
259 ClientData clientData,
260 Tcl_Interp *interp,
261 int objc,
262 Tcl_Obj *CONST objv[]
264 sqlite3rbu *pRbu = 0;
265 const char *zCmd;
266 const char *zTarget;
267 const char *zStateDb = 0;
269 if( objc!=3 && objc!=4 ){
270 Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB ?STATE-DB?");
271 return TCL_ERROR;
273 zCmd = Tcl_GetString(objv[1]);
274 zTarget = Tcl_GetString(objv[2]);
275 if( objc==4 ) zStateDb = Tcl_GetString(objv[3]);
276 if( zStateDb && zStateDb[0]=='\0' ) zStateDb = 0;
278 pRbu = sqlite3rbu_vacuum(zTarget, zStateDb);
279 Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
280 Tcl_SetObjResult(interp, objv[1]);
281 return TCL_OK;
285 ** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT
287 static int SQLITE_TCLAPI test_sqlite3rbu_create_vfs(
288 ClientData clientData,
289 Tcl_Interp *interp,
290 int objc,
291 Tcl_Obj *CONST objv[]
293 const char *zName;
294 const char *zParent;
295 int rc;
297 if( objc!=3 && objc!=4 ){
298 Tcl_WrongNumArgs(interp, 1, objv, "?-default? NAME PARENT");
299 return TCL_ERROR;
302 zName = Tcl_GetString(objv[objc-2]);
303 zParent = Tcl_GetString(objv[objc-1]);
304 if( zParent[0]=='\0' ) zParent = 0;
306 rc = sqlite3rbu_create_vfs(zName, zParent);
307 if( rc!=SQLITE_OK ){
308 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
309 return TCL_ERROR;
310 }else if( objc==4 ){
311 sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
312 sqlite3_vfs_register(pVfs, 1);
315 Tcl_ResetResult(interp);
316 return TCL_OK;
320 ** Tclcmd: sqlite3rbu_destroy_vfs NAME
322 static int SQLITE_TCLAPI test_sqlite3rbu_destroy_vfs(
323 ClientData clientData,
324 Tcl_Interp *interp,
325 int objc,
326 Tcl_Obj *CONST objv[]
328 const char *zName;
330 if( objc!=2 ){
331 Tcl_WrongNumArgs(interp, 1, objv, "NAME");
332 return TCL_ERROR;
335 zName = Tcl_GetString(objv[1]);
336 sqlite3rbu_destroy_vfs(zName);
337 return TCL_OK;
341 ** Tclcmd: sqlite3rbu_internal_test
343 static int SQLITE_TCLAPI test_sqlite3rbu_internal_test(
344 ClientData clientData,
345 Tcl_Interp *interp,
346 int objc,
347 Tcl_Obj *CONST objv[]
349 sqlite3 *db;
351 if( objc!=1 ){
352 Tcl_WrongNumArgs(interp, 1, objv, "");
353 return TCL_ERROR;
356 db = sqlite3rbu_db(0, 0);
357 if( db!=0 ){
358 Tcl_AppendResult(interp, "sqlite3rbu_db(0, 0)!=0", 0);
359 return TCL_ERROR;
362 return TCL_OK;
365 int SqliteRbu_Init(Tcl_Interp *interp){
366 static struct {
367 char *zName;
368 Tcl_ObjCmdProc *xProc;
369 } aObjCmd[] = {
370 { "sqlite3rbu", test_sqlite3rbu },
371 { "sqlite3rbu_vacuum", test_sqlite3rbu_vacuum },
372 { "sqlite3rbu_create_vfs", test_sqlite3rbu_create_vfs },
373 { "sqlite3rbu_destroy_vfs", test_sqlite3rbu_destroy_vfs },
374 { "sqlite3rbu_internal_test", test_sqlite3rbu_internal_test },
376 int i;
377 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
378 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
380 return TCL_OK;
383 #else
384 #if defined(INCLUDE_SQLITE_TCL_H)
385 # include "sqlite_tcl.h"
386 #else
387 # include "tcl.h"
388 #endif
389 int SqliteRbu_Init(Tcl_Interp *interp){ return TCL_OK; }
390 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
391 #endif /* defined(SQLITE_TEST) */