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. It is used for automated
14 ** testing of the SQLite library.
16 #include "sqliteInt.h"
22 #if defined(INCLUDE_SQLITE_TCL_H)
23 # include "sqlite_tcl.h"
31 ** This is a copy of the first part of the SqliteDb structure in
32 ** tclsqlite.c. We need it here so that the get_sqlite_pointer routine
33 ** can extract the sqlite3* pointer from an existing Tcl SQLite
41 ** Convert text generated by the "%p" conversion format back into
44 static int testHexToInt(int h
){
45 if( h
>='0' && h
<='9' ){
47 }else if( h
>='a' && h
<='f' ){
50 assert( h
>='A' && h
<='F' );
54 void *sqlite3TestTextToPtr(const char *z
){
58 if( z
[0]=='0' && z
[1]=='x' ){
63 v
= (v
<<4) + testHexToInt(*z
);
66 if( sizeof(p
)==sizeof(v
) ){
67 memcpy(&p
, &v
, sizeof(p
));
69 assert( sizeof(p
)==sizeof(v2
) );
71 memcpy(&p
, &v2
, sizeof(p
));
78 ** A TCL command that returns the address of the sqlite* pointer
79 ** for an sqlite connection instance. Bad things happen if the
80 ** input is not an sqlite connection.
82 static int SQLITE_TCLAPI
get_sqlite_pointer(
92 Tcl_WrongNumArgs(interp
, 1, objv
, "SQLITE-CONNECTION");
95 if( !Tcl_GetCommandInfo(interp
, Tcl_GetString(objv
[1]), &cmdInfo
) ){
96 Tcl_AppendResult(interp
, "command not found: ",
97 Tcl_GetString(objv
[1]), (char*)0);
100 p
= (struct SqliteDb
*)cmdInfo
.objClientData
;
101 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%p", p
->db
);
102 Tcl_AppendResult(interp
, zBuf
, 0);
107 ** Decode a pointer to an sqlite3 object.
109 int getDbPointer(Tcl_Interp
*interp
, const char *zA
, sqlite3
**ppDb
){
112 if( Tcl_GetCommandInfo(interp
, zA
, &cmdInfo
) ){
113 p
= (struct SqliteDb
*)cmdInfo
.objClientData
;
116 *ppDb
= (sqlite3
*)sqlite3TestTextToPtr(zA
);
123 ** Decode a Win32 HANDLE object.
125 int getWin32Handle(Tcl_Interp
*interp
, const char *zA
, LPHANDLE phFile
){
126 *phFile
= (HANDLE
)sqlite3TestTextToPtr(zA
);
131 extern const char *sqlite3ErrName(int);
132 #define t1ErrorName sqlite3ErrName
135 ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the
136 ** fact that the sqlite3* is the first field in the Vdbe structure.
138 #define StmtToDb(X) sqlite3_db_handle(X)
141 ** Check a return value to make sure it agrees with the results
142 ** from sqlite3_errcode.
144 int sqlite3TestErrCode(Tcl_Interp
*interp
, sqlite3
*db
, int rc
){
145 if( sqlite3_threadsafe()==0 && rc
!=SQLITE_MISUSE
&& rc
!=SQLITE_OK
146 && sqlite3_errcode(db
)!=rc
){
148 int r2
= sqlite3_errcode(db
);
149 sqlite3_snprintf(sizeof(zBuf
), zBuf
,
150 "error code %s (%d) does not match sqlite3_errcode %s (%d)",
151 t1ErrorName(rc
), rc
, t1ErrorName(r2
), r2
);
152 Tcl_ResetResult(interp
);
153 Tcl_AppendResult(interp
, zBuf
, 0);
160 ** Decode a pointer to an sqlite3_stmt object.
162 static int getStmtPointer(
165 sqlite3_stmt
**ppStmt
167 *ppStmt
= (sqlite3_stmt
*)sqlite3TestTextToPtr(zArg
);
172 ** Generate a text representation of a pointer that can be understood
173 ** by the getDbPointer and getVmPointer routines above.
175 ** The problem is, on some machines (Solaris) if you do a printf with
176 ** "%p" you cannot turn around and do a scanf with the same "%p" and
177 ** get your pointer back. You have to prepend a "0x" before it will
178 ** work. Or at least that is what is reported to me (drh). But this
179 ** behavior varies from machine to machine. The solution used her is
180 ** to test the string right after it is generated to see if it can be
181 ** understood by scanf, and if not, try prepending an "0x" to see if
182 ** that helps. If nothing works, a fatal error is generated.
184 int sqlite3TestMakePointerStr(Tcl_Interp
*interp
, char *zPtr
, void *p
){
185 sqlite3_snprintf(100, zPtr
, "%p", p
);
190 ** The callback routine for sqlite3_exec_printf().
192 static int exec_printf_cb(void *pArg
, int argc
, char **argv
, char **name
){
193 Tcl_DString
*str
= (Tcl_DString
*)pArg
;
196 if( Tcl_DStringLength(str
)==0 ){
197 for(i
=0; i
<argc
; i
++){
198 Tcl_DStringAppendElement(str
, name
[i
] ? name
[i
] : "NULL");
201 for(i
=0; i
<argc
; i
++){
202 Tcl_DStringAppendElement(str
, argv
[i
] ? argv
[i
] : "NULL");
208 ** The I/O tracing callback.
210 #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
211 static FILE *iotrace_file
= 0;
212 static void io_trace_callback(const char *zFormat
, ...){
214 va_start(ap
, zFormat
);
215 vfprintf(iotrace_file
, zFormat
, ap
);
217 fflush(iotrace_file
);
222 ** Usage: io_trace FILENAME
224 ** Turn I/O tracing on or off. If FILENAME is not an empty string,
225 ** I/O tracing begins going into FILENAME. If FILENAME is an empty
226 ** string, I/O tracing is turned off.
228 static int SQLITE_TCLAPI
test_io_trace(
230 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
231 int argc
, /* Number of arguments */
232 char **argv
/* Text of each argument */
234 #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
236 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
241 if( iotrace_file
!=stdout
&& iotrace_file
!=stderr
){
242 fclose(iotrace_file
);
248 if( strcmp(argv
[1],"stdout")==0 ){
249 iotrace_file
= stdout
;
250 }else if( strcmp(argv
[1],"stderr")==0 ){
251 iotrace_file
= stderr
;
253 iotrace_file
= fopen(argv
[1], "w");
255 sqlite3IoTrace
= io_trace_callback
;
262 ** Usage: clang_sanitize_address
264 ** Returns true if the program was compiled using clang with the
265 ** -fsanitize=address switch on the command line. False otherwise.
267 ** Also return true if the OMIT_MISUSE environment variable exists.
269 static int SQLITE_TCLAPI
clang_sanitize_address(
271 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
272 int argc
, /* Number of arguments */
273 char **argv
/* Text of each argument */
276 #if defined(__has_feature)
277 # if __has_feature(address_sanitizer)
281 #ifdef __SANITIZE_ADDRESS__
284 if( res
==0 && getenv("OMIT_MISUSE")!=0 ) res
= 1;
285 Tcl_SetObjResult(interp
, Tcl_NewIntObj(res
));
290 ** Usage: sqlite3_exec_printf DB FORMAT STRING
292 ** Invoke the sqlite3_exec_printf() interface using the open database
293 ** DB. The SQL is the string FORMAT. The format string should contain
294 ** one %s or %q. STRING is the value inserted into %s or %q.
296 static int SQLITE_TCLAPI
test_exec_printf(
298 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
299 int argc
, /* Number of arguments */
300 char **argv
/* Text of each argument */
309 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
310 " DB FORMAT STRING", 0);
313 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
314 Tcl_DStringInit(&str
);
315 zSql
= sqlite3_mprintf(argv
[2], argv
[3]);
316 rc
= sqlite3_exec(db
, zSql
, exec_printf_cb
, &str
, &zErr
);
318 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", rc
);
319 Tcl_AppendElement(interp
, zBuf
);
320 Tcl_AppendElement(interp
, rc
==SQLITE_OK
? Tcl_DStringValue(&str
) : zErr
);
321 Tcl_DStringFree(&str
);
322 if( zErr
) sqlite3_free(zErr
);
323 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
328 ** Usage: sqlite3_exec_hex DB HEX
330 ** Invoke the sqlite3_exec() on a string that is obtained by translating
331 ** HEX into ASCII. Most characters are translated as is. %HH becomes
334 static int SQLITE_TCLAPI
test_exec_hex(
336 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
337 int argc
, /* Number of arguments */
338 char **argv
/* Text of each argument */
348 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
352 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
354 for(i
=j
=0; i
<(sizeof(zSql
)-1) && zHex
[j
]; i
++, j
++){
355 if( zHex
[j
]=='%' && zHex
[j
+2] && zHex
[j
+2] ){
356 zSql
[i
] = (testHexToInt(zHex
[j
+1])<<4) + testHexToInt(zHex
[j
+2]);
363 Tcl_DStringInit(&str
);
364 rc
= sqlite3_exec(db
, zSql
, exec_printf_cb
, &str
, &zErr
);
365 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", rc
);
366 Tcl_AppendElement(interp
, zBuf
);
367 Tcl_AppendElement(interp
, rc
==SQLITE_OK
? Tcl_DStringValue(&str
) : zErr
);
368 Tcl_DStringFree(&str
);
369 if( zErr
) sqlite3_free(zErr
);
370 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
375 ** Usage: db_enter DB
378 ** Enter or leave the mutex on a database connection.
380 static int SQLITE_TCLAPI
db_enter(
382 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
383 int argc
, /* Number of arguments */
384 char **argv
/* Text of each argument */
388 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
392 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
393 sqlite3_mutex_enter(db
->mutex
);
396 static int SQLITE_TCLAPI
db_leave(
398 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
399 int argc
, /* Number of arguments */
400 char **argv
/* Text of each argument */
404 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
408 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
409 sqlite3_mutex_leave(db
->mutex
);
414 ** Usage: sqlite3_exec DB SQL
416 ** Invoke the sqlite3_exec interface using the open database DB
418 static int SQLITE_TCLAPI
test_exec(
420 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
421 int argc
, /* Number of arguments */
422 char **argv
/* Text of each argument */
432 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
436 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
437 Tcl_DStringInit(&str
);
438 zSql
= sqlite3_mprintf("%s", argv
[2]);
439 for(i
=j
=0; zSql
[i
];){
441 zSql
[j
++] = (testHexToInt(zSql
[i
+1])<<4) + testHexToInt(zSql
[i
+2]);
444 zSql
[j
++] = zSql
[i
++];
448 rc
= sqlite3_exec(db
, zSql
, exec_printf_cb
, &str
, &zErr
);
450 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", rc
);
451 Tcl_AppendElement(interp
, zBuf
);
452 Tcl_AppendElement(interp
, rc
==SQLITE_OK
? Tcl_DStringValue(&str
) : zErr
);
453 Tcl_DStringFree(&str
);
454 if( zErr
) sqlite3_free(zErr
);
455 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
460 ** Usage: sqlite3_exec_nr DB SQL
462 ** Invoke the sqlite3_exec interface using the open database DB. Discard
465 static int SQLITE_TCLAPI
test_exec_nr(
467 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
468 int argc
, /* Number of arguments */
469 char **argv
/* Text of each argument */
475 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
479 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
480 rc
= sqlite3_exec(db
, argv
[2], 0, 0, &zErr
);
481 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
486 ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ...
488 ** Test the %z format of sqlite_mprintf(). Use multiple mprintf() calls to
489 ** concatenate arg0 through argn using separator as the separator.
490 ** Return the result.
492 static int SQLITE_TCLAPI
test_mprintf_z(
494 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
495 int argc
, /* Number of arguments */
496 char **argv
/* Text of each argument */
501 for(i
=2; i
<argc
&& (i
==2 || zResult
); i
++){
502 zResult
= sqlite3_mprintf("%z%s%s", zResult
, argv
[1], argv
[i
]);
504 Tcl_AppendResult(interp
, zResult
, 0);
505 sqlite3_free(zResult
);
510 ** Usage: sqlite3_mprintf_n_test STRING
512 ** Test the %n format of sqlite_mprintf(). Return the length of the
515 static int SQLITE_TCLAPI
test_mprintf_n(
517 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
518 int argc
, /* Number of arguments */
519 char **argv
/* Text of each argument */
523 zStr
= sqlite3_mprintf("%s%n", argv
[1], &n
);
525 Tcl_SetObjResult(interp
, Tcl_NewIntObj(n
));
530 ** Usage: sqlite3_snprintf_int SIZE FORMAT INT
532 ** Test the of sqlite3_snprintf() routine. SIZE is the size of the
533 ** output buffer in bytes. The maximum size is 100. FORMAT is the
534 ** format string. INT is a single integer argument. The FORMAT
535 ** string must require no more than this one integer argument. If
536 ** You pass in a format string that requires more than one argument,
537 ** bad things will happen.
539 static int SQLITE_TCLAPI
test_snprintf_int(
541 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
542 int argc
, /* Number of arguments */
543 char **argv
/* Text of each argument */
546 int n
= atoi(argv
[1]);
547 const char *zFormat
= argv
[2];
548 int a1
= atoi(argv
[3]);
549 if( n
>sizeof(zStr
) ) n
= sizeof(zStr
);
550 sqlite3_snprintf(sizeof(zStr
), zStr
, "abcdefghijklmnopqrstuvwxyz");
551 sqlite3_snprintf(n
, zStr
, zFormat
, a1
);
552 Tcl_AppendResult(interp
, zStr
, 0);
556 #ifndef SQLITE_OMIT_GET_TABLE
559 ** Usage: sqlite3_get_table_printf DB FORMAT STRING ?--no-counts?
561 ** Invoke the sqlite3_get_table_printf() interface using the open database
562 ** DB. The SQL is the string FORMAT. The format string should contain
563 ** one %s or %q. STRING is the value inserted into %s or %q.
565 static int SQLITE_TCLAPI
test_get_table_printf(
567 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
568 int argc
, /* Number of arguments */
569 char **argv
/* Text of each argument */
575 int nRow
= 0, nCol
= 0;
582 if( Tcl_GetInt(interp
, argv
[4], &resCount
) ) return TCL_ERROR
;
584 if( argc
!=4 && argc
!=5 ){
585 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
586 " DB FORMAT STRING ?COUNT?", 0);
589 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
590 Tcl_DStringInit(&str
);
591 zSql
= sqlite3_mprintf(argv
[2],argv
[3]);
593 rc
= sqlite3_get_table(db
, zSql
, &aResult
, 0, 0, &zErr
);
595 rc
= sqlite3_get_table(db
, zSql
, &aResult
, &nRow
, &nCol
, &zErr
);
596 resCount
= (nRow
+1)*nCol
;
599 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", rc
);
600 Tcl_AppendElement(interp
, zBuf
);
603 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", nRow
);
604 Tcl_AppendElement(interp
, zBuf
);
605 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", nCol
);
606 Tcl_AppendElement(interp
, zBuf
);
608 for(i
=0; i
<resCount
; i
++){
609 Tcl_AppendElement(interp
, aResult
[i
] ? aResult
[i
] : "NULL");
612 Tcl_AppendElement(interp
, zErr
);
614 sqlite3_free_table(aResult
);
615 if( zErr
) sqlite3_free(zErr
);
616 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
620 #endif /* SQLITE_OMIT_GET_TABLE */
624 ** Usage: sqlite3_last_insert_rowid DB
626 ** Returns the integer ROWID of the most recent insert.
628 static int SQLITE_TCLAPI
test_last_rowid(
630 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
631 int argc
, /* Number of arguments */
632 char **argv
/* Text of each argument */
638 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0], " DB\"", 0);
641 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
642 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%lld", sqlite3_last_insert_rowid(db
));
643 Tcl_AppendResult(interp
, zBuf
, 0);
648 ** Usage: sqlite3_key DB KEY
650 ** Set the codec key.
652 static int SQLITE_TCLAPI
test_key(
654 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
655 int argc
, /* Number of arguments */
656 char **argv
/* Text of each argument */
658 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
663 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
667 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
670 sqlite3_key(db
, zKey
, nKey
);
676 ** Usage: sqlite3_rekey DB KEY
678 ** Change the codec key.
680 static int SQLITE_TCLAPI
test_rekey(
682 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
683 int argc
, /* Number of arguments */
684 char **argv
/* Text of each argument */
686 #ifdef SQLITE_HAS_CODEC
691 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
695 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
698 sqlite3_rekey(db
, zKey
, nKey
);
704 ** Usage: sqlite3_close DB
706 ** Closes the database opened by sqlite3_open.
708 static int SQLITE_TCLAPI
sqlite_test_close(
710 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
711 int argc
, /* Number of arguments */
712 char **argv
/* Text of each argument */
717 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
721 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
722 rc
= sqlite3_close(db
);
723 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
728 ** Usage: sqlite3_close_v2 DB
730 ** Closes the database opened by sqlite3_open.
732 static int SQLITE_TCLAPI
sqlite_test_close_v2(
734 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
735 int argc
, /* Number of arguments */
736 char **argv
/* Text of each argument */
741 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
745 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
746 rc
= sqlite3_close_v2(db
);
747 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
752 ** Implementation of the x_coalesce() function.
753 ** Return the first argument non-NULL argument.
755 static void t1_ifnullFunc(
756 sqlite3_context
*context
,
761 for(i
=0; i
<argc
; i
++){
762 if( SQLITE_NULL
!=sqlite3_value_type(argv
[i
]) ){
763 int n
= sqlite3_value_bytes(argv
[i
]);
764 sqlite3_result_text(context
, (char*)sqlite3_value_text(argv
[i
]),
765 n
, SQLITE_TRANSIENT
);
772 ** These are test functions. hex8() interprets its argument as
773 ** UTF8 and returns a hex encoding. hex16le() interprets its argument
774 ** as UTF16le and returns a hex encoding.
776 static void hex8Func(sqlite3_context
*p
, int argc
, sqlite3_value
**argv
){
777 const unsigned char *z
;
780 z
= sqlite3_value_text(argv
[0]);
781 for(i
=0; i
<sizeof(zBuf
)/2 - 2 && z
[i
]; i
++){
782 sqlite3_snprintf(sizeof(zBuf
)-i
*2, &zBuf
[i
*2], "%02x", z
[i
]);
785 sqlite3_result_text(p
, (char*)zBuf
, -1, SQLITE_TRANSIENT
);
787 #ifndef SQLITE_OMIT_UTF16
788 static void hex16Func(sqlite3_context
*p
, int argc
, sqlite3_value
**argv
){
789 const unsigned short int *z
;
792 z
= sqlite3_value_text16(argv
[0]);
793 for(i
=0; i
<sizeof(zBuf
)/4 - 4 && z
[i
]; i
++){
794 sqlite3_snprintf(sizeof(zBuf
)-i
*4, &zBuf
[i
*4],"%04x", z
[i
]&0xff);
797 sqlite3_result_text(p
, (char*)zBuf
, -1, SQLITE_TRANSIENT
);
802 ** A structure into which to accumulate text.
805 int nAlloc
; /* Space allocated */
806 int nUsed
; /* Space used */
807 char *z
; /* The space */
811 ** Append text to a dstr
813 static void dstrAppend(struct dstr
*p
, const char *z
, int divider
){
814 int n
= (int)strlen(z
);
815 if( p
->nUsed
+ n
+ 2 > p
->nAlloc
){
817 p
->nAlloc
= p
->nAlloc
*2 + n
+ 200;
818 zNew
= sqlite3_realloc(p
->z
, p
->nAlloc
);
821 memset(p
, 0, sizeof(*p
));
826 if( divider
&& p
->nUsed
>0 ){
827 p
->z
[p
->nUsed
++] = divider
;
829 memcpy(&p
->z
[p
->nUsed
], z
, n
+1);
834 ** Invoked for each callback from sqlite3ExecFunc
836 static int execFuncCallback(void *pData
, int argc
, char **argv
, char **NotUsed
){
837 struct dstr
*p
= (struct dstr
*)pData
;
839 for(i
=0; i
<argc
; i
++){
841 dstrAppend(p
, "NULL", ' ');
843 dstrAppend(p
, argv
[i
], ' ');
850 ** Implementation of the x_sqlite_exec() function. This function takes
851 ** a single argument and attempts to execute that argument as SQL code.
852 ** This is illegal and should set the SQLITE_MISUSE flag on the database.
854 ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec()
855 ** from within a function call.
857 ** This routine simulates the effect of having two threads attempt to
858 ** use the same database at the same time.
860 static void sqlite3ExecFunc(
861 sqlite3_context
*context
,
866 memset(&x
, 0, sizeof(x
));
867 (void)sqlite3_exec((sqlite3
*)sqlite3_user_data(context
),
868 (char*)sqlite3_value_text(argv
[0]),
869 execFuncCallback
, &x
, 0);
870 sqlite3_result_text(context
, x
.z
, x
.nUsed
, SQLITE_TRANSIENT
);
875 ** Implementation of tkt2213func(), a scalar function that takes exactly
876 ** one argument. It has two interesting features:
878 ** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*.
879 ** If the three pointers returned are not the same an SQL error is raised.
881 ** * Otherwise it returns a copy of the text representation of its
882 ** argument in such a way as the VDBE representation is a Mem* cell
883 ** with the MEM_Term flag clear.
885 ** Ticket #2213 can therefore be tested by evaluating the following
888 ** tkt2213func(tkt2213func('a string'));
890 static void tkt2213Function(
891 sqlite3_context
*context
,
896 unsigned char const *zText1
;
897 unsigned char const *zText2
;
898 unsigned char const *zText3
;
900 nText
= sqlite3_value_bytes(argv
[0]);
901 zText1
= sqlite3_value_text(argv
[0]);
902 zText2
= sqlite3_value_text(argv
[0]);
903 zText3
= sqlite3_value_text(argv
[0]);
905 if( zText1
!=zText2
|| zText2
!=zText3
){
906 sqlite3_result_error(context
, "tkt2213 is not fixed", -1);
908 char *zCopy
= (char *)sqlite3_malloc(nText
);
909 memcpy(zCopy
, zText1
, nText
);
910 sqlite3_result_text(context
, zCopy
, nText
, sqlite3_free
);
915 ** The following SQL function takes 4 arguments. The 2nd and
916 ** 4th argument must be one of these strings: 'text', 'text16',
917 ** or 'blob' corresponding to API functions
919 ** sqlite3_value_text()
920 ** sqlite3_value_text16()
921 ** sqlite3_value_blob()
923 ** The third argument is a string, either 'bytes' or 'bytes16' or 'noop',
924 ** corresponding to APIs:
926 ** sqlite3_value_bytes()
927 ** sqlite3_value_bytes16()
930 ** The APIs designated by the 2nd through 4th arguments are applied
931 ** to the first argument in order. If the pointers returned by the
932 ** second and fourth are different, this routine returns 1. Otherwise,
933 ** this routine returns 0.
935 ** This function is used to test to see when returned pointers from
936 ** the _text(), _text16() and _blob() APIs become invalidated.
938 static void ptrChngFunction(
939 sqlite3_context
*context
,
945 if( argc
!=4 ) return;
946 zCmd
= (const char*)sqlite3_value_text(argv
[1]);
947 if( zCmd
==0 ) return;
948 if( strcmp(zCmd
,"text")==0 ){
949 p1
= (const void*)sqlite3_value_text(argv
[0]);
950 #ifndef SQLITE_OMIT_UTF16
951 }else if( strcmp(zCmd
, "text16")==0 ){
952 p1
= (const void*)sqlite3_value_text16(argv
[0]);
954 }else if( strcmp(zCmd
, "blob")==0 ){
955 p1
= (const void*)sqlite3_value_blob(argv
[0]);
959 zCmd
= (const char*)sqlite3_value_text(argv
[2]);
960 if( zCmd
==0 ) return;
961 if( strcmp(zCmd
,"bytes")==0 ){
962 sqlite3_value_bytes(argv
[0]);
963 #ifndef SQLITE_OMIT_UTF16
964 }else if( strcmp(zCmd
, "bytes16")==0 ){
965 sqlite3_value_bytes16(argv
[0]);
967 }else if( strcmp(zCmd
, "noop")==0 ){
972 zCmd
= (const char*)sqlite3_value_text(argv
[3]);
973 if( zCmd
==0 ) return;
974 if( strcmp(zCmd
,"text")==0 ){
975 p2
= (const void*)sqlite3_value_text(argv
[0]);
976 #ifndef SQLITE_OMIT_UTF16
977 }else if( strcmp(zCmd
, "text16")==0 ){
978 p2
= (const void*)sqlite3_value_text16(argv
[0]);
980 }else if( strcmp(zCmd
, "blob")==0 ){
981 p2
= (const void*)sqlite3_value_blob(argv
[0]);
985 sqlite3_result_int(context
, p1
!=p2
);
989 ** This SQL function returns a different answer each time it is called, even if
990 ** the arguments are the same.
992 static void nondeterministicFunction(
993 sqlite3_context
*context
,
998 sqlite3_result_int(context
, cnt
++);
1002 ** This SQL function returns the integer value of its argument as a MEM_IntReal
1005 static void intrealFunction(
1006 sqlite3_context
*context
,
1008 sqlite3_value
**argv
1010 sqlite3_int64 v
= sqlite3_value_int64(argv
[0]);
1011 sqlite3_result_int64(context
, v
);
1012 sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL
, context
);
1016 ** Usage: sqlite3_create_function DB
1018 ** Call the sqlite3_create_function API on the given database in order
1019 ** to create a function named "x_coalesce". This function does the same thing
1020 ** as the "coalesce" function. This function also registers an SQL function
1021 ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec()
1022 ** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
1023 ** The effect is similar to trying to use the same database connection from
1024 ** two threads at the same time.
1026 ** The original motivation for this routine was to be able to call the
1027 ** sqlite3_create_function function while a query is in progress in order
1028 ** to test the SQLITE_MISUSE detection logic.
1030 static int SQLITE_TCLAPI
test_create_function(
1032 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1033 int argc
, /* Number of arguments */
1034 char **argv
/* Text of each argument */
1040 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1044 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
1045 rc
= sqlite3_create_function(db
, "x_coalesce", -1, SQLITE_UTF8
, 0,
1046 t1_ifnullFunc
, 0, 0);
1047 if( rc
==SQLITE_OK
){
1048 rc
= sqlite3_create_function(db
, "hex8", 1, SQLITE_UTF8
| SQLITE_DETERMINISTIC
,
1051 #ifndef SQLITE_OMIT_UTF16
1052 if( rc
==SQLITE_OK
){
1053 rc
= sqlite3_create_function(db
, "hex16", 1, SQLITE_UTF16
| SQLITE_DETERMINISTIC
,
1054 0, hex16Func
, 0, 0);
1057 if( rc
==SQLITE_OK
){
1058 rc
= sqlite3_create_function(db
, "tkt2213func", 1, SQLITE_ANY
, 0,
1059 tkt2213Function
, 0, 0);
1061 if( rc
==SQLITE_OK
){
1062 rc
= sqlite3_create_function(db
, "pointer_change", 4, SQLITE_ANY
, 0,
1063 ptrChngFunction
, 0, 0);
1066 /* Functions counter1() and counter2() have the same implementation - they
1067 ** both return an ascending integer with each call. But counter1() is marked
1068 ** as non-deterministic and counter2() is marked as deterministic.
1070 if( rc
==SQLITE_OK
){
1071 rc
= sqlite3_create_function(db
, "counter1", -1, SQLITE_UTF8
,
1072 0, nondeterministicFunction
, 0, 0);
1074 if( rc
==SQLITE_OK
){
1075 rc
= sqlite3_create_function(db
, "counter2", -1, SQLITE_UTF8
|SQLITE_DETERMINISTIC
,
1076 0, nondeterministicFunction
, 0, 0);
1079 /* The intreal() function converts its argument to an integer and returns
1080 ** it as a MEM_IntReal.
1082 if( rc
==SQLITE_OK
){
1083 rc
= sqlite3_create_function(db
, "intreal", 1, SQLITE_UTF8
,
1084 0, intrealFunction
, 0, 0);
1087 #ifndef SQLITE_OMIT_UTF16
1088 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also
1089 ** because it is not tested anywhere else. */
1090 if( rc
==SQLITE_OK
){
1092 sqlite3_value
*pVal
;
1093 sqlite3_mutex_enter(db
->mutex
);
1094 pVal
= sqlite3ValueNew(db
);
1095 sqlite3ValueSetStr(pVal
, -1, "x_sqlite_exec", SQLITE_UTF8
, SQLITE_STATIC
);
1096 zUtf16
= sqlite3ValueText(pVal
, SQLITE_UTF16NATIVE
);
1097 if( db
->mallocFailed
){
1100 rc
= sqlite3_create_function16(db
, zUtf16
,
1101 1, SQLITE_UTF16
, db
, sqlite3ExecFunc
, 0, 0);
1103 sqlite3ValueFree(pVal
);
1104 sqlite3_mutex_leave(db
->mutex
);
1108 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
1109 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), 0);
1114 ** Usage: sqlite3_drop_modules DB ?NAME ...?
1116 ** Invoke the sqlite3_drop_modules(D,L) interface on database
1117 ** connection DB, in order to drop all modules except those named in
1120 static int SQLITE_TCLAPI
test_drop_modules(
1122 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1123 int argc
, /* Number of arguments */
1124 char **argv
/* Text of each argument */
1129 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1133 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
1134 #ifndef SQLITE_OMIT_VIRTUALTABLE
1135 sqlite3_drop_modules(db
, argc
>2 ? (const char**)(argv
+2) : 0);
1141 ** Routines to implement the x_count() aggregate function.
1143 ** x_count() counts the number of non-null arguments. But there are
1144 ** some twists for testing purposes.
1146 ** If the argument to x_count() is 40 then a UTF-8 error is reported
1147 ** on the step function. If x_count(41) is seen, then a UTF-16 error
1148 ** is reported on the step function. If the total count is 42, then
1149 ** a UTF-8 error is reported on the finalize function.
1151 typedef struct t1CountCtx t1CountCtx
;
1155 static void t1CountStep(
1156 sqlite3_context
*context
,
1158 sqlite3_value
**argv
1161 p
= sqlite3_aggregate_context(context
, sizeof(*p
));
1162 if( (argc
==0 || SQLITE_NULL
!=sqlite3_value_type(argv
[0]) ) && p
){
1166 int v
= sqlite3_value_int(argv
[0]);
1168 sqlite3_result_error(context
, "value of 40 handed to x_count", -1);
1169 #ifndef SQLITE_OMIT_UTF16
1171 const char zUtf16ErrMsg
[] = { 0, 0x61, 0, 0x62, 0, 0x63, 0, 0, 0};
1172 sqlite3_result_error16(context
, &zUtf16ErrMsg
[1-SQLITE_BIGENDIAN
], -1);
1177 static void t1CountFinalize(sqlite3_context
*context
){
1179 p
= sqlite3_aggregate_context(context
, sizeof(*p
));
1182 sqlite3_result_error(context
, "x_count totals to 42", -1);
1184 sqlite3_result_int(context
, p
? p
->n
: 0);
1189 #ifndef SQLITE_OMIT_DEPRECATED
1190 static void legacyCountStep(
1191 sqlite3_context
*context
,
1193 sqlite3_value
**argv
1198 static void legacyCountFinalize(sqlite3_context
*context
){
1199 sqlite3_result_int(context
, sqlite3_aggregate_count(context
));
1204 ** Usage: sqlite3_create_aggregate DB
1206 ** Call the sqlite3_create_function API on the given database in order
1207 ** to create a function named "x_count". This function is similar
1208 ** to the built-in count() function, with a few special quirks
1209 ** for testing the sqlite3_result_error() APIs.
1211 ** The original motivation for this routine was to be able to call the
1212 ** sqlite3_create_aggregate function while a query is in progress in order
1213 ** to test the SQLITE_MISUSE detection logic. See misuse.test.
1215 ** This routine was later extended to test the use of sqlite3_result_error()
1216 ** within aggregate functions.
1218 ** Later: It is now also extended to register the aggregate function
1219 ** "legacy_count()" with the supplied database handle. This is used
1220 ** to test the deprecated sqlite3_aggregate_count() API.
1222 static int SQLITE_TCLAPI
test_create_aggregate(
1224 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1225 int argc
, /* Number of arguments */
1226 char **argv
/* Text of each argument */
1231 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1235 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
1236 rc
= sqlite3_create_function(db
, "x_count", 0, SQLITE_UTF8
, 0, 0,
1237 t1CountStep
,t1CountFinalize
);
1238 if( rc
==SQLITE_OK
){
1239 rc
= sqlite3_create_function(db
, "x_count", 1, SQLITE_UTF8
, 0, 0,
1240 t1CountStep
,t1CountFinalize
);
1242 #ifndef SQLITE_OMIT_DEPRECATED
1243 if( rc
==SQLITE_OK
){
1244 rc
= sqlite3_create_function(db
, "legacy_count", 0, SQLITE_ANY
, 0, 0,
1245 legacyCountStep
, legacyCountFinalize
1249 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
1250 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), 0);
1256 ** Usage: printf TEXT
1258 ** Send output to printf. Use this rather than puts to merge the output
1259 ** in the correct sequence with debugging printfs inserted into C code.
1260 ** Puts uses a separate buffer and debugging statements will be out of
1261 ** sequence if it is used.
1263 static int SQLITE_TCLAPI
test_printf(
1265 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1266 int argc
, /* Number of arguments */
1267 char **argv
/* Text of each argument */
1270 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1274 printf("%s\n", argv
[1]);
1281 ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER
1283 ** Call mprintf with three integer arguments
1285 static int SQLITE_TCLAPI
sqlite3_mprintf_int(
1287 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1288 int argc
, /* Number of arguments */
1289 char **argv
/* Text of each argument */
1294 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1295 " FORMAT INT INT INT\"", 0);
1299 if( Tcl_GetInt(interp
, argv
[i
], &a
[i
-2]) ) return TCL_ERROR
;
1301 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], a
[2]);
1302 Tcl_AppendResult(interp
, z
, 0);
1308 ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER
1310 ** Call mprintf with three 64-bit integer arguments
1312 static int SQLITE_TCLAPI
sqlite3_mprintf_int64(
1314 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1315 int argc
, /* Number of arguments */
1316 char **argv
/* Text of each argument */
1322 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1323 " FORMAT INT INT INT\"", 0);
1327 if( sqlite3Atoi64(argv
[i
], &a
[i
-2], sqlite3Strlen30(argv
[i
]), SQLITE_UTF8
) ){
1328 Tcl_AppendResult(interp
, "argument is not a valid 64-bit integer", 0);
1332 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], a
[2]);
1333 Tcl_AppendResult(interp
, z
, 0);
1339 ** Usage: sqlite3_mprintf_long FORMAT INTEGER INTEGER INTEGER
1341 ** Call mprintf with three long integer arguments. This might be the
1342 ** same as sqlite3_mprintf_int or sqlite3_mprintf_int64, depending on
1345 static int SQLITE_TCLAPI
sqlite3_mprintf_long(
1347 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1348 int argc
, /* Number of arguments */
1349 char **argv
/* Text of each argument */
1356 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1357 " FORMAT INT INT INT\"", 0);
1361 if( Tcl_GetInt(interp
, argv
[i
], &b
[i
-2]) ) return TCL_ERROR
;
1362 a
[i
-2] = (long int)b
[i
-2];
1363 a
[i
-2] &= (((u64
)1)<<(sizeof(int)*8))-1;
1365 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], a
[2]);
1366 Tcl_AppendResult(interp
, z
, 0);
1372 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING
1374 ** Call mprintf with two integer arguments and one string argument
1376 static int SQLITE_TCLAPI
sqlite3_mprintf_str(
1378 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1379 int argc
, /* Number of arguments */
1380 char **argv
/* Text of each argument */
1384 if( argc
<4 || argc
>5 ){
1385 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1386 " FORMAT INT INT ?STRING?\"", 0);
1390 if( Tcl_GetInt(interp
, argv
[i
], &a
[i
-2]) ) return TCL_ERROR
;
1392 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], argc
>4 ? argv
[4] : NULL
);
1393 Tcl_AppendResult(interp
, z
, 0);
1399 ** Usage: sqlite3_snprintf_str INTEGER FORMAT INTEGER INTEGER STRING
1401 ** Call mprintf with two integer arguments and one string argument
1403 static int SQLITE_TCLAPI
sqlite3_snprintf_str(
1405 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1406 int argc
, /* Number of arguments */
1407 char **argv
/* Text of each argument */
1412 if( argc
<5 || argc
>6 ){
1413 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1414 " INT FORMAT INT INT ?STRING?\"", 0);
1417 if( Tcl_GetInt(interp
, argv
[1], &n
) ) return TCL_ERROR
;
1419 Tcl_AppendResult(interp
, "N must be non-negative", 0);
1423 if( Tcl_GetInt(interp
, argv
[i
], &a
[i
-3]) ) return TCL_ERROR
;
1425 z
= sqlite3_malloc( n
+1 );
1426 sqlite3_snprintf(n
, z
, argv
[2], a
[0], a
[1], argc
>4 ? argv
[5] : NULL
);
1427 Tcl_AppendResult(interp
, z
, 0);
1433 ** Usage: sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE
1435 ** Call mprintf with two integer arguments and one double argument
1437 static int SQLITE_TCLAPI
sqlite3_mprintf_double(
1439 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1440 int argc
, /* Number of arguments */
1441 char **argv
/* Text of each argument */
1447 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1448 " FORMAT INT INT DOUBLE\"", 0);
1452 if( Tcl_GetInt(interp
, argv
[i
], &a
[i
-2]) ) return TCL_ERROR
;
1454 if( Tcl_GetDouble(interp
, argv
[4], &r
) ) return TCL_ERROR
;
1455 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], r
);
1456 Tcl_AppendResult(interp
, z
, 0);
1462 ** Usage: sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE
1464 ** Call mprintf with a single double argument which is the product of the
1465 ** two arguments given above. This is used to generate overflow and underflow
1466 ** doubles to test that they are converted properly.
1468 static int SQLITE_TCLAPI
sqlite3_mprintf_scaled(
1470 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1471 int argc
, /* Number of arguments */
1472 char **argv
/* Text of each argument */
1478 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1479 " FORMAT DOUBLE DOUBLE\"", 0);
1483 if( Tcl_GetDouble(interp
, argv
[i
], &r
[i
-2]) ) return TCL_ERROR
;
1485 z
= sqlite3_mprintf(argv
[1], r
[0]*r
[1]);
1486 Tcl_AppendResult(interp
, z
, 0);
1492 ** Usage: sqlite3_mprintf_stronly FORMAT STRING
1494 ** Call mprintf with a single double argument which is the product of the
1495 ** two arguments given above. This is used to generate overflow and underflow
1496 ** doubles to test that they are converted properly.
1498 static int SQLITE_TCLAPI
sqlite3_mprintf_stronly(
1500 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1501 int argc
, /* Number of arguments */
1502 char **argv
/* Text of each argument */
1506 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1507 " FORMAT STRING\"", 0);
1510 z
= sqlite3_mprintf(argv
[1], argv
[2]);
1511 Tcl_AppendResult(interp
, z
, 0);
1517 ** Usage: sqlite3_mprintf_hexdouble FORMAT HEX
1519 ** Call mprintf with a single double argument which is derived from the
1520 ** hexadecimal encoding of an IEEE double.
1522 static int SQLITE_TCLAPI
sqlite3_mprintf_hexdouble(
1524 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1525 int argc
, /* Number of arguments */
1526 char **argv
/* Text of each argument */
1530 unsigned int x1
, x2
;
1533 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1534 " FORMAT STRING\"", 0);
1537 if( sscanf(argv
[2], "%08x%08x", &x2
, &x1
)!=2 ){
1538 Tcl_AppendResult(interp
, "2nd argument should be 16-characters of hex", 0);
1543 memcpy(&r
, &d
, sizeof(r
));
1544 z
= sqlite3_mprintf(argv
[1], r
);
1545 Tcl_AppendResult(interp
, z
, 0);
1551 ** Usage: sqlite3_enable_shared_cache ?BOOLEAN?
1554 #if !defined(SQLITE_OMIT_SHARED_CACHE)
1555 static int SQLITE_TCLAPI
test_enable_shared(
1556 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
1557 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1558 int objc
, /* Number of arguments */
1559 Tcl_Obj
*CONST objv
[] /* Command arguments */
1565 if( objc
!=2 && objc
!=1 ){
1566 Tcl_WrongNumArgs(interp
, 1, objv
, "?BOOLEAN?");
1569 ret
= sqlite3GlobalConfig
.sharedCacheEnabled
;
1572 if( Tcl_GetBooleanFromObj(interp
, objv
[1], &enable
) ){
1575 rc
= sqlite3_enable_shared_cache(enable
);
1576 if( rc
!=SQLITE_OK
){
1577 Tcl_SetResult(interp
, (char *)sqlite3ErrStr(rc
), TCL_STATIC
);
1581 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(ret
));
1589 ** Usage: sqlite3_extended_result_codes DB BOOLEAN
1592 static int SQLITE_TCLAPI
test_extended_result_codes(
1593 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
1594 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1595 int objc
, /* Number of arguments */
1596 Tcl_Obj
*CONST objv
[] /* Command arguments */
1602 Tcl_WrongNumArgs(interp
, 1, objv
, "DB BOOLEAN");
1605 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
1606 if( Tcl_GetBooleanFromObj(interp
, objv
[2], &enable
) ) return TCL_ERROR
;
1607 sqlite3_extended_result_codes(db
, enable
);
1612 ** Usage: sqlite3_libversion_number
1615 static int SQLITE_TCLAPI
test_libversion_number(
1616 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
1617 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1618 int objc
, /* Number of arguments */
1619 Tcl_Obj
*CONST objv
[] /* Command arguments */
1621 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_libversion_number()));
1626 ** Usage: sqlite3_table_column_metadata DB dbname tblname colname
1629 static int SQLITE_TCLAPI
test_table_column_metadata(
1630 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
1631 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1632 int objc
, /* Number of arguments */
1633 Tcl_Obj
*CONST objv
[] /* Command arguments */
1642 const char *zDatatype
;
1643 const char *zCollseq
;
1648 if( objc
!=5 && objc
!=4 ){
1649 Tcl_WrongNumArgs(interp
, 1, objv
, "DB dbname tblname colname");
1652 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
1653 zDb
= Tcl_GetString(objv
[2]);
1654 zTbl
= Tcl_GetString(objv
[3]);
1655 zCol
= objc
==5 ? Tcl_GetString(objv
[4]) : 0;
1657 if( strlen(zDb
)==0 ) zDb
= 0;
1659 rc
= sqlite3_table_column_metadata(db
, zDb
, zTbl
, zCol
,
1660 &zDatatype
, &zCollseq
, ¬null
, &primarykey
, &autoincrement
);
1662 if( rc
!=SQLITE_OK
){
1663 Tcl_AppendResult(interp
, sqlite3_errmsg(db
), 0);
1667 pRet
= Tcl_NewObj();
1668 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj(zDatatype
, -1));
1669 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj(zCollseq
, -1));
1670 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(notnull
));
1671 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(primarykey
));
1672 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(autoincrement
));
1673 Tcl_SetObjResult(interp
, pRet
);
1678 #ifndef SQLITE_OMIT_INCRBLOB
1680 static int SQLITE_TCLAPI
blobHandleFromObj(
1683 sqlite3_blob
**ppBlob
1688 z
= Tcl_GetStringFromObj(pObj
, &n
);
1693 Tcl_Channel channel
;
1694 ClientData instanceData
;
1696 channel
= Tcl_GetChannel(interp
, z
, ¬Used
);
1697 if( !channel
) return TCL_ERROR
;
1700 Tcl_Seek(channel
, 0, SEEK_SET
);
1702 instanceData
= Tcl_GetChannelInstanceData(channel
);
1703 *ppBlob
= *((sqlite3_blob
**)instanceData
);
1709 static int SQLITE_TCLAPI
test_blob_reopen(
1710 ClientData clientData
, /* Not used */
1711 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1712 int objc
, /* Number of arguments */
1713 Tcl_Obj
*CONST objv
[] /* Command arguments */
1716 sqlite3_blob
*pBlob
;
1720 Tcl_WrongNumArgs(interp
, 1, objv
, "CHANNEL ROWID");
1724 if( blobHandleFromObj(interp
, objv
[1], &pBlob
) ) return TCL_ERROR
;
1725 if( Tcl_GetWideIntFromObj(interp
, objv
[2], &iRowid
) ) return TCL_ERROR
;
1727 rc
= sqlite3_blob_reopen(pBlob
, iRowid
);
1728 if( rc
!=SQLITE_OK
){
1729 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_VOLATILE
);
1732 return (rc
==SQLITE_OK
? TCL_OK
: TCL_ERROR
);
1738 ** Usage: sqlite3_create_collation_v2 DB-HANDLE NAME CMP-PROC DEL-PROC
1740 ** This Tcl proc is used for testing the experimental
1741 ** sqlite3_create_collation_v2() interface.
1743 struct TestCollationX
{
1748 typedef struct TestCollationX TestCollationX
;
1749 static void testCreateCollationDel(void *pCtx
){
1750 TestCollationX
*p
= (TestCollationX
*)pCtx
;
1752 int rc
= Tcl_EvalObjEx(p
->interp
, p
->pDel
, TCL_EVAL_DIRECT
|TCL_EVAL_GLOBAL
);
1754 Tcl_BackgroundError(p
->interp
);
1757 Tcl_DecrRefCount(p
->pCmp
);
1758 Tcl_DecrRefCount(p
->pDel
);
1759 sqlite3_free((void *)p
);
1761 static int testCreateCollationCmp(
1768 TestCollationX
*p
= (TestCollationX
*)pCtx
;
1769 Tcl_Obj
*pScript
= Tcl_DuplicateObj(p
->pCmp
);
1772 Tcl_IncrRefCount(pScript
);
1773 Tcl_ListObjAppendElement(0, pScript
, Tcl_NewStringObj((char *)zLeft
, nLeft
));
1774 Tcl_ListObjAppendElement(0, pScript
, Tcl_NewStringObj((char *)zRight
,nRight
));
1776 if( TCL_OK
!=Tcl_EvalObjEx(p
->interp
, pScript
, TCL_EVAL_DIRECT
|TCL_EVAL_GLOBAL
)
1777 || TCL_OK
!=Tcl_GetIntFromObj(p
->interp
, Tcl_GetObjResult(p
->interp
), &iRes
)
1779 Tcl_BackgroundError(p
->interp
);
1781 Tcl_DecrRefCount(pScript
);
1785 static int SQLITE_TCLAPI
test_create_collation_v2(
1786 ClientData clientData
, /* Not used */
1787 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1788 int objc
, /* Number of arguments */
1789 Tcl_Obj
*CONST objv
[] /* Command arguments */
1796 Tcl_WrongNumArgs(interp
, 1, objv
, "DB-HANDLE NAME CMP-PROC DEL-PROC");
1799 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
1801 p
= (TestCollationX
*)sqlite3_malloc(sizeof(TestCollationX
));
1805 Tcl_IncrRefCount(p
->pCmp
);
1806 Tcl_IncrRefCount(p
->pDel
);
1808 rc
= sqlite3_create_collation_v2(db
, Tcl_GetString(objv
[2]), 16,
1809 (void *)p
, testCreateCollationCmp
, testCreateCollationDel
1811 if( rc
!=SQLITE_MISUSE
){
1812 Tcl_AppendResult(interp
, "sqlite3_create_collate_v2() failed to detect "
1813 "an invalid encoding", (char*)0);
1816 rc
= sqlite3_create_collation_v2(db
, Tcl_GetString(objv
[2]), SQLITE_UTF8
,
1817 (void *)p
, testCreateCollationCmp
, testCreateCollationDel
1823 ** USAGE: sqlite3_create_function_v2 DB NAME NARG ENC ?SWITCHES?
1825 ** Available switches are:
1832 typedef struct CreateFunctionV2 CreateFunctionV2
;
1833 struct CreateFunctionV2
{
1835 Tcl_Obj
*pFunc
; /* Script for function invocation */
1836 Tcl_Obj
*pStep
; /* Script for agg. step invocation */
1837 Tcl_Obj
*pFinal
; /* Script for agg. finalization invocation */
1838 Tcl_Obj
*pDestroy
; /* Destructor script */
1840 static void cf2Func(sqlite3_context
*ctx
, int nArg
, sqlite3_value
**aArg
){
1842 static void cf2Step(sqlite3_context
*ctx
, int nArg
, sqlite3_value
**aArg
){
1844 static void cf2Final(sqlite3_context
*ctx
){
1846 static void cf2Destroy(void *pUser
){
1847 CreateFunctionV2
*p
= (CreateFunctionV2
*)pUser
;
1849 if( p
->interp
&& p
->pDestroy
){
1850 int rc
= Tcl_EvalObjEx(p
->interp
, p
->pDestroy
, 0);
1851 if( rc
!=TCL_OK
) Tcl_BackgroundError(p
->interp
);
1854 if( p
->pFunc
) Tcl_DecrRefCount(p
->pFunc
);
1855 if( p
->pStep
) Tcl_DecrRefCount(p
->pStep
);
1856 if( p
->pFinal
) Tcl_DecrRefCount(p
->pFinal
);
1857 if( p
->pDestroy
) Tcl_DecrRefCount(p
->pDestroy
);
1860 static int SQLITE_TCLAPI
test_create_function_v2(
1861 ClientData clientData
, /* Not used */
1862 Tcl_Interp
*interp
, /* The invoking TCL interpreter */
1863 int objc
, /* Number of arguments */
1864 Tcl_Obj
*CONST objv
[] /* Command arguments */
1870 CreateFunctionV2
*p
;
1878 {"utf8", SQLITE_UTF8
},
1879 {"utf16", SQLITE_UTF16
},
1880 {"utf16le", SQLITE_UTF16LE
},
1881 {"utf16be", SQLITE_UTF16BE
},
1882 {"any", SQLITE_ANY
},
1886 if( objc
<5 || (objc
%2)==0 ){
1887 Tcl_WrongNumArgs(interp
, 1, objv
, "DB NAME NARG ENC SWITCHES...");
1891 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
1892 zFunc
= Tcl_GetString(objv
[2]);
1893 if( Tcl_GetIntFromObj(interp
, objv
[3], &nArg
) ) return TCL_ERROR
;
1894 if( Tcl_GetIndexFromObjStruct(interp
, objv
[4], aEnc
, sizeof(aEnc
[0]),
1895 "encoding", 0, &enc
)
1899 enc
= aEnc
[enc
].enc
;
1901 p
= sqlite3_malloc(sizeof(CreateFunctionV2
));
1903 memset(p
, 0, sizeof(CreateFunctionV2
));
1906 for(i
=5; i
<objc
; i
+=2){
1908 const char *azSwitch
[] = {"-func", "-step", "-final", "-destroy", 0};
1909 if( Tcl_GetIndexFromObj(interp
, objv
[i
], azSwitch
, "switch", 0, &iSwitch
) ){
1915 case 0: p
->pFunc
= objv
[i
+1]; break;
1916 case 1: p
->pStep
= objv
[i
+1]; break;
1917 case 2: p
->pFinal
= objv
[i
+1]; break;
1918 case 3: p
->pDestroy
= objv
[i
+1]; break;
1921 if( p
->pFunc
) p
->pFunc
= Tcl_DuplicateObj(p
->pFunc
);
1922 if( p
->pStep
) p
->pStep
= Tcl_DuplicateObj(p
->pStep
);
1923 if( p
->pFinal
) p
->pFinal
= Tcl_DuplicateObj(p
->pFinal
);
1924 if( p
->pDestroy
) p
->pDestroy
= Tcl_DuplicateObj(p
->pDestroy
);
1926 if( p
->pFunc
) Tcl_IncrRefCount(p
->pFunc
);
1927 if( p
->pStep
) Tcl_IncrRefCount(p
->pStep
);
1928 if( p
->pFinal
) Tcl_IncrRefCount(p
->pFinal
);
1929 if( p
->pDestroy
) Tcl_IncrRefCount(p
->pDestroy
);
1931 rc
= sqlite3_create_function_v2(db
, zFunc
, nArg
, enc
, (void *)p
,
1932 (p
->pFunc
? cf2Func
: 0),
1933 (p
->pStep
? cf2Step
: 0),
1934 (p
->pFinal
? cf2Final
: 0),
1937 if( rc
!=SQLITE_OK
){
1938 Tcl_ResetResult(interp
);
1939 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
1946 ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC?
1948 static int SQLITE_TCLAPI
test_load_extension(
1949 ClientData clientData
, /* Not used */
1950 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1951 int objc
, /* Number of arguments */
1952 Tcl_Obj
*CONST objv
[] /* Command arguments */
1954 Tcl_CmdInfo cmdInfo
;
1962 if( objc
!=4 && objc
!=3 ){
1963 Tcl_WrongNumArgs(interp
, 1, objv
, "DB-HANDLE FILE ?PROC?");
1966 zDb
= Tcl_GetString(objv
[1]);
1967 zFile
= Tcl_GetString(objv
[2]);
1969 zProc
= Tcl_GetString(objv
[3]);
1972 /* Extract the C database handle from the Tcl command name */
1973 if( !Tcl_GetCommandInfo(interp
, zDb
, &cmdInfo
) ){
1974 Tcl_AppendResult(interp
, "command not found: ", zDb
, (char*)0);
1977 db
= ((struct SqliteDb
*)cmdInfo
.objClientData
)->db
;
1980 /* Call the underlying C function. If an error occurs, set rc to
1981 ** TCL_ERROR and load any error string into the interpreter. If no
1982 ** error occurs, set rc to TCL_OK.
1984 #ifdef SQLITE_OMIT_LOAD_EXTENSION
1986 zErr
= sqlite3_mprintf("this build omits sqlite3_load_extension()");
1990 rc
= sqlite3_load_extension(db
, zFile
, zProc
, &zErr
);
1992 if( rc
!=SQLITE_OK
){
1993 Tcl_SetResult(interp
, zErr
? zErr
: "", TCL_VOLATILE
);
2004 ** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF
2006 static int SQLITE_TCLAPI
test_enable_load(
2007 ClientData clientData
, /* Not used */
2008 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
2009 int objc
, /* Number of arguments */
2010 Tcl_Obj
*CONST objv
[] /* Command arguments */
2012 Tcl_CmdInfo cmdInfo
;
2018 Tcl_WrongNumArgs(interp
, 1, objv
, "DB-HANDLE ONOFF");
2021 zDb
= Tcl_GetString(objv
[1]);
2023 /* Extract the C database handle from the Tcl command name */
2024 if( !Tcl_GetCommandInfo(interp
, zDb
, &cmdInfo
) ){
2025 Tcl_AppendResult(interp
, "command not found: ", zDb
, (char*)0);
2028 db
= ((struct SqliteDb
*)cmdInfo
.objClientData
)->db
;
2031 /* Get the onoff parameter */
2032 if( Tcl_GetBooleanFromObj(interp
, objv
[2], &onoff
) ){
2036 #ifdef SQLITE_OMIT_LOAD_EXTENSION
2037 Tcl_AppendResult(interp
, "this build omits sqlite3_load_extension()");
2040 sqlite3_enable_load_extension(db
, onoff
);
2046 ** Usage: sqlite_abort
2048 ** Shutdown the process immediately. This is not a clean shutdown.
2049 ** This command is used to test the recoverability of a database in
2050 ** the event of a program crash.
2052 static int SQLITE_TCLAPI
sqlite_abort(
2054 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
2055 int argc
, /* Number of arguments */
2056 char **argv
/* Text of each argument */
2058 #if defined(_MSC_VER)
2059 /* We do this, otherwise the test will halt with a popup message
2060 * that we have to click away before the test will continue.
2062 _set_abort_behavior( 0, _CALL_REPORTFAULT
);
2065 assert( interp
==0 ); /* This will always fail */
2070 ** The following routine is a user-defined SQL function whose purpose
2071 ** is to test the sqlite_set_result() API.
2073 static void testFunc(sqlite3_context
*context
, int argc
, sqlite3_value
**argv
){
2075 const char *zArg0
= (char*)sqlite3_value_text(argv
[0]);
2077 if( 0==sqlite3StrICmp(zArg0
, "int") ){
2078 sqlite3_result_int(context
, sqlite3_value_int(argv
[1]));
2079 }else if( sqlite3StrICmp(zArg0
,"int64")==0 ){
2080 sqlite3_result_int64(context
, sqlite3_value_int64(argv
[1]));
2081 }else if( sqlite3StrICmp(zArg0
,"string")==0 ){
2082 sqlite3_result_text(context
, (char*)sqlite3_value_text(argv
[1]), -1,
2084 }else if( sqlite3StrICmp(zArg0
,"double")==0 ){
2085 sqlite3_result_double(context
, sqlite3_value_double(argv
[1]));
2086 }else if( sqlite3StrICmp(zArg0
,"null")==0 ){
2087 sqlite3_result_null(context
);
2088 }else if( sqlite3StrICmp(zArg0
,"value")==0 ){
2089 sqlite3_result_value(context
, argv
[sqlite3_value_int(argv
[1])]);
2102 sqlite3_result_error(context
,"first argument should be one of: "
2103 "int int64 string double null value", -1);
2107 ** Usage: sqlite_register_test_function DB NAME
2109 ** Register the test SQL function on the database DB under the name NAME.
2111 static int SQLITE_TCLAPI
test_register_func(
2113 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
2114 int argc
, /* Number of arguments */
2115 char **argv
/* Text of each argument */
2120 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
2121 " DB FUNCTION-NAME", 0);
2124 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
2125 rc
= sqlite3_create_function(db
, argv
[2], -1, SQLITE_UTF8
, 0,
2128 Tcl_AppendResult(interp
, sqlite3ErrStr(rc
), 0);
2131 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
2136 ** Usage: sqlite3_finalize STMT
2138 ** Finalize a statement handle.
2140 static int SQLITE_TCLAPI
test_finalize(
2144 Tcl_Obj
*CONST objv
[]
2146 sqlite3_stmt
*pStmt
;
2151 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2152 Tcl_GetStringFromObj(objv
[0], 0), " <STMT>", 0);
2156 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2159 db
= StmtToDb(pStmt
);
2161 rc
= sqlite3_finalize(pStmt
);
2162 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
2163 if( db
&& sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
2168 ** Usage: sqlite3_stmt_status STMT CODE RESETFLAG
2170 ** Get the value of a status counter from a statement.
2172 static int SQLITE_TCLAPI
test_stmt_status(
2176 Tcl_Obj
*CONST objv
[]
2179 int i
, op
= 0, resetFlag
;
2180 const char *zOpName
;
2181 sqlite3_stmt
*pStmt
;
2183 static const struct {
2187 { "SQLITE_STMTSTATUS_FULLSCAN_STEP", SQLITE_STMTSTATUS_FULLSCAN_STEP
},
2188 { "SQLITE_STMTSTATUS_SORT", SQLITE_STMTSTATUS_SORT
},
2189 { "SQLITE_STMTSTATUS_AUTOINDEX", SQLITE_STMTSTATUS_AUTOINDEX
},
2190 { "SQLITE_STMTSTATUS_VM_STEP", SQLITE_STMTSTATUS_VM_STEP
},
2191 { "SQLITE_STMTSTATUS_REPREPARE", SQLITE_STMTSTATUS_REPREPARE
},
2192 { "SQLITE_STMTSTATUS_RUN", SQLITE_STMTSTATUS_RUN
},
2193 { "SQLITE_STMTSTATUS_MEMUSED", SQLITE_STMTSTATUS_MEMUSED
},
2196 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT PARAMETER RESETFLAG");
2199 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2200 zOpName
= Tcl_GetString(objv
[2]);
2201 for(i
=0; i
<ArraySize(aOp
); i
++){
2202 if( strcmp(aOp
[i
].zName
, zOpName
)==0 ){
2207 if( i
>=ArraySize(aOp
) ){
2208 if( Tcl_GetIntFromObj(interp
, objv
[2], &op
) ) return TCL_ERROR
;
2210 if( Tcl_GetBooleanFromObj(interp
, objv
[3], &resetFlag
) ) return TCL_ERROR
;
2211 iValue
= sqlite3_stmt_status(pStmt
, op
, resetFlag
);
2212 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iValue
));
2216 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
2218 ** Usage: sqlite3_stmt_scanstatus STMT IDX
2220 static int SQLITE_TCLAPI
test_stmt_scanstatus(
2224 Tcl_Obj
*CONST objv
[]
2226 sqlite3_stmt
*pStmt
; /* First argument */
2227 int idx
; /* Second argument */
2230 const char *zExplain
;
2231 sqlite3_int64 nLoop
;
2232 sqlite3_int64 nVisit
;
2237 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT IDX");
2240 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2241 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
2243 res
= sqlite3_stmt_scanstatus(pStmt
, idx
, SQLITE_SCANSTAT_NLOOP
, (void*)&nLoop
);
2245 Tcl_Obj
*pRet
= Tcl_NewObj();
2246 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("nLoop", -1));
2247 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewWideIntObj(nLoop
));
2248 sqlite3_stmt_scanstatus(pStmt
, idx
, SQLITE_SCANSTAT_NVISIT
, (void*)&nVisit
);
2249 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("nVisit", -1));
2250 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewWideIntObj(nVisit
));
2251 sqlite3_stmt_scanstatus(pStmt
, idx
, SQLITE_SCANSTAT_EST
, (void*)&rEst
);
2252 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("nEst", -1));
2253 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewDoubleObj(rEst
));
2254 sqlite3_stmt_scanstatus(pStmt
, idx
, SQLITE_SCANSTAT_NAME
, (void*)&zName
);
2255 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("zName", -1));
2256 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj(zName
, -1));
2257 sqlite3_stmt_scanstatus(pStmt
, idx
, SQLITE_SCANSTAT_EXPLAIN
, (void*)&zExplain
);
2258 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("zExplain", -1));
2259 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj(zExplain
, -1));
2260 Tcl_SetObjResult(interp
, pRet
);
2262 Tcl_ResetResult(interp
);
2268 ** Usage: sqlite3_stmt_scanstatus_reset STMT
2270 static int SQLITE_TCLAPI
test_stmt_scanstatus_reset(
2274 Tcl_Obj
*CONST objv
[]
2276 sqlite3_stmt
*pStmt
; /* First argument */
2278 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
2281 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2282 sqlite3_stmt_scanstatus_reset(pStmt
);
2287 #ifdef SQLITE_ENABLE_SQLLOG
2289 ** Usage: sqlite3_config_sqllog
2291 ** Zero the SQLITE_CONFIG_SQLLOG configuration
2293 static int SQLITE_TCLAPI
test_config_sqllog(
2297 Tcl_Obj
*CONST objv
[]
2300 Tcl_WrongNumArgs(interp
, 1, objv
, "");
2303 sqlite3_config(SQLITE_CONFIG_SQLLOG
, 0, 0);
2309 ** Usage: sqlite3_config_sorterref
2311 ** Set the SQLITE_CONFIG_SORTERREF_SIZE configuration option
2313 static int SQLITE_TCLAPI
test_config_sorterref(
2317 Tcl_Obj
*CONST objv
[]
2321 Tcl_WrongNumArgs(interp
, 1, objv
, "NBYTE");
2324 if( Tcl_GetIntFromObj(interp
, objv
[1], &iVal
) ) return TCL_ERROR
;
2325 sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE
, iVal
);
2330 ** Usage: vfs_current_time_int64
2332 ** Return the value returned by the default VFS's xCurrentTimeInt64 method.
2334 static int SQLITE_TCLAPI
vfsCurrentTimeInt64(
2338 Tcl_Obj
*CONST objv
[]
2341 sqlite3_vfs
*pVfs
= sqlite3_vfs_find(0);
2343 Tcl_WrongNumArgs(interp
, 1, objv
, "");
2346 pVfs
->xCurrentTimeInt64(pVfs
, &t
);
2347 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(t
));
2351 #ifdef SQLITE_ENABLE_SNAPSHOT
2353 ** Usage: sqlite3_snapshot_get DB DBNAME
2355 static int SQLITE_TCLAPI
test_snapshot_get(
2359 Tcl_Obj
*CONST objv
[]
2364 sqlite3_snapshot
*pSnapshot
= 0;
2367 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
2370 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2371 zName
= Tcl_GetString(objv
[2]);
2373 rc
= sqlite3_snapshot_get(db
, zName
, &pSnapshot
);
2374 if( rc
!=SQLITE_OK
){
2375 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2379 if( sqlite3TestMakePointerStr(interp
, zBuf
, pSnapshot
) ) return TCL_ERROR
;
2380 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zBuf
, -1));
2384 #endif /* SQLITE_ENABLE_SNAPSHOT */
2386 #ifdef SQLITE_ENABLE_SNAPSHOT
2388 ** Usage: sqlite3_snapshot_recover DB DBNAME
2390 static int SQLITE_TCLAPI
test_snapshot_recover(
2394 Tcl_Obj
*CONST objv
[]
2401 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
2404 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2405 zName
= Tcl_GetString(objv
[2]);
2407 rc
= sqlite3_snapshot_recover(db
, zName
);
2408 if( rc
!=SQLITE_OK
){
2409 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2412 Tcl_ResetResult(interp
);
2416 #endif /* SQLITE_ENABLE_SNAPSHOT */
2418 #ifdef SQLITE_ENABLE_SNAPSHOT
2420 ** Usage: sqlite3_snapshot_open DB DBNAME SNAPSHOT
2422 static int SQLITE_TCLAPI
test_snapshot_open(
2426 Tcl_Obj
*CONST objv
[]
2431 sqlite3_snapshot
*pSnapshot
;
2434 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME SNAPSHOT");
2437 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2438 zName
= Tcl_GetString(objv
[2]);
2439 pSnapshot
= (sqlite3_snapshot
*)sqlite3TestTextToPtr(Tcl_GetString(objv
[3]));
2441 rc
= sqlite3_snapshot_open(db
, zName
, pSnapshot
);
2442 if( rc
!=SQLITE_OK
){
2443 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2446 Tcl_ResetResult(interp
);
2450 #endif /* SQLITE_ENABLE_SNAPSHOT */
2452 #ifdef SQLITE_ENABLE_SNAPSHOT
2454 ** Usage: sqlite3_snapshot_free SNAPSHOT
2456 static int SQLITE_TCLAPI
test_snapshot_free(
2460 Tcl_Obj
*CONST objv
[]
2462 sqlite3_snapshot
*pSnapshot
;
2464 Tcl_WrongNumArgs(interp
, 1, objv
, "SNAPSHOT");
2467 pSnapshot
= (sqlite3_snapshot
*)sqlite3TestTextToPtr(Tcl_GetString(objv
[1]));
2468 sqlite3_snapshot_free(pSnapshot
);
2471 #endif /* SQLITE_ENABLE_SNAPSHOT */
2473 #ifdef SQLITE_ENABLE_SNAPSHOT
2475 ** Usage: sqlite3_snapshot_cmp SNAPSHOT1 SNAPSHOT2
2477 static int SQLITE_TCLAPI
test_snapshot_cmp(
2481 Tcl_Obj
*CONST objv
[]
2484 sqlite3_snapshot
*p1
;
2485 sqlite3_snapshot
*p2
;
2487 Tcl_WrongNumArgs(interp
, 1, objv
, "SNAPSHOT1 SNAPSHOT2");
2490 p1
= (sqlite3_snapshot
*)sqlite3TestTextToPtr(Tcl_GetString(objv
[1]));
2491 p2
= (sqlite3_snapshot
*)sqlite3TestTextToPtr(Tcl_GetString(objv
[2]));
2492 res
= sqlite3_snapshot_cmp(p1
, p2
);
2493 Tcl_SetObjResult(interp
, Tcl_NewIntObj(res
));
2496 #endif /* SQLITE_ENABLE_SNAPSHOT */
2498 #ifdef SQLITE_ENABLE_SNAPSHOT
2500 ** Usage: sqlite3_snapshot_get_blob DB DBNAME
2502 static int SQLITE_TCLAPI
test_snapshot_get_blob(
2506 Tcl_Obj
*CONST objv
[]
2511 sqlite3_snapshot
*pSnapshot
= 0;
2514 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
2517 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2518 zName
= Tcl_GetString(objv
[2]);
2520 rc
= sqlite3_snapshot_get(db
, zName
, &pSnapshot
);
2521 if( rc
!=SQLITE_OK
){
2522 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2525 Tcl_SetObjResult(interp
,
2526 Tcl_NewByteArrayObj((unsigned char*)pSnapshot
, sizeof(sqlite3_snapshot
))
2528 sqlite3_snapshot_free(pSnapshot
);
2532 #endif /* SQLITE_ENABLE_SNAPSHOT */
2534 #ifdef SQLITE_ENABLE_SNAPSHOT
2536 ** Usage: sqlite3_snapshot_open_blob DB DBNAME SNAPSHOT
2538 static int SQLITE_TCLAPI
test_snapshot_open_blob(
2542 Tcl_Obj
*CONST objv
[]
2547 unsigned char *pBlob
;
2551 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME SNAPSHOT");
2554 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2555 zName
= Tcl_GetString(objv
[2]);
2556 pBlob
= Tcl_GetByteArrayFromObj(objv
[3], &nBlob
);
2557 if( nBlob
!=sizeof(sqlite3_snapshot
) ){
2558 Tcl_AppendResult(interp
, "bad SNAPSHOT", 0);
2561 rc
= sqlite3_snapshot_open(db
, zName
, (sqlite3_snapshot
*)pBlob
);
2562 if( rc
!=SQLITE_OK
){
2563 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2568 #endif /* SQLITE_ENABLE_SNAPSHOT */
2570 #ifdef SQLITE_ENABLE_SNAPSHOT
2572 ** Usage: sqlite3_snapshot_cmp_blob SNAPSHOT1 SNAPSHOT2
2574 static int SQLITE_TCLAPI
test_snapshot_cmp_blob(
2578 Tcl_Obj
*CONST objv
[]
2587 Tcl_WrongNumArgs(interp
, 1, objv
, "SNAPSHOT1 SNAPSHOT2");
2591 p1
= Tcl_GetByteArrayFromObj(objv
[1], &n1
);
2592 p2
= Tcl_GetByteArrayFromObj(objv
[2], &n2
);
2594 if( n1
!=sizeof(sqlite3_snapshot
) || n1
!=n2
){
2595 Tcl_AppendResult(interp
, "bad SNAPSHOT", 0);
2599 res
= sqlite3_snapshot_cmp((sqlite3_snapshot
*)p1
, (sqlite3_snapshot
*)p2
);
2600 Tcl_SetObjResult(interp
, Tcl_NewIntObj(res
));
2603 #endif /* SQLITE_ENABLE_SNAPSHOT */
2606 ** Usage: sqlite3_delete_database FILENAME
2608 int sqlite3_delete_database(const char*); /* in test_delete.c */
2609 static int SQLITE_TCLAPI
test_delete_database(
2613 Tcl_Obj
*CONST objv
[]
2618 Tcl_WrongNumArgs(interp
, 1, objv
, "FILE");
2621 zFile
= (const char*)Tcl_GetString(objv
[1]);
2622 rc
= sqlite3_delete_database(zFile
);
2624 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2629 ** Usage: atomic_batch_write PATH
2631 static int SQLITE_TCLAPI
test_atomic_batch_write(
2635 Tcl_Obj
*CONST objv
[]
2637 char *zFile
= 0; /* Path to file to test */
2638 sqlite3
*db
= 0; /* Database handle */
2639 sqlite3_file
*pFd
= 0; /* SQLite fd open on zFile */
2640 int bRes
= 0; /* Integer result of this command */
2641 int dc
= 0; /* Device-characteristics mask */
2642 int rc
; /* sqlite3_open() return code */
2645 Tcl_WrongNumArgs(interp
, 1, objv
, "PATH");
2648 zFile
= Tcl_GetString(objv
[1]);
2650 rc
= sqlite3_open(zFile
, &db
);
2651 if( rc
!=SQLITE_OK
){
2652 Tcl_AppendResult(interp
, sqlite3_errmsg(db
), 0);
2657 rc
= sqlite3_file_control(db
, "main", SQLITE_FCNTL_FILE_POINTER
, (void*)&pFd
);
2658 dc
= pFd
->pMethods
->xDeviceCharacteristics(pFd
);
2659 if( dc
& SQLITE_IOCAP_BATCH_ATOMIC
){
2663 Tcl_SetObjResult(interp
, Tcl_NewIntObj(bRes
));
2669 ** Usage: sqlite3_next_stmt DB STMT
2671 ** Return the next statment in sequence after STMT.
2673 static int SQLITE_TCLAPI
test_next_stmt(
2677 Tcl_Obj
*CONST objv
[]
2679 sqlite3_stmt
*pStmt
;
2684 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2685 Tcl_GetStringFromObj(objv
[0], 0), " DB STMT", 0);
2689 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2690 if( getStmtPointer(interp
, Tcl_GetString(objv
[2]), &pStmt
) ) return TCL_ERROR
;
2691 pStmt
= sqlite3_next_stmt(db
, pStmt
);
2693 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
2694 Tcl_AppendResult(interp
, zBuf
, 0);
2700 ** Usage: sqlite3_stmt_readonly STMT
2702 ** Return true if STMT is a NULL pointer or a pointer to a statement
2703 ** that is guaranteed to leave the database unmodified.
2705 static int SQLITE_TCLAPI
test_stmt_readonly(
2709 Tcl_Obj
*CONST objv
[]
2711 sqlite3_stmt
*pStmt
;
2715 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2716 Tcl_GetStringFromObj(objv
[0], 0), " STMT", 0);
2720 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2721 rc
= sqlite3_stmt_readonly(pStmt
);
2722 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(rc
));
2727 ** Usage: sqlite3_stmt_isexplain STMT
2729 ** Return 1, 2, or 0 respectively if STMT is an EXPLAIN statement, an
2730 ** EXPLAIN QUERY PLAN statement or an ordinary statement or NULL pointer.
2732 static int SQLITE_TCLAPI
test_stmt_isexplain(
2736 Tcl_Obj
*CONST objv
[]
2738 sqlite3_stmt
*pStmt
;
2742 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2743 Tcl_GetStringFromObj(objv
[0], 0), " STMT", 0);
2747 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2748 rc
= sqlite3_stmt_isexplain(pStmt
);
2749 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
2754 ** Usage: sqlite3_stmt_busy STMT
2756 ** Return true if STMT is a non-NULL pointer to a statement
2757 ** that has been stepped but not to completion.
2759 static int SQLITE_TCLAPI
test_stmt_busy(
2763 Tcl_Obj
*CONST objv
[]
2765 sqlite3_stmt
*pStmt
;
2769 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2770 Tcl_GetStringFromObj(objv
[0], 0), " STMT", 0);
2774 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2775 rc
= sqlite3_stmt_busy(pStmt
);
2776 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(rc
));
2781 ** Usage: uses_stmt_journal STMT
2783 ** Return true if STMT uses a statement journal.
2785 static int SQLITE_TCLAPI
uses_stmt_journal(
2789 Tcl_Obj
*CONST objv
[]
2791 sqlite3_stmt
*pStmt
;
2794 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2795 Tcl_GetStringFromObj(objv
[0], 0), " STMT", 0);
2799 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2800 sqlite3_stmt_readonly(pStmt
);
2801 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(((Vdbe
*)pStmt
)->usesStmtJournal
));
2807 ** Usage: sqlite3_reset STMT
2809 ** Reset a statement handle.
2811 static int SQLITE_TCLAPI
test_reset(
2815 Tcl_Obj
*CONST objv
[]
2817 sqlite3_stmt
*pStmt
;
2821 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2822 Tcl_GetStringFromObj(objv
[0], 0), " <STMT>", 0);
2826 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2828 rc
= sqlite3_reset(pStmt
);
2829 if( pStmt
&& sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ){
2832 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
2842 ** Usage: sqlite3_expired STMT
2844 ** Return TRUE if a recompilation of the statement is recommended.
2846 static int SQLITE_TCLAPI
test_expired(
2850 Tcl_Obj
*CONST objv
[]
2852 #ifndef SQLITE_OMIT_DEPRECATED
2853 sqlite3_stmt
*pStmt
;
2855 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2856 Tcl_GetStringFromObj(objv
[0], 0), " <STMT>", 0);
2859 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2860 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(sqlite3_expired(pStmt
)));
2866 ** Usage: sqlite3_transfer_bindings FROMSTMT TOSTMT
2868 ** Transfer all bindings from FROMSTMT over to TOSTMT
2870 static int SQLITE_TCLAPI
test_transfer_bind(
2874 Tcl_Obj
*CONST objv
[]
2876 #ifndef SQLITE_OMIT_DEPRECATED
2877 sqlite3_stmt
*pStmt1
, *pStmt2
;
2879 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2880 Tcl_GetStringFromObj(objv
[0], 0), " FROM-STMT TO-STMT", 0);
2883 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt1
)) return TCL_ERROR
;
2884 if( getStmtPointer(interp
, Tcl_GetString(objv
[2]), &pStmt2
)) return TCL_ERROR
;
2885 Tcl_SetObjResult(interp
,
2886 Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1
,pStmt2
)));
2892 ** Usage: sqlite3_changes DB
2894 ** Return the number of changes made to the database by the last SQL
2897 static int SQLITE_TCLAPI
test_changes(
2901 Tcl_Obj
*CONST objv
[]
2905 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2906 Tcl_GetString(objv
[0]), " DB", 0);
2909 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2910 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_changes(db
)));
2915 ** This is the "static_bind_value" that variables are bound to when
2916 ** the FLAG option of sqlite3_bind is "static"
2918 static char *sqlite_static_bind_value
= 0;
2919 static int sqlite_static_bind_nbyte
= 0;
2922 ** Usage: sqlite3_bind VM IDX VALUE FLAGS
2924 ** Sets the value of the IDX-th occurrence of "?" in the original SQL
2925 ** string. VALUE is the new value. If FLAGS=="null" then VALUE is
2926 ** ignored and the value is set to NULL. If FLAGS=="static" then
2927 ** the value is set to the value of a static variable named
2928 ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy
2929 ** of the VALUE is made. If FLAGS=="blob10" then a VALUE is ignored
2930 ** an a 10-byte blob "abc\000xyz\000pq" is inserted.
2932 static int SQLITE_TCLAPI
test_bind(
2934 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
2935 int argc
, /* Number of arguments */
2936 char **argv
/* Text of each argument */
2938 sqlite3_stmt
*pStmt
;
2942 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
2943 " VM IDX VALUE (null|static|normal)\"", 0);
2946 if( getStmtPointer(interp
, argv
[1], &pStmt
) ) return TCL_ERROR
;
2947 if( Tcl_GetInt(interp
, argv
[2], &idx
) ) return TCL_ERROR
;
2948 if( strcmp(argv
[4],"null")==0 ){
2949 rc
= sqlite3_bind_null(pStmt
, idx
);
2950 }else if( strcmp(argv
[4],"static")==0 ){
2951 rc
= sqlite3_bind_text(pStmt
, idx
, sqlite_static_bind_value
, -1, 0);
2952 }else if( strcmp(argv
[4],"static-nbytes")==0 ){
2953 rc
= sqlite3_bind_text(pStmt
, idx
, sqlite_static_bind_value
,
2954 sqlite_static_bind_nbyte
, 0);
2955 }else if( strcmp(argv
[4],"normal")==0 ){
2956 rc
= sqlite3_bind_text(pStmt
, idx
, argv
[3], -1, SQLITE_TRANSIENT
);
2957 }else if( strcmp(argv
[4],"blob10")==0 ){
2958 rc
= sqlite3_bind_text(pStmt
, idx
, "abc\000xyz\000pq", 10, SQLITE_STATIC
);
2960 Tcl_AppendResult(interp
, "4th argument should be "
2961 "\"null\" or \"static\" or \"normal\"", 0);
2964 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
2967 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
2968 Tcl_AppendResult(interp
, zBuf
, sqlite3ErrStr(rc
), 0);
2974 #ifndef SQLITE_OMIT_UTF16
2976 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be>
2978 ** This function is used to test that SQLite selects the correct collation
2979 ** sequence callback when multiple versions (for different text encodings)
2982 ** Calling this routine registers the collation sequence "test_collate"
2983 ** with database handle <db>. The second argument must be a list of three
2984 ** boolean values. If the first is true, then a version of test_collate is
2985 ** registered for UTF-8, if the second is true, a version is registered for
2986 ** UTF-16le, if the third is true, a UTF-16be version is available.
2987 ** Previous versions of test_collate are deleted.
2989 ** The collation sequence test_collate is implemented by calling the
2990 ** following TCL script:
2992 ** "test_collate <enc> <lhs> <rhs>"
2994 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8.
2995 ** The <enc> parameter is the encoding of the collation function that
2996 ** SQLite selected to call. The TCL test script implements the
2997 ** "test_collate" proc.
2999 ** Note that this will only work with one interpreter at a time, as the
3000 ** interp pointer to use when evaluating the TCL script is stored in
3001 ** pTestCollateInterp.
3003 static Tcl_Interp
* pTestCollateInterp
;
3004 static int test_collate_func(
3006 int nA
, const void *zA
,
3007 int nB
, const void *zB
3009 Tcl_Interp
*i
= pTestCollateInterp
;
3010 int encin
= SQLITE_PTR_TO_INT(pCtx
);
3014 sqlite3_value
*pVal
;
3017 pX
= Tcl_NewStringObj("test_collate", -1);
3018 Tcl_IncrRefCount(pX
);
3022 Tcl_ListObjAppendElement(i
,pX
,Tcl_NewStringObj("UTF-8",-1));
3024 case SQLITE_UTF16LE
:
3025 Tcl_ListObjAppendElement(i
,pX
,Tcl_NewStringObj("UTF-16LE",-1));
3027 case SQLITE_UTF16BE
:
3028 Tcl_ListObjAppendElement(i
,pX
,Tcl_NewStringObj("UTF-16BE",-1));
3034 sqlite3BeginBenignMalloc();
3035 pVal
= sqlite3ValueNew(0);
3037 sqlite3ValueSetStr(pVal
, nA
, zA
, encin
, SQLITE_STATIC
);
3038 n
= sqlite3_value_bytes(pVal
);
3039 Tcl_ListObjAppendElement(i
,pX
,
3040 Tcl_NewStringObj((char*)sqlite3_value_text(pVal
),n
));
3041 sqlite3ValueSetStr(pVal
, nB
, zB
, encin
, SQLITE_STATIC
);
3042 n
= sqlite3_value_bytes(pVal
);
3043 Tcl_ListObjAppendElement(i
,pX
,
3044 Tcl_NewStringObj((char*)sqlite3_value_text(pVal
),n
));
3045 sqlite3ValueFree(pVal
);
3047 sqlite3EndBenignMalloc();
3049 Tcl_EvalObjEx(i
, pX
, 0);
3050 Tcl_DecrRefCount(pX
);
3051 Tcl_GetIntFromObj(i
, Tcl_GetObjResult(i
), &res
);
3054 static int SQLITE_TCLAPI
test_collate(
3058 Tcl_Obj
*CONST objv
[]
3062 sqlite3_value
*pVal
;
3065 if( objc
!=5 ) goto bad_args
;
3066 pTestCollateInterp
= interp
;
3067 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3069 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[2], &val
) ) return TCL_ERROR
;
3070 rc
= sqlite3_create_collation(db
, "test_collate", SQLITE_UTF8
,
3071 (void *)SQLITE_UTF8
, val
?test_collate_func
:0);
3072 if( rc
==SQLITE_OK
){
3074 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
3075 rc
= sqlite3_create_collation(db
, "test_collate", SQLITE_UTF16LE
,
3076 (void *)SQLITE_UTF16LE
, val
?test_collate_func
:0);
3077 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[4], &val
) ) return TCL_ERROR
;
3080 if( sqlite3_iMallocFail
>0 ){
3081 sqlite3_iMallocFail
++;
3084 sqlite3_mutex_enter(db
->mutex
);
3085 pVal
= sqlite3ValueNew(db
);
3086 sqlite3ValueSetStr(pVal
, -1, "test_collate", SQLITE_UTF8
, SQLITE_STATIC
);
3087 zUtf16
= sqlite3ValueText(pVal
, SQLITE_UTF16NATIVE
);
3088 if( db
->mallocFailed
){
3091 rc
= sqlite3_create_collation16(db
, zUtf16
, SQLITE_UTF16BE
,
3092 (void *)SQLITE_UTF16BE
, val
?test_collate_func
:0);
3094 sqlite3ValueFree(pVal
);
3095 sqlite3_mutex_leave(db
->mutex
);
3097 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
3099 if( rc
!=SQLITE_OK
){
3100 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
3106 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3107 Tcl_GetStringFromObj(objv
[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
3112 ** Usage: add_test_utf16bin_collate <db ptr>
3114 ** Add a utf-16 collation sequence named "utf16bin" to the database
3115 ** handle. This collation sequence compares arguments in the same way as the
3116 ** built-in collation "binary".
3118 static int test_utf16bin_collate_func(
3120 int nA
, const void *zA
,
3121 int nB
, const void *zB
3123 int nCmp
= (nA
>nB
? nB
: nA
);
3124 int res
= memcmp(zA
, zB
, nCmp
);
3125 if( res
==0 ) res
= nA
- nB
;
3128 static int SQLITE_TCLAPI
test_utf16bin_collate(
3132 Tcl_Obj
*CONST objv
[]
3137 if( objc
!=2 ) goto bad_args
;
3138 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3140 rc
= sqlite3_create_collation(db
, "utf16bin", SQLITE_UTF16
, 0,
3141 test_utf16bin_collate_func
3143 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
3147 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
3152 ** When the collation needed callback is invoked, record the name of
3153 ** the requested collating function here. The recorded name is linked
3154 ** to a TCL variable and used to make sure that the requested collation
3157 static char zNeededCollation
[200];
3158 static char *pzNeededCollation
= zNeededCollation
;
3162 ** Called when a collating sequence is needed. Registered using
3163 ** sqlite3_collation_needed16().
3165 static void test_collate_needed_cb(
3174 for(z
= (char*)pName
, i
=0; *z
|| z
[1]; z
++){
3175 if( *z
) zNeededCollation
[i
++] = *z
;
3177 zNeededCollation
[i
] = 0;
3178 sqlite3_create_collation(
3179 db
, "test_collate", ENC(db
), SQLITE_INT_TO_PTR(enc
), test_collate_func
);
3183 ** Usage: add_test_collate_needed DB
3185 static int SQLITE_TCLAPI
test_collate_needed(
3189 Tcl_Obj
*CONST objv
[]
3194 if( objc
!=2 ) goto bad_args
;
3195 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3196 rc
= sqlite3_collation_needed16(db
, 0, test_collate_needed_cb
);
3197 zNeededCollation
[0] = 0;
3198 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
3202 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
3207 ** tclcmd: add_alignment_test_collations DB
3209 ** Add two new collating sequences to the database DB
3214 ** Both collating sequences use the same sort order as BINARY.
3215 ** The only difference is that the utf16_aligned collating
3216 ** sequence is declared with the SQLITE_UTF16_ALIGNED flag.
3217 ** Both collating functions increment the unaligned utf16 counter
3218 ** whenever they see a string that begins on an odd byte boundary.
3220 static int unaligned_string_counter
= 0;
3221 static int alignmentCollFunc(
3223 int nKey1
, const void *pKey1
,
3224 int nKey2
, const void *pKey2
3227 n
= nKey1
<nKey2
? nKey1
: nKey2
;
3228 if( nKey1
>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey1
))) ) unaligned_string_counter
++;
3229 if( nKey2
>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey2
))) ) unaligned_string_counter
++;
3230 rc
= memcmp(pKey1
, pKey2
, n
);
3236 static int SQLITE_TCLAPI
add_alignment_test_collations(
3240 Tcl_Obj
*CONST objv
[]
3244 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3245 sqlite3_create_collation(db
, "utf16_unaligned", SQLITE_UTF16
,
3246 0, alignmentCollFunc
);
3247 sqlite3_create_collation(db
, "utf16_aligned", SQLITE_UTF16_ALIGNED
,
3248 0, alignmentCollFunc
);
3252 #endif /* !defined(SQLITE_OMIT_UTF16) */
3255 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be>
3257 ** This function is used to test that SQLite selects the correct user
3258 ** function callback when multiple versions (for different text encodings)
3261 ** Calling this routine registers up to three versions of the user function
3262 ** "test_function" with database handle <db>. If the second argument is
3263 ** true, then a version of test_function is registered for UTF-8, if the
3264 ** third is true, a version is registered for UTF-16le, if the fourth is
3265 ** true, a UTF-16be version is available. Previous versions of
3266 ** test_function are deleted.
3268 ** The user function is implemented by calling the following TCL script:
3270 ** "test_function <enc> <arg>"
3272 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the
3273 ** single argument passed to the SQL function. The value returned by
3274 ** the TCL script is used as the return value of the SQL function. It
3275 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8
3276 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that
3277 ** prefers UTF-16BE.
3279 #ifndef SQLITE_OMIT_UTF16
3280 static void test_function_utf8(
3281 sqlite3_context
*pCtx
,
3283 sqlite3_value
**argv
3287 sqlite3_value
*pVal
;
3288 interp
= (Tcl_Interp
*)sqlite3_user_data(pCtx
);
3289 pX
= Tcl_NewStringObj("test_function", -1);
3290 Tcl_IncrRefCount(pX
);
3291 Tcl_ListObjAppendElement(interp
, pX
, Tcl_NewStringObj("UTF-8", -1));
3292 Tcl_ListObjAppendElement(interp
, pX
,
3293 Tcl_NewStringObj((char*)sqlite3_value_text(argv
[0]), -1));
3294 Tcl_EvalObjEx(interp
, pX
, 0);
3295 Tcl_DecrRefCount(pX
);
3296 sqlite3_result_text(pCtx
, Tcl_GetStringResult(interp
), -1, SQLITE_TRANSIENT
);
3297 pVal
= sqlite3ValueNew(0);
3298 sqlite3ValueSetStr(pVal
, -1, Tcl_GetStringResult(interp
),
3299 SQLITE_UTF8
, SQLITE_STATIC
);
3300 sqlite3_result_text16be(pCtx
, sqlite3_value_text16be(pVal
),
3301 -1, SQLITE_TRANSIENT
);
3302 sqlite3ValueFree(pVal
);
3304 static void test_function_utf16le(
3305 sqlite3_context
*pCtx
,
3307 sqlite3_value
**argv
3311 sqlite3_value
*pVal
;
3312 interp
= (Tcl_Interp
*)sqlite3_user_data(pCtx
);
3313 pX
= Tcl_NewStringObj("test_function", -1);
3314 Tcl_IncrRefCount(pX
);
3315 Tcl_ListObjAppendElement(interp
, pX
, Tcl_NewStringObj("UTF-16LE", -1));
3316 Tcl_ListObjAppendElement(interp
, pX
,
3317 Tcl_NewStringObj((char*)sqlite3_value_text(argv
[0]), -1));
3318 Tcl_EvalObjEx(interp
, pX
, 0);
3319 Tcl_DecrRefCount(pX
);
3320 pVal
= sqlite3ValueNew(0);
3321 sqlite3ValueSetStr(pVal
, -1, Tcl_GetStringResult(interp
),
3322 SQLITE_UTF8
, SQLITE_STATIC
);
3323 sqlite3_result_text(pCtx
,(char*)sqlite3_value_text(pVal
),-1,SQLITE_TRANSIENT
);
3324 sqlite3ValueFree(pVal
);
3326 static void test_function_utf16be(
3327 sqlite3_context
*pCtx
,
3329 sqlite3_value
**argv
3333 sqlite3_value
*pVal
;
3334 interp
= (Tcl_Interp
*)sqlite3_user_data(pCtx
);
3335 pX
= Tcl_NewStringObj("test_function", -1);
3336 Tcl_IncrRefCount(pX
);
3337 Tcl_ListObjAppendElement(interp
, pX
, Tcl_NewStringObj("UTF-16BE", -1));
3338 Tcl_ListObjAppendElement(interp
, pX
,
3339 Tcl_NewStringObj((char*)sqlite3_value_text(argv
[0]), -1));
3340 Tcl_EvalObjEx(interp
, pX
, 0);
3341 Tcl_DecrRefCount(pX
);
3342 pVal
= sqlite3ValueNew(0);
3343 sqlite3ValueSetStr(pVal
, -1, Tcl_GetStringResult(interp
),
3344 SQLITE_UTF8
, SQLITE_STATIC
);
3345 sqlite3_result_text16(pCtx
, sqlite3_value_text16le(pVal
),
3346 -1, SQLITE_TRANSIENT
);
3347 sqlite3_result_text16be(pCtx
, sqlite3_value_text16le(pVal
),
3348 -1, SQLITE_TRANSIENT
);
3349 sqlite3_result_text16le(pCtx
, sqlite3_value_text16le(pVal
),
3350 -1, SQLITE_TRANSIENT
);
3351 sqlite3ValueFree(pVal
);
3353 #endif /* SQLITE_OMIT_UTF16 */
3354 static int SQLITE_TCLAPI
test_function(
3358 Tcl_Obj
*CONST objv
[]
3360 #ifndef SQLITE_OMIT_UTF16
3364 if( objc
!=5 ) goto bad_args
;
3365 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3367 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[2], &val
) ) return TCL_ERROR
;
3369 sqlite3_create_function(db
, "test_function", 1, SQLITE_UTF8
,
3370 interp
, test_function_utf8
, 0, 0);
3372 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
3374 sqlite3_create_function(db
, "test_function", 1, SQLITE_UTF16LE
,
3375 interp
, test_function_utf16le
, 0, 0);
3377 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[4], &val
) ) return TCL_ERROR
;
3379 sqlite3_create_function(db
, "test_function", 1, SQLITE_UTF16BE
,
3380 interp
, test_function_utf16be
, 0, 0);
3385 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3386 Tcl_GetStringFromObj(objv
[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
3387 #endif /* SQLITE_OMIT_UTF16 */
3392 ** Usage: sqlite3_test_errstr <err code>
3394 ** Test that the english language string equivalents for sqlite error codes
3395 ** are sane. The parameter is an integer representing an sqlite error code.
3396 ** The result is a list of two elements, the string representation of the
3397 ** error code and the english language explanation.
3399 static int SQLITE_TCLAPI
test_errstr(
3403 Tcl_Obj
*CONST objv
[]
3408 Tcl_WrongNumArgs(interp
, 1, objv
, "<error code>");
3411 zCode
= Tcl_GetString(objv
[1]);
3412 for(i
=0; i
<200; i
++){
3413 if( 0==strcmp(t1ErrorName(i
), zCode
) ) break;
3415 Tcl_SetResult(interp
, (char *)sqlite3ErrStr(i
), 0);
3420 ** Usage: breakpoint
3422 ** This routine exists for one purpose - to provide a place to put a
3423 ** breakpoint with GDB that can be triggered using TCL code. The use
3424 ** for this is when a particular test fails on (say) the 1485th iteration.
3425 ** In the TCL test script, we can add code like this:
3427 ** if {$i==1485} breakpoint
3429 ** Then run testfixture in the debugger and wait for the breakpoint to
3430 ** fire. Then additional breakpoints can be set to trace down the bug.
3432 static int SQLITE_TCLAPI
test_breakpoint(
3434 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
3435 int argc
, /* Number of arguments */
3436 char **argv
/* Text of each argument */
3438 return TCL_OK
; /* Do nothing */
3442 ** Usage: sqlite3_bind_zeroblob STMT IDX N
3444 ** Test the sqlite3_bind_zeroblob interface. STMT is a prepared statement.
3445 ** IDX is the index of a wildcard in the prepared statement. This command
3446 ** binds a N-byte zero-filled BLOB to the wildcard.
3448 static int SQLITE_TCLAPI
test_bind_zeroblob(
3452 Tcl_Obj
*CONST objv
[]
3454 sqlite3_stmt
*pStmt
;
3460 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT IDX N");
3464 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3465 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3466 if( Tcl_GetIntFromObj(interp
, objv
[3], &n
) ) return TCL_ERROR
;
3468 rc
= sqlite3_bind_zeroblob(pStmt
, idx
, n
);
3469 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3470 if( rc
!=SQLITE_OK
){
3478 ** Usage: sqlite3_bind_zeroblob64 STMT IDX N
3480 ** Test the sqlite3_bind_zeroblob64 interface. STMT is a prepared statement.
3481 ** IDX is the index of a wildcard in the prepared statement. This command
3482 ** binds a N-byte zero-filled BLOB to the wildcard.
3484 static int SQLITE_TCLAPI
test_bind_zeroblob64(
3488 Tcl_Obj
*CONST objv
[]
3490 sqlite3_stmt
*pStmt
;
3496 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT IDX N");
3500 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3501 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3502 if( Tcl_GetWideIntFromObj(interp
, objv
[3], &n
) ) return TCL_ERROR
;
3504 rc
= sqlite3_bind_zeroblob64(pStmt
, idx
, n
);
3505 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3506 if( rc
!=SQLITE_OK
){
3507 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
3515 ** Usage: sqlite3_bind_int STMT N VALUE
3517 ** Test the sqlite3_bind_int interface. STMT is a prepared statement.
3518 ** N is the index of a wildcard in the prepared statement. This command
3519 ** binds a 32-bit integer VALUE to that wildcard.
3521 static int SQLITE_TCLAPI
test_bind_int(
3525 Tcl_Obj
*CONST objv
[]
3527 sqlite3_stmt
*pStmt
;
3533 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3534 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE", 0);
3538 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3539 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3540 if( Tcl_GetIntFromObj(interp
, objv
[3], &value
) ) return TCL_ERROR
;
3542 rc
= sqlite3_bind_int(pStmt
, idx
, value
);
3543 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3544 if( rc
!=SQLITE_OK
){
3553 ** Usage: intarray_addr INT ...
3555 ** Return the address of a C-language array of 32-bit integers.
3557 ** Space to hold the array is obtained from malloc(). Call this procedure once
3558 ** with no arguments in order to release memory. Each call to this procedure
3559 ** overwrites the previous array.
3561 static int SQLITE_TCLAPI
test_intarray_addr(
3565 Tcl_Obj
*CONST objv
[]
3573 p
= sqlite3_malloc( sizeof(p
[0])*(objc
-1) );
3574 if( p
==0 ) return TCL_ERROR
;
3575 for(i
=0; i
<objc
-1; i
++){
3576 if( Tcl_GetIntFromObj(interp
, objv
[1+i
], &p
[i
]) ){
3583 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj((sqlite3_int64
)p
));
3587 ** Usage: intarray_addr INT ...
3589 ** Return the address of a C-language array of 32-bit integers.
3591 ** Space to hold the array is obtained from malloc(). Call this procedure once
3592 ** with no arguments in order to release memory. Each call to this procedure
3593 ** overwrites the previous array.
3595 static int SQLITE_TCLAPI
test_int64array_addr(
3599 Tcl_Obj
*CONST objv
[]
3602 static sqlite3_int64
*p
= 0;
3607 p
= sqlite3_malloc( sizeof(p
[0])*(objc
-1) );
3608 if( p
==0 ) return TCL_ERROR
;
3609 for(i
=0; i
<objc
-1; i
++){
3611 if( Tcl_GetWideIntFromObj(interp
, objv
[1+i
], &v
) ){
3619 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj((sqlite3_int64
)p
));
3623 ** Usage: doublearray_addr INT ...
3625 ** Return the address of a C-language array of doubles.
3627 ** Space to hold the array is obtained from malloc(). Call this procedure once
3628 ** with no arguments in order to release memory. Each call to this procedure
3629 ** overwrites the previous array.
3631 static int SQLITE_TCLAPI
test_doublearray_addr(
3635 Tcl_Obj
*CONST objv
[]
3638 static double *p
= 0;
3643 p
= sqlite3_malloc( sizeof(p
[0])*(objc
-1) );
3644 if( p
==0 ) return TCL_ERROR
;
3645 for(i
=0; i
<objc
-1; i
++){
3646 if( Tcl_GetDoubleFromObj(interp
, objv
[1+i
], &p
[i
]) ){
3653 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj((sqlite3_int64
)p
));
3657 ** Usage: textarray_addr TEXT ...
3659 ** Return the address of a C-language array of strings.
3661 ** Space to hold the array is obtained from malloc(). Call this procedure once
3662 ** with no arguments in order to release memory. Each call to this procedure
3663 ** overwrites the previous array.
3665 static int SQLITE_TCLAPI
test_textarray_addr(
3669 Tcl_Obj
*CONST objv
[]
3673 static char **p
= 0;
3675 for(i
=0; i
<n
; i
++) sqlite3_free(p
[i
]);
3679 p
= sqlite3_malloc( sizeof(p
[0])*(objc
-1) );
3680 if( p
==0 ) return TCL_ERROR
;
3681 for(i
=0; i
<objc
-1; i
++){
3682 p
[i
] = sqlite3_mprintf("%s", Tcl_GetString(objv
[1+i
]));
3686 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj((sqlite3_int64
)p
));
3692 ** Usage: sqlite3_bind_int64 STMT N VALUE
3694 ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement.
3695 ** N is the index of a wildcard in the prepared statement. This command
3696 ** binds a 64-bit integer VALUE to that wildcard.
3698 static int SQLITE_TCLAPI
test_bind_int64(
3702 Tcl_Obj
*CONST objv
[]
3704 sqlite3_stmt
*pStmt
;
3710 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3711 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE", 0);
3715 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3716 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3717 if( Tcl_GetWideIntFromObj(interp
, objv
[3], &value
) ) return TCL_ERROR
;
3719 rc
= sqlite3_bind_int64(pStmt
, idx
, value
);
3720 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3721 if( rc
!=SQLITE_OK
){
3730 ** Usage: sqlite3_bind_double STMT N VALUE
3732 ** Test the sqlite3_bind_double interface. STMT is a prepared statement.
3733 ** N is the index of a wildcard in the prepared statement. This command
3734 ** binds a 64-bit integer VALUE to that wildcard.
3736 static int SQLITE_TCLAPI
test_bind_double(
3740 Tcl_Obj
*CONST objv
[]
3742 sqlite3_stmt
*pStmt
;
3748 static const struct {
3749 const char *zName
; /* Name of the special floating point value */
3750 unsigned int iUpper
; /* Upper 32 bits */
3751 unsigned int iLower
; /* Lower 32 bits */
3753 { "NaN", 0x7fffffff, 0xffffffff },
3754 { "SNaN", 0x7ff7ffff, 0xffffffff },
3755 { "-NaN", 0xffffffff, 0xffffffff },
3756 { "-SNaN", 0xfff7ffff, 0xffffffff },
3757 { "+Inf", 0x7ff00000, 0x00000000 },
3758 { "-Inf", 0xfff00000, 0x00000000 },
3759 { "Epsilon", 0x00000000, 0x00000001 },
3760 { "-Epsilon", 0x80000000, 0x00000001 },
3761 { "NaN0", 0x7ff80000, 0x00000000 },
3762 { "-NaN0", 0xfff80000, 0x00000000 },
3766 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3767 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE", 0);
3771 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3772 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3774 /* Intercept the string "NaN" and generate a NaN value for it.
3775 ** All other strings are passed through to Tcl_GetDoubleFromObj().
3776 ** Tcl_GetDoubleFromObj() should understand "NaN" but some versions
3779 zVal
= Tcl_GetString(objv
[3]);
3780 for(i
=0; i
<sizeof(aSpecialFp
)/sizeof(aSpecialFp
[0]); i
++){
3781 if( strcmp(aSpecialFp
[i
].zName
, zVal
)==0 ){
3783 x
= aSpecialFp
[i
].iUpper
;
3785 x
|= aSpecialFp
[i
].iLower
;
3786 assert( sizeof(value
)==8 );
3787 assert( sizeof(x
)==8 );
3788 memcpy(&value
, &x
, 8);
3792 if( i
>=sizeof(aSpecialFp
)/sizeof(aSpecialFp
[0]) &&
3793 Tcl_GetDoubleFromObj(interp
, objv
[3], &value
) ){
3796 rc
= sqlite3_bind_double(pStmt
, idx
, value
);
3797 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3798 if( rc
!=SQLITE_OK
){
3806 ** Usage: sqlite3_bind_null STMT N
3808 ** Test the sqlite3_bind_null interface. STMT is a prepared statement.
3809 ** N is the index of a wildcard in the prepared statement. This command
3810 ** binds a NULL to the wildcard.
3812 static int SQLITE_TCLAPI
test_bind_null(
3816 Tcl_Obj
*CONST objv
[]
3818 sqlite3_stmt
*pStmt
;
3823 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3824 Tcl_GetStringFromObj(objv
[0], 0), " STMT N", 0);
3828 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3829 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3831 rc
= sqlite3_bind_null(pStmt
, idx
);
3832 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3833 if( rc
!=SQLITE_OK
){
3841 ** Usage: sqlite3_bind_text STMT N STRING BYTES
3843 ** Test the sqlite3_bind_text interface. STMT is a prepared statement.
3844 ** N is the index of a wildcard in the prepared statement. This command
3845 ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes
3848 static int SQLITE_TCLAPI
test_bind_text(
3852 Tcl_Obj
*CONST objv
[]
3854 sqlite3_stmt
*pStmt
;
3863 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3864 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE BYTES", 0);
3868 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3869 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3870 value
= (char*)Tcl_GetByteArrayFromObj(objv
[3], &trueLength
);
3871 if( Tcl_GetIntFromObj(interp
, objv
[4], &bytes
) ) return TCL_ERROR
;
3873 toFree
= malloc( trueLength
+ 1 );
3875 Tcl_AppendResult(interp
, "out of memory", (void*)0);
3878 memcpy(toFree
, value
, trueLength
);
3879 toFree
[trueLength
] = 0;
3882 rc
= sqlite3_bind_text(pStmt
, idx
, value
, bytes
, SQLITE_TRANSIENT
);
3884 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3885 if( rc
!=SQLITE_OK
){
3886 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), (void*)0);
3894 ** Usage: sqlite3_bind_text16 ?-static? STMT N STRING BYTES
3896 ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement.
3897 ** N is the index of a wildcard in the prepared statement. This command
3898 ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes
3901 static int SQLITE_TCLAPI
test_bind_text16(
3905 Tcl_Obj
*CONST objv
[]
3907 #ifndef SQLITE_OMIT_UTF16
3908 sqlite3_stmt
*pStmt
;
3916 void (*xDel
)(void*) = (objc
==6?SQLITE_STATIC
:SQLITE_TRANSIENT
);
3917 Tcl_Obj
*oStmt
= objv
[objc
-4];
3918 Tcl_Obj
*oN
= objv
[objc
-3];
3919 Tcl_Obj
*oString
= objv
[objc
-2];
3920 Tcl_Obj
*oBytes
= objv
[objc
-1];
3922 if( objc
!=5 && objc
!=6){
3923 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3924 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE BYTES", 0);
3928 if( getStmtPointer(interp
, Tcl_GetString(oStmt
), &pStmt
) ) return TCL_ERROR
;
3929 if( Tcl_GetIntFromObj(interp
, oN
, &idx
) ) return TCL_ERROR
;
3930 value
= (char*)Tcl_GetByteArrayFromObj(oString
, &trueLength
);
3931 if( Tcl_GetIntFromObj(interp
, oBytes
, &bytes
) ) return TCL_ERROR
;
3932 if( bytes
<0 && xDel
==SQLITE_TRANSIENT
){
3933 toFree
= malloc( trueLength
+ 3 );
3935 Tcl_AppendResult(interp
, "out of memory", (void*)0);
3938 memcpy(toFree
, value
, trueLength
);
3939 memset(toFree
+trueLength
, 0, 3);
3942 rc
= sqlite3_bind_text16(pStmt
, idx
, (void *)value
, bytes
, xDel
);
3944 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3945 if( rc
!=SQLITE_OK
){
3946 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
3950 #endif /* SQLITE_OMIT_UTF16 */
3955 ** Usage: sqlite3_bind_blob ?-static? STMT N DATA BYTES
3957 ** Test the sqlite3_bind_blob interface. STMT is a prepared statement.
3958 ** N is the index of a wildcard in the prepared statement. This command
3959 ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size.
3961 static int SQLITE_TCLAPI
test_bind_blob(
3965 Tcl_Obj
*CONST objv
[]
3967 sqlite3_stmt
*pStmt
;
3972 sqlite3_destructor_type xDestructor
= SQLITE_TRANSIENT
;
3974 if( objc
!=5 && objc
!=6 ){
3975 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3976 Tcl_GetStringFromObj(objv
[0], 0), " STMT N DATA BYTES", 0);
3981 xDestructor
= SQLITE_STATIC
;
3985 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3986 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3988 value
= (char*)Tcl_GetByteArrayFromObj(objv
[3], &len
);
3989 if( Tcl_GetIntFromObj(interp
, objv
[4], &bytes
) ) return TCL_ERROR
;
3993 sqlite3_snprintf(sizeof(zBuf
), zBuf
,
3994 "cannot use %d blob bytes, have %d", bytes
, len
);
3995 Tcl_AppendResult(interp
, zBuf
, (char*)0);
3999 rc
= sqlite3_bind_blob(pStmt
, idx
, value
, bytes
, xDestructor
);
4000 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
4001 if( rc
!=SQLITE_OK
){
4009 #ifndef SQLITE_OMIT_VIRTUALTABLE
4011 ** sqlite3_carray_bind [options...] STMT NAME VALUE ...
4021 ** Each call clears static data. Called with no options does nothing
4022 ** but clear static data.
4024 static int SQLITE_TCLAPI
test_carray_bind(
4028 Tcl_Obj
*CONST objv
[]
4030 sqlite3_stmt
*pStmt
;
4031 int eType
= 0; /* CARRAY_INT32 */
4034 int isTransient
= 0;
4039 void (*xDel
)(void*) = sqlite3_free
;
4040 static void *aStaticData
= 0;
4041 static int nStaticData
= 0;
4042 static int eStaticType
= 0;
4043 extern int sqlite3_carray_bind(
4044 sqlite3_stmt
*pStmt
,
4049 void (*xDestroy
)(void*)
4053 /* Always clear preexisting static data on every call */
4054 if( eStaticType
==3 ){
4055 for(i
=0; i
<nStaticData
; i
++){
4056 sqlite3_free(((char**)aStaticData
)[i
]);
4059 sqlite3_free(aStaticData
);
4064 if( objc
==1 ) return TCL_OK
;
4066 for(i
=1; i
<objc
&& Tcl_GetString(objv
[i
])[0]=='-'; i
++){
4067 const char *z
= Tcl_GetString(objv
[i
]);
4068 if( strcmp(z
, "-transient")==0 ){
4070 xDel
= SQLITE_TRANSIENT
;
4072 if( strcmp(z
, "-static")==0 ){
4074 xDel
= SQLITE_STATIC
;
4076 if( strcmp(z
, "-int32")==0 ){
4077 eType
= 0; /* CARRAY_INT32 */
4079 if( strcmp(z
, "-int64")==0 ){
4080 eType
= 1; /* CARRAY_INT64 */
4082 if( strcmp(z
, "-double")==0 ){
4083 eType
= 2; /* CARRAY_DOUBLE */
4085 if( strcmp(z
, "-text")==0 ){
4086 eType
= 3; /* CARRAY_TEXT */
4088 if( strcmp(z
, "--")==0 ){
4092 Tcl_AppendResult(interp
, "unknown option: ", z
, (char*)0);
4096 if( eType
==3 && !isStatic
&& !isTransient
){
4097 Tcl_AppendResult(interp
, "text data must be either -static or -transient",
4101 if( isStatic
&& isTransient
){
4102 Tcl_AppendResult(interp
, "cannot be both -static and -transient",
4107 Tcl_WrongNumArgs(interp
, 1, objv
, "[OPTIONS] STMT IDX VALUE ...");
4110 if( getStmtPointer(interp
, Tcl_GetString(objv
[i
]), &pStmt
) ) return TCL_ERROR
;
4112 if( Tcl_GetIntFromObj(interp
, objv
[i
], &idx
) ) return TCL_ERROR
;
4115 switch( eType
+ 4*(nData
<=0) ){
4116 case 0: { /* INT32 */
4117 int *a
= sqlite3_malloc( sizeof(int)*nData
);
4118 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4119 for(j
=0; j
<nData
; j
++){
4121 if( Tcl_GetIntFromObj(interp
, objv
[i
+j
], &v
) ){
4130 case 1: { /* INT64 */
4131 sqlite3_int64
*a
= sqlite3_malloc( sizeof(sqlite3_int64
)*nData
);
4132 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4133 for(j
=0; j
<nData
; j
++){
4135 if( Tcl_GetWideIntFromObj(interp
, objv
[i
+j
], &v
) ){
4144 case 2: { /* DOUBLE */
4145 double *a
= sqlite3_malloc( sizeof(double)*nData
);
4146 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4147 for(j
=0; j
<nData
; j
++){
4149 if( Tcl_GetDoubleFromObj(interp
, objv
[i
+j
], &v
) ){
4158 case 3: { /* TEXT */
4159 char **a
= sqlite3_malloc( sizeof(char*)*nData
);
4160 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4161 for(j
=0; j
<nData
; j
++){
4162 const char *v
= Tcl_GetString(objv
[i
+j
]);
4163 a
[j
] = sqlite3_mprintf("%s", v
);
4168 case 4: { /* nData==0 */
4170 xDel
= SQLITE_STATIC
;
4177 aStaticData
= aData
;
4178 nStaticData
= nData
;
4179 eStaticType
= eType
;
4181 rc
= sqlite3_carray_bind(pStmt
, idx
, aData
, nData
, eType
, xDel
);
4184 for(i
=0; i
<nData
; i
++) sqlite3_free(((char**)aData
)[i
]);
4186 sqlite3_free(aData
);
4190 Tcl_AppendResult(interp
, sqlite3_errstr(rc
), (char*)0);
4195 #endif /* SQLITE_OMIT_VIRTUALTABLE */
4198 ** Usage: sqlite3_bind_parameter_count STMT
4200 ** Return the number of wildcards in the given statement.
4202 static int SQLITE_TCLAPI
test_bind_parameter_count(
4206 Tcl_Obj
*CONST objv
[]
4208 sqlite3_stmt
*pStmt
;
4211 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
4214 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4215 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt
)));
4220 ** Usage: sqlite3_bind_parameter_name STMT N
4222 ** Return the name of the Nth wildcard. The first wildcard is 1.
4223 ** An empty string is returned if N is out of range or if the wildcard
4226 static int SQLITE_TCLAPI
test_bind_parameter_name(
4230 Tcl_Obj
*CONST objv
[]
4232 sqlite3_stmt
*pStmt
;
4236 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT N");
4239 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4240 if( Tcl_GetIntFromObj(interp
, objv
[2], &i
) ) return TCL_ERROR
;
4241 Tcl_SetObjResult(interp
,
4242 Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt
,i
),-1)
4248 ** Usage: sqlite3_bind_parameter_index STMT NAME
4250 ** Return the index of the wildcard called NAME. Return 0 if there is
4251 ** no such wildcard.
4253 static int SQLITE_TCLAPI
test_bind_parameter_index(
4257 Tcl_Obj
*CONST objv
[]
4259 sqlite3_stmt
*pStmt
;
4262 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT NAME");
4265 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4266 Tcl_SetObjResult(interp
,
4268 sqlite3_bind_parameter_index(pStmt
,Tcl_GetString(objv
[2]))
4275 ** Usage: sqlite3_clear_bindings STMT
4278 static int SQLITE_TCLAPI
test_clear_bindings(
4282 Tcl_Obj
*CONST objv
[]
4284 sqlite3_stmt
*pStmt
;
4287 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
4290 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4291 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt
)));
4296 ** Usage: sqlite3_sleep MILLISECONDS
4298 static int SQLITE_TCLAPI
test_sleep(
4302 Tcl_Obj
*CONST objv
[]
4307 Tcl_WrongNumArgs(interp
, 1, objv
, "MILLISECONDS");
4310 if( Tcl_GetIntFromObj(interp
, objv
[1], &ms
) ){
4313 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_sleep(ms
)));
4318 ** Usage: sqlite3_extended_errcode DB
4320 ** Return the string representation of the most recent sqlite3_* API
4321 ** error code. e.g. "SQLITE_ERROR".
4323 static int SQLITE_TCLAPI
test_ex_errcode(
4327 Tcl_Obj
*CONST objv
[]
4333 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4334 Tcl_GetString(objv
[0]), " DB", 0);
4337 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4338 rc
= sqlite3_extended_errcode(db
);
4339 Tcl_AppendResult(interp
, (char *)t1ErrorName(rc
), 0);
4345 ** Usage: sqlite3_errcode DB
4347 ** Return the string representation of the most recent sqlite3_* API
4348 ** error code. e.g. "SQLITE_ERROR".
4350 static int SQLITE_TCLAPI
test_errcode(
4354 Tcl_Obj
*CONST objv
[]
4360 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4361 Tcl_GetString(objv
[0]), " DB", 0);
4364 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4365 rc
= sqlite3_errcode(db
);
4366 Tcl_AppendResult(interp
, (char *)t1ErrorName(rc
), 0);
4371 ** Usage: sqlite3_errmsg DB
4373 ** Returns the UTF-8 representation of the error message string for the
4374 ** most recent sqlite3_* API call.
4376 static int SQLITE_TCLAPI
test_errmsg(
4380 Tcl_Obj
*CONST objv
[]
4386 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4387 Tcl_GetString(objv
[0]), " DB", 0);
4390 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4392 zErr
= sqlite3_errmsg(db
);
4393 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zErr
, -1));
4398 ** Usage: test_errmsg16 DB
4400 ** Returns the UTF-16 representation of the error message string for the
4401 ** most recent sqlite3_* API call. This is a byte array object at the TCL
4402 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the
4405 static int SQLITE_TCLAPI
test_errmsg16(
4409 Tcl_Obj
*CONST objv
[]
4411 #ifndef SQLITE_OMIT_UTF16
4418 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4419 Tcl_GetString(objv
[0]), " DB", 0);
4422 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4424 zErr
= sqlite3_errmsg16(db
);
4427 for(bytes
=0; z
[bytes
] || z
[bytes
+1]; bytes
+=2){}
4429 Tcl_SetObjResult(interp
, Tcl_NewByteArrayObj(zErr
, bytes
));
4430 #endif /* SQLITE_OMIT_UTF16 */
4435 ** Usage: sqlite3_prepare DB sql bytes ?tailvar?
4437 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4438 ** database handle <DB>. The parameter <tailval> is the name of a global
4439 ** variable that is set to the unused portion of <sql> (if any). A
4440 ** STMT handle is returned.
4442 static int SQLITE_TCLAPI
test_prepare(
4446 Tcl_Obj
*CONST objv
[]
4451 const char *zTail
= 0;
4452 sqlite3_stmt
*pStmt
= 0;
4456 if( objc
!=5 && objc
!=4 ){
4457 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4458 Tcl_GetString(objv
[0]), " DB sql bytes ?tailvar?", 0);
4461 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4462 zSql
= Tcl_GetString(objv
[2]);
4463 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
4465 rc
= sqlite3_prepare(db
, zSql
, bytes
, &pStmt
, objc
>=5 ? &zTail
: 0);
4466 Tcl_ResetResult(interp
);
4467 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
4468 if( zTail
&& objc
>=5 ){
4470 bytes
= bytes
- (int)(zTail
-zSql
);
4472 if( (int)strlen(zTail
)<bytes
){
4473 bytes
= (int)strlen(zTail
);
4475 Tcl_ObjSetVar2(interp
, objv
[4], 0, Tcl_NewStringObj(zTail
, bytes
), 0);
4477 if( rc
!=SQLITE_OK
){
4479 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
4480 Tcl_AppendResult(interp
, zBuf
, sqlite3_errmsg(db
), 0);
4485 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
4486 Tcl_AppendResult(interp
, zBuf
, 0);
4492 ** Usage: sqlite3_prepare_v2 DB sql bytes ?tailvar?
4494 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4495 ** database handle <DB>. The parameter <tailval> is the name of a global
4496 ** variable that is set to the unused portion of <sql> (if any). A
4497 ** STMT handle is returned.
4499 static int SQLITE_TCLAPI
test_prepare_v2(
4503 Tcl_Obj
*CONST objv
[]
4507 char *zCopy
= 0; /* malloc() copy of zSql */
4509 const char *zTail
= 0;
4510 const char **pzTail
;
4511 sqlite3_stmt
*pStmt
= 0;
4515 if( objc
!=5 && objc
!=4 ){
4516 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4517 Tcl_GetString(objv
[0]), " DB sql bytes tailvar", 0);
4520 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4521 zSql
= Tcl_GetString(objv
[2]);
4522 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
4524 /* Instead of using zSql directly, make a copy into a buffer obtained
4525 ** directly from malloc(). The idea is to make it easier for valgrind
4526 ** to spot buffer overreads. */
4528 zCopy
= malloc(bytes
);
4529 memcpy(zCopy
, zSql
, bytes
);
4531 int n
= (int)strlen(zSql
) + 1;
4533 memcpy(zCopy
, zSql
, n
);
4535 pzTail
= objc
>=5 ? &zTail
: 0;
4536 rc
= sqlite3_prepare_v2(db
, zCopy
, bytes
, &pStmt
, pzTail
);
4538 zTail
= &zSql
[(zTail
- zCopy
)];
4542 assert(rc
==SQLITE_OK
|| pStmt
==0);
4543 Tcl_ResetResult(interp
);
4544 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
4545 if( rc
==SQLITE_OK
&& objc
>=5 && zTail
){
4547 bytes
= bytes
- (int)(zTail
-zSql
);
4549 Tcl_ObjSetVar2(interp
, objv
[4], 0, Tcl_NewStringObj(zTail
, bytes
), 0);
4551 if( rc
!=SQLITE_OK
){
4553 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
4554 Tcl_AppendResult(interp
, zBuf
, sqlite3_errmsg(db
), 0);
4559 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
4560 Tcl_AppendResult(interp
, zBuf
, 0);
4566 ** Usage: sqlite3_prepare_v3 DB sql bytes flags ?tailvar?
4568 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4569 ** database handle <DB> and flags <flags>. The parameter <tailval> is
4570 ** the name of a global variable that is set to the unused portion of
4571 ** <sql> (if any). A STMT handle is returned.
4573 static int SQLITE_TCLAPI
test_prepare_v3(
4577 Tcl_Obj
*CONST objv
[]
4581 char *zCopy
= 0; /* malloc() copy of zSql */
4583 const char *zTail
= 0;
4584 const char **pzTail
;
4585 sqlite3_stmt
*pStmt
= 0;
4589 if( objc
!=6 && objc
!=5 ){
4590 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4591 Tcl_GetString(objv
[0]), " DB sql bytes flags tailvar", 0);
4594 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4595 zSql
= Tcl_GetString(objv
[2]);
4596 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
4597 if( Tcl_GetIntFromObj(interp
, objv
[4], &flags
) ) return TCL_ERROR
;
4599 /* Instead of using zSql directly, make a copy into a buffer obtained
4600 ** directly from malloc(). The idea is to make it easier for valgrind
4601 ** to spot buffer overreads. */
4603 zCopy
= malloc(bytes
);
4604 memcpy(zCopy
, zSql
, bytes
);
4606 int n
= (int)strlen(zSql
) + 1;
4608 memcpy(zCopy
, zSql
, n
);
4610 pzTail
= objc
>=6 ? &zTail
: 0;
4611 rc
= sqlite3_prepare_v3(db
, zCopy
, bytes
, (unsigned int)flags
,&pStmt
,pzTail
);
4613 zTail
= &zSql
[(zTail
- zCopy
)];
4615 assert(rc
==SQLITE_OK
|| pStmt
==0);
4616 Tcl_ResetResult(interp
);
4617 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
4618 if( rc
==SQLITE_OK
&& zTail
&& objc
>=6 ){
4620 bytes
= bytes
- (int)(zTail
-zSql
);
4622 Tcl_ObjSetVar2(interp
, objv
[5], 0, Tcl_NewStringObj(zTail
, bytes
), 0);
4624 if( rc
!=SQLITE_OK
){
4626 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
4627 Tcl_AppendResult(interp
, zBuf
, sqlite3_errmsg(db
), 0);
4632 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
4633 Tcl_AppendResult(interp
, zBuf
, 0);
4639 ** Usage: sqlite3_prepare_tkt3134 DB
4641 ** Generate a prepared statement for a zero-byte string as a test
4642 ** for ticket #3134. The string should be preceded by a zero byte.
4644 static int SQLITE_TCLAPI
test_prepare_tkt3134(
4648 Tcl_Obj
*CONST objv
[]
4651 static const char zSql
[] = "\000SELECT 1";
4652 sqlite3_stmt
*pStmt
= 0;
4657 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4658 Tcl_GetString(objv
[0]), " DB sql bytes tailvar", 0);
4661 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4662 rc
= sqlite3_prepare_v2(db
, &zSql
[1], 0, &pStmt
, 0);
4663 assert(rc
==SQLITE_OK
|| pStmt
==0);
4664 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
4665 if( rc
!=SQLITE_OK
){
4667 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
4668 Tcl_AppendResult(interp
, zBuf
, sqlite3_errmsg(db
), 0);
4673 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
4674 Tcl_AppendResult(interp
, zBuf
, 0);
4680 ** Usage: sqlite3_prepare16 DB sql bytes tailvar
4682 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4683 ** database handle <DB>. The parameter <tailval> is the name of a global
4684 ** variable that is set to the unused portion of <sql> (if any). A
4685 ** STMT handle is returned.
4687 static int SQLITE_TCLAPI
test_prepare16(
4691 Tcl_Obj
*CONST objv
[]
4693 #ifndef SQLITE_OMIT_UTF16
4696 const void *zTail
= 0;
4698 sqlite3_stmt
*pStmt
= 0;
4701 int bytes
; /* The integer specified as arg 3 */
4702 int objlen
; /* The byte-array length of arg 2 */
4704 if( objc
!=5 && objc
!=4 ){
4705 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4706 Tcl_GetString(objv
[0]), " DB sql bytes ?tailvar?", 0);
4709 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4710 zSql
= Tcl_GetByteArrayFromObj(objv
[2], &objlen
);
4711 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
4713 rc
= sqlite3_prepare16(db
, zSql
, bytes
, &pStmt
, objc
>=5 ? &zTail
: 0);
4714 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
4721 objlen
= objlen
- (int)((u8
*)zTail
-(u8
*)zSql
);
4725 pTail
= Tcl_NewByteArrayObj((u8
*)zTail
, objlen
);
4726 Tcl_IncrRefCount(pTail
);
4727 Tcl_ObjSetVar2(interp
, objv
[4], 0, pTail
, 0);
4728 Tcl_DecrRefCount(pTail
);
4732 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
4734 Tcl_AppendResult(interp
, zBuf
, 0);
4735 #endif /* SQLITE_OMIT_UTF16 */
4740 ** Usage: sqlite3_prepare16_v2 DB sql bytes ?tailvar?
4742 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4743 ** database handle <DB>. The parameter <tailval> is the name of a global
4744 ** variable that is set to the unused portion of <sql> (if any). A
4745 ** STMT handle is returned.
4747 static int SQLITE_TCLAPI
test_prepare16_v2(
4751 Tcl_Obj
*CONST objv
[]
4753 #ifndef SQLITE_OMIT_UTF16
4756 const void *zTail
= 0;
4758 sqlite3_stmt
*pStmt
= 0;
4761 int bytes
; /* The integer specified as arg 3 */
4762 int objlen
; /* The byte-array length of arg 2 */
4764 if( objc
!=5 && objc
!=4 ){
4765 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4766 Tcl_GetString(objv
[0]), " DB sql bytes ?tailvar?", 0);
4769 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4770 zSql
= Tcl_GetByteArrayFromObj(objv
[2], &objlen
);
4771 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
4773 rc
= sqlite3_prepare16_v2(db
, zSql
, bytes
, &pStmt
, objc
>=5 ? &zTail
: 0);
4774 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
4781 objlen
= objlen
- (int)((u8
*)zTail
-(u8
*)zSql
);
4785 pTail
= Tcl_NewByteArrayObj((u8
*)zTail
, objlen
);
4786 Tcl_IncrRefCount(pTail
);
4787 Tcl_ObjSetVar2(interp
, objv
[4], 0, pTail
, 0);
4788 Tcl_DecrRefCount(pTail
);
4792 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
4794 Tcl_AppendResult(interp
, zBuf
, 0);
4795 #endif /* SQLITE_OMIT_UTF16 */
4800 ** Usage: sqlite3_open filename ?options-list?
4802 static int SQLITE_TCLAPI
test_open(
4806 Tcl_Obj
*CONST objv
[]
4808 const char *zFilename
;
4812 if( objc
!=3 && objc
!=2 && objc
!=1 ){
4813 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4814 Tcl_GetString(objv
[0]), " filename options-list", 0);
4818 zFilename
= objc
>1 ? Tcl_GetString(objv
[1]) : 0;
4819 sqlite3_open(zFilename
, &db
);
4821 if( sqlite3TestMakePointerStr(interp
, zBuf
, db
) ) return TCL_ERROR
;
4822 Tcl_AppendResult(interp
, zBuf
, 0);
4827 ** Usage: sqlite3_open_v2 FILENAME FLAGS VFS
4829 static int SQLITE_TCLAPI
test_open_v2(
4833 Tcl_Obj
*CONST objv
[]
4835 const char *zFilename
;
4847 Tcl_WrongNumArgs(interp
, 1, objv
, "FILENAME FLAGS VFS");
4850 zFilename
= Tcl_GetString(objv
[1]);
4851 zVfs
= Tcl_GetString(objv
[3]);
4852 if( zVfs
[0]==0x00 ) zVfs
= 0;
4854 rc
= Tcl_ListObjGetElements(interp
, objv
[2], &nFlag
, &apFlag
);
4855 if( rc
!=TCL_OK
) return rc
;
4856 for(i
=0; i
<nFlag
; i
++){
4862 { "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY
},
4863 { "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE
},
4864 { "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE
},
4865 { "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE
},
4866 { "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE
},
4867 { "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY
},
4868 { "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB
},
4869 { "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB
},
4870 { "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB
},
4871 { "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL
},
4872 { "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL
},
4873 { "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL
},
4874 { "SQLITE_OPEN_SUPER_JOURNAL", SQLITE_OPEN_SUPER_JOURNAL
},
4875 { "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX
},
4876 { "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX
},
4877 { "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE
},
4878 { "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE
},
4879 { "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL
},
4880 { "SQLITE_OPEN_URI", SQLITE_OPEN_URI
},
4883 rc
= Tcl_GetIndexFromObjStruct(interp
, apFlag
[i
], aFlag
, sizeof(aFlag
[0]),
4886 if( rc
!=TCL_OK
) return rc
;
4887 flags
|= aFlag
[iFlag
].flag
;
4890 rc
= sqlite3_open_v2(zFilename
, &db
, flags
, zVfs
);
4891 if( sqlite3TestMakePointerStr(interp
, zBuf
, db
) ) return TCL_ERROR
;
4892 Tcl_AppendResult(interp
, zBuf
, 0);
4897 ** Usage: sqlite3_open16 filename options
4899 static int SQLITE_TCLAPI
test_open16(
4903 Tcl_Obj
*CONST objv
[]
4905 #ifndef SQLITE_OMIT_UTF16
4906 const void *zFilename
;
4911 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4912 Tcl_GetString(objv
[0]), " filename options-list", 0);
4916 zFilename
= Tcl_GetByteArrayFromObj(objv
[1], 0);
4917 sqlite3_open16(zFilename
, &db
);
4919 if( sqlite3TestMakePointerStr(interp
, zBuf
, db
) ) return TCL_ERROR
;
4920 Tcl_AppendResult(interp
, zBuf
, 0);
4921 #endif /* SQLITE_OMIT_UTF16 */
4926 ** Usage: sqlite3_complete16 <UTF-16 string>
4928 ** Return 1 if the supplied argument is a complete SQL statement, or zero
4931 static int SQLITE_TCLAPI
test_complete16(
4935 Tcl_Obj
*CONST objv
[]
4937 #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16)
4941 Tcl_WrongNumArgs(interp
, 1, objv
, "<utf-16 sql>");
4945 zBuf
= (char*)Tcl_GetByteArrayFromObj(objv
[1], 0);
4946 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_complete16(zBuf
)));
4947 #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */
4952 ** Usage: sqlite3_normalize SQL
4954 ** Return the normalized value for an SQL statement.
4956 static int SQLITE_TCLAPI
test_normalize(
4960 Tcl_Obj
*CONST objv
[]
4964 extern char *sqlite3_normalize(const char*);
4967 Tcl_WrongNumArgs(interp
, 1, objv
, "SQL");
4971 zSql
= (char*)Tcl_GetString(objv
[1]);
4972 zNorm
= sqlite3_normalize(zSql
);
4974 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zNorm
, -1));
4975 sqlite3_free(zNorm
);
4981 ** Usage: sqlite3_step STMT
4983 ** Advance the statement to the next row.
4985 static int SQLITE_TCLAPI
test_step(
4989 Tcl_Obj
*CONST objv
[]
4991 sqlite3_stmt
*pStmt
;
4995 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4996 Tcl_GetString(objv
[0]), " STMT", 0);
5000 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5001 rc
= sqlite3_step(pStmt
);
5003 /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */
5004 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), 0);
5008 static int SQLITE_TCLAPI
test_sql(
5012 Tcl_Obj
*CONST objv
[]
5014 sqlite3_stmt
*pStmt
;
5017 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
5021 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5022 Tcl_SetResult(interp
, (char *)sqlite3_sql(pStmt
), TCL_VOLATILE
);
5025 static int SQLITE_TCLAPI
test_ex_sql(
5029 Tcl_Obj
*CONST objv
[]
5031 sqlite3_stmt
*pStmt
;
5035 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
5039 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5040 z
= sqlite3_expanded_sql(pStmt
);
5041 Tcl_SetResult(interp
, z
, TCL_VOLATILE
);
5045 #ifdef SQLITE_ENABLE_NORMALIZE
5046 static int SQLITE_TCLAPI
test_norm_sql(
5050 Tcl_Obj
*CONST objv
[]
5052 sqlite3_stmt
*pStmt
;
5055 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
5059 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5060 Tcl_SetResult(interp
, (char *)sqlite3_normalized_sql(pStmt
), TCL_VOLATILE
);
5063 #endif /* SQLITE_ENABLE_NORMALIZE */
5066 ** Usage: sqlite3_column_count STMT
5068 ** Return the number of columns returned by the sql statement STMT.
5070 static int SQLITE_TCLAPI
test_column_count(
5074 Tcl_Obj
*CONST objv
[]
5076 sqlite3_stmt
*pStmt
;
5079 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5080 Tcl_GetString(objv
[0]), " STMT column", 0);
5084 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5086 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_column_count(pStmt
)));
5091 ** Usage: sqlite3_column_type STMT column
5093 ** Return the type of the data in column 'column' of the current row.
5095 static int SQLITE_TCLAPI
test_column_type(
5099 Tcl_Obj
*CONST objv
[]
5101 sqlite3_stmt
*pStmt
;
5106 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5107 Tcl_GetString(objv
[0]), " STMT column", 0);
5111 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5112 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5114 tp
= sqlite3_column_type(pStmt
, col
);
5116 case SQLITE_INTEGER
:
5117 Tcl_SetResult(interp
, "INTEGER", TCL_STATIC
);
5120 Tcl_SetResult(interp
, "NULL", TCL_STATIC
);
5123 Tcl_SetResult(interp
, "FLOAT", TCL_STATIC
);
5126 Tcl_SetResult(interp
, "TEXT", TCL_STATIC
);
5129 Tcl_SetResult(interp
, "BLOB", TCL_STATIC
);
5139 ** Usage: sqlite3_column_int64 STMT column
5141 ** Return the data in column 'column' of the current row cast as an
5142 ** wide (64-bit) integer.
5144 static int SQLITE_TCLAPI
test_column_int64(
5148 Tcl_Obj
*CONST objv
[]
5150 sqlite3_stmt
*pStmt
;
5155 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5156 Tcl_GetString(objv
[0]), " STMT column", 0);
5160 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5161 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5163 iVal
= sqlite3_column_int64(pStmt
, col
);
5164 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(iVal
));
5169 ** Usage: sqlite3_column_blob STMT column
5171 static int SQLITE_TCLAPI
test_column_blob(
5175 Tcl_Obj
*CONST objv
[]
5177 sqlite3_stmt
*pStmt
;
5184 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5185 Tcl_GetString(objv
[0]), " STMT column", 0);
5189 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5190 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5192 len
= sqlite3_column_bytes(pStmt
, col
);
5193 pBlob
= sqlite3_column_blob(pStmt
, col
);
5194 Tcl_SetObjResult(interp
, Tcl_NewByteArrayObj(pBlob
, len
));
5199 ** Usage: sqlite3_column_double STMT column
5201 ** Return the data in column 'column' of the current row cast as a double.
5203 static int SQLITE_TCLAPI
test_column_double(
5207 Tcl_Obj
*CONST objv
[]
5209 sqlite3_stmt
*pStmt
;
5214 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5215 Tcl_GetString(objv
[0]), " STMT column", 0);
5219 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5220 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5222 rVal
= sqlite3_column_double(pStmt
, col
);
5223 Tcl_SetObjResult(interp
, Tcl_NewDoubleObj(rVal
));
5228 ** Usage: sqlite3_data_count STMT
5230 ** Return the number of columns returned by the sql statement STMT.
5232 static int SQLITE_TCLAPI
test_data_count(
5236 Tcl_Obj
*CONST objv
[]
5238 sqlite3_stmt
*pStmt
;
5241 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5242 Tcl_GetString(objv
[0]), " STMT column", 0);
5246 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5248 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_data_count(pStmt
)));
5253 ** Usage: sqlite3_column_text STMT column
5255 ** Usage: sqlite3_column_decltype STMT column
5257 ** Usage: sqlite3_column_name STMT column
5259 static int SQLITE_TCLAPI
test_stmt_utf8(
5260 void * clientData
, /* Pointer to SQLite API function to be invoke */
5263 Tcl_Obj
*CONST objv
[]
5265 sqlite3_stmt
*pStmt
;
5267 const char *(*xFunc
)(sqlite3_stmt
*, int);
5270 xFunc
= (const char *(*)(sqlite3_stmt
*, int))clientData
;
5272 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5273 Tcl_GetString(objv
[0]), " STMT column", 0);
5277 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5278 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5279 zRet
= xFunc(pStmt
, col
);
5281 Tcl_SetResult(interp
, (char *)zRet
, 0);
5286 static int SQLITE_TCLAPI
test_global_recover(
5290 Tcl_Obj
*CONST objv
[]
5292 #ifndef SQLITE_OMIT_DEPRECATED
5295 Tcl_WrongNumArgs(interp
, 1, objv
, "");
5298 rc
= sqlite3_global_recover();
5299 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
5305 ** Usage: sqlite3_column_text STMT column
5307 ** Usage: sqlite3_column_decltype STMT column
5309 ** Usage: sqlite3_column_name STMT column
5311 static int SQLITE_TCLAPI
test_stmt_utf16(
5312 void * clientData
, /* Pointer to SQLite API function to be invoked */
5315 Tcl_Obj
*CONST objv
[]
5317 #ifndef SQLITE_OMIT_UTF16
5318 sqlite3_stmt
*pStmt
;
5321 const void *zName16
;
5322 const void *(*xFunc
)(sqlite3_stmt
*, int);
5324 xFunc
= (const void *(*)(sqlite3_stmt
*, int))clientData
;
5326 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5327 Tcl_GetString(objv
[0]), " STMT column", 0);
5331 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5332 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5334 zName16
= xFunc(pStmt
, col
);
5337 const char *z
= zName16
;
5338 for(n
=0; z
[n
] || z
[n
+1]; n
+=2){}
5339 pRet
= Tcl_NewByteArrayObj(zName16
, n
+2);
5340 Tcl_SetObjResult(interp
, pRet
);
5342 #endif /* SQLITE_OMIT_UTF16 */
5348 ** Usage: sqlite3_column_int STMT column
5350 ** Usage: sqlite3_column_bytes STMT column
5352 ** Usage: sqlite3_column_bytes16 STMT column
5355 static int SQLITE_TCLAPI
test_stmt_int(
5356 void * clientData
, /* Pointer to SQLite API function to be invoked */
5359 Tcl_Obj
*CONST objv
[]
5361 sqlite3_stmt
*pStmt
;
5363 int (*xFunc
)(sqlite3_stmt
*, int);
5365 xFunc
= (int (*)(sqlite3_stmt
*, int))clientData
;
5367 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5368 Tcl_GetString(objv
[0]), " STMT column", 0);
5372 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5373 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5375 Tcl_SetObjResult(interp
, Tcl_NewIntObj(xFunc(pStmt
, col
)));
5380 ** Usage: sqlite_set_magic DB MAGIC-NUMBER
5382 ** Set the db->magic value. This is used to test error recovery logic.
5384 static int SQLITE_TCLAPI
sqlite_set_magic(
5392 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5396 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5397 if( strcmp(argv
[2], "SQLITE_MAGIC_OPEN")==0 ){
5398 db
->magic
= SQLITE_MAGIC_OPEN
;
5399 }else if( strcmp(argv
[2], "SQLITE_MAGIC_CLOSED")==0 ){
5400 db
->magic
= SQLITE_MAGIC_CLOSED
;
5401 }else if( strcmp(argv
[2], "SQLITE_MAGIC_BUSY")==0 ){
5402 db
->magic
= SQLITE_MAGIC_BUSY
;
5403 }else if( strcmp(argv
[2], "SQLITE_MAGIC_ERROR")==0 ){
5404 db
->magic
= SQLITE_MAGIC_ERROR
;
5405 }else if( Tcl_GetInt(interp
, argv
[2], (int*)&db
->magic
) ){
5412 ** Usage: sqlite3_interrupt DB
5414 ** Trigger an interrupt on DB
5416 static int SQLITE_TCLAPI
test_interrupt(
5424 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0], " DB", 0);
5427 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5428 sqlite3_interrupt(db
);
5433 ** Usage: sqlite_delete_function DB function-name
5435 ** Delete the user function 'function-name' from database handle DB. It
5436 ** is assumed that the user function was created as UTF8, any number of
5437 ** arguments (the way the TCL interface does it).
5439 static int SQLITE_TCLAPI
delete_function(
5448 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5449 " DB function-name", 0);
5452 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5453 rc
= sqlite3_create_function(db
, argv
[2], -1, SQLITE_UTF8
, 0, 0, 0, 0);
5454 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
5459 ** Usage: sqlite_delete_collation DB collation-name
5461 ** Delete the collation sequence 'collation-name' from database handle
5462 ** DB. It is assumed that the collation sequence was created as UTF8 (the
5463 ** way the TCL interface does it).
5465 static int SQLITE_TCLAPI
delete_collation(
5474 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5475 " DB function-name", 0);
5478 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5479 rc
= sqlite3_create_collation(db
, argv
[2], SQLITE_UTF8
, 0, 0);
5480 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
5485 ** Usage: sqlite3_get_autocommit DB
5487 ** Return true if the database DB is currently in auto-commit mode.
5488 ** Return false if not.
5490 static int SQLITE_TCLAPI
get_autocommit(
5499 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5503 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5504 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", sqlite3_get_autocommit(db
));
5505 Tcl_AppendResult(interp
, zBuf
, 0);
5510 ** Usage: sqlite3_busy_timeout DB MS
5512 ** Set the busy timeout. This is more easily done using the timeout
5513 ** method of the TCL interface. But we need a way to test the case
5514 ** where it returns SQLITE_MISUSE.
5516 static int SQLITE_TCLAPI
test_busy_timeout(
5525 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5529 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5530 if( Tcl_GetInt(interp
, argv
[2], &ms
) ) return TCL_ERROR
;
5531 rc
= sqlite3_busy_timeout(db
, ms
);
5532 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
5537 ** Usage: tcl_variable_type VARIABLENAME
5539 ** Return the name of the internal representation for the
5540 ** value of the given variable.
5542 static int SQLITE_TCLAPI
tcl_variable_type(
5546 Tcl_Obj
*CONST objv
[]
5550 Tcl_WrongNumArgs(interp
, 1, objv
, "VARIABLE");
5553 pVar
= Tcl_GetVar2Ex(interp
, Tcl_GetString(objv
[1]), 0, TCL_LEAVE_ERR_MSG
);
5554 if( pVar
==0 ) return TCL_ERROR
;
5555 if( pVar
->typePtr
){
5556 Tcl_SetObjResult(interp
, Tcl_NewStringObj(pVar
->typePtr
->name
, -1));
5562 ** Usage: sqlite3_release_memory ?N?
5564 ** Attempt to release memory currently held but not actually required.
5565 ** The integer N is the number of bytes we are trying to release. The
5566 ** return value is the amount of memory actually released.
5568 static int SQLITE_TCLAPI
test_release_memory(
5572 Tcl_Obj
*CONST objv
[]
5574 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
5577 if( objc
!=1 && objc
!=2 ){
5578 Tcl_WrongNumArgs(interp
, 1, objv
, "?N?");
5582 if( Tcl_GetIntFromObj(interp
, objv
[1], &N
) ) return TCL_ERROR
;
5586 amt
= sqlite3_release_memory(N
);
5587 Tcl_SetObjResult(interp
, Tcl_NewIntObj(amt
));
5594 ** Usage: sqlite3_db_release_memory DB
5596 ** Attempt to release memory currently held by database DB. Return the
5597 ** result code (which in the current implementation is always zero).
5599 static int SQLITE_TCLAPI
test_db_release_memory(
5603 Tcl_Obj
*CONST objv
[]
5608 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
5611 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5612 rc
= sqlite3_db_release_memory(db
);
5613 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
5618 ** Usage: sqlite3_db_cacheflush DB
5620 ** Attempt to flush any dirty pages to disk.
5622 static int SQLITE_TCLAPI
test_db_cacheflush(
5626 Tcl_Obj
*CONST objv
[]
5631 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
5634 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5635 rc
= sqlite3_db_cacheflush(db
);
5637 Tcl_SetResult(interp
, (char *)sqlite3ErrStr(rc
), TCL_STATIC
);
5641 Tcl_ResetResult(interp
);
5646 ** Usage: sqlite3_system_errno DB
5648 ** Return the low-level system errno value.
5650 static int SQLITE_TCLAPI
test_system_errno(
5654 Tcl_Obj
*CONST objv
[]
5659 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
5662 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5663 iErrno
= sqlite3_system_errno(db
);
5664 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iErrno
));
5669 ** Usage: sqlite3_db_filename DB DBNAME
5671 ** Return the name of a file associated with a database.
5673 static int SQLITE_TCLAPI
test_db_filename(
5677 Tcl_Obj
*CONST objv
[]
5680 const char *zDbName
;
5682 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
5685 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5686 zDbName
= Tcl_GetString(objv
[2]);
5687 Tcl_AppendResult(interp
, sqlite3_db_filename(db
, zDbName
), (void*)0);
5692 ** Usage: sqlite3_db_readonly DB DBNAME
5694 ** Return 1 or 0 if DBNAME is readonly or not. Return -1 if DBNAME does
5697 static int SQLITE_TCLAPI
test_db_readonly(
5701 Tcl_Obj
*CONST objv
[]
5704 const char *zDbName
;
5706 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
5709 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5710 zDbName
= Tcl_GetString(objv
[2]);
5711 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_db_readonly(db
, zDbName
)));
5716 ** Usage: sqlite3_soft_heap_limit ?N?
5718 ** Query or set the soft heap limit for the current thread. The
5719 ** limit is only changed if the N is present. The previous limit
5722 static int SQLITE_TCLAPI
test_soft_heap_limit(
5726 Tcl_Obj
*CONST objv
[]
5730 if( objc
!=1 && objc
!=2 ){
5731 Tcl_WrongNumArgs(interp
, 1, objv
, "?N?");
5735 if( Tcl_GetWideIntFromObj(interp
, objv
[1], &N
) ) return TCL_ERROR
;
5737 amt
= sqlite3_soft_heap_limit64(N
);
5738 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(amt
));
5743 ** Usage: sqlite3_hard_heap_limit ?N?
5745 ** Query or set the hard heap limit for the current thread. The
5746 ** limit is only changed if the N is present. The previous limit
5749 static int SQLITE_TCLAPI
test_hard_heap_limit(
5753 Tcl_Obj
*CONST objv
[]
5757 if( objc
!=1 && objc
!=2 ){
5758 Tcl_WrongNumArgs(interp
, 1, objv
, "?N?");
5762 if( Tcl_GetWideIntFromObj(interp
, objv
[1], &N
) ) return TCL_ERROR
;
5764 amt
= sqlite3_hard_heap_limit64(N
);
5765 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(amt
));
5770 ** Usage: sqlite3_thread_cleanup
5772 ** Call the sqlite3_thread_cleanup API.
5774 static int SQLITE_TCLAPI
test_thread_cleanup(
5778 Tcl_Obj
*CONST objv
[]
5780 #ifndef SQLITE_OMIT_DEPRECATED
5781 sqlite3_thread_cleanup();
5787 ** Usage: sqlite3_pager_refcounts DB
5789 ** Return a list of numbers which are the PagerRefcount for all
5790 ** pagers on each database connection.
5792 static int SQLITE_TCLAPI
test_pager_refcounts(
5796 Tcl_Obj
*CONST objv
[]
5804 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5805 Tcl_GetStringFromObj(objv
[0], 0), " DB", 0);
5808 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5809 pResult
= Tcl_NewObj();
5810 for(i
=0; i
<db
->nDb
; i
++){
5811 if( db
->aDb
[i
].pBt
==0 ){
5814 sqlite3_mutex_enter(db
->mutex
);
5815 a
= sqlite3PagerStats(sqlite3BtreePager(db
->aDb
[i
].pBt
));
5817 sqlite3_mutex_leave(db
->mutex
);
5819 Tcl_ListObjAppendElement(0, pResult
, Tcl_NewIntObj(v
));
5821 Tcl_SetObjResult(interp
, pResult
);
5827 ** tclcmd: working_64bit_int
5829 ** Some TCL builds (ex: cygwin) do not support 64-bit integers. This
5830 ** leads to a number of test failures. The present command checks the
5831 ** TCL build to see whether or not it supports 64-bit integers. It
5832 ** returns TRUE if it does and FALSE if not.
5834 ** This command is used to warn users that their TCL build is defective
5835 ** and that the errors they are seeing in the test scripts might be
5836 ** a result of their defective TCL rather than problems in SQLite.
5838 static int SQLITE_TCLAPI
working_64bit_int(
5839 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
5840 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
5841 int objc
, /* Number of arguments */
5842 Tcl_Obj
*CONST objv
[] /* Command arguments */
5847 pTestObj
= Tcl_NewWideIntObj(1000000*(i64
)1234567890);
5848 working
= strcmp(Tcl_GetString(pTestObj
), "1234567890000000")==0;
5849 Tcl_DecrRefCount(pTestObj
);
5850 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(working
));
5856 ** tclcmd: vfs_unlink_test
5858 ** This TCL command unregisters the primary VFS and then registers
5859 ** it back again. This is used to test the ability to register a
5860 ** VFS when none are previously registered, and the ability to
5861 ** unregister the only available VFS. Ticket #2738
5863 static int SQLITE_TCLAPI
vfs_unlink_test(
5864 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
5865 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
5866 int objc
, /* Number of arguments */
5867 Tcl_Obj
*CONST objv
[] /* Command arguments */
5871 sqlite3_vfs
*apVfs
[20];
5872 sqlite3_vfs one
, two
;
5874 sqlite3_vfs_unregister(0); /* Unregister of NULL is harmless */
5875 one
.zName
= "__one";
5876 two
.zName
= "__two";
5878 /* Calling sqlite3_vfs_register with 2nd argument of 0 does not
5879 ** change the default VFS
5881 pMain
= sqlite3_vfs_find(0);
5882 sqlite3_vfs_register(&one
, 0);
5883 assert( pMain
==0 || pMain
==sqlite3_vfs_find(0) );
5884 sqlite3_vfs_register(&two
, 0);
5885 assert( pMain
==0 || pMain
==sqlite3_vfs_find(0) );
5887 /* We can find a VFS by its name */
5888 assert( sqlite3_vfs_find("__one")==&one
);
5889 assert( sqlite3_vfs_find("__two")==&two
);
5891 /* Calling sqlite_vfs_register with non-zero second parameter changes the
5892 ** default VFS, even if the 1st parameter is an existig VFS that is
5893 ** previously registered as the non-default.
5895 sqlite3_vfs_register(&one
, 1);
5896 assert( sqlite3_vfs_find("__one")==&one
);
5897 assert( sqlite3_vfs_find("__two")==&two
);
5898 assert( sqlite3_vfs_find(0)==&one
);
5899 sqlite3_vfs_register(&two
, 1);
5900 assert( sqlite3_vfs_find("__one")==&one
);
5901 assert( sqlite3_vfs_find("__two")==&two
);
5902 assert( sqlite3_vfs_find(0)==&two
);
5904 sqlite3_vfs_register(pMain
, 1);
5905 assert( sqlite3_vfs_find("__one")==&one
);
5906 assert( sqlite3_vfs_find("__two")==&two
);
5907 assert( sqlite3_vfs_find(0)==pMain
);
5910 /* Unlink the default VFS. Repeat until there are no more VFSes
5913 for(i
=0; i
<sizeof(apVfs
)/sizeof(apVfs
[0]); i
++){
5914 apVfs
[i
] = sqlite3_vfs_find(0);
5916 assert( apVfs
[i
]==sqlite3_vfs_find(apVfs
[i
]->zName
) );
5917 sqlite3_vfs_unregister(apVfs
[i
]);
5918 assert( 0==sqlite3_vfs_find(apVfs
[i
]->zName
) );
5921 assert( 0==sqlite3_vfs_find(0) );
5923 /* Register the main VFS as non-default (will be made default, since
5924 ** it'll be the only one in existence).
5926 sqlite3_vfs_register(pMain
, 0);
5927 assert( sqlite3_vfs_find(0)==pMain
);
5929 /* Un-register the main VFS again to restore an empty VFS list */
5930 sqlite3_vfs_unregister(pMain
);
5931 assert( 0==sqlite3_vfs_find(0) );
5933 /* Relink all VFSes in reverse order. */
5934 for(i
=sizeof(apVfs
)/sizeof(apVfs
[0])-1; i
>=0; i
--){
5936 sqlite3_vfs_register(apVfs
[i
], 1);
5937 assert( apVfs
[i
]==sqlite3_vfs_find(0) );
5938 assert( apVfs
[i
]==sqlite3_vfs_find(apVfs
[i
]->zName
) );
5942 /* Unregister out sample VFSes. */
5943 sqlite3_vfs_unregister(&one
);
5944 sqlite3_vfs_unregister(&two
);
5946 /* Unregistering a VFS that is not currently registered is harmless */
5947 sqlite3_vfs_unregister(&one
);
5948 sqlite3_vfs_unregister(&two
);
5949 assert( sqlite3_vfs_find("__one")==0 );
5950 assert( sqlite3_vfs_find("__two")==0 );
5952 /* We should be left with the original default VFS back as the
5954 assert( sqlite3_vfs_find(0)==pMain
);
5960 ** tclcmd: vfs_initfail_test
5962 ** This TCL command attempts to vfs_find and vfs_register when the
5963 ** sqlite3_initialize() interface is failing. All calls should fail.
5965 static int SQLITE_TCLAPI
vfs_initfail_test(
5966 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
5967 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
5968 int objc
, /* Number of arguments */
5969 Tcl_Obj
*CONST objv
[] /* Command arguments */
5972 one
.zName
= "__one";
5974 if( sqlite3_vfs_find(0) ) return TCL_ERROR
;
5975 sqlite3_vfs_register(&one
, 0);
5976 if( sqlite3_vfs_find(0) ) return TCL_ERROR
;
5977 sqlite3_vfs_register(&one
, 1);
5978 if( sqlite3_vfs_find(0) ) return TCL_ERROR
;
5985 static sqlite3_vfs
*apVfs
[20];
5986 static int nVfs
= 0;
5989 ** tclcmd: vfs_unregister_all
5991 ** Unregister all VFSes.
5993 static int SQLITE_TCLAPI
vfs_unregister_all(
5994 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
5995 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
5996 int objc
, /* Number of arguments */
5997 Tcl_Obj
*CONST objv
[] /* Command arguments */
6000 for(i
=0; i
<ArraySize(apVfs
); i
++){
6001 apVfs
[i
] = sqlite3_vfs_find(0);
6002 if( apVfs
[i
]==0 ) break;
6003 sqlite3_vfs_unregister(apVfs
[i
]);
6009 ** tclcmd: vfs_reregister_all
6011 ** Restore all VFSes that were removed using vfs_unregister_all. Taking
6012 ** care to put the linked list back together in the same order as it was
6013 ** in before vfs_unregister_all was invoked.
6015 static int SQLITE_TCLAPI
vfs_reregister_all(
6016 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6017 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6018 int objc
, /* Number of arguments */
6019 Tcl_Obj
*CONST objv
[] /* Command arguments */
6022 for(i
=nVfs
-1; i
>=0; i
--){
6023 sqlite3_vfs_register(apVfs
[i
], 1);
6030 ** tclcmd: file_control_test DB
6032 ** This TCL command runs the sqlite3_file_control interface and
6033 ** verifies correct operation of the same.
6035 static int SQLITE_TCLAPI
file_control_test(
6036 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6037 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6038 int objc
, /* Number of arguments */
6039 Tcl_Obj
*CONST objv
[] /* Command arguments */
6046 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6047 Tcl_GetStringFromObj(objv
[0], 0), " DB", 0);
6050 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6051 rc
= sqlite3_file_control(db
, 0, 0, &iArg
);
6052 assert( rc
==SQLITE_NOTFOUND
);
6053 rc
= sqlite3_file_control(db
, "notadatabase", SQLITE_FCNTL_LOCKSTATE
, &iArg
);
6054 assert( rc
==SQLITE_ERROR
);
6055 rc
= sqlite3_file_control(db
, "main", -1, &iArg
);
6056 assert( rc
==SQLITE_NOTFOUND
);
6057 rc
= sqlite3_file_control(db
, "temp", -1, &iArg
);
6058 assert( rc
==SQLITE_NOTFOUND
|| rc
==SQLITE_ERROR
);
6065 ** tclcmd: file_control_lasterrno_test DB
6067 ** This TCL command runs the sqlite3_file_control interface and
6068 ** verifies correct operation of the SQLITE_LAST_ERRNO verb.
6070 static int SQLITE_TCLAPI
file_control_lasterrno_test(
6071 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6072 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6073 int objc
, /* Number of arguments */
6074 Tcl_Obj
*CONST objv
[] /* Command arguments */
6081 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6082 Tcl_GetStringFromObj(objv
[0], 0), " DB", 0);
6085 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6088 rc
= sqlite3_file_control(db
, NULL
, SQLITE_LAST_ERRNO
, &iArg
);
6090 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6094 Tcl_AppendResult(interp
, "Unexpected non-zero errno: ",
6095 Tcl_GetStringFromObj(Tcl_NewIntObj(iArg
), 0), " ", 0);
6102 ** tclcmd: file_control_data_version DB DBNAME
6104 ** This TCL command runs the sqlite3_file_control with the
6105 ** SQLITE_FCNTL_DATA_VERSION opcode, returning the result.
6107 static int SQLITE_TCLAPI
file_control_data_version(
6108 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6109 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6110 int objc
, /* Number of arguments */
6111 Tcl_Obj
*CONST objv
[] /* Command arguments */
6113 unsigned int iVers
; /* data version */
6114 char *zDb
; /* Db name ("main", "temp" etc.) */
6115 sqlite3
*db
; /* Database handle */
6116 int rc
; /* file_control() return code */
6119 if( objc
!=3 && objc
!=2 ){
6120 Tcl_WrongNumArgs(interp
, 1, objv
, "DB [DBNAME]");
6123 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6126 zDb
= objc
==3 ? Tcl_GetString(objv
[2]) : NULL
;
6128 rc
= sqlite3_file_control(db
, zDb
, SQLITE_FCNTL_DATA_VERSION
, (void *)&iVers
);
6130 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_STATIC
);
6133 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"%u",iVers
);
6134 Tcl_SetResult(interp
, (char *)zBuf
, TCL_VOLATILE
);
6140 ** tclcmd: file_control_chunksize_test DB DBNAME SIZE
6142 ** This TCL command runs the sqlite3_file_control interface and
6143 ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
6144 ** SQLITE_SET_LOCKPROXYFILE verbs.
6146 static int SQLITE_TCLAPI
file_control_chunksize_test(
6147 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6148 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6149 int objc
, /* Number of arguments */
6150 Tcl_Obj
*CONST objv
[] /* Command arguments */
6152 int nSize
; /* New chunk size */
6153 char *zDb
; /* Db name ("main", "temp" etc.) */
6154 sqlite3
*db
; /* Database handle */
6155 int rc
; /* file_control() return code */
6158 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME SIZE");
6161 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
)
6162 || Tcl_GetIntFromObj(interp
, objv
[3], &nSize
)
6166 zDb
= Tcl_GetString(objv
[2]);
6167 if( zDb
[0]=='\0' ) zDb
= NULL
;
6169 rc
= sqlite3_file_control(db
, zDb
, SQLITE_FCNTL_CHUNK_SIZE
, (void *)&nSize
);
6171 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_STATIC
);
6178 ** tclcmd: file_control_sizehint_test DB DBNAME SIZE
6180 ** This TCL command runs the sqlite3_file_control interface
6181 ** with SQLITE_FCNTL_SIZE_HINT
6183 static int SQLITE_TCLAPI
file_control_sizehint_test(
6184 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6185 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6186 int objc
, /* Number of arguments */
6187 Tcl_Obj
*CONST objv
[] /* Command arguments */
6189 Tcl_WideInt nSize
; /* Hinted size */
6190 char *zDb
; /* Db name ("main", "temp" etc.) */
6191 sqlite3
*db
; /* Database handle */
6192 int rc
; /* file_control() return code */
6195 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME SIZE");
6198 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
)
6199 || Tcl_GetWideIntFromObj(interp
, objv
[3], &nSize
)
6203 zDb
= Tcl_GetString(objv
[2]);
6204 if( zDb
[0]=='\0' ) zDb
= NULL
;
6206 rc
= sqlite3_file_control(db
, zDb
, SQLITE_FCNTL_SIZE_HINT
, (void *)&nSize
);
6208 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_STATIC
);
6215 ** tclcmd: file_control_lockproxy_test DB PWD
6217 ** This TCL command runs the sqlite3_file_control interface and
6218 ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
6219 ** SQLITE_SET_LOCKPROXYFILE verbs.
6221 static int SQLITE_TCLAPI
file_control_lockproxy_test(
6222 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6223 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6224 int objc
, /* Number of arguments */
6225 Tcl_Obj
*CONST objv
[] /* Command arguments */
6230 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6231 Tcl_GetStringFromObj(objv
[0], 0), " DB PWD", 0);
6234 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6238 #if !defined(SQLITE_ENABLE_LOCKING_STYLE)
6239 # if defined(__APPLE__)
6240 # define SQLITE_ENABLE_LOCKING_STYLE 1
6242 # define SQLITE_ENABLE_LOCKING_STYLE 0
6245 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
6251 char proxyPath
[400];
6253 zPwd
= Tcl_GetStringFromObj(objv
[2], &nPwd
);
6254 if( sizeof(proxyPath
)<nPwd
+20 ){
6255 Tcl_AppendResult(interp
, "PWD too big", (void*)0);
6258 sqlite3_snprintf(sizeof(proxyPath
), proxyPath
, "%s/test.proxy", zPwd
);
6259 rc
= sqlite3_file_control(db
, NULL
, SQLITE_SET_LOCKPROXYFILE
, proxyPath
);
6261 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6264 rc
= sqlite3_file_control(db
, NULL
, SQLITE_GET_LOCKPROXYFILE
, &testPath
);
6265 if( strncmp(proxyPath
,testPath
,11) ){
6266 Tcl_AppendResult(interp
, "Lock proxy file did not match the "
6267 "previously assigned value", 0);
6271 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6274 rc
= sqlite3_file_control(db
, NULL
, SQLITE_SET_LOCKPROXYFILE
, proxyPath
);
6276 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6286 ** tclcmd: file_control_win32_av_retry DB NRETRY DELAY
6288 ** This TCL command runs the sqlite3_file_control interface with
6289 ** the SQLITE_FCNTL_WIN32_AV_RETRY opcode.
6291 static int SQLITE_TCLAPI
file_control_win32_av_retry(
6292 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6293 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6294 int objc
, /* Number of arguments */
6295 Tcl_Obj
*CONST objv
[] /* Command arguments */
6303 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6304 Tcl_GetStringFromObj(objv
[0], 0), " DB NRETRY DELAY", 0);
6307 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6310 if( Tcl_GetIntFromObj(interp
, objv
[2], &a
[0]) ) return TCL_ERROR
;
6311 if( Tcl_GetIntFromObj(interp
, objv
[3], &a
[1]) ) return TCL_ERROR
;
6312 rc
= sqlite3_file_control(db
, NULL
, SQLITE_FCNTL_WIN32_AV_RETRY
, (void*)a
);
6313 sqlite3_snprintf(sizeof(z
), z
, "%d %d %d", rc
, a
[0], a
[1]);
6314 Tcl_AppendResult(interp
, z
, (char*)0);
6319 ** tclcmd: file_control_win32_get_handle DB
6321 ** This TCL command runs the sqlite3_file_control interface with
6322 ** the SQLITE_FCNTL_WIN32_GET_HANDLE opcode.
6324 static int file_control_win32_get_handle(
6325 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6326 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6327 int objc
, /* Number of arguments */
6328 Tcl_Obj
*CONST objv
[] /* Command arguments */
6332 HANDLE hFile
= NULL
;
6336 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6337 Tcl_GetStringFromObj(objv
[0], 0), " DB", 0);
6340 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6343 rc
= sqlite3_file_control(db
, NULL
, SQLITE_FCNTL_WIN32_GET_HANDLE
,
6345 sqlite3_snprintf(sizeof(z
), z
, "%d %p", rc
, (void*)hFile
);
6346 Tcl_AppendResult(interp
, z
, (char*)0);
6351 ** tclcmd: file_control_win32_set_handle DB HANDLE
6353 ** This TCL command runs the sqlite3_file_control interface with
6354 ** the SQLITE_FCNTL_WIN32_SET_HANDLE opcode.
6356 static int SQLITE_TCLAPI
file_control_win32_set_handle(
6357 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6358 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6359 int objc
, /* Number of arguments */
6360 Tcl_Obj
*CONST objv
[] /* Command arguments */
6364 HANDLE hFile
= NULL
;
6368 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6369 Tcl_GetStringFromObj(objv
[0], 0), " DB HANDLE", 0);
6372 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6375 if( getWin32Handle(interp
, Tcl_GetString(objv
[2]), &hFile
) ){
6378 rc
= sqlite3_file_control(db
, NULL
, SQLITE_FCNTL_WIN32_SET_HANDLE
,
6380 sqlite3_snprintf(sizeof(z
), z
, "%d %p", rc
, (void*)hFile
);
6381 Tcl_AppendResult(interp
, z
, (char*)0);
6387 ** tclcmd: file_control_persist_wal DB PERSIST-FLAG
6389 ** This TCL command runs the sqlite3_file_control interface with
6390 ** the SQLITE_FCNTL_PERSIST_WAL opcode.
6392 static int SQLITE_TCLAPI
file_control_persist_wal(
6393 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6394 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6395 int objc
, /* Number of arguments */
6396 Tcl_Obj
*CONST objv
[] /* Command arguments */
6404 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6405 Tcl_GetStringFromObj(objv
[0], 0), " DB FLAG", 0);
6408 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6411 if( Tcl_GetIntFromObj(interp
, objv
[2], &bPersist
) ) return TCL_ERROR
;
6412 rc
= sqlite3_file_control(db
, NULL
, SQLITE_FCNTL_PERSIST_WAL
, (void*)&bPersist
);
6413 sqlite3_snprintf(sizeof(z
), z
, "%d %d", rc
, bPersist
);
6414 Tcl_AppendResult(interp
, z
, (char*)0);
6419 ** tclcmd: file_control_powersafe_overwrite DB PSOW-FLAG
6421 ** This TCL command runs the sqlite3_file_control interface with
6422 ** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode.
6424 static int SQLITE_TCLAPI
file_control_powersafe_overwrite(
6425 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6426 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6427 int objc
, /* Number of arguments */
6428 Tcl_Obj
*CONST objv
[] /* Command arguments */
6436 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6437 Tcl_GetStringFromObj(objv
[0], 0), " DB FLAG", 0);
6440 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6443 if( Tcl_GetIntFromObj(interp
, objv
[2], &b
) ) return TCL_ERROR
;
6444 rc
= sqlite3_file_control(db
,NULL
,SQLITE_FCNTL_POWERSAFE_OVERWRITE
,(void*)&b
);
6445 sqlite3_snprintf(sizeof(z
), z
, "%d %d", rc
, b
);
6446 Tcl_AppendResult(interp
, z
, (char*)0);
6452 ** tclcmd: file_control_vfsname DB ?AUXDB?
6454 ** Return a string that describes the stack of VFSes.
6456 static int SQLITE_TCLAPI
file_control_vfsname(
6457 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6458 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6459 int objc
, /* Number of arguments */
6460 Tcl_Obj
*CONST objv
[] /* Command arguments */
6463 const char *zDbName
= "main";
6466 if( objc
!=2 && objc
!=3 ){
6467 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6468 Tcl_GetStringFromObj(objv
[0], 0), " DB ?AUXDB?", 0);
6471 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6475 zDbName
= Tcl_GetString(objv
[2]);
6477 sqlite3_file_control(db
, zDbName
, SQLITE_FCNTL_VFSNAME
,(void*)&zVfsName
);
6478 Tcl_AppendResult(interp
, zVfsName
, (char*)0);
6479 sqlite3_free(zVfsName
);
6484 ** tclcmd: file_control_reservebytes DB N
6486 static int SQLITE_TCLAPI
file_control_reservebytes(
6487 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6488 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6489 int objc
, /* Number of arguments */
6490 Tcl_Obj
*CONST objv
[] /* Command arguments */
6493 const char *zDbName
= "main";
6498 Tcl_WrongNumArgs(interp
, 1, objv
, "DB N");
6501 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
)
6502 || Tcl_GetIntFromObj(interp
, objv
[2], &n
)
6507 rc
= sqlite3_file_control(db
, zDbName
, SQLITE_FCNTL_RESERVE_BYTES
, (void*)&n
);
6508 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
6514 ** tclcmd: file_control_tempfilename DB ?AUXDB?
6516 ** Return a string that is a temporary filename
6518 static int SQLITE_TCLAPI
file_control_tempfilename(
6519 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6520 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6521 int objc
, /* Number of arguments */
6522 Tcl_Obj
*CONST objv
[] /* Command arguments */
6525 const char *zDbName
= "main";
6528 if( objc
!=2 && objc
!=3 ){
6529 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6530 Tcl_GetStringFromObj(objv
[0], 0), " DB ?AUXDB?", 0);
6533 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6537 zDbName
= Tcl_GetString(objv
[2]);
6539 sqlite3_file_control(db
, zDbName
, SQLITE_FCNTL_TEMPFILENAME
, (void*)&zTName
);
6540 Tcl_AppendResult(interp
, zTName
, (char*)0);
6541 sqlite3_free(zTName
);
6546 ** tclcmd: file_control_external_reader DB ?AUXDB?
6548 ** Return a string that is a temporary filename
6550 static int SQLITE_TCLAPI
file_control_external_reader(
6551 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6552 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6553 int objc
, /* Number of arguments */
6554 Tcl_Obj
*CONST objv
[] /* Command arguments */
6557 const char *zName
= "main";
6561 if( objc
!=2 && objc
!=3 ){
6562 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6563 Tcl_GetStringFromObj(objv
[0], 0), " DB ?AUXDB?", 0);
6566 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6570 zName
= Tcl_GetString(objv
[2]);
6572 rc
= sqlite3_file_control(db
, zName
, SQLITE_FCNTL_EXTERNAL_READER
, &iRes
);
6573 if( rc
!=SQLITE_OK
){
6574 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
6577 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iRes
));
6583 ** tclcmd: sqlite3_vfs_list
6585 ** Return a tcl list containing the names of all registered vfs's.
6587 static int SQLITE_TCLAPI
vfs_list(
6588 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6589 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6590 int objc
, /* Number of arguments */
6591 Tcl_Obj
*CONST objv
[] /* Command arguments */
6594 Tcl_Obj
*pRet
= Tcl_NewObj();
6596 Tcl_WrongNumArgs(interp
, 1, objv
, "");
6599 for(pVfs
=sqlite3_vfs_find(0); pVfs
; pVfs
=pVfs
->pNext
){
6600 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj(pVfs
->zName
, -1));
6602 Tcl_SetObjResult(interp
, pRet
);
6607 ** tclcmd: sqlite3_limit DB ID VALUE
6609 ** This TCL command runs the sqlite3_limit interface and
6610 ** verifies correct operation of the same.
6612 static int SQLITE_TCLAPI
test_limit(
6613 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6614 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6615 int objc
, /* Number of arguments */
6616 Tcl_Obj
*CONST objv
[] /* Command arguments */
6620 static const struct {
6624 { "SQLITE_LIMIT_LENGTH", SQLITE_LIMIT_LENGTH
},
6625 { "SQLITE_LIMIT_SQL_LENGTH", SQLITE_LIMIT_SQL_LENGTH
},
6626 { "SQLITE_LIMIT_COLUMN", SQLITE_LIMIT_COLUMN
},
6627 { "SQLITE_LIMIT_EXPR_DEPTH", SQLITE_LIMIT_EXPR_DEPTH
},
6628 { "SQLITE_LIMIT_COMPOUND_SELECT", SQLITE_LIMIT_COMPOUND_SELECT
},
6629 { "SQLITE_LIMIT_VDBE_OP", SQLITE_LIMIT_VDBE_OP
},
6630 { "SQLITE_LIMIT_FUNCTION_ARG", SQLITE_LIMIT_FUNCTION_ARG
},
6631 { "SQLITE_LIMIT_ATTACHED", SQLITE_LIMIT_ATTACHED
},
6632 { "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH
},
6633 { "SQLITE_LIMIT_VARIABLE_NUMBER", SQLITE_LIMIT_VARIABLE_NUMBER
},
6634 { "SQLITE_LIMIT_TRIGGER_DEPTH", SQLITE_LIMIT_TRIGGER_DEPTH
},
6635 { "SQLITE_LIMIT_WORKER_THREADS", SQLITE_LIMIT_WORKER_THREADS
},
6637 /* Out of range test cases */
6638 { "SQLITE_LIMIT_TOOSMALL", -1, },
6639 { "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_WORKER_THREADS
+1 },
6646 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6647 Tcl_GetStringFromObj(objv
[0], 0), " DB ID VALUE", 0);
6650 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6651 zId
= Tcl_GetString(objv
[2]);
6652 for(i
=0; i
<sizeof(aId
)/sizeof(aId
[0]); i
++){
6653 if( strcmp(zId
, aId
[i
].zName
)==0 ){
6658 if( i
>=sizeof(aId
)/sizeof(aId
[0]) ){
6659 Tcl_AppendResult(interp
, "unknown limit type: ", zId
, (char*)0);
6662 if( Tcl_GetIntFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
6663 rc
= sqlite3_limit(db
, id
, val
);
6664 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6669 ** tclcmd: save_prng_state
6671 ** Save the state of the pseudo-random number generator.
6672 ** At the same time, verify that sqlite3_test_control works even when
6673 ** called with an out-of-range opcode.
6675 static int SQLITE_TCLAPI
save_prng_state(
6676 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6677 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6678 int objc
, /* Number of arguments */
6679 Tcl_Obj
*CONST objv
[] /* Command arguments */
6681 int rc
= sqlite3_test_control(9999);
6683 rc
= sqlite3_test_control(-1);
6685 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SAVE
);
6689 ** tclcmd: restore_prng_state
6691 static int SQLITE_TCLAPI
restore_prng_state(
6692 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6693 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6694 int objc
, /* Number of arguments */
6695 Tcl_Obj
*CONST objv
[] /* Command arguments */
6697 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESTORE
);
6701 ** tclcmd: reset_prng_state
6703 static int SQLITE_TCLAPI
reset_prng_state(
6704 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6705 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6706 int objc
, /* Number of arguments */
6707 Tcl_Obj
*CONST objv
[] /* Command arguments */
6709 sqlite3_randomness(0,0);
6713 ** tclcmd: prng_seed INT ?DB?
6715 ** Set up the SQLITE_TESTCTRL_PRNG_SEED pragma with parameter INT and DB.
6716 ** INT is an integer. DB is a database connection, or a NULL pointer if
6719 ** When INT!=0 and DB!=0, set the PRNG seed to the value of the schema
6720 ** cookie for DB, or to INT if the schema cookie happens to be zero.
6722 ** When INT!=0 and DB==0, set the PRNG seed to just INT.
6724 ** If INT==0 and DB==0 then use the default procedure of calling the
6725 ** xRandomness method on the default VFS to get the PRNG seed.
6727 static int SQLITE_TCLAPI
prng_seed(
6728 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6729 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6730 int objc
, /* Number of arguments */
6731 Tcl_Obj
*CONST objv
[] /* Command arguments */
6735 if( objc
!=2 && objc
!=3 ){
6736 Tcl_WrongNumArgs(interp
, 1, objv
, "SEED ?DB?");
6739 if( Tcl_GetIntFromObj(interp
,objv
[1],&i
) ) return TCL_ERROR
;
6740 if( objc
==3 && getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ){
6743 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED
, i
, db
);
6748 ** tclcmd: extra_schema_checks BOOLEAN
6750 ** Enable or disable schema checks when parsing the sqlite_schema file.
6751 ** This is always enabled in production, but it is sometimes useful to
6752 ** disable the checks in order to make some internal error states reachable
6755 static int SQLITE_TCLAPI
extra_schema_checks(
6756 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6757 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6758 int objc
, /* Number of arguments */
6759 Tcl_Obj
*CONST objv
[] /* Command arguments */
6763 Tcl_WrongNumArgs(interp
, 1, objv
, "BOOLEAN");
6766 if( Tcl_GetBooleanFromObj(interp
,objv
[1],&i
) ) return TCL_ERROR
;
6767 sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS
, i
);
6772 ** tclcmd: database_may_be_corrupt
6774 ** Indicate that database files might be corrupt. In other words, set the normal
6775 ** state of operation.
6777 static int SQLITE_TCLAPI
database_may_be_corrupt(
6778 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6779 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6780 int objc
, /* Number of arguments */
6781 Tcl_Obj
*CONST objv
[] /* Command arguments */
6783 sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT
, 0);
6787 ** tclcmd: database_never_corrupt
6789 ** Indicate that database files are always well-formed. This enables
6790 ** extra assert() statements that test conditions that are always true
6791 ** for well-formed databases.
6793 static int SQLITE_TCLAPI
database_never_corrupt(
6794 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6795 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6796 int objc
, /* Number of arguments */
6797 Tcl_Obj
*CONST objv
[] /* Command arguments */
6799 sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT
, 1);
6804 ** tclcmd: pcache_stats
6806 static int SQLITE_TCLAPI
test_pcache_stats(
6807 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6808 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6809 int objc
, /* Number of arguments */
6810 Tcl_Obj
*CONST objv
[] /* Command arguments */
6818 sqlite3PcacheStats(&nCurrent
, &nMax
, &nMin
, &nRecyclable
);
6820 pRet
= Tcl_NewObj();
6821 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("current", -1));
6822 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nCurrent
));
6823 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("max", -1));
6824 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nMax
));
6825 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("min", -1));
6826 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nMin
));
6827 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("recyclable", -1));
6828 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nRecyclable
));
6830 Tcl_SetObjResult(interp
, pRet
);
6835 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
6836 static void test_unlock_notify_cb(void **aArg
, int nArg
){
6838 for(ii
=0; ii
<nArg
; ii
++){
6839 Tcl_EvalEx((Tcl_Interp
*)aArg
[ii
], "unlock_notify", -1, TCL_EVAL_GLOBAL
);
6842 #endif /* SQLITE_ENABLE_UNLOCK_NOTIFY */
6845 ** tclcmd: sqlite3_unlock_notify db
6847 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
6848 static int SQLITE_TCLAPI
test_unlock_notify(
6849 ClientData clientData
, /* Unused */
6850 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6851 int objc
, /* Number of arguments */
6852 Tcl_Obj
*CONST objv
[] /* Command arguments */
6858 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
6862 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6865 rc
= sqlite3_unlock_notify(db
, test_unlock_notify_cb
, (void *)interp
);
6866 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
6872 ** tclcmd: sqlite3_wal_checkpoint db ?NAME?
6874 static int SQLITE_TCLAPI
test_wal_checkpoint(
6875 ClientData clientData
, /* Unused */
6876 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6877 int objc
, /* Number of arguments */
6878 Tcl_Obj
*CONST objv
[] /* Command arguments */
6884 if( objc
!=3 && objc
!=2 ){
6885 Tcl_WrongNumArgs(interp
, 1, objv
, "DB ?NAME?");
6889 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6893 zDb
= Tcl_GetString(objv
[2]);
6895 rc
= sqlite3_wal_checkpoint(db
, zDb
);
6896 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
6901 ** tclcmd: sqlite3_wal_checkpoint_v2 db MODE ?NAME?
6903 ** This command calls the wal_checkpoint_v2() function with the specified
6904 ** mode argument (passive, full or restart). If present, the database name
6905 ** NAME is passed as the second argument to wal_checkpoint_v2(). If it the
6906 ** NAME argument is not present, a NULL pointer is passed instead.
6908 ** If wal_checkpoint_v2() returns any value other than SQLITE_BUSY or
6909 ** SQLITE_OK, then this command returns TCL_ERROR. The Tcl result is set
6910 ** to the error message obtained from sqlite3_errmsg().
6912 ** Otherwise, this command returns a list of three integers. The first integer
6913 ** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers
6914 ** are the values returned via the output parameters by wal_checkpoint_v2() -
6915 ** the number of frames in the log and the number of frames in the log
6916 ** that have been checkpointed.
6918 static int SQLITE_TCLAPI
test_wal_checkpoint_v2(
6919 ClientData clientData
, /* Unused */
6920 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6921 int objc
, /* Number of arguments */
6922 Tcl_Obj
*CONST objv
[] /* Command arguments */
6933 const char * aMode
[] = { "passive", "full", "restart", "truncate", 0 };
6934 assert( SQLITE_CHECKPOINT_PASSIVE
==0 );
6935 assert( SQLITE_CHECKPOINT_FULL
==1 );
6936 assert( SQLITE_CHECKPOINT_RESTART
==2 );
6937 assert( SQLITE_CHECKPOINT_TRUNCATE
==3 );
6939 if( objc
!=3 && objc
!=4 ){
6940 Tcl_WrongNumArgs(interp
, 1, objv
, "DB MODE ?NAME?");
6945 zDb
= Tcl_GetString(objv
[3]);
6947 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) || (
6948 TCL_OK
!=Tcl_GetIntFromObj(0, objv
[2], &eMode
)
6949 && TCL_OK
!=Tcl_GetIndexFromObj(interp
, objv
[2], aMode
, "mode", 0, &eMode
)
6954 rc
= sqlite3_wal_checkpoint_v2(db
, zDb
, eMode
, &nLog
, &nCkpt
);
6955 if( rc
!=SQLITE_OK
&& rc
!=SQLITE_BUSY
){
6956 const char *zErrCode
= sqlite3ErrName(rc
);
6957 Tcl_ResetResult(interp
);
6958 Tcl_AppendResult(interp
, zErrCode
, " - ", (char *)sqlite3_errmsg(db
), 0);
6962 pRet
= Tcl_NewObj();
6963 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(rc
==SQLITE_BUSY
?1:0));
6964 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nLog
));
6965 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nCkpt
));
6966 Tcl_SetObjResult(interp
, pRet
);
6972 ** tclcmd: sqlite3_wal_autocheckpoint db VALUE
6974 static int SQLITE_TCLAPI
test_wal_autocheckpoint(
6975 ClientData clientData
, /* Unused */
6976 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6977 int objc
, /* Number of arguments */
6978 Tcl_Obj
*CONST objv
[] /* Command arguments */
6986 Tcl_WrongNumArgs(interp
, 1, objv
, "DB VALUE");
6990 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
)
6991 || Tcl_GetIntFromObj(0, objv
[2], &iVal
)
6996 rc
= sqlite3_wal_autocheckpoint(db
, iVal
);
6997 Tcl_ResetResult(interp
);
6998 if( rc
!=SQLITE_OK
){
6999 const char *zErrCode
= sqlite3ErrName(rc
);
7000 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zErrCode
, -1));
7009 ** tclcmd: test_sqlite3_log ?SCRIPT?
7011 static struct LogCallback
{
7012 Tcl_Interp
*pInterp
;
7014 } logcallback
= {0, 0};
7015 static void xLogcallback(void *unused
, int err
, char *zMsg
){
7016 Tcl_Obj
*pNew
= Tcl_DuplicateObj(logcallback
.pObj
);
7017 Tcl_IncrRefCount(pNew
);
7018 Tcl_ListObjAppendElement(
7019 0, pNew
, Tcl_NewStringObj(sqlite3ErrName(err
), -1)
7021 Tcl_ListObjAppendElement(0, pNew
, Tcl_NewStringObj(zMsg
, -1));
7022 Tcl_EvalObjEx(logcallback
.pInterp
, pNew
, TCL_EVAL_GLOBAL
|TCL_EVAL_DIRECT
);
7023 Tcl_DecrRefCount(pNew
);
7025 static int SQLITE_TCLAPI
test_sqlite3_log(
7026 ClientData clientData
,
7027 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7028 int objc
, /* Number of arguments */
7029 Tcl_Obj
*CONST objv
[] /* Command arguments */
7032 Tcl_WrongNumArgs(interp
, 1, objv
, "SCRIPT");
7035 if( logcallback
.pObj
){
7036 Tcl_DecrRefCount(logcallback
.pObj
);
7037 logcallback
.pObj
= 0;
7038 logcallback
.pInterp
= 0;
7039 sqlite3_config(SQLITE_CONFIG_LOG
, (void*)0, (void*)0);
7042 logcallback
.pObj
= objv
[1];
7043 Tcl_IncrRefCount(logcallback
.pObj
);
7044 logcallback
.pInterp
= interp
;
7045 sqlite3_config(SQLITE_CONFIG_LOG
, xLogcallback
, (void*)0);
7051 ** tcl_objproc COMMANDNAME ARGS...
7053 ** Run a TCL command using its objProc interface. Throw an error if
7054 ** the command has no objProc interface.
7056 static int SQLITE_TCLAPI
runAsObjProc(
7060 Tcl_Obj
*CONST objv
[]
7062 Tcl_CmdInfo cmdInfo
;
7064 Tcl_WrongNumArgs(interp
, 1, objv
, "COMMAND ...");
7067 if( !Tcl_GetCommandInfo(interp
, Tcl_GetString(objv
[1]), &cmdInfo
) ){
7068 Tcl_AppendResult(interp
, "command not found: ",
7069 Tcl_GetString(objv
[1]), (char*)0);
7072 if( cmdInfo
.objProc
==0 ){
7073 Tcl_AppendResult(interp
, "command has no objProc: ",
7074 Tcl_GetString(objv
[1]), (char*)0);
7077 return cmdInfo
.objProc(cmdInfo
.objClientData
, interp
, objc
-1, objv
+1);
7080 #ifndef SQLITE_OMIT_EXPLAIN
7082 ** WARNING: The following function, printExplainQueryPlan() is an exact
7083 ** copy of example code from eqp.in (eqp.html). If this code is modified,
7084 ** then the documentation copy needs to be modified as well.
7087 ** Argument pStmt is a prepared SQL statement. This function compiles
7088 ** an EXPLAIN QUERY PLAN command to report on the prepared statement,
7089 ** and prints the report to stdout using printf().
7091 int printExplainQueryPlan(sqlite3_stmt
*pStmt
){
7092 const char *zSql
; /* Input SQL */
7093 char *zExplain
; /* SQL with EXPLAIN QUERY PLAN prepended */
7094 sqlite3_stmt
*pExplain
; /* Compiled EXPLAIN QUERY PLAN command */
7095 int rc
; /* Return code from sqlite3_prepare_v2() */
7097 zSql
= sqlite3_sql(pStmt
);
7098 if( zSql
==0 ) return SQLITE_ERROR
;
7100 zExplain
= sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zSql
);
7101 if( zExplain
==0 ) return SQLITE_NOMEM
;
7103 rc
= sqlite3_prepare_v2(sqlite3_db_handle(pStmt
), zExplain
, -1, &pExplain
, 0);
7104 sqlite3_free(zExplain
);
7105 if( rc
!=SQLITE_OK
) return rc
;
7107 while( SQLITE_ROW
==sqlite3_step(pExplain
) ){
7108 int iSelectid
= sqlite3_column_int(pExplain
, 0);
7109 int iOrder
= sqlite3_column_int(pExplain
, 1);
7110 int iFrom
= sqlite3_column_int(pExplain
, 2);
7111 const char *zDetail
= (const char *)sqlite3_column_text(pExplain
, 3);
7113 printf("%d %d %d %s\n", iSelectid
, iOrder
, iFrom
, zDetail
);
7116 return sqlite3_finalize(pExplain
);
7119 static int SQLITE_TCLAPI
test_print_eqp(
7123 Tcl_Obj
*CONST objv
[]
7126 sqlite3_stmt
*pStmt
;
7129 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
7132 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
7133 rc
= printExplainQueryPlan(pStmt
);
7134 /* This is needed on Windows so that a test case using this
7135 ** function can open a read pipe and get the output of
7136 ** printExplainQueryPlan() immediately.
7139 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), 0);
7142 #endif /* SQLITE_OMIT_EXPLAIN */
7145 ** sqlite3_test_control VERB ARGS...
7147 static int SQLITE_TCLAPI
test_test_control(
7151 Tcl_Obj
*CONST objv
[]
7157 { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT
},
7158 { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP
},
7159 { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER
},
7160 { "SQLITE_TESTCTRL_INTERNAL_FUNCTIONS", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
},
7167 Tcl_WrongNumArgs(interp
, 1, objv
, "VERB ARGS...");
7171 rc
= Tcl_GetIndexFromObjStruct(
7172 interp
, objv
[1], aVerb
, sizeof(aVerb
[0]), "VERB", 0, &iVerb
7174 if( rc
!=TCL_OK
) return rc
;
7176 iFlag
= aVerb
[iVerb
].i
;
7178 case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
: {
7181 Tcl_WrongNumArgs(interp
, 2, objv
, "DB");
7184 if( getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ) return TCL_ERROR
;
7185 sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
, db
);
7188 case SQLITE_TESTCTRL_LOCALTIME_FAULT
: {
7191 Tcl_WrongNumArgs(interp
, 2, objv
, "ONOFF");
7194 if( Tcl_GetBooleanFromObj(interp
, objv
[2], &val
) ) return TCL_ERROR
;
7195 sqlite3_test_control(iFlag
, val
);
7199 case SQLITE_TESTCTRL_SORTER_MMAP
: {
7203 Tcl_WrongNumArgs(interp
, 2, objv
, "DB LIMIT");
7206 if( getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ) return TCL_ERROR
;
7207 if( Tcl_GetIntFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
7208 sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP
, db
, val
);
7212 case SQLITE_TESTCTRL_IMPOSTER
: {
7214 const char *zDbName
;
7217 Tcl_WrongNumArgs(interp
, 2, objv
, "DB dbName onOff tnum");
7220 if( getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ) return TCL_ERROR
;
7221 zDbName
= Tcl_GetString(objv
[3]);
7222 if( Tcl_GetIntFromObj(interp
, objv
[4], &onOff
) ) return TCL_ERROR
;
7223 if( Tcl_GetIntFromObj(interp
, objv
[5], &tnum
) ) return TCL_ERROR
;
7224 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER
, db
, zDbName
, onOff
, tnum
);
7229 Tcl_ResetResult(interp
);
7234 #include <sys/time.h>
7235 #include <sys/resource.h>
7237 static int SQLITE_TCLAPI
test_getrusage(
7241 Tcl_Obj
*CONST objv
[]
7245 memset(&r
, 0, sizeof(r
));
7246 getrusage(RUSAGE_SELF
, &r
);
7248 sqlite3_snprintf(sizeof(buf
), buf
,
7249 "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d",
7250 (int)r
.ru_utime
.tv_sec
, (int)r
.ru_utime
.tv_usec
,
7251 (int)r
.ru_stime
.tv_sec
, (int)r
.ru_stime
.tv_usec
,
7252 (int)r
.ru_minflt
, (int)r
.ru_majflt
7254 Tcl_SetObjResult(interp
, Tcl_NewStringObj(buf
, -1));
7261 ** Information passed from the main thread into the windows file locker
7262 ** background thread.
7264 struct win32FileLocker
{
7265 char *evName
; /* Name of event to signal thread startup */
7266 HANDLE h
; /* Handle of the file to be locked */
7267 int delay1
; /* Delay before locking */
7268 int delay2
; /* Delay before unlocking */
7269 int ok
; /* Finished ok */
7270 int err
; /* True if an error occurs */
7276 #include <process.h>
7278 ** The background thread that does file locking.
7280 static void SQLITE_CDECL
win32_file_locker(void *pAppData
){
7281 struct win32FileLocker
*p
= (struct win32FileLocker
*)pAppData
;
7283 HANDLE ev
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, p
->evName
);
7289 if( p
->delay1
) Sleep(p
->delay1
);
7290 if( LockFile(p
->h
, 0, 0, 100000000, 0) ){
7292 UnlockFile(p
->h
, 0, 0, 100000000, 0);
7306 ** lock_win32_file FILENAME DELAY1 DELAY2
7308 ** Get an exclusive manditory lock on file for DELAY2 milliseconds.
7309 ** Wait DELAY1 milliseconds before acquiring the lock.
7311 static int SQLITE_TCLAPI
win32_file_lock(
7315 Tcl_Obj
*CONST objv
[]
7317 static struct win32FileLocker x
= { "win32_file_lock", 0, 0, 0, 0, 0 };
7318 const char *zFilename
;
7324 if( objc
!=4 && objc
!=1 ){
7325 Tcl_WrongNumArgs(interp
, 1, objv
, "FILENAME DELAY1 DELAY2");
7329 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d %d %d %d %d",
7330 x
.ok
, x
.err
, x
.delay1
, x
.delay2
, x
.h
);
7331 Tcl_AppendResult(interp
, zBuf
, (char*)0);
7334 while( x
.h
&& retry
<30 ){
7339 Tcl_AppendResult(interp
, "busy", (char*)0);
7342 if( Tcl_GetIntFromObj(interp
, objv
[2], &x
.delay1
) ) return TCL_ERROR
;
7343 if( Tcl_GetIntFromObj(interp
, objv
[3], &x
.delay2
) ) return TCL_ERROR
;
7344 zFilename
= Tcl_GetString(objv
[1]);
7345 x
.h
= CreateFile(zFilename
, GENERIC_READ
|GENERIC_WRITE
,
7346 FILE_SHARE_READ
|FILE_SHARE_WRITE
, 0, OPEN_ALWAYS
,
7347 FILE_ATTRIBUTE_NORMAL
, 0);
7349 Tcl_AppendResult(interp
, "cannot open file: ", zFilename
, (char*)0);
7352 ev
= CreateEvent(NULL
, TRUE
, FALSE
, x
.evName
);
7354 Tcl_AppendResult(interp
, "cannot create event: ", x
.evName
, (char*)0);
7357 _beginthread(win32_file_locker
, 0, (void*)&x
);
7359 if ( (wResult
= WaitForSingleObject(ev
, 10000))!=WAIT_OBJECT_0
){
7360 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "0x%x", wResult
);
7361 Tcl_AppendResult(interp
, "wait failed: ", zBuf
, (char*)0);
7370 ** exists_win32_path PATH
7372 ** Returns non-zero if the specified path exists, whose fully qualified name
7373 ** may exceed 260 characters if it is prefixed with "\\?\".
7375 static int SQLITE_TCLAPI
win32_exists_path(
7379 Tcl_Obj
*CONST objv
[]
7382 Tcl_WrongNumArgs(interp
, 1, objv
, "PATH");
7385 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(
7386 GetFileAttributesW( Tcl_GetUnicode(objv
[1]))!=INVALID_FILE_ATTRIBUTES
));
7391 ** find_win32_file PATTERN
7393 ** Returns a list of entries in a directory that match the specified pattern,
7394 ** whose fully qualified name may exceed 248 characters if it is prefixed with
7397 static int SQLITE_TCLAPI
win32_find_file(
7401 Tcl_Obj
*CONST objv
[]
7403 HANDLE hFindFile
= INVALID_HANDLE_VALUE
;
7404 WIN32_FIND_DATAW findData
;
7408 Tcl_WrongNumArgs(interp
, 1, objv
, "PATTERN");
7411 hFindFile
= FindFirstFileW(Tcl_GetUnicode(objv
[1]), &findData
);
7412 if( hFindFile
==INVALID_HANDLE_VALUE
){
7413 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
7416 listObj
= Tcl_NewObj();
7417 Tcl_IncrRefCount(listObj
);
7419 Tcl_ListObjAppendElement(interp
, listObj
, Tcl_NewUnicodeObj(
7420 findData
.cFileName
, -1));
7421 Tcl_ListObjAppendElement(interp
, listObj
, Tcl_NewWideIntObj(
7422 findData
.dwFileAttributes
));
7423 } while( FindNextFileW(hFindFile
, &findData
) );
7424 lastErrno
= GetLastError();
7425 if( lastErrno
!=NO_ERROR
&& lastErrno
!=ERROR_NO_MORE_FILES
){
7426 FindClose(hFindFile
);
7427 Tcl_DecrRefCount(listObj
);
7428 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
7431 FindClose(hFindFile
);
7432 Tcl_SetObjResult(interp
, listObj
);
7437 ** delete_win32_file FILENAME
7439 ** Deletes the specified file, whose fully qualified name may exceed 260
7440 ** characters if it is prefixed with "\\?\".
7442 static int SQLITE_TCLAPI
win32_delete_file(
7446 Tcl_Obj
*CONST objv
[]
7449 Tcl_WrongNumArgs(interp
, 1, objv
, "FILENAME");
7452 if( !DeleteFileW(Tcl_GetUnicode(objv
[1])) ){
7453 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
7456 Tcl_ResetResult(interp
);
7461 ** make_win32_dir DIRECTORY
7463 ** Creates the specified directory, whose fully qualified name may exceed 248
7464 ** characters if it is prefixed with "\\?\".
7466 static int SQLITE_TCLAPI
win32_mkdir(
7470 Tcl_Obj
*CONST objv
[]
7473 Tcl_WrongNumArgs(interp
, 1, objv
, "DIRECTORY");
7476 if( !CreateDirectoryW(Tcl_GetUnicode(objv
[1]), NULL
) ){
7477 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
7480 Tcl_ResetResult(interp
);
7485 ** remove_win32_dir DIRECTORY
7487 ** Removes the specified directory, whose fully qualified name may exceed 248
7488 ** characters if it is prefixed with "\\?\".
7490 static int SQLITE_TCLAPI
win32_rmdir(
7494 Tcl_Obj
*CONST objv
[]
7497 Tcl_WrongNumArgs(interp
, 1, objv
, "DIRECTORY");
7500 if( !RemoveDirectoryW(Tcl_GetUnicode(objv
[1])) ){
7501 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
7504 Tcl_ResetResult(interp
);
7511 ** optimization_control DB OPT BOOLEAN
7513 ** Enable or disable query optimizations using the sqlite3_test_control()
7514 ** interface. Disable if BOOLEAN is false and enable if BOOLEAN is true.
7515 ** OPT is the name of the optimization to be disabled.
7517 static int SQLITE_TCLAPI
optimization_control(
7521 Tcl_Obj
*CONST objv
[]
7528 static const struct {
7529 const char *zOptName
;
7532 { "all", SQLITE_AllOpts
},
7534 { "query-flattener", SQLITE_QueryFlattener
},
7535 { "groupby-order", SQLITE_GroupByOrder
},
7536 { "factor-constants", SQLITE_FactorOutConst
},
7537 { "distinct-opt", SQLITE_DistinctOpt
},
7538 { "cover-idx-scan", SQLITE_CoverIdxScan
},
7539 { "order-by-idx-join", SQLITE_OrderByIdxJoin
},
7540 { "transitive", SQLITE_Transitive
},
7541 { "omit-noop-join", SQLITE_OmitNoopJoin
},
7542 { "stat4", SQLITE_Stat4
},
7543 { "skip-scan", SQLITE_SkipScan
},
7544 { "push-down", SQLITE_PushDown
},
7548 Tcl_WrongNumArgs(interp
, 1, objv
, "DB OPT BOOLEAN");
7551 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
7552 if( Tcl_GetBooleanFromObj(interp
, objv
[3], &onoff
) ) return TCL_ERROR
;
7553 zOpt
= Tcl_GetString(objv
[2]);
7554 for(i
=0; i
<sizeof(aOpt
)/sizeof(aOpt
[0]); i
++){
7555 if( strcmp(zOpt
, aOpt
[i
].zOptName
)==0 ){
7556 mask
= aOpt
[i
].mask
;
7560 if( onoff
) mask
= ~mask
;
7561 if( i
>=sizeof(aOpt
)/sizeof(aOpt
[0]) ){
7562 Tcl_AppendResult(interp
, "unknown optimization - should be one of:",
7564 for(i
=0; i
<sizeof(aOpt
)/sizeof(aOpt
[0]); i
++){
7565 Tcl_AppendResult(interp
, " ", aOpt
[i
].zOptName
, (char*)0);
7569 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS
, db
, mask
);
7574 ** load_static_extension DB NAME ...
7576 ** Load one or more statically linked extensions.
7578 static int SQLITE_TCLAPI
tclLoadStaticExtensionCmd(
7582 Tcl_Obj
*CONST objv
[]
7584 extern int sqlite3_amatch_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7585 extern int sqlite3_appendvfs_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7586 extern int sqlite3_carray_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7587 extern int sqlite3_closure_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7588 extern int sqlite3_csv_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7589 extern int sqlite3_eval_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7590 extern int sqlite3_explain_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7591 extern int sqlite3_fileio_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7592 extern int sqlite3_decimal_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7593 extern int sqlite3_fuzzer_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7594 extern int sqlite3_ieee_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7595 extern int sqlite3_nextchar_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7596 extern int sqlite3_percentile_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7597 #ifndef SQLITE_OMIT_VIRTUALTABLE
7598 extern int sqlite3_prefixes_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7600 extern int sqlite3_regexp_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7601 extern int sqlite3_remember_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7602 extern int sqlite3_series_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7603 extern int sqlite3_spellfix_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7604 extern int sqlite3_totype_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7605 extern int sqlite3_wholenumber_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7606 extern int sqlite3_unionvtab_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7607 #ifdef SQLITE_HAVE_ZLIB
7608 extern int sqlite3_zipfile_init(sqlite3
*,char**,const sqlite3_api_routines
*);
7610 static const struct {
7611 const char *zExtName
;
7612 int (*pInit
)(sqlite3
*,char**,const sqlite3_api_routines
*);
7614 { "amatch", sqlite3_amatch_init
},
7615 { "appendvfs", sqlite3_appendvfs_init
},
7616 { "carray", sqlite3_carray_init
},
7617 { "closure", sqlite3_closure_init
},
7618 { "csv", sqlite3_csv_init
},
7619 { "decimal", sqlite3_decimal_init
},
7620 { "eval", sqlite3_eval_init
},
7621 { "explain", sqlite3_explain_init
},
7622 { "fileio", sqlite3_fileio_init
},
7623 { "fuzzer", sqlite3_fuzzer_init
},
7624 { "ieee754", sqlite3_ieee_init
},
7625 { "nextchar", sqlite3_nextchar_init
},
7626 { "percentile", sqlite3_percentile_init
},
7627 #ifndef SQLITE_OMIT_VIRTUALTABLE
7628 { "prefixes", sqlite3_prefixes_init
},
7630 { "regexp", sqlite3_regexp_init
},
7631 { "remember", sqlite3_remember_init
},
7632 { "series", sqlite3_series_init
},
7633 { "spellfix", sqlite3_spellfix_init
},
7634 { "totype", sqlite3_totype_init
},
7635 { "unionvtab", sqlite3_unionvtab_init
},
7636 { "wholenumber", sqlite3_wholenumber_init
},
7637 #ifdef SQLITE_HAVE_ZLIB
7638 { "zipfile", sqlite3_zipfile_init
},
7646 Tcl_WrongNumArgs(interp
, 1, objv
, "DB NAME ...");
7649 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
7650 for(j
=2; j
<objc
; j
++){
7651 zName
= Tcl_GetString(objv
[j
]);
7652 for(i
=0; i
<ArraySize(aExtension
); i
++){
7653 if( strcmp(zName
, aExtension
[i
].zExtName
)==0 ) break;
7655 if( i
>=ArraySize(aExtension
) ){
7656 Tcl_AppendResult(interp
, "no such extension: ", zName
, (char*)0);
7659 if( aExtension
[i
].pInit
){
7660 rc
= aExtension
[i
].pInit(db
, &zErrMsg
, 0);
7664 if( (rc
!=SQLITE_OK
&& rc
!=SQLITE_OK_LOAD_PERMANENTLY
) || zErrMsg
){
7665 Tcl_AppendResult(interp
, "initialization of ", zName
, " failed: ", zErrMsg
,
7667 sqlite3_free(zErrMsg
);
7675 ** sorter_test_fakeheap BOOL
7678 static int SQLITE_TCLAPI
sorter_test_fakeheap(
7682 Tcl_Obj
*CONST objv
[]
7686 Tcl_WrongNumArgs(interp
, 1, objv
, "BOOL");
7690 if( Tcl_GetBooleanFromObj(interp
, objv
[1], &bArg
) ){
7695 if( sqlite3GlobalConfig
.pHeap
==0 ){
7696 sqlite3GlobalConfig
.pHeap
= SQLITE_INT_TO_PTR(-1);
7699 if( sqlite3GlobalConfig
.pHeap
==SQLITE_INT_TO_PTR(-1) ){
7700 sqlite3GlobalConfig
.pHeap
= 0;
7704 Tcl_ResetResult(interp
);
7709 ** sorter_test_sort4_helper DB SQL1 NSTEP SQL2
7711 ** Compile SQL statement $SQL1 and step it $NSTEP times. For each row,
7712 ** check that the leftmost and rightmost columns returned are both integers,
7713 ** and that both contain the same value.
7715 ** Then execute statement $SQL2. Check that the statement returns the same
7716 ** set of integers in the same order as in the previous step (using $SQL1).
7718 static int SQLITE_TCLAPI
sorter_test_sort4_helper(
7722 Tcl_Obj
*CONST objv
[]
7728 unsigned int iCksum1
= 0;
7729 unsigned int iCksum2
= 0;
7733 sqlite3_stmt
*pStmt
;
7736 Tcl_WrongNumArgs(interp
, 1, objv
, "DB SQL1 NSTEP SQL2");
7740 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
7741 zSql1
= Tcl_GetString(objv
[2]);
7742 if( Tcl_GetIntFromObj(interp
, objv
[3], &nStep
) ) return TCL_ERROR
;
7743 zSql2
= Tcl_GetString(objv
[4]);
7745 rc
= sqlite3_prepare_v2(db
, zSql1
, -1, &pStmt
, 0);
7746 if( rc
!=SQLITE_OK
) goto sql_error
;
7748 iB
= sqlite3_column_count(pStmt
)-1;
7749 for(iStep
=0; iStep
<nStep
&& SQLITE_ROW
==sqlite3_step(pStmt
); iStep
++){
7750 int a
= sqlite3_column_int(pStmt
, 0);
7751 if( a
!=sqlite3_column_int(pStmt
, iB
) ){
7752 Tcl_AppendResult(interp
, "data error: (a!=b)", 0);
7756 iCksum1
+= (iCksum1
<< 3) + (unsigned int)a
;
7758 rc
= sqlite3_finalize(pStmt
);
7759 if( rc
!=SQLITE_OK
) goto sql_error
;
7761 rc
= sqlite3_prepare_v2(db
, zSql2
, -1, &pStmt
, 0);
7762 if( rc
!=SQLITE_OK
) goto sql_error
;
7763 for(iStep
=0; SQLITE_ROW
==sqlite3_step(pStmt
); iStep
++){
7764 int a
= sqlite3_column_int(pStmt
, 0);
7765 iCksum2
+= (iCksum2
<< 3) + (unsigned int)a
;
7767 rc
= sqlite3_finalize(pStmt
);
7768 if( rc
!=SQLITE_OK
) goto sql_error
;
7770 if( iCksum1
!=iCksum2
){
7771 Tcl_AppendResult(interp
, "checksum mismatch", 0);
7777 Tcl_AppendResult(interp
, "sql error: ", sqlite3_errmsg(db
), 0);
7782 #ifdef SQLITE_USER_AUTHENTICATION
7783 #include "sqlite3userauth.h"
7785 ** tclcmd: sqlite3_user_authenticate DB USERNAME PASSWORD
7787 static int SQLITE_TCLAPI
test_user_authenticate(
7788 ClientData clientData
, /* Unused */
7789 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7790 int objc
, /* Number of arguments */
7791 Tcl_Obj
*CONST objv
[] /* Command arguments */
7800 Tcl_WrongNumArgs(interp
, 1, objv
, "DB USERNAME PASSWORD");
7803 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
7806 zUser
= Tcl_GetString(objv
[2]);
7807 zPasswd
= Tcl_GetStringFromObj(objv
[3], &nPasswd
);
7808 rc
= sqlite3_user_authenticate(db
, zUser
, zPasswd
, nPasswd
);
7809 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
7812 #endif /* SQLITE_USER_AUTHENTICATION */
7814 #ifdef SQLITE_USER_AUTHENTICATION
7816 ** tclcmd: sqlite3_user_add DB USERNAME PASSWORD ISADMIN
7818 static int SQLITE_TCLAPI
test_user_add(
7819 ClientData clientData
, /* Unused */
7820 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7821 int objc
, /* Number of arguments */
7822 Tcl_Obj
*CONST objv
[] /* Command arguments */
7832 Tcl_WrongNumArgs(interp
, 1, objv
, "DB USERNAME PASSWORD ISADMIN");
7835 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
7838 zUser
= Tcl_GetString(objv
[2]);
7839 zPasswd
= Tcl_GetStringFromObj(objv
[3], &nPasswd
);
7840 Tcl_GetBooleanFromObj(interp
, objv
[4], &isAdmin
);
7841 rc
= sqlite3_user_add(db
, zUser
, zPasswd
, nPasswd
, isAdmin
);
7842 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
7845 #endif /* SQLITE_USER_AUTHENTICATION */
7847 #ifdef SQLITE_USER_AUTHENTICATION
7849 ** tclcmd: sqlite3_user_change DB USERNAME PASSWORD ISADMIN
7851 static int SQLITE_TCLAPI
test_user_change(
7852 ClientData clientData
, /* Unused */
7853 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7854 int objc
, /* Number of arguments */
7855 Tcl_Obj
*CONST objv
[] /* Command arguments */
7865 Tcl_WrongNumArgs(interp
, 1, objv
, "DB USERNAME PASSWORD ISADMIN");
7868 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
7871 zUser
= Tcl_GetString(objv
[2]);
7872 zPasswd
= Tcl_GetStringFromObj(objv
[3], &nPasswd
);
7873 Tcl_GetBooleanFromObj(interp
, objv
[4], &isAdmin
);
7874 rc
= sqlite3_user_change(db
, zUser
, zPasswd
, nPasswd
, isAdmin
);
7875 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
7878 #endif /* SQLITE_USER_AUTHENTICATION */
7880 #ifdef SQLITE_USER_AUTHENTICATION
7882 ** tclcmd: sqlite3_user_delete DB USERNAME
7884 static int SQLITE_TCLAPI
test_user_delete(
7885 ClientData clientData
, /* Unused */
7886 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7887 int objc
, /* Number of arguments */
7888 Tcl_Obj
*CONST objv
[] /* Command arguments */
7895 Tcl_WrongNumArgs(interp
, 1, objv
, "DB USERNAME");
7898 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
7901 zUser
= Tcl_GetString(objv
[2]);
7902 rc
= sqlite3_user_delete(db
, zUser
);
7903 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
7906 #endif /* SQLITE_USER_AUTHENTICATION */
7909 ** tclcmd: bad_behavior TYPE
7911 ** Do some things that should trigger a valgrind or -fsanitize=undefined
7912 ** warning. This is used to verify that errors and warnings output by those
7913 ** tools are detected by the test scripts.
7916 ** 1 Overflow a signed integer
7917 ** 2 Jump based on an uninitialized variable
7918 ** 3 Read after free
7921 static int SQLITE_TCLAPI
test_bad_behavior(
7922 ClientData clientData
, /* Pointer to an integer containing zero */
7923 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7924 int objc
, /* Number of arguments */
7925 Tcl_Obj
*CONST objv
[] /* Command arguments */
7929 int i
= *(int*)clientData
;
7934 Tcl_WrongNumArgs(interp
, 1, objv
, "TYPE");
7937 if( Tcl_GetIntFromObj(interp
, objv
[1], &iType
) ) return TCL_ERROR
;
7940 xyz
= 0x7fffff00 - i
;
7942 Tcl_SetObjResult(interp
, Tcl_NewIntObj(xyz
));
7947 if( w
[i
]>0 ) w
[1]++;
7948 Tcl_SetObjResult(interp
, Tcl_NewIntObj(w
[1]));
7952 a
= malloc( sizeof(int)*10 );
7953 for(j
=0; j
<10; j
++) a
[j
] = j
;
7955 Tcl_SetObjResult(interp
, Tcl_NewIntObj(a
[i
]));
7959 Tcl_Panic("Deliberate panic");
7967 ** tclcmd: register_dbstat_vtab DB
7969 ** Cause the dbstat virtual table to be available on the connection DB
7971 static int SQLITE_TCLAPI
test_register_dbstat_vtab(
7975 Tcl_Obj
*CONST objv
[]
7977 #ifdef SQLITE_OMIT_VIRTUALTABLE
7978 Tcl_AppendResult(interp
, "dbstat not available because of "
7979 "SQLITE_OMIT_VIRTUALTABLE", (void*)0);
7982 struct SqliteDb
{ sqlite3
*db
; };
7984 Tcl_CmdInfo cmdInfo
;
7987 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
7991 zDb
= Tcl_GetString(objv
[1]);
7992 if( Tcl_GetCommandInfo(interp
, zDb
, &cmdInfo
) ){
7993 sqlite3
* db
= ((struct SqliteDb
*)cmdInfo
.objClientData
)->db
;
7994 sqlite3DbstatRegister(db
);
7997 #endif /* SQLITE_OMIT_VIRTUALTABLE */
8001 ** tclcmd: sqlite3_db_config DB SETTING VALUE
8003 ** Invoke sqlite3_db_config() for one of the setting values.
8005 static int SQLITE_TCLAPI
test_sqlite3_db_config(
8009 Tcl_Obj
*CONST objv
[]
8011 static const struct {
8015 { "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY
},
8016 { "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER
},
8017 { "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
},
8018 { "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
},
8019 { "NO_CKPT_ON_CLOSE", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
},
8020 { "QPSG", SQLITE_DBCONFIG_ENABLE_QPSG
},
8021 { "TRIGGER_EQP", SQLITE_DBCONFIG_TRIGGER_EQP
},
8022 { "RESET_DB", SQLITE_DBCONFIG_RESET_DATABASE
},
8023 { "DEFENSIVE", SQLITE_DBCONFIG_DEFENSIVE
},
8024 { "WRITABLE_SCHEMA", SQLITE_DBCONFIG_WRITABLE_SCHEMA
},
8025 { "LEGACY_ALTER_TABLE", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
},
8026 { "DQS_DML", SQLITE_DBCONFIG_DQS_DML
},
8027 { "DQS_DDL", SQLITE_DBCONFIG_DQS_DDL
},
8028 { "LEGACY_FILE_FORMAT", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
},
8032 const char *zSetting
;
8035 if( objc
!=4 && objc
!=3 ){
8036 Tcl_WrongNumArgs(interp
, 1, objv
, "DB SETTING [VALUE]");
8039 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8040 zSetting
= Tcl_GetString(objv
[2]);
8041 if( sqlite3_strglob("SQLITE_*", zSetting
)==0 ) zSetting
+= 7;
8042 if( sqlite3_strglob("DBCONFIG_*", zSetting
)==0 ) zSetting
+= 9;
8043 if( sqlite3_strglob("ENABLE_*", zSetting
)==0 ) zSetting
+= 7;
8044 for(i
=0; i
<ArraySize(aSetting
); i
++){
8045 if( strcmp(zSetting
, aSetting
[i
].zName
)==0 ) break;
8047 if( i
>=ArraySize(aSetting
) ){
8048 Tcl_SetObjResult(interp
,
8049 Tcl_NewStringObj("unknown sqlite3_db_config setting", -1));
8053 if( Tcl_GetIntFromObj(interp
, objv
[3], &v
) ) return TCL_ERROR
;
8057 sqlite3_db_config(db
, aSetting
[i
].eVal
, v
, &v
);
8058 Tcl_SetObjResult(interp
, Tcl_NewIntObj(v
));
8062 ** tclcmd: sqlite3_txn_state DB ?SCHEMA?
8064 ** Invoke sqlite3_txn_state(DB,SCHEMA) and return the
8065 ** numeric value that results. Use NULL for SCHEMA if the 3 argument
8068 static int SQLITE_TCLAPI
test_sqlite3_txn_state(
8072 Tcl_Obj
*CONST objv
[]
8075 const char *zSchema
;
8078 if( objc
!=2 && objc
!=3 ){
8079 Tcl_WrongNumArgs(interp
, 1, objv
, "DB ?SCHEMA?");
8082 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8083 zSchema
= objc
==3 ? Tcl_GetString(objv
[2]) : 0;
8084 iTxn
= sqlite3_txn_state(db
, zSchema
);
8085 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iTxn
));
8090 ** Change the name of the main database schema from "main" to "icecube".
8092 static int SQLITE_TCLAPI
test_dbconfig_maindbname_icecube(
8096 Tcl_Obj
*CONST objv
[]
8100 extern int getDbPointer(Tcl_Interp
*, const char*, sqlite3
**);
8102 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
8105 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8106 rc
= sqlite3_db_config(db
, SQLITE_DBCONFIG_MAINDBNAME
, "icecube");
8107 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
8113 ** Usage: sqlite3_mmap_warm DB DBNAME
8115 static int SQLITE_TCLAPI
test_mmap_warm(
8119 Tcl_Obj
*CONST objv
[]
8121 extern int getDbPointer(Tcl_Interp
*, const char*, sqlite3
**);
8122 extern int sqlite3_mmap_warm(sqlite3
*db
, const char *);
8124 if( objc
!=2 && objc
!=3 ){
8125 Tcl_WrongNumArgs(interp
, 1, objv
, "DB ?DBNAME?");
8130 const char *zDb
= 0;
8131 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8133 zDb
= Tcl_GetString(objv
[2]);
8135 rc
= sqlite3_mmap_warm(db
, zDb
);
8136 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
8142 ** Usage: test_write_db DB OFFSET DATA
8144 ** Obtain the sqlite3_file* object for the database file for the "main" db
8145 ** of handle DB. Then invoke its xWrite method to write data DATA to offset
8148 static int SQLITE_TCLAPI
test_write_db(
8152 Tcl_Obj
*CONST objv
[]
8155 Tcl_WideInt iOff
= 0;
8156 const unsigned char *aData
= 0;
8158 sqlite3_file
*pFile
= 0;
8162 Tcl_WrongNumArgs(interp
, 1, objv
, "DB OFFSET DATA");
8165 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8166 if( Tcl_GetWideIntFromObj(interp
, objv
[2], &iOff
) ) return TCL_ERROR
;
8167 aData
= Tcl_GetByteArrayFromObj(objv
[3], &nData
);
8169 sqlite3_file_control(db
, "main", SQLITE_FCNTL_FILE_POINTER
, (void*)&pFile
);
8170 rc
= pFile
->pMethods
->xWrite(pFile
, aData
, nData
, iOff
);
8172 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_VOLATILE
);
8177 ** Usage: sqlite3_register_cksumvfs
8180 static int SQLITE_TCLAPI
test_register_cksumvfs(
8184 Tcl_Obj
*CONST objv
[]
8187 Tcl_WrongNumArgs(interp
, 1, objv
, "");
8190 extern int sqlite3_register_cksumvfs(const char*);
8191 int rc
= sqlite3_register_cksumvfs(0);
8192 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_VOLATILE
);
8198 ** Usage: sqlite3_unregister_cksumvfs
8201 static int SQLITE_TCLAPI
test_unregister_cksumvfs(
8205 Tcl_Obj
*CONST objv
[]
8208 Tcl_WrongNumArgs(interp
, 1, objv
, "");
8211 extern int sqlite3_unregister_cksumvfs(void);
8212 int rc
= sqlite3_unregister_cksumvfs();
8213 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_VOLATILE
);
8219 ** Usage: decode_hexdb TEXT
8221 ** Example: db deserialize [decode_hexdb $output_of_dbtotxt]
8223 ** This routine returns a byte-array for an SQLite database file that
8224 ** is constructed from a text input which is the output of the "dbtotxt"
8227 static int SQLITE_TCLAPI
test_decode_hexdb(
8231 Tcl_Obj
*CONST objv
[]
8233 const char *zIn
= 0;
8234 unsigned char *a
= 0;
8243 Tcl_WrongNumArgs(interp
, 1, objv
, "HEXDB");
8246 zIn
= Tcl_GetString(objv
[1]);
8247 for(i
=0; zIn
[i
]; i
=iNext
){
8249 for(iNext
=i
; zIn
[iNext
] && zIn
[iNext
]!='\n'; iNext
++){}
8250 if( zIn
[iNext
]=='\n' ) iNext
++;
8251 while( zIn
[i
]==' ' || zIn
[i
]=='\t' ){ i
++; }
8254 rc
= sscanf(zIn
+i
, "| size %d pagesize %d", &n
, &pgsz
);
8255 if( rc
!=2 ) continue;
8256 if( pgsz
<512 || pgsz
>65536 || (pgsz
&(pgsz
-1))!=0 ){
8257 Tcl_AppendResult(interp
, "bad 'pagesize' field", (void*)0);
8260 n
= (n
+pgsz
-1)&~(pgsz
-1); /* Round n up to the next multiple of pgsz */
8262 Tcl_AppendResult(interp
, "bad 'size' field", (void*)0);
8267 Tcl_AppendResult(interp
, "out of memory", (void*)0);
8273 rc
= sscanf(zIn
+i
, "| page %d offset %d", &j
, &k
);
8278 rc
= sscanf(zIn
+i
,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
8279 &j
, &x
[0], &x
[1], &x
[2], &x
[3], &x
[4], &x
[5], &x
[6], &x
[7],
8280 &x
[8], &x
[9], &x
[10], &x
[11], &x
[12], &x
[13], &x
[14], &x
[15]);
8285 for(ii
=0; ii
<16; ii
++) a
[k
+ii
] = x
[ii
]&0xff;
8290 Tcl_SetObjResult(interp
, Tcl_NewByteArrayObj(a
, n
));
8297 ** Register commands with the TCL interpreter.
8299 int Sqlitetest1_Init(Tcl_Interp
*interp
){
8300 extern int sqlite3_search_count
;
8301 extern int sqlite3_found_count
;
8302 extern int sqlite3_interrupt_count
;
8303 extern int sqlite3_open_file_count
;
8304 extern int sqlite3_sort_count
;
8305 extern int sqlite3_current_time
;
8306 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
8307 extern int sqlite3_hostid_num
;
8309 extern int sqlite3_max_blobsize
;
8310 extern int SQLITE_TCLAPI
sqlite3BtreeSharedCacheReport(void*,
8311 Tcl_Interp
*,int,Tcl_Obj
*CONST
*);
8312 static int iZero
= 0;
8317 { "db_enter", (Tcl_CmdProc
*)db_enter
},
8318 { "db_leave", (Tcl_CmdProc
*)db_leave
},
8319 { "sqlite3_mprintf_int", (Tcl_CmdProc
*)sqlite3_mprintf_int
},
8320 { "sqlite3_mprintf_int64", (Tcl_CmdProc
*)sqlite3_mprintf_int64
},
8321 { "sqlite3_mprintf_long", (Tcl_CmdProc
*)sqlite3_mprintf_long
},
8322 { "sqlite3_mprintf_str", (Tcl_CmdProc
*)sqlite3_mprintf_str
},
8323 { "sqlite3_snprintf_str", (Tcl_CmdProc
*)sqlite3_snprintf_str
},
8324 { "sqlite3_mprintf_stronly", (Tcl_CmdProc
*)sqlite3_mprintf_stronly
},
8325 { "sqlite3_mprintf_double", (Tcl_CmdProc
*)sqlite3_mprintf_double
},
8326 { "sqlite3_mprintf_scaled", (Tcl_CmdProc
*)sqlite3_mprintf_scaled
},
8327 { "sqlite3_mprintf_hexdouble", (Tcl_CmdProc
*)sqlite3_mprintf_hexdouble
},
8328 { "sqlite3_mprintf_z_test", (Tcl_CmdProc
*)test_mprintf_z
},
8329 { "sqlite3_mprintf_n_test", (Tcl_CmdProc
*)test_mprintf_n
},
8330 { "sqlite3_snprintf_int", (Tcl_CmdProc
*)test_snprintf_int
},
8331 { "sqlite3_last_insert_rowid", (Tcl_CmdProc
*)test_last_rowid
},
8332 { "sqlite3_exec_printf", (Tcl_CmdProc
*)test_exec_printf
},
8333 { "sqlite3_exec_hex", (Tcl_CmdProc
*)test_exec_hex
},
8334 { "sqlite3_exec", (Tcl_CmdProc
*)test_exec
},
8335 { "sqlite3_exec_nr", (Tcl_CmdProc
*)test_exec_nr
},
8336 #ifndef SQLITE_OMIT_GET_TABLE
8337 { "sqlite3_get_table_printf", (Tcl_CmdProc
*)test_get_table_printf
},
8339 { "sqlite3_close", (Tcl_CmdProc
*)sqlite_test_close
},
8340 { "sqlite3_close_v2", (Tcl_CmdProc
*)sqlite_test_close_v2
},
8341 { "sqlite3_create_function", (Tcl_CmdProc
*)test_create_function
},
8342 { "sqlite3_create_aggregate", (Tcl_CmdProc
*)test_create_aggregate
},
8343 { "sqlite3_drop_modules", (Tcl_CmdProc
*)test_drop_modules
},
8344 { "sqlite_register_test_function", (Tcl_CmdProc
*)test_register_func
},
8345 { "sqlite_abort", (Tcl_CmdProc
*)sqlite_abort
},
8346 { "sqlite_bind", (Tcl_CmdProc
*)test_bind
},
8347 { "breakpoint", (Tcl_CmdProc
*)test_breakpoint
},
8348 { "sqlite3_key", (Tcl_CmdProc
*)test_key
},
8349 { "sqlite3_rekey", (Tcl_CmdProc
*)test_rekey
},
8350 { "sqlite_set_magic", (Tcl_CmdProc
*)sqlite_set_magic
},
8351 { "sqlite3_interrupt", (Tcl_CmdProc
*)test_interrupt
},
8352 { "sqlite_delete_function", (Tcl_CmdProc
*)delete_function
},
8353 { "sqlite_delete_collation", (Tcl_CmdProc
*)delete_collation
},
8354 { "sqlite3_get_autocommit", (Tcl_CmdProc
*)get_autocommit
},
8355 { "sqlite3_busy_timeout", (Tcl_CmdProc
*)test_busy_timeout
},
8356 { "printf", (Tcl_CmdProc
*)test_printf
},
8357 { "sqlite3IoTrace", (Tcl_CmdProc
*)test_io_trace
},
8358 { "clang_sanitize_address", (Tcl_CmdProc
*)clang_sanitize_address
},
8362 Tcl_ObjCmdProc
*xProc
;
8365 { "sqlite3_db_config", test_sqlite3_db_config
, 0 },
8366 { "sqlite3_txn_state", test_sqlite3_txn_state
, 0 },
8367 { "bad_behavior", test_bad_behavior
, (void*)&iZero
},
8368 { "register_dbstat_vtab", test_register_dbstat_vtab
},
8369 { "sqlite3_connection_pointer", get_sqlite_pointer
, 0 },
8370 { "intarray_addr", test_intarray_addr
, 0 },
8371 { "int64array_addr", test_int64array_addr
, 0 },
8372 { "doublearray_addr", test_doublearray_addr
, 0 },
8373 { "textarray_addr", test_textarray_addr
, 0 },
8374 { "sqlite3_bind_int", test_bind_int
, 0 },
8375 { "sqlite3_bind_zeroblob", test_bind_zeroblob
, 0 },
8376 { "sqlite3_bind_zeroblob64", test_bind_zeroblob64
, 0 },
8377 { "sqlite3_bind_int64", test_bind_int64
, 0 },
8378 { "sqlite3_bind_double", test_bind_double
, 0 },
8379 { "sqlite3_bind_null", test_bind_null
,0 },
8380 { "sqlite3_bind_text", test_bind_text
,0 },
8381 { "sqlite3_bind_text16", test_bind_text16
,0 },
8382 { "sqlite3_bind_blob", test_bind_blob
,0 },
8383 #ifndef SQLITE_OMIT_VIRTUALTABLE
8384 { "sqlite3_carray_bind", test_carray_bind
,0 },
8386 { "sqlite3_bind_parameter_count", test_bind_parameter_count
, 0},
8387 { "sqlite3_bind_parameter_name", test_bind_parameter_name
, 0},
8388 { "sqlite3_bind_parameter_index", test_bind_parameter_index
, 0},
8389 { "sqlite3_clear_bindings", test_clear_bindings
, 0},
8390 { "sqlite3_sleep", test_sleep
, 0},
8391 { "sqlite3_errcode", test_errcode
,0 },
8392 { "sqlite3_extended_errcode", test_ex_errcode
,0 },
8393 { "sqlite3_errmsg", test_errmsg
,0 },
8394 { "sqlite3_errmsg16", test_errmsg16
,0 },
8395 { "sqlite3_open", test_open
,0 },
8396 { "sqlite3_open16", test_open16
,0 },
8397 { "sqlite3_open_v2", test_open_v2
,0 },
8398 { "sqlite3_complete16", test_complete16
,0 },
8399 { "sqlite3_normalize", test_normalize
,0 },
8401 { "sqlite3_prepare", test_prepare
,0 },
8402 { "sqlite3_prepare16", test_prepare16
,0 },
8403 { "sqlite3_prepare_v2", test_prepare_v2
,0 },
8404 { "sqlite3_prepare_v3", test_prepare_v3
,0 },
8405 { "sqlite3_prepare_tkt3134", test_prepare_tkt3134
, 0},
8406 { "sqlite3_prepare16_v2", test_prepare16_v2
,0 },
8407 { "sqlite3_finalize", test_finalize
,0 },
8408 { "sqlite3_stmt_status", test_stmt_status
,0 },
8409 { "sqlite3_reset", test_reset
,0 },
8410 { "sqlite3_expired", test_expired
,0 },
8411 { "sqlite3_transfer_bindings", test_transfer_bind
,0 },
8412 { "sqlite3_changes", test_changes
,0 },
8413 { "sqlite3_step", test_step
,0 },
8414 { "sqlite3_sql", test_sql
,0 },
8415 { "sqlite3_expanded_sql", test_ex_sql
,0 },
8416 #ifdef SQLITE_ENABLE_NORMALIZE
8417 { "sqlite3_normalized_sql", test_norm_sql
,0 },
8419 { "sqlite3_next_stmt", test_next_stmt
,0 },
8420 { "sqlite3_stmt_readonly", test_stmt_readonly
,0 },
8421 { "sqlite3_stmt_isexplain", test_stmt_isexplain
,0 },
8422 { "sqlite3_stmt_busy", test_stmt_busy
,0 },
8423 { "uses_stmt_journal", uses_stmt_journal
,0 },
8425 { "sqlite3_release_memory", test_release_memory
, 0},
8426 { "sqlite3_db_release_memory", test_db_release_memory
, 0},
8427 { "sqlite3_db_cacheflush", test_db_cacheflush
, 0},
8428 { "sqlite3_system_errno", test_system_errno
, 0},
8429 { "sqlite3_db_filename", test_db_filename
, 0},
8430 { "sqlite3_db_readonly", test_db_readonly
, 0},
8431 { "sqlite3_soft_heap_limit", test_soft_heap_limit
, 0},
8432 { "sqlite3_soft_heap_limit64", test_soft_heap_limit
, 0},
8433 { "sqlite3_hard_heap_limit64", test_hard_heap_limit
, 0},
8434 { "sqlite3_thread_cleanup", test_thread_cleanup
, 0},
8435 { "sqlite3_pager_refcounts", test_pager_refcounts
, 0},
8437 { "sqlite3_load_extension", test_load_extension
, 0},
8438 { "sqlite3_enable_load_extension", test_enable_load
, 0},
8439 { "sqlite3_extended_result_codes", test_extended_result_codes
, 0},
8440 { "sqlite3_limit", test_limit
, 0},
8441 { "dbconfig_maindbname_icecube", test_dbconfig_maindbname_icecube
},
8443 { "save_prng_state", save_prng_state
, 0 },
8444 { "restore_prng_state", restore_prng_state
, 0 },
8445 { "reset_prng_state", reset_prng_state
, 0 },
8446 { "prng_seed", prng_seed
, 0 },
8447 { "extra_schema_checks", extra_schema_checks
, 0},
8448 { "database_never_corrupt", database_never_corrupt
, 0},
8449 { "database_may_be_corrupt", database_may_be_corrupt
, 0},
8450 { "optimization_control", optimization_control
,0},
8452 { "lock_win32_file", win32_file_lock
, 0 },
8453 { "exists_win32_path", win32_exists_path
, 0 },
8454 { "find_win32_file", win32_find_file
, 0 },
8455 { "delete_win32_file", win32_delete_file
, 0 },
8456 { "make_win32_dir", win32_mkdir
, 0 },
8457 { "remove_win32_dir", win32_rmdir
, 0 },
8459 { "tcl_objproc", runAsObjProc
, 0 },
8461 /* sqlite3_column_*() API */
8462 { "sqlite3_column_count", test_column_count
,0 },
8463 { "sqlite3_data_count", test_data_count
,0 },
8464 { "sqlite3_column_type", test_column_type
,0 },
8465 { "sqlite3_column_blob", test_column_blob
,0 },
8466 { "sqlite3_column_double", test_column_double
,0 },
8467 { "sqlite3_column_int64", test_column_int64
,0 },
8468 { "sqlite3_column_text", test_stmt_utf8
, (void*)sqlite3_column_text
},
8469 { "sqlite3_column_name", test_stmt_utf8
, (void*)sqlite3_column_name
},
8470 { "sqlite3_column_int", test_stmt_int
, (void*)sqlite3_column_int
},
8471 { "sqlite3_column_bytes", test_stmt_int
, (void*)sqlite3_column_bytes
},
8472 #ifndef SQLITE_OMIT_DECLTYPE
8473 { "sqlite3_column_decltype",test_stmt_utf8
,(void*)sqlite3_column_decltype
},
8475 #ifdef SQLITE_ENABLE_COLUMN_METADATA
8476 { "sqlite3_column_database_name",test_stmt_utf8
,(void*)sqlite3_column_database_name
},
8477 { "sqlite3_column_table_name",test_stmt_utf8
,(void*)sqlite3_column_table_name
},
8478 { "sqlite3_column_origin_name",test_stmt_utf8
,(void*)sqlite3_column_origin_name
},
8481 #ifndef SQLITE_OMIT_UTF16
8482 { "sqlite3_column_bytes16", test_stmt_int
, (void*)sqlite3_column_bytes16
},
8483 { "sqlite3_column_text16", test_stmt_utf16
, (void*)sqlite3_column_text16
},
8484 { "sqlite3_column_name16", test_stmt_utf16
, (void*)sqlite3_column_name16
},
8485 { "add_alignment_test_collations", add_alignment_test_collations
, 0 },
8486 #ifndef SQLITE_OMIT_DECLTYPE
8487 { "sqlite3_column_decltype16",test_stmt_utf16
,(void*)sqlite3_column_decltype16
},
8489 #ifdef SQLITE_ENABLE_COLUMN_METADATA
8490 {"sqlite3_column_database_name16",
8491 test_stmt_utf16
, (void*)sqlite3_column_database_name16
},
8492 {"sqlite3_column_table_name16", test_stmt_utf16
, (void*)sqlite3_column_table_name16
},
8493 {"sqlite3_column_origin_name16", test_stmt_utf16
, (void*)sqlite3_column_origin_name16
},
8496 { "sqlite3_create_collation_v2", test_create_collation_v2
, 0 },
8497 { "sqlite3_global_recover", test_global_recover
, 0 },
8498 { "working_64bit_int", working_64bit_int
, 0 },
8499 { "vfs_unlink_test", vfs_unlink_test
, 0 },
8500 { "vfs_initfail_test", vfs_initfail_test
, 0 },
8501 { "vfs_unregister_all", vfs_unregister_all
, 0 },
8502 { "vfs_reregister_all", vfs_reregister_all
, 0 },
8503 { "file_control_test", file_control_test
, 0 },
8504 { "file_control_lasterrno_test", file_control_lasterrno_test
, 0 },
8505 { "file_control_lockproxy_test", file_control_lockproxy_test
, 0 },
8506 { "file_control_chunksize_test", file_control_chunksize_test
, 0 },
8507 { "file_control_sizehint_test", file_control_sizehint_test
, 0 },
8508 { "file_control_data_version", file_control_data_version
, 0 },
8510 { "file_control_win32_av_retry", file_control_win32_av_retry
, 0 },
8511 { "file_control_win32_get_handle", file_control_win32_get_handle
, 0 },
8512 { "file_control_win32_set_handle", file_control_win32_set_handle
, 0 },
8514 { "file_control_persist_wal", file_control_persist_wal
, 0 },
8515 { "file_control_powersafe_overwrite",file_control_powersafe_overwrite
,0},
8516 { "file_control_vfsname", file_control_vfsname
, 0 },
8517 { "file_control_reservebytes", file_control_reservebytes
, 0 },
8518 { "file_control_tempfilename", file_control_tempfilename
, 0 },
8519 { "file_control_external_reader", file_control_external_reader
, 0 },
8520 { "sqlite3_vfs_list", vfs_list
, 0 },
8521 { "sqlite3_create_function_v2", test_create_function_v2
, 0 },
8523 /* Functions from os.h */
8524 #ifndef SQLITE_OMIT_UTF16
8525 { "add_test_collate", test_collate
, 0 },
8526 { "add_test_collate_needed", test_collate_needed
, 0 },
8527 { "add_test_function", test_function
, 0 },
8528 { "add_test_utf16bin_collate", test_utf16bin_collate
, 0 },
8530 { "sqlite3_test_errstr", test_errstr
, 0 },
8531 { "tcl_variable_type", tcl_variable_type
, 0 },
8532 #ifndef SQLITE_OMIT_SHARED_CACHE
8533 { "sqlite3_enable_shared_cache", test_enable_shared
, 0 },
8534 { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport
, 0},
8536 { "sqlite3_libversion_number", test_libversion_number
, 0 },
8537 { "sqlite3_table_column_metadata", test_table_column_metadata
, 0 },
8538 #ifndef SQLITE_OMIT_INCRBLOB
8539 { "sqlite3_blob_reopen", test_blob_reopen
, 0 },
8541 { "pcache_stats", test_pcache_stats
, 0 },
8542 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
8543 { "sqlite3_unlock_notify", test_unlock_notify
, 0 },
8545 { "sqlite3_wal_checkpoint", test_wal_checkpoint
, 0 },
8546 { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2
, 0 },
8547 { "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint
, 0 },
8548 { "test_sqlite3_log", test_sqlite3_log
, 0 },
8549 #ifndef SQLITE_OMIT_EXPLAIN
8550 { "print_explain_query_plan", test_print_eqp
, 0 },
8552 { "sqlite3_test_control", test_test_control
},
8554 { "getrusage", test_getrusage
},
8556 { "load_static_extension", tclLoadStaticExtensionCmd
},
8557 { "sorter_test_fakeheap", sorter_test_fakeheap
},
8558 { "sorter_test_sort4_helper", sorter_test_sort4_helper
},
8559 #ifdef SQLITE_USER_AUTHENTICATION
8560 { "sqlite3_user_authenticate", test_user_authenticate
, 0 },
8561 { "sqlite3_user_add", test_user_add
, 0 },
8562 { "sqlite3_user_change", test_user_change
, 0 },
8563 { "sqlite3_user_delete", test_user_delete
, 0 },
8565 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
8566 { "sqlite3_stmt_scanstatus", test_stmt_scanstatus
, 0 },
8567 { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset
, 0 },
8569 #ifdef SQLITE_ENABLE_SQLLOG
8570 { "sqlite3_config_sqllog", test_config_sqllog
, 0 },
8572 { "vfs_current_time_int64", vfsCurrentTimeInt64
, 0 },
8573 #ifdef SQLITE_ENABLE_SNAPSHOT
8574 { "sqlite3_snapshot_get", test_snapshot_get
, 0 },
8575 { "sqlite3_snapshot_open", test_snapshot_open
, 0 },
8576 { "sqlite3_snapshot_free", test_snapshot_free
, 0 },
8577 { "sqlite3_snapshot_cmp", test_snapshot_cmp
, 0 },
8578 { "sqlite3_snapshot_recover", test_snapshot_recover
, 0 },
8579 { "sqlite3_snapshot_get_blob", test_snapshot_get_blob
, 0 },
8580 { "sqlite3_snapshot_open_blob", test_snapshot_open_blob
, 0 },
8581 { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob
, 0 },
8583 { "sqlite3_delete_database", test_delete_database
, 0 },
8584 { "atomic_batch_write", test_atomic_batch_write
, 0 },
8585 { "sqlite3_mmap_warm", test_mmap_warm
, 0 },
8586 { "sqlite3_config_sorterref", test_config_sorterref
, 0 },
8587 { "decode_hexdb", test_decode_hexdb
, 0 },
8588 { "test_write_db", test_write_db
, 0 },
8589 { "sqlite3_register_cksumvfs", test_register_cksumvfs
, 0 },
8590 { "sqlite3_unregister_cksumvfs", test_unregister_cksumvfs
, 0 },
8592 static int bitmask_size
= sizeof(Bitmask
)*8;
8593 static int longdouble_size
= sizeof(LONGDOUBLE_TYPE
);
8595 extern int sqlite3_sync_count
, sqlite3_fullsync_count
;
8596 extern int sqlite3_opentemp_count
;
8597 extern int sqlite3_like_count
;
8598 extern int sqlite3_xferopt_count
;
8599 extern int sqlite3_pager_readdb_count
;
8600 extern int sqlite3_pager_writedb_count
;
8601 extern int sqlite3_pager_writej_count
;
8603 extern LONG
volatile sqlite3_os_type
;
8606 extern u32 sqlite3WhereTrace
;
8607 extern int sqlite3OSTrace
;
8608 extern int sqlite3WalTrace
;
8611 #ifdef SQLITE_ENABLE_FTS3
8612 extern int sqlite3_fts3_enable_parentheses
;
8616 for(i
=0; i
<sizeof(aCmd
)/sizeof(aCmd
[0]); i
++){
8617 Tcl_CreateCommand(interp
, aCmd
[i
].zName
, aCmd
[i
].xProc
, 0, 0);
8619 for(i
=0; i
<sizeof(aObjCmd
)/sizeof(aObjCmd
[0]); i
++){
8620 Tcl_CreateObjCommand(interp
, aObjCmd
[i
].zName
,
8621 aObjCmd
[i
].xProc
, aObjCmd
[i
].clientData
, 0);
8623 Tcl_LinkVar(interp
, "sqlite_search_count",
8624 (char*)&sqlite3_search_count
, TCL_LINK_INT
);
8625 Tcl_LinkVar(interp
, "sqlite_found_count",
8626 (char*)&sqlite3_found_count
, TCL_LINK_INT
);
8627 Tcl_LinkVar(interp
, "sqlite_sort_count",
8628 (char*)&sqlite3_sort_count
, TCL_LINK_INT
);
8629 Tcl_LinkVar(interp
, "sqlite3_max_blobsize",
8630 (char*)&sqlite3_max_blobsize
, TCL_LINK_INT
);
8631 Tcl_LinkVar(interp
, "sqlite_like_count",
8632 (char*)&sqlite3_like_count
, TCL_LINK_INT
);
8633 Tcl_LinkVar(interp
, "sqlite_interrupt_count",
8634 (char*)&sqlite3_interrupt_count
, TCL_LINK_INT
);
8635 Tcl_LinkVar(interp
, "sqlite_open_file_count",
8636 (char*)&sqlite3_open_file_count
, TCL_LINK_INT
);
8637 Tcl_LinkVar(interp
, "sqlite_current_time",
8638 (char*)&sqlite3_current_time
, TCL_LINK_INT
);
8639 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
8640 Tcl_LinkVar(interp
, "sqlite_hostid_num",
8641 (char*)&sqlite3_hostid_num
, TCL_LINK_INT
);
8643 Tcl_LinkVar(interp
, "sqlite3_xferopt_count",
8644 (char*)&sqlite3_xferopt_count
, TCL_LINK_INT
);
8645 Tcl_LinkVar(interp
, "sqlite3_pager_readdb_count",
8646 (char*)&sqlite3_pager_readdb_count
, TCL_LINK_INT
);
8647 Tcl_LinkVar(interp
, "sqlite3_pager_writedb_count",
8648 (char*)&sqlite3_pager_writedb_count
, TCL_LINK_INT
);
8649 Tcl_LinkVar(interp
, "sqlite3_pager_writej_count",
8650 (char*)&sqlite3_pager_writej_count
, TCL_LINK_INT
);
8651 #ifndef SQLITE_OMIT_UTF16
8652 Tcl_LinkVar(interp
, "unaligned_string_counter",
8653 (char*)&unaligned_string_counter
, TCL_LINK_INT
);
8655 #ifndef SQLITE_OMIT_UTF16
8656 Tcl_LinkVar(interp
, "sqlite_last_needed_collation",
8657 (char*)&pzNeededCollation
, TCL_LINK_STRING
|TCL_LINK_READ_ONLY
);
8660 Tcl_LinkVar(interp
, "sqlite_os_type",
8661 (char*)&sqlite3_os_type
, TCL_LINK_LONG
);
8665 static const char *query_plan
= "*** OBSOLETE VARIABLE ***";
8666 Tcl_LinkVar(interp
, "sqlite_query_plan",
8667 (char*)&query_plan
, TCL_LINK_STRING
|TCL_LINK_READ_ONLY
);
8671 Tcl_LinkVar(interp
, "sqlite_where_trace",
8672 (char*)&sqlite3WhereTrace
, TCL_LINK_INT
);
8673 Tcl_LinkVar(interp
, "sqlite_os_trace",
8674 (char*)&sqlite3OSTrace
, TCL_LINK_INT
);
8675 #ifndef SQLITE_OMIT_WAL
8676 Tcl_LinkVar(interp
, "sqlite_wal_trace",
8677 (char*)&sqlite3WalTrace
, TCL_LINK_INT
);
8680 #ifndef SQLITE_OMIT_DISKIO
8681 Tcl_LinkVar(interp
, "sqlite_opentemp_count",
8682 (char*)&sqlite3_opentemp_count
, TCL_LINK_INT
);
8684 Tcl_LinkVar(interp
, "sqlite_static_bind_value",
8685 (char*)&sqlite_static_bind_value
, TCL_LINK_STRING
);
8686 Tcl_LinkVar(interp
, "sqlite_static_bind_nbyte",
8687 (char*)&sqlite_static_bind_nbyte
, TCL_LINK_INT
);
8688 Tcl_LinkVar(interp
, "sqlite_temp_directory",
8689 (char*)&sqlite3_temp_directory
, TCL_LINK_STRING
);
8690 Tcl_LinkVar(interp
, "sqlite_data_directory",
8691 (char*)&sqlite3_data_directory
, TCL_LINK_STRING
);
8692 Tcl_LinkVar(interp
, "bitmask_size",
8693 (char*)&bitmask_size
, TCL_LINK_INT
|TCL_LINK_READ_ONLY
);
8694 Tcl_LinkVar(interp
, "longdouble_size",
8695 (char*)&longdouble_size
, TCL_LINK_INT
|TCL_LINK_READ_ONLY
);
8696 Tcl_LinkVar(interp
, "sqlite_sync_count",
8697 (char*)&sqlite3_sync_count
, TCL_LINK_INT
);
8698 Tcl_LinkVar(interp
, "sqlite_fullsync_count",
8699 (char*)&sqlite3_fullsync_count
, TCL_LINK_INT
);
8700 #if defined(SQLITE_ENABLE_SELECTTRACE)
8701 Tcl_LinkVar(interp
, "sqlite3_unsupported_selecttrace",
8702 (char*)&sqlite3SelectTrace
, TCL_LINK_INT
);
8704 #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
8705 Tcl_LinkVar(interp
, "sqlite_fts3_enable_parentheses",
8706 (char*)&sqlite3_fts3_enable_parentheses
, TCL_LINK_INT
);