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 *************************************************************************
12 ** Code for testing all sorts of SQLite interfaces. This code
13 ** is not included in the SQLite library.
17 #include "sqlite3intck.h"
19 #if defined(INCLUDE_SQLITE_TCL_H)
20 # include "sqlite_tcl.h"
29 int getDbPointer(Tcl_Interp
*interp
, const char *zA
, sqlite3
**ppDb
);
30 const char *sqlite3ErrName(int);
32 typedef struct TestIntck TestIntck
;
37 static int testIntckCmd(
48 {"close", 0, ""}, /* 0 */
49 {"step", 0, ""}, /* 1 */
50 {"message", 0, ""}, /* 2 */
51 {"error", 0, ""}, /* 3 */
52 {"suspend", 0, ""}, /* 4 */
53 {"test_sql", 1, ""}, /* 5 */
58 TestIntck
*p
= (TestIntck
*)clientData
;
61 Tcl_WrongNumArgs(interp
, 1, objv
, "SUB-COMMAND ...");
65 rc
= Tcl_GetIndexFromObjStruct(
66 interp
, objv
[1], aCmd
, sizeof(aCmd
[0]), "SUB-COMMAND", 0, &iIdx
70 if( objc
!=2+aCmd
[iIdx
].nArg
){
71 Tcl_WrongNumArgs(interp
, 2, objv
, aCmd
[iIdx
].zExpect
);
76 case 0: assert( 0==strcmp("close", aCmd
[iIdx
].zName
) ); {
77 Tcl_DeleteCommand(interp
, Tcl_GetStringFromObj(objv
[0], 0));
81 case 1: assert( 0==strcmp("step", aCmd
[iIdx
].zName
) ); {
82 int rc
= sqlite3_intck_step(p
->intck
);
83 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
87 case 2: assert( 0==strcmp("message", aCmd
[iIdx
].zName
) ); {
88 const char *z
= sqlite3_intck_message(p
->intck
);
89 Tcl_SetObjResult(interp
, Tcl_NewStringObj(z
? z
: "", -1));
93 case 3: assert( 0==strcmp("error", aCmd
[iIdx
].zName
) ); {
95 int rc
= sqlite3_intck_error(p
->intck
, &zErr
);
96 Tcl_Obj
*pRes
= Tcl_NewObj();
98 Tcl_ListObjAppendElement(
99 interp
, pRes
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1)
101 Tcl_ListObjAppendElement(
102 interp
, pRes
, Tcl_NewStringObj(zErr
? zErr
: 0, -1)
104 Tcl_SetObjResult(interp
, pRes
);
108 case 4: assert( 0==strcmp("suspend", aCmd
[iIdx
].zName
) ); {
109 int rc
= sqlite3_intck_suspend(p
->intck
);
110 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
114 case 5: assert( 0==strcmp("test_sql", aCmd
[iIdx
].zName
) ); {
115 const char *zObj
= Tcl_GetString(objv
[2]);
116 const char *zSql
= sqlite3_intck_test_sql(p
->intck
, zObj
[0] ? zObj
: 0);
117 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zSql
, -1));
126 ** Destructor for commands created by test_sqlite3_intck().
128 static void testIntckFree(void *clientData
){
129 TestIntck
*p
= (TestIntck
*)clientData
;
130 sqlite3_intck_close(p
->intck
);
135 ** tclcmd: sqlite3_intck DB DBNAME PATH
137 static int test_sqlite3_intck(
141 Tcl_Obj
*CONST objv
[]
149 const char *zFile
= 0;
153 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME PATH");
157 p
= (TestIntck
*)ckalloc(sizeof(TestIntck
));
158 memset(p
, 0, sizeof(TestIntck
));
160 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
163 zDb
= Tcl_GetString(objv
[2]);
164 zFile
= Tcl_GetString(objv
[3]);
166 rc
= sqlite3_intck_open(db
, zDb
, zFile
, &p
->intck
);
169 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3_errstr(rc
), -1));
174 sprintf(zName
, "intck%d", iName
);
175 }while( Tcl_GetCommandInfo(interp
, zName
, &info
)!=0 );
176 Tcl_CreateObjCommand(interp
, zName
, testIntckCmd
, (void*)p
, testIntckFree
);
177 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zName
, -1));
183 ** tclcmd: test_do_intck DB DBNAME
185 static int test_do_intck(
189 Tcl_Obj
*CONST objv
[]
194 sqlite3_intck
*pCk
= 0;
196 const char *zErr
= 0;
199 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
202 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
205 zDb
= Tcl_GetString(objv
[2]);
208 Tcl_IncrRefCount(pRet
);
210 rc
= sqlite3_intck_open(db
, zDb
, 0, &pCk
);
212 while( sqlite3_intck_step(pCk
)==SQLITE_OK
){
213 const char *zMsg
= sqlite3_intck_message(pCk
);
215 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj(zMsg
, -1));
218 rc
= sqlite3_intck_error(pCk
, &zErr
);
222 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zErr
, -1));
224 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
227 Tcl_SetObjResult(interp
, pRet
);
229 Tcl_DecrRefCount(pRet
);
230 sqlite3_intck_close(pCk
);
231 return rc
? TCL_ERROR
: TCL_OK
;
234 int Sqlitetestintck_Init(Tcl_Interp
*interp
){
235 Tcl_CreateObjCommand(interp
, "sqlite3_intck", test_sqlite3_intck
, 0, 0);
236 Tcl_CreateObjCommand(interp
, "test_do_intck", test_do_intck
, 0, 0);