xref: /sqlite-3.40.0/src/test1.c (revision ef5ecb41)
1 /*
2 ** 2001 September 15
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
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.
10 **
11 *************************************************************************
12 ** Code for testing the printf() interface to SQLite.  This code
13 ** is not included in the SQLite library.  It is used for automated
14 ** testing of the SQLite library.
15 **
16 ** $Id: test1.c,v 1.75 2004/06/10 14:01:08 danielk1977 Exp $
17 */
18 #include "sqliteInt.h"
19 #include "tcl.h"
20 #include "os.h"
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #if OS_WIN
25 # define PTR_FMT "%x"
26 #else
27 # define PTR_FMT "%p"
28 #endif
29 
30 int sqlite3_exec_printf(
31   sqlite *db,                   /* An open database */
32   const char *sqlFormat,        /* printf-style format string for the SQL */
33   sqlite_callback xCallback,    /* Callback function */
34   void *pArg,                   /* 1st argument to callback function */
35   char **errmsg,                /* Error msg written here */
36   ...                           /* Arguments to the format string. */
37 );
38 int sqlite3_exec_printf(
39   sqlite *db,                   /* An open database */
40   const char *sqlFormat,        /* printf-style format string for the SQL */
41   sqlite_callback xCallback,    /* Callback function */
42   void *pArg,                   /* 1st argument to callback function */
43   char **errmsg,                /* Error msg written here */
44   ...                           /* Arguments to the format string. */
45 );
46 int sqlite3_get_table_printf(
47   sqlite *db,            /* An open database */
48   const char *sqlFormat, /* printf-style format string for the SQL */
49   char ***resultp,       /* Result written to a char *[]  that this points to */
50   int *nrow,             /* Number of result rows written here */
51   int *ncol,             /* Number of result columns written here */
52   char **errmsg,         /* Error msg written here */
53   ...                    /* Arguments to the format string */
54 );
55 
56 static const char * errorName(int rc){
57   const char *zName = 0;
58   switch( rc ){
59     case SQLITE_OK:         zName = "SQLITE_OK";          break;
60     case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
61     case SQLITE_INTERNAL:   zName = "SQLITE_INTERNAL";    break;
62     case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
63     case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
64     case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
65     case SQLITE_LOCKED:     zName = "SQLITE_LOCKED";      break;
66     case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
67     case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
68     case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
69     case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
70     case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
71     case SQLITE_NOTFOUND:   zName = "SQLITE_NOTFOUND";    break;
72     case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
73     case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
74     case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
75     case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
76     case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
77     case SQLITE_TOOBIG:     zName = "SQLITE_TOOBIG";      break;
78     case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
79     case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
80     case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
81     case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
82     case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;
83     case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;
84     case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;
85     case SQLITE_ROW:        zName = "SQLITE_ROW";         break;
86     case SQLITE_DONE:       zName = "SQLITE_DONE";        break;
87     default:                zName = "SQLITE_Unknown";     break;
88   }
89   return zName;
90 }
91 
92 /*
93 ** Decode a pointer to an sqlite object.
94 */
95 static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite **ppDb){
96   if( sscanf(zA, PTR_FMT, (void**)ppDb)!=1 &&
97       (zA[0]!='0' || zA[1]!='x' || sscanf(&zA[2], PTR_FMT, (void**)ppDb)!=1)
98   ){
99     Tcl_AppendResult(interp, "\"", zA, "\" is not a valid pointer value", 0);
100     return TCL_ERROR;
101   }
102   return TCL_OK;
103 }
104 
105 /*
106 ** Decode a pointer to an sqlite3_stmt object.
107 */
108 static int getStmtPointer(
109   Tcl_Interp *interp,
110   const char *zArg,
111   sqlite3_stmt **ppStmt
112 ){
113   if( sscanf(zArg, PTR_FMT, (void**)ppStmt)!=1 ){
114     Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);
115     return TCL_ERROR;
116   }
117   return TCL_OK;
118 }
119 
120 /*
121 ** Decode a pointer to an sqlite3_stmt object.
122 */
123 static int getFilePointer(
124   Tcl_Interp *interp,
125   const char *zArg,
126   OsFile **ppFile
127 ){
128   if( sscanf(zArg, PTR_FMT, (void**)ppFile)!=1 ){
129     Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);
130     return TCL_ERROR;
131   }
132   return TCL_OK;
133 }
134 
135 /*
136 ** Generate a text representation of a pointer that can be understood
137 ** by the getDbPointer and getVmPointer routines above.
138 **
139 ** The problem is, on some machines (Solaris) if you do a printf with
140 ** "%p" you cannot turn around and do a scanf with the same "%p" and
141 ** get your pointer back.  You have to prepend a "0x" before it will
142 ** work.  Or at least that is what is reported to me (drh).  But this
143 ** behavior varies from machine to machine.  The solution used her is
144 ** to test the string right after it is generated to see if it can be
145 ** understood by scanf, and if not, try prepending an "0x" to see if
146 ** that helps.  If nothing works, a fatal error is generated.
147 */
148 static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){
149   void *p2;
150   sprintf(zPtr, PTR_FMT, p);
151   if( sscanf(zPtr, PTR_FMT, &p2)!=1 || p2!=p ){
152     sprintf(zPtr, "0x" PTR_FMT, p);
153     if( sscanf(zPtr, PTR_FMT, &p2)!=1 || p2!=p ){
154       Tcl_AppendResult(interp, "unable to convert a pointer to a string "
155          "in the file " __FILE__ " in function makePointerStr().  Please "
156          "report this problem to the SQLite mailing list or as a new but "
157          "report.  Please provide detailed information about how you compiled "
158          "SQLite and what computer you are running on.", 0);
159       return TCL_ERROR;
160     }
161   }
162   return TCL_OK;
163 }
164 
165 /*
166 ** The callback routine for sqlite3_exec_printf().
167 */
168 static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){
169   Tcl_DString *str = (Tcl_DString*)pArg;
170   int i;
171 
172   if( Tcl_DStringLength(str)==0 ){
173     for(i=0; i<argc; i++){
174       Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL");
175     }
176   }
177   for(i=0; i<argc; i++){
178     Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL");
179   }
180   return 0;
181 }
182 
183 /*
184 ** Usage:  sqlite3_exec_printf  DB  FORMAT  STRING
185 **
186 ** Invoke the sqlite3_exec_printf() interface using the open database
187 ** DB.  The SQL is the string FORMAT.  The format string should contain
188 ** one %s or %q.  STRING is the value inserted into %s or %q.
189 */
190 static int test_exec_printf(
191   void *NotUsed,
192   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
193   int argc,              /* Number of arguments */
194   char **argv            /* Text of each argument */
195 ){
196   sqlite *db;
197   Tcl_DString str;
198   int rc;
199   char *zErr = 0;
200   char zBuf[30];
201   if( argc!=4 ){
202     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
203        " DB FORMAT STRING", 0);
204     return TCL_ERROR;
205   }
206   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
207   Tcl_DStringInit(&str);
208   rc = sqlite3_exec_printf(db, argv[2], exec_printf_cb, &str, &zErr, argv[3]);
209   sprintf(zBuf, "%d", rc);
210   Tcl_AppendElement(interp, zBuf);
211   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
212   Tcl_DStringFree(&str);
213   if( zErr ) free(zErr);
214   return TCL_OK;
215 }
216 
217 /*
218 ** Usage:  sqlite3_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...
219 **
220 ** Test the %z format of mprintf().  Use multiple mprintf() calls to
221 ** concatenate arg0 through argn using separator as the separator.
222 ** Return the result.
223 */
224 static int test_mprintf_z(
225   void *NotUsed,
226   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
227   int argc,              /* Number of arguments */
228   char **argv            /* Text of each argument */
229 ){
230   char *zResult = 0;
231   int i;
232 
233   for(i=2; i<argc; i++){
234     zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]);
235   }
236   Tcl_AppendResult(interp, zResult, 0);
237   sqliteFree(zResult);
238   return TCL_OK;
239 }
240 
241 /*
242 ** Usage:  sqlite3_get_table_printf  DB  FORMAT  STRING
243 **
244 ** Invoke the sqlite3_get_table_printf() interface using the open database
245 ** DB.  The SQL is the string FORMAT.  The format string should contain
246 ** one %s or %q.  STRING is the value inserted into %s or %q.
247 */
248 static int test_get_table_printf(
249   void *NotUsed,
250   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
251   int argc,              /* Number of arguments */
252   char **argv            /* Text of each argument */
253 ){
254   sqlite *db;
255   Tcl_DString str;
256   int rc;
257   char *zErr = 0;
258   int nRow, nCol;
259   char **aResult;
260   int i;
261   char zBuf[30];
262   if( argc!=4 ){
263     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
264        " DB FORMAT STRING", 0);
265     return TCL_ERROR;
266   }
267   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
268   Tcl_DStringInit(&str);
269   rc = sqlite3_get_table_printf(db, argv[2], &aResult, &nRow, &nCol,
270                &zErr, argv[3]);
271   sprintf(zBuf, "%d", rc);
272   Tcl_AppendElement(interp, zBuf);
273   if( rc==SQLITE_OK ){
274     sprintf(zBuf, "%d", nRow);
275     Tcl_AppendElement(interp, zBuf);
276     sprintf(zBuf, "%d", nCol);
277     Tcl_AppendElement(interp, zBuf);
278     for(i=0; i<(nRow+1)*nCol; i++){
279       Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
280     }
281   }else{
282     Tcl_AppendElement(interp, zErr);
283   }
284   sqlite3_free_table(aResult);
285   if( zErr ) free(zErr);
286   return TCL_OK;
287 }
288 
289 
290 /*
291 ** Usage:  sqlite3_last_insert_rowid DB
292 **
293 ** Returns the integer ROWID of the most recent insert.
294 */
295 static int test_last_rowid(
296   void *NotUsed,
297   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
298   int argc,              /* Number of arguments */
299   char **argv            /* Text of each argument */
300 ){
301   sqlite *db;
302   char zBuf[30];
303 
304   if( argc!=2 ){
305     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0);
306     return TCL_ERROR;
307   }
308   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
309   sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db));
310   Tcl_AppendResult(interp, zBuf, 0);
311   return SQLITE_OK;
312 }
313 
314 /*
315 ** Usage:  sqlite3_close DB
316 **
317 ** Closes the database opened by sqlite3_open.
318 */
319 static int sqlite_test_close(
320   void *NotUsed,
321   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
322   int argc,              /* Number of arguments */
323   char **argv            /* Text of each argument */
324 ){
325   sqlite *db;
326   if( argc!=2 ){
327     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
328        " FILENAME\"", 0);
329     return TCL_ERROR;
330   }
331   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
332   sqlite3_close(db);
333   return TCL_OK;
334 }
335 
336 /*
337 ** Implementation of the x_coalesce() function.
338 ** Return the first argument non-NULL argument.
339 */
340 static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
341   int i;
342   for(i=0; i<argc; i++){
343     if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
344       sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1, 1);
345       break;
346     }
347   }
348 }
349 
350 /*
351 ** A structure into which to accumulate text.
352 */
353 struct dstr {
354   int nAlloc;  /* Space allocated */
355   int nUsed;   /* Space used */
356   char *z;     /* The space */
357 };
358 
359 /*
360 ** Append text to a dstr
361 */
362 static void dstrAppend(struct dstr *p, const char *z, int divider){
363   int n = strlen(z);
364   if( p->nUsed + n + 2 > p->nAlloc ){
365     char *zNew;
366     p->nAlloc = p->nAlloc*2 + n + 200;
367     zNew = sqliteRealloc(p->z, p->nAlloc);
368     if( zNew==0 ){
369       sqliteFree(p->z);
370       memset(p, 0, sizeof(*p));
371       return;
372     }
373     p->z = zNew;
374   }
375   if( divider && p->nUsed>0 ){
376     p->z[p->nUsed++] = divider;
377   }
378   memcpy(&p->z[p->nUsed], z, n+1);
379   p->nUsed += n;
380 }
381 
382 /*
383 ** Invoked for each callback from sqlite3ExecFunc
384 */
385 static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){
386   struct dstr *p = (struct dstr*)pData;
387   int i;
388   for(i=0; i<argc; i++){
389     if( argv[i]==0 ){
390       dstrAppend(p, "NULL", ' ');
391     }else{
392       dstrAppend(p, argv[i], ' ');
393     }
394   }
395   return 0;
396 }
397 
398 /*
399 ** Implementation of the x_sqlite3_exec() function.  This function takes
400 ** a single argument and attempts to execute that argument as SQL code.
401 ** This is illegal and should set the SQLITE_MISUSE flag on the database.
402 **
403 ** 2004-Jan-07:  We have changed this to make it legal to call sqlite3_exec()
404 ** from within a function call.
405 **
406 ** This routine simulates the effect of having two threads attempt to
407 ** use the same database at the same time.
408 */
409 static void sqlite3ExecFunc(
410   sqlite3_context *context,
411   int argc,
412   sqlite3_value **argv
413 ){
414   struct dstr x;
415   memset(&x, 0, sizeof(x));
416   sqlite3_exec((sqlite*)sqlite3_user_data(context),
417       sqlite3_value_text(argv[0]),
418       execFuncCallback, &x, 0);
419   sqlite3_result_text(context, x.z, x.nUsed, 1);
420   sqliteFree(x.z);
421 }
422 
423 /*
424 ** Usage:  sqlite_test_create_function DB
425 **
426 ** Call the sqlite3_create_function API on the given database in order
427 ** to create a function named "x_coalesce".  This function does the same thing
428 ** as the "coalesce" function.  This function also registers an SQL function
429 ** named "x_sqlite3_exec" that invokes sqlite3_exec().  Invoking sqlite3_exec()
430 ** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
431 ** The effect is similar to trying to use the same database connection from
432 ** two threads at the same time.
433 **
434 ** The original motivation for this routine was to be able to call the
435 ** sqlite3_create_function function while a query is in progress in order
436 ** to test the SQLITE_MISUSE detection logic.
437 */
438 static int test_create_function(
439   void *NotUsed,
440   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
441   int argc,              /* Number of arguments */
442   char **argv            /* Text of each argument */
443 ){
444   sqlite *db;
445   extern void Md5_Register(sqlite*);
446   if( argc!=2 ){
447     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
448        " FILENAME\"", 0);
449     return TCL_ERROR;
450   }
451   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
452   sqlite3_create_function(db, "x_coalesce", -1, 0, 0, 0, ifnullFunc, 0, 0);
453   sqlite3_create_function(db, "x_sqlite3_exec", 1, 0, 0, db,
454       sqlite3ExecFunc, 0, 0);
455   return TCL_OK;
456 }
457 
458 /*
459 ** Routines to implement the x_count() aggregate function.
460 */
461 typedef struct CountCtx CountCtx;
462 struct CountCtx {
463   int n;
464 };
465 static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
466   CountCtx *p;
467   p = sqlite3_aggregate_context(context, sizeof(*p));
468   if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){
469     p->n++;
470   }
471 }
472 static void countFinalize(sqlite3_context *context){
473   CountCtx *p;
474   p = sqlite3_aggregate_context(context, sizeof(*p));
475   sqlite3_result_int(context, p ? p->n : 0);
476 }
477 
478 /*
479 ** Usage:  sqlite_test_create_aggregate DB
480 **
481 ** Call the sqlite3_create_function API on the given database in order
482 ** to create a function named "x_count".  This function does the same thing
483 ** as the "md5sum" function.
484 **
485 ** The original motivation for this routine was to be able to call the
486 ** sqlite3_create_aggregate function while a query is in progress in order
487 ** to test the SQLITE_MISUSE detection logic.
488 */
489 static int test_create_aggregate(
490   void *NotUsed,
491   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
492   int argc,              /* Number of arguments */
493   char **argv            /* Text of each argument */
494 ){
495   sqlite *db;
496   if( argc!=2 ){
497     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
498        " FILENAME\"", 0);
499     return TCL_ERROR;
500   }
501   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
502   sqlite3_create_function(db, "x_count", 0, 0, 0, 0, 0,countStep,countFinalize);
503   sqlite3_create_function(db, "x_count", 1, 0, 0, 0, 0,countStep,countFinalize);
504   return TCL_OK;
505 }
506 
507 
508 
509 /*
510 ** Usage:  sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER
511 **
512 ** Call mprintf with three integer arguments
513 */
514 static int sqlite3_mprintf_int(
515   void *NotUsed,
516   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
517   int argc,              /* Number of arguments */
518   char **argv            /* Text of each argument */
519 ){
520   int a[3], i;
521   char *z;
522   if( argc!=5 ){
523     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
524        " FORMAT INT INT INT\"", 0);
525     return TCL_ERROR;
526   }
527   for(i=2; i<5; i++){
528     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
529   }
530   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
531   Tcl_AppendResult(interp, z, 0);
532   sqlite3_free(z);
533   return TCL_OK;
534 }
535 
536 /*
537 ** Usage:  sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING
538 **
539 ** Call mprintf with two integer arguments and one string argument
540 */
541 static int sqlite3_mprintf_str(
542   void *NotUsed,
543   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
544   int argc,              /* Number of arguments */
545   char **argv            /* Text of each argument */
546 ){
547   int a[3], i;
548   char *z;
549   if( argc<4 || argc>5 ){
550     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
551        " FORMAT INT INT ?STRING?\"", 0);
552     return TCL_ERROR;
553   }
554   for(i=2; i<4; i++){
555     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
556   }
557   z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL);
558   Tcl_AppendResult(interp, z, 0);
559   sqlite3_free(z);
560   return TCL_OK;
561 }
562 
563 /*
564 ** Usage:  sqlite3_mprintf_str FORMAT INTEGER INTEGER DOUBLE
565 **
566 ** Call mprintf with two integer arguments and one double argument
567 */
568 static int sqlite3_mprintf_double(
569   void *NotUsed,
570   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
571   int argc,              /* Number of arguments */
572   char **argv            /* Text of each argument */
573 ){
574   int a[3], i;
575   double r;
576   char *z;
577   if( argc!=5 ){
578     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
579        " FORMAT INT INT STRING\"", 0);
580     return TCL_ERROR;
581   }
582   for(i=2; i<4; i++){
583     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
584   }
585   if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR;
586   z = sqlite3_mprintf(argv[1], a[0], a[1], r);
587   Tcl_AppendResult(interp, z, 0);
588   sqlite3_free(z);
589   return TCL_OK;
590 }
591 
592 /*
593 ** Usage:  sqlite3_mprintf_str FORMAT DOUBLE DOUBLE
594 **
595 ** Call mprintf with a single double argument which is the product of the
596 ** two arguments given above.  This is used to generate overflow and underflow
597 ** doubles to test that they are converted properly.
598 */
599 static int sqlite3_mprintf_scaled(
600   void *NotUsed,
601   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
602   int argc,              /* Number of arguments */
603   char **argv            /* Text of each argument */
604 ){
605   int i;
606   double r[2];
607   char *z;
608   if( argc!=4 ){
609     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
610        " FORMAT DOUBLE DOUBLE\"", 0);
611     return TCL_ERROR;
612   }
613   for(i=2; i<4; i++){
614     if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR;
615   }
616   z = sqlite3_mprintf(argv[1], r[0]*r[1]);
617   Tcl_AppendResult(interp, z, 0);
618   sqlite3_free(z);
619   return TCL_OK;
620 }
621 
622 /*
623 ** Usage: sqlite_malloc_fail N
624 **
625 ** Rig sqliteMalloc() to fail on the N-th call.  Turn off this mechanism
626 ** and reset the sqlite3_malloc_failed variable is N==0.
627 */
628 #ifdef SQLITE_DEBUG
629 static int sqlite_malloc_fail(
630   void *NotUsed,
631   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
632   int argc,              /* Number of arguments */
633   char **argv            /* Text of each argument */
634 ){
635   int n;
636   if( argc!=2 ){
637     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0);
638     return TCL_ERROR;
639   }
640   if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
641   sqlite3_iMallocFail = n;
642   sqlite3_malloc_failed = 0;
643   return TCL_OK;
644 }
645 #endif
646 
647 /*
648 ** Usage: sqlite_malloc_stat
649 **
650 ** Return the number of prior calls to sqliteMalloc() and sqliteFree().
651 */
652 #ifdef SQLITE_DEBUG
653 static int sqlite_malloc_stat(
654   void *NotUsed,
655   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
656   int argc,              /* Number of arguments */
657   char **argv            /* Text of each argument */
658 ){
659   char zBuf[200];
660   sprintf(zBuf, "%d %d %d", sqlite3_nMalloc, sqlite3_nFree, sqlite3_iMallocFail);
661   Tcl_AppendResult(interp, zBuf, 0);
662   return TCL_OK;
663 }
664 #endif
665 
666 /*
667 ** Usage:  sqlite_abort
668 **
669 ** Shutdown the process immediately.  This is not a clean shutdown.
670 ** This command is used to test the recoverability of a database in
671 ** the event of a program crash.
672 */
673 static int sqlite_abort(
674   void *NotUsed,
675   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
676   int argc,              /* Number of arguments */
677   char **argv            /* Text of each argument */
678 ){
679   assert( interp==0 );   /* This will always fail */
680   return TCL_OK;
681 }
682 
683 /*
684 ** The following routine is a user-defined SQL function whose purpose
685 ** is to test the sqlite_set_result() API.
686 */
687 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
688   while( argc>=2 ){
689     const char *zArg0 = sqlite3_value_text(argv[0]);
690     if( zArg0 ){
691       if( 0==sqlite3StrICmp(zArg0, "int") ){
692         sqlite3_result_int(context, sqlite3_value_int(argv[1]));
693       }else if( sqlite3StrICmp(zArg0,"int64")==0 ){
694         sqlite3_result_int64(context, sqlite3_value_int64(argv[1]));
695       }else if( sqlite3StrICmp(zArg0,"string")==0 ){
696         sqlite3_result_text(context, sqlite3_value_text(argv[1]), -1, 1);
697       }else if( sqlite3StrICmp(zArg0,"double")==0 ){
698         sqlite3_result_double(context, sqlite3_value_double(argv[1]));
699       }else if( sqlite3StrICmp(zArg0,"null")==0 ){
700         sqlite3_result_null(context);
701       }else if( sqlite3StrICmp(zArg0,"value")==0 ){
702         sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]);
703       }else{
704         goto error_out;
705       }
706     }else{
707       goto error_out;
708     }
709     argc -= 2;
710     argv += 2;
711   }
712   return;
713 
714 error_out:
715   sqlite3_result_error(context,"first argument should be one of: "
716       "int int64 string double null value", -1);
717 }
718 
719 /*
720 ** Usage:   sqlite_register_test_function  DB  NAME
721 **
722 ** Register the test SQL function on the database DB under the name NAME.
723 */
724 static int test_register_func(
725   void *NotUsed,
726   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
727   int argc,              /* Number of arguments */
728   char **argv            /* Text of each argument */
729 ){
730   sqlite *db;
731   int rc;
732   if( argc!=3 ){
733     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
734        " DB FUNCTION-NAME", 0);
735     return TCL_ERROR;
736   }
737   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
738   rc = sqlite3_create_function(db, argv[2], -1, 0, 0, 0, testFunc, 0, 0);
739   if( rc!=0 ){
740     Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
741     return TCL_ERROR;
742   }
743   return TCL_OK;
744 }
745 
746 /*
747 ** Usage:  sqlite3_finalize  STMT
748 **
749 ** Finalize a statement handle.
750 */
751 static int test_finalize(
752   void * clientData,
753   Tcl_Interp *interp,
754   int objc,
755   Tcl_Obj *CONST objv[]
756 ){
757   sqlite3_stmt *pStmt;
758   int rc;
759 
760   if( objc!=2 ){
761     Tcl_AppendResult(interp, "wrong # args: should be \"",
762         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
763     return TCL_ERROR;
764   }
765 
766   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
767 
768   rc = sqlite3_finalize(pStmt);
769   Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
770   if( rc ){
771     return TCL_ERROR;
772   }
773   return TCL_OK;
774 }
775 
776 /*
777 ** Usage:  sqlite3_reset  STMT
778 **
779 ** Finalize a statement handle.
780 */
781 static int test_reset(
782   void * clientData,
783   Tcl_Interp *interp,
784   int objc,
785   Tcl_Obj *CONST objv[]
786 ){
787   sqlite3_stmt *pStmt;
788   int rc;
789 
790   if( objc!=2 ){
791     Tcl_AppendResult(interp, "wrong # args: should be \"",
792         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
793     return TCL_ERROR;
794   }
795 
796   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
797 
798   rc = sqlite3_reset(pStmt);
799   if( rc ){
800     return TCL_ERROR;
801   }
802   return TCL_OK;
803 }
804 
805 /*
806 ** Usage:  sqlite3_reset   VM
807 **
808 ** Reset a virtual machine and prepare it to be run again.
809 */
810 
811 /*
812 ** This is the "static_bind_value" that variables are bound to when
813 ** the FLAG option of sqlite3_bind is "static"
814 */
815 static char *sqlite_static_bind_value = 0;
816 
817 /*
818 ** Usage:  sqlite3_bind  VM  IDX  VALUE  FLAGS
819 **
820 ** Sets the value of the IDX-th occurance of "?" in the original SQL
821 ** string.  VALUE is the new value.  If FLAGS=="null" then VALUE is
822 ** ignored and the value is set to NULL.  If FLAGS=="static" then
823 ** the value is set to the value of a static variable named
824 ** "sqlite_static_bind_value".  If FLAGS=="normal" then a copy
825 ** of the VALUE is made.
826 */
827 static int test_bind(
828   void *NotUsed,
829   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
830   int argc,              /* Number of arguments */
831   char **argv            /* Text of each argument */
832 ){
833   sqlite3_stmt *pStmt;
834   int rc;
835   int idx;
836   if( argc!=5 ){
837     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
838        " VM IDX VALUE (null|static|normal)\"", 0);
839     return TCL_ERROR;
840   }
841   if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR;
842   if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR;
843   if( strcmp(argv[4],"null")==0 ){
844     rc = sqlite3_bind_null(pStmt, idx);
845   }else if( strcmp(argv[4],"static")==0 ){
846     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0);
847   }else if( strcmp(argv[4],"normal")==0 ){
848     rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, 1);
849   }else{
850     Tcl_AppendResult(interp, "4th argument should be "
851         "\"null\" or \"static\" or \"normal\"", 0);
852     return TCL_ERROR;
853   }
854   if( rc ){
855     char zBuf[50];
856     sprintf(zBuf, "(%d) ", rc);
857     Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0);
858     return TCL_ERROR;
859   }
860   return TCL_OK;
861 }
862 
863 
864 /*
865 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be>
866 **
867 ** This function is used to test that SQLite selects the correct collation
868 ** sequence callback when multiple versions (for different text encodings)
869 ** are available.
870 **
871 ** Calling this routine registers the collation sequence "test_collate"
872 ** with database handle <db>. The second argument must be a list of three
873 ** boolean values. If the first is true, then a version of test_collate is
874 ** registered for UTF-8, if the second is true, a version is registered for
875 ** UTF-16le, if the third is true, a UTF-16be version is available.
876 ** Previous versions of test_collate are deleted.
877 **
878 ** The collation sequence test_collate is implemented by calling the
879 ** following TCL script:
880 **
881 **   "test_collate <enc> <lhs> <rhs>"
882 **
883 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8.
884 ** The <enc> parameter is the encoding of the collation function that
885 ** SQLite selected to call. The TCL test script implements the
886 ** "test_collate" proc.
887 **
888 ** Note that this will only work with one intepreter at a time, as the
889 ** interp pointer to use when evaluating the TCL script is stored in
890 ** pTestCollateInterp.
891 */
892 static Tcl_Interp* pTestCollateInterp;
893 static int test_collate_func(
894   void *pCtx,
895   int nA, const void *zA,
896   int nB, const void *zB
897 ){
898   Tcl_Interp *i = pTestCollateInterp;
899   int encin = (int)pCtx;
900   int res;
901 
902   sqlite3_value *pVal;
903   Tcl_Obj *pX;
904 
905   pX = Tcl_NewStringObj("test_collate", -1);
906   Tcl_IncrRefCount(pX);
907 
908   switch( encin ){
909     case SQLITE_UTF8:
910       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1));
911       break;
912     case SQLITE_UTF16LE:
913       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1));
914       break;
915     case SQLITE_UTF16BE:
916       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1));
917       break;
918     default:
919       assert(0);
920   }
921 
922   pVal = sqlite3ValueNew();
923   sqlite3ValueSetStr(pVal, nA, zA, encin);
924   Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1));
925   sqlite3ValueSetStr(pVal, nB, zB, encin);
926   Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1));
927   sqlite3ValueFree(pVal);
928 
929   Tcl_EvalObjEx(i, pX, 0);
930   Tcl_DecrRefCount(pX);
931   Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res);
932   return res;
933 }
934 static int test_collate(
935   void * clientData,
936   Tcl_Interp *interp,
937   int objc,
938   Tcl_Obj *CONST objv[]
939 ){
940   sqlite3 *db;
941   int val;
942 
943   if( objc!=5 ) goto bad_args;
944   pTestCollateInterp = interp;
945   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
946 
947   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
948   sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
949         (void *)SQLITE_UTF8, val?test_collate_func:0);
950   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
951   sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
952         (void *)SQLITE_UTF16LE, val?test_collate_func:0);
953   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
954   sqlite3_create_collation(db, "test_collate", SQLITE_UTF16BE,
955         (void *)SQLITE_UTF16BE, val?test_collate_func:0);
956 
957   return TCL_OK;
958 
959 bad_args:
960   Tcl_AppendResult(interp, "wrong # args: should be \"",
961       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
962   return TCL_ERROR;
963 }
964 
965 /*
966 ** Usage:    breakpoint
967 **
968 ** This routine exists for one purpose - to provide a place to put a
969 ** breakpoint with GDB that can be triggered using TCL code.  The use
970 ** for this is when a particular test fails on (say) the 1485th iteration.
971 ** In the TCL test script, we can add code like this:
972 **
973 **     if {$i==1485} breakpoint
974 **
975 ** Then run testfixture in the debugger and wait for the breakpoint to
976 ** fire.  Then additional breakpoints can be set to trace down the bug.
977 */
978 static int test_breakpoint(
979   void *NotUsed,
980   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
981   int argc,              /* Number of arguments */
982   char **argv            /* Text of each argument */
983 ){
984   return TCL_OK;         /* Do nothing */
985 }
986 
987 static int test_bind_int32(
988   void * clientData,
989   Tcl_Interp *interp,
990   int objc,
991   Tcl_Obj *CONST objv[]
992 ){
993   sqlite3_stmt *pStmt;
994   int idx;
995   int value;
996   int rc;
997 
998   if( objc!=4 ){
999     Tcl_AppendResult(interp, "wrong # args: should be \"",
1000         Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0);
1001     return TCL_ERROR;
1002   }
1003 
1004   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1005   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1006   if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
1007 
1008   rc = sqlite3_bind_int(pStmt, idx, value);
1009   if( rc!=SQLITE_OK ){
1010     return TCL_ERROR;
1011   }
1012 
1013   return TCL_OK;
1014 }
1015 
1016 static int test_bind_int64(
1017   void * clientData,
1018   Tcl_Interp *interp,
1019   int objc,
1020   Tcl_Obj *CONST objv[]
1021 ){
1022   sqlite3_stmt *pStmt;
1023   int idx;
1024   i64 value;
1025   int rc;
1026 
1027   if( objc!=4 ){
1028     Tcl_AppendResult(interp, "wrong # args: should be \"",
1029         Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0);
1030     return TCL_ERROR;
1031   }
1032 
1033   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1034   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1035   if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
1036 
1037   rc = sqlite3_bind_int64(pStmt, idx, value);
1038   if( rc!=SQLITE_OK ){
1039     return TCL_ERROR;
1040   }
1041 
1042   return TCL_OK;
1043 }
1044 
1045 static int test_bind_double(
1046   void * clientData,
1047   Tcl_Interp *interp,
1048   int objc,
1049   Tcl_Obj *CONST objv[]
1050 ){
1051   sqlite3_stmt *pStmt;
1052   int idx;
1053   double value;
1054   int rc;
1055 
1056   if( objc!=4 ){
1057     Tcl_AppendResult(interp, "wrong # args: should be \"",
1058         Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0);
1059     return TCL_ERROR;
1060   }
1061 
1062   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1063   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1064   if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR;
1065 
1066   rc = sqlite3_bind_double(pStmt, idx, value);
1067   if( rc!=SQLITE_OK ){
1068     return TCL_ERROR;
1069   }
1070 
1071   return TCL_OK;
1072 }
1073 
1074 static int test_bind_null(
1075   void * clientData,
1076   Tcl_Interp *interp,
1077   int objc,
1078   Tcl_Obj *CONST objv[]
1079 ){
1080   sqlite3_stmt *pStmt;
1081   int idx;
1082   int rc;
1083 
1084   if( objc!=3 ){
1085     Tcl_AppendResult(interp, "wrong # args: should be \"",
1086         Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.>", 0);
1087     return TCL_ERROR;
1088   }
1089 
1090   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1091   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1092 
1093   rc = sqlite3_bind_null(pStmt, idx);
1094   if( rc!=SQLITE_OK ){
1095     return TCL_ERROR;
1096   }
1097 
1098   return TCL_OK;
1099 }
1100 
1101 static int test_bind_text(
1102   void * clientData,
1103   Tcl_Interp *interp,
1104   int objc,
1105   Tcl_Obj *CONST objv[]
1106 ){
1107   sqlite3_stmt *pStmt;
1108   int idx;
1109   int bytes;
1110   char *value;
1111   int rc;
1112 
1113   if( objc!=5 ){
1114     Tcl_AppendResult(interp, "wrong # args: should be \"",
1115         Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>"
1116         " <bytes>", 0);
1117     return TCL_ERROR;
1118   }
1119 
1120   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1121   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1122   value = Tcl_GetString(objv[3]);
1123   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
1124 
1125   rc = sqlite3_bind_text(pStmt, idx, value, bytes, 1);
1126   if( rc!=SQLITE_OK ){
1127     return TCL_ERROR;
1128   }
1129 
1130   return TCL_OK;
1131 }
1132 
1133 static int test_bind_text16(
1134   void * clientData,
1135   Tcl_Interp *interp,
1136   int objc,
1137   Tcl_Obj *CONST objv[]
1138 ){
1139   sqlite3_stmt *pStmt;
1140   int idx;
1141   int bytes;
1142   char *value;
1143   int rc;
1144 
1145   if( objc!=5 ){
1146     Tcl_AppendResult(interp, "wrong # args: should be \"",
1147         Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>"
1148         " <bytes>", 0);
1149     return TCL_ERROR;
1150   }
1151 
1152   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1153   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1154   value = Tcl_GetByteArrayFromObj(objv[3], 0);
1155   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
1156 
1157   rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, 1);
1158   if( rc!=SQLITE_OK ){
1159     return TCL_ERROR;
1160   }
1161 
1162   return TCL_OK;
1163 }
1164 
1165 static int test_bind_blob(
1166   void * clientData,
1167   Tcl_Interp *interp,
1168   int objc,
1169   Tcl_Obj *CONST objv[]
1170 ){
1171   sqlite3_stmt *pStmt;
1172   int idx;
1173   int bytes;
1174   char *value;
1175   int rc;
1176 
1177   if( objc!=5 ){
1178     Tcl_AppendResult(interp, "wrong # args: should be \"",
1179         Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>"
1180         " <bytes>", 0);
1181     return TCL_ERROR;
1182   }
1183 
1184   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1185   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
1186   value = Tcl_GetString(objv[3]);
1187   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
1188 
1189   rc = sqlite3_bind_blob(pStmt, idx, value, bytes, 1);
1190   if( rc!=SQLITE_OK ){
1191     return TCL_ERROR;
1192   }
1193 
1194   return TCL_OK;
1195 }
1196 
1197 /*
1198 ** Usage: sqlite3_errcode DB
1199 **
1200 ** Return the string representation of the most recent sqlite3_* API
1201 ** error code. e.g. "SQLITE_ERROR".
1202 */
1203 static int test_errcode(
1204   void * clientData,
1205   Tcl_Interp *interp,
1206   int objc,
1207   Tcl_Obj *CONST objv[]
1208 ){
1209   sqlite3 *db;
1210 
1211   if( objc!=2 ){
1212     Tcl_AppendResult(interp, "wrong # args: should be \"",
1213        Tcl_GetString(objv[0]), " DB", 0);
1214     return TCL_ERROR;
1215   }
1216   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1217   Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0);
1218   return TCL_OK;
1219 }
1220 
1221 /*
1222 ** Usage:   test_errmsg DB
1223 **
1224 ** Returns the UTF-8 representation of the error message string for the
1225 ** most recent sqlite3_* API call.
1226 */
1227 static int test_errmsg(
1228   void * clientData,
1229   Tcl_Interp *interp,
1230   int objc,
1231   Tcl_Obj *CONST objv[]
1232 ){
1233   sqlite *db;
1234   const char *zErr;
1235 
1236   if( objc!=2 ){
1237     Tcl_AppendResult(interp, "wrong # args: should be \"",
1238        Tcl_GetString(objv[0]), " DB", 0);
1239     return TCL_ERROR;
1240   }
1241   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1242 
1243   zErr = sqlite3_errmsg(db);
1244   Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
1245   return TCL_OK;
1246 }
1247 
1248 /*
1249 ** Usage:   test_errmsg16 DB
1250 **
1251 ** Returns the UTF-16 representation of the error message string for the
1252 ** most recent sqlite3_* API call. This is a byte array object at the TCL
1253 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the
1254 ** UTF-16 string.
1255 */
1256 static int test_errmsg16(
1257   void * clientData,
1258   Tcl_Interp *interp,
1259   int objc,
1260   Tcl_Obj *CONST objv[]
1261 ){
1262   sqlite *db;
1263   const void *zErr;
1264   int bytes;
1265 
1266   if( objc!=2 ){
1267     Tcl_AppendResult(interp, "wrong # args: should be \"",
1268        Tcl_GetString(objv[0]), " DB", 0);
1269     return TCL_ERROR;
1270   }
1271   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1272 
1273   zErr = sqlite3_errmsg16(db);
1274   bytes = sqlite3utf16ByteLen(zErr, -1);
1275   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes));
1276   return TCL_OK;
1277 }
1278 
1279 /*
1280 ** Usage: sqlite3_prepare DB sql bytes tailvar
1281 **
1282 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
1283 ** database handle <DB>. The parameter <tailval> is the name of a global
1284 ** variable that is set to the unused portion of <sql> (if any). A
1285 ** STMT handle is returned.
1286 */
1287 static int test_prepare(
1288   void * clientData,
1289   Tcl_Interp *interp,
1290   int objc,
1291   Tcl_Obj *CONST objv[]
1292 ){
1293   sqlite3 *db;
1294   const char *zSql;
1295   int bytes;
1296   const char *zTail = 0;
1297   sqlite3_stmt *pStmt = 0;
1298   char zBuf[50];
1299   int rc;
1300 
1301   if( objc!=5 ){
1302     Tcl_AppendResult(interp, "wrong # args: should be \"",
1303        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
1304     return TCL_ERROR;
1305   }
1306   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1307   zSql = Tcl_GetString(objv[2]);
1308   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
1309 
1310   rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail);
1311   if( zTail ){
1312     if( bytes>=0 ){
1313       bytes = bytes - (zTail-zSql);
1314     }
1315     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
1316   }
1317   if( rc!=SQLITE_OK ){
1318     assert( pStmt==0 );
1319     sprintf(zBuf, "(%d) ", rc);
1320     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
1321     return TCL_ERROR;
1322   }
1323 
1324   if( pStmt ){
1325     if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
1326     Tcl_AppendResult(interp, zBuf, 0);
1327   }
1328   return TCL_OK;
1329 }
1330 
1331 /*
1332 ** Usage: sqlite3_prepare DB sql bytes tailvar
1333 **
1334 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
1335 ** database handle <DB>. The parameter <tailval> is the name of a global
1336 ** variable that is set to the unused portion of <sql> (if any). A
1337 ** STMT handle is returned.
1338 */
1339 static int test_prepare16(
1340   void * clientData,
1341   Tcl_Interp *interp,
1342   int objc,
1343   Tcl_Obj *CONST objv[]
1344 ){
1345   sqlite3 *db;
1346   const void *zSql;
1347   const void *zTail = 0;
1348   Tcl_Obj *pTail = 0;
1349   sqlite3_stmt *pStmt = 0;
1350   char zBuf[50];
1351   int bytes;                /* The integer specified as arg 3 */
1352   int objlen;               /* The byte-array length of arg 2 */
1353 
1354   if( objc!=5 ){
1355     Tcl_AppendResult(interp, "wrong # args: should be \"",
1356        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
1357     return TCL_ERROR;
1358   }
1359   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1360   zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
1361   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
1362 
1363   if( SQLITE_OK!=sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail) ){
1364     return TCL_ERROR;
1365   }
1366 
1367   if( zTail ){
1368     objlen = objlen - ((u8 *)zTail-(u8 *)zSql);
1369   }else{
1370     objlen = 0;
1371   }
1372   pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
1373   Tcl_IncrRefCount(pTail);
1374   Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
1375   Tcl_DecrRefCount(pTail);
1376 
1377   if( pStmt ){
1378     if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
1379   }
1380   Tcl_AppendResult(interp, zBuf, 0);
1381   return TCL_OK;
1382 }
1383 
1384 /*
1385 ** Usage: sqlite3_open filename ?options-list?
1386 */
1387 static int test_open(
1388   void * clientData,
1389   Tcl_Interp *interp,
1390   int objc,
1391   Tcl_Obj *CONST objv[]
1392 ){
1393   const char *zFilename;
1394   sqlite3 *db;
1395   int rc;
1396   char zBuf[100];
1397 
1398   if( objc!=3 && objc!=2 ){
1399     Tcl_AppendResult(interp, "wrong # args: should be \"",
1400        Tcl_GetString(objv[0]), " filename options-list", 0);
1401     return TCL_ERROR;
1402   }
1403 
1404   zFilename = Tcl_GetString(objv[1]);
1405   rc = sqlite3_open(zFilename, &db);
1406 
1407   if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
1408   Tcl_AppendResult(interp, zBuf, 0);
1409   return TCL_OK;
1410 }
1411 
1412 /*
1413 ** Usage: sqlite3_open16 filename options
1414 */
1415 static int test_open16(
1416   void * clientData,
1417   Tcl_Interp *interp,
1418   int objc,
1419   Tcl_Obj *CONST objv[]
1420 ){
1421   const void *zFilename;
1422   sqlite3 *db;
1423   int rc;
1424   char zBuf[100];
1425 
1426   if( objc!=3 ){
1427     Tcl_AppendResult(interp, "wrong # args: should be \"",
1428        Tcl_GetString(objv[0]), " filename options-list", 0);
1429     return TCL_ERROR;
1430   }
1431 
1432   zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
1433   rc = sqlite3_open16(zFilename, &db);
1434 
1435   if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
1436   Tcl_AppendResult(interp, zBuf, 0);
1437   return TCL_OK;
1438 }
1439 
1440 /*
1441 ** Usage: sqlite3_step STMT
1442 **
1443 ** Advance the statement to the next row.
1444 */
1445 static int test_step(
1446   void * clientData,
1447   Tcl_Interp *interp,
1448   int objc,
1449   Tcl_Obj *CONST objv[]
1450 ){
1451   sqlite3_stmt *pStmt;
1452   int rc;
1453 
1454   if( objc!=2 ){
1455     Tcl_AppendResult(interp, "wrong # args: should be \"",
1456        Tcl_GetString(objv[0]), " STMT", 0);
1457     return TCL_ERROR;
1458   }
1459 
1460   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1461   rc = sqlite3_step(pStmt);
1462 
1463   if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR;
1464   Tcl_SetResult(interp, (char *)errorName(rc), 0);
1465   return TCL_OK;
1466 }
1467 
1468 /*
1469 ** Usage: sqlite3_column_count STMT
1470 **
1471 ** Return the number of columns returned by the sql statement STMT.
1472 */
1473 static int test_column_count(
1474   void * clientData,
1475   Tcl_Interp *interp,
1476   int objc,
1477   Tcl_Obj *CONST objv[]
1478 ){
1479   sqlite3_stmt *pStmt;
1480 
1481   if( objc!=2 ){
1482     Tcl_AppendResult(interp, "wrong # args: should be \"",
1483        Tcl_GetString(objv[0]), " STMT column", 0);
1484     return TCL_ERROR;
1485   }
1486 
1487   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1488 
1489   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt)));
1490   return TCL_OK;
1491 }
1492 
1493 /*
1494 ** Usage: sqlite3_column_type STMT column
1495 **
1496 ** Return the type of the data in column 'column' of the current row.
1497 */
1498 static int test_column_type(
1499   void * clientData,
1500   Tcl_Interp *interp,
1501   int objc,
1502   Tcl_Obj *CONST objv[]
1503 ){
1504   sqlite3_stmt *pStmt;
1505   int col;
1506   int tp;
1507 
1508   if( objc!=3 ){
1509     Tcl_AppendResult(interp, "wrong # args: should be \"",
1510        Tcl_GetString(objv[0]), " STMT column", 0);
1511     return TCL_ERROR;
1512   }
1513 
1514   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1515   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
1516 
1517   tp = sqlite3_column_type(pStmt, col);
1518   switch( tp ){
1519     case SQLITE_INTEGER:
1520       Tcl_SetResult(interp, "INTEGER", TCL_STATIC);
1521       break;
1522     case SQLITE_NULL:
1523       Tcl_SetResult(interp, "NULL", TCL_STATIC);
1524       break;
1525     case SQLITE_FLOAT:
1526       Tcl_SetResult(interp, "FLOAT", TCL_STATIC);
1527       break;
1528     case SQLITE_TEXT:
1529       Tcl_SetResult(interp, "TEXT", TCL_STATIC);
1530       break;
1531     case SQLITE_BLOB:
1532       Tcl_SetResult(interp, "BLOB", TCL_STATIC);
1533       break;
1534     default:
1535       assert(0);
1536   }
1537 
1538   return TCL_OK;
1539 }
1540 
1541 /*
1542 ** Usage: sqlite3_column_int64 STMT column
1543 **
1544 ** Return the data in column 'column' of the current row cast as an
1545 ** wide (64-bit) integer.
1546 */
1547 static int test_column_int64(
1548   void * clientData,
1549   Tcl_Interp *interp,
1550   int objc,
1551   Tcl_Obj *CONST objv[]
1552 ){
1553   sqlite3_stmt *pStmt;
1554   int col;
1555   i64 iVal;
1556 
1557   if( objc!=3 ){
1558     Tcl_AppendResult(interp, "wrong # args: should be \"",
1559        Tcl_GetString(objv[0]), " STMT column", 0);
1560     return TCL_ERROR;
1561   }
1562 
1563   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1564   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
1565 
1566   iVal = sqlite3_column_int64(pStmt, col);
1567   Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal));
1568   return TCL_OK;
1569 }
1570 
1571 /*
1572 ** Usage: sqlite3_column_blob STMT column
1573 */
1574 static int test_column_blob(
1575   void * clientData,
1576   Tcl_Interp *interp,
1577   int objc,
1578   Tcl_Obj *CONST objv[]
1579 ){
1580   sqlite3_stmt *pStmt;
1581   int col;
1582 
1583   int len;
1584   const void *pBlob;
1585 
1586   if( objc!=3 ){
1587     Tcl_AppendResult(interp, "wrong # args: should be \"",
1588        Tcl_GetString(objv[0]), " STMT column", 0);
1589     return TCL_ERROR;
1590   }
1591 
1592   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1593   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
1594 
1595   pBlob = sqlite3_column_blob(pStmt, col);
1596   len = sqlite3_column_bytes(pStmt, col);
1597   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len));
1598   return TCL_OK;
1599 }
1600 
1601 /*
1602 ** Usage: sqlite3_column_double STMT column
1603 **
1604 ** Return the data in column 'column' of the current row cast as a double.
1605 */
1606 static int test_column_double(
1607   void * clientData,
1608   Tcl_Interp *interp,
1609   int objc,
1610   Tcl_Obj *CONST objv[]
1611 ){
1612   sqlite3_stmt *pStmt;
1613   int col;
1614   double rVal;
1615 
1616   if( objc!=3 ){
1617     Tcl_AppendResult(interp, "wrong # args: should be \"",
1618        Tcl_GetString(objv[0]), " STMT column", 0);
1619     return TCL_ERROR;
1620   }
1621 
1622   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1623   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
1624 
1625   rVal = sqlite3_column_double(pStmt, col);
1626   Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal));
1627   return TCL_OK;
1628 }
1629 
1630 /*
1631 ** Usage: sqlite3_data_count STMT
1632 **
1633 ** Return the number of columns returned by the sql statement STMT.
1634 */
1635 static int test_data_count(
1636   void * clientData,
1637   Tcl_Interp *interp,
1638   int objc,
1639   Tcl_Obj *CONST objv[]
1640 ){
1641   sqlite3_stmt *pStmt;
1642 
1643   if( objc!=2 ){
1644     Tcl_AppendResult(interp, "wrong # args: should be \"",
1645        Tcl_GetString(objv[0]), " STMT column", 0);
1646     return TCL_ERROR;
1647   }
1648 
1649   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1650 
1651   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt)));
1652   return TCL_OK;
1653 }
1654 
1655 /*
1656 ** Usage: sqlite3_column_text STMT column
1657 **
1658 ** Usage: sqlite3_column_decltype STMT column
1659 **
1660 ** Usage: sqlite3_column_name STMT column
1661 */
1662 static int test_stmt_utf8(
1663   void * clientData,
1664   Tcl_Interp *interp,
1665   int objc,
1666   Tcl_Obj *CONST objv[]
1667 ){
1668   sqlite3_stmt *pStmt;
1669   int col;
1670   const char *(*xFunc)(sqlite3_stmt*, int) = clientData;
1671   const char *zRet;
1672 
1673   if( objc!=3 ){
1674     Tcl_AppendResult(interp, "wrong # args: should be \"",
1675        Tcl_GetString(objv[0]), " STMT column", 0);
1676     return TCL_ERROR;
1677   }
1678 
1679   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1680   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
1681   zRet = xFunc(pStmt, col);
1682   if( zRet ){
1683     Tcl_SetResult(interp, (char *)zRet, 0);
1684   }
1685   return TCL_OK;
1686 }
1687 
1688 /*
1689 ** Usage: sqlite3_column_text STMT column
1690 **
1691 ** Usage: sqlite3_column_decltype STMT column
1692 **
1693 ** Usage: sqlite3_column_name STMT column
1694 */
1695 static int test_stmt_utf16(
1696   void * clientData,
1697   Tcl_Interp *interp,
1698   int objc,
1699   Tcl_Obj *CONST objv[]
1700 ){
1701   sqlite3_stmt *pStmt;
1702   int col;
1703   Tcl_Obj *pRet;
1704   const void *zName16;
1705   const void *(*xFunc)(sqlite3_stmt*, int) = clientData;
1706 
1707   if( objc!=3 ){
1708     Tcl_AppendResult(interp, "wrong # args: should be \"",
1709        Tcl_GetString(objv[0]), " STMT column", 0);
1710     return TCL_ERROR;
1711   }
1712 
1713   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1714   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
1715 
1716   zName16 = xFunc(pStmt, col);
1717   if( zName16 ){
1718     pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2);
1719     Tcl_SetObjResult(interp, pRet);
1720   }
1721 
1722   return TCL_OK;
1723 }
1724 
1725 /*
1726 ** Usage: sqlite3_column_int STMT column
1727 **
1728 ** Usage: sqlite3_column_bytes STMT column
1729 **
1730 ** Usage: sqlite3_column_bytes16 STMT column
1731 **
1732 */
1733 static int test_stmt_int(
1734   void * clientData,
1735   Tcl_Interp *interp,
1736   int objc,
1737   Tcl_Obj *CONST objv[]
1738 ){
1739   sqlite3_stmt *pStmt;
1740   int col;
1741   int (*xFunc)(sqlite3_stmt*, int) = clientData;
1742 
1743   if( objc!=3 ){
1744     Tcl_AppendResult(interp, "wrong # args: should be \"",
1745        Tcl_GetString(objv[0]), " STMT column", 0);
1746     return TCL_ERROR;
1747   }
1748 
1749   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
1750   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
1751 
1752   Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col)));
1753   return TCL_OK;
1754 }
1755 
1756 /*
1757 ** Usage:  sqlite3OsOpenReadWrite <filename>
1758 */
1759 static int test_sqlite3OsOpenReadWrite(
1760   void * clientData,
1761   Tcl_Interp *interp,
1762   int objc,
1763   Tcl_Obj *CONST objv[]
1764 ){
1765   OsFile * pFile;
1766   int rc;
1767   int dummy;
1768   char zBuf[100];
1769 
1770   if( objc!=2 ){
1771     Tcl_AppendResult(interp, "wrong # args: should be \"",
1772        Tcl_GetString(objv[0]), " filename", 0);
1773     return TCL_ERROR;
1774   }
1775 
1776   pFile = sqliteMalloc(sizeof(OsFile));
1777   rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy);
1778   if( rc!=SQLITE_OK ){
1779     sqliteFree(pFile);
1780     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
1781     return TCL_ERROR;
1782   }
1783   makePointerStr(interp, zBuf, pFile);
1784   Tcl_SetResult(interp, zBuf, 0);
1785   return TCL_ERROR;
1786 }
1787 
1788 /*
1789 ** Usage:  sqlite3OsClose <file handle>
1790 */
1791 static int test_sqlite3OsClose(
1792   void * clientData,
1793   Tcl_Interp *interp,
1794   int objc,
1795   Tcl_Obj *CONST objv[]
1796 ){
1797   OsFile * pFile;
1798   int rc;
1799 
1800   if( objc!=2 ){
1801     Tcl_AppendResult(interp, "wrong # args: should be \"",
1802        Tcl_GetString(objv[0]), " filehandle", 0);
1803     return TCL_ERROR;
1804   }
1805 
1806   if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
1807     return TCL_ERROR;
1808   }
1809   rc = sqlite3OsClose(pFile);
1810   if( rc!=SQLITE_OK ){
1811     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
1812     return TCL_ERROR;
1813   }
1814   sqliteFree(pFile);
1815   return TCL_OK;
1816 }
1817 
1818 /*
1819 ** Usage:  sqlite3OsLock <file handle> <locktype>
1820 */
1821 static int test_sqlite3OsLock(
1822   void * clientData,
1823   Tcl_Interp *interp,
1824   int objc,
1825   Tcl_Obj *CONST objv[]
1826 ){
1827   OsFile * pFile;
1828   int rc;
1829 
1830   if( objc!=3 ){
1831     Tcl_AppendResult(interp, "wrong # args: should be \"",
1832         Tcl_GetString(objv[0]),
1833         " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
1834     return TCL_ERROR;
1835   }
1836 
1837   if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
1838     return TCL_ERROR;
1839   }
1840 
1841   if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){
1842     rc = sqlite3OsLock(pFile, SHARED_LOCK);
1843   }
1844   else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){
1845     rc = sqlite3OsLock(pFile, RESERVED_LOCK);
1846   }
1847   else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){
1848     rc = sqlite3OsLock(pFile, PENDING_LOCK);
1849   }
1850   else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){
1851     rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK);
1852   }else{
1853     Tcl_AppendResult(interp, "wrong # args: should be \"",
1854         Tcl_GetString(objv[0]),
1855         " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
1856     return TCL_ERROR;
1857   }
1858 
1859   if( rc!=SQLITE_OK ){
1860     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
1861     return TCL_ERROR;
1862   }
1863   return TCL_OK;
1864 }
1865 
1866 /*
1867 ** Usage:  sqlite3OsUnlock <file handle>
1868 */
1869 static int test_sqlite3OsUnlock(
1870   void * clientData,
1871   Tcl_Interp *interp,
1872   int objc,
1873   Tcl_Obj *CONST objv[]
1874 ){
1875   OsFile * pFile;
1876   int rc;
1877 
1878   if( objc!=2 ){
1879     Tcl_AppendResult(interp, "wrong # args: should be \"",
1880        Tcl_GetString(objv[0]), " filehandle", 0);
1881     return TCL_ERROR;
1882   }
1883 
1884   if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
1885     return TCL_ERROR;
1886   }
1887   rc = sqlite3OsUnlock(pFile, NO_LOCK);
1888   if( rc!=SQLITE_OK ){
1889     Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
1890     return TCL_ERROR;
1891   }
1892   return TCL_OK;
1893 }
1894 
1895 /*
1896 ** Register commands with the TCL interpreter.
1897 */
1898 int Sqlitetest1_Init(Tcl_Interp *interp){
1899   extern int sqlite3_search_count;
1900   extern int sqlite3_interrupt_count;
1901   extern int sqlite3_open_file_count;
1902   extern int sqlite3_current_time;
1903   static struct {
1904      char *zName;
1905      Tcl_CmdProc *xProc;
1906   } aCmd[] = {
1907      { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
1908      { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
1909      { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
1910      { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
1911      { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
1912      { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
1913      { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
1914      { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
1915      { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
1916      { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
1917      { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
1918      { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
1919      { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
1920 #ifdef SQLITE_DEBUG
1921      { "sqlite_malloc_fail",            (Tcl_CmdProc*)sqlite_malloc_fail    },
1922      { "sqlite_malloc_stat",            (Tcl_CmdProc*)sqlite_malloc_stat    },
1923 #endif
1924      { "sqlite_bind",                    (Tcl_CmdProc*)test_bind             },
1925      { "breakpoint",                     (Tcl_CmdProc*)test_breakpoint       },
1926   };
1927   static struct {
1928      char *zName;
1929      Tcl_ObjCmdProc *xProc;
1930      void *clientData;
1931   } aObjCmd[] = {
1932      { "sqlite3_bind_int32",            test_bind_int32, 0    },
1933      { "sqlite3_bind_int64",            test_bind_int64 , 0   },
1934      { "sqlite3_bind_double",           test_bind_double, 0   },
1935      { "sqlite3_bind_null",             test_bind_null     ,0 },
1936      { "sqlite3_bind_text",             test_bind_text     ,0 },
1937      { "sqlite3_bind_text16",           test_bind_text16   ,0 },
1938      { "sqlite3_bind_blob",             test_bind_blob     ,0 },
1939      { "sqlite3_errcode",               test_errcode       ,0 },
1940      { "sqlite3_errmsg",                test_errmsg        ,0 },
1941      { "sqlite3_errmsg16",              test_errmsg16      ,0 },
1942      { "sqlite3_open",                  test_open          ,0 },
1943      { "sqlite3_open16",                test_open16        ,0 },
1944 
1945      { "sqlite3_prepare",               test_prepare       ,0 },
1946      { "sqlite3_prepare16",             test_prepare16     ,0 },
1947      { "sqlite3_finalize",              test_finalize      ,0 },
1948      { "sqlite3_reset",                 test_reset         ,0 },
1949      { "sqlite3_step",                  test_step,0 },
1950 
1951      /* sqlite3_column_*() API */
1952      { "sqlite3_column_count",          test_column_count  ,0 },
1953      { "sqlite3_data_count",            test_data_count    ,0 },
1954      { "sqlite3_column_type",           test_column_type   ,0 },
1955      { "sqlite3_column_blob",           test_column_blob   ,0 },
1956      { "sqlite3_column_double",         test_column_double ,0 },
1957      { "sqlite3_column_int64",          test_column_int64  ,0 },
1958      { "sqlite3_column_int", test_stmt_int ,sqlite3_column_int },
1959      { "sqlite3_column_bytes", test_stmt_int ,sqlite3_column_bytes },
1960      { "sqlite3_column_bytes16", test_stmt_int ,sqlite3_column_bytes16 },
1961      { "sqlite3_column_text", test_stmt_utf8,       sqlite3_column_text},
1962      { "sqlite3_column_decltype", test_stmt_utf8,   sqlite3_column_decltype},
1963      { "sqlite3_column_name", test_stmt_utf8,       sqlite3_column_name},
1964      { "sqlite3_column_text16", test_stmt_utf16,    sqlite3_column_text16},
1965      { "sqlite3_column_decltype16", test_stmt_utf16,sqlite3_column_decltype16},
1966      { "sqlite3_column_name16", test_stmt_utf16,    sqlite3_column_name16},
1967 
1968      /* Functions from os.h */
1969      { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
1970      { "sqlite3OsClose",        test_sqlite3OsClose, 0 },
1971      { "sqlite3OsLock",         test_sqlite3OsLock, 0 },
1972      { "sqlite3OsUnlock",       test_sqlite3OsUnlock, 0 },
1973      { "add_test_collate",      test_collate, 0         },
1974 
1975   };
1976   int i;
1977   extern int sqlite3_os_trace;
1978 
1979   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
1980     Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
1981   }
1982   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
1983     Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
1984         aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
1985   }
1986   Tcl_LinkVar(interp, "sqlite_search_count",
1987       (char*)&sqlite3_search_count, TCL_LINK_INT);
1988   Tcl_LinkVar(interp, "sqlite_interrupt_count",
1989       (char*)&sqlite3_interrupt_count, TCL_LINK_INT);
1990   Tcl_LinkVar(interp, "sqlite_open_file_count",
1991       (char*)&sqlite3_open_file_count, TCL_LINK_INT);
1992   Tcl_LinkVar(interp, "sqlite_current_time",
1993       (char*)&sqlite3_current_time, TCL_LINK_INT);
1994   Tcl_LinkVar(interp, "sqlite_os_trace",
1995       (char*)&sqlite3_os_trace, TCL_LINK_INT);
1996   Tcl_LinkVar(interp, "sqlite_static_bind_value",
1997       (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
1998   return TCL_OK;
1999 }
2000