18c8eba10Sdanielk1977 /*
28c8eba10Sdanielk1977 ** 2007 March 29
38c8eba10Sdanielk1977 **
48c8eba10Sdanielk1977 ** The author disclaims copyright to this source code. In place of
58c8eba10Sdanielk1977 ** a legal notice, here is a blessing:
68c8eba10Sdanielk1977 **
78c8eba10Sdanielk1977 ** May you do good and not evil.
88c8eba10Sdanielk1977 ** May you find forgiveness for yourself and forgive others.
98c8eba10Sdanielk1977 ** May you share freely, never taking more than you give.
108c8eba10Sdanielk1977 **
118c8eba10Sdanielk1977 *************************************************************************
128c8eba10Sdanielk1977 **
138c8eba10Sdanielk1977 ** This file contains obscure tests of the C-interface required
148c8eba10Sdanielk1977 ** for completeness. Test code is written in C for these cases
158c8eba10Sdanielk1977 ** as there is not much point in binding to Tcl.
168c8eba10Sdanielk1977 */
178c8eba10Sdanielk1977 #include "sqliteInt.h"
1852b1dbb5Smistachkin #if defined(INCLUDE_SQLITE_TCL_H)
1952b1dbb5Smistachkin # include "sqlite_tcl.h"
2052b1dbb5Smistachkin #else
218c8eba10Sdanielk1977 # include "tcl.h"
2252b1dbb5Smistachkin #endif
238c8eba10Sdanielk1977 #include <stdlib.h>
248c8eba10Sdanielk1977 #include <string.h>
258c8eba10Sdanielk1977
268c8eba10Sdanielk1977 /*
278c8eba10Sdanielk1977 ** c_collation_test
288c8eba10Sdanielk1977 */
c_collation_test(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv[])29*7617e4a8Smistachkin static int SQLITE_TCLAPI c_collation_test(
308c8eba10Sdanielk1977 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
318c8eba10Sdanielk1977 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
328c8eba10Sdanielk1977 int objc, /* Number of arguments */
338c8eba10Sdanielk1977 Tcl_Obj *CONST objv[] /* Command arguments */
348c8eba10Sdanielk1977 ){
358c8eba10Sdanielk1977 const char *zErrFunction = "N/A";
368c8eba10Sdanielk1977 sqlite3 *db;
378c8eba10Sdanielk1977
388c8eba10Sdanielk1977 int rc;
398c8eba10Sdanielk1977 if( objc!=1 ){
408c8eba10Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "");
418c8eba10Sdanielk1977 return TCL_ERROR;
428c8eba10Sdanielk1977 }
438c8eba10Sdanielk1977
448c8eba10Sdanielk1977 /* Open a database. */
458c8eba10Sdanielk1977 rc = sqlite3_open(":memory:", &db);
468c8eba10Sdanielk1977 if( rc!=SQLITE_OK ){
478c8eba10Sdanielk1977 zErrFunction = "sqlite3_open";
488c8eba10Sdanielk1977 goto error_out;
498c8eba10Sdanielk1977 }
508c8eba10Sdanielk1977
518c8eba10Sdanielk1977 rc = sqlite3_create_collation(db, "collate", 456, 0, 0);
528278ce79Sdrh if( rc!=SQLITE_MISUSE ){
538c8eba10Sdanielk1977 sqlite3_close(db);
548c8eba10Sdanielk1977 zErrFunction = "sqlite3_create_collation";
558c8eba10Sdanielk1977 goto error_out;
568c8eba10Sdanielk1977 }
578c8eba10Sdanielk1977
588c8eba10Sdanielk1977 sqlite3_close(db);
598c8eba10Sdanielk1977 return TCL_OK;
608c8eba10Sdanielk1977
618c8eba10Sdanielk1977 error_out:
628c8eba10Sdanielk1977 Tcl_ResetResult(interp);
638c8eba10Sdanielk1977 Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0);
648c8eba10Sdanielk1977 return TCL_ERROR;
658c8eba10Sdanielk1977 }
668c8eba10Sdanielk1977
678c8eba10Sdanielk1977 /*
688c8eba10Sdanielk1977 ** c_realloc_test
698c8eba10Sdanielk1977 */
c_realloc_test(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv[])70*7617e4a8Smistachkin static int SQLITE_TCLAPI c_realloc_test(
718c8eba10Sdanielk1977 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
728c8eba10Sdanielk1977 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
738c8eba10Sdanielk1977 int objc, /* Number of arguments */
748c8eba10Sdanielk1977 Tcl_Obj *CONST objv[] /* Command arguments */
758c8eba10Sdanielk1977 ){
768c8eba10Sdanielk1977 void *p;
778c8eba10Sdanielk1977 const char *zErrFunction = "N/A";
788c8eba10Sdanielk1977
798c8eba10Sdanielk1977 if( objc!=1 ){
808c8eba10Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "");
818c8eba10Sdanielk1977 return TCL_ERROR;
828c8eba10Sdanielk1977 }
838c8eba10Sdanielk1977
848c8eba10Sdanielk1977 p = sqlite3_malloc(5);
858c8eba10Sdanielk1977 if( !p ){
868c8eba10Sdanielk1977 zErrFunction = "sqlite3_malloc";
878c8eba10Sdanielk1977 goto error_out;
888c8eba10Sdanielk1977 }
898c8eba10Sdanielk1977
908c8eba10Sdanielk1977 /* Test that realloc()ing a block of memory to a negative size is
918c8eba10Sdanielk1977 ** the same as free()ing that memory.
928c8eba10Sdanielk1977 */
938c8eba10Sdanielk1977 p = sqlite3_realloc(p, -1);
948c8eba10Sdanielk1977 if( p ){
958c8eba10Sdanielk1977 zErrFunction = "sqlite3_realloc";
968c8eba10Sdanielk1977 goto error_out;
978c8eba10Sdanielk1977 }
988c8eba10Sdanielk1977
998c8eba10Sdanielk1977 return TCL_OK;
1008c8eba10Sdanielk1977
1018c8eba10Sdanielk1977 error_out:
1028c8eba10Sdanielk1977 Tcl_ResetResult(interp);
1038c8eba10Sdanielk1977 Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0);
1048c8eba10Sdanielk1977 return TCL_ERROR;
1058c8eba10Sdanielk1977 }
1068c8eba10Sdanielk1977
1078c8eba10Sdanielk1977
1088c8eba10Sdanielk1977 /*
1098c8eba10Sdanielk1977 ** c_misuse_test
1108c8eba10Sdanielk1977 */
c_misuse_test(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv[])111*7617e4a8Smistachkin static int SQLITE_TCLAPI c_misuse_test(
1128c8eba10Sdanielk1977 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
1138c8eba10Sdanielk1977 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
1148c8eba10Sdanielk1977 int objc, /* Number of arguments */
1158c8eba10Sdanielk1977 Tcl_Obj *CONST objv[] /* Command arguments */
1168c8eba10Sdanielk1977 ){
1178c8eba10Sdanielk1977 const char *zErrFunction = "N/A";
1188c8eba10Sdanielk1977 sqlite3 *db = 0;
119860e077aSdrh sqlite3_stmt *pStmt;
1208c8eba10Sdanielk1977 int rc;
1218c8eba10Sdanielk1977
1228c8eba10Sdanielk1977 if( objc!=1 ){
1238c8eba10Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "");
1248c8eba10Sdanielk1977 return TCL_ERROR;
1258c8eba10Sdanielk1977 }
1268c8eba10Sdanielk1977
1278c8eba10Sdanielk1977 /* Open a database. Then close it again. We need to do this so that
1288c8eba10Sdanielk1977 ** we have a "closed database handle" to pass to various API functions.
1298c8eba10Sdanielk1977 */
1308c8eba10Sdanielk1977 rc = sqlite3_open(":memory:", &db);
1318c8eba10Sdanielk1977 if( rc!=SQLITE_OK ){
1328c8eba10Sdanielk1977 zErrFunction = "sqlite3_open";
1338c8eba10Sdanielk1977 goto error_out;
1348c8eba10Sdanielk1977 }
1358c8eba10Sdanielk1977 sqlite3_close(db);
1368c8eba10Sdanielk1977
1378c8eba10Sdanielk1977
1388c8eba10Sdanielk1977 rc = sqlite3_errcode(db);
1398c8eba10Sdanielk1977 if( rc!=SQLITE_MISUSE ){
14001495b99Sdrh zErrFunction = "sqlite3_errcode";
14101495b99Sdrh goto error_out;
14201495b99Sdrh }
14301495b99Sdrh
144860e077aSdrh pStmt = (sqlite3_stmt*)1234;
145860e077aSdrh rc = sqlite3_prepare(db, 0, 0, &pStmt, 0);
14601495b99Sdrh if( rc!=SQLITE_MISUSE ){
14701495b99Sdrh zErrFunction = "sqlite3_prepare";
14801495b99Sdrh goto error_out;
14901495b99Sdrh }
150860e077aSdrh assert( pStmt==0 ); /* Verify that pStmt is zeroed even on a MISUSE error */
15101495b99Sdrh
152860e077aSdrh pStmt = (sqlite3_stmt*)1234;
153860e077aSdrh rc = sqlite3_prepare_v2(db, 0, 0, &pStmt, 0);
15401495b99Sdrh if( rc!=SQLITE_MISUSE ){
15501495b99Sdrh zErrFunction = "sqlite3_prepare_v2";
1568c8eba10Sdanielk1977 goto error_out;
1578c8eba10Sdanielk1977 }
158860e077aSdrh assert( pStmt==0 );
1598c8eba10Sdanielk1977
160af30469dSdrh #ifndef SQLITE_OMIT_UTF16
161860e077aSdrh pStmt = (sqlite3_stmt*)1234;
162860e077aSdrh rc = sqlite3_prepare16(db, 0, 0, &pStmt, 0);
1638c8eba10Sdanielk1977 if( rc!=SQLITE_MISUSE ){
1648c8eba10Sdanielk1977 zErrFunction = "sqlite3_prepare16";
1658c8eba10Sdanielk1977 goto error_out;
1668c8eba10Sdanielk1977 }
167860e077aSdrh assert( pStmt==0 );
168860e077aSdrh pStmt = (sqlite3_stmt*)1234;
169860e077aSdrh rc = sqlite3_prepare16_v2(db, 0, 0, &pStmt, 0);
17001495b99Sdrh if( rc!=SQLITE_MISUSE ){
17101495b99Sdrh zErrFunction = "sqlite3_prepare16_v2";
17201495b99Sdrh goto error_out;
17301495b99Sdrh }
174860e077aSdrh assert( pStmt==0 );
175af30469dSdrh #endif
1768c8eba10Sdanielk1977
1778c8eba10Sdanielk1977 return TCL_OK;
1788c8eba10Sdanielk1977
1798c8eba10Sdanielk1977 error_out:
1808c8eba10Sdanielk1977 Tcl_ResetResult(interp);
1818c8eba10Sdanielk1977 Tcl_AppendResult(interp, "Error testing function: ", zErrFunction, 0);
1828c8eba10Sdanielk1977 return TCL_ERROR;
1838c8eba10Sdanielk1977 }
1848c8eba10Sdanielk1977
1858c8eba10Sdanielk1977 /*
1868c8eba10Sdanielk1977 ** Register commands with the TCL interpreter.
1878c8eba10Sdanielk1977 */
Sqlitetest9_Init(Tcl_Interp * interp)1888c8eba10Sdanielk1977 int Sqlitetest9_Init(Tcl_Interp *interp){
1898c8eba10Sdanielk1977 static struct {
1908c8eba10Sdanielk1977 char *zName;
1918c8eba10Sdanielk1977 Tcl_ObjCmdProc *xProc;
1928c8eba10Sdanielk1977 void *clientData;
1938c8eba10Sdanielk1977 } aObjCmd[] = {
1948c8eba10Sdanielk1977 { "c_misuse_test", c_misuse_test, 0 },
1958c8eba10Sdanielk1977 { "c_realloc_test", c_realloc_test, 0 },
1968c8eba10Sdanielk1977 { "c_collation_test", c_collation_test, 0 },
1978c8eba10Sdanielk1977 };
1988c8eba10Sdanielk1977 int i;
1998c8eba10Sdanielk1977 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
2008c8eba10Sdanielk1977 Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
2018c8eba10Sdanielk1977 aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
2028c8eba10Sdanielk1977 }
2038c8eba10Sdanielk1977 return TCL_OK;
2048c8eba10Sdanielk1977 }
205