Annotation of embedaddon/sqlite3/src/test1.c, revision 1.1.1.1

1.1       misho       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 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.
                     15: */
                     16: #include "sqliteInt.h"
                     17: #include "vdbeInt.h"
                     18: #include "tcl.h"
                     19: #include <stdlib.h>
                     20: #include <string.h>
                     21: 
                     22: /*
                     23: ** This is a copy of the first part of the SqliteDb structure in 
                     24: ** tclsqlite.c.  We need it here so that the get_sqlite_pointer routine
                     25: ** can extract the sqlite3* pointer from an existing Tcl SQLite
                     26: ** connection.
                     27: */
                     28: struct SqliteDb {
                     29:   sqlite3 *db;
                     30: };
                     31: 
                     32: /*
                     33: ** Convert text generated by the "%p" conversion format back into
                     34: ** a pointer.
                     35: */
                     36: static int testHexToInt(int h){
                     37:   if( h>='0' && h<='9' ){
                     38:     return h - '0';
                     39:   }else if( h>='a' && h<='f' ){
                     40:     return h - 'a' + 10;
                     41:   }else{
                     42:     assert( h>='A' && h<='F' );
                     43:     return h - 'A' + 10;
                     44:   }
                     45: }
                     46: void *sqlite3TestTextToPtr(const char *z){
                     47:   void *p;
                     48:   u64 v;
                     49:   u32 v2;
                     50:   if( z[0]=='0' && z[1]=='x' ){
                     51:     z += 2;
                     52:   }
                     53:   v = 0;
                     54:   while( *z ){
                     55:     v = (v<<4) + testHexToInt(*z);
                     56:     z++;
                     57:   }
                     58:   if( sizeof(p)==sizeof(v) ){
                     59:     memcpy(&p, &v, sizeof(p));
                     60:   }else{
                     61:     assert( sizeof(p)==sizeof(v2) );
                     62:     v2 = (u32)v;
                     63:     memcpy(&p, &v2, sizeof(p));
                     64:   }
                     65:   return p;
                     66: }
                     67: 
                     68: 
                     69: /*
                     70: ** A TCL command that returns the address of the sqlite* pointer
                     71: ** for an sqlite connection instance.  Bad things happen if the
                     72: ** input is not an sqlite connection.
                     73: */
                     74: static int get_sqlite_pointer(
                     75:   void * clientData,
                     76:   Tcl_Interp *interp,
                     77:   int objc,
                     78:   Tcl_Obj *CONST objv[]
                     79: ){
                     80:   struct SqliteDb *p;
                     81:   Tcl_CmdInfo cmdInfo;
                     82:   char zBuf[100];
                     83:   if( objc!=2 ){
                     84:     Tcl_WrongNumArgs(interp, 1, objv, "SQLITE-CONNECTION");
                     85:     return TCL_ERROR;
                     86:   }
                     87:   if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
                     88:     Tcl_AppendResult(interp, "command not found: ",
                     89:            Tcl_GetString(objv[1]), (char*)0);
                     90:     return TCL_ERROR;
                     91:   }
                     92:   p = (struct SqliteDb*)cmdInfo.objClientData;
                     93:   sprintf(zBuf, "%p", p->db);
                     94:   if( strncmp(zBuf,"0x",2) ){
                     95:     sprintf(zBuf, "0x%p", p->db);
                     96:   }
                     97:   Tcl_AppendResult(interp, zBuf, 0);
                     98:   return TCL_OK;
                     99: }
                    100: 
                    101: /*
                    102: ** Decode a pointer to an sqlite3 object.
                    103: */
                    104: int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
                    105:   struct SqliteDb *p;
                    106:   Tcl_CmdInfo cmdInfo;
                    107:   if( Tcl_GetCommandInfo(interp, zA, &cmdInfo) ){
                    108:     p = (struct SqliteDb*)cmdInfo.objClientData;
                    109:     *ppDb = p->db;
                    110:   }else{
                    111:     *ppDb = (sqlite3*)sqlite3TestTextToPtr(zA);
                    112:   }
                    113:   return TCL_OK;
                    114: }
                    115: 
                    116: 
                    117: const char *sqlite3TestErrorName(int rc){
                    118:   const char *zName = 0;
                    119:   switch( rc ){
                    120:     case SQLITE_OK:                  zName = "SQLITE_OK";                break;
                    121:     case SQLITE_ERROR:               zName = "SQLITE_ERROR";             break;
                    122:     case SQLITE_INTERNAL:            zName = "SQLITE_INTERNAL";          break;
                    123:     case SQLITE_PERM:                zName = "SQLITE_PERM";              break;
                    124:     case SQLITE_ABORT:               zName = "SQLITE_ABORT";             break;
                    125:     case SQLITE_BUSY:                zName = "SQLITE_BUSY";              break;
                    126:     case SQLITE_LOCKED:              zName = "SQLITE_LOCKED";            break;
                    127:     case SQLITE_LOCKED_SHAREDCACHE:  zName = "SQLITE_LOCKED_SHAREDCACHE";break;
                    128:     case SQLITE_NOMEM:               zName = "SQLITE_NOMEM";             break;
                    129:     case SQLITE_READONLY:            zName = "SQLITE_READONLY";          break;
                    130:     case SQLITE_INTERRUPT:           zName = "SQLITE_INTERRUPT";         break;
                    131:     case SQLITE_IOERR:               zName = "SQLITE_IOERR";             break;
                    132:     case SQLITE_CORRUPT:             zName = "SQLITE_CORRUPT";           break;
                    133:     case SQLITE_NOTFOUND:            zName = "SQLITE_NOTFOUND";          break;
                    134:     case SQLITE_FULL:                zName = "SQLITE_FULL";              break;
                    135:     case SQLITE_CANTOPEN:            zName = "SQLITE_CANTOPEN";          break;
                    136:     case SQLITE_PROTOCOL:            zName = "SQLITE_PROTOCOL";          break;
                    137:     case SQLITE_EMPTY:               zName = "SQLITE_EMPTY";             break;
                    138:     case SQLITE_SCHEMA:              zName = "SQLITE_SCHEMA";            break;
                    139:     case SQLITE_TOOBIG:              zName = "SQLITE_TOOBIG";            break;
                    140:     case SQLITE_CONSTRAINT:          zName = "SQLITE_CONSTRAINT";        break;
                    141:     case SQLITE_MISMATCH:            zName = "SQLITE_MISMATCH";          break;
                    142:     case SQLITE_MISUSE:              zName = "SQLITE_MISUSE";            break;
                    143:     case SQLITE_NOLFS:               zName = "SQLITE_NOLFS";             break;
                    144:     case SQLITE_AUTH:                zName = "SQLITE_AUTH";              break;
                    145:     case SQLITE_FORMAT:              zName = "SQLITE_FORMAT";            break;
                    146:     case SQLITE_RANGE:               zName = "SQLITE_RANGE";             break;
                    147:     case SQLITE_NOTADB:              zName = "SQLITE_NOTADB";            break;
                    148:     case SQLITE_ROW:                 zName = "SQLITE_ROW";               break;
                    149:     case SQLITE_DONE:                zName = "SQLITE_DONE";              break;
                    150:     case SQLITE_IOERR_READ:          zName = "SQLITE_IOERR_READ";        break;
                    151:     case SQLITE_IOERR_SHORT_READ:    zName = "SQLITE_IOERR_SHORT_READ";  break;
                    152:     case SQLITE_IOERR_WRITE:         zName = "SQLITE_IOERR_WRITE";       break;
                    153:     case SQLITE_IOERR_FSYNC:         zName = "SQLITE_IOERR_FSYNC";       break;
                    154:     case SQLITE_IOERR_DIR_FSYNC:     zName = "SQLITE_IOERR_DIR_FSYNC";   break;
                    155:     case SQLITE_IOERR_TRUNCATE:      zName = "SQLITE_IOERR_TRUNCATE";    break;
                    156:     case SQLITE_IOERR_FSTAT:         zName = "SQLITE_IOERR_FSTAT";       break;
                    157:     case SQLITE_IOERR_UNLOCK:        zName = "SQLITE_IOERR_UNLOCK";      break;
                    158:     case SQLITE_IOERR_RDLOCK:        zName = "SQLITE_IOERR_RDLOCK";      break;
                    159:     case SQLITE_IOERR_DELETE:        zName = "SQLITE_IOERR_DELETE";      break;
                    160:     case SQLITE_IOERR_BLOCKED:       zName = "SQLITE_IOERR_BLOCKED";     break;
                    161:     case SQLITE_IOERR_NOMEM:         zName = "SQLITE_IOERR_NOMEM";       break;
                    162:     case SQLITE_IOERR_ACCESS:        zName = "SQLITE_IOERR_ACCESS";      break;
                    163:     case SQLITE_IOERR_CHECKRESERVEDLOCK:
                    164:                                zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
                    165:     case SQLITE_IOERR_LOCK:          zName = "SQLITE_IOERR_LOCK";        break;
                    166:     case SQLITE_CORRUPT_VTAB:        zName = "SQLITE_CORRUPT_VTAB";      break;
                    167:     case SQLITE_READONLY_RECOVERY:   zName = "SQLITE_READONLY_RECOVERY"; break;
                    168:     case SQLITE_READONLY_CANTLOCK:   zName = "SQLITE_READONLY_CANTLOCK"; break;
                    169:     default:                         zName = "SQLITE_Unknown";           break;
                    170:   }
                    171:   return zName;
                    172: }
                    173: #define t1ErrorName sqlite3TestErrorName
                    174: 
                    175: /*
                    176: ** Convert an sqlite3_stmt* into an sqlite3*.  This depends on the
                    177: ** fact that the sqlite3* is the first field in the Vdbe structure.
                    178: */
                    179: #define StmtToDb(X)   sqlite3_db_handle(X)
                    180: 
                    181: /*
                    182: ** Check a return value to make sure it agrees with the results
                    183: ** from sqlite3_errcode.
                    184: */
                    185: int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){
                    186:   if( sqlite3_threadsafe()==0 && rc!=SQLITE_MISUSE && rc!=SQLITE_OK
                    187:    && sqlite3_errcode(db)!=rc ){
                    188:     char zBuf[200];
                    189:     int r2 = sqlite3_errcode(db);
                    190:     sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)",
                    191:        t1ErrorName(rc), rc, t1ErrorName(r2), r2);
                    192:     Tcl_ResetResult(interp);
                    193:     Tcl_AppendResult(interp, zBuf, 0);
                    194:     return 1;
                    195:   }
                    196:   return 0;
                    197: }
                    198: 
                    199: /*
                    200: ** Decode a pointer to an sqlite3_stmt object.
                    201: */
                    202: static int getStmtPointer(
                    203:   Tcl_Interp *interp, 
                    204:   const char *zArg,  
                    205:   sqlite3_stmt **ppStmt
                    206: ){
                    207:   *ppStmt = (sqlite3_stmt*)sqlite3TestTextToPtr(zArg);
                    208:   return TCL_OK;
                    209: }
                    210: 
                    211: /*
                    212: ** Generate a text representation of a pointer that can be understood
                    213: ** by the getDbPointer and getVmPointer routines above.
                    214: **
                    215: ** The problem is, on some machines (Solaris) if you do a printf with
                    216: ** "%p" you cannot turn around and do a scanf with the same "%p" and
                    217: ** get your pointer back.  You have to prepend a "0x" before it will
                    218: ** work.  Or at least that is what is reported to me (drh).  But this
                    219: ** behavior varies from machine to machine.  The solution used her is
                    220: ** to test the string right after it is generated to see if it can be
                    221: ** understood by scanf, and if not, try prepending an "0x" to see if
                    222: ** that helps.  If nothing works, a fatal error is generated.
                    223: */
                    224: int sqlite3TestMakePointerStr(Tcl_Interp *interp, char *zPtr, void *p){
                    225:   sqlite3_snprintf(100, zPtr, "%p", p);
                    226:   return TCL_OK;
                    227: }
                    228: 
                    229: /*
                    230: ** The callback routine for sqlite3_exec_printf().
                    231: */
                    232: static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){
                    233:   Tcl_DString *str = (Tcl_DString*)pArg;
                    234:   int i;
                    235: 
                    236:   if( Tcl_DStringLength(str)==0 ){
                    237:     for(i=0; i<argc; i++){
                    238:       Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL");
                    239:     }
                    240:   }
                    241:   for(i=0; i<argc; i++){
                    242:     Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL");
                    243:   }
                    244:   return 0;
                    245: }
                    246: 
                    247: /*
                    248: ** The I/O tracing callback.
                    249: */
                    250: #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
                    251: static FILE *iotrace_file = 0;
                    252: static void io_trace_callback(const char *zFormat, ...){
                    253:   va_list ap;
                    254:   va_start(ap, zFormat);
                    255:   vfprintf(iotrace_file, zFormat, ap);
                    256:   va_end(ap);
                    257:   fflush(iotrace_file);
                    258: }
                    259: #endif
                    260: 
                    261: /*
                    262: ** Usage:  io_trace FILENAME
                    263: **
                    264: ** Turn I/O tracing on or off.  If FILENAME is not an empty string,
                    265: ** I/O tracing begins going into FILENAME. If FILENAME is an empty
                    266: ** string, I/O tracing is turned off.
                    267: */
                    268: static int test_io_trace(
                    269:   void *NotUsed,
                    270:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    271:   int argc,              /* Number of arguments */
                    272:   char **argv            /* Text of each argument */
                    273: ){
                    274: #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
                    275:   if( argc!=2 ){
                    276:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    277:           " FILENAME\"", 0);
                    278:     return TCL_ERROR;
                    279:   }
                    280:   if( iotrace_file ){
                    281:     if( iotrace_file!=stdout && iotrace_file!=stderr ){
                    282:       fclose(iotrace_file);
                    283:     }
                    284:     iotrace_file = 0;
                    285:     sqlite3IoTrace = 0;
                    286:   }
                    287:   if( argv[1][0] ){
                    288:     if( strcmp(argv[1],"stdout")==0 ){
                    289:       iotrace_file = stdout;
                    290:     }else if( strcmp(argv[1],"stderr")==0 ){
                    291:       iotrace_file = stderr;
                    292:     }else{
                    293:       iotrace_file = fopen(argv[1], "w");
                    294:     }
                    295:     sqlite3IoTrace = io_trace_callback;
                    296:   }
                    297: #endif
                    298:   return TCL_OK;
                    299: }
                    300: 
                    301: 
                    302: /*
                    303: ** Usage:  sqlite3_exec_printf  DB  FORMAT  STRING
                    304: **
                    305: ** Invoke the sqlite3_exec_printf() interface using the open database
                    306: ** DB.  The SQL is the string FORMAT.  The format string should contain
                    307: ** one %s or %q.  STRING is the value inserted into %s or %q.
                    308: */
                    309: static int test_exec_printf(
                    310:   void *NotUsed,
                    311:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    312:   int argc,              /* Number of arguments */
                    313:   char **argv            /* Text of each argument */
                    314: ){
                    315:   sqlite3 *db;
                    316:   Tcl_DString str;
                    317:   int rc;
                    318:   char *zErr = 0;
                    319:   char *zSql;
                    320:   char zBuf[30];
                    321:   if( argc!=4 ){
                    322:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                    323:        " DB FORMAT STRING", 0);
                    324:     return TCL_ERROR;
                    325:   }
                    326:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    327:   Tcl_DStringInit(&str);
                    328:   zSql = sqlite3_mprintf(argv[2], argv[3]);
                    329:   rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
                    330:   sqlite3_free(zSql);
                    331:   sprintf(zBuf, "%d", rc);
                    332:   Tcl_AppendElement(interp, zBuf);
                    333:   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
                    334:   Tcl_DStringFree(&str);
                    335:   if( zErr ) sqlite3_free(zErr);
                    336:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                    337:   return TCL_OK;
                    338: }
                    339: 
                    340: /*
                    341: ** Usage:  sqlite3_exec_hex  DB  HEX
                    342: **
                    343: ** Invoke the sqlite3_exec() on a string that is obtained by translating
                    344: ** HEX into ASCII.  Most characters are translated as is.  %HH becomes
                    345: ** a hex character.
                    346: */
                    347: static int test_exec_hex(
                    348:   void *NotUsed,
                    349:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    350:   int argc,              /* Number of arguments */
                    351:   char **argv            /* Text of each argument */
                    352: ){
                    353:   sqlite3 *db;
                    354:   Tcl_DString str;
                    355:   int rc, i, j;
                    356:   char *zErr = 0;
                    357:   char *zHex;
                    358:   char zSql[500];
                    359:   char zBuf[30];
                    360:   if( argc!=3 ){
                    361:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                    362:        " DB HEX", 0);
                    363:     return TCL_ERROR;
                    364:   }
                    365:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    366:   zHex = argv[2];
                    367:   for(i=j=0; i<sizeof(zSql) && zHex[j]; i++, j++){
                    368:     if( zHex[j]=='%' && zHex[j+2] && zHex[j+2] ){
                    369:       zSql[i] = (testHexToInt(zHex[j+1])<<4) + testHexToInt(zHex[j+2]);
                    370:       j += 2;
                    371:     }else{
                    372:       zSql[i] = zHex[j];
                    373:     }
                    374:   }
                    375:   zSql[i] = 0;
                    376:   Tcl_DStringInit(&str);
                    377:   rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
                    378:   sprintf(zBuf, "%d", rc);
                    379:   Tcl_AppendElement(interp, zBuf);
                    380:   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
                    381:   Tcl_DStringFree(&str);
                    382:   if( zErr ) sqlite3_free(zErr);
                    383:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                    384:   return TCL_OK;
                    385: }
                    386: 
                    387: /*
                    388: ** Usage:  db_enter DB
                    389: **         db_leave DB
                    390: **
                    391: ** Enter or leave the mutex on a database connection.
                    392: */
                    393: static int db_enter(
                    394:   void *NotUsed,
                    395:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    396:   int argc,              /* Number of arguments */
                    397:   char **argv            /* Text of each argument */
                    398: ){
                    399:   sqlite3 *db;
                    400:   if( argc!=2 ){
                    401:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                    402:        " DB", 0);
                    403:     return TCL_ERROR;
                    404:   }
                    405:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    406:   sqlite3_mutex_enter(db->mutex);
                    407:   return TCL_OK;
                    408: }
                    409: static int db_leave(
                    410:   void *NotUsed,
                    411:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    412:   int argc,              /* Number of arguments */
                    413:   char **argv            /* Text of each argument */
                    414: ){
                    415:   sqlite3 *db;
                    416:   if( argc!=2 ){
                    417:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                    418:        " DB", 0);
                    419:     return TCL_ERROR;
                    420:   }
                    421:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    422:   sqlite3_mutex_leave(db->mutex);
                    423:   return TCL_OK;
                    424: }
                    425: 
                    426: /*
                    427: ** Usage:  sqlite3_exec  DB  SQL
                    428: **
                    429: ** Invoke the sqlite3_exec interface using the open database DB
                    430: */
                    431: static int test_exec(
                    432:   void *NotUsed,
                    433:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    434:   int argc,              /* Number of arguments */
                    435:   char **argv            /* Text of each argument */
                    436: ){
                    437:   sqlite3 *db;
                    438:   Tcl_DString str;
                    439:   int rc;
                    440:   char *zErr = 0;
                    441:   char *zSql;
                    442:   int i, j;
                    443:   char zBuf[30];
                    444:   if( argc!=3 ){
                    445:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                    446:        " DB SQL", 0);
                    447:     return TCL_ERROR;
                    448:   }
                    449:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    450:   Tcl_DStringInit(&str);
                    451:   zSql = sqlite3_mprintf("%s", argv[2]);
                    452:   for(i=j=0; zSql[i];){
                    453:     if( zSql[i]=='%' ){
                    454:       zSql[j++] = (testHexToInt(zSql[i+1])<<4) + testHexToInt(zSql[i+2]);
                    455:       i += 3;
                    456:     }else{
                    457:       zSql[j++] = zSql[i++];
                    458:     }
                    459:   }
                    460:   zSql[j] = 0;
                    461:   rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
                    462:   sqlite3_free(zSql);
                    463:   sprintf(zBuf, "%d", rc);
                    464:   Tcl_AppendElement(interp, zBuf);
                    465:   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
                    466:   Tcl_DStringFree(&str);
                    467:   if( zErr ) sqlite3_free(zErr);
                    468:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                    469:   return TCL_OK;
                    470: }
                    471: 
                    472: /*
                    473: ** Usage:  sqlite3_exec_nr  DB  SQL
                    474: **
                    475: ** Invoke the sqlite3_exec interface using the open database DB.  Discard
                    476: ** all results
                    477: */
                    478: static int test_exec_nr(
                    479:   void *NotUsed,
                    480:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    481:   int argc,              /* Number of arguments */
                    482:   char **argv            /* Text of each argument */
                    483: ){
                    484:   sqlite3 *db;
                    485:   int rc;
                    486:   char *zErr = 0;
                    487:   if( argc!=3 ){
                    488:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                    489:        " DB SQL", 0);
                    490:     return TCL_ERROR;
                    491:   }
                    492:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    493:   rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
                    494:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                    495:   return TCL_OK;
                    496: }
                    497: 
                    498: /*
                    499: ** Usage:  sqlite3_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...
                    500: **
                    501: ** Test the %z format of sqlite_mprintf().  Use multiple mprintf() calls to 
                    502: ** concatenate arg0 through argn using separator as the separator.
                    503: ** Return the result.
                    504: */
                    505: static int test_mprintf_z(
                    506:   void *NotUsed,
                    507:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    508:   int argc,              /* Number of arguments */
                    509:   char **argv            /* Text of each argument */
                    510: ){
                    511:   char *zResult = 0;
                    512:   int i;
                    513: 
                    514:   for(i=2; i<argc && (i==2 || zResult); i++){
                    515:     zResult = sqlite3_mprintf("%z%s%s", zResult, argv[1], argv[i]);
                    516:   }
                    517:   Tcl_AppendResult(interp, zResult, 0);
                    518:   sqlite3_free(zResult);
                    519:   return TCL_OK;
                    520: }
                    521: 
                    522: /*
                    523: ** Usage:  sqlite3_mprintf_n_test  STRING
                    524: **
                    525: ** Test the %n format of sqlite_mprintf().  Return the length of the
                    526: ** input string.
                    527: */
                    528: static int test_mprintf_n(
                    529:   void *NotUsed,
                    530:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    531:   int argc,              /* Number of arguments */
                    532:   char **argv            /* Text of each argument */
                    533: ){
                    534:   char *zStr;
                    535:   int n = 0;
                    536:   zStr = sqlite3_mprintf("%s%n", argv[1], &n);
                    537:   sqlite3_free(zStr);
                    538:   Tcl_SetObjResult(interp, Tcl_NewIntObj(n));
                    539:   return TCL_OK;
                    540: }
                    541: 
                    542: /*
                    543: ** Usage:  sqlite3_snprintf_int  SIZE FORMAT  INT
                    544: **
                    545: ** Test the of sqlite3_snprintf() routine.  SIZE is the size of the
                    546: ** output buffer in bytes.  The maximum size is 100.  FORMAT is the
                    547: ** format string.  INT is a single integer argument.  The FORMAT
                    548: ** string must require no more than this one integer argument.  If
                    549: ** You pass in a format string that requires more than one argument,
                    550: ** bad things will happen.
                    551: */
                    552: static int test_snprintf_int(
                    553:   void *NotUsed,
                    554:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    555:   int argc,              /* Number of arguments */
                    556:   char **argv            /* Text of each argument */
                    557: ){
                    558:   char zStr[100];
                    559:   int n = atoi(argv[1]);
                    560:   const char *zFormat = argv[2];
                    561:   int a1 = atoi(argv[3]);
                    562:   if( n>sizeof(zStr) ) n = sizeof(zStr);
                    563:   sqlite3_snprintf(sizeof(zStr), zStr, "abcdefghijklmnopqrstuvwxyz");
                    564:   sqlite3_snprintf(n, zStr, zFormat, a1);
                    565:   Tcl_AppendResult(interp, zStr, 0);
                    566:   return TCL_OK;
                    567: }
                    568: 
                    569: #ifndef SQLITE_OMIT_GET_TABLE
                    570: 
                    571: /*
                    572: ** Usage:  sqlite3_get_table_printf  DB  FORMAT  STRING  ?--no-counts?
                    573: **
                    574: ** Invoke the sqlite3_get_table_printf() interface using the open database
                    575: ** DB.  The SQL is the string FORMAT.  The format string should contain
                    576: ** one %s or %q.  STRING is the value inserted into %s or %q.
                    577: */
                    578: static int test_get_table_printf(
                    579:   void *NotUsed,
                    580:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    581:   int argc,              /* Number of arguments */
                    582:   char **argv            /* Text of each argument */
                    583: ){
                    584:   sqlite3 *db;
                    585:   Tcl_DString str;
                    586:   int rc;
                    587:   char *zErr = 0;
                    588:   int nRow, nCol;
                    589:   char **aResult;
                    590:   int i;
                    591:   char zBuf[30];
                    592:   char *zSql;
                    593:   int resCount = -1;
                    594:   if( argc==5 ){
                    595:     if( Tcl_GetInt(interp, argv[4], &resCount) ) return TCL_ERROR;
                    596:   }
                    597:   if( argc!=4 && argc!=5 ){
                    598:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                    599:        " DB FORMAT STRING ?COUNT?", 0);
                    600:     return TCL_ERROR;
                    601:   }
                    602:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    603:   Tcl_DStringInit(&str);
                    604:   zSql = sqlite3_mprintf(argv[2],argv[3]);
                    605:   if( argc==5 ){
                    606:     rc = sqlite3_get_table(db, zSql, &aResult, 0, 0, &zErr);
                    607:   }else{
                    608:     rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr);
                    609:     resCount = (nRow+1)*nCol;
                    610:   }
                    611:   sqlite3_free(zSql);
                    612:   sprintf(zBuf, "%d", rc);
                    613:   Tcl_AppendElement(interp, zBuf);
                    614:   if( rc==SQLITE_OK ){
                    615:     if( argc==4 ){
                    616:       sprintf(zBuf, "%d", nRow);
                    617:       Tcl_AppendElement(interp, zBuf);
                    618:       sprintf(zBuf, "%d", nCol);
                    619:       Tcl_AppendElement(interp, zBuf);
                    620:     }
                    621:     for(i=0; i<resCount; i++){
                    622:       Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
                    623:     }
                    624:   }else{
                    625:     Tcl_AppendElement(interp, zErr);
                    626:   }
                    627:   sqlite3_free_table(aResult);
                    628:   if( zErr ) sqlite3_free(zErr);
                    629:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                    630:   return TCL_OK;
                    631: }
                    632: 
                    633: #endif /* SQLITE_OMIT_GET_TABLE */
                    634: 
                    635: 
                    636: /*
                    637: ** Usage:  sqlite3_last_insert_rowid DB
                    638: **
                    639: ** Returns the integer ROWID of the most recent insert.
                    640: */
                    641: static int test_last_rowid(
                    642:   void *NotUsed,
                    643:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    644:   int argc,              /* Number of arguments */
                    645:   char **argv            /* Text of each argument */
                    646: ){
                    647:   sqlite3 *db;
                    648:   char zBuf[30];
                    649: 
                    650:   if( argc!=2 ){
                    651:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0);
                    652:     return TCL_ERROR;
                    653:   }
                    654:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    655:   sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db));
                    656:   Tcl_AppendResult(interp, zBuf, 0);
                    657:   return SQLITE_OK;
                    658: }
                    659: 
                    660: /*
                    661: ** Usage:  sqlite3_key DB KEY
                    662: **
                    663: ** Set the codec key.
                    664: */
                    665: static int test_key(
                    666:   void *NotUsed,
                    667:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    668:   int argc,              /* Number of arguments */
                    669:   char **argv            /* Text of each argument */
                    670: ){
                    671:   sqlite3 *db;
                    672:   const char *zKey;
                    673:   int nKey;
                    674:   if( argc!=3 ){
                    675:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    676:        " FILENAME\"", 0);
                    677:     return TCL_ERROR;
                    678:   }
                    679:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    680:   zKey = argv[2];
                    681:   nKey = strlen(zKey);
                    682: #ifdef SQLITE_HAS_CODEC
                    683:   sqlite3_key(db, zKey, nKey);
                    684: #endif
                    685:   return TCL_OK;
                    686: }
                    687: 
                    688: /*
                    689: ** Usage:  sqlite3_rekey DB KEY
                    690: **
                    691: ** Change the codec key.
                    692: */
                    693: static int test_rekey(
                    694:   void *NotUsed,
                    695:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    696:   int argc,              /* Number of arguments */
                    697:   char **argv            /* Text of each argument */
                    698: ){
                    699:   sqlite3 *db;
                    700:   const char *zKey;
                    701:   int nKey;
                    702:   if( argc!=3 ){
                    703:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    704:        " FILENAME\"", 0);
                    705:     return TCL_ERROR;
                    706:   }
                    707:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    708:   zKey = argv[2];
                    709:   nKey = strlen(zKey);
                    710: #ifdef SQLITE_HAS_CODEC
                    711:   sqlite3_rekey(db, zKey, nKey);
                    712: #endif
                    713:   return TCL_OK;
                    714: }
                    715: 
                    716: /*
                    717: ** Usage:  sqlite3_close DB
                    718: **
                    719: ** Closes the database opened by sqlite3_open.
                    720: */
                    721: static int sqlite_test_close(
                    722:   void *NotUsed,
                    723:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    724:   int argc,              /* Number of arguments */
                    725:   char **argv            /* Text of each argument */
                    726: ){
                    727:   sqlite3 *db;
                    728:   int rc;
                    729:   if( argc!=2 ){
                    730:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    731:        " FILENAME\"", 0);
                    732:     return TCL_ERROR;
                    733:   }
                    734:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                    735:   rc = sqlite3_close(db);
                    736:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
                    737:   return TCL_OK;
                    738: }
                    739: 
                    740: /*
                    741: ** Implementation of the x_coalesce() function.
                    742: ** Return the first argument non-NULL argument.
                    743: */
                    744: static void t1_ifnullFunc(
                    745:   sqlite3_context *context,
                    746:   int argc,
                    747:   sqlite3_value **argv
                    748: ){
                    749:   int i;
                    750:   for(i=0; i<argc; i++){
                    751:     if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
                    752:       int n = sqlite3_value_bytes(argv[i]);
                    753:       sqlite3_result_text(context, (char*)sqlite3_value_text(argv[i]),
                    754:           n, SQLITE_TRANSIENT);
                    755:       break;
                    756:     }
                    757:   }
                    758: }
                    759: 
                    760: /*
                    761: ** These are test functions.    hex8() interprets its argument as
                    762: ** UTF8 and returns a hex encoding.  hex16le() interprets its argument
                    763: ** as UTF16le and returns a hex encoding.
                    764: */
                    765: static void hex8Func(sqlite3_context *p, int argc, sqlite3_value **argv){
                    766:   const unsigned char *z;
                    767:   int i;
                    768:   char zBuf[200];
                    769:   z = sqlite3_value_text(argv[0]);
                    770:   for(i=0; i<sizeof(zBuf)/2 - 2 && z[i]; i++){
                    771:     sprintf(&zBuf[i*2], "%02x", z[i]&0xff);
                    772:   }
                    773:   zBuf[i*2] = 0;
                    774:   sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);
                    775: }
                    776: #ifndef SQLITE_OMIT_UTF16
                    777: static void hex16Func(sqlite3_context *p, int argc, sqlite3_value **argv){
                    778:   const unsigned short int *z;
                    779:   int i;
                    780:   char zBuf[400];
                    781:   z = sqlite3_value_text16(argv[0]);
                    782:   for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){
                    783:     sprintf(&zBuf[i*4], "%04x", z[i]&0xff);
                    784:   }
                    785:   zBuf[i*4] = 0;
                    786:   sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);
                    787: }
                    788: #endif
                    789: 
                    790: /*
                    791: ** A structure into which to accumulate text.
                    792: */
                    793: struct dstr {
                    794:   int nAlloc;  /* Space allocated */
                    795:   int nUsed;   /* Space used */
                    796:   char *z;     /* The space */
                    797: };
                    798: 
                    799: /*
                    800: ** Append text to a dstr
                    801: */
                    802: static void dstrAppend(struct dstr *p, const char *z, int divider){
                    803:   int n = strlen(z);
                    804:   if( p->nUsed + n + 2 > p->nAlloc ){
                    805:     char *zNew;
                    806:     p->nAlloc = p->nAlloc*2 + n + 200;
                    807:     zNew = sqlite3_realloc(p->z, p->nAlloc);
                    808:     if( zNew==0 ){
                    809:       sqlite3_free(p->z);
                    810:       memset(p, 0, sizeof(*p));
                    811:       return;
                    812:     }
                    813:     p->z = zNew;
                    814:   }
                    815:   if( divider && p->nUsed>0 ){
                    816:     p->z[p->nUsed++] = divider;
                    817:   }
                    818:   memcpy(&p->z[p->nUsed], z, n+1);
                    819:   p->nUsed += n;
                    820: }
                    821: 
                    822: /*
                    823: ** Invoked for each callback from sqlite3ExecFunc
                    824: */
                    825: static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){
                    826:   struct dstr *p = (struct dstr*)pData;
                    827:   int i;
                    828:   for(i=0; i<argc; i++){
                    829:     if( argv[i]==0 ){
                    830:       dstrAppend(p, "NULL", ' ');
                    831:     }else{
                    832:       dstrAppend(p, argv[i], ' ');
                    833:     }
                    834:   }
                    835:   return 0;
                    836: }
                    837: 
                    838: /*
                    839: ** Implementation of the x_sqlite_exec() function.  This function takes
                    840: ** a single argument and attempts to execute that argument as SQL code.
                    841: ** This is illegal and should set the SQLITE_MISUSE flag on the database.
                    842: **
                    843: ** 2004-Jan-07:  We have changed this to make it legal to call sqlite3_exec()
                    844: ** from within a function call.  
                    845: ** 
                    846: ** This routine simulates the effect of having two threads attempt to
                    847: ** use the same database at the same time.
                    848: */
                    849: static void sqlite3ExecFunc(
                    850:   sqlite3_context *context, 
                    851:   int argc,  
                    852:   sqlite3_value **argv
                    853: ){
                    854:   struct dstr x;
                    855:   memset(&x, 0, sizeof(x));
                    856:   (void)sqlite3_exec((sqlite3*)sqlite3_user_data(context),
                    857:       (char*)sqlite3_value_text(argv[0]),
                    858:       execFuncCallback, &x, 0);
                    859:   sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT);
                    860:   sqlite3_free(x.z);
                    861: }
                    862: 
                    863: /*
                    864: ** Implementation of tkt2213func(), a scalar function that takes exactly
                    865: ** one argument. It has two interesting features:
                    866: **
                    867: ** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*.
                    868: **   If the three pointers returned are not the same an SQL error is raised.
                    869: **
                    870: ** * Otherwise it returns a copy of the text representation of its 
                    871: **   argument in such a way as the VDBE representation is a Mem* cell 
                    872: **   with the MEM_Term flag clear. 
                    873: **
                    874: ** Ticket #2213 can therefore be tested by evaluating the following
                    875: ** SQL expression:
                    876: **
                    877: **   tkt2213func(tkt2213func('a string'));
                    878: */
                    879: static void tkt2213Function(
                    880:   sqlite3_context *context, 
                    881:   int argc,  
                    882:   sqlite3_value **argv
                    883: ){
                    884:   int nText;
                    885:   unsigned char const *zText1;
                    886:   unsigned char const *zText2;
                    887:   unsigned char const *zText3;
                    888: 
                    889:   nText = sqlite3_value_bytes(argv[0]);
                    890:   zText1 = sqlite3_value_text(argv[0]);
                    891:   zText2 = sqlite3_value_text(argv[0]);
                    892:   zText3 = sqlite3_value_text(argv[0]);
                    893: 
                    894:   if( zText1!=zText2 || zText2!=zText3 ){
                    895:     sqlite3_result_error(context, "tkt2213 is not fixed", -1);
                    896:   }else{
                    897:     char *zCopy = (char *)sqlite3_malloc(nText);
                    898:     memcpy(zCopy, zText1, nText);
                    899:     sqlite3_result_text(context, zCopy, nText, sqlite3_free);
                    900:   }
                    901: }
                    902: 
                    903: /*
                    904: ** The following SQL function takes 4 arguments.  The 2nd and
                    905: ** 4th argument must be one of these strings:  'text', 'text16',
                    906: ** or 'blob' corresponding to API functions
                    907: **
                    908: **      sqlite3_value_text()
                    909: **      sqlite3_value_text16()
                    910: **      sqlite3_value_blob()
                    911: **
                    912: ** The third argument is a string, either 'bytes' or 'bytes16' or 'noop',
                    913: ** corresponding to APIs:
                    914: **
                    915: **      sqlite3_value_bytes()
                    916: **      sqlite3_value_bytes16()
                    917: **      noop
                    918: **
                    919: ** The APIs designated by the 2nd through 4th arguments are applied
                    920: ** to the first argument in order.  If the pointers returned by the
                    921: ** second and fourth are different, this routine returns 1.  Otherwise,
                    922: ** this routine returns 0.
                    923: **
                    924: ** This function is used to test to see when returned pointers from
                    925: ** the _text(), _text16() and _blob() APIs become invalidated.
                    926: */
                    927: static void ptrChngFunction(
                    928:   sqlite3_context *context, 
                    929:   int argc,  
                    930:   sqlite3_value **argv
                    931: ){
                    932:   const void *p1, *p2;
                    933:   const char *zCmd;
                    934:   if( argc!=4 ) return;
                    935:   zCmd = (const char*)sqlite3_value_text(argv[1]);
                    936:   if( zCmd==0 ) return;
                    937:   if( strcmp(zCmd,"text")==0 ){
                    938:     p1 = (const void*)sqlite3_value_text(argv[0]);
                    939: #ifndef SQLITE_OMIT_UTF16
                    940:   }else if( strcmp(zCmd, "text16")==0 ){
                    941:     p1 = (const void*)sqlite3_value_text16(argv[0]);
                    942: #endif
                    943:   }else if( strcmp(zCmd, "blob")==0 ){
                    944:     p1 = (const void*)sqlite3_value_blob(argv[0]);
                    945:   }else{
                    946:     return;
                    947:   }
                    948:   zCmd = (const char*)sqlite3_value_text(argv[2]);
                    949:   if( zCmd==0 ) return;
                    950:   if( strcmp(zCmd,"bytes")==0 ){
                    951:     sqlite3_value_bytes(argv[0]);
                    952: #ifndef SQLITE_OMIT_UTF16
                    953:   }else if( strcmp(zCmd, "bytes16")==0 ){
                    954:     sqlite3_value_bytes16(argv[0]);
                    955: #endif
                    956:   }else if( strcmp(zCmd, "noop")==0 ){
                    957:     /* do nothing */
                    958:   }else{
                    959:     return;
                    960:   }
                    961:   zCmd = (const char*)sqlite3_value_text(argv[3]);
                    962:   if( zCmd==0 ) return;
                    963:   if( strcmp(zCmd,"text")==0 ){
                    964:     p2 = (const void*)sqlite3_value_text(argv[0]);
                    965: #ifndef SQLITE_OMIT_UTF16
                    966:   }else if( strcmp(zCmd, "text16")==0 ){
                    967:     p2 = (const void*)sqlite3_value_text16(argv[0]);
                    968: #endif
                    969:   }else if( strcmp(zCmd, "blob")==0 ){
                    970:     p2 = (const void*)sqlite3_value_blob(argv[0]);
                    971:   }else{
                    972:     return;
                    973:   }
                    974:   sqlite3_result_int(context, p1!=p2);
                    975: }
                    976: 
                    977: 
                    978: /*
                    979: ** Usage:  sqlite_test_create_function DB
                    980: **
                    981: ** Call the sqlite3_create_function API on the given database in order
                    982: ** to create a function named "x_coalesce".  This function does the same thing
                    983: ** as the "coalesce" function.  This function also registers an SQL function
                    984: ** named "x_sqlite_exec" that invokes sqlite3_exec().  Invoking sqlite3_exec()
                    985: ** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
                    986: ** The effect is similar to trying to use the same database connection from
                    987: ** two threads at the same time.
                    988: **
                    989: ** The original motivation for this routine was to be able to call the
                    990: ** sqlite3_create_function function while a query is in progress in order
                    991: ** to test the SQLITE_MISUSE detection logic.
                    992: */
                    993: static int test_create_function(
                    994:   void *NotUsed,
                    995:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                    996:   int argc,              /* Number of arguments */
                    997:   char **argv            /* Text of each argument */
                    998: ){
                    999:   int rc;
                   1000:   sqlite3 *db;
                   1001: 
                   1002:   if( argc!=2 ){
                   1003:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1004:        " DB\"", 0);
                   1005:     return TCL_ERROR;
                   1006:   }
                   1007:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   1008:   rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 
                   1009:         t1_ifnullFunc, 0, 0);
                   1010:   if( rc==SQLITE_OK ){
                   1011:     rc = sqlite3_create_function(db, "hex8", 1, SQLITE_ANY, 0, 
                   1012:           hex8Func, 0, 0);
                   1013:   }
                   1014: #ifndef SQLITE_OMIT_UTF16
                   1015:   if( rc==SQLITE_OK ){
                   1016:     rc = sqlite3_create_function(db, "hex16", 1, SQLITE_ANY, 0, 
                   1017:           hex16Func, 0, 0);
                   1018:   }
                   1019: #endif
                   1020:   if( rc==SQLITE_OK ){
                   1021:     rc = sqlite3_create_function(db, "tkt2213func", 1, SQLITE_ANY, 0, 
                   1022:           tkt2213Function, 0, 0);
                   1023:   }
                   1024:   if( rc==SQLITE_OK ){
                   1025:     rc = sqlite3_create_function(db, "pointer_change", 4, SQLITE_ANY, 0, 
                   1026:           ptrChngFunction, 0, 0);
                   1027:   }
                   1028: 
                   1029: #ifndef SQLITE_OMIT_UTF16
                   1030:   /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
                   1031:   ** because it is not tested anywhere else. */
                   1032:   if( rc==SQLITE_OK ){
                   1033:     const void *zUtf16;
                   1034:     sqlite3_value *pVal;
                   1035:     sqlite3_mutex_enter(db->mutex);
                   1036:     pVal = sqlite3ValueNew(db);
                   1037:     sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
                   1038:     zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
                   1039:     if( db->mallocFailed ){
                   1040:       rc = SQLITE_NOMEM;
                   1041:     }else{
                   1042:       rc = sqlite3_create_function16(db, zUtf16, 
                   1043:                 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
                   1044:     }
                   1045:     sqlite3ValueFree(pVal);
                   1046:     sqlite3_mutex_leave(db->mutex);
                   1047:   }
                   1048: #endif
                   1049: 
                   1050:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   1051:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
                   1052:   return TCL_OK;
                   1053: }
                   1054: 
                   1055: /*
                   1056: ** Routines to implement the x_count() aggregate function.
                   1057: **
                   1058: ** x_count() counts the number of non-null arguments.  But there are
                   1059: ** some twists for testing purposes.
                   1060: **
                   1061: ** If the argument to x_count() is 40 then a UTF-8 error is reported
                   1062: ** on the step function.  If x_count(41) is seen, then a UTF-16 error
                   1063: ** is reported on the step function.  If the total count is 42, then
                   1064: ** a UTF-8 error is reported on the finalize function.
                   1065: */
                   1066: typedef struct t1CountCtx t1CountCtx;
                   1067: struct t1CountCtx {
                   1068:   int n;
                   1069: };
                   1070: static void t1CountStep(
                   1071:   sqlite3_context *context,
                   1072:   int argc,
                   1073:   sqlite3_value **argv
                   1074: ){
                   1075:   t1CountCtx *p;
                   1076:   p = sqlite3_aggregate_context(context, sizeof(*p));
                   1077:   if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){
                   1078:     p->n++;
                   1079:   }
                   1080:   if( argc>0 ){
                   1081:     int v = sqlite3_value_int(argv[0]);
                   1082:     if( v==40 ){
                   1083:       sqlite3_result_error(context, "value of 40 handed to x_count", -1);
                   1084: #ifndef SQLITE_OMIT_UTF16
                   1085:     }else if( v==41 ){
                   1086:       const char zUtf16ErrMsg[] = { 0, 0x61, 0, 0x62, 0, 0x63, 0, 0, 0};
                   1087:       sqlite3_result_error16(context, &zUtf16ErrMsg[1-SQLITE_BIGENDIAN], -1);
                   1088: #endif
                   1089:     }
                   1090:   }
                   1091: }   
                   1092: static void t1CountFinalize(sqlite3_context *context){
                   1093:   t1CountCtx *p;
                   1094:   p = sqlite3_aggregate_context(context, sizeof(*p));
                   1095:   if( p ){
                   1096:     if( p->n==42 ){
                   1097:       sqlite3_result_error(context, "x_count totals to 42", -1);
                   1098:     }else{
                   1099:       sqlite3_result_int(context, p ? p->n : 0);
                   1100:     }
                   1101:   }
                   1102: }
                   1103: 
                   1104: #ifndef SQLITE_OMIT_DEPRECATED
                   1105: static void legacyCountStep(
                   1106:   sqlite3_context *context,
                   1107:   int argc,
                   1108:   sqlite3_value **argv
                   1109: ){
                   1110:   /* no-op */
                   1111: }
                   1112: 
                   1113: static void legacyCountFinalize(sqlite3_context *context){
                   1114:   sqlite3_result_int(context, sqlite3_aggregate_count(context));
                   1115: }
                   1116: #endif
                   1117: 
                   1118: /*
                   1119: ** Usage:  sqlite3_create_aggregate DB
                   1120: **
                   1121: ** Call the sqlite3_create_function API on the given database in order
                   1122: ** to create a function named "x_count".  This function is similar
                   1123: ** to the built-in count() function, with a few special quirks
                   1124: ** for testing the sqlite3_result_error() APIs.
                   1125: **
                   1126: ** The original motivation for this routine was to be able to call the
                   1127: ** sqlite3_create_aggregate function while a query is in progress in order
                   1128: ** to test the SQLITE_MISUSE detection logic.  See misuse.test.
                   1129: **
                   1130: ** This routine was later extended to test the use of sqlite3_result_error()
                   1131: ** within aggregate functions.
                   1132: **
                   1133: ** Later: It is now also extended to register the aggregate function
                   1134: ** "legacy_count()" with the supplied database handle. This is used
                   1135: ** to test the deprecated sqlite3_aggregate_count() API.
                   1136: */
                   1137: static int test_create_aggregate(
                   1138:   void *NotUsed,
                   1139:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1140:   int argc,              /* Number of arguments */
                   1141:   char **argv            /* Text of each argument */
                   1142: ){
                   1143:   sqlite3 *db;
                   1144:   int rc;
                   1145:   if( argc!=2 ){
                   1146:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1147:        " FILENAME\"", 0);
                   1148:     return TCL_ERROR;
                   1149:   }
                   1150:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   1151:   rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
                   1152:       t1CountStep,t1CountFinalize);
                   1153:   if( rc==SQLITE_OK ){
                   1154:     rc = sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
                   1155:         t1CountStep,t1CountFinalize);
                   1156:   }
                   1157: #ifndef SQLITE_OMIT_DEPRECATED
                   1158:   if( rc==SQLITE_OK ){
                   1159:     rc = sqlite3_create_function(db, "legacy_count", 0, SQLITE_ANY, 0, 0,
                   1160:         legacyCountStep, legacyCountFinalize
                   1161:     );
                   1162:   }
                   1163: #endif
                   1164:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   1165:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
                   1166:   return TCL_OK;
                   1167: }
                   1168: 
                   1169: 
                   1170: /*
                   1171: ** Usage:  printf TEXT
                   1172: **
                   1173: ** Send output to printf.  Use this rather than puts to merge the output
                   1174: ** in the correct sequence with debugging printfs inserted into C code.
                   1175: ** Puts uses a separate buffer and debugging statements will be out of
                   1176: ** sequence if it is used.
                   1177: */
                   1178: static int test_printf(
                   1179:   void *NotUsed,
                   1180:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1181:   int argc,              /* Number of arguments */
                   1182:   char **argv            /* Text of each argument */
                   1183: ){
                   1184:   if( argc!=2 ){
                   1185:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1186:        " TEXT\"", 0);
                   1187:     return TCL_ERROR;
                   1188:   }
                   1189:   printf("%s\n", argv[1]);
                   1190:   return TCL_OK;
                   1191: }
                   1192: 
                   1193: 
                   1194: 
                   1195: /*
                   1196: ** Usage:  sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER
                   1197: **
                   1198: ** Call mprintf with three integer arguments
                   1199: */
                   1200: static int sqlite3_mprintf_int(
                   1201:   void *NotUsed,
                   1202:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1203:   int argc,              /* Number of arguments */
                   1204:   char **argv            /* Text of each argument */
                   1205: ){
                   1206:   int a[3], i;
                   1207:   char *z;
                   1208:   if( argc!=5 ){
                   1209:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1210:        " FORMAT INT INT INT\"", 0);
                   1211:     return TCL_ERROR;
                   1212:   }
                   1213:   for(i=2; i<5; i++){
                   1214:     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
                   1215:   }
                   1216:   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
                   1217:   Tcl_AppendResult(interp, z, 0);
                   1218:   sqlite3_free(z);
                   1219:   return TCL_OK;
                   1220: }
                   1221: 
                   1222: /*
                   1223: ** Usage:  sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER
                   1224: **
                   1225: ** Call mprintf with three 64-bit integer arguments
                   1226: */
                   1227: static int sqlite3_mprintf_int64(
                   1228:   void *NotUsed,
                   1229:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1230:   int argc,              /* Number of arguments */
                   1231:   char **argv            /* Text of each argument */
                   1232: ){
                   1233:   int i;
                   1234:   sqlite_int64 a[3];
                   1235:   char *z;
                   1236:   if( argc!=5 ){
                   1237:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1238:        " FORMAT INT INT INT\"", 0);
                   1239:     return TCL_ERROR;
                   1240:   }
                   1241:   for(i=2; i<5; i++){
                   1242:     if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){
                   1243:       Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
                   1244:       return TCL_ERROR;
                   1245:     }
                   1246:   }
                   1247:   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
                   1248:   Tcl_AppendResult(interp, z, 0);
                   1249:   sqlite3_free(z);
                   1250:   return TCL_OK;
                   1251: }
                   1252: 
                   1253: /*
                   1254: ** Usage:  sqlite3_mprintf_long FORMAT INTEGER INTEGER INTEGER
                   1255: **
                   1256: ** Call mprintf with three long integer arguments.   This might be the
                   1257: ** same as sqlite3_mprintf_int or sqlite3_mprintf_int64, depending on
                   1258: ** platform.
                   1259: */
                   1260: static int sqlite3_mprintf_long(
                   1261:   void *NotUsed,
                   1262:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1263:   int argc,              /* Number of arguments */
                   1264:   char **argv            /* Text of each argument */
                   1265: ){
                   1266:   int i;
                   1267:   long int a[3];
                   1268:   int b[3];
                   1269:   char *z;
                   1270:   if( argc!=5 ){
                   1271:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1272:        " FORMAT INT INT INT\"", 0);
                   1273:     return TCL_ERROR;
                   1274:   }
                   1275:   for(i=2; i<5; i++){
                   1276:     if( Tcl_GetInt(interp, argv[i], &b[i-2]) ) return TCL_ERROR;
                   1277:     a[i-2] = (long int)b[i-2];
                   1278:     a[i-2] &= (((u64)1)<<(sizeof(int)*8))-1;
                   1279:   }
                   1280:   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
                   1281:   Tcl_AppendResult(interp, z, 0);
                   1282:   sqlite3_free(z);
                   1283:   return TCL_OK;
                   1284: }
                   1285: 
                   1286: /*
                   1287: ** Usage:  sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING
                   1288: **
                   1289: ** Call mprintf with two integer arguments and one string argument
                   1290: */
                   1291: static int sqlite3_mprintf_str(
                   1292:   void *NotUsed,
                   1293:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1294:   int argc,              /* Number of arguments */
                   1295:   char **argv            /* Text of each argument */
                   1296: ){
                   1297:   int a[3], i;
                   1298:   char *z;
                   1299:   if( argc<4 || argc>5 ){
                   1300:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1301:        " FORMAT INT INT ?STRING?\"", 0);
                   1302:     return TCL_ERROR;
                   1303:   }
                   1304:   for(i=2; i<4; i++){
                   1305:     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
                   1306:   }
                   1307:   z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL);
                   1308:   Tcl_AppendResult(interp, z, 0);
                   1309:   sqlite3_free(z);
                   1310:   return TCL_OK;
                   1311: }
                   1312: 
                   1313: /*
                   1314: ** Usage:  sqlite3_snprintf_str INTEGER FORMAT INTEGER INTEGER STRING
                   1315: **
                   1316: ** Call mprintf with two integer arguments and one string argument
                   1317: */
                   1318: static int sqlite3_snprintf_str(
                   1319:   void *NotUsed,
                   1320:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1321:   int argc,              /* Number of arguments */
                   1322:   char **argv            /* Text of each argument */
                   1323: ){
                   1324:   int a[3], i;
                   1325:   int n;
                   1326:   char *z;
                   1327:   if( argc<5 || argc>6 ){
                   1328:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1329:        " INT FORMAT INT INT ?STRING?\"", 0);
                   1330:     return TCL_ERROR;
                   1331:   }
                   1332:   if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
                   1333:   if( n<0 ){
                   1334:     Tcl_AppendResult(interp, "N must be non-negative", 0);
                   1335:     return TCL_ERROR;
                   1336:   }
                   1337:   for(i=3; i<5; i++){
                   1338:     if( Tcl_GetInt(interp, argv[i], &a[i-3]) ) return TCL_ERROR;
                   1339:   }
                   1340:   z = sqlite3_malloc( n+1 );
                   1341:   sqlite3_snprintf(n, z, argv[2], a[0], a[1], argc>4 ? argv[5] : NULL);
                   1342:   Tcl_AppendResult(interp, z, 0);
                   1343:   sqlite3_free(z);
                   1344:   return TCL_OK;
                   1345: }
                   1346: 
                   1347: /*
                   1348: ** Usage:  sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE
                   1349: **
                   1350: ** Call mprintf with two integer arguments and one double argument
                   1351: */
                   1352: static int sqlite3_mprintf_double(
                   1353:   void *NotUsed,
                   1354:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1355:   int argc,              /* Number of arguments */
                   1356:   char **argv            /* Text of each argument */
                   1357: ){
                   1358:   int a[3], i;
                   1359:   double r;
                   1360:   char *z;
                   1361:   if( argc!=5 ){
                   1362:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1363:        " FORMAT INT INT DOUBLE\"", 0);
                   1364:     return TCL_ERROR;
                   1365:   }
                   1366:   for(i=2; i<4; i++){
                   1367:     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
                   1368:   }
                   1369:   if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR;
                   1370:   z = sqlite3_mprintf(argv[1], a[0], a[1], r);
                   1371:   Tcl_AppendResult(interp, z, 0);
                   1372:   sqlite3_free(z);
                   1373:   return TCL_OK;
                   1374: }
                   1375: 
                   1376: /*
                   1377: ** Usage:  sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE
                   1378: **
                   1379: ** Call mprintf with a single double argument which is the product of the
                   1380: ** two arguments given above.  This is used to generate overflow and underflow
                   1381: ** doubles to test that they are converted properly.
                   1382: */
                   1383: static int sqlite3_mprintf_scaled(
                   1384:   void *NotUsed,
                   1385:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1386:   int argc,              /* Number of arguments */
                   1387:   char **argv            /* Text of each argument */
                   1388: ){
                   1389:   int i;
                   1390:   double r[2];
                   1391:   char *z;
                   1392:   if( argc!=4 ){
                   1393:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1394:        " FORMAT DOUBLE DOUBLE\"", 0);
                   1395:     return TCL_ERROR;
                   1396:   }
                   1397:   for(i=2; i<4; i++){
                   1398:     if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR;
                   1399:   }
                   1400:   z = sqlite3_mprintf(argv[1], r[0]*r[1]);
                   1401:   Tcl_AppendResult(interp, z, 0);
                   1402:   sqlite3_free(z);
                   1403:   return TCL_OK;
                   1404: }
                   1405: 
                   1406: /*
                   1407: ** Usage:  sqlite3_mprintf_stronly FORMAT STRING
                   1408: **
                   1409: ** Call mprintf with a single double argument which is the product of the
                   1410: ** two arguments given above.  This is used to generate overflow and underflow
                   1411: ** doubles to test that they are converted properly.
                   1412: */
                   1413: static int sqlite3_mprintf_stronly(
                   1414:   void *NotUsed,
                   1415:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1416:   int argc,              /* Number of arguments */
                   1417:   char **argv            /* Text of each argument */
                   1418: ){
                   1419:   char *z;
                   1420:   if( argc!=3 ){
                   1421:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1422:        " FORMAT STRING\"", 0);
                   1423:     return TCL_ERROR;
                   1424:   }
                   1425:   z = sqlite3_mprintf(argv[1], argv[2]);
                   1426:   Tcl_AppendResult(interp, z, 0);
                   1427:   sqlite3_free(z);
                   1428:   return TCL_OK;
                   1429: }
                   1430: 
                   1431: /*
                   1432: ** Usage:  sqlite3_mprintf_hexdouble FORMAT HEX
                   1433: **
                   1434: ** Call mprintf with a single double argument which is derived from the
                   1435: ** hexadecimal encoding of an IEEE double.
                   1436: */
                   1437: static int sqlite3_mprintf_hexdouble(
                   1438:   void *NotUsed,
                   1439:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1440:   int argc,              /* Number of arguments */
                   1441:   char **argv            /* Text of each argument */
                   1442: ){
                   1443:   char *z;
                   1444:   double r;
                   1445:   unsigned int x1, x2;
                   1446:   sqlite_uint64 d;
                   1447:   if( argc!=3 ){
                   1448:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   1449:        " FORMAT STRING\"", 0);
                   1450:     return TCL_ERROR;
                   1451:   }
                   1452:   if( sscanf(argv[2], "%08x%08x", &x2, &x1)!=2 ){
                   1453:     Tcl_AppendResult(interp, "2nd argument should be 16-characters of hex", 0);
                   1454:     return TCL_ERROR;
                   1455:   }
                   1456:   d = x2;
                   1457:   d = (d<<32) + x1;
                   1458:   memcpy(&r, &d, sizeof(r));
                   1459:   z = sqlite3_mprintf(argv[1], r);
                   1460:   Tcl_AppendResult(interp, z, 0);
                   1461:   sqlite3_free(z);
                   1462:   return TCL_OK;
                   1463: }
                   1464: 
                   1465: /*
                   1466: ** Usage: sqlite3_enable_shared_cache ?BOOLEAN?
                   1467: **
                   1468: */
                   1469: #if !defined(SQLITE_OMIT_SHARED_CACHE)
                   1470: static int test_enable_shared(
                   1471:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   1472:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1473:   int objc,              /* Number of arguments */
                   1474:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1475: ){
                   1476:   int rc;
                   1477:   int enable;
                   1478:   int ret = 0;
                   1479: 
                   1480:   if( objc!=2 && objc!=1 ){
                   1481:     Tcl_WrongNumArgs(interp, 1, objv, "?BOOLEAN?");
                   1482:     return TCL_ERROR;
                   1483:   }
                   1484:   ret = sqlite3GlobalConfig.sharedCacheEnabled;
                   1485: 
                   1486:   if( objc==2 ){
                   1487:     if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
                   1488:       return TCL_ERROR;
                   1489:     }
                   1490:     rc = sqlite3_enable_shared_cache(enable);
                   1491:     if( rc!=SQLITE_OK ){
                   1492:       Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC);
                   1493:       return TCL_ERROR;
                   1494:     }
                   1495:   }
                   1496:   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(ret));
                   1497:   return TCL_OK;
                   1498: }
                   1499: #endif
                   1500: 
                   1501: 
                   1502: 
                   1503: /*
                   1504: ** Usage: sqlite3_extended_result_codes   DB    BOOLEAN
                   1505: **
                   1506: */
                   1507: static int test_extended_result_codes(
                   1508:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   1509:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1510:   int objc,              /* Number of arguments */
                   1511:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1512: ){
                   1513:   int enable;
                   1514:   sqlite3 *db;
                   1515: 
                   1516:   if( objc!=3 ){
                   1517:     Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
                   1518:     return TCL_ERROR;
                   1519:   }
                   1520:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   1521:   if( Tcl_GetBooleanFromObj(interp, objv[2], &enable) ) return TCL_ERROR;
                   1522:   sqlite3_extended_result_codes(db, enable);
                   1523:   return TCL_OK;
                   1524: }
                   1525: 
                   1526: /*
                   1527: ** Usage: sqlite3_libversion_number
                   1528: **
                   1529: */
                   1530: static int test_libversion_number(
                   1531:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   1532:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1533:   int objc,              /* Number of arguments */
                   1534:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1535: ){
                   1536:   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_libversion_number()));
                   1537:   return TCL_OK;
                   1538: }
                   1539: 
                   1540: /*
                   1541: ** Usage: sqlite3_table_column_metadata DB dbname tblname colname
                   1542: **
                   1543: */
                   1544: #ifdef SQLITE_ENABLE_COLUMN_METADATA
                   1545: static int test_table_column_metadata(
                   1546:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   1547:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1548:   int objc,              /* Number of arguments */
                   1549:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1550: ){
                   1551:   sqlite3 *db;
                   1552:   const char *zDb;
                   1553:   const char *zTbl;
                   1554:   const char *zCol;
                   1555:   int rc;
                   1556:   Tcl_Obj *pRet;
                   1557: 
                   1558:   const char *zDatatype;
                   1559:   const char *zCollseq;
                   1560:   int notnull;
                   1561:   int primarykey;
                   1562:   int autoincrement;
                   1563: 
                   1564:   if( objc!=5 ){
                   1565:     Tcl_WrongNumArgs(interp, 1, objv, "DB dbname tblname colname");
                   1566:     return TCL_ERROR;
                   1567:   }
                   1568:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   1569:   zDb = Tcl_GetString(objv[2]);
                   1570:   zTbl = Tcl_GetString(objv[3]);
                   1571:   zCol = Tcl_GetString(objv[4]);
                   1572: 
                   1573:   if( strlen(zDb)==0 ) zDb = 0;
                   1574: 
                   1575:   rc = sqlite3_table_column_metadata(db, zDb, zTbl, zCol, 
                   1576:       &zDatatype, &zCollseq, &notnull, &primarykey, &autoincrement);
                   1577: 
                   1578:   if( rc!=SQLITE_OK ){
                   1579:     Tcl_AppendResult(interp, sqlite3_errmsg(db), 0);
                   1580:     return TCL_ERROR;
                   1581:   }
                   1582: 
                   1583:   pRet = Tcl_NewObj();
                   1584:   Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zDatatype, -1));
                   1585:   Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zCollseq, -1));
                   1586:   Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(notnull));
                   1587:   Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(primarykey));
                   1588:   Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(autoincrement));
                   1589:   Tcl_SetObjResult(interp, pRet);
                   1590: 
                   1591:   return TCL_OK;
                   1592: }
                   1593: #endif
                   1594: 
                   1595: #ifndef SQLITE_OMIT_INCRBLOB
                   1596: 
                   1597: static int blobHandleFromObj(
                   1598:   Tcl_Interp *interp, 
                   1599:   Tcl_Obj *pObj,
                   1600:   sqlite3_blob **ppBlob
                   1601: ){
                   1602:   char *z;
                   1603:   int n;
                   1604: 
                   1605:   z = Tcl_GetStringFromObj(pObj, &n);
                   1606:   if( n==0 ){
                   1607:     *ppBlob = 0;
                   1608:   }else{
                   1609:     int notUsed;
                   1610:     Tcl_Channel channel;
                   1611:     ClientData instanceData;
                   1612:     
                   1613:     channel = Tcl_GetChannel(interp, z, &notUsed);
                   1614:     if( !channel ) return TCL_ERROR;
                   1615: 
                   1616:     Tcl_Flush(channel);
                   1617:     Tcl_Seek(channel, 0, SEEK_SET);
                   1618: 
                   1619:     instanceData = Tcl_GetChannelInstanceData(channel);
                   1620:     *ppBlob = *((sqlite3_blob **)instanceData);
                   1621:   }
                   1622: 
                   1623:   return TCL_OK;
                   1624: }
                   1625: 
                   1626: /*
                   1627: ** sqlite3_blob_bytes  CHANNEL
                   1628: */
                   1629: static int test_blob_bytes(
                   1630:   ClientData clientData, /* Not used */
                   1631:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1632:   int objc,              /* Number of arguments */
                   1633:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1634: ){
                   1635:   sqlite3_blob *pBlob;
                   1636:   int nByte;
                   1637:   
                   1638:   if( objc!=2 ){
                   1639:     Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL");
                   1640:     return TCL_ERROR;
                   1641:   }
                   1642: 
                   1643:   if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
                   1644:   nByte = sqlite3_blob_bytes(pBlob);
                   1645:   Tcl_SetObjResult(interp, Tcl_NewIntObj(nByte));
                   1646: 
                   1647:   return TCL_OK;
                   1648: }
                   1649: 
                   1650: /*
                   1651: ** sqlite3_blob_close  CHANNEL
                   1652: */
                   1653: static int test_blob_close(
                   1654:   ClientData clientData, /* Not used */
                   1655:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1656:   int objc,              /* Number of arguments */
                   1657:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1658: ){
                   1659:   sqlite3_blob *pBlob;
                   1660:   
                   1661:   if( objc!=2 ){
                   1662:     Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL");
                   1663:     return TCL_ERROR;
                   1664:   }
                   1665: 
                   1666:   if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
                   1667:   sqlite3_blob_close(pBlob);
                   1668: 
                   1669:   return TCL_OK;
                   1670: }
                   1671: 
                   1672: /*
                   1673: ** sqlite3_blob_read  CHANNEL OFFSET N
                   1674: **
                   1675: **   This command is used to test the sqlite3_blob_read() in ways that
                   1676: **   the Tcl channel interface does not. The first argument should
                   1677: **   be the name of a valid channel created by the [incrblob] method
                   1678: **   of a database handle. This function calls sqlite3_blob_read()
                   1679: **   to read N bytes from offset OFFSET from the underlying SQLite
                   1680: **   blob handle.
                   1681: **
                   1682: **   On success, a byte-array object containing the read data is 
                   1683: **   returned. On failure, the interpreter result is set to the
                   1684: **   text representation of the returned error code (i.e. "SQLITE_NOMEM")
                   1685: **   and a Tcl exception is thrown.
                   1686: */
                   1687: static int test_blob_read(
                   1688:   ClientData clientData, /* Not used */
                   1689:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1690:   int objc,              /* Number of arguments */
                   1691:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1692: ){
                   1693:   sqlite3_blob *pBlob;
                   1694:   int nByte;
                   1695:   int iOffset;
                   1696:   unsigned char *zBuf = 0;
                   1697:   int rc;
                   1698:   
                   1699:   if( objc!=4 ){
                   1700:     Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N");
                   1701:     return TCL_ERROR;
                   1702:   }
                   1703: 
                   1704:   if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
                   1705:   if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset)
                   1706:    || TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte)
                   1707:   ){ 
                   1708:     return TCL_ERROR;
                   1709:   }
                   1710: 
                   1711:   if( nByte>0 ){
                   1712:     zBuf = (unsigned char *)Tcl_Alloc(nByte);
                   1713:   }
                   1714:   rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset);
                   1715:   if( rc==SQLITE_OK ){
                   1716:     Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zBuf, nByte));
                   1717:   }else{
                   1718:     Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
                   1719:   }
                   1720:   Tcl_Free((char *)zBuf);
                   1721: 
                   1722:   return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
                   1723: }
                   1724: 
                   1725: /*
                   1726: ** sqlite3_blob_write CHANNEL OFFSET DATA ?NDATA?
                   1727: **
                   1728: **   This command is used to test the sqlite3_blob_write() in ways that
                   1729: **   the Tcl channel interface does not. The first argument should
                   1730: **   be the name of a valid channel created by the [incrblob] method
                   1731: **   of a database handle. This function calls sqlite3_blob_write()
                   1732: **   to write the DATA byte-array to the underlying SQLite blob handle.
                   1733: **   at offset OFFSET.
                   1734: **
                   1735: **   On success, an empty string is returned. On failure, the interpreter
                   1736: **   result is set to the text representation of the returned error code 
                   1737: **   (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown.
                   1738: */
                   1739: static int test_blob_write(
                   1740:   ClientData clientData, /* Not used */
                   1741:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1742:   int objc,              /* Number of arguments */
                   1743:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1744: ){
                   1745:   sqlite3_blob *pBlob;
                   1746:   int iOffset;
                   1747:   int rc;
                   1748: 
                   1749:   unsigned char *zBuf;
                   1750:   int nBuf;
                   1751:   
                   1752:   if( objc!=4 && objc!=5 ){
                   1753:     Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?");
                   1754:     return TCL_ERROR;
                   1755:   }
                   1756: 
                   1757:   if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
                   1758:   if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ 
                   1759:     return TCL_ERROR;
                   1760:   }
                   1761: 
                   1762:   zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf);
                   1763:   if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){
                   1764:     return TCL_ERROR;
                   1765:   }
                   1766:   rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset);
                   1767:   if( rc!=SQLITE_OK ){
                   1768:     Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
                   1769:   }
                   1770: 
                   1771:   return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
                   1772: }
                   1773: 
                   1774: static int test_blob_reopen(
                   1775:   ClientData clientData, /* Not used */
                   1776:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1777:   int objc,              /* Number of arguments */
                   1778:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1779: ){
                   1780:   Tcl_WideInt iRowid;
                   1781:   sqlite3_blob *pBlob;
                   1782:   int rc;
                   1783: 
                   1784:   if( objc!=3 ){
                   1785:     Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL ROWID");
                   1786:     return TCL_ERROR;
                   1787:   }
                   1788: 
                   1789:   if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
                   1790:   if( Tcl_GetWideIntFromObj(interp, objv[2], &iRowid) ) return TCL_ERROR;
                   1791: 
                   1792:   rc = sqlite3_blob_reopen(pBlob, iRowid);
                   1793:   if( rc!=SQLITE_OK ){
                   1794:     Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
                   1795:   }
                   1796: 
                   1797:   return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
                   1798: }
                   1799: 
                   1800: #endif
                   1801: 
                   1802: /*
                   1803: ** Usage: sqlite3_create_collation_v2 DB-HANDLE NAME CMP-PROC DEL-PROC
                   1804: **
                   1805: **   This Tcl proc is used for testing the experimental
                   1806: **   sqlite3_create_collation_v2() interface.
                   1807: */
                   1808: struct TestCollationX {
                   1809:   Tcl_Interp *interp;
                   1810:   Tcl_Obj *pCmp;
                   1811:   Tcl_Obj *pDel;
                   1812: };
                   1813: typedef struct TestCollationX TestCollationX;
                   1814: static void testCreateCollationDel(void *pCtx){
                   1815:   TestCollationX *p = (TestCollationX *)pCtx;
                   1816: 
                   1817:   int rc = Tcl_EvalObjEx(p->interp, p->pDel, TCL_EVAL_DIRECT|TCL_EVAL_GLOBAL);
                   1818:   if( rc!=TCL_OK ){
                   1819:     Tcl_BackgroundError(p->interp);
                   1820:   }
                   1821: 
                   1822:   Tcl_DecrRefCount(p->pCmp);
                   1823:   Tcl_DecrRefCount(p->pDel);
                   1824:   sqlite3_free((void *)p);
                   1825: }
                   1826: static int testCreateCollationCmp(
                   1827:   void *pCtx,
                   1828:   int nLeft,
                   1829:   const void *zLeft,
                   1830:   int nRight,
                   1831:   const void *zRight
                   1832: ){
                   1833:   TestCollationX *p = (TestCollationX *)pCtx;
                   1834:   Tcl_Obj *pScript = Tcl_DuplicateObj(p->pCmp);
                   1835:   int iRes = 0;
                   1836: 
                   1837:   Tcl_IncrRefCount(pScript);
                   1838:   Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj((char *)zLeft, nLeft));
                   1839:   Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj((char *)zRight,nRight));
                   1840: 
                   1841:   if( TCL_OK!=Tcl_EvalObjEx(p->interp, pScript, TCL_EVAL_DIRECT|TCL_EVAL_GLOBAL)
                   1842:    || TCL_OK!=Tcl_GetIntFromObj(p->interp, Tcl_GetObjResult(p->interp), &iRes)
                   1843:   ){
                   1844:     Tcl_BackgroundError(p->interp);
                   1845:   }
                   1846:   Tcl_DecrRefCount(pScript);
                   1847: 
                   1848:   return iRes;
                   1849: }
                   1850: static int test_create_collation_v2(
                   1851:   ClientData clientData, /* Not used */
                   1852:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   1853:   int objc,              /* Number of arguments */
                   1854:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   1855: ){
                   1856:   TestCollationX *p;
                   1857:   sqlite3 *db;
                   1858:   int rc;
                   1859: 
                   1860:   if( objc!=5 ){
                   1861:     Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE NAME CMP-PROC DEL-PROC");
                   1862:     return TCL_ERROR;
                   1863:   }
                   1864:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   1865: 
                   1866:   p = (TestCollationX *)sqlite3_malloc(sizeof(TestCollationX));
                   1867:   p->pCmp = objv[3];
                   1868:   p->pDel = objv[4];
                   1869:   p->interp = interp;
                   1870:   Tcl_IncrRefCount(p->pCmp);
                   1871:   Tcl_IncrRefCount(p->pDel);
                   1872: 
                   1873:   rc = sqlite3_create_collation_v2(db, Tcl_GetString(objv[2]), 16, 
                   1874:       (void *)p, testCreateCollationCmp, testCreateCollationDel
                   1875:   );
                   1876:   if( rc!=SQLITE_MISUSE ){
                   1877:     Tcl_AppendResult(interp, "sqlite3_create_collate_v2() failed to detect "
                   1878:       "an invalid encoding", (char*)0);
                   1879:     return TCL_ERROR;
                   1880:   }
                   1881:   rc = sqlite3_create_collation_v2(db, Tcl_GetString(objv[2]), SQLITE_UTF8, 
                   1882:       (void *)p, testCreateCollationCmp, testCreateCollationDel
                   1883:   );
                   1884:   return TCL_OK;
                   1885: }
                   1886: 
                   1887: /*
                   1888: ** USAGE: sqlite3_create_function_v2 DB NAME NARG ENC ?SWITCHES?
                   1889: **
                   1890: ** Available switches are:
                   1891: **
                   1892: **   -func    SCRIPT
                   1893: **   -step    SCRIPT
                   1894: **   -final   SCRIPT
                   1895: **   -destroy SCRIPT
                   1896: */
                   1897: typedef struct CreateFunctionV2 CreateFunctionV2;
                   1898: struct CreateFunctionV2 {
                   1899:   Tcl_Interp *interp;
                   1900:   Tcl_Obj *pFunc;                 /* Script for function invocation */
                   1901:   Tcl_Obj *pStep;                 /* Script for agg. step invocation */
                   1902:   Tcl_Obj *pFinal;                /* Script for agg. finalization invocation */
                   1903:   Tcl_Obj *pDestroy;              /* Destructor script */
                   1904: };
                   1905: static void cf2Func(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
                   1906: }
                   1907: static void cf2Step(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
                   1908: }
                   1909: static void cf2Final(sqlite3_context *ctx){
                   1910: }
                   1911: static void cf2Destroy(void *pUser){
                   1912:   CreateFunctionV2 *p = (CreateFunctionV2 *)pUser;
                   1913: 
                   1914:   if( p->interp && p->pDestroy ){
                   1915:     int rc = Tcl_EvalObjEx(p->interp, p->pDestroy, 0);
                   1916:     if( rc!=TCL_OK ) Tcl_BackgroundError(p->interp);
                   1917:   }
                   1918: 
                   1919:   if( p->pFunc ) Tcl_DecrRefCount(p->pFunc); 
                   1920:   if( p->pStep ) Tcl_DecrRefCount(p->pStep); 
                   1921:   if( p->pFinal ) Tcl_DecrRefCount(p->pFinal); 
                   1922:   if( p->pDestroy ) Tcl_DecrRefCount(p->pDestroy); 
                   1923:   sqlite3_free(p);
                   1924: }
                   1925: static int test_create_function_v2(
                   1926:   ClientData clientData,          /* Not used */
                   1927:   Tcl_Interp *interp,             /* The invoking TCL interpreter */
                   1928:   int objc,                       /* Number of arguments */
                   1929:   Tcl_Obj *CONST objv[]           /* Command arguments */
                   1930: ){
                   1931:   sqlite3 *db;
                   1932:   const char *zFunc;
                   1933:   int nArg;
                   1934:   int enc;
                   1935:   CreateFunctionV2 *p;
                   1936:   int i;
                   1937:   int rc;
                   1938: 
                   1939:   struct EncTable {
                   1940:     const char *zEnc;
                   1941:     int enc;
                   1942:   } aEnc[] = {
                   1943:     {"utf8",    SQLITE_UTF8 },
                   1944:     {"utf16",   SQLITE_UTF16 },
                   1945:     {"utf16le", SQLITE_UTF16LE },
                   1946:     {"utf16be", SQLITE_UTF16BE },
                   1947:     {"any",     SQLITE_ANY },
                   1948:     {"0", 0 }
                   1949:   };
                   1950: 
                   1951:   if( objc<5 || (objc%2)==0 ){
                   1952:     Tcl_WrongNumArgs(interp, 1, objv, "DB NAME NARG ENC SWITCHES...");
                   1953:     return TCL_ERROR;
                   1954:   }
                   1955: 
                   1956:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   1957:   zFunc = Tcl_GetString(objv[2]);
                   1958:   if( Tcl_GetIntFromObj(interp, objv[3], &nArg) ) return TCL_ERROR;
                   1959:   if( Tcl_GetIndexFromObjStruct(interp, objv[4], aEnc, sizeof(aEnc[0]), 
                   1960:           "encoding", 0, &enc)
                   1961:   ){
                   1962:     return TCL_ERROR;
                   1963:   }
                   1964:   enc = aEnc[enc].enc;
                   1965: 
                   1966:   p = sqlite3_malloc(sizeof(CreateFunctionV2));
                   1967:   assert( p );
                   1968:   memset(p, 0, sizeof(CreateFunctionV2));
                   1969:   p->interp = interp;
                   1970: 
                   1971:   for(i=5; i<objc; i+=2){
                   1972:     int iSwitch;
                   1973:     const char *azSwitch[] = {"-func", "-step", "-final", "-destroy", 0};
                   1974:     if( Tcl_GetIndexFromObj(interp, objv[i], azSwitch, "switch", 0, &iSwitch) ){
                   1975:       sqlite3_free(p);
                   1976:       return TCL_ERROR;
                   1977:     }
                   1978: 
                   1979:     switch( iSwitch ){
                   1980:       case 0: p->pFunc = objv[i+1];      break;
                   1981:       case 1: p->pStep = objv[i+1];      break;
                   1982:       case 2: p->pFinal = objv[i+1];     break;
                   1983:       case 3: p->pDestroy = objv[i+1];   break;
                   1984:     }
                   1985:   }
                   1986:   if( p->pFunc ) p->pFunc = Tcl_DuplicateObj(p->pFunc); 
                   1987:   if( p->pStep ) p->pStep = Tcl_DuplicateObj(p->pStep); 
                   1988:   if( p->pFinal ) p->pFinal = Tcl_DuplicateObj(p->pFinal); 
                   1989:   if( p->pDestroy ) p->pDestroy = Tcl_DuplicateObj(p->pDestroy); 
                   1990: 
                   1991:   if( p->pFunc ) Tcl_IncrRefCount(p->pFunc); 
                   1992:   if( p->pStep ) Tcl_IncrRefCount(p->pStep); 
                   1993:   if( p->pFinal ) Tcl_IncrRefCount(p->pFinal); 
                   1994:   if( p->pDestroy ) Tcl_IncrRefCount(p->pDestroy); 
                   1995: 
                   1996:   rc = sqlite3_create_function_v2(db, zFunc, nArg, enc, (void *)p, 
                   1997:       (p->pFunc ? cf2Func : 0),
                   1998:       (p->pStep ? cf2Step : 0),
                   1999:       (p->pFinal ? cf2Final : 0),
                   2000:       cf2Destroy
                   2001:   );
                   2002:   if( rc!=SQLITE_OK ){
                   2003:     Tcl_ResetResult(interp);
                   2004:     Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
                   2005:     return TCL_ERROR;
                   2006:   }
                   2007:   return TCL_OK;
                   2008: }
                   2009: 
                   2010: /*
                   2011: ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC?
                   2012: */
                   2013: static int test_load_extension(
                   2014:   ClientData clientData, /* Not used */
                   2015:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   2016:   int objc,              /* Number of arguments */
                   2017:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   2018: ){
                   2019:   Tcl_CmdInfo cmdInfo;
                   2020:   sqlite3 *db;
                   2021:   int rc;
                   2022:   char *zDb;
                   2023:   char *zFile;
                   2024:   char *zProc = 0;
                   2025:   char *zErr = 0;
                   2026: 
                   2027:   if( objc!=4 && objc!=3 ){
                   2028:     Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE FILE ?PROC?");
                   2029:     return TCL_ERROR;
                   2030:   }
                   2031:   zDb = Tcl_GetString(objv[1]);
                   2032:   zFile = Tcl_GetString(objv[2]);
                   2033:   if( objc==4 ){
                   2034:     zProc = Tcl_GetString(objv[3]);
                   2035:   }
                   2036: 
                   2037:   /* Extract the C database handle from the Tcl command name */
                   2038:   if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
                   2039:     Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0);
                   2040:     return TCL_ERROR;
                   2041:   }
                   2042:   db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
                   2043:   assert(db);
                   2044: 
                   2045:   /* Call the underlying C function. If an error occurs, set rc to 
                   2046:   ** TCL_ERROR and load any error string into the interpreter. If no 
                   2047:   ** error occurs, set rc to TCL_OK.
                   2048:   */
                   2049: #ifdef SQLITE_OMIT_LOAD_EXTENSION
                   2050:   rc = SQLITE_ERROR;
                   2051:   zErr = sqlite3_mprintf("this build omits sqlite3_load_extension()");
                   2052: #else
                   2053:   rc = sqlite3_load_extension(db, zFile, zProc, &zErr);
                   2054: #endif
                   2055:   if( rc!=SQLITE_OK ){
                   2056:     Tcl_SetResult(interp, zErr ? zErr : "", TCL_VOLATILE);
                   2057:     rc = TCL_ERROR;
                   2058:   }else{
                   2059:     rc = TCL_OK;
                   2060:   }
                   2061:   sqlite3_free(zErr);
                   2062: 
                   2063:   return rc;
                   2064: }
                   2065: 
                   2066: /*
                   2067: ** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF
                   2068: */
                   2069: static int test_enable_load(
                   2070:   ClientData clientData, /* Not used */
                   2071:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   2072:   int objc,              /* Number of arguments */
                   2073:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   2074: ){
                   2075:   Tcl_CmdInfo cmdInfo;
                   2076:   sqlite3 *db;
                   2077:   char *zDb;
                   2078:   int onoff;
                   2079: 
                   2080:   if( objc!=3 ){
                   2081:     Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE ONOFF");
                   2082:     return TCL_ERROR;
                   2083:   }
                   2084:   zDb = Tcl_GetString(objv[1]);
                   2085: 
                   2086:   /* Extract the C database handle from the Tcl command name */
                   2087:   if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
                   2088:     Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0);
                   2089:     return TCL_ERROR;
                   2090:   }
                   2091:   db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
                   2092:   assert(db);
                   2093: 
                   2094:   /* Get the onoff parameter */
                   2095:   if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
                   2096:     return TCL_ERROR;
                   2097:   }
                   2098: 
                   2099: #ifdef SQLITE_OMIT_LOAD_EXTENSION
                   2100:   Tcl_AppendResult(interp, "this build omits sqlite3_load_extension()");
                   2101:   return TCL_ERROR;
                   2102: #else
                   2103:   sqlite3_enable_load_extension(db, onoff);
                   2104:   return TCL_OK;
                   2105: #endif
                   2106: }
                   2107: 
                   2108: /*
                   2109: ** Usage:  sqlite_abort
                   2110: **
                   2111: ** Shutdown the process immediately.  This is not a clean shutdown.
                   2112: ** This command is used to test the recoverability of a database in
                   2113: ** the event of a program crash.
                   2114: */
                   2115: static int sqlite_abort(
                   2116:   void *NotUsed,
                   2117:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   2118:   int argc,              /* Number of arguments */
                   2119:   char **argv            /* Text of each argument */
                   2120: ){
                   2121: #if defined(_MSC_VER)
                   2122:   /* We do this, otherwise the test will halt with a popup message
                   2123:    * that we have to click away before the test will continue.
                   2124:    */
                   2125:   _set_abort_behavior( 0, _CALL_REPORTFAULT );
                   2126: #endif
                   2127:   exit(255);
                   2128:   assert( interp==0 );   /* This will always fail */
                   2129:   return TCL_OK;
                   2130: }
                   2131: 
                   2132: /*
                   2133: ** The following routine is a user-defined SQL function whose purpose
                   2134: ** is to test the sqlite_set_result() API.
                   2135: */
                   2136: static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
                   2137:   while( argc>=2 ){
                   2138:     const char *zArg0 = (char*)sqlite3_value_text(argv[0]);
                   2139:     if( zArg0 ){
                   2140:       if( 0==sqlite3StrICmp(zArg0, "int") ){
                   2141:         sqlite3_result_int(context, sqlite3_value_int(argv[1]));
                   2142:       }else if( sqlite3StrICmp(zArg0,"int64")==0 ){
                   2143:         sqlite3_result_int64(context, sqlite3_value_int64(argv[1]));
                   2144:       }else if( sqlite3StrICmp(zArg0,"string")==0 ){
                   2145:         sqlite3_result_text(context, (char*)sqlite3_value_text(argv[1]), -1,
                   2146:             SQLITE_TRANSIENT);
                   2147:       }else if( sqlite3StrICmp(zArg0,"double")==0 ){
                   2148:         sqlite3_result_double(context, sqlite3_value_double(argv[1]));
                   2149:       }else if( sqlite3StrICmp(zArg0,"null")==0 ){
                   2150:         sqlite3_result_null(context);
                   2151:       }else if( sqlite3StrICmp(zArg0,"value")==0 ){
                   2152:         sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]);
                   2153:       }else{
                   2154:         goto error_out;
                   2155:       }
                   2156:     }else{
                   2157:       goto error_out;
                   2158:     }
                   2159:     argc -= 2;
                   2160:     argv += 2;
                   2161:   }
                   2162:   return;
                   2163: 
                   2164: error_out:
                   2165:   sqlite3_result_error(context,"first argument should be one of: "
                   2166:       "int int64 string double null value", -1);
                   2167: }
                   2168: 
                   2169: /*
                   2170: ** Usage:   sqlite_register_test_function  DB  NAME
                   2171: **
                   2172: ** Register the test SQL function on the database DB under the name NAME.
                   2173: */
                   2174: static int test_register_func(
                   2175:   void *NotUsed,
                   2176:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   2177:   int argc,              /* Number of arguments */
                   2178:   char **argv            /* Text of each argument */
                   2179: ){
                   2180:   sqlite3 *db;
                   2181:   int rc;
                   2182:   if( argc!=3 ){
                   2183:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                   2184:        " DB FUNCTION-NAME", 0);
                   2185:     return TCL_ERROR;
                   2186:   }
                   2187:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   2188:   rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 
                   2189:       testFunc, 0, 0);
                   2190:   if( rc!=0 ){
                   2191:     Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
                   2192:     return TCL_ERROR;
                   2193:   }
                   2194:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   2195:   return TCL_OK;
                   2196: }
                   2197: 
                   2198: /*
                   2199: ** Usage:  sqlite3_finalize  STMT 
                   2200: **
                   2201: ** Finalize a statement handle.
                   2202: */
                   2203: static int test_finalize(
                   2204:   void * clientData,
                   2205:   Tcl_Interp *interp,
                   2206:   int objc,
                   2207:   Tcl_Obj *CONST objv[]
                   2208: ){
                   2209:   sqlite3_stmt *pStmt;
                   2210:   int rc;
                   2211:   sqlite3 *db = 0;
                   2212: 
                   2213:   if( objc!=2 ){
                   2214:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2215:         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
                   2216:     return TCL_ERROR;
                   2217:   }
                   2218: 
                   2219:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   2220: 
                   2221:   if( pStmt ){
                   2222:     db = StmtToDb(pStmt);
                   2223:   }
                   2224:   rc = sqlite3_finalize(pStmt);
                   2225:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
                   2226:   if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   2227:   return TCL_OK;
                   2228: }
                   2229: 
                   2230: /*
                   2231: ** Usage:  sqlite3_stmt_status  STMT  CODE  RESETFLAG
                   2232: **
                   2233: ** Get the value of a status counter from a statement.
                   2234: */
                   2235: static int test_stmt_status(
                   2236:   void * clientData,
                   2237:   Tcl_Interp *interp,
                   2238:   int objc,
                   2239:   Tcl_Obj *CONST objv[]
                   2240: ){
                   2241:   int iValue;
                   2242:   int i, op, resetFlag;
                   2243:   const char *zOpName;
                   2244:   sqlite3_stmt *pStmt;
                   2245: 
                   2246:   static const struct {
                   2247:     const char *zName;
                   2248:     int op;
                   2249:   } aOp[] = {
                   2250:     { "SQLITE_STMTSTATUS_FULLSCAN_STEP",   SQLITE_STMTSTATUS_FULLSCAN_STEP   },
                   2251:     { "SQLITE_STMTSTATUS_SORT",            SQLITE_STMTSTATUS_SORT            },
                   2252:     { "SQLITE_STMTSTATUS_AUTOINDEX",       SQLITE_STMTSTATUS_AUTOINDEX       },
                   2253:   };
                   2254:   if( objc!=4 ){
                   2255:     Tcl_WrongNumArgs(interp, 1, objv, "STMT PARAMETER RESETFLAG");
                   2256:     return TCL_ERROR;
                   2257:   }
                   2258:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   2259:   zOpName = Tcl_GetString(objv[2]);
                   2260:   for(i=0; i<ArraySize(aOp); i++){
                   2261:     if( strcmp(aOp[i].zName, zOpName)==0 ){
                   2262:       op = aOp[i].op;
                   2263:       break;
                   2264:     }
                   2265:   }
                   2266:   if( i>=ArraySize(aOp) ){
                   2267:     if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR;
                   2268:   }
                   2269:   if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR;
                   2270:   iValue = sqlite3_stmt_status(pStmt, op, resetFlag);
                   2271:   Tcl_SetObjResult(interp, Tcl_NewIntObj(iValue));
                   2272:   return TCL_OK;
                   2273: }
                   2274: 
                   2275: /*
                   2276: ** Usage:  sqlite3_next_stmt  DB  STMT
                   2277: **
                   2278: ** Return the next statment in sequence after STMT.
                   2279: */
                   2280: static int test_next_stmt(
                   2281:   void * clientData,
                   2282:   Tcl_Interp *interp,
                   2283:   int objc,
                   2284:   Tcl_Obj *CONST objv[]
                   2285: ){
                   2286:   sqlite3_stmt *pStmt;
                   2287:   sqlite3 *db = 0;
                   2288:   char zBuf[50];
                   2289: 
                   2290:   if( objc!=3 ){
                   2291:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2292:         Tcl_GetStringFromObj(objv[0], 0), " DB STMT", 0);
                   2293:     return TCL_ERROR;
                   2294:   }
                   2295: 
                   2296:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   2297:   if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt) ) return TCL_ERROR;
                   2298:   pStmt = sqlite3_next_stmt(db, pStmt);
                   2299:   if( pStmt ){
                   2300:     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
                   2301:     Tcl_AppendResult(interp, zBuf, 0);
                   2302:   }
                   2303:   return TCL_OK;
                   2304: }
                   2305: 
                   2306: /*
                   2307: ** Usage:  sqlite3_stmt_readonly  STMT
                   2308: **
                   2309: ** Return true if STMT is a NULL pointer or a pointer to a statement
                   2310: ** that is guaranteed to leave the database unmodified.
                   2311: */
                   2312: static int test_stmt_readonly(
                   2313:   void * clientData,
                   2314:   Tcl_Interp *interp,
                   2315:   int objc,
                   2316:   Tcl_Obj *CONST objv[]
                   2317: ){
                   2318:   sqlite3_stmt *pStmt;
                   2319:   int rc;
                   2320: 
                   2321:   if( objc!=2 ){
                   2322:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2323:         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
                   2324:     return TCL_ERROR;
                   2325:   }
                   2326: 
                   2327:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   2328:   rc = sqlite3_stmt_readonly(pStmt);
                   2329:   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
                   2330:   return TCL_OK;
                   2331: }
                   2332: 
                   2333: /*
                   2334: ** Usage:  sqlite3_stmt_busy  STMT
                   2335: **
                   2336: ** Return true if STMT is a non-NULL pointer to a statement
                   2337: ** that has been stepped but not to completion.
                   2338: */
                   2339: static int test_stmt_busy(
                   2340:   void * clientData,
                   2341:   Tcl_Interp *interp,
                   2342:   int objc,
                   2343:   Tcl_Obj *CONST objv[]
                   2344: ){
                   2345:   sqlite3_stmt *pStmt;
                   2346:   int rc;
                   2347: 
                   2348:   if( objc!=2 ){
                   2349:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2350:         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
                   2351:     return TCL_ERROR;
                   2352:   }
                   2353: 
                   2354:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   2355:   rc = sqlite3_stmt_busy(pStmt);
                   2356:   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
                   2357:   return TCL_OK;
                   2358: }
                   2359: 
                   2360: /*
                   2361: ** Usage:  uses_stmt_journal  STMT
                   2362: **
                   2363: ** Return true if STMT uses a statement journal.
                   2364: */
                   2365: static int uses_stmt_journal(
                   2366:   void * clientData,
                   2367:   Tcl_Interp *interp,
                   2368:   int objc,
                   2369:   Tcl_Obj *CONST objv[]
                   2370: ){
                   2371:   sqlite3_stmt *pStmt;
                   2372:   int rc;
                   2373: 
                   2374:   if( objc!=2 ){
                   2375:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2376:         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
                   2377:     return TCL_ERROR;
                   2378:   }
                   2379: 
                   2380:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   2381:   rc = sqlite3_stmt_readonly(pStmt);
                   2382:   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(((Vdbe *)pStmt)->usesStmtJournal));
                   2383:   return TCL_OK;
                   2384: }
                   2385: 
                   2386: 
                   2387: /*
                   2388: ** Usage:  sqlite3_reset  STMT 
                   2389: **
                   2390: ** Reset a statement handle.
                   2391: */
                   2392: static int test_reset(
                   2393:   void * clientData,
                   2394:   Tcl_Interp *interp,
                   2395:   int objc,
                   2396:   Tcl_Obj *CONST objv[]
                   2397: ){
                   2398:   sqlite3_stmt *pStmt;
                   2399:   int rc;
                   2400: 
                   2401:   if( objc!=2 ){
                   2402:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2403:         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
                   2404:     return TCL_ERROR;
                   2405:   }
                   2406: 
                   2407:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   2408: 
                   2409:   rc = sqlite3_reset(pStmt);
                   2410:   if( pStmt && sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ){
                   2411:     return TCL_ERROR;
                   2412:   }
                   2413:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
                   2414: /*
                   2415:   if( rc ){
                   2416:     return TCL_ERROR;
                   2417:   }
                   2418: */
                   2419:   return TCL_OK;
                   2420: }
                   2421: 
                   2422: /*
                   2423: ** Usage:  sqlite3_expired STMT 
                   2424: **
                   2425: ** Return TRUE if a recompilation of the statement is recommended.
                   2426: */
                   2427: static int test_expired(
                   2428:   void * clientData,
                   2429:   Tcl_Interp *interp,
                   2430:   int objc,
                   2431:   Tcl_Obj *CONST objv[]
                   2432: ){
                   2433: #ifndef SQLITE_OMIT_DEPRECATED
                   2434:   sqlite3_stmt *pStmt;
                   2435:   if( objc!=2 ){
                   2436:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2437:         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
                   2438:     return TCL_ERROR;
                   2439:   }
                   2440:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   2441:   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt)));
                   2442: #endif
                   2443:   return TCL_OK;
                   2444: }
                   2445: 
                   2446: /*
                   2447: ** Usage:  sqlite3_transfer_bindings FROMSTMT TOSTMT
                   2448: **
                   2449: ** Transfer all bindings from FROMSTMT over to TOSTMT
                   2450: */
                   2451: static int test_transfer_bind(
                   2452:   void * clientData,
                   2453:   Tcl_Interp *interp,
                   2454:   int objc,
                   2455:   Tcl_Obj *CONST objv[]
                   2456: ){
                   2457: #ifndef SQLITE_OMIT_DEPRECATED
                   2458:   sqlite3_stmt *pStmt1, *pStmt2;
                   2459:   if( objc!=3 ){
                   2460:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2461:         Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0);
                   2462:     return TCL_ERROR;
                   2463:   }
                   2464:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR;
                   2465:   if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR;
                   2466:   Tcl_SetObjResult(interp, 
                   2467:      Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2)));
                   2468: #endif
                   2469:   return TCL_OK;
                   2470: }
                   2471: 
                   2472: /*
                   2473: ** Usage:  sqlite3_changes DB
                   2474: **
                   2475: ** Return the number of changes made to the database by the last SQL
                   2476: ** execution.
                   2477: */
                   2478: static int test_changes(
                   2479:   void * clientData,
                   2480:   Tcl_Interp *interp,
                   2481:   int objc,
                   2482:   Tcl_Obj *CONST objv[]
                   2483: ){
                   2484:   sqlite3 *db;
                   2485:   if( objc!=2 ){
                   2486:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2487:        Tcl_GetString(objv[0]), " DB", 0);
                   2488:     return TCL_ERROR;
                   2489:   }
                   2490:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   2491:   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db)));
                   2492:   return TCL_OK;
                   2493: }
                   2494: 
                   2495: /*
                   2496: ** This is the "static_bind_value" that variables are bound to when
                   2497: ** the FLAG option of sqlite3_bind is "static"
                   2498: */
                   2499: static char *sqlite_static_bind_value = 0;
                   2500: static int sqlite_static_bind_nbyte = 0;
                   2501: 
                   2502: /*
                   2503: ** Usage:  sqlite3_bind  VM  IDX  VALUE  FLAGS
                   2504: **
                   2505: ** Sets the value of the IDX-th occurance of "?" in the original SQL
                   2506: ** string.  VALUE is the new value.  If FLAGS=="null" then VALUE is
                   2507: ** ignored and the value is set to NULL.  If FLAGS=="static" then
                   2508: ** the value is set to the value of a static variable named
                   2509: ** "sqlite_static_bind_value".  If FLAGS=="normal" then a copy
                   2510: ** of the VALUE is made.  If FLAGS=="blob10" then a VALUE is ignored
                   2511: ** an a 10-byte blob "abc\000xyz\000pq" is inserted.
                   2512: */
                   2513: static int test_bind(
                   2514:   void *NotUsed,
                   2515:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   2516:   int argc,              /* Number of arguments */
                   2517:   char **argv            /* Text of each argument */
                   2518: ){
                   2519:   sqlite3_stmt *pStmt;
                   2520:   int rc;
                   2521:   int idx;
                   2522:   if( argc!=5 ){
                   2523:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                   2524:        " VM IDX VALUE (null|static|normal)\"", 0);
                   2525:     return TCL_ERROR;
                   2526:   }
                   2527:   if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR;
                   2528:   if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR;
                   2529:   if( strcmp(argv[4],"null")==0 ){
                   2530:     rc = sqlite3_bind_null(pStmt, idx);
                   2531:   }else if( strcmp(argv[4],"static")==0 ){
                   2532:     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0);
                   2533:   }else if( strcmp(argv[4],"static-nbytes")==0 ){
                   2534:     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value,
                   2535:                                        sqlite_static_bind_nbyte, 0);
                   2536:   }else if( strcmp(argv[4],"normal")==0 ){
                   2537:     rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT);
                   2538:   }else if( strcmp(argv[4],"blob10")==0 ){
                   2539:     rc = sqlite3_bind_text(pStmt, idx, "abc\000xyz\000pq", 10, SQLITE_STATIC);
                   2540:   }else{
                   2541:     Tcl_AppendResult(interp, "4th argument should be "
                   2542:         "\"null\" or \"static\" or \"normal\"", 0);
                   2543:     return TCL_ERROR;
                   2544:   }
                   2545:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   2546:   if( rc ){
                   2547:     char zBuf[50];
                   2548:     sprintf(zBuf, "(%d) ", rc);
                   2549:     Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0);
                   2550:     return TCL_ERROR;
                   2551:   }
                   2552:   return TCL_OK;
                   2553: }
                   2554: 
                   2555: #ifndef SQLITE_OMIT_UTF16
                   2556: /*
                   2557: ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be>
                   2558: **
                   2559: ** This function is used to test that SQLite selects the correct collation
                   2560: ** sequence callback when multiple versions (for different text encodings)
                   2561: ** are available.
                   2562: **
                   2563: ** Calling this routine registers the collation sequence "test_collate"
                   2564: ** with database handle <db>. The second argument must be a list of three
                   2565: ** boolean values. If the first is true, then a version of test_collate is
                   2566: ** registered for UTF-8, if the second is true, a version is registered for
                   2567: ** UTF-16le, if the third is true, a UTF-16be version is available.
                   2568: ** Previous versions of test_collate are deleted.
                   2569: **
                   2570: ** The collation sequence test_collate is implemented by calling the
                   2571: ** following TCL script:
                   2572: **
                   2573: **   "test_collate <enc> <lhs> <rhs>"
                   2574: **
                   2575: ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8.
                   2576: ** The <enc> parameter is the encoding of the collation function that
                   2577: ** SQLite selected to call. The TCL test script implements the
                   2578: ** "test_collate" proc.
                   2579: **
                   2580: ** Note that this will only work with one intepreter at a time, as the
                   2581: ** interp pointer to use when evaluating the TCL script is stored in
                   2582: ** pTestCollateInterp.
                   2583: */
                   2584: static Tcl_Interp* pTestCollateInterp;
                   2585: static int test_collate_func(
                   2586:   void *pCtx, 
                   2587:   int nA, const void *zA,
                   2588:   int nB, const void *zB
                   2589: ){
                   2590:   Tcl_Interp *i = pTestCollateInterp;
                   2591:   int encin = SQLITE_PTR_TO_INT(pCtx);
                   2592:   int res;
                   2593:   int n;
                   2594: 
                   2595:   sqlite3_value *pVal;
                   2596:   Tcl_Obj *pX;
                   2597: 
                   2598:   pX = Tcl_NewStringObj("test_collate", -1);
                   2599:   Tcl_IncrRefCount(pX);
                   2600: 
                   2601:   switch( encin ){
                   2602:     case SQLITE_UTF8:
                   2603:       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1));
                   2604:       break;
                   2605:     case SQLITE_UTF16LE:
                   2606:       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1));
                   2607:       break;
                   2608:     case SQLITE_UTF16BE:
                   2609:       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1));
                   2610:       break;
                   2611:     default:
                   2612:       assert(0);
                   2613:   }
                   2614: 
                   2615:   sqlite3BeginBenignMalloc();
                   2616:   pVal = sqlite3ValueNew(0);
                   2617:   if( pVal ){
                   2618:     sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC);
                   2619:     n = sqlite3_value_bytes(pVal);
                   2620:     Tcl_ListObjAppendElement(i,pX,
                   2621:         Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
                   2622:     sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC);
                   2623:     n = sqlite3_value_bytes(pVal);
                   2624:     Tcl_ListObjAppendElement(i,pX,
                   2625:         Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
                   2626:     sqlite3ValueFree(pVal);
                   2627:   }
                   2628:   sqlite3EndBenignMalloc();
                   2629: 
                   2630:   Tcl_EvalObjEx(i, pX, 0);
                   2631:   Tcl_DecrRefCount(pX);
                   2632:   Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res);
                   2633:   return res;
                   2634: }
                   2635: static int test_collate(
                   2636:   void * clientData,
                   2637:   Tcl_Interp *interp,
                   2638:   int objc,
                   2639:   Tcl_Obj *CONST objv[]
                   2640: ){
                   2641:   sqlite3 *db;
                   2642:   int val;
                   2643:   sqlite3_value *pVal;
                   2644:   int rc;
                   2645: 
                   2646:   if( objc!=5 ) goto bad_args;
                   2647:   pTestCollateInterp = interp;
                   2648:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   2649: 
                   2650:   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
                   2651:   rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 
                   2652:           (void *)SQLITE_UTF8, val?test_collate_func:0);
                   2653:   if( rc==SQLITE_OK ){
                   2654:     const void *zUtf16;
                   2655:     if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
                   2656:     rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 
                   2657:             (void *)SQLITE_UTF16LE, val?test_collate_func:0);
                   2658:     if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
                   2659: 
                   2660: #if 0
                   2661:     if( sqlite3_iMallocFail>0 ){
                   2662:       sqlite3_iMallocFail++;
                   2663:     }
                   2664: #endif
                   2665:     sqlite3_mutex_enter(db->mutex);
                   2666:     pVal = sqlite3ValueNew(db);
                   2667:     sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
                   2668:     zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
                   2669:     if( db->mallocFailed ){
                   2670:       rc = SQLITE_NOMEM;
                   2671:     }else{
                   2672:       rc = sqlite3_create_collation16(db, zUtf16, SQLITE_UTF16BE, 
                   2673:           (void *)SQLITE_UTF16BE, val?test_collate_func:0);
                   2674:     }
                   2675:     sqlite3ValueFree(pVal);
                   2676:     sqlite3_mutex_leave(db->mutex);
                   2677:   }
                   2678:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   2679:   
                   2680:   if( rc!=SQLITE_OK ){
                   2681:     Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
                   2682:     return TCL_ERROR;
                   2683:   }
                   2684:   return TCL_OK;
                   2685: 
                   2686: bad_args:
                   2687:   Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2688:       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
                   2689:   return TCL_ERROR;
                   2690: }
                   2691: 
                   2692: /*
                   2693: ** When the collation needed callback is invoked, record the name of 
                   2694: ** the requested collating function here.  The recorded name is linked
                   2695: ** to a TCL variable and used to make sure that the requested collation
                   2696: ** name is correct.
                   2697: */
                   2698: static char zNeededCollation[200];
                   2699: static char *pzNeededCollation = zNeededCollation;
                   2700: 
                   2701: 
                   2702: /*
                   2703: ** Called when a collating sequence is needed.  Registered using
                   2704: ** sqlite3_collation_needed16().
                   2705: */
                   2706: static void test_collate_needed_cb(
                   2707:   void *pCtx, 
                   2708:   sqlite3 *db,
                   2709:   int eTextRep,
                   2710:   const void *pName
                   2711: ){
                   2712:   int enc = ENC(db);
                   2713:   int i;
                   2714:   char *z;
                   2715:   for(z = (char*)pName, i=0; *z || z[1]; z++){
                   2716:     if( *z ) zNeededCollation[i++] = *z;
                   2717:   }
                   2718:   zNeededCollation[i] = 0;
                   2719:   sqlite3_create_collation(
                   2720:       db, "test_collate", ENC(db), SQLITE_INT_TO_PTR(enc), test_collate_func);
                   2721: }
                   2722: 
                   2723: /*
                   2724: ** Usage: add_test_collate_needed DB
                   2725: */
                   2726: static int test_collate_needed(
                   2727:   void * clientData,
                   2728:   Tcl_Interp *interp,
                   2729:   int objc,
                   2730:   Tcl_Obj *CONST objv[]
                   2731: ){
                   2732:   sqlite3 *db;
                   2733:   int rc;
                   2734: 
                   2735:   if( objc!=2 ) goto bad_args;
                   2736:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   2737:   rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
                   2738:   zNeededCollation[0] = 0;
                   2739:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   2740:   return TCL_OK;
                   2741: 
                   2742: bad_args:
                   2743:   Tcl_WrongNumArgs(interp, 1, objv, "DB");
                   2744:   return TCL_ERROR;
                   2745: }
                   2746: 
                   2747: /*
                   2748: ** tclcmd:   add_alignment_test_collations  DB
                   2749: **
                   2750: ** Add two new collating sequences to the database DB
                   2751: **
                   2752: **     utf16_aligned
                   2753: **     utf16_unaligned
                   2754: **
                   2755: ** Both collating sequences use the same sort order as BINARY.
                   2756: ** The only difference is that the utf16_aligned collating
                   2757: ** sequence is declared with the SQLITE_UTF16_ALIGNED flag.
                   2758: ** Both collating functions increment the unaligned utf16 counter
                   2759: ** whenever they see a string that begins on an odd byte boundary.
                   2760: */
                   2761: static int unaligned_string_counter = 0;
                   2762: static int alignmentCollFunc(
                   2763:   void *NotUsed,
                   2764:   int nKey1, const void *pKey1,
                   2765:   int nKey2, const void *pKey2
                   2766: ){
                   2767:   int rc, n;
                   2768:   n = nKey1<nKey2 ? nKey1 : nKey2;
                   2769:   if( nKey1>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey1))) ) unaligned_string_counter++;
                   2770:   if( nKey2>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey2))) ) unaligned_string_counter++;
                   2771:   rc = memcmp(pKey1, pKey2, n);
                   2772:   if( rc==0 ){
                   2773:     rc = nKey1 - nKey2;
                   2774:   }
                   2775:   return rc;
                   2776: }
                   2777: static int add_alignment_test_collations(
                   2778:   void * clientData,
                   2779:   Tcl_Interp *interp,
                   2780:   int objc,
                   2781:   Tcl_Obj *CONST objv[]
                   2782: ){
                   2783:   sqlite3 *db;
                   2784:   if( objc>=2 ){
                   2785:     if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   2786:     sqlite3_create_collation(db, "utf16_unaligned", SQLITE_UTF16, 
                   2787:         0, alignmentCollFunc);
                   2788:     sqlite3_create_collation(db, "utf16_aligned", SQLITE_UTF16_ALIGNED, 
                   2789:         0, alignmentCollFunc);
                   2790:   }
                   2791:   return SQLITE_OK;
                   2792: }
                   2793: #endif /* !defined(SQLITE_OMIT_UTF16) */
                   2794: 
                   2795: /*
                   2796: ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be>
                   2797: **
                   2798: ** This function is used to test that SQLite selects the correct user
                   2799: ** function callback when multiple versions (for different text encodings)
                   2800: ** are available.
                   2801: **
                   2802: ** Calling this routine registers up to three versions of the user function
                   2803: ** "test_function" with database handle <db>.  If the second argument is
                   2804: ** true, then a version of test_function is registered for UTF-8, if the
                   2805: ** third is true, a version is registered for UTF-16le, if the fourth is
                   2806: ** true, a UTF-16be version is available.  Previous versions of
                   2807: ** test_function are deleted.
                   2808: **
                   2809: ** The user function is implemented by calling the following TCL script:
                   2810: **
                   2811: **   "test_function <enc> <arg>"
                   2812: **
                   2813: ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the
                   2814: ** single argument passed to the SQL function. The value returned by
                   2815: ** the TCL script is used as the return value of the SQL function. It
                   2816: ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8
                   2817: ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that
                   2818: ** prefers UTF-16BE.
                   2819: */
                   2820: #ifndef SQLITE_OMIT_UTF16
                   2821: static void test_function_utf8(
                   2822:   sqlite3_context *pCtx, 
                   2823:   int nArg,
                   2824:   sqlite3_value **argv
                   2825: ){
                   2826:   Tcl_Interp *interp;
                   2827:   Tcl_Obj *pX;
                   2828:   sqlite3_value *pVal;
                   2829:   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
                   2830:   pX = Tcl_NewStringObj("test_function", -1);
                   2831:   Tcl_IncrRefCount(pX);
                   2832:   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1));
                   2833:   Tcl_ListObjAppendElement(interp, pX, 
                   2834:       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
                   2835:   Tcl_EvalObjEx(interp, pX, 0);
                   2836:   Tcl_DecrRefCount(pX);
                   2837:   sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT);
                   2838:   pVal = sqlite3ValueNew(0);
                   2839:   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 
                   2840:       SQLITE_UTF8, SQLITE_STATIC);
                   2841:   sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal),
                   2842:       -1, SQLITE_TRANSIENT);
                   2843:   sqlite3ValueFree(pVal);
                   2844: }
                   2845: static void test_function_utf16le(
                   2846:   sqlite3_context *pCtx, 
                   2847:   int nArg,
                   2848:   sqlite3_value **argv
                   2849: ){
                   2850:   Tcl_Interp *interp;
                   2851:   Tcl_Obj *pX;
                   2852:   sqlite3_value *pVal;
                   2853:   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
                   2854:   pX = Tcl_NewStringObj("test_function", -1);
                   2855:   Tcl_IncrRefCount(pX);
                   2856:   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1));
                   2857:   Tcl_ListObjAppendElement(interp, pX, 
                   2858:       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
                   2859:   Tcl_EvalObjEx(interp, pX, 0);
                   2860:   Tcl_DecrRefCount(pX);
                   2861:   pVal = sqlite3ValueNew(0);
                   2862:   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 
                   2863:       SQLITE_UTF8, SQLITE_STATIC);
                   2864:   sqlite3_result_text(pCtx,(char*)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT);
                   2865:   sqlite3ValueFree(pVal);
                   2866: }
                   2867: static void test_function_utf16be(
                   2868:   sqlite3_context *pCtx, 
                   2869:   int nArg,
                   2870:   sqlite3_value **argv
                   2871: ){
                   2872:   Tcl_Interp *interp;
                   2873:   Tcl_Obj *pX;
                   2874:   sqlite3_value *pVal;
                   2875:   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
                   2876:   pX = Tcl_NewStringObj("test_function", -1);
                   2877:   Tcl_IncrRefCount(pX);
                   2878:   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1));
                   2879:   Tcl_ListObjAppendElement(interp, pX, 
                   2880:       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
                   2881:   Tcl_EvalObjEx(interp, pX, 0);
                   2882:   Tcl_DecrRefCount(pX);
                   2883:   pVal = sqlite3ValueNew(0);
                   2884:   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 
                   2885:       SQLITE_UTF8, SQLITE_STATIC);
                   2886:   sqlite3_result_text16(pCtx, sqlite3_value_text16le(pVal),
                   2887:       -1, SQLITE_TRANSIENT);
                   2888:   sqlite3_result_text16be(pCtx, sqlite3_value_text16le(pVal),
                   2889:       -1, SQLITE_TRANSIENT);
                   2890:   sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal),
                   2891:       -1, SQLITE_TRANSIENT);
                   2892:   sqlite3ValueFree(pVal);
                   2893: }
                   2894: #endif /* SQLITE_OMIT_UTF16 */
                   2895: static int test_function(
                   2896:   void * clientData,
                   2897:   Tcl_Interp *interp,
                   2898:   int objc,
                   2899:   Tcl_Obj *CONST objv[]
                   2900: ){
                   2901: #ifndef SQLITE_OMIT_UTF16
                   2902:   sqlite3 *db;
                   2903:   int val;
                   2904: 
                   2905:   if( objc!=5 ) goto bad_args;
                   2906:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   2907: 
                   2908:   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
                   2909:   if( val ){
                   2910:     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, 
                   2911:         interp, test_function_utf8, 0, 0);
                   2912:   }
                   2913:   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
                   2914:   if( val ){
                   2915:     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, 
                   2916:         interp, test_function_utf16le, 0, 0);
                   2917:   }
                   2918:   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
                   2919:   if( val ){
                   2920:     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, 
                   2921:         interp, test_function_utf16be, 0, 0);
                   2922:   }
                   2923: 
                   2924:   return TCL_OK;
                   2925: bad_args:
                   2926:   Tcl_AppendResult(interp, "wrong # args: should be \"",
                   2927:       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
                   2928: #endif /* SQLITE_OMIT_UTF16 */
                   2929:   return TCL_ERROR;
                   2930: }
                   2931: 
                   2932: /*
                   2933: ** Usage:         sqlite3_test_errstr <err code>
                   2934: **
                   2935: ** Test that the english language string equivalents for sqlite error codes
                   2936: ** are sane. The parameter is an integer representing an sqlite error code.
                   2937: ** The result is a list of two elements, the string representation of the
                   2938: ** error code and the english language explanation.
                   2939: */
                   2940: static int test_errstr(
                   2941:   void * clientData,
                   2942:   Tcl_Interp *interp,
                   2943:   int objc,
                   2944:   Tcl_Obj *CONST objv[]
                   2945: ){
                   2946:   char *zCode;
                   2947:   int i;
                   2948:   if( objc!=1 ){
                   2949:     Tcl_WrongNumArgs(interp, 1, objv, "<error code>");
                   2950:   }
                   2951: 
                   2952:   zCode = Tcl_GetString(objv[1]);
                   2953:   for(i=0; i<200; i++){
                   2954:     if( 0==strcmp(t1ErrorName(i), zCode) ) break;
                   2955:   }
                   2956:   Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0);
                   2957:   return TCL_OK;
                   2958: }
                   2959: 
                   2960: /*
                   2961: ** Usage:    breakpoint
                   2962: **
                   2963: ** This routine exists for one purpose - to provide a place to put a
                   2964: ** breakpoint with GDB that can be triggered using TCL code.  The use
                   2965: ** for this is when a particular test fails on (say) the 1485th iteration.
                   2966: ** In the TCL test script, we can add code like this:
                   2967: **
                   2968: **     if {$i==1485} breakpoint
                   2969: **
                   2970: ** Then run testfixture in the debugger and wait for the breakpoint to
                   2971: ** fire.  Then additional breakpoints can be set to trace down the bug.
                   2972: */
                   2973: static int test_breakpoint(
                   2974:   void *NotUsed,
                   2975:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   2976:   int argc,              /* Number of arguments */
                   2977:   char **argv            /* Text of each argument */
                   2978: ){
                   2979:   return TCL_OK;         /* Do nothing */
                   2980: }
                   2981: 
                   2982: /*
                   2983: ** Usage:   sqlite3_bind_zeroblob  STMT IDX N
                   2984: **
                   2985: ** Test the sqlite3_bind_zeroblob interface.  STMT is a prepared statement.
                   2986: ** IDX is the index of a wildcard in the prepared statement.  This command
                   2987: ** binds a N-byte zero-filled BLOB to the wildcard.
                   2988: */
                   2989: static int test_bind_zeroblob(
                   2990:   void * clientData,
                   2991:   Tcl_Interp *interp,
                   2992:   int objc,
                   2993:   Tcl_Obj *CONST objv[]
                   2994: ){
                   2995:   sqlite3_stmt *pStmt;
                   2996:   int idx;
                   2997:   int n;
                   2998:   int rc;
                   2999: 
                   3000:   if( objc!=4 ){
                   3001:     Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX N");
                   3002:     return TCL_ERROR;
                   3003:   }
                   3004: 
                   3005:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3006:   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
                   3007:   if( Tcl_GetIntFromObj(interp, objv[3], &n) ) return TCL_ERROR;
                   3008: 
                   3009:   rc = sqlite3_bind_zeroblob(pStmt, idx, n);
                   3010:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   3011:   if( rc!=SQLITE_OK ){
                   3012:     return TCL_ERROR;
                   3013:   }
                   3014: 
                   3015:   return TCL_OK;
                   3016: }
                   3017: 
                   3018: /*
                   3019: ** Usage:   sqlite3_bind_int  STMT N VALUE
                   3020: **
                   3021: ** Test the sqlite3_bind_int interface.  STMT is a prepared statement.
                   3022: ** N is the index of a wildcard in the prepared statement.  This command
                   3023: ** binds a 32-bit integer VALUE to that wildcard.
                   3024: */
                   3025: static int test_bind_int(
                   3026:   void * clientData,
                   3027:   Tcl_Interp *interp,
                   3028:   int objc,
                   3029:   Tcl_Obj *CONST objv[]
                   3030: ){
                   3031:   sqlite3_stmt *pStmt;
                   3032:   int idx;
                   3033:   int value;
                   3034:   int rc;
                   3035: 
                   3036:   if( objc!=4 ){
                   3037:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   3038:         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
                   3039:     return TCL_ERROR;
                   3040:   }
                   3041: 
                   3042:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3043:   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
                   3044:   if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
                   3045: 
                   3046:   rc = sqlite3_bind_int(pStmt, idx, value);
                   3047:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   3048:   if( rc!=SQLITE_OK ){
                   3049:     return TCL_ERROR;
                   3050:   }
                   3051: 
                   3052:   return TCL_OK;
                   3053: }
                   3054: 
                   3055: 
                   3056: /*
                   3057: ** Usage:   sqlite3_bind_int64  STMT N VALUE
                   3058: **
                   3059: ** Test the sqlite3_bind_int64 interface.  STMT is a prepared statement.
                   3060: ** N is the index of a wildcard in the prepared statement.  This command
                   3061: ** binds a 64-bit integer VALUE to that wildcard.
                   3062: */
                   3063: static int test_bind_int64(
                   3064:   void * clientData,
                   3065:   Tcl_Interp *interp,
                   3066:   int objc,
                   3067:   Tcl_Obj *CONST objv[]
                   3068: ){
                   3069:   sqlite3_stmt *pStmt;
                   3070:   int idx;
                   3071:   i64 value;
                   3072:   int rc;
                   3073: 
                   3074:   if( objc!=4 ){
                   3075:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   3076:         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
                   3077:     return TCL_ERROR;
                   3078:   }
                   3079: 
                   3080:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3081:   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
                   3082:   if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
                   3083: 
                   3084:   rc = sqlite3_bind_int64(pStmt, idx, value);
                   3085:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   3086:   if( rc!=SQLITE_OK ){
                   3087:     return TCL_ERROR;
                   3088:   }
                   3089: 
                   3090:   return TCL_OK;
                   3091: }
                   3092: 
                   3093: 
                   3094: /*
                   3095: ** Usage:   sqlite3_bind_double  STMT N VALUE
                   3096: **
                   3097: ** Test the sqlite3_bind_double interface.  STMT is a prepared statement.
                   3098: ** N is the index of a wildcard in the prepared statement.  This command
                   3099: ** binds a 64-bit integer VALUE to that wildcard.
                   3100: */
                   3101: static int test_bind_double(
                   3102:   void * clientData,
                   3103:   Tcl_Interp *interp,
                   3104:   int objc,
                   3105:   Tcl_Obj *CONST objv[]
                   3106: ){
                   3107:   sqlite3_stmt *pStmt;
                   3108:   int idx;
                   3109:   double value;
                   3110:   int rc;
                   3111:   const char *zVal;
                   3112:   int i;
                   3113:   static const struct {
                   3114:     const char *zName;     /* Name of the special floating point value */
                   3115:     unsigned int iUpper;   /* Upper 32 bits */
                   3116:     unsigned int iLower;   /* Lower 32 bits */
                   3117:   } aSpecialFp[] = {
                   3118:     {  "NaN",      0x7fffffff, 0xffffffff },
                   3119:     {  "SNaN",     0x7ff7ffff, 0xffffffff },
                   3120:     {  "-NaN",     0xffffffff, 0xffffffff },
                   3121:     {  "-SNaN",    0xfff7ffff, 0xffffffff },
                   3122:     {  "+Inf",     0x7ff00000, 0x00000000 },
                   3123:     {  "-Inf",     0xfff00000, 0x00000000 },
                   3124:     {  "Epsilon",  0x00000000, 0x00000001 },
                   3125:     {  "-Epsilon", 0x80000000, 0x00000001 },
                   3126:     {  "NaN0",     0x7ff80000, 0x00000000 },
                   3127:     {  "-NaN0",    0xfff80000, 0x00000000 },
                   3128:   };
                   3129: 
                   3130:   if( objc!=4 ){
                   3131:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   3132:         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
                   3133:     return TCL_ERROR;
                   3134:   }
                   3135: 
                   3136:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3137:   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
                   3138: 
                   3139:   /* Intercept the string "NaN" and generate a NaN value for it.
                   3140:   ** All other strings are passed through to Tcl_GetDoubleFromObj().
                   3141:   ** Tcl_GetDoubleFromObj() should understand "NaN" but some versions
                   3142:   ** contain a bug.
                   3143:   */
                   3144:   zVal = Tcl_GetString(objv[3]);
                   3145:   for(i=0; i<sizeof(aSpecialFp)/sizeof(aSpecialFp[0]); i++){
                   3146:     if( strcmp(aSpecialFp[i].zName, zVal)==0 ){
                   3147:       sqlite3_uint64 x;
                   3148:       x = aSpecialFp[i].iUpper;
                   3149:       x <<= 32;
                   3150:       x |= aSpecialFp[i].iLower;
                   3151:       assert( sizeof(value)==8 );
                   3152:       assert( sizeof(x)==8 );
                   3153:       memcpy(&value, &x, 8);
                   3154:       break;
                   3155:     }
                   3156:   }
                   3157:   if( i>=sizeof(aSpecialFp)/sizeof(aSpecialFp[0]) &&
                   3158:          Tcl_GetDoubleFromObj(interp, objv[3], &value) ){
                   3159:     return TCL_ERROR;
                   3160:   }
                   3161:   rc = sqlite3_bind_double(pStmt, idx, value);
                   3162:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   3163:   if( rc!=SQLITE_OK ){
                   3164:     return TCL_ERROR;
                   3165:   }
                   3166: 
                   3167:   return TCL_OK;
                   3168: }
                   3169: 
                   3170: /*
                   3171: ** Usage:   sqlite3_bind_null  STMT N
                   3172: **
                   3173: ** Test the sqlite3_bind_null interface.  STMT is a prepared statement.
                   3174: ** N is the index of a wildcard in the prepared statement.  This command
                   3175: ** binds a NULL to the wildcard.
                   3176: */
                   3177: static int test_bind_null(
                   3178:   void * clientData,
                   3179:   Tcl_Interp *interp,
                   3180:   int objc,
                   3181:   Tcl_Obj *CONST objv[]
                   3182: ){
                   3183:   sqlite3_stmt *pStmt;
                   3184:   int idx;
                   3185:   int rc;
                   3186: 
                   3187:   if( objc!=3 ){
                   3188:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   3189:         Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0);
                   3190:     return TCL_ERROR;
                   3191:   }
                   3192: 
                   3193:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3194:   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
                   3195: 
                   3196:   rc = sqlite3_bind_null(pStmt, idx);
                   3197:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   3198:   if( rc!=SQLITE_OK ){
                   3199:     return TCL_ERROR;
                   3200:   }
                   3201: 
                   3202:   return TCL_OK;
                   3203: }
                   3204: 
                   3205: /*
                   3206: ** Usage:   sqlite3_bind_text  STMT N STRING BYTES
                   3207: **
                   3208: ** Test the sqlite3_bind_text interface.  STMT is a prepared statement.
                   3209: ** N is the index of a wildcard in the prepared statement.  This command
                   3210: ** binds a UTF-8 string STRING to the wildcard.  The string is BYTES bytes
                   3211: ** long.
                   3212: */
                   3213: static int test_bind_text(
                   3214:   void * clientData,
                   3215:   Tcl_Interp *interp,
                   3216:   int objc,
                   3217:   Tcl_Obj *CONST objv[]
                   3218: ){
                   3219:   sqlite3_stmt *pStmt;
                   3220:   int idx;
                   3221:   int bytes;
                   3222:   char *value;
                   3223:   int rc;
                   3224: 
                   3225:   if( objc!=5 ){
                   3226:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   3227:         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0);
                   3228:     return TCL_ERROR;
                   3229:   }
                   3230: 
                   3231:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3232:   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
                   3233:   value = (char*)Tcl_GetByteArrayFromObj(objv[3], &bytes);
                   3234:   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
                   3235: 
                   3236:   rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
                   3237:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   3238:   if( rc!=SQLITE_OK ){
                   3239:     Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
                   3240:     return TCL_ERROR;
                   3241:   }
                   3242: 
                   3243:   return TCL_OK;
                   3244: }
                   3245: 
                   3246: /*
                   3247: ** Usage:   sqlite3_bind_text16 ?-static? STMT N STRING BYTES
                   3248: **
                   3249: ** Test the sqlite3_bind_text16 interface.  STMT is a prepared statement.
                   3250: ** N is the index of a wildcard in the prepared statement.  This command
                   3251: ** binds a UTF-16 string STRING to the wildcard.  The string is BYTES bytes
                   3252: ** long.
                   3253: */
                   3254: static int test_bind_text16(
                   3255:   void * clientData,
                   3256:   Tcl_Interp *interp,
                   3257:   int objc,
                   3258:   Tcl_Obj *CONST objv[]
                   3259: ){
                   3260: #ifndef SQLITE_OMIT_UTF16
                   3261:   sqlite3_stmt *pStmt;
                   3262:   int idx;
                   3263:   int bytes;
                   3264:   char *value;
                   3265:   int rc;
                   3266: 
                   3267:   void (*xDel)() = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT);
                   3268:   Tcl_Obj *oStmt    = objv[objc-4];
                   3269:   Tcl_Obj *oN       = objv[objc-3];
                   3270:   Tcl_Obj *oString  = objv[objc-2];
                   3271:   Tcl_Obj *oBytes   = objv[objc-1];
                   3272: 
                   3273:   if( objc!=5 && objc!=6){
                   3274:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   3275:         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0);
                   3276:     return TCL_ERROR;
                   3277:   }
                   3278: 
                   3279:   if( getStmtPointer(interp, Tcl_GetString(oStmt), &pStmt) ) return TCL_ERROR;
                   3280:   if( Tcl_GetIntFromObj(interp, oN, &idx) ) return TCL_ERROR;
                   3281:   value = (char*)Tcl_GetByteArrayFromObj(oString, 0);
                   3282:   if( Tcl_GetIntFromObj(interp, oBytes, &bytes) ) return TCL_ERROR;
                   3283: 
                   3284:   rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, xDel);
                   3285:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   3286:   if( rc!=SQLITE_OK ){
                   3287:     Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
                   3288:     return TCL_ERROR;
                   3289:   }
                   3290: 
                   3291: #endif /* SQLITE_OMIT_UTF16 */
                   3292:   return TCL_OK;
                   3293: }
                   3294: 
                   3295: /*
                   3296: ** Usage:   sqlite3_bind_blob ?-static? STMT N DATA BYTES
                   3297: **
                   3298: ** Test the sqlite3_bind_blob interface.  STMT is a prepared statement.
                   3299: ** N is the index of a wildcard in the prepared statement.  This command
                   3300: ** binds a BLOB to the wildcard.  The BLOB is BYTES bytes in size.
                   3301: */
                   3302: static int test_bind_blob(
                   3303:   void * clientData,
                   3304:   Tcl_Interp *interp,
                   3305:   int objc,
                   3306:   Tcl_Obj *CONST objv[]
                   3307: ){
                   3308:   sqlite3_stmt *pStmt;
                   3309:   int idx;
                   3310:   int bytes;
                   3311:   char *value;
                   3312:   int rc;
                   3313:   sqlite3_destructor_type xDestructor = SQLITE_TRANSIENT;
                   3314: 
                   3315:   if( objc!=5 && objc!=6 ){
                   3316:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   3317:         Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0);
                   3318:     return TCL_ERROR;
                   3319:   }
                   3320: 
                   3321:   if( objc==6 ){
                   3322:     xDestructor = SQLITE_STATIC;
                   3323:     objv++;
                   3324:   }
                   3325: 
                   3326:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3327:   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
                   3328:   value = Tcl_GetString(objv[3]);
                   3329:   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
                   3330: 
                   3331:   rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor);
                   3332:   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
                   3333:   if( rc!=SQLITE_OK ){
                   3334:     return TCL_ERROR;
                   3335:   }
                   3336: 
                   3337:   return TCL_OK;
                   3338: }
                   3339: 
                   3340: /*
                   3341: ** Usage:   sqlite3_bind_parameter_count  STMT
                   3342: **
                   3343: ** Return the number of wildcards in the given statement.
                   3344: */
                   3345: static int test_bind_parameter_count(
                   3346:   void * clientData,
                   3347:   Tcl_Interp *interp,
                   3348:   int objc,
                   3349:   Tcl_Obj *CONST objv[]
                   3350: ){
                   3351:   sqlite3_stmt *pStmt;
                   3352: 
                   3353:   if( objc!=2 ){
                   3354:     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
                   3355:     return TCL_ERROR;
                   3356:   }
                   3357:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3358:   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt)));
                   3359:   return TCL_OK;
                   3360: }
                   3361: 
                   3362: /*
                   3363: ** Usage:   sqlite3_bind_parameter_name  STMT  N
                   3364: **
                   3365: ** Return the name of the Nth wildcard.  The first wildcard is 1.
                   3366: ** An empty string is returned if N is out of range or if the wildcard
                   3367: ** is nameless.
                   3368: */
                   3369: static int test_bind_parameter_name(
                   3370:   void * clientData,
                   3371:   Tcl_Interp *interp,
                   3372:   int objc,
                   3373:   Tcl_Obj *CONST objv[]
                   3374: ){
                   3375:   sqlite3_stmt *pStmt;
                   3376:   int i;
                   3377: 
                   3378:   if( objc!=3 ){
                   3379:     Tcl_WrongNumArgs(interp, 1, objv, "STMT N");
                   3380:     return TCL_ERROR;
                   3381:   }
                   3382:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3383:   if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR;
                   3384:   Tcl_SetObjResult(interp, 
                   3385:      Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1)
                   3386:   );
                   3387:   return TCL_OK;
                   3388: }
                   3389: 
                   3390: /*
                   3391: ** Usage:   sqlite3_bind_parameter_index  STMT  NAME
                   3392: **
                   3393: ** Return the index of the wildcard called NAME.  Return 0 if there is
                   3394: ** no such wildcard.
                   3395: */
                   3396: static int test_bind_parameter_index(
                   3397:   void * clientData,
                   3398:   Tcl_Interp *interp,
                   3399:   int objc,
                   3400:   Tcl_Obj *CONST objv[]
                   3401: ){
                   3402:   sqlite3_stmt *pStmt;
                   3403: 
                   3404:   if( objc!=3 ){
                   3405:     Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME");
                   3406:     return TCL_ERROR;
                   3407:   }
                   3408:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3409:   Tcl_SetObjResult(interp, 
                   3410:      Tcl_NewIntObj(
                   3411:        sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2]))
                   3412:      )
                   3413:   );
                   3414:   return TCL_OK;
                   3415: }
                   3416: 
                   3417: /*
                   3418: ** Usage:   sqlite3_clear_bindings STMT
                   3419: **
                   3420: */
                   3421: static int test_clear_bindings(
                   3422:   void * clientData,
                   3423:   Tcl_Interp *interp,
                   3424:   int objc,
                   3425:   Tcl_Obj *CONST objv[]
                   3426: ){
                   3427:   sqlite3_stmt *pStmt;
                   3428: 
                   3429:   if( objc!=2 ){
                   3430:     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
                   3431:     return TCL_ERROR;
                   3432:   }
                   3433:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   3434:   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt)));
                   3435:   return TCL_OK;
                   3436: }
                   3437: 
                   3438: /*
                   3439: ** Usage:   sqlite3_sleep MILLISECONDS
                   3440: */
                   3441: static int test_sleep(
                   3442:   void * clientData,
                   3443:   Tcl_Interp *interp,
                   3444:   int objc,
                   3445:   Tcl_Obj *CONST objv[]
                   3446: ){
                   3447:   int ms;
                   3448: 
                   3449:   if( objc!=2 ){
                   3450:     Tcl_WrongNumArgs(interp, 1, objv, "MILLISECONDS");
                   3451:     return TCL_ERROR;
                   3452:   }
                   3453:   if( Tcl_GetIntFromObj(interp, objv[1], &ms) ){
                   3454:     return TCL_ERROR;
                   3455:   }
                   3456:   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_sleep(ms)));
                   3457:   return TCL_OK;
                   3458: }
                   3459: 
                   3460: /*
                   3461: ** Usage: sqlite3_extended_errcode DB
                   3462: **
                   3463: ** Return the string representation of the most recent sqlite3_* API
                   3464: ** error code. e.g. "SQLITE_ERROR".
                   3465: */
                   3466: static int test_ex_errcode(
                   3467:   void * clientData,
                   3468:   Tcl_Interp *interp,
                   3469:   int objc,
                   3470:   Tcl_Obj *CONST objv[]
                   3471: ){
                   3472:   sqlite3 *db;
                   3473:   int rc;
                   3474: 
                   3475:   if( objc!=2 ){
                   3476:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3477:        Tcl_GetString(objv[0]), " DB", 0);
                   3478:     return TCL_ERROR;
                   3479:   }
                   3480:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3481:   rc = sqlite3_extended_errcode(db);
                   3482:   Tcl_AppendResult(interp, (char *)t1ErrorName(rc), 0);
                   3483:   return TCL_OK;
                   3484: }
                   3485: 
                   3486: 
                   3487: /*
                   3488: ** Usage: sqlite3_errcode DB
                   3489: **
                   3490: ** Return the string representation of the most recent sqlite3_* API
                   3491: ** error code. e.g. "SQLITE_ERROR".
                   3492: */
                   3493: static int test_errcode(
                   3494:   void * clientData,
                   3495:   Tcl_Interp *interp,
                   3496:   int objc,
                   3497:   Tcl_Obj *CONST objv[]
                   3498: ){
                   3499:   sqlite3 *db;
                   3500:   int rc;
                   3501: 
                   3502:   if( objc!=2 ){
                   3503:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3504:        Tcl_GetString(objv[0]), " DB", 0);
                   3505:     return TCL_ERROR;
                   3506:   }
                   3507:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3508:   rc = sqlite3_errcode(db);
                   3509:   Tcl_AppendResult(interp, (char *)t1ErrorName(rc), 0);
                   3510:   return TCL_OK;
                   3511: }
                   3512: 
                   3513: /*
                   3514: ** Usage:   sqlite3_errmsg DB
                   3515: **
                   3516: ** Returns the UTF-8 representation of the error message string for the
                   3517: ** most recent sqlite3_* API call.
                   3518: */
                   3519: static int test_errmsg(
                   3520:   void * clientData,
                   3521:   Tcl_Interp *interp,
                   3522:   int objc,
                   3523:   Tcl_Obj *CONST objv[]
                   3524: ){
                   3525:   sqlite3 *db;
                   3526:   const char *zErr;
                   3527: 
                   3528:   if( objc!=2 ){
                   3529:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3530:        Tcl_GetString(objv[0]), " DB", 0);
                   3531:     return TCL_ERROR;
                   3532:   }
                   3533:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3534: 
                   3535:   zErr = sqlite3_errmsg(db);
                   3536:   Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
                   3537:   return TCL_OK;
                   3538: }
                   3539: 
                   3540: /*
                   3541: ** Usage:   test_errmsg16 DB
                   3542: **
                   3543: ** Returns the UTF-16 representation of the error message string for the
                   3544: ** most recent sqlite3_* API call. This is a byte array object at the TCL 
                   3545: ** level, and it includes the 0x00 0x00 terminator bytes at the end of the
                   3546: ** UTF-16 string.
                   3547: */
                   3548: static int test_errmsg16(
                   3549:   void * clientData,
                   3550:   Tcl_Interp *interp,
                   3551:   int objc,
                   3552:   Tcl_Obj *CONST objv[]
                   3553: ){
                   3554: #ifndef SQLITE_OMIT_UTF16
                   3555:   sqlite3 *db;
                   3556:   const void *zErr;
                   3557:   const char *z;
                   3558:   int bytes = 0;
                   3559: 
                   3560:   if( objc!=2 ){
                   3561:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3562:        Tcl_GetString(objv[0]), " DB", 0);
                   3563:     return TCL_ERROR;
                   3564:   }
                   3565:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3566: 
                   3567:   zErr = sqlite3_errmsg16(db);
                   3568:   if( zErr ){
                   3569:     z = zErr;
                   3570:     for(bytes=0; z[bytes] || z[bytes+1]; bytes+=2){}
                   3571:   }
                   3572:   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes));
                   3573: #endif /* SQLITE_OMIT_UTF16 */
                   3574:   return TCL_OK;
                   3575: }
                   3576: 
                   3577: /*
                   3578: ** Usage: sqlite3_prepare DB sql bytes ?tailvar?
                   3579: **
                   3580: ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
                   3581: ** database handle <DB>. The parameter <tailval> is the name of a global
                   3582: ** variable that is set to the unused portion of <sql> (if any). A
                   3583: ** STMT handle is returned.
                   3584: */
                   3585: static int test_prepare(
                   3586:   void * clientData,
                   3587:   Tcl_Interp *interp,
                   3588:   int objc,
                   3589:   Tcl_Obj *CONST objv[]
                   3590: ){
                   3591:   sqlite3 *db;
                   3592:   const char *zSql;
                   3593:   int bytes;
                   3594:   const char *zTail = 0;
                   3595:   sqlite3_stmt *pStmt = 0;
                   3596:   char zBuf[50];
                   3597:   int rc;
                   3598: 
                   3599:   if( objc!=5 && objc!=4 ){
                   3600:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3601:        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
                   3602:     return TCL_ERROR;
                   3603:   }
                   3604:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3605:   zSql = Tcl_GetString(objv[2]);
                   3606:   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
                   3607: 
                   3608:   rc = sqlite3_prepare(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
                   3609:   Tcl_ResetResult(interp);
                   3610:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   3611:   if( zTail && objc>=5 ){
                   3612:     if( bytes>=0 ){
                   3613:       bytes = bytes - (zTail-zSql);
                   3614:     }
                   3615:     if( strlen(zTail)<bytes ){
                   3616:       bytes = strlen(zTail);
                   3617:     }
                   3618:     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
                   3619:   }
                   3620:   if( rc!=SQLITE_OK ){
                   3621:     assert( pStmt==0 );
                   3622:     sprintf(zBuf, "(%d) ", rc);
                   3623:     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
                   3624:     return TCL_ERROR;
                   3625:   }
                   3626: 
                   3627:   if( pStmt ){
                   3628:     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
                   3629:     Tcl_AppendResult(interp, zBuf, 0);
                   3630:   }
                   3631:   return TCL_OK;
                   3632: }
                   3633: 
                   3634: /*
                   3635: ** Usage: sqlite3_prepare_v2 DB sql bytes ?tailvar?
                   3636: **
                   3637: ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
                   3638: ** database handle <DB>. The parameter <tailval> is the name of a global
                   3639: ** variable that is set to the unused portion of <sql> (if any). A
                   3640: ** STMT handle is returned.
                   3641: */
                   3642: static int test_prepare_v2(
                   3643:   void * clientData,
                   3644:   Tcl_Interp *interp,
                   3645:   int objc,
                   3646:   Tcl_Obj *CONST objv[]
                   3647: ){
                   3648:   sqlite3 *db;
                   3649:   const char *zSql;
                   3650:   int bytes;
                   3651:   const char *zTail = 0;
                   3652:   sqlite3_stmt *pStmt = 0;
                   3653:   char zBuf[50];
                   3654:   int rc;
                   3655: 
                   3656:   if( objc!=5 && objc!=4 ){
                   3657:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3658:        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
                   3659:     return TCL_ERROR;
                   3660:   }
                   3661:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3662:   zSql = Tcl_GetString(objv[2]);
                   3663:   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
                   3664: 
                   3665:   rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
                   3666:   assert(rc==SQLITE_OK || pStmt==0);
                   3667:   Tcl_ResetResult(interp);
                   3668:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   3669:   if( zTail && objc>=5 ){
                   3670:     if( bytes>=0 ){
                   3671:       bytes = bytes - (zTail-zSql);
                   3672:     }
                   3673:     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
                   3674:   }
                   3675:   if( rc!=SQLITE_OK ){
                   3676:     assert( pStmt==0 );
                   3677:     sprintf(zBuf, "(%d) ", rc);
                   3678:     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
                   3679:     return TCL_ERROR;
                   3680:   }
                   3681: 
                   3682:   if( pStmt ){
                   3683:     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
                   3684:     Tcl_AppendResult(interp, zBuf, 0);
                   3685:   }
                   3686:   return TCL_OK;
                   3687: }
                   3688: 
                   3689: /*
                   3690: ** Usage: sqlite3_prepare_tkt3134 DB
                   3691: **
                   3692: ** Generate a prepared statement for a zero-byte string as a test
                   3693: ** for ticket #3134.  The string should be preceeded by a zero byte.
                   3694: */
                   3695: static int test_prepare_tkt3134(
                   3696:   void * clientData,
                   3697:   Tcl_Interp *interp,
                   3698:   int objc,
                   3699:   Tcl_Obj *CONST objv[]
                   3700: ){
                   3701:   sqlite3 *db;
                   3702:   static const char zSql[] = "\000SELECT 1";
                   3703:   sqlite3_stmt *pStmt = 0;
                   3704:   char zBuf[50];
                   3705:   int rc;
                   3706: 
                   3707:   if( objc!=2 ){
                   3708:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3709:        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
                   3710:     return TCL_ERROR;
                   3711:   }
                   3712:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3713:   rc = sqlite3_prepare_v2(db, &zSql[1], 0, &pStmt, 0);
                   3714:   assert(rc==SQLITE_OK || pStmt==0);
                   3715:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   3716:   if( rc!=SQLITE_OK ){
                   3717:     assert( pStmt==0 );
                   3718:     sprintf(zBuf, "(%d) ", rc);
                   3719:     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
                   3720:     return TCL_ERROR;
                   3721:   }
                   3722: 
                   3723:   if( pStmt ){
                   3724:     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
                   3725:     Tcl_AppendResult(interp, zBuf, 0);
                   3726:   }
                   3727:   return TCL_OK;
                   3728: }
                   3729: 
                   3730: /*
                   3731: ** Usage: sqlite3_prepare16 DB sql bytes tailvar
                   3732: **
                   3733: ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
                   3734: ** database handle <DB>. The parameter <tailval> is the name of a global
                   3735: ** variable that is set to the unused portion of <sql> (if any). A
                   3736: ** STMT handle is returned.
                   3737: */
                   3738: static int test_prepare16(
                   3739:   void * clientData,
                   3740:   Tcl_Interp *interp,
                   3741:   int objc,
                   3742:   Tcl_Obj *CONST objv[]
                   3743: ){
                   3744: #ifndef SQLITE_OMIT_UTF16
                   3745:   sqlite3 *db;
                   3746:   const void *zSql;
                   3747:   const void *zTail = 0;
                   3748:   Tcl_Obj *pTail = 0;
                   3749:   sqlite3_stmt *pStmt = 0;
                   3750:   char zBuf[50]; 
                   3751:   int rc;
                   3752:   int bytes;                /* The integer specified as arg 3 */
                   3753:   int objlen;               /* The byte-array length of arg 2 */
                   3754: 
                   3755:   if( objc!=5 && objc!=4 ){
                   3756:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3757:        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
                   3758:     return TCL_ERROR;
                   3759:   }
                   3760:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3761:   zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
                   3762:   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
                   3763: 
                   3764:   rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
                   3765:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   3766:   if( rc ){
                   3767:     return TCL_ERROR;
                   3768:   }
                   3769: 
                   3770:   if( objc>=5 ){
                   3771:     if( zTail ){
                   3772:       objlen = objlen - ((u8 *)zTail-(u8 *)zSql);
                   3773:     }else{
                   3774:       objlen = 0;
                   3775:     }
                   3776:     pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
                   3777:     Tcl_IncrRefCount(pTail);
                   3778:     Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
                   3779:     Tcl_DecrRefCount(pTail);
                   3780:   }
                   3781: 
                   3782:   if( pStmt ){
                   3783:     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
                   3784:   }
                   3785:   Tcl_AppendResult(interp, zBuf, 0);
                   3786: #endif /* SQLITE_OMIT_UTF16 */
                   3787:   return TCL_OK;
                   3788: }
                   3789: 
                   3790: /*
                   3791: ** Usage: sqlite3_prepare16_v2 DB sql bytes ?tailvar?
                   3792: **
                   3793: ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
                   3794: ** database handle <DB>. The parameter <tailval> is the name of a global
                   3795: ** variable that is set to the unused portion of <sql> (if any). A
                   3796: ** STMT handle is returned.
                   3797: */
                   3798: static int test_prepare16_v2(
                   3799:   void * clientData,
                   3800:   Tcl_Interp *interp,
                   3801:   int objc,
                   3802:   Tcl_Obj *CONST objv[]
                   3803: ){
                   3804: #ifndef SQLITE_OMIT_UTF16
                   3805:   sqlite3 *db;
                   3806:   const void *zSql;
                   3807:   const void *zTail = 0;
                   3808:   Tcl_Obj *pTail = 0;
                   3809:   sqlite3_stmt *pStmt = 0;
                   3810:   char zBuf[50]; 
                   3811:   int rc;
                   3812:   int bytes;                /* The integer specified as arg 3 */
                   3813:   int objlen;               /* The byte-array length of arg 2 */
                   3814: 
                   3815:   if( objc!=5 && objc!=4 ){
                   3816:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3817:        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
                   3818:     return TCL_ERROR;
                   3819:   }
                   3820:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   3821:   zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
                   3822:   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
                   3823: 
                   3824:   rc = sqlite3_prepare16_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
                   3825:   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
                   3826:   if( rc ){
                   3827:     return TCL_ERROR;
                   3828:   }
                   3829: 
                   3830:   if( objc>=5 ){
                   3831:     if( zTail ){
                   3832:       objlen = objlen - ((u8 *)zTail-(u8 *)zSql);
                   3833:     }else{
                   3834:       objlen = 0;
                   3835:     }
                   3836:     pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
                   3837:     Tcl_IncrRefCount(pTail);
                   3838:     Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
                   3839:     Tcl_DecrRefCount(pTail);
                   3840:   }
                   3841: 
                   3842:   if( pStmt ){
                   3843:     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
                   3844:   }
                   3845:   Tcl_AppendResult(interp, zBuf, 0);
                   3846: #endif /* SQLITE_OMIT_UTF16 */
                   3847:   return TCL_OK;
                   3848: }
                   3849: 
                   3850: /*
                   3851: ** Usage: sqlite3_open filename ?options-list?
                   3852: */
                   3853: static int test_open(
                   3854:   void * clientData,
                   3855:   Tcl_Interp *interp,
                   3856:   int objc,
                   3857:   Tcl_Obj *CONST objv[]
                   3858: ){
                   3859:   const char *zFilename;
                   3860:   sqlite3 *db;
                   3861:   int rc;
                   3862:   char zBuf[100];
                   3863: 
                   3864:   if( objc!=3 && objc!=2 && objc!=1 ){
                   3865:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3866:        Tcl_GetString(objv[0]), " filename options-list", 0);
                   3867:     return TCL_ERROR;
                   3868:   }
                   3869: 
                   3870:   zFilename = objc>1 ? Tcl_GetString(objv[1]) : 0;
                   3871:   rc = sqlite3_open(zFilename, &db);
                   3872:   
                   3873:   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
                   3874:   Tcl_AppendResult(interp, zBuf, 0);
                   3875:   return TCL_OK;
                   3876: }
                   3877: 
                   3878: /*
                   3879: ** Usage: sqlite3_open_v2 FILENAME FLAGS VFS
                   3880: */
                   3881: static int test_open_v2(
                   3882:   void * clientData,
                   3883:   Tcl_Interp *interp,
                   3884:   int objc,
                   3885:   Tcl_Obj *CONST objv[]
                   3886: ){
                   3887:   const char *zFilename;
                   3888:   const char *zVfs;
                   3889:   int flags = 0;
                   3890:   sqlite3 *db;
                   3891:   int rc;
                   3892:   char zBuf[100];
                   3893: 
                   3894:   int nFlag;
                   3895:   Tcl_Obj **apFlag;
                   3896:   int i;
                   3897: 
                   3898:   if( objc!=4 ){
                   3899:     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME FLAGS VFS");
                   3900:     return TCL_ERROR;
                   3901:   }
                   3902:   zFilename = Tcl_GetString(objv[1]);
                   3903:   zVfs = Tcl_GetString(objv[3]);
                   3904:   if( zVfs[0]==0x00 ) zVfs = 0;
                   3905: 
                   3906:   rc = Tcl_ListObjGetElements(interp, objv[2], &nFlag, &apFlag);
                   3907:   if( rc!=TCL_OK ) return rc;
                   3908:   for(i=0; i<nFlag; i++){
                   3909:     int iFlag;
                   3910:     struct OpenFlag {
                   3911:       const char *zFlag;
                   3912:       int flag;
                   3913:     } aFlag[] = {
                   3914:       { "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY },
                   3915:       { "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE },
                   3916:       { "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE },
                   3917:       { "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE },
                   3918:       { "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE },
                   3919:       { "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY },
                   3920:       { "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB },
                   3921:       { "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB },
                   3922:       { "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB },
                   3923:       { "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL },
                   3924:       { "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL },
                   3925:       { "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL },
                   3926:       { "SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL },
                   3927:       { "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX },
                   3928:       { "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX },
                   3929:       { "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE },
                   3930:       { "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE },
                   3931:       { "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL },
                   3932:       { "SQLITE_OPEN_URI", SQLITE_OPEN_URI },
                   3933:       { 0, 0 }
                   3934:     };
                   3935:     rc = Tcl_GetIndexFromObjStruct(interp, apFlag[i], aFlag, sizeof(aFlag[0]), 
                   3936:         "flag", 0, &iFlag
                   3937:     );
                   3938:     if( rc!=TCL_OK ) return rc;
                   3939:     flags |= aFlag[iFlag].flag;
                   3940:   }
                   3941: 
                   3942:   rc = sqlite3_open_v2(zFilename, &db, flags, zVfs);
                   3943:   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
                   3944:   Tcl_AppendResult(interp, zBuf, 0);
                   3945:   return TCL_OK;
                   3946: }
                   3947: 
                   3948: /*
                   3949: ** Usage: sqlite3_open16 filename options
                   3950: */
                   3951: static int test_open16(
                   3952:   void * clientData,
                   3953:   Tcl_Interp *interp,
                   3954:   int objc,
                   3955:   Tcl_Obj *CONST objv[]
                   3956: ){
                   3957: #ifndef SQLITE_OMIT_UTF16
                   3958:   const void *zFilename;
                   3959:   sqlite3 *db;
                   3960:   int rc;
                   3961:   char zBuf[100];
                   3962: 
                   3963:   if( objc!=3 ){
                   3964:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   3965:        Tcl_GetString(objv[0]), " filename options-list", 0);
                   3966:     return TCL_ERROR;
                   3967:   }
                   3968: 
                   3969:   zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
                   3970:   rc = sqlite3_open16(zFilename, &db);
                   3971:   
                   3972:   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
                   3973:   Tcl_AppendResult(interp, zBuf, 0);
                   3974: #endif /* SQLITE_OMIT_UTF16 */
                   3975:   return TCL_OK;
                   3976: }
                   3977: 
                   3978: /*
                   3979: ** Usage: sqlite3_complete16 <UTF-16 string>
                   3980: **
                   3981: ** Return 1 if the supplied argument is a complete SQL statement, or zero
                   3982: ** otherwise.
                   3983: */
                   3984: static int test_complete16(
                   3985:   void * clientData,
                   3986:   Tcl_Interp *interp,
                   3987:   int objc,
                   3988:   Tcl_Obj *CONST objv[]
                   3989: ){
                   3990: #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16)
                   3991:   char *zBuf;
                   3992: 
                   3993:   if( objc!=2 ){
                   3994:     Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>");
                   3995:     return TCL_ERROR;
                   3996:   }
                   3997: 
                   3998:   zBuf = (char*)Tcl_GetByteArrayFromObj(objv[1], 0);
                   3999:   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf)));
                   4000: #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */
                   4001:   return TCL_OK;
                   4002: }
                   4003: 
                   4004: /*
                   4005: ** Usage: sqlite3_step STMT
                   4006: **
                   4007: ** Advance the statement to the next row.
                   4008: */
                   4009: static int test_step(
                   4010:   void * clientData,
                   4011:   Tcl_Interp *interp,
                   4012:   int objc,
                   4013:   Tcl_Obj *CONST objv[]
                   4014: ){
                   4015:   sqlite3_stmt *pStmt;
                   4016:   int rc;
                   4017: 
                   4018:   if( objc!=2 ){
                   4019:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4020:        Tcl_GetString(objv[0]), " STMT", 0);
                   4021:     return TCL_ERROR;
                   4022:   }
                   4023: 
                   4024:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4025:   rc = sqlite3_step(pStmt);
                   4026: 
                   4027:   /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */
                   4028:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
                   4029:   return TCL_OK;
                   4030: }
                   4031: 
                   4032: static int test_sql(
                   4033:   void * clientData,
                   4034:   Tcl_Interp *interp,
                   4035:   int objc,
                   4036:   Tcl_Obj *CONST objv[]
                   4037: ){
                   4038:   sqlite3_stmt *pStmt;
                   4039: 
                   4040:   if( objc!=2 ){
                   4041:     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
                   4042:     return TCL_ERROR;
                   4043:   }
                   4044: 
                   4045:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4046:   Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE);
                   4047:   return TCL_OK;
                   4048: }
                   4049: 
                   4050: /*
                   4051: ** Usage: sqlite3_column_count STMT 
                   4052: **
                   4053: ** Return the number of columns returned by the sql statement STMT.
                   4054: */
                   4055: static int test_column_count(
                   4056:   void * clientData,
                   4057:   Tcl_Interp *interp,
                   4058:   int objc,
                   4059:   Tcl_Obj *CONST objv[]
                   4060: ){
                   4061:   sqlite3_stmt *pStmt;
                   4062: 
                   4063:   if( objc!=2 ){
                   4064:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4065:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4066:     return TCL_ERROR;
                   4067:   }
                   4068: 
                   4069:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4070: 
                   4071:   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt)));
                   4072:   return TCL_OK;
                   4073: }
                   4074: 
                   4075: /*
                   4076: ** Usage: sqlite3_column_type STMT column
                   4077: **
                   4078: ** Return the type of the data in column 'column' of the current row.
                   4079: */
                   4080: static int test_column_type(
                   4081:   void * clientData,
                   4082:   Tcl_Interp *interp,
                   4083:   int objc,
                   4084:   Tcl_Obj *CONST objv[]
                   4085: ){
                   4086:   sqlite3_stmt *pStmt;
                   4087:   int col;
                   4088:   int tp;
                   4089: 
                   4090:   if( objc!=3 ){
                   4091:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4092:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4093:     return TCL_ERROR;
                   4094:   }
                   4095: 
                   4096:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4097:   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
                   4098: 
                   4099:   tp = sqlite3_column_type(pStmt, col);
                   4100:   switch( tp ){
                   4101:     case SQLITE_INTEGER: 
                   4102:       Tcl_SetResult(interp, "INTEGER", TCL_STATIC); 
                   4103:       break;
                   4104:     case SQLITE_NULL:
                   4105:       Tcl_SetResult(interp, "NULL", TCL_STATIC); 
                   4106:       break;
                   4107:     case SQLITE_FLOAT:
                   4108:       Tcl_SetResult(interp, "FLOAT", TCL_STATIC); 
                   4109:       break;
                   4110:     case SQLITE_TEXT:
                   4111:       Tcl_SetResult(interp, "TEXT", TCL_STATIC); 
                   4112:       break;
                   4113:     case SQLITE_BLOB:
                   4114:       Tcl_SetResult(interp, "BLOB", TCL_STATIC); 
                   4115:       break;
                   4116:     default:
                   4117:       assert(0);
                   4118:   }
                   4119: 
                   4120:   return TCL_OK;
                   4121: }
                   4122: 
                   4123: /*
                   4124: ** Usage: sqlite3_column_int64 STMT column
                   4125: **
                   4126: ** Return the data in column 'column' of the current row cast as an
                   4127: ** wide (64-bit) integer.
                   4128: */
                   4129: static int test_column_int64(
                   4130:   void * clientData,
                   4131:   Tcl_Interp *interp,
                   4132:   int objc,
                   4133:   Tcl_Obj *CONST objv[]
                   4134: ){
                   4135:   sqlite3_stmt *pStmt;
                   4136:   int col;
                   4137:   i64 iVal;
                   4138: 
                   4139:   if( objc!=3 ){
                   4140:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4141:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4142:     return TCL_ERROR;
                   4143:   }
                   4144: 
                   4145:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4146:   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
                   4147: 
                   4148:   iVal = sqlite3_column_int64(pStmt, col);
                   4149:   Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal));
                   4150:   return TCL_OK;
                   4151: }
                   4152: 
                   4153: /*
                   4154: ** Usage: sqlite3_column_blob STMT column
                   4155: */
                   4156: static int test_column_blob(
                   4157:   void * clientData,
                   4158:   Tcl_Interp *interp,
                   4159:   int objc,
                   4160:   Tcl_Obj *CONST objv[]
                   4161: ){
                   4162:   sqlite3_stmt *pStmt;
                   4163:   int col;
                   4164: 
                   4165:   int len;
                   4166:   const void *pBlob;
                   4167: 
                   4168:   if( objc!=3 ){
                   4169:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4170:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4171:     return TCL_ERROR;
                   4172:   }
                   4173: 
                   4174:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4175:   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
                   4176: 
                   4177:   len = sqlite3_column_bytes(pStmt, col);
                   4178:   pBlob = sqlite3_column_blob(pStmt, col);
                   4179:   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len));
                   4180:   return TCL_OK;
                   4181: }
                   4182: 
                   4183: /*
                   4184: ** Usage: sqlite3_column_double STMT column
                   4185: **
                   4186: ** Return the data in column 'column' of the current row cast as a double.
                   4187: */
                   4188: static int test_column_double(
                   4189:   void * clientData,
                   4190:   Tcl_Interp *interp,
                   4191:   int objc,
                   4192:   Tcl_Obj *CONST objv[]
                   4193: ){
                   4194:   sqlite3_stmt *pStmt;
                   4195:   int col;
                   4196:   double rVal;
                   4197: 
                   4198:   if( objc!=3 ){
                   4199:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4200:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4201:     return TCL_ERROR;
                   4202:   }
                   4203: 
                   4204:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4205:   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
                   4206: 
                   4207:   rVal = sqlite3_column_double(pStmt, col);
                   4208:   Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal));
                   4209:   return TCL_OK;
                   4210: }
                   4211: 
                   4212: /*
                   4213: ** Usage: sqlite3_data_count STMT 
                   4214: **
                   4215: ** Return the number of columns returned by the sql statement STMT.
                   4216: */
                   4217: static int test_data_count(
                   4218:   void * clientData,
                   4219:   Tcl_Interp *interp,
                   4220:   int objc,
                   4221:   Tcl_Obj *CONST objv[]
                   4222: ){
                   4223:   sqlite3_stmt *pStmt;
                   4224: 
                   4225:   if( objc!=2 ){
                   4226:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4227:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4228:     return TCL_ERROR;
                   4229:   }
                   4230: 
                   4231:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4232: 
                   4233:   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt)));
                   4234:   return TCL_OK;
                   4235: }
                   4236: 
                   4237: /*
                   4238: ** Usage: sqlite3_column_text STMT column
                   4239: **
                   4240: ** Usage: sqlite3_column_decltype STMT column
                   4241: **
                   4242: ** Usage: sqlite3_column_name STMT column
                   4243: */
                   4244: static int test_stmt_utf8(
                   4245:   void * clientData,        /* Pointer to SQLite API function to be invoke */
                   4246:   Tcl_Interp *interp,
                   4247:   int objc,
                   4248:   Tcl_Obj *CONST objv[]
                   4249: ){
                   4250:   sqlite3_stmt *pStmt;
                   4251:   int col;
                   4252:   const char *(*xFunc)(sqlite3_stmt*, int);
                   4253:   const char *zRet;
                   4254: 
                   4255:   xFunc = (const char *(*)(sqlite3_stmt*, int))clientData;
                   4256:   if( objc!=3 ){
                   4257:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4258:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4259:     return TCL_ERROR;
                   4260:   }
                   4261: 
                   4262:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4263:   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
                   4264:   zRet = xFunc(pStmt, col);
                   4265:   if( zRet ){
                   4266:     Tcl_SetResult(interp, (char *)zRet, 0);
                   4267:   }
                   4268:   return TCL_OK;
                   4269: }
                   4270: 
                   4271: static int test_global_recover(
                   4272:   void * clientData,
                   4273:   Tcl_Interp *interp,
                   4274:   int objc,
                   4275:   Tcl_Obj *CONST objv[]
                   4276: ){
                   4277: #ifndef SQLITE_OMIT_DEPRECATED
                   4278:   int rc;
                   4279:   if( objc!=1 ){
                   4280:     Tcl_WrongNumArgs(interp, 1, objv, "");
                   4281:     return TCL_ERROR;
                   4282:   }
                   4283:   rc = sqlite3_global_recover();
                   4284:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
                   4285: #endif
                   4286:   return TCL_OK;
                   4287: }
                   4288: 
                   4289: /*
                   4290: ** Usage: sqlite3_column_text STMT column
                   4291: **
                   4292: ** Usage: sqlite3_column_decltype STMT column
                   4293: **
                   4294: ** Usage: sqlite3_column_name STMT column
                   4295: */
                   4296: static int test_stmt_utf16(
                   4297:   void * clientData,     /* Pointer to SQLite API function to be invoked */
                   4298:   Tcl_Interp *interp,
                   4299:   int objc,
                   4300:   Tcl_Obj *CONST objv[]
                   4301: ){
                   4302: #ifndef SQLITE_OMIT_UTF16
                   4303:   sqlite3_stmt *pStmt;
                   4304:   int col;
                   4305:   Tcl_Obj *pRet;
                   4306:   const void *zName16;
                   4307:   const void *(*xFunc)(sqlite3_stmt*, int);
                   4308: 
                   4309:   xFunc = (const void *(*)(sqlite3_stmt*, int))clientData;
                   4310:   if( objc!=3 ){
                   4311:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4312:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4313:     return TCL_ERROR;
                   4314:   }
                   4315: 
                   4316:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4317:   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
                   4318: 
                   4319:   zName16 = xFunc(pStmt, col);
                   4320:   if( zName16 ){
                   4321:     int n;
                   4322:     const char *z = zName16;
                   4323:     for(n=0; z[n] || z[n+1]; n+=2){}
                   4324:     pRet = Tcl_NewByteArrayObj(zName16, n+2);
                   4325:     Tcl_SetObjResult(interp, pRet);
                   4326:   }
                   4327: #endif /* SQLITE_OMIT_UTF16 */
                   4328: 
                   4329:   return TCL_OK;
                   4330: }
                   4331: 
                   4332: /*
                   4333: ** Usage: sqlite3_column_int STMT column
                   4334: **
                   4335: ** Usage: sqlite3_column_bytes STMT column
                   4336: **
                   4337: ** Usage: sqlite3_column_bytes16 STMT column
                   4338: **
                   4339: */
                   4340: static int test_stmt_int(
                   4341:   void * clientData,    /* Pointer to SQLite API function to be invoked */
                   4342:   Tcl_Interp *interp,
                   4343:   int objc,
                   4344:   Tcl_Obj *CONST objv[]
                   4345: ){
                   4346:   sqlite3_stmt *pStmt;
                   4347:   int col;
                   4348:   int (*xFunc)(sqlite3_stmt*, int);
                   4349: 
                   4350:   xFunc = (int (*)(sqlite3_stmt*, int))clientData;
                   4351:   if( objc!=3 ){
                   4352:     Tcl_AppendResult(interp, "wrong # args: should be \"", 
                   4353:        Tcl_GetString(objv[0]), " STMT column", 0);
                   4354:     return TCL_ERROR;
                   4355:   }
                   4356: 
                   4357:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   4358:   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
                   4359: 
                   4360:   Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col)));
                   4361:   return TCL_OK;
                   4362: }
                   4363: 
                   4364: /*
                   4365: ** Usage:  sqlite_set_magic  DB  MAGIC-NUMBER
                   4366: **
                   4367: ** Set the db->magic value.  This is used to test error recovery logic.
                   4368: */
                   4369: static int sqlite_set_magic(
                   4370:   void * clientData,
                   4371:   Tcl_Interp *interp,
                   4372:   int argc,
                   4373:   char **argv
                   4374: ){
                   4375:   sqlite3 *db;
                   4376:   if( argc!=3 ){
                   4377:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                   4378:          " DB MAGIC", 0);
                   4379:     return TCL_ERROR;
                   4380:   }
                   4381:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   4382:   if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){
                   4383:     db->magic = SQLITE_MAGIC_OPEN;
                   4384:   }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){
                   4385:     db->magic = SQLITE_MAGIC_CLOSED;
                   4386:   }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){
                   4387:     db->magic = SQLITE_MAGIC_BUSY;
                   4388:   }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){
                   4389:     db->magic = SQLITE_MAGIC_ERROR;
                   4390:   }else if( Tcl_GetInt(interp, argv[2], (int*)&db->magic) ){
                   4391:     return TCL_ERROR;
                   4392:   }
                   4393:   return TCL_OK;
                   4394: }
                   4395: 
                   4396: /*
                   4397: ** Usage:  sqlite3_interrupt  DB 
                   4398: **
                   4399: ** Trigger an interrupt on DB
                   4400: */
                   4401: static int test_interrupt(
                   4402:   void * clientData,
                   4403:   Tcl_Interp *interp,
                   4404:   int argc,
                   4405:   char **argv
                   4406: ){
                   4407:   sqlite3 *db;
                   4408:   if( argc!=2 ){
                   4409:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0);
                   4410:     return TCL_ERROR;
                   4411:   }
                   4412:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   4413:   sqlite3_interrupt(db);
                   4414:   return TCL_OK;
                   4415: }
                   4416: 
                   4417: static u8 *sqlite3_stack_baseline = 0;
                   4418: 
                   4419: /*
                   4420: ** Fill the stack with a known bitpattern.
                   4421: */
                   4422: static void prepStack(void){
                   4423:   int i;
                   4424:   u32 bigBuf[65536];
                   4425:   for(i=0; i<sizeof(bigBuf)/sizeof(bigBuf[0]); i++) bigBuf[i] = 0xdeadbeef;
                   4426:   sqlite3_stack_baseline = (u8*)&bigBuf[65536];
                   4427: }
                   4428: 
                   4429: /*
                   4430: ** Get the current stack depth.  Used for debugging only.
                   4431: */
                   4432: u64 sqlite3StackDepth(void){
                   4433:   u8 x;
                   4434:   return (u64)(sqlite3_stack_baseline - &x);
                   4435: }
                   4436: 
                   4437: /*
                   4438: ** Usage:  sqlite3_stack_used DB SQL
                   4439: **
                   4440: ** Try to measure the amount of stack space used by a call to sqlite3_exec
                   4441: */
                   4442: static int test_stack_used(
                   4443:   void * clientData,
                   4444:   Tcl_Interp *interp,
                   4445:   int argc,
                   4446:   char **argv
                   4447: ){
                   4448:   sqlite3 *db;
                   4449:   int i;
                   4450:   if( argc!=3 ){
                   4451:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                   4452:         " DB SQL", 0);
                   4453:     return TCL_ERROR;
                   4454:   }
                   4455:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   4456:   prepStack();
                   4457:   (void)sqlite3_exec(db, argv[2], 0, 0, 0);
                   4458:   for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){}
                   4459:   Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4));
                   4460:   return TCL_OK;
                   4461: }
                   4462: 
                   4463: /*
                   4464: ** Usage: sqlite_delete_function DB function-name
                   4465: **
                   4466: ** Delete the user function 'function-name' from database handle DB. It
                   4467: ** is assumed that the user function was created as UTF8, any number of
                   4468: ** arguments (the way the TCL interface does it).
                   4469: */
                   4470: static int delete_function(
                   4471:   void * clientData,
                   4472:   Tcl_Interp *interp,
                   4473:   int argc,
                   4474:   char **argv
                   4475: ){
                   4476:   int rc;
                   4477:   sqlite3 *db;
                   4478:   if( argc!=3 ){
                   4479:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                   4480:         " DB function-name", 0);
                   4481:     return TCL_ERROR;
                   4482:   }
                   4483:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   4484:   rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0);
                   4485:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
                   4486:   return TCL_OK;
                   4487: }
                   4488: 
                   4489: /*
                   4490: ** Usage: sqlite_delete_collation DB collation-name
                   4491: **
                   4492: ** Delete the collation sequence 'collation-name' from database handle 
                   4493: ** DB. It is assumed that the collation sequence was created as UTF8 (the 
                   4494: ** way the TCL interface does it).
                   4495: */
                   4496: static int delete_collation(
                   4497:   void * clientData,
                   4498:   Tcl_Interp *interp,
                   4499:   int argc,
                   4500:   char **argv
                   4501: ){
                   4502:   int rc;
                   4503:   sqlite3 *db;
                   4504:   if( argc!=3 ){
                   4505:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                   4506:         " DB function-name", 0);
                   4507:     return TCL_ERROR;
                   4508:   }
                   4509:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   4510:   rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0);
                   4511:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
                   4512:   return TCL_OK;
                   4513: }
                   4514: 
                   4515: /*
                   4516: ** Usage: sqlite3_get_autocommit DB
                   4517: **
                   4518: ** Return true if the database DB is currently in auto-commit mode.
                   4519: ** Return false if not.
                   4520: */
                   4521: static int get_autocommit(
                   4522:   void * clientData,
                   4523:   Tcl_Interp *interp,
                   4524:   int argc,
                   4525:   char **argv
                   4526: ){
                   4527:   char zBuf[30];
                   4528:   sqlite3 *db;
                   4529:   if( argc!=2 ){
                   4530:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                   4531:         " DB", 0);
                   4532:     return TCL_ERROR;
                   4533:   }
                   4534:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   4535:   sprintf(zBuf, "%d", sqlite3_get_autocommit(db));
                   4536:   Tcl_AppendResult(interp, zBuf, 0);
                   4537:   return TCL_OK;
                   4538: }
                   4539: 
                   4540: /*
                   4541: ** Usage: sqlite3_busy_timeout DB MS
                   4542: **
                   4543: ** Set the busy timeout.  This is more easily done using the timeout
                   4544: ** method of the TCL interface.  But we need a way to test the case
                   4545: ** where it returns SQLITE_MISUSE.
                   4546: */
                   4547: static int test_busy_timeout(
                   4548:   void * clientData,
                   4549:   Tcl_Interp *interp,
                   4550:   int argc,
                   4551:   char **argv
                   4552: ){
                   4553:   int rc, ms;
                   4554:   sqlite3 *db;
                   4555:   if( argc!=3 ){
                   4556:     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                   4557:         " DB", 0);
                   4558:     return TCL_ERROR;
                   4559:   }
                   4560:   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
                   4561:   if( Tcl_GetInt(interp, argv[2], &ms) ) return TCL_ERROR;
                   4562:   rc = sqlite3_busy_timeout(db, ms);
                   4563:   Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
                   4564:   return TCL_OK;
                   4565: }
                   4566: 
                   4567: /*
                   4568: ** Usage:  tcl_variable_type VARIABLENAME
                   4569: **
                   4570: ** Return the name of the internal representation for the
                   4571: ** value of the given variable.
                   4572: */
                   4573: static int tcl_variable_type(
                   4574:   void * clientData,
                   4575:   Tcl_Interp *interp,
                   4576:   int objc,
                   4577:   Tcl_Obj *CONST objv[]
                   4578: ){
                   4579:   Tcl_Obj *pVar;
                   4580:   if( objc!=2 ){
                   4581:     Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE");
                   4582:     return TCL_ERROR;
                   4583:   }
                   4584:   pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG);
                   4585:   if( pVar==0 ) return TCL_ERROR;
                   4586:   if( pVar->typePtr ){
                   4587:     Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1));
                   4588:   }
                   4589:   return TCL_OK;
                   4590: }
                   4591: 
                   4592: /*
                   4593: ** Usage:  sqlite3_release_memory ?N?
                   4594: **
                   4595: ** Attempt to release memory currently held but not actually required.
                   4596: ** The integer N is the number of bytes we are trying to release.  The 
                   4597: ** return value is the amount of memory actually released.
                   4598: */
                   4599: static int test_release_memory(
                   4600:   void * clientData,
                   4601:   Tcl_Interp *interp,
                   4602:   int objc,
                   4603:   Tcl_Obj *CONST objv[]
                   4604: ){
                   4605: #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
                   4606:   int N;
                   4607:   int amt;
                   4608:   if( objc!=1 && objc!=2 ){
                   4609:     Tcl_WrongNumArgs(interp, 1, objv, "?N?");
                   4610:     return TCL_ERROR;
                   4611:   }
                   4612:   if( objc==2 ){
                   4613:     if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
                   4614:   }else{
                   4615:     N = -1;
                   4616:   }
                   4617:   amt = sqlite3_release_memory(N);
                   4618:   Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));
                   4619: #endif
                   4620:   return TCL_OK;
                   4621: }
                   4622: 
                   4623: 
                   4624: /*
                   4625: ** Usage:  sqlite3_db_release_memory DB
                   4626: **
                   4627: ** Attempt to release memory currently held by database DB.  Return the
                   4628: ** result code (which in the current implementation is always zero).
                   4629: */
                   4630: static int test_db_release_memory(
                   4631:   void * clientData,
                   4632:   Tcl_Interp *interp,
                   4633:   int objc,
                   4634:   Tcl_Obj *CONST objv[]
                   4635: ){
                   4636:   sqlite3 *db;
                   4637:   int rc;
                   4638:   if( objc!=2 ){
                   4639:     Tcl_WrongNumArgs(interp, 1, objv, "DB");
                   4640:     return TCL_ERROR;
                   4641:   }
                   4642:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   4643:   rc = sqlite3_db_release_memory(db);
                   4644:   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
                   4645:   return TCL_OK;
                   4646: }
                   4647: 
                   4648: /*
                   4649: ** Usage:  sqlite3_db_filename DB DBNAME
                   4650: **
                   4651: ** Return the name of a file associated with a database.
                   4652: */
                   4653: static int test_db_filename(
                   4654:   void * clientData,
                   4655:   Tcl_Interp *interp,
                   4656:   int objc,
                   4657:   Tcl_Obj *CONST objv[]
                   4658: ){
                   4659:   sqlite3 *db;
                   4660:   const char *zDbName;
                   4661:   if( objc!=3 ){
                   4662:     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME");
                   4663:     return TCL_ERROR;
                   4664:   }
                   4665:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   4666:   zDbName = Tcl_GetString(objv[2]);
                   4667:   Tcl_AppendResult(interp, sqlite3_db_filename(db, zDbName), (void*)0);
                   4668:   return TCL_OK;
                   4669: }
                   4670: 
                   4671: /*
                   4672: ** Usage:  sqlite3_soft_heap_limit ?N?
                   4673: **
                   4674: ** Query or set the soft heap limit for the current thread.  The
                   4675: ** limit is only changed if the N is present.  The previous limit
                   4676: ** is returned.
                   4677: */
                   4678: static int test_soft_heap_limit(
                   4679:   void * clientData,
                   4680:   Tcl_Interp *interp,
                   4681:   int objc,
                   4682:   Tcl_Obj *CONST objv[]
                   4683: ){
                   4684:   sqlite3_int64 amt;
                   4685:   sqlite3_int64 N = -1;
                   4686:   if( objc!=1 && objc!=2 ){
                   4687:     Tcl_WrongNumArgs(interp, 1, objv, "?N?");
                   4688:     return TCL_ERROR;
                   4689:   }
                   4690:   if( objc==2 ){
                   4691:     if( Tcl_GetWideIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
                   4692:   }
                   4693:   amt = sqlite3_soft_heap_limit64(N);
                   4694:   Tcl_SetObjResult(interp, Tcl_NewWideIntObj(amt));
                   4695:   return TCL_OK;
                   4696: }
                   4697: 
                   4698: /*
                   4699: ** Usage:   sqlite3_thread_cleanup
                   4700: **
                   4701: ** Call the sqlite3_thread_cleanup API.
                   4702: */
                   4703: static int test_thread_cleanup(
                   4704:   void * clientData,
                   4705:   Tcl_Interp *interp,
                   4706:   int objc,
                   4707:   Tcl_Obj *CONST objv[]
                   4708: ){
                   4709: #ifndef SQLITE_OMIT_DEPRECATED
                   4710:   sqlite3_thread_cleanup();
                   4711: #endif
                   4712:   return TCL_OK;
                   4713: }
                   4714: 
                   4715: /*
                   4716: ** Usage:   sqlite3_pager_refcounts  DB
                   4717: **
                   4718: ** Return a list of numbers which are the PagerRefcount for all
                   4719: ** pagers on each database connection.
                   4720: */
                   4721: static int test_pager_refcounts(
                   4722:   void * clientData,
                   4723:   Tcl_Interp *interp,
                   4724:   int objc,
                   4725:   Tcl_Obj *CONST objv[]
                   4726: ){
                   4727:   sqlite3 *db;
                   4728:   int i;
                   4729:   int v, *a;
                   4730:   Tcl_Obj *pResult;
                   4731: 
                   4732:   if( objc!=2 ){
                   4733:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   4734:         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
                   4735:     return TCL_ERROR;
                   4736:   }
                   4737:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   4738:   pResult = Tcl_NewObj();
                   4739:   for(i=0; i<db->nDb; i++){
                   4740:     if( db->aDb[i].pBt==0 ){
                   4741:       v = -1;
                   4742:     }else{
                   4743:       sqlite3_mutex_enter(db->mutex);
                   4744:       a = sqlite3PagerStats(sqlite3BtreePager(db->aDb[i].pBt));
                   4745:       v = a[0];
                   4746:       sqlite3_mutex_leave(db->mutex);
                   4747:     }
                   4748:     Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(v));
                   4749:   }
                   4750:   Tcl_SetObjResult(interp, pResult);
                   4751:   return TCL_OK;
                   4752: }
                   4753: 
                   4754: 
                   4755: /*
                   4756: ** tclcmd:   working_64bit_int
                   4757: **
                   4758: ** Some TCL builds (ex: cygwin) do not support 64-bit integers.  This
                   4759: ** leads to a number of test failures.  The present command checks the
                   4760: ** TCL build to see whether or not it supports 64-bit integers.  It
                   4761: ** returns TRUE if it does and FALSE if not.
                   4762: **
                   4763: ** This command is used to warn users that their TCL build is defective
                   4764: ** and that the errors they are seeing in the test scripts might be
                   4765: ** a result of their defective TCL rather than problems in SQLite.
                   4766: */
                   4767: static int working_64bit_int(
                   4768:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   4769:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   4770:   int objc,              /* Number of arguments */
                   4771:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   4772: ){
                   4773:   Tcl_Obj *pTestObj;
                   4774:   int working = 0;
                   4775: 
                   4776:   pTestObj = Tcl_NewWideIntObj(1000000*(i64)1234567890);
                   4777:   working = strcmp(Tcl_GetString(pTestObj), "1234567890000000")==0;
                   4778:   Tcl_DecrRefCount(pTestObj);
                   4779:   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(working));
                   4780:   return TCL_OK;
                   4781: }
                   4782: 
                   4783: 
                   4784: /*
                   4785: ** tclcmd:   vfs_unlink_test
                   4786: **
                   4787: ** This TCL command unregisters the primary VFS and then registers
                   4788: ** it back again.  This is used to test the ability to register a
                   4789: ** VFS when none are previously registered, and the ability to 
                   4790: ** unregister the only available VFS.  Ticket #2738
                   4791: */
                   4792: static int vfs_unlink_test(
                   4793:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   4794:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   4795:   int objc,              /* Number of arguments */
                   4796:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   4797: ){
                   4798:   int i;
                   4799:   sqlite3_vfs *pMain;
                   4800:   sqlite3_vfs *apVfs[20];
                   4801:   sqlite3_vfs one, two;
                   4802: 
                   4803:   sqlite3_vfs_unregister(0);   /* Unregister of NULL is harmless */
                   4804:   one.zName = "__one";
                   4805:   two.zName = "__two";
                   4806: 
                   4807:   /* Calling sqlite3_vfs_register with 2nd argument of 0 does not
                   4808:   ** change the default VFS
                   4809:   */
                   4810:   pMain = sqlite3_vfs_find(0);
                   4811:   sqlite3_vfs_register(&one, 0);
                   4812:   assert( pMain==0 || pMain==sqlite3_vfs_find(0) );
                   4813:   sqlite3_vfs_register(&two, 0);
                   4814:   assert( pMain==0 || pMain==sqlite3_vfs_find(0) );
                   4815: 
                   4816:   /* We can find a VFS by its name */
                   4817:   assert( sqlite3_vfs_find("__one")==&one );
                   4818:   assert( sqlite3_vfs_find("__two")==&two );
                   4819: 
                   4820:   /* Calling sqlite_vfs_register with non-zero second parameter changes the
                   4821:   ** default VFS, even if the 1st parameter is an existig VFS that is
                   4822:   ** previously registered as the non-default.
                   4823:   */
                   4824:   sqlite3_vfs_register(&one, 1);
                   4825:   assert( sqlite3_vfs_find("__one")==&one );
                   4826:   assert( sqlite3_vfs_find("__two")==&two );
                   4827:   assert( sqlite3_vfs_find(0)==&one );
                   4828:   sqlite3_vfs_register(&two, 1);
                   4829:   assert( sqlite3_vfs_find("__one")==&one );
                   4830:   assert( sqlite3_vfs_find("__two")==&two );
                   4831:   assert( sqlite3_vfs_find(0)==&two );
                   4832:   if( pMain ){
                   4833:     sqlite3_vfs_register(pMain, 1);
                   4834:     assert( sqlite3_vfs_find("__one")==&one );
                   4835:     assert( sqlite3_vfs_find("__two")==&two );
                   4836:     assert( sqlite3_vfs_find(0)==pMain );
                   4837:   }
                   4838:   
                   4839:   /* Unlink the default VFS.  Repeat until there are no more VFSes
                   4840:   ** registered.
                   4841:   */
                   4842:   for(i=0; i<sizeof(apVfs)/sizeof(apVfs[0]); i++){
                   4843:     apVfs[i] = sqlite3_vfs_find(0);
                   4844:     if( apVfs[i] ){
                   4845:       assert( apVfs[i]==sqlite3_vfs_find(apVfs[i]->zName) );
                   4846:       sqlite3_vfs_unregister(apVfs[i]);
                   4847:       assert( 0==sqlite3_vfs_find(apVfs[i]->zName) );
                   4848:     }
                   4849:   }
                   4850:   assert( 0==sqlite3_vfs_find(0) );
                   4851:   
                   4852:   /* Register the main VFS as non-default (will be made default, since
                   4853:   ** it'll be the only one in existence).
                   4854:   */
                   4855:   sqlite3_vfs_register(pMain, 0);
                   4856:   assert( sqlite3_vfs_find(0)==pMain );
                   4857:   
                   4858:   /* Un-register the main VFS again to restore an empty VFS list */
                   4859:   sqlite3_vfs_unregister(pMain);
                   4860:   assert( 0==sqlite3_vfs_find(0) );
                   4861: 
                   4862:   /* Relink all VFSes in reverse order. */  
                   4863:   for(i=sizeof(apVfs)/sizeof(apVfs[0])-1; i>=0; i--){
                   4864:     if( apVfs[i] ){
                   4865:       sqlite3_vfs_register(apVfs[i], 1);
                   4866:       assert( apVfs[i]==sqlite3_vfs_find(0) );
                   4867:       assert( apVfs[i]==sqlite3_vfs_find(apVfs[i]->zName) );
                   4868:     }
                   4869:   }
                   4870: 
                   4871:   /* Unregister out sample VFSes. */
                   4872:   sqlite3_vfs_unregister(&one);
                   4873:   sqlite3_vfs_unregister(&two);
                   4874: 
                   4875:   /* Unregistering a VFS that is not currently registered is harmless */
                   4876:   sqlite3_vfs_unregister(&one);
                   4877:   sqlite3_vfs_unregister(&two);
                   4878:   assert( sqlite3_vfs_find("__one")==0 );
                   4879:   assert( sqlite3_vfs_find("__two")==0 );
                   4880: 
                   4881:   /* We should be left with the original default VFS back as the
                   4882:   ** original */
                   4883:   assert( sqlite3_vfs_find(0)==pMain );
                   4884: 
                   4885:   return TCL_OK;
                   4886: }
                   4887: 
                   4888: /*
                   4889: ** tclcmd:   vfs_initfail_test
                   4890: **
                   4891: ** This TCL command attempts to vfs_find and vfs_register when the
                   4892: ** sqlite3_initialize() interface is failing.  All calls should fail.
                   4893: */
                   4894: static int vfs_initfail_test(
                   4895:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   4896:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   4897:   int objc,              /* Number of arguments */
                   4898:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   4899: ){
                   4900:   sqlite3_vfs one;
                   4901:   one.zName = "__one";
                   4902: 
                   4903:   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
                   4904:   sqlite3_vfs_register(&one, 0);
                   4905:   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
                   4906:   sqlite3_vfs_register(&one, 1);
                   4907:   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
                   4908:   return TCL_OK;
                   4909: }
                   4910: 
                   4911: /*
                   4912: ** Saved VFSes
                   4913: */
                   4914: static sqlite3_vfs *apVfs[20];
                   4915: static int nVfs = 0;
                   4916: 
                   4917: /*
                   4918: ** tclcmd:   vfs_unregister_all
                   4919: **
                   4920: ** Unregister all VFSes.
                   4921: */
                   4922: static int vfs_unregister_all(
                   4923:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   4924:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   4925:   int objc,              /* Number of arguments */
                   4926:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   4927: ){
                   4928:   int i;
                   4929:   for(i=0; i<ArraySize(apVfs); i++){
                   4930:     apVfs[i] = sqlite3_vfs_find(0);
                   4931:     if( apVfs[i]==0 ) break;
                   4932:     sqlite3_vfs_unregister(apVfs[i]);
                   4933:   }
                   4934:   nVfs = i;
                   4935:   return TCL_OK;
                   4936: }
                   4937: /*
                   4938: ** tclcmd:   vfs_reregister_all
                   4939: **
                   4940: ** Restore all VFSes that were removed using vfs_unregister_all
                   4941: */
                   4942: static int vfs_reregister_all(
                   4943:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   4944:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   4945:   int objc,              /* Number of arguments */
                   4946:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   4947: ){
                   4948:   int i;
                   4949:   for(i=0; i<nVfs; i++){
                   4950:     sqlite3_vfs_register(apVfs[i], i==0);
                   4951:   }
                   4952:   return TCL_OK;
                   4953: }
                   4954: 
                   4955: 
                   4956: /*
                   4957: ** tclcmd:   file_control_test DB
                   4958: **
                   4959: ** This TCL command runs the sqlite3_file_control interface and
                   4960: ** verifies correct operation of the same.
                   4961: */
                   4962: static int file_control_test(
                   4963:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   4964:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   4965:   int objc,              /* Number of arguments */
                   4966:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   4967: ){
                   4968:   int iArg = 0;
                   4969:   sqlite3 *db;
                   4970:   int rc;
                   4971: 
                   4972:   if( objc!=2 ){
                   4973:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   4974:         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
                   4975:     return TCL_ERROR;
                   4976:   }
                   4977:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   4978:   rc = sqlite3_file_control(db, 0, 0, &iArg);
                   4979:   assert( rc==SQLITE_NOTFOUND );
                   4980:   rc = sqlite3_file_control(db, "notadatabase", SQLITE_FCNTL_LOCKSTATE, &iArg);
                   4981:   assert( rc==SQLITE_ERROR );
                   4982:   rc = sqlite3_file_control(db, "main", -1, &iArg);
                   4983:   assert( rc==SQLITE_NOTFOUND );
                   4984:   rc = sqlite3_file_control(db, "temp", -1, &iArg);
                   4985:   assert( rc==SQLITE_NOTFOUND || rc==SQLITE_ERROR );
                   4986: 
                   4987:   return TCL_OK;
                   4988: }
                   4989: 
                   4990: 
                   4991: /*
                   4992: ** tclcmd:   file_control_lasterrno_test DB
                   4993: **
                   4994: ** This TCL command runs the sqlite3_file_control interface and
                   4995: ** verifies correct operation of the SQLITE_LAST_ERRNO verb.
                   4996: */
                   4997: static int file_control_lasterrno_test(
                   4998:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   4999:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5000:   int objc,              /* Number of arguments */
                   5001:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5002: ){
                   5003:   int iArg = 0;
                   5004:   sqlite3 *db;
                   5005:   int rc;
                   5006: 
                   5007:   if( objc!=2 ){
                   5008:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   5009:         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
                   5010:     return TCL_ERROR;
                   5011:   }
                   5012:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
                   5013:     return TCL_ERROR;
                   5014:   }
                   5015:   rc = sqlite3_file_control(db, NULL, SQLITE_LAST_ERRNO, &iArg);
                   5016:   if( rc ){ 
                   5017:     Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); 
                   5018:     return TCL_ERROR; 
                   5019:   }
                   5020:   if( iArg!=0 ) {
                   5021:     Tcl_AppendResult(interp, "Unexpected non-zero errno: ",
                   5022:                      Tcl_GetStringFromObj(Tcl_NewIntObj(iArg), 0), " ", 0);
                   5023:     return TCL_ERROR;
                   5024:   }
                   5025:   return TCL_OK;  
                   5026: }
                   5027: 
                   5028: /*
                   5029: ** tclcmd:   file_control_chunksize_test DB DBNAME SIZE
                   5030: **
                   5031: ** This TCL command runs the sqlite3_file_control interface and
                   5032: ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
                   5033: ** SQLITE_SET_LOCKPROXYFILE verbs.
                   5034: */
                   5035: static int file_control_chunksize_test(
                   5036:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5037:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5038:   int objc,              /* Number of arguments */
                   5039:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5040: ){
                   5041:   int nSize;                      /* New chunk size */
                   5042:   char *zDb;                      /* Db name ("main", "temp" etc.) */
                   5043:   sqlite3 *db;                    /* Database handle */
                   5044:   int rc;                         /* file_control() return code */
                   5045: 
                   5046:   if( objc!=4 ){
                   5047:     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
                   5048:     return TCL_ERROR;
                   5049:   }
                   5050:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
                   5051:    || Tcl_GetIntFromObj(interp, objv[3], &nSize)
                   5052:   ){
                   5053:    return TCL_ERROR;
                   5054:   }
                   5055:   zDb = Tcl_GetString(objv[2]);
                   5056:   if( zDb[0]=='\0' ) zDb = NULL;
                   5057: 
                   5058:   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_CHUNK_SIZE, (void *)&nSize);
                   5059:   if( rc ){
                   5060:     Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
                   5061:     return TCL_ERROR;
                   5062:   }
                   5063:   return TCL_OK;
                   5064: }
                   5065: 
                   5066: /*
                   5067: ** tclcmd:   file_control_sizehint_test DB DBNAME SIZE
                   5068: **
                   5069: ** This TCL command runs the sqlite3_file_control interface 
                   5070: ** with SQLITE_FCNTL_SIZE_HINT
                   5071: */
                   5072: static int file_control_sizehint_test(
                   5073:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5074:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5075:   int objc,              /* Number of arguments */
                   5076:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5077: ){
                   5078:   sqlite3_int64 nSize;            /* Hinted size */
                   5079:   char *zDb;                      /* Db name ("main", "temp" etc.) */
                   5080:   sqlite3 *db;                    /* Database handle */
                   5081:   int rc;                         /* file_control() return code */
                   5082: 
                   5083:   if( objc!=4 ){
                   5084:     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
                   5085:     return TCL_ERROR;
                   5086:   }
                   5087:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
                   5088:    || Tcl_GetWideIntFromObj(interp, objv[3], &nSize)
                   5089:   ){
                   5090:    return TCL_ERROR;
                   5091:   }
                   5092:   zDb = Tcl_GetString(objv[2]);
                   5093:   if( zDb[0]=='\0' ) zDb = NULL;
                   5094: 
                   5095:   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_SIZE_HINT, (void *)&nSize);
                   5096:   if( rc ){
                   5097:     Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
                   5098:     return TCL_ERROR;
                   5099:   }
                   5100:   return TCL_OK;
                   5101: }
                   5102: 
                   5103: /*
                   5104: ** tclcmd:   file_control_lockproxy_test DB PWD
                   5105: **
                   5106: ** This TCL command runs the sqlite3_file_control interface and
                   5107: ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
                   5108: ** SQLITE_SET_LOCKPROXYFILE verbs.
                   5109: */
                   5110: static int file_control_lockproxy_test(
                   5111:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5112:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5113:   int objc,              /* Number of arguments */
                   5114:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5115: ){
                   5116:   sqlite3 *db;
                   5117:   const char *zPwd;
                   5118:   int nPwd;
                   5119:   
                   5120:   if( objc!=3 ){
                   5121:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   5122:                      Tcl_GetStringFromObj(objv[0], 0), " DB PWD", 0);
                   5123:     return TCL_ERROR;
                   5124:   }
                   5125:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
                   5126:    return TCL_ERROR;
                   5127:   }
                   5128:   zPwd = Tcl_GetStringFromObj(objv[2], &nPwd);
                   5129:   
                   5130: #if !defined(SQLITE_ENABLE_LOCKING_STYLE)
                   5131: #  if defined(__APPLE__)
                   5132: #    define SQLITE_ENABLE_LOCKING_STYLE 1
                   5133: #  else
                   5134: #    define SQLITE_ENABLE_LOCKING_STYLE 0
                   5135: #  endif
                   5136: #endif
                   5137: #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
                   5138:   {
                   5139:     char *testPath;
                   5140:     int rc;
                   5141:     char proxyPath[400];
                   5142:     
                   5143:     if( sizeof(proxyPath)<nPwd+20 ){
                   5144:       Tcl_AppendResult(interp, "PWD too big", (void*)0);
                   5145:       return TCL_ERROR;
                   5146:     }
                   5147:     sprintf(proxyPath, "%s/test.proxy", zPwd);
                   5148:     rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
                   5149:     if( rc ){
                   5150:       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); 
                   5151:       return TCL_ERROR;
                   5152:     }
                   5153:     rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath);
                   5154:     if( strncmp(proxyPath,testPath,11) ){
                   5155:       Tcl_AppendResult(interp, "Lock proxy file did not match the "
                   5156:                                "previously assigned value", 0);
                   5157:       return TCL_ERROR;
                   5158:     }
                   5159:     if( rc ){
                   5160:       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
                   5161:       return TCL_ERROR;
                   5162:     }
                   5163:     rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
                   5164:     if( rc ){
                   5165:       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
                   5166:       return TCL_ERROR;
                   5167:     }
                   5168:   }
                   5169: #endif
                   5170:   return TCL_OK;  
                   5171: }
                   5172: 
                   5173: /*
                   5174: ** tclcmd:   file_control_win32_av_retry DB  NRETRY  DELAY
                   5175: **
                   5176: ** This TCL command runs the sqlite3_file_control interface with
                   5177: ** the SQLITE_FCNTL_WIN32_AV_RETRY opcode.
                   5178: */
                   5179: static int file_control_win32_av_retry(
                   5180:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5181:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5182:   int objc,              /* Number of arguments */
                   5183:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5184: ){
                   5185:   sqlite3 *db;
                   5186:   int rc;
                   5187:   int a[2];
                   5188:   char z[100];
                   5189: 
                   5190:   if( objc!=4 ){
                   5191:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   5192:         Tcl_GetStringFromObj(objv[0], 0), " DB NRETRY DELAY", 0);
                   5193:     return TCL_ERROR;
                   5194:   }
                   5195:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
                   5196:     return TCL_ERROR;
                   5197:   }
                   5198:   if( Tcl_GetIntFromObj(interp, objv[2], &a[0]) ) return TCL_ERROR;
                   5199:   if( Tcl_GetIntFromObj(interp, objv[3], &a[1]) ) return TCL_ERROR;
                   5200:   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_AV_RETRY, (void*)a);
                   5201:   sqlite3_snprintf(sizeof(z), z, "%d %d %d", rc, a[0], a[1]);
                   5202:   Tcl_AppendResult(interp, z, (char*)0);
                   5203:   return TCL_OK;  
                   5204: }
                   5205: 
                   5206: /*
                   5207: ** tclcmd:   file_control_persist_wal DB PERSIST-FLAG
                   5208: **
                   5209: ** This TCL command runs the sqlite3_file_control interface with
                   5210: ** the SQLITE_FCNTL_PERSIST_WAL opcode.
                   5211: */
                   5212: static int file_control_persist_wal(
                   5213:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5214:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5215:   int objc,              /* Number of arguments */
                   5216:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5217: ){
                   5218:   sqlite3 *db;
                   5219:   int rc;
                   5220:   int bPersist;
                   5221:   char z[100];
                   5222: 
                   5223:   if( objc!=3 ){
                   5224:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   5225:         Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0);
                   5226:     return TCL_ERROR;
                   5227:   }
                   5228:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
                   5229:     return TCL_ERROR;
                   5230:   }
                   5231:   if( Tcl_GetIntFromObj(interp, objv[2], &bPersist) ) return TCL_ERROR;
                   5232:   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist);
                   5233:   sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist);
                   5234:   Tcl_AppendResult(interp, z, (char*)0);
                   5235:   return TCL_OK;  
                   5236: }
                   5237: 
                   5238: /*
                   5239: ** tclcmd:   file_control_powersafe_overwrite DB PSOW-FLAG
                   5240: **
                   5241: ** This TCL command runs the sqlite3_file_control interface with
                   5242: ** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode.
                   5243: */
                   5244: static int file_control_powersafe_overwrite(
                   5245:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5246:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5247:   int objc,              /* Number of arguments */
                   5248:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5249: ){
                   5250:   sqlite3 *db;
                   5251:   int rc;
                   5252:   int b;
                   5253:   char z[100];
                   5254: 
                   5255:   if( objc!=3 ){
                   5256:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   5257:         Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0);
                   5258:     return TCL_ERROR;
                   5259:   }
                   5260:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
                   5261:     return TCL_ERROR;
                   5262:   }
                   5263:   if( Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR;
                   5264:   rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_POWERSAFE_OVERWRITE,(void*)&b);
                   5265:   sqlite3_snprintf(sizeof(z), z, "%d %d", rc, b);
                   5266:   Tcl_AppendResult(interp, z, (char*)0);
                   5267:   return TCL_OK;  
                   5268: }
                   5269: 
                   5270: 
                   5271: /*
                   5272: ** tclcmd:   file_control_vfsname DB ?AUXDB?
                   5273: **
                   5274: ** Return a string that describes the stack of VFSes.
                   5275: */
                   5276: static int file_control_vfsname(
                   5277:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5278:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5279:   int objc,              /* Number of arguments */
                   5280:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5281: ){
                   5282:   sqlite3 *db;
                   5283:   const char *zDbName = "main";
                   5284:   char *zVfsName = 0;
                   5285: 
                   5286:   if( objc!=2 && objc!=3 ){
                   5287:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   5288:         Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
                   5289:     return TCL_ERROR;
                   5290:   }
                   5291:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
                   5292:     return TCL_ERROR;
                   5293:   }
                   5294:   if( objc==3 ){
                   5295:     zDbName = Tcl_GetString(objv[2]);
                   5296:   }
                   5297:   sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName);
                   5298:   Tcl_AppendResult(interp, zVfsName, (char*)0);
                   5299:   sqlite3_free(zVfsName);
                   5300:   return TCL_OK;  
                   5301: }
                   5302: 
                   5303: 
                   5304: /*
                   5305: ** tclcmd:   sqlite3_vfs_list
                   5306: **
                   5307: **   Return a tcl list containing the names of all registered vfs's.
                   5308: */
                   5309: static int vfs_list(
                   5310:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5311:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5312:   int objc,              /* Number of arguments */
                   5313:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5314: ){
                   5315:   sqlite3_vfs *pVfs;
                   5316:   Tcl_Obj *pRet = Tcl_NewObj();
                   5317:   if( objc!=1 ){
                   5318:     Tcl_WrongNumArgs(interp, 1, objv, "");
                   5319:     return TCL_ERROR;
                   5320:   }
                   5321:   for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
                   5322:     Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(pVfs->zName, -1));
                   5323:   }
                   5324:   Tcl_SetObjResult(interp, pRet);
                   5325:   return TCL_OK;  
                   5326: }
                   5327: 
                   5328: /*
                   5329: ** tclcmd:   sqlite3_limit DB ID VALUE
                   5330: **
                   5331: ** This TCL command runs the sqlite3_limit interface and
                   5332: ** verifies correct operation of the same.
                   5333: */
                   5334: static int test_limit(
                   5335:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5336:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5337:   int objc,              /* Number of arguments */
                   5338:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5339: ){
                   5340:   sqlite3 *db;
                   5341:   int rc;
                   5342:   static const struct {
                   5343:      char *zName;
                   5344:      int id;
                   5345:   } aId[] = {
                   5346:     { "SQLITE_LIMIT_LENGTH",              SQLITE_LIMIT_LENGTH               },
                   5347:     { "SQLITE_LIMIT_SQL_LENGTH",          SQLITE_LIMIT_SQL_LENGTH           },
                   5348:     { "SQLITE_LIMIT_COLUMN",              SQLITE_LIMIT_COLUMN               },
                   5349:     { "SQLITE_LIMIT_EXPR_DEPTH",          SQLITE_LIMIT_EXPR_DEPTH           },
                   5350:     { "SQLITE_LIMIT_COMPOUND_SELECT",     SQLITE_LIMIT_COMPOUND_SELECT      },
                   5351:     { "SQLITE_LIMIT_VDBE_OP",             SQLITE_LIMIT_VDBE_OP              },
                   5352:     { "SQLITE_LIMIT_FUNCTION_ARG",        SQLITE_LIMIT_FUNCTION_ARG         },
                   5353:     { "SQLITE_LIMIT_ATTACHED",            SQLITE_LIMIT_ATTACHED             },
                   5354:     { "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH  },
                   5355:     { "SQLITE_LIMIT_VARIABLE_NUMBER",     SQLITE_LIMIT_VARIABLE_NUMBER      },
                   5356:     { "SQLITE_LIMIT_TRIGGER_DEPTH",       SQLITE_LIMIT_TRIGGER_DEPTH        },
                   5357:     
                   5358:     /* Out of range test cases */
                   5359:     { "SQLITE_LIMIT_TOOSMALL",            -1,                               },
                   5360:     { "SQLITE_LIMIT_TOOBIG",              SQLITE_LIMIT_TRIGGER_DEPTH+1      },
                   5361:   };
                   5362:   int i, id;
                   5363:   int val;
                   5364:   const char *zId;
                   5365: 
                   5366:   if( objc!=4 ){
                   5367:     Tcl_AppendResult(interp, "wrong # args: should be \"",
                   5368:         Tcl_GetStringFromObj(objv[0], 0), " DB ID VALUE", 0);
                   5369:     return TCL_ERROR;
                   5370:   }
                   5371:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   5372:   zId = Tcl_GetString(objv[2]);
                   5373:   for(i=0; i<sizeof(aId)/sizeof(aId[0]); i++){
                   5374:     if( strcmp(zId, aId[i].zName)==0 ){
                   5375:       id = aId[i].id;
                   5376:       break;
                   5377:     }
                   5378:   }
                   5379:   if( i>=sizeof(aId)/sizeof(aId[0]) ){
                   5380:     Tcl_AppendResult(interp, "unknown limit type: ", zId, (char*)0);
                   5381:     return TCL_ERROR;
                   5382:   }
                   5383:   if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
                   5384:   rc = sqlite3_limit(db, id, val);
                   5385:   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
                   5386:   return TCL_OK;  
                   5387: }
                   5388: 
                   5389: /*
                   5390: ** tclcmd:  save_prng_state
                   5391: **
                   5392: ** Save the state of the pseudo-random number generator.
                   5393: ** At the same time, verify that sqlite3_test_control works even when
                   5394: ** called with an out-of-range opcode.
                   5395: */
                   5396: static int save_prng_state(
                   5397:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5398:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5399:   int objc,              /* Number of arguments */
                   5400:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5401: ){
                   5402:   int rc = sqlite3_test_control(9999);
                   5403:   assert( rc==0 );
                   5404:   rc = sqlite3_test_control(-1);
                   5405:   assert( rc==0 );
                   5406:   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SAVE);
                   5407:   return TCL_OK;
                   5408: }
                   5409: /*
                   5410: ** tclcmd:  restore_prng_state
                   5411: */
                   5412: static int restore_prng_state(
                   5413:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5414:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5415:   int objc,              /* Number of arguments */
                   5416:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5417: ){
                   5418:   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESTORE);
                   5419:   return TCL_OK;
                   5420: }
                   5421: /*
                   5422: ** tclcmd:  reset_prng_state
                   5423: */
                   5424: static int reset_prng_state(
                   5425:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5426:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5427:   int objc,              /* Number of arguments */
                   5428:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5429: ){
                   5430:   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET);
                   5431:   return TCL_OK;
                   5432: }
                   5433: 
                   5434: /*
                   5435: ** tclcmd:  pcache_stats
                   5436: */
                   5437: static int test_pcache_stats(
                   5438:   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
                   5439:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5440:   int objc,              /* Number of arguments */
                   5441:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5442: ){
                   5443:   int nMin;
                   5444:   int nMax;
                   5445:   int nCurrent;
                   5446:   int nRecyclable;
                   5447:   Tcl_Obj *pRet;
                   5448: 
                   5449:   sqlite3PcacheStats(&nCurrent, &nMax, &nMin, &nRecyclable);
                   5450: 
                   5451:   pRet = Tcl_NewObj();
                   5452:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("current", -1));
                   5453:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCurrent));
                   5454:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("max", -1));
                   5455:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMax));
                   5456:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("min", -1));
                   5457:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMin));
                   5458:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("recyclable", -1));
                   5459:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nRecyclable));
                   5460: 
                   5461:   Tcl_SetObjResult(interp, pRet);
                   5462: 
                   5463:   return TCL_OK;
                   5464: }
                   5465: 
                   5466: #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
                   5467: static void test_unlock_notify_cb(void **aArg, int nArg){
                   5468:   int ii;
                   5469:   for(ii=0; ii<nArg; ii++){
                   5470:     Tcl_EvalEx((Tcl_Interp *)aArg[ii], "unlock_notify", -1, TCL_EVAL_GLOBAL);
                   5471:   }
                   5472: }
                   5473: #endif /* SQLITE_ENABLE_UNLOCK_NOTIFY */
                   5474: 
                   5475: /*
                   5476: ** tclcmd:  sqlite3_unlock_notify db
                   5477: */
                   5478: #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
                   5479: static int test_unlock_notify(
                   5480:   ClientData clientData, /* Unused */
                   5481:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5482:   int objc,              /* Number of arguments */
                   5483:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5484: ){
                   5485:   sqlite3 *db;
                   5486:   int rc;
                   5487: 
                   5488:   if( objc!=2 ){
                   5489:     Tcl_WrongNumArgs(interp, 1, objv, "DB");
                   5490:     return TCL_ERROR;
                   5491:   }
                   5492: 
                   5493:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
                   5494:     return TCL_ERROR;
                   5495:   }
                   5496:   rc = sqlite3_unlock_notify(db, test_unlock_notify_cb, (void *)interp);
                   5497:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
                   5498:   return TCL_OK;
                   5499: }
                   5500: #endif
                   5501: 
                   5502: /*
                   5503: ** tclcmd:  sqlite3_wal_checkpoint db ?NAME?
                   5504: */
                   5505: static int test_wal_checkpoint(
                   5506:   ClientData clientData, /* Unused */
                   5507:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5508:   int objc,              /* Number of arguments */
                   5509:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5510: ){
                   5511:   char *zDb = 0;
                   5512:   sqlite3 *db;
                   5513:   int rc;
                   5514: 
                   5515:   if( objc!=3 && objc!=2 ){
                   5516:     Tcl_WrongNumArgs(interp, 1, objv, "DB ?NAME?");
                   5517:     return TCL_ERROR;
                   5518:   }
                   5519: 
                   5520:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
                   5521:     return TCL_ERROR;
                   5522:   }
                   5523:   if( objc==3 ){
                   5524:     zDb = Tcl_GetString(objv[2]);
                   5525:   }
                   5526:   rc = sqlite3_wal_checkpoint(db, zDb);
                   5527:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
                   5528:   return TCL_OK;
                   5529: }
                   5530: 
                   5531: /*
                   5532: ** tclcmd:  sqlite3_wal_checkpoint_v2 db MODE ?NAME?
                   5533: **
                   5534: ** This command calls the wal_checkpoint_v2() function with the specified
                   5535: ** mode argument (passive, full or restart). If present, the database name
                   5536: ** NAME is passed as the second argument to wal_checkpoint_v2(). If it the
                   5537: ** NAME argument is not present, a NULL pointer is passed instead.
                   5538: **
                   5539: ** If wal_checkpoint_v2() returns any value other than SQLITE_BUSY or
                   5540: ** SQLITE_OK, then this command returns TCL_ERROR. The Tcl result is set
                   5541: ** to the error message obtained from sqlite3_errmsg().
                   5542: **
                   5543: ** Otherwise, this command returns a list of three integers. The first integer
                   5544: ** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers
                   5545: ** are the values returned via the output paramaters by wal_checkpoint_v2() -
                   5546: ** the number of frames in the log and the number of frames in the log
                   5547: ** that have been checkpointed.
                   5548: */
                   5549: static int test_wal_checkpoint_v2(
                   5550:   ClientData clientData, /* Unused */
                   5551:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5552:   int objc,              /* Number of arguments */
                   5553:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5554: ){
                   5555:   char *zDb = 0;
                   5556:   sqlite3 *db;
                   5557:   int rc;
                   5558: 
                   5559:   int eMode;
                   5560:   int nLog = -555;
                   5561:   int nCkpt = -555;
                   5562:   Tcl_Obj *pRet;
                   5563: 
                   5564:   const char * aMode[] = { "passive", "full", "restart", 0 };
                   5565:   assert( SQLITE_CHECKPOINT_PASSIVE==0 );
                   5566:   assert( SQLITE_CHECKPOINT_FULL==1 );
                   5567:   assert( SQLITE_CHECKPOINT_RESTART==2 );
                   5568: 
                   5569:   if( objc!=3 && objc!=4 ){
                   5570:     Tcl_WrongNumArgs(interp, 1, objv, "DB MODE ?NAME?");
                   5571:     return TCL_ERROR;
                   5572:   }
                   5573: 
                   5574:   if( objc==4 ){
                   5575:     zDb = Tcl_GetString(objv[3]);
                   5576:   }
                   5577:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
                   5578:    || Tcl_GetIndexFromObj(interp, objv[2], aMode, "mode", 0, &eMode) 
                   5579:   ){
                   5580:     return TCL_ERROR;
                   5581:   }
                   5582: 
                   5583:   rc = sqlite3_wal_checkpoint_v2(db, zDb, eMode, &nLog, &nCkpt);
                   5584:   if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
                   5585:     Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
                   5586:     return TCL_ERROR;
                   5587:   }
                   5588: 
                   5589:   pRet = Tcl_NewObj();
                   5590:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(rc==SQLITE_BUSY?1:0));
                   5591:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nLog));
                   5592:   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCkpt));
                   5593:   Tcl_SetObjResult(interp, pRet);
                   5594: 
                   5595:   return TCL_OK;
                   5596: }
                   5597: 
                   5598: /*
                   5599: ** tclcmd:  test_sqlite3_log ?SCRIPT?
                   5600: */
                   5601: static struct LogCallback {
                   5602:   Tcl_Interp *pInterp;
                   5603:   Tcl_Obj *pObj;
                   5604: } logcallback = {0, 0};
                   5605: static void xLogcallback(void *unused, int err, char *zMsg){
                   5606:   Tcl_Obj *pNew = Tcl_DuplicateObj(logcallback.pObj);
                   5607:   Tcl_IncrRefCount(pNew);
                   5608:   Tcl_ListObjAppendElement(
                   5609:       0, pNew, Tcl_NewStringObj(sqlite3TestErrorName(err), -1)
                   5610:   );
                   5611:   Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zMsg, -1));
                   5612:   Tcl_EvalObjEx(logcallback.pInterp, pNew, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
                   5613:   Tcl_DecrRefCount(pNew);
                   5614: }
                   5615: static int test_sqlite3_log(
                   5616:   ClientData clientData,
                   5617:   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
                   5618:   int objc,              /* Number of arguments */
                   5619:   Tcl_Obj *CONST objv[]  /* Command arguments */
                   5620: ){
                   5621:   if( objc>2 ){
                   5622:     Tcl_WrongNumArgs(interp, 1, objv, "SCRIPT");
                   5623:     return TCL_ERROR;
                   5624:   }
                   5625:   if( logcallback.pObj ){
                   5626:     Tcl_DecrRefCount(logcallback.pObj);
                   5627:     logcallback.pObj = 0;
                   5628:     logcallback.pInterp = 0;
                   5629:     sqlite3_config(SQLITE_CONFIG_LOG, 0, 0);
                   5630:   }
                   5631:   if( objc>1 ){
                   5632:     logcallback.pObj = objv[1];
                   5633:     Tcl_IncrRefCount(logcallback.pObj);
                   5634:     logcallback.pInterp = interp;
                   5635:     sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, 0);
                   5636:   }
                   5637:   return TCL_OK;
                   5638: }
                   5639: 
                   5640: /*
                   5641: **     tcl_objproc COMMANDNAME ARGS...
                   5642: **
                   5643: ** Run a TCL command using its objProc interface.  Throw an error if
                   5644: ** the command has no objProc interface.
                   5645: */
                   5646: static int runAsObjProc(
                   5647:   void * clientData,
                   5648:   Tcl_Interp *interp,
                   5649:   int objc,
                   5650:   Tcl_Obj *CONST objv[]
                   5651: ){
                   5652:   Tcl_CmdInfo cmdInfo;
                   5653:   if( objc<2 ){
                   5654:     Tcl_WrongNumArgs(interp, 1, objv, "COMMAND ...");
                   5655:     return TCL_ERROR;
                   5656:   }
                   5657:   if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
                   5658:     Tcl_AppendResult(interp, "command not found: ",
                   5659:            Tcl_GetString(objv[1]), (char*)0);
                   5660:     return TCL_ERROR;
                   5661:   }
                   5662:   if( cmdInfo.objProc==0 ){
                   5663:     Tcl_AppendResult(interp, "command has no objProc: ",
                   5664:            Tcl_GetString(objv[1]), (char*)0);
                   5665:     return TCL_ERROR;
                   5666:   }
                   5667:   return cmdInfo.objProc(cmdInfo.objClientData, interp, objc-1, objv+1);
                   5668: }
                   5669: 
                   5670: #ifndef SQLITE_OMIT_EXPLAIN
                   5671: /*
                   5672: ** WARNING: The following function, printExplainQueryPlan() is an exact
                   5673: ** copy of example code from eqp.in (eqp.html). If this code is modified,
                   5674: ** then the documentation copy needs to be modified as well.
                   5675: */
                   5676: /*
                   5677: ** Argument pStmt is a prepared SQL statement. This function compiles
                   5678: ** an EXPLAIN QUERY PLAN command to report on the prepared statement,
                   5679: ** and prints the report to stdout using printf().
                   5680: */
                   5681: int printExplainQueryPlan(sqlite3_stmt *pStmt){
                   5682:   const char *zSql;               /* Input SQL */
                   5683:   char *zExplain;                 /* SQL with EXPLAIN QUERY PLAN prepended */
                   5684:   sqlite3_stmt *pExplain;         /* Compiled EXPLAIN QUERY PLAN command */
                   5685:   int rc;                         /* Return code from sqlite3_prepare_v2() */
                   5686: 
                   5687:   zSql = sqlite3_sql(pStmt);
                   5688:   if( zSql==0 ) return SQLITE_ERROR;
                   5689: 
                   5690:   zExplain = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zSql);
                   5691:   if( zExplain==0 ) return SQLITE_NOMEM;
                   5692: 
                   5693:   rc = sqlite3_prepare_v2(sqlite3_db_handle(pStmt), zExplain, -1, &pExplain, 0);
                   5694:   sqlite3_free(zExplain);
                   5695:   if( rc!=SQLITE_OK ) return rc;
                   5696: 
                   5697:   while( SQLITE_ROW==sqlite3_step(pExplain) ){
                   5698:     int iSelectid = sqlite3_column_int(pExplain, 0);
                   5699:     int iOrder = sqlite3_column_int(pExplain, 1);
                   5700:     int iFrom = sqlite3_column_int(pExplain, 2);
                   5701:     const char *zDetail = (const char *)sqlite3_column_text(pExplain, 3);
                   5702: 
                   5703:     printf("%d %d %d %s\n", iSelectid, iOrder, iFrom, zDetail);
                   5704:   }
                   5705: 
                   5706:   return sqlite3_finalize(pExplain);
                   5707: }
                   5708: 
                   5709: static int test_print_eqp(
                   5710:   void * clientData,
                   5711:   Tcl_Interp *interp,
                   5712:   int objc,
                   5713:   Tcl_Obj *CONST objv[]
                   5714: ){
                   5715:   int rc;
                   5716:   sqlite3_stmt *pStmt;
                   5717: 
                   5718:   if( objc!=2 ){
                   5719:     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
                   5720:     return TCL_ERROR;
                   5721:   }
                   5722:   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
                   5723:   rc = printExplainQueryPlan(pStmt);
                   5724:   /* This is needed on Windows so that a test case using this 
                   5725:   ** function can open a read pipe and get the output of
                   5726:   ** printExplainQueryPlan() immediately.
                   5727:   */
                   5728:   fflush(stdout);
                   5729:   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
                   5730:   return TCL_OK;
                   5731: }
                   5732: #endif /* SQLITE_OMIT_EXPLAIN */
                   5733: 
                   5734: /*
                   5735: ** sqlite3_test_control VERB ARGS...
                   5736: */
                   5737: static int test_test_control(
                   5738:   void * clientData,
                   5739:   Tcl_Interp *interp,
                   5740:   int objc,
                   5741:   Tcl_Obj *CONST objv[]
                   5742: ){
                   5743:   struct Verb {
                   5744:     const char *zName;
                   5745:     int i;
                   5746:   } aVerb[] = {
                   5747:     { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT }, 
                   5748:   };
                   5749:   int iVerb;
                   5750:   int iFlag;
                   5751:   int rc;
                   5752: 
                   5753:   if( objc<2 ){
                   5754:     Tcl_WrongNumArgs(interp, 1, objv, "VERB ARGS...");
                   5755:     return TCL_ERROR;
                   5756:   }
                   5757: 
                   5758:   rc = Tcl_GetIndexFromObjStruct(
                   5759:       interp, objv[1], aVerb, sizeof(aVerb[0]), "VERB", 0, &iVerb
                   5760:   );
                   5761:   if( rc!=TCL_OK ) return rc;
                   5762: 
                   5763:   iFlag = aVerb[iVerb].i;
                   5764:   switch( iFlag ){
                   5765:     case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
                   5766:       int val;
                   5767:       if( objc!=3 ){
                   5768:         Tcl_WrongNumArgs(interp, 2, objv, "ONOFF");
                   5769:         return TCL_ERROR;
                   5770:       }
                   5771:       if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
                   5772:       sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val);
                   5773:       break;
                   5774:     }
                   5775:   }
                   5776: 
                   5777:   Tcl_ResetResult(interp);
                   5778:   return TCL_OK;
                   5779: }
                   5780: 
                   5781: #if SQLITE_OS_WIN
                   5782: /*
                   5783: ** Information passed from the main thread into the windows file locker
                   5784: ** background thread.
                   5785: */
                   5786: struct win32FileLocker {
                   5787:   char *evName;       /* Name of event to signal thread startup */
                   5788:   HANDLE h;           /* Handle of the file to be locked */
                   5789:   int delay1;         /* Delay before locking */
                   5790:   int delay2;         /* Delay before unlocking */
                   5791:   int ok;             /* Finished ok */
                   5792:   int err;            /* True if an error occurs */
                   5793: };
                   5794: #endif
                   5795: 
                   5796: 
                   5797: #if SQLITE_OS_WIN
                   5798: /*
                   5799: ** The background thread that does file locking.
                   5800: */
                   5801: static void win32_file_locker(void *pAppData){
                   5802:   struct win32FileLocker *p = (struct win32FileLocker*)pAppData;
                   5803:   if( p->evName ){
                   5804:     HANDLE ev = OpenEvent(EVENT_MODIFY_STATE, FALSE, p->evName);
                   5805:     if ( ev ){
                   5806:       SetEvent(ev);
                   5807:       CloseHandle(ev);
                   5808:     }
                   5809:   }
                   5810:   if( p->delay1 ) Sleep(p->delay1);
                   5811:   if( LockFile(p->h, 0, 0, 100000000, 0) ){
                   5812:     Sleep(p->delay2);
                   5813:     UnlockFile(p->h, 0, 0, 100000000, 0);
                   5814:     p->ok = 1;
                   5815:   }else{
                   5816:     p->err = 1;
                   5817:   }
                   5818:   CloseHandle(p->h);
                   5819:   p->h = 0;
                   5820:   p->delay1 = 0;
                   5821:   p->delay2 = 0;
                   5822: }
                   5823: #endif
                   5824: 
                   5825: #if SQLITE_OS_WIN
                   5826: /*
                   5827: **      lock_win32_file FILENAME DELAY1 DELAY2
                   5828: **
                   5829: ** Get an exclusive manditory lock on file for DELAY2 milliseconds.
                   5830: ** Wait DELAY1 milliseconds before acquiring the lock.
                   5831: */
                   5832: static int win32_file_lock(
                   5833:   void * clientData,
                   5834:   Tcl_Interp *interp,
                   5835:   int objc,
                   5836:   Tcl_Obj *CONST objv[]
                   5837: ){
                   5838:   static struct win32FileLocker x = { "win32_file_lock", 0, 0, 0, 0, 0 };
                   5839:   const char *zFilename;
                   5840:   char zBuf[200];
                   5841:   int retry = 0;
                   5842:   HANDLE ev;
                   5843:   DWORD wResult;
                   5844:   
                   5845:   if( objc!=4 && objc!=1 ){
                   5846:     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME DELAY1 DELAY2");
                   5847:     return TCL_ERROR;
                   5848:   }
                   5849:   if( objc==1 ){
                   5850:     sqlite3_snprintf(sizeof(zBuf), zBuf, "%d %d %d %d %d",
                   5851:                      x.ok, x.err, x.delay1, x.delay2, x.h);
                   5852:     Tcl_AppendResult(interp, zBuf, (char*)0);
                   5853:     return TCL_OK;
                   5854:   }
                   5855:   while( x.h && retry<30 ){
                   5856:     retry++;
                   5857:     Sleep(100);
                   5858:   }
                   5859:   if( x.h ){
                   5860:     Tcl_AppendResult(interp, "busy", (char*)0);
                   5861:     return TCL_ERROR;
                   5862:   }
                   5863:   if( Tcl_GetIntFromObj(interp, objv[2], &x.delay1) ) return TCL_ERROR;
                   5864:   if( Tcl_GetIntFromObj(interp, objv[3], &x.delay2) ) return TCL_ERROR;
                   5865:   zFilename = Tcl_GetString(objv[1]);
                   5866:   x.h = CreateFile(zFilename, GENERIC_READ|GENERIC_WRITE,
                   5867:               FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
                   5868:               FILE_ATTRIBUTE_NORMAL, 0);
                   5869:   if( !x.h ){
                   5870:     Tcl_AppendResult(interp, "cannot open file: ", zFilename, (char*)0);
                   5871:     return TCL_ERROR;
                   5872:   }
                   5873:   ev = CreateEvent(NULL, TRUE, FALSE, x.evName);
                   5874:   if ( !ev ){
                   5875:     Tcl_AppendResult(interp, "cannot create event: ", x.evName, (char*)0);
                   5876:     return TCL_ERROR;
                   5877:   }
                   5878:   _beginthread(win32_file_locker, 0, (void*)&x);
                   5879:   Sleep(0);
                   5880:   if ( (wResult = WaitForSingleObject(ev, 10000))!=WAIT_OBJECT_0 ){
                   5881:     sqlite3_snprintf(sizeof(zBuf), zBuf, "0x%x", wResult);
                   5882:     Tcl_AppendResult(interp, "wait failed: ", zBuf, (char*)0);
                   5883:     CloseHandle(ev);
                   5884:     return TCL_ERROR;
                   5885:   }
                   5886:   CloseHandle(ev);
                   5887:   return TCL_OK;
                   5888: }
                   5889: #endif
                   5890: 
                   5891: 
                   5892: /*
                   5893: **      optimization_control DB OPT BOOLEAN
                   5894: **
                   5895: ** Enable or disable query optimizations using the sqlite3_test_control()
                   5896: ** interface.  Disable if BOOLEAN is false and enable if BOOLEAN is true.
                   5897: ** OPT is the name of the optimization to be disabled.
                   5898: */
                   5899: static int optimization_control(
                   5900:   void * clientData,
                   5901:   Tcl_Interp *interp,
                   5902:   int objc,
                   5903:   Tcl_Obj *CONST objv[]
                   5904: ){
                   5905:   int i;
                   5906:   sqlite3 *db;
                   5907:   const char *zOpt;
                   5908:   int onoff;
                   5909:   int mask;
                   5910:   static const struct {
                   5911:     const char *zOptName;
                   5912:     int mask;
                   5913:   } aOpt[] = {
                   5914:     { "all",              SQLITE_OptMask        },
                   5915:     { "query-flattener",  SQLITE_QueryFlattener },
                   5916:     { "column-cache",     SQLITE_ColumnCache    },
                   5917:     { "index-sort",       SQLITE_IndexSort      },
                   5918:     { "index-search",     SQLITE_IndexSearch    },
                   5919:     { "index-cover",      SQLITE_IndexCover     },
                   5920:     { "groupby-order",    SQLITE_GroupByOrder   },
                   5921:     { "factor-constants", SQLITE_FactorOutConst },
                   5922:     { "real-as-int",      SQLITE_IdxRealAsInt   },
                   5923:   };
                   5924: 
                   5925:   if( objc!=4 ){
                   5926:     Tcl_WrongNumArgs(interp, 1, objv, "DB OPT BOOLEAN");
                   5927:     return TCL_ERROR;
                   5928:   }
                   5929:   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
                   5930:   if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ) return TCL_ERROR;
                   5931:   zOpt = Tcl_GetString(objv[2]);
                   5932:   for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
                   5933:     if( strcmp(zOpt, aOpt[i].zOptName)==0 ){
                   5934:       mask = aOpt[i].mask;
                   5935:       break;
                   5936:     }
                   5937:   }
                   5938:   if( onoff ) mask = ~mask;
                   5939:   if( i>=sizeof(aOpt)/sizeof(aOpt[0]) ){
                   5940:     Tcl_AppendResult(interp, "unknown optimization - should be one of:",
                   5941:                      (char*)0);
                   5942:     for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
                   5943:       Tcl_AppendResult(interp, " ", aOpt[i].zOptName);
                   5944:     }
                   5945:     return TCL_ERROR;
                   5946:   }
                   5947:   sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask);
                   5948:   return TCL_OK;
                   5949: }
                   5950: 
                   5951: /*
                   5952: ** Register commands with the TCL interpreter.
                   5953: */
                   5954: int Sqlitetest1_Init(Tcl_Interp *interp){
                   5955:   extern int sqlite3_search_count;
                   5956:   extern int sqlite3_found_count;
                   5957:   extern int sqlite3_interrupt_count;
                   5958:   extern int sqlite3_open_file_count;
                   5959:   extern int sqlite3_sort_count;
                   5960:   extern int sqlite3_current_time;
                   5961: #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
                   5962:   extern int sqlite3_hostid_num;
                   5963: #endif
                   5964:   extern int sqlite3_max_blobsize;
                   5965:   extern int sqlite3BtreeSharedCacheReport(void*,
                   5966:                                           Tcl_Interp*,int,Tcl_Obj*CONST*);
                   5967:   static struct {
                   5968:      char *zName;
                   5969:      Tcl_CmdProc *xProc;
                   5970:   } aCmd[] = {
                   5971:      { "db_enter",                      (Tcl_CmdProc*)db_enter               },
                   5972:      { "db_leave",                      (Tcl_CmdProc*)db_leave               },
                   5973:      { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
                   5974:      { "sqlite3_mprintf_int64",         (Tcl_CmdProc*)sqlite3_mprintf_int64  },
                   5975:      { "sqlite3_mprintf_long",          (Tcl_CmdProc*)sqlite3_mprintf_long   },
                   5976:      { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
                   5977:      { "sqlite3_snprintf_str",          (Tcl_CmdProc*)sqlite3_snprintf_str   },
                   5978:      { "sqlite3_mprintf_stronly",       (Tcl_CmdProc*)sqlite3_mprintf_stronly},
                   5979:      { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
                   5980:      { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
                   5981:      { "sqlite3_mprintf_hexdouble",   (Tcl_CmdProc*)sqlite3_mprintf_hexdouble},
                   5982:      { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
                   5983:      { "sqlite3_mprintf_n_test",        (Tcl_CmdProc*)test_mprintf_n        },
                   5984:      { "sqlite3_snprintf_int",          (Tcl_CmdProc*)test_snprintf_int     },
                   5985:      { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
                   5986:      { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
                   5987:      { "sqlite3_exec_hex",              (Tcl_CmdProc*)test_exec_hex         },
                   5988:      { "sqlite3_exec",                  (Tcl_CmdProc*)test_exec             },
                   5989:      { "sqlite3_exec_nr",               (Tcl_CmdProc*)test_exec_nr          },
                   5990: #ifndef SQLITE_OMIT_GET_TABLE
                   5991:      { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
                   5992: #endif
                   5993:      { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
                   5994:      { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
                   5995:      { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
                   5996:      { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
                   5997:      { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
                   5998:      { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
                   5999:      { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
                   6000:      { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
                   6001:      { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
                   6002:      { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },
                   6003:      { "sqlite3_interrupt",             (Tcl_CmdProc*)test_interrupt        },
                   6004:      { "sqlite_delete_function",        (Tcl_CmdProc*)delete_function       },
                   6005:      { "sqlite_delete_collation",       (Tcl_CmdProc*)delete_collation      },
                   6006:      { "sqlite3_get_autocommit",        (Tcl_CmdProc*)get_autocommit        },
                   6007:      { "sqlite3_stack_used",            (Tcl_CmdProc*)test_stack_used       },
                   6008:      { "sqlite3_busy_timeout",          (Tcl_CmdProc*)test_busy_timeout     },
                   6009:      { "printf",                        (Tcl_CmdProc*)test_printf           },
                   6010:      { "sqlite3IoTrace",              (Tcl_CmdProc*)test_io_trace         },
                   6011:   };
                   6012:   static struct {
                   6013:      char *zName;
                   6014:      Tcl_ObjCmdProc *xProc;
                   6015:      void *clientData;
                   6016:   } aObjCmd[] = {
                   6017:      { "sqlite3_connection_pointer",    get_sqlite_pointer, 0 },
                   6018:      { "sqlite3_bind_int",              test_bind_int,      0 },
                   6019:      { "sqlite3_bind_zeroblob",         test_bind_zeroblob, 0 },
                   6020:      { "sqlite3_bind_int64",            test_bind_int64,    0 },
                   6021:      { "sqlite3_bind_double",           test_bind_double,   0 },
                   6022:      { "sqlite3_bind_null",             test_bind_null     ,0 },
                   6023:      { "sqlite3_bind_text",             test_bind_text     ,0 },
                   6024:      { "sqlite3_bind_text16",           test_bind_text16   ,0 },
                   6025:      { "sqlite3_bind_blob",             test_bind_blob     ,0 },
                   6026:      { "sqlite3_bind_parameter_count",  test_bind_parameter_count, 0},
                   6027:      { "sqlite3_bind_parameter_name",   test_bind_parameter_name,  0},
                   6028:      { "sqlite3_bind_parameter_index",  test_bind_parameter_index, 0},
                   6029:      { "sqlite3_clear_bindings",        test_clear_bindings, 0},
                   6030:      { "sqlite3_sleep",                 test_sleep,          0},
                   6031:      { "sqlite3_errcode",               test_errcode       ,0 },
                   6032:      { "sqlite3_extended_errcode",      test_ex_errcode    ,0 },
                   6033:      { "sqlite3_errmsg",                test_errmsg        ,0 },
                   6034:      { "sqlite3_errmsg16",              test_errmsg16      ,0 },
                   6035:      { "sqlite3_open",                  test_open          ,0 },
                   6036:      { "sqlite3_open16",                test_open16        ,0 },
                   6037:      { "sqlite3_open_v2",               test_open_v2       ,0 },
                   6038:      { "sqlite3_complete16",            test_complete16    ,0 },
                   6039: 
                   6040:      { "sqlite3_prepare",               test_prepare       ,0 },
                   6041:      { "sqlite3_prepare16",             test_prepare16     ,0 },
                   6042:      { "sqlite3_prepare_v2",            test_prepare_v2    ,0 },
                   6043:      { "sqlite3_prepare_tkt3134",       test_prepare_tkt3134, 0},
                   6044:      { "sqlite3_prepare16_v2",          test_prepare16_v2  ,0 },
                   6045:      { "sqlite3_finalize",              test_finalize      ,0 },
                   6046:      { "sqlite3_stmt_status",           test_stmt_status   ,0 },
                   6047:      { "sqlite3_reset",                 test_reset         ,0 },
                   6048:      { "sqlite3_expired",               test_expired       ,0 },
                   6049:      { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
                   6050:      { "sqlite3_changes",               test_changes       ,0 },
                   6051:      { "sqlite3_step",                  test_step          ,0 },
                   6052:      { "sqlite3_sql",                   test_sql           ,0 },
                   6053:      { "sqlite3_next_stmt",             test_next_stmt     ,0 },
                   6054:      { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },
                   6055:      { "sqlite3_stmt_busy",             test_stmt_busy     ,0 },
                   6056:      { "uses_stmt_journal",             uses_stmt_journal ,0 },
                   6057: 
                   6058:      { "sqlite3_release_memory",        test_release_memory,     0},
                   6059:      { "sqlite3_db_release_memory",     test_db_release_memory,  0},
                   6060:      { "sqlite3_db_filename",           test_db_filename,        0},
                   6061:      { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
                   6062:      { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
                   6063:      { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},
                   6064: 
                   6065:      { "sqlite3_load_extension",        test_load_extension,     0},
                   6066:      { "sqlite3_enable_load_extension", test_enable_load,        0},
                   6067:      { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
                   6068:      { "sqlite3_limit",                 test_limit,                 0},
                   6069: 
                   6070:      { "save_prng_state",               save_prng_state,    0 },
                   6071:      { "restore_prng_state",            restore_prng_state, 0 },
                   6072:      { "reset_prng_state",              reset_prng_state,   0 },
                   6073:      { "optimization_control",          optimization_control,0},
                   6074: #if SQLITE_OS_WIN
                   6075:      { "lock_win32_file",               win32_file_lock,    0 },
                   6076: #endif
                   6077:      { "tcl_objproc",                   runAsObjProc,       0 },
                   6078: 
                   6079:      /* sqlite3_column_*() API */
                   6080:      { "sqlite3_column_count",          test_column_count  ,0 },
                   6081:      { "sqlite3_data_count",            test_data_count    ,0 },
                   6082:      { "sqlite3_column_type",           test_column_type   ,0 },
                   6083:      { "sqlite3_column_blob",           test_column_blob   ,0 },
                   6084:      { "sqlite3_column_double",         test_column_double ,0 },
                   6085:      { "sqlite3_column_int64",          test_column_int64  ,0 },
                   6086:      { "sqlite3_column_text",   test_stmt_utf8,  (void*)sqlite3_column_text },
                   6087:      { "sqlite3_column_name",   test_stmt_utf8,  (void*)sqlite3_column_name },
                   6088:      { "sqlite3_column_int",    test_stmt_int,   (void*)sqlite3_column_int  },
                   6089:      { "sqlite3_column_bytes",  test_stmt_int,   (void*)sqlite3_column_bytes},
                   6090: #ifndef SQLITE_OMIT_DECLTYPE
                   6091:      { "sqlite3_column_decltype",test_stmt_utf8,(void*)sqlite3_column_decltype},
                   6092: #endif
                   6093: #ifdef SQLITE_ENABLE_COLUMN_METADATA
                   6094: { "sqlite3_column_database_name",test_stmt_utf8,(void*)sqlite3_column_database_name},
                   6095: { "sqlite3_column_table_name",test_stmt_utf8,(void*)sqlite3_column_table_name},
                   6096: { "sqlite3_column_origin_name",test_stmt_utf8,(void*)sqlite3_column_origin_name},
                   6097: #endif
                   6098: 
                   6099: #ifndef SQLITE_OMIT_UTF16
                   6100:      { "sqlite3_column_bytes16", test_stmt_int, (void*)sqlite3_column_bytes16 },
                   6101:      { "sqlite3_column_text16",  test_stmt_utf16, (void*)sqlite3_column_text16},
                   6102:      { "sqlite3_column_name16",  test_stmt_utf16, (void*)sqlite3_column_name16},
                   6103:      { "add_alignment_test_collations", add_alignment_test_collations, 0      },
                   6104: #ifndef SQLITE_OMIT_DECLTYPE
                   6105:      { "sqlite3_column_decltype16",test_stmt_utf16,(void*)sqlite3_column_decltype16},
                   6106: #endif
                   6107: #ifdef SQLITE_ENABLE_COLUMN_METADATA
                   6108: {"sqlite3_column_database_name16",
                   6109:   test_stmt_utf16, sqlite3_column_database_name16},
                   6110: {"sqlite3_column_table_name16", test_stmt_utf16, (void*)sqlite3_column_table_name16},
                   6111: {"sqlite3_column_origin_name16", test_stmt_utf16, (void*)sqlite3_column_origin_name16},
                   6112: #endif
                   6113: #endif
                   6114:      { "sqlite3_create_collation_v2", test_create_collation_v2, 0 },
                   6115:      { "sqlite3_global_recover",     test_global_recover, 0   },
                   6116:      { "working_64bit_int",          working_64bit_int,   0   },
                   6117:      { "vfs_unlink_test",            vfs_unlink_test,     0   },
                   6118:      { "vfs_initfail_test",          vfs_initfail_test,   0   },
                   6119:      { "vfs_unregister_all",         vfs_unregister_all,  0   },
                   6120:      { "vfs_reregister_all",         vfs_reregister_all,  0   },
                   6121:      { "file_control_test",          file_control_test,   0   },
                   6122:      { "file_control_lasterrno_test", file_control_lasterrno_test,  0   },
                   6123:      { "file_control_lockproxy_test", file_control_lockproxy_test,  0   },
                   6124:      { "file_control_chunksize_test", file_control_chunksize_test,  0   },
                   6125:      { "file_control_sizehint_test",  file_control_sizehint_test,   0   },
                   6126:      { "file_control_win32_av_retry", file_control_win32_av_retry,  0   },
                   6127:      { "file_control_persist_wal",    file_control_persist_wal,     0   },
                   6128:      { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
                   6129:      { "file_control_vfsname",        file_control_vfsname,         0   },
                   6130:      { "sqlite3_vfs_list",           vfs_list,     0   },
                   6131:      { "sqlite3_create_function_v2", test_create_function_v2, 0 },
                   6132: 
                   6133:      /* Functions from os.h */
                   6134: #ifndef SQLITE_OMIT_UTF16
                   6135:      { "add_test_collate",        test_collate, 0            },
                   6136:      { "add_test_collate_needed", test_collate_needed, 0     },
                   6137:      { "add_test_function",       test_function, 0           },
                   6138: #endif
                   6139:      { "sqlite3_test_errstr",     test_errstr, 0             },
                   6140:      { "tcl_variable_type",       tcl_variable_type, 0       },
                   6141: #ifndef SQLITE_OMIT_SHARED_CACHE
                   6142:      { "sqlite3_enable_shared_cache", test_enable_shared, 0  },
                   6143:      { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0},
                   6144: #endif
                   6145:      { "sqlite3_libversion_number", test_libversion_number, 0  },
                   6146: #ifdef SQLITE_ENABLE_COLUMN_METADATA
                   6147:      { "sqlite3_table_column_metadata", test_table_column_metadata, 0  },
                   6148: #endif
                   6149: #ifndef SQLITE_OMIT_INCRBLOB
                   6150:      { "sqlite3_blob_read",   test_blob_read, 0  },
                   6151:      { "sqlite3_blob_write",  test_blob_write, 0  },
                   6152:      { "sqlite3_blob_reopen", test_blob_reopen, 0  },
                   6153:      { "sqlite3_blob_bytes",  test_blob_bytes, 0  },
                   6154:      { "sqlite3_blob_close",  test_blob_close, 0  },
                   6155: #endif
                   6156:      { "pcache_stats",       test_pcache_stats, 0  },
                   6157: #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
                   6158:      { "sqlite3_unlock_notify", test_unlock_notify, 0  },
                   6159: #endif
                   6160:      { "sqlite3_wal_checkpoint",   test_wal_checkpoint, 0  },
                   6161:      { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0  },
                   6162:      { "test_sqlite3_log",         test_sqlite3_log, 0  },
                   6163: #ifndef SQLITE_OMIT_EXPLAIN
                   6164:      { "print_explain_query_plan", test_print_eqp, 0  },
                   6165: #endif
                   6166:      { "sqlite3_test_control", test_test_control },
                   6167:   };
                   6168:   static int bitmask_size = sizeof(Bitmask)*8;
                   6169:   int i;
                   6170:   extern int sqlite3_sync_count, sqlite3_fullsync_count;
                   6171:   extern int sqlite3_opentemp_count;
                   6172:   extern int sqlite3_like_count;
                   6173:   extern int sqlite3_xferopt_count;
                   6174:   extern int sqlite3_pager_readdb_count;
                   6175:   extern int sqlite3_pager_writedb_count;
                   6176:   extern int sqlite3_pager_writej_count;
                   6177: #if SQLITE_OS_WIN
                   6178:   extern int sqlite3_os_type;
                   6179: #endif
                   6180: #ifdef SQLITE_DEBUG
                   6181:   extern int sqlite3WhereTrace;
                   6182:   extern int sqlite3OSTrace;
                   6183:   extern int sqlite3VdbeAddopTrace;
                   6184:   extern int sqlite3WalTrace;
                   6185: #endif
                   6186: #ifdef SQLITE_TEST
                   6187:   extern char sqlite3_query_plan[];
                   6188:   static char *query_plan = sqlite3_query_plan;
                   6189: #ifdef SQLITE_ENABLE_FTS3
                   6190:   extern int sqlite3_fts3_enable_parentheses;
                   6191: #endif
                   6192: #endif
                   6193: 
                   6194:   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
                   6195:     Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
                   6196:   }
                   6197:   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
                   6198:     Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
                   6199:         aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
                   6200:   }
                   6201:   Tcl_LinkVar(interp, "sqlite_search_count", 
                   6202:       (char*)&sqlite3_search_count, TCL_LINK_INT);
                   6203:   Tcl_LinkVar(interp, "sqlite_found_count", 
                   6204:       (char*)&sqlite3_found_count, TCL_LINK_INT);
                   6205:   Tcl_LinkVar(interp, "sqlite_sort_count", 
                   6206:       (char*)&sqlite3_sort_count, TCL_LINK_INT);
                   6207:   Tcl_LinkVar(interp, "sqlite3_max_blobsize", 
                   6208:       (char*)&sqlite3_max_blobsize, TCL_LINK_INT);
                   6209:   Tcl_LinkVar(interp, "sqlite_like_count", 
                   6210:       (char*)&sqlite3_like_count, TCL_LINK_INT);
                   6211:   Tcl_LinkVar(interp, "sqlite_interrupt_count", 
                   6212:       (char*)&sqlite3_interrupt_count, TCL_LINK_INT);
                   6213:   Tcl_LinkVar(interp, "sqlite_open_file_count", 
                   6214:       (char*)&sqlite3_open_file_count, TCL_LINK_INT);
                   6215:   Tcl_LinkVar(interp, "sqlite_current_time", 
                   6216:       (char*)&sqlite3_current_time, TCL_LINK_INT);
                   6217: #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
                   6218:   Tcl_LinkVar(interp, "sqlite_hostid_num", 
                   6219:       (char*)&sqlite3_hostid_num, TCL_LINK_INT);
                   6220: #endif
                   6221:   Tcl_LinkVar(interp, "sqlite3_xferopt_count",
                   6222:       (char*)&sqlite3_xferopt_count, TCL_LINK_INT);
                   6223:   Tcl_LinkVar(interp, "sqlite3_pager_readdb_count",
                   6224:       (char*)&sqlite3_pager_readdb_count, TCL_LINK_INT);
                   6225:   Tcl_LinkVar(interp, "sqlite3_pager_writedb_count",
                   6226:       (char*)&sqlite3_pager_writedb_count, TCL_LINK_INT);
                   6227:   Tcl_LinkVar(interp, "sqlite3_pager_writej_count",
                   6228:       (char*)&sqlite3_pager_writej_count, TCL_LINK_INT);
                   6229: #ifndef SQLITE_OMIT_UTF16
                   6230:   Tcl_LinkVar(interp, "unaligned_string_counter",
                   6231:       (char*)&unaligned_string_counter, TCL_LINK_INT);
                   6232: #endif
                   6233: #ifndef SQLITE_OMIT_UTF16
                   6234:   Tcl_LinkVar(interp, "sqlite_last_needed_collation",
                   6235:       (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
                   6236: #endif
                   6237: #if SQLITE_OS_WIN
                   6238:   Tcl_LinkVar(interp, "sqlite_os_type",
                   6239:       (char*)&sqlite3_os_type, TCL_LINK_INT);
                   6240: #endif
                   6241: #ifdef SQLITE_TEST
                   6242:   Tcl_LinkVar(interp, "sqlite_query_plan",
                   6243:       (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
                   6244: #endif
                   6245: #ifdef SQLITE_DEBUG
                   6246:   Tcl_LinkVar(interp, "sqlite_addop_trace",
                   6247:       (char*)&sqlite3VdbeAddopTrace, TCL_LINK_INT);
                   6248:   Tcl_LinkVar(interp, "sqlite_where_trace",
                   6249:       (char*)&sqlite3WhereTrace, TCL_LINK_INT);
                   6250:   Tcl_LinkVar(interp, "sqlite_os_trace",
                   6251:       (char*)&sqlite3OSTrace, TCL_LINK_INT);
                   6252: #ifndef SQLITE_OMIT_WAL
                   6253:   Tcl_LinkVar(interp, "sqlite_wal_trace",
                   6254:       (char*)&sqlite3WalTrace, TCL_LINK_INT);
                   6255: #endif
                   6256: #endif
                   6257: #ifndef SQLITE_OMIT_DISKIO
                   6258:   Tcl_LinkVar(interp, "sqlite_opentemp_count",
                   6259:       (char*)&sqlite3_opentemp_count, TCL_LINK_INT);
                   6260: #endif
                   6261:   Tcl_LinkVar(interp, "sqlite_static_bind_value",
                   6262:       (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
                   6263:   Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",
                   6264:       (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT);
                   6265:   Tcl_LinkVar(interp, "sqlite_temp_directory",
                   6266:       (char*)&sqlite3_temp_directory, TCL_LINK_STRING);
                   6267:   Tcl_LinkVar(interp, "bitmask_size",
                   6268:       (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
                   6269:   Tcl_LinkVar(interp, "sqlite_sync_count",
                   6270:       (char*)&sqlite3_sync_count, TCL_LINK_INT);
                   6271:   Tcl_LinkVar(interp, "sqlite_fullsync_count",
                   6272:       (char*)&sqlite3_fullsync_count, TCL_LINK_INT);
                   6273: #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
                   6274:   Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses",
                   6275:       (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT);
                   6276: #endif
                   6277:   return TCL_OK;
                   6278: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>