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 *************************************************************************
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"
24 # ifndef SQLITE_TCLAPI
25 # define SQLITE_TCLAPI
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
);
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
);
52 Tcl_BackgroundError(interp
);
55 Tcl_DecrRefCount(pScript
);
59 static int SQLITE_TCLAPI
test_sqlite3rbu_cmd(
60 ClientData clientData
,
66 sqlite3rbu
*pRbu
= (sqlite3rbu
*)clientData
;
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 */
90 Tcl_WrongNumArgs(interp
, 1, objv
, "METHOD");
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
);
104 int rc
= sqlite3rbu_step(pRbu
);
105 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
109 case 9: /* close_no_error */
110 case 1: /* close */ {
113 Tcl_DeleteCommand(interp
, Tcl_GetString(objv
[0]));
115 rc
= sqlite3rbu_close(pRbu
, &zErrmsg
);
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 );
123 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
125 Tcl_AppendResult(interp
, " - ", zErrmsg
, 0);
126 sqlite3_free(zErrmsg
);
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
);
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
);
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);
155 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3_errmsg(db
), -1));
161 case 5: /* bp_progress */ {
164 sqlite3rbu_bp_progress(pRbu
, &one
, &two
);
167 Tcl_ListObjAppendElement(interp
, pObj
, Tcl_NewIntObj(one
));
168 Tcl_ListObjAppendElement(interp
, pObj
, Tcl_NewIntObj(two
));
169 Tcl_SetObjResult(interp
, pObj
);
175 if( Tcl_GetBooleanFromObj(interp
, objv
[2], &bArg
) ){
179 sqlite3
*db
= sqlite3rbu_db(pRbu
, bArg
);
180 if( sqlite3TestMakePointerStr(interp
, zBuf
, (void*)db
) ){
183 Tcl_SetResult(interp
, zBuf
, TCL_VOLATILE
);
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
);
195 case 8: /* progress */ {
196 sqlite3_int64 nStep
= sqlite3rbu_progress(pRbu
);
197 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(nStep
));
201 case 10: /* temp_size_limit */ {
202 sqlite3_int64 nLimit
;
203 if( Tcl_GetWideIntFromObj(interp
, objv
[2], &nLimit
) ){
206 nLimit
= sqlite3rbu_temp_size_limit(pRbu
, nLimit
);
207 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(nLimit
));
211 case 11: /* temp_size */ {
212 sqlite3_int64 sz
= sqlite3rbu_temp_size(pRbu
);
213 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(sz
));
217 default: /* seems unlikely */
218 assert( !"cannot happen" );
226 ** Tclcmd: sqlite3rbu CMD <target-db> <rbu-db> ?<state-db>?
228 static int SQLITE_TCLAPI
test_sqlite3rbu(
229 ClientData clientData
,
232 Tcl_Obj
*CONST objv
[]
234 sqlite3rbu
*pRbu
= 0;
238 const char *zStateDb
= 0;
240 if( objc
!=4 && objc
!=5 ){
241 Tcl_WrongNumArgs(interp
, 1, objv
, "NAME TARGET-DB RBU-DB ?STATE-DB?");
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]);
256 ** Tclcmd: sqlite3rbu_vacuum CMD <target-db> <state-db>
258 static int SQLITE_TCLAPI
test_sqlite3rbu_vacuum(
259 ClientData clientData
,
262 Tcl_Obj
*CONST objv
[]
264 sqlite3rbu
*pRbu
= 0;
267 const char *zStateDb
= 0;
269 if( objc
!=3 && objc
!=4 ){
270 Tcl_WrongNumArgs(interp
, 1, objv
, "NAME TARGET-DB ?STATE-DB?");
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]);
285 ** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT
287 static int SQLITE_TCLAPI
test_sqlite3rbu_create_vfs(
288 ClientData clientData
,
291 Tcl_Obj
*CONST objv
[]
297 if( objc
!=3 && objc
!=4 ){
298 Tcl_WrongNumArgs(interp
, 1, objv
, "?-default? NAME PARENT");
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
);
308 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
311 sqlite3_vfs
*pVfs
= sqlite3_vfs_find(zName
);
312 sqlite3_vfs_register(pVfs
, 1);
315 Tcl_ResetResult(interp
);
320 ** Tclcmd: sqlite3rbu_destroy_vfs NAME
322 static int SQLITE_TCLAPI
test_sqlite3rbu_destroy_vfs(
323 ClientData clientData
,
326 Tcl_Obj
*CONST objv
[]
331 Tcl_WrongNumArgs(interp
, 1, objv
, "NAME");
335 zName
= Tcl_GetString(objv
[1]);
336 sqlite3rbu_destroy_vfs(zName
);
341 ** Tclcmd: sqlite3rbu_internal_test
343 static int SQLITE_TCLAPI
test_sqlite3rbu_internal_test(
344 ClientData clientData
,
347 Tcl_Obj
*CONST objv
[]
352 Tcl_WrongNumArgs(interp
, 1, objv
, "");
356 db
= sqlite3rbu_db(0, 0);
358 Tcl_AppendResult(interp
, "sqlite3rbu_db(0, 0)!=0", 0);
365 int SqliteRbu_Init(Tcl_Interp
*interp
){
368 Tcl_ObjCmdProc
*xProc
;
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
},
377 for(i
=0; i
<sizeof(aObjCmd
)/sizeof(aObjCmd
[0]); i
++){
378 Tcl_CreateObjCommand(interp
, aObjCmd
[i
].zName
, aObjCmd
[i
].xProc
, 0, 0);
384 #if defined(INCLUDE_SQLITE_TCL_H)
385 # include "sqlite_tcl.h"
389 int SqliteRbu_Init(Tcl_Interp
*interp
){ return TCL_OK
; }
390 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
391 #endif /* defined(SQLITE_TEST) */