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"
23 /* From main.c (apparently...) */
24 extern const char *sqlite3ErrName(int);
26 void test_rbu_delta(sqlite3_context
*pCtx
, int nArg
, sqlite3_value
**apVal
){
27 Tcl_Interp
*interp
= (Tcl_Interp
*)sqlite3_user_data(pCtx
);
31 pScript
= Tcl_NewObj();
32 Tcl_IncrRefCount(pScript
);
33 Tcl_ListObjAppendElement(0, pScript
, Tcl_NewStringObj("rbu_delta", -1));
34 for(i
=0; i
<nArg
; i
++){
35 sqlite3_value
*pIn
= apVal
[i
];
36 const char *z
= (const char*)sqlite3_value_text(pIn
);
37 Tcl_ListObjAppendElement(0, pScript
, Tcl_NewStringObj(z
, -1));
40 if( TCL_OK
==Tcl_EvalObjEx(interp
, pScript
, TCL_GLOBAL_ONLY
) ){
41 const char *z
= Tcl_GetStringResult(interp
);
42 sqlite3_result_text(pCtx
, z
, -1, SQLITE_TRANSIENT
);
44 Tcl_BackgroundError(interp
);
47 Tcl_DecrRefCount(pScript
);
51 static int test_sqlite3rbu_cmd(
52 ClientData clientData
,
58 sqlite3rbu
*pRbu
= (sqlite3rbu
*)clientData
;
64 {"step", 2, ""}, /* 0 */
65 {"close", 2, ""}, /* 1 */
66 {"create_rbu_delta", 2, ""}, /* 2 */
67 {"savestate", 2, ""}, /* 3 */
68 {"dbMain_eval", 3, "SQL"}, /* 4 */
74 Tcl_WrongNumArgs(interp
, 1, objv
, "METHOD");
77 ret
= Tcl_GetIndexFromObjStruct(
78 interp
, objv
[1], aCmd
, sizeof(aCmd
[0]), "method", 0, &iCmd
80 if( ret
) return TCL_ERROR
;
81 if( objc
!=aCmd
[iCmd
].nArg
){
82 Tcl_WrongNumArgs(interp
, 1, objv
, aCmd
[iCmd
].zUsage
);
88 int rc
= sqlite3rbu_step(pRbu
);
89 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
96 Tcl_DeleteCommand(interp
, Tcl_GetString(objv
[0]));
97 rc
= sqlite3rbu_close(pRbu
, &zErrmsg
);
98 if( rc
==SQLITE_OK
|| rc
==SQLITE_DONE
){
99 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
100 assert( zErrmsg
==0 );
102 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
104 Tcl_AppendResult(interp
, " - ", zErrmsg
, 0);
105 sqlite3_free(zErrmsg
);
112 case 2: /* create_rbu_delta */ {
113 sqlite3
*db
= sqlite3rbu_db(pRbu
, 0);
114 int rc
= sqlite3_create_function(
115 db
, "rbu_delta", -1, SQLITE_UTF8
, (void*)interp
, test_rbu_delta
, 0, 0
117 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
118 ret
= (rc
==SQLITE_OK
? TCL_OK
: TCL_ERROR
);
122 case 3: /* savestate */ {
123 int rc
= sqlite3rbu_savestate(pRbu
);
124 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
125 ret
= (rc
==SQLITE_OK
? TCL_OK
: TCL_ERROR
);
129 case 4: /* dbMain_eval */ {
130 sqlite3
*db
= sqlite3rbu_db(pRbu
, 0);
131 int rc
= sqlite3_exec(db
, Tcl_GetString(objv
[2]), 0, 0, 0);
133 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3_errmsg(db
), -1));
139 default: /* seems unlikely */
140 assert( !"cannot happen" );
148 ** Tclcmd: sqlite3rbu CMD <target-db> <rbu-db> ?<state-db>?
150 static int test_sqlite3rbu(
151 ClientData clientData
,
154 Tcl_Obj
*CONST objv
[]
156 sqlite3rbu
*pRbu
= 0;
160 const char *zStateDb
= 0;
162 if( objc
!=4 && objc
!=5 ){
163 Tcl_WrongNumArgs(interp
, 1, objv
, "NAME TARGET-DB RBU-DB ?STATE-DB?");
166 zCmd
= Tcl_GetString(objv
[1]);
167 zTarget
= Tcl_GetString(objv
[2]);
168 zRbu
= Tcl_GetString(objv
[3]);
169 if( objc
==5 ) zStateDb
= Tcl_GetString(objv
[4]);
171 pRbu
= sqlite3rbu_open(zTarget
, zRbu
, zStateDb
);
172 Tcl_CreateObjCommand(interp
, zCmd
, test_sqlite3rbu_cmd
, (ClientData
)pRbu
, 0);
173 Tcl_SetObjResult(interp
, objv
[1]);
178 ** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT
180 static int test_sqlite3rbu_create_vfs(
181 ClientData clientData
,
184 Tcl_Obj
*CONST objv
[]
190 if( objc
!=3 && objc
!=4 ){
191 Tcl_WrongNumArgs(interp
, 1, objv
, "?-default? NAME PARENT");
195 zName
= Tcl_GetString(objv
[objc
-2]);
196 zParent
= Tcl_GetString(objv
[objc
-1]);
197 if( zParent
[0]=='\0' ) zParent
= 0;
199 rc
= sqlite3rbu_create_vfs(zName
, zParent
);
201 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
204 sqlite3_vfs
*pVfs
= sqlite3_vfs_find(zName
);
205 sqlite3_vfs_register(pVfs
, 1);
208 Tcl_ResetResult(interp
);
213 ** Tclcmd: sqlite3rbu_destroy_vfs NAME
215 static int test_sqlite3rbu_destroy_vfs(
216 ClientData clientData
,
219 Tcl_Obj
*CONST objv
[]
224 Tcl_WrongNumArgs(interp
, 1, objv
, "NAME");
228 zName
= Tcl_GetString(objv
[1]);
229 sqlite3rbu_destroy_vfs(zName
);
234 ** Tclcmd: sqlite3rbu_internal_test
236 static int test_sqlite3rbu_internal_test(
237 ClientData clientData
,
240 Tcl_Obj
*CONST objv
[]
245 Tcl_WrongNumArgs(interp
, 1, objv
, "");
249 db
= sqlite3rbu_db(0, 0);
251 Tcl_AppendResult(interp
, "sqlite3rbu_db(0, 0)!=0", 0);
258 int SqliteRbu_Init(Tcl_Interp
*interp
){
261 Tcl_ObjCmdProc
*xProc
;
263 { "sqlite3rbu", test_sqlite3rbu
},
264 { "sqlite3rbu_create_vfs", test_sqlite3rbu_create_vfs
},
265 { "sqlite3rbu_destroy_vfs", test_sqlite3rbu_destroy_vfs
},
266 { "sqlite3rbu_internal_test", test_sqlite3rbu_internal_test
},
269 for(i
=0; i
<sizeof(aObjCmd
)/sizeof(aObjCmd
[0]); i
++){
270 Tcl_CreateObjCommand(interp
, aObjCmd
[i
].zName
, aObjCmd
[i
].xProc
, 0, 0);
277 int SqliteRbu_Init(Tcl_Interp
*interp
){ return TCL_OK
; }
278 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
279 #endif /* defined(SQLITE_TEST) */