000001 /*
000002 ** 2001 September 15
000003 **
000004 ** The author disclaims copyright to this source code. In place of
000005 ** a legal notice, here is a blessing:
000006 **
000007 ** May you do good and not evil.
000008 ** May you find forgiveness for yourself and forgive others.
000009 ** May you share freely, never taking more than you give.
000010 **
000011 *************************************************************************
000012 ** A TCL Interface to SQLite. Append this file to sqlite3.c and
000013 ** compile the whole thing to build a TCL-enabled version of SQLite.
000014 **
000015 ** Compile-time options:
000016 **
000017 ** -DTCLSH Add a "main()" routine that works as a tclsh.
000018 **
000019 ** -DTCLSH_INIT_PROC=name
000020 **
000021 ** Invoke name(interp) to initialize the Tcl interpreter.
000022 ** If name(interp) returns a non-NULL string, then run
000023 ** that string as a Tcl script to launch the application.
000024 ** If name(interp) returns NULL, then run the regular
000025 ** tclsh-emulator code.
000026 */
000027 #ifdef TCLSH_INIT_PROC
000028 # define TCLSH 1
000029 #endif
000030
000031 /*
000032 ** If requested, include the SQLite compiler options file for MSVC.
000033 */
000034 #if defined(INCLUDE_MSVC_H)
000035 # include "msvc.h"
000036 #endif
000037
000038 #if defined(INCLUDE_SQLITE_TCL_H)
000039 # include "sqlite_tcl.h"
000040 #else
000041 # include "tcl.h"
000042 # ifndef SQLITE_TCLAPI
000043 # define SQLITE_TCLAPI
000044 # endif
000045 #endif
000046 #include <errno.h>
000047
000048 /*
000049 ** Some additional include files are needed if this file is not
000050 ** appended to the amalgamation.
000051 */
000052 #ifndef SQLITE_AMALGAMATION
000053 # include "sqlite3.h"
000054 # include <stdlib.h>
000055 # include <string.h>
000056 # include <assert.h>
000057 typedef unsigned char u8;
000058 #endif
000059 #include <ctype.h>
000060
000061 /* Used to get the current process ID */
000062 #if !defined(_WIN32)
000063 # include <signal.h>
000064 # include <unistd.h>
000065 # define GETPID getpid
000066 #elif !defined(_WIN32_WCE)
000067 # ifndef SQLITE_AMALGAMATION
000068 # ifndef WIN32_LEAN_AND_MEAN
000069 # define WIN32_LEAN_AND_MEAN
000070 # endif
000071 # include <windows.h>
000072 # endif
000073 # include <io.h>
000074 # define isatty(h) _isatty(h)
000075 # define GETPID (int)GetCurrentProcessId
000076 #endif
000077
000078 /*
000079 * Windows needs to know which symbols to export. Unix does not.
000080 * BUILD_sqlite should be undefined for Unix.
000081 */
000082 #ifdef BUILD_sqlite
000083 #undef TCL_STORAGE_CLASS
000084 #define TCL_STORAGE_CLASS DLLEXPORT
000085 #endif /* BUILD_sqlite */
000086
000087 #define NUM_PREPARED_STMTS 10
000088 #define MAX_PREPARED_STMTS 100
000089
000090 /* Forward declaration */
000091 typedef struct SqliteDb SqliteDb;
000092
000093 /*
000094 ** New SQL functions can be created as TCL scripts. Each such function
000095 ** is described by an instance of the following structure.
000096 **
000097 ** Variable eType may be set to SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT,
000098 ** SQLITE_BLOB or SQLITE_NULL. If it is SQLITE_NULL, then the implementation
000099 ** attempts to determine the type of the result based on the Tcl object.
000100 ** If it is SQLITE_TEXT or SQLITE_BLOB, then a text (sqlite3_result_text())
000101 ** or blob (sqlite3_result_blob()) is returned. If it is SQLITE_INTEGER
000102 ** or SQLITE_FLOAT, then an attempt is made to return an integer or float
000103 ** value, falling back to float and then text if this is not possible.
000104 */
000105 typedef struct SqlFunc SqlFunc;
000106 struct SqlFunc {
000107 Tcl_Interp *interp; /* The TCL interpret to execute the function */
000108 Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
000109 SqliteDb *pDb; /* Database connection that owns this function */
000110 int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
000111 int eType; /* Type of value to return */
000112 char *zName; /* Name of this function */
000113 SqlFunc *pNext; /* Next function on the list of them all */
000114 };
000115
000116 /*
000117 ** New collation sequences function can be created as TCL scripts. Each such
000118 ** function is described by an instance of the following structure.
000119 */
000120 typedef struct SqlCollate SqlCollate;
000121 struct SqlCollate {
000122 Tcl_Interp *interp; /* The TCL interpret to execute the function */
000123 char *zScript; /* The script to be run */
000124 SqlCollate *pNext; /* Next function on the list of them all */
000125 };
000126
000127 /*
000128 ** Prepared statements are cached for faster execution. Each prepared
000129 ** statement is described by an instance of the following structure.
000130 */
000131 typedef struct SqlPreparedStmt SqlPreparedStmt;
000132 struct SqlPreparedStmt {
000133 SqlPreparedStmt *pNext; /* Next in linked list */
000134 SqlPreparedStmt *pPrev; /* Previous on the list */
000135 sqlite3_stmt *pStmt; /* The prepared statement */
000136 int nSql; /* chars in zSql[] */
000137 const char *zSql; /* Text of the SQL statement */
000138 int nParm; /* Size of apParm array */
000139 Tcl_Obj **apParm; /* Array of referenced object pointers */
000140 };
000141
000142 typedef struct IncrblobChannel IncrblobChannel;
000143
000144 /*
000145 ** There is one instance of this structure for each SQLite database
000146 ** that has been opened by the SQLite TCL interface.
000147 **
000148 ** If this module is built with SQLITE_TEST defined (to create the SQLite
000149 ** testfixture executable), then it may be configured to use either
000150 ** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
000151 ** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
000152 */
000153 struct SqliteDb {
000154 sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
000155 Tcl_Interp *interp; /* The interpreter used for this database */
000156 char *zBusy; /* The busy callback routine */
000157 char *zCommit; /* The commit hook callback routine */
000158 char *zTrace; /* The trace callback routine */
000159 char *zTraceV2; /* The trace_v2 callback routine */
000160 char *zProfile; /* The profile callback routine */
000161 char *zProgress; /* The progress callback routine */
000162 char *zBindFallback; /* Callback to invoke on a binding miss */
000163 char *zAuth; /* The authorization callback routine */
000164 int disableAuth; /* Disable the authorizer if it exists */
000165 char *zNull; /* Text to substitute for an SQL NULL value */
000166 SqlFunc *pFunc; /* List of SQL functions */
000167 Tcl_Obj *pUpdateHook; /* Update hook script (if any) */
000168 Tcl_Obj *pPreUpdateHook; /* Pre-update hook script (if any) */
000169 Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */
000170 Tcl_Obj *pWalHook; /* WAL hook script (if any) */
000171 Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */
000172 SqlCollate *pCollate; /* List of SQL collation functions */
000173 int rc; /* Return code of most recent sqlite3_exec() */
000174 Tcl_Obj *pCollateNeeded; /* Collation needed script */
000175 SqlPreparedStmt *stmtList; /* List of prepared statements*/
000176 SqlPreparedStmt *stmtLast; /* Last statement in the list */
000177 int maxStmt; /* The next maximum number of stmtList */
000178 int nStmt; /* Number of statements in stmtList */
000179 IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
000180 int nStep, nSort, nIndex; /* Statistics for most recent operation */
000181 int nVMStep; /* Another statistic for most recent operation */
000182 int nTransaction; /* Number of nested [transaction] methods */
000183 int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */
000184 #ifdef SQLITE_TEST
000185 int bLegacyPrepare; /* True to use sqlite3_prepare() */
000186 #endif
000187 };
000188
000189 struct IncrblobChannel {
000190 sqlite3_blob *pBlob; /* sqlite3 blob handle */
000191 SqliteDb *pDb; /* Associated database connection */
000192 int iSeek; /* Current seek offset */
000193 Tcl_Channel channel; /* Channel identifier */
000194 IncrblobChannel *pNext; /* Linked list of all open incrblob channels */
000195 IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */
000196 };
000197
000198 /*
000199 ** Compute a string length that is limited to what can be stored in
000200 ** lower 30 bits of a 32-bit signed integer.
000201 */
000202 static int strlen30(const char *z){
000203 const char *z2 = z;
000204 while( *z2 ){ z2++; }
000205 return 0x3fffffff & (int)(z2 - z);
000206 }
000207
000208
000209 #ifndef SQLITE_OMIT_INCRBLOB
000210 /*
000211 ** Close all incrblob channels opened using database connection pDb.
000212 ** This is called when shutting down the database connection.
000213 */
000214 static void closeIncrblobChannels(SqliteDb *pDb){
000215 IncrblobChannel *p;
000216 IncrblobChannel *pNext;
000217
000218 for(p=pDb->pIncrblob; p; p=pNext){
000219 pNext = p->pNext;
000220
000221 /* Note: Calling unregister here call Tcl_Close on the incrblob channel,
000222 ** which deletes the IncrblobChannel structure at *p. So do not
000223 ** call Tcl_Free() here.
000224 */
000225 Tcl_UnregisterChannel(pDb->interp, p->channel);
000226 }
000227 }
000228
000229 /*
000230 ** Close an incremental blob channel.
000231 */
000232 static int SQLITE_TCLAPI incrblobClose(
000233 ClientData instanceData,
000234 Tcl_Interp *interp
000235 ){
000236 IncrblobChannel *p = (IncrblobChannel *)instanceData;
000237 int rc = sqlite3_blob_close(p->pBlob);
000238 sqlite3 *db = p->pDb->db;
000239
000240 /* Remove the channel from the SqliteDb.pIncrblob list. */
000241 if( p->pNext ){
000242 p->pNext->pPrev = p->pPrev;
000243 }
000244 if( p->pPrev ){
000245 p->pPrev->pNext = p->pNext;
000246 }
000247 if( p->pDb->pIncrblob==p ){
000248 p->pDb->pIncrblob = p->pNext;
000249 }
000250
000251 /* Free the IncrblobChannel structure */
000252 Tcl_Free((char *)p);
000253
000254 if( rc!=SQLITE_OK ){
000255 Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
000256 return TCL_ERROR;
000257 }
000258 return TCL_OK;
000259 }
000260
000261 /*
000262 ** Read data from an incremental blob channel.
000263 */
000264 static int SQLITE_TCLAPI incrblobInput(
000265 ClientData instanceData,
000266 char *buf,
000267 int bufSize,
000268 int *errorCodePtr
000269 ){
000270 IncrblobChannel *p = (IncrblobChannel *)instanceData;
000271 int nRead = bufSize; /* Number of bytes to read */
000272 int nBlob; /* Total size of the blob */
000273 int rc; /* sqlite error code */
000274
000275 nBlob = sqlite3_blob_bytes(p->pBlob);
000276 if( (p->iSeek+nRead)>nBlob ){
000277 nRead = nBlob-p->iSeek;
000278 }
000279 if( nRead<=0 ){
000280 return 0;
000281 }
000282
000283 rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek);
000284 if( rc!=SQLITE_OK ){
000285 *errorCodePtr = rc;
000286 return -1;
000287 }
000288
000289 p->iSeek += nRead;
000290 return nRead;
000291 }
000292
000293 /*
000294 ** Write data to an incremental blob channel.
000295 */
000296 static int SQLITE_TCLAPI incrblobOutput(
000297 ClientData instanceData,
000298 CONST char *buf,
000299 int toWrite,
000300 int *errorCodePtr
000301 ){
000302 IncrblobChannel *p = (IncrblobChannel *)instanceData;
000303 int nWrite = toWrite; /* Number of bytes to write */
000304 int nBlob; /* Total size of the blob */
000305 int rc; /* sqlite error code */
000306
000307 nBlob = sqlite3_blob_bytes(p->pBlob);
000308 if( (p->iSeek+nWrite)>nBlob ){
000309 *errorCodePtr = EINVAL;
000310 return -1;
000311 }
000312 if( nWrite<=0 ){
000313 return 0;
000314 }
000315
000316 rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek);
000317 if( rc!=SQLITE_OK ){
000318 *errorCodePtr = EIO;
000319 return -1;
000320 }
000321
000322 p->iSeek += nWrite;
000323 return nWrite;
000324 }
000325
000326 /*
000327 ** Seek an incremental blob channel.
000328 */
000329 static int SQLITE_TCLAPI incrblobSeek(
000330 ClientData instanceData,
000331 long offset,
000332 int seekMode,
000333 int *errorCodePtr
000334 ){
000335 IncrblobChannel *p = (IncrblobChannel *)instanceData;
000336
000337 switch( seekMode ){
000338 case SEEK_SET:
000339 p->iSeek = offset;
000340 break;
000341 case SEEK_CUR:
000342 p->iSeek += offset;
000343 break;
000344 case SEEK_END:
000345 p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset;
000346 break;
000347
000348 default: assert(!"Bad seekMode");
000349 }
000350
000351 return p->iSeek;
000352 }
000353
000354
000355 static void SQLITE_TCLAPI incrblobWatch(
000356 ClientData instanceData,
000357 int mode
000358 ){
000359 /* NO-OP */
000360 }
000361 static int SQLITE_TCLAPI incrblobHandle(
000362 ClientData instanceData,
000363 int dir,
000364 ClientData *hPtr
000365 ){
000366 return TCL_ERROR;
000367 }
000368
000369 static Tcl_ChannelType IncrblobChannelType = {
000370 "incrblob", /* typeName */
000371 TCL_CHANNEL_VERSION_2, /* version */
000372 incrblobClose, /* closeProc */
000373 incrblobInput, /* inputProc */
000374 incrblobOutput, /* outputProc */
000375 incrblobSeek, /* seekProc */
000376 0, /* setOptionProc */
000377 0, /* getOptionProc */
000378 incrblobWatch, /* watchProc (this is a no-op) */
000379 incrblobHandle, /* getHandleProc (always returns error) */
000380 0, /* close2Proc */
000381 0, /* blockModeProc */
000382 0, /* flushProc */
000383 0, /* handlerProc */
000384 0, /* wideSeekProc */
000385 };
000386
000387 /*
000388 ** Create a new incrblob channel.
000389 */
000390 static int createIncrblobChannel(
000391 Tcl_Interp *interp,
000392 SqliteDb *pDb,
000393 const char *zDb,
000394 const char *zTable,
000395 const char *zColumn,
000396 sqlite_int64 iRow,
000397 int isReadonly
000398 ){
000399 IncrblobChannel *p;
000400 sqlite3 *db = pDb->db;
000401 sqlite3_blob *pBlob;
000402 int rc;
000403 int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE);
000404
000405 /* This variable is used to name the channels: "incrblob_[incr count]" */
000406 static int count = 0;
000407 char zChannel[64];
000408
000409 rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob);
000410 if( rc!=SQLITE_OK ){
000411 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
000412 return TCL_ERROR;
000413 }
000414
000415 p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel));
000416 p->iSeek = 0;
000417 p->pBlob = pBlob;
000418
000419 sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count);
000420 p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags);
000421 Tcl_RegisterChannel(interp, p->channel);
000422
000423 /* Link the new channel into the SqliteDb.pIncrblob list. */
000424 p->pNext = pDb->pIncrblob;
000425 p->pPrev = 0;
000426 if( p->pNext ){
000427 p->pNext->pPrev = p;
000428 }
000429 pDb->pIncrblob = p;
000430 p->pDb = pDb;
000431
000432 Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE);
000433 return TCL_OK;
000434 }
000435 #else /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */
000436 #define closeIncrblobChannels(pDb)
000437 #endif
000438
000439 /*
000440 ** Look at the script prefix in pCmd. We will be executing this script
000441 ** after first appending one or more arguments. This routine analyzes
000442 ** the script to see if it is safe to use Tcl_EvalObjv() on the script
000443 ** rather than the more general Tcl_EvalEx(). Tcl_EvalObjv() is much
000444 ** faster.
000445 **
000446 ** Scripts that are safe to use with Tcl_EvalObjv() consists of a
000447 ** command name followed by zero or more arguments with no [...] or $
000448 ** or {...} or ; to be seen anywhere. Most callback scripts consist
000449 ** of just a single procedure name and they meet this requirement.
000450 */
000451 static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
000452 /* We could try to do something with Tcl_Parse(). But we will instead
000453 ** just do a search for forbidden characters. If any of the forbidden
000454 ** characters appear in pCmd, we will report the string as unsafe.
000455 */
000456 const char *z;
000457 int n;
000458 z = Tcl_GetStringFromObj(pCmd, &n);
000459 while( n-- > 0 ){
000460 int c = *(z++);
000461 if( c=='$' || c=='[' || c==';' ) return 0;
000462 }
000463 return 1;
000464 }
000465
000466 /*
000467 ** Find an SqlFunc structure with the given name. Or create a new
000468 ** one if an existing one cannot be found. Return a pointer to the
000469 ** structure.
000470 */
000471 static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
000472 SqlFunc *p, *pNew;
000473 int nName = strlen30(zName);
000474 pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 );
000475 pNew->zName = (char*)&pNew[1];
000476 memcpy(pNew->zName, zName, nName+1);
000477 for(p=pDb->pFunc; p; p=p->pNext){
000478 if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){
000479 Tcl_Free((char*)pNew);
000480 return p;
000481 }
000482 }
000483 pNew->interp = pDb->interp;
000484 pNew->pDb = pDb;
000485 pNew->pScript = 0;
000486 pNew->pNext = pDb->pFunc;
000487 pDb->pFunc = pNew;
000488 return pNew;
000489 }
000490
000491 /*
000492 ** Free a single SqlPreparedStmt object.
000493 */
000494 static void dbFreeStmt(SqlPreparedStmt *pStmt){
000495 #ifdef SQLITE_TEST
000496 if( sqlite3_sql(pStmt->pStmt)==0 ){
000497 Tcl_Free((char *)pStmt->zSql);
000498 }
000499 #endif
000500 sqlite3_finalize(pStmt->pStmt);
000501 Tcl_Free((char *)pStmt);
000502 }
000503
000504 /*
000505 ** Finalize and free a list of prepared statements
000506 */
000507 static void flushStmtCache(SqliteDb *pDb){
000508 SqlPreparedStmt *pPreStmt;
000509 SqlPreparedStmt *pNext;
000510
000511 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
000512 pNext = pPreStmt->pNext;
000513 dbFreeStmt(pPreStmt);
000514 }
000515 pDb->nStmt = 0;
000516 pDb->stmtLast = 0;
000517 pDb->stmtList = 0;
000518 }
000519
000520 /*
000521 ** TCL calls this procedure when an sqlite3 database command is
000522 ** deleted.
000523 */
000524 static void SQLITE_TCLAPI DbDeleteCmd(void *db){
000525 SqliteDb *pDb = (SqliteDb*)db;
000526 flushStmtCache(pDb);
000527 closeIncrblobChannels(pDb);
000528 sqlite3_close(pDb->db);
000529 while( pDb->pFunc ){
000530 SqlFunc *pFunc = pDb->pFunc;
000531 pDb->pFunc = pFunc->pNext;
000532 assert( pFunc->pDb==pDb );
000533 Tcl_DecrRefCount(pFunc->pScript);
000534 Tcl_Free((char*)pFunc);
000535 }
000536 while( pDb->pCollate ){
000537 SqlCollate *pCollate = pDb->pCollate;
000538 pDb->pCollate = pCollate->pNext;
000539 Tcl_Free((char*)pCollate);
000540 }
000541 if( pDb->zBusy ){
000542 Tcl_Free(pDb->zBusy);
000543 }
000544 if( pDb->zTrace ){
000545 Tcl_Free(pDb->zTrace);
000546 }
000547 if( pDb->zTraceV2 ){
000548 Tcl_Free(pDb->zTraceV2);
000549 }
000550 if( pDb->zProfile ){
000551 Tcl_Free(pDb->zProfile);
000552 }
000553 if( pDb->zBindFallback ){
000554 Tcl_Free(pDb->zBindFallback);
000555 }
000556 if( pDb->zAuth ){
000557 Tcl_Free(pDb->zAuth);
000558 }
000559 if( pDb->zNull ){
000560 Tcl_Free(pDb->zNull);
000561 }
000562 if( pDb->pUpdateHook ){
000563 Tcl_DecrRefCount(pDb->pUpdateHook);
000564 }
000565 if( pDb->pPreUpdateHook ){
000566 Tcl_DecrRefCount(pDb->pPreUpdateHook);
000567 }
000568 if( pDb->pRollbackHook ){
000569 Tcl_DecrRefCount(pDb->pRollbackHook);
000570 }
000571 if( pDb->pWalHook ){
000572 Tcl_DecrRefCount(pDb->pWalHook);
000573 }
000574 if( pDb->pCollateNeeded ){
000575 Tcl_DecrRefCount(pDb->pCollateNeeded);
000576 }
000577 Tcl_Free((char*)pDb);
000578 }
000579
000580 /*
000581 ** This routine is called when a database file is locked while trying
000582 ** to execute SQL.
000583 */
000584 static int DbBusyHandler(void *cd, int nTries){
000585 SqliteDb *pDb = (SqliteDb*)cd;
000586 int rc;
000587 char zVal[30];
000588
000589 sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);
000590 rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);
000591 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
000592 return 0;
000593 }
000594 return 1;
000595 }
000596
000597 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
000598 /*
000599 ** This routine is invoked as the 'progress callback' for the database.
000600 */
000601 static int DbProgressHandler(void *cd){
000602 SqliteDb *pDb = (SqliteDb*)cd;
000603 int rc;
000604
000605 assert( pDb->zProgress );
000606 rc = Tcl_Eval(pDb->interp, pDb->zProgress);
000607 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
000608 return 1;
000609 }
000610 return 0;
000611 }
000612 #endif
000613
000614 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
000615 !defined(SQLITE_OMIT_DEPRECATED)
000616 /*
000617 ** This routine is called by the SQLite trace handler whenever a new
000618 ** block of SQL is executed. The TCL script in pDb->zTrace is executed.
000619 */
000620 static void DbTraceHandler(void *cd, const char *zSql){
000621 SqliteDb *pDb = (SqliteDb*)cd;
000622 Tcl_DString str;
000623
000624 Tcl_DStringInit(&str);
000625 Tcl_DStringAppend(&str, pDb->zTrace, -1);
000626 Tcl_DStringAppendElement(&str, zSql);
000627 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
000628 Tcl_DStringFree(&str);
000629 Tcl_ResetResult(pDb->interp);
000630 }
000631 #endif
000632
000633 #ifndef SQLITE_OMIT_TRACE
000634 /*
000635 ** This routine is called by the SQLite trace_v2 handler whenever a new
000636 ** supported event is generated. Unsupported event types are ignored.
000637 ** The TCL script in pDb->zTraceV2 is executed, with the arguments for
000638 ** the event appended to it (as list elements).
000639 */
000640 static int DbTraceV2Handler(
000641 unsigned type, /* One of the SQLITE_TRACE_* event types. */
000642 void *cd, /* The original context data pointer. */
000643 void *pd, /* Primary event data, depends on event type. */
000644 void *xd /* Extra event data, depends on event type. */
000645 ){
000646 SqliteDb *pDb = (SqliteDb*)cd;
000647 Tcl_Obj *pCmd;
000648
000649 switch( type ){
000650 case SQLITE_TRACE_STMT: {
000651 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
000652 char *zSql = (char *)xd;
000653
000654 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
000655 Tcl_IncrRefCount(pCmd);
000656 Tcl_ListObjAppendElement(pDb->interp, pCmd,
000657 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
000658 Tcl_ListObjAppendElement(pDb->interp, pCmd,
000659 Tcl_NewStringObj(zSql, -1));
000660 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000661 Tcl_DecrRefCount(pCmd);
000662 Tcl_ResetResult(pDb->interp);
000663 break;
000664 }
000665 case SQLITE_TRACE_PROFILE: {
000666 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
000667 sqlite3_int64 ns = *(sqlite3_int64*)xd;
000668
000669 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
000670 Tcl_IncrRefCount(pCmd);
000671 Tcl_ListObjAppendElement(pDb->interp, pCmd,
000672 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
000673 Tcl_ListObjAppendElement(pDb->interp, pCmd,
000674 Tcl_NewWideIntObj((Tcl_WideInt)ns));
000675 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000676 Tcl_DecrRefCount(pCmd);
000677 Tcl_ResetResult(pDb->interp);
000678 break;
000679 }
000680 case SQLITE_TRACE_ROW: {
000681 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
000682
000683 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
000684 Tcl_IncrRefCount(pCmd);
000685 Tcl_ListObjAppendElement(pDb->interp, pCmd,
000686 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
000687 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000688 Tcl_DecrRefCount(pCmd);
000689 Tcl_ResetResult(pDb->interp);
000690 break;
000691 }
000692 case SQLITE_TRACE_CLOSE: {
000693 sqlite3 *db = (sqlite3 *)pd;
000694
000695 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
000696 Tcl_IncrRefCount(pCmd);
000697 Tcl_ListObjAppendElement(pDb->interp, pCmd,
000698 Tcl_NewWideIntObj((Tcl_WideInt)db));
000699 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000700 Tcl_DecrRefCount(pCmd);
000701 Tcl_ResetResult(pDb->interp);
000702 break;
000703 }
000704 }
000705 return SQLITE_OK;
000706 }
000707 #endif
000708
000709 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
000710 !defined(SQLITE_OMIT_DEPRECATED)
000711 /*
000712 ** This routine is called by the SQLite profile handler after a statement
000713 ** SQL has executed. The TCL script in pDb->zProfile is evaluated.
000714 */
000715 static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
000716 SqliteDb *pDb = (SqliteDb*)cd;
000717 Tcl_DString str;
000718 char zTm[100];
000719
000720 sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
000721 Tcl_DStringInit(&str);
000722 Tcl_DStringAppend(&str, pDb->zProfile, -1);
000723 Tcl_DStringAppendElement(&str, zSql);
000724 Tcl_DStringAppendElement(&str, zTm);
000725 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
000726 Tcl_DStringFree(&str);
000727 Tcl_ResetResult(pDb->interp);
000728 }
000729 #endif
000730
000731 /*
000732 ** This routine is called when a transaction is committed. The
000733 ** TCL script in pDb->zCommit is executed. If it returns non-zero or
000734 ** if it throws an exception, the transaction is rolled back instead
000735 ** of being committed.
000736 */
000737 static int DbCommitHandler(void *cd){
000738 SqliteDb *pDb = (SqliteDb*)cd;
000739 int rc;
000740
000741 rc = Tcl_Eval(pDb->interp, pDb->zCommit);
000742 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
000743 return 1;
000744 }
000745 return 0;
000746 }
000747
000748 static void DbRollbackHandler(void *clientData){
000749 SqliteDb *pDb = (SqliteDb*)clientData;
000750 assert(pDb->pRollbackHook);
000751 if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){
000752 Tcl_BackgroundError(pDb->interp);
000753 }
000754 }
000755
000756 /*
000757 ** This procedure handles wal_hook callbacks.
000758 */
000759 static int DbWalHandler(
000760 void *clientData,
000761 sqlite3 *db,
000762 const char *zDb,
000763 int nEntry
000764 ){
000765 int ret = SQLITE_OK;
000766 Tcl_Obj *p;
000767 SqliteDb *pDb = (SqliteDb*)clientData;
000768 Tcl_Interp *interp = pDb->interp;
000769 assert(pDb->pWalHook);
000770
000771 assert( db==pDb->db );
000772 p = Tcl_DuplicateObj(pDb->pWalHook);
000773 Tcl_IncrRefCount(p);
000774 Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
000775 Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
000776 if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
000777 || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
000778 ){
000779 Tcl_BackgroundError(interp);
000780 }
000781 Tcl_DecrRefCount(p);
000782
000783 return ret;
000784 }
000785
000786 #if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
000787 static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
000788 char zBuf[64];
000789 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iArg);
000790 Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
000791 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nArg);
000792 Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
000793 }
000794 #else
000795 # define setTestUnlockNotifyVars(x,y,z)
000796 #endif
000797
000798 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
000799 static void DbUnlockNotify(void **apArg, int nArg){
000800 int i;
000801 for(i=0; i<nArg; i++){
000802 const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
000803 SqliteDb *pDb = (SqliteDb *)apArg[i];
000804 setTestUnlockNotifyVars(pDb->interp, i, nArg);
000805 assert( pDb->pUnlockNotify);
000806 Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
000807 Tcl_DecrRefCount(pDb->pUnlockNotify);
000808 pDb->pUnlockNotify = 0;
000809 }
000810 }
000811 #endif
000812
000813 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
000814 /*
000815 ** Pre-update hook callback.
000816 */
000817 static void DbPreUpdateHandler(
000818 void *p,
000819 sqlite3 *db,
000820 int op,
000821 const char *zDb,
000822 const char *zTbl,
000823 sqlite_int64 iKey1,
000824 sqlite_int64 iKey2
000825 ){
000826 SqliteDb *pDb = (SqliteDb *)p;
000827 Tcl_Obj *pCmd;
000828 static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
000829
000830 assert( (SQLITE_DELETE-1)/9 == 0 );
000831 assert( (SQLITE_INSERT-1)/9 == 1 );
000832 assert( (SQLITE_UPDATE-1)/9 == 2 );
000833 assert( pDb->pPreUpdateHook );
000834 assert( db==pDb->db );
000835 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
000836
000837 pCmd = Tcl_DuplicateObj(pDb->pPreUpdateHook);
000838 Tcl_IncrRefCount(pCmd);
000839 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
000840 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
000841 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
000842 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey1));
000843 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey2));
000844 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000845 Tcl_DecrRefCount(pCmd);
000846 }
000847 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
000848
000849 static void DbUpdateHandler(
000850 void *p,
000851 int op,
000852 const char *zDb,
000853 const char *zTbl,
000854 sqlite_int64 rowid
000855 ){
000856 SqliteDb *pDb = (SqliteDb *)p;
000857 Tcl_Obj *pCmd;
000858 static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
000859
000860 assert( (SQLITE_DELETE-1)/9 == 0 );
000861 assert( (SQLITE_INSERT-1)/9 == 1 );
000862 assert( (SQLITE_UPDATE-1)/9 == 2 );
000863
000864 assert( pDb->pUpdateHook );
000865 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
000866
000867 pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
000868 Tcl_IncrRefCount(pCmd);
000869 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
000870 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
000871 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
000872 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
000873 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000874 Tcl_DecrRefCount(pCmd);
000875 }
000876
000877 static void tclCollateNeeded(
000878 void *pCtx,
000879 sqlite3 *db,
000880 int enc,
000881 const char *zName
000882 ){
000883 SqliteDb *pDb = (SqliteDb *)pCtx;
000884 Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
000885 Tcl_IncrRefCount(pScript);
000886 Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
000887 Tcl_EvalObjEx(pDb->interp, pScript, 0);
000888 Tcl_DecrRefCount(pScript);
000889 }
000890
000891 /*
000892 ** This routine is called to evaluate an SQL collation function implemented
000893 ** using TCL script.
000894 */
000895 static int tclSqlCollate(
000896 void *pCtx,
000897 int nA,
000898 const void *zA,
000899 int nB,
000900 const void *zB
000901 ){
000902 SqlCollate *p = (SqlCollate *)pCtx;
000903 Tcl_Obj *pCmd;
000904
000905 pCmd = Tcl_NewStringObj(p->zScript, -1);
000906 Tcl_IncrRefCount(pCmd);
000907 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
000908 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
000909 Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
000910 Tcl_DecrRefCount(pCmd);
000911 return (atoi(Tcl_GetStringResult(p->interp)));
000912 }
000913
000914 /*
000915 ** This routine is called to evaluate an SQL function implemented
000916 ** using TCL script.
000917 */
000918 static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
000919 SqlFunc *p = sqlite3_user_data(context);
000920 Tcl_Obj *pCmd;
000921 int i;
000922 int rc;
000923
000924 if( argc==0 ){
000925 /* If there are no arguments to the function, call Tcl_EvalObjEx on the
000926 ** script object directly. This allows the TCL compiler to generate
000927 ** bytecode for the command on the first invocation and thus make
000928 ** subsequent invocations much faster. */
000929 pCmd = p->pScript;
000930 Tcl_IncrRefCount(pCmd);
000931 rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
000932 Tcl_DecrRefCount(pCmd);
000933 }else{
000934 /* If there are arguments to the function, make a shallow copy of the
000935 ** script object, lappend the arguments, then evaluate the copy.
000936 **
000937 ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated.
000938 ** The new Tcl_Obj contains pointers to the original list elements.
000939 ** That way, when Tcl_EvalObjv() is run and shimmers the first element
000940 ** of the list to tclCmdNameType, that alternate representation will
000941 ** be preserved and reused on the next invocation.
000942 */
000943 Tcl_Obj **aArg;
000944 int nArg;
000945 if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
000946 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
000947 return;
000948 }
000949 pCmd = Tcl_NewListObj(nArg, aArg);
000950 Tcl_IncrRefCount(pCmd);
000951 for(i=0; i<argc; i++){
000952 sqlite3_value *pIn = argv[i];
000953 Tcl_Obj *pVal;
000954
000955 /* Set pVal to contain the i'th column of this row. */
000956 switch( sqlite3_value_type(pIn) ){
000957 case SQLITE_BLOB: {
000958 int bytes = sqlite3_value_bytes(pIn);
000959 pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
000960 break;
000961 }
000962 case SQLITE_INTEGER: {
000963 sqlite_int64 v = sqlite3_value_int64(pIn);
000964 if( v>=-2147483647 && v<=2147483647 ){
000965 pVal = Tcl_NewIntObj((int)v);
000966 }else{
000967 pVal = Tcl_NewWideIntObj(v);
000968 }
000969 break;
000970 }
000971 case SQLITE_FLOAT: {
000972 double r = sqlite3_value_double(pIn);
000973 pVal = Tcl_NewDoubleObj(r);
000974 break;
000975 }
000976 case SQLITE_NULL: {
000977 pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
000978 break;
000979 }
000980 default: {
000981 int bytes = sqlite3_value_bytes(pIn);
000982 pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
000983 break;
000984 }
000985 }
000986 rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
000987 if( rc ){
000988 Tcl_DecrRefCount(pCmd);
000989 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
000990 return;
000991 }
000992 }
000993 if( !p->useEvalObjv ){
000994 /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
000995 ** is a list without a string representation. To prevent this from
000996 ** happening, make sure pCmd has a valid string representation */
000997 Tcl_GetString(pCmd);
000998 }
000999 rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
001000 Tcl_DecrRefCount(pCmd);
001001 }
001002
001003 if( rc && rc!=TCL_RETURN ){
001004 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
001005 }else{
001006 Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
001007 int n;
001008 u8 *data;
001009 const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
001010 char c = zType[0];
001011 int eType = p->eType;
001012
001013 if( eType==SQLITE_NULL ){
001014 if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
001015 /* Only return a BLOB type if the Tcl variable is a bytearray and
001016 ** has no string representation. */
001017 eType = SQLITE_BLOB;
001018 }else if( (c=='b' && strcmp(zType,"boolean")==0)
001019 || (c=='w' && strcmp(zType,"wideInt")==0)
001020 || (c=='i' && strcmp(zType,"int")==0)
001021 ){
001022 eType = SQLITE_INTEGER;
001023 }else if( c=='d' && strcmp(zType,"double")==0 ){
001024 eType = SQLITE_FLOAT;
001025 }else{
001026 eType = SQLITE_TEXT;
001027 }
001028 }
001029
001030 switch( eType ){
001031 case SQLITE_BLOB: {
001032 data = Tcl_GetByteArrayFromObj(pVar, &n);
001033 sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
001034 break;
001035 }
001036 case SQLITE_INTEGER: {
001037 Tcl_WideInt v;
001038 if( TCL_OK==Tcl_GetWideIntFromObj(0, pVar, &v) ){
001039 sqlite3_result_int64(context, v);
001040 break;
001041 }
001042 /* fall-through */
001043 }
001044 case SQLITE_FLOAT: {
001045 double r;
001046 if( TCL_OK==Tcl_GetDoubleFromObj(0, pVar, &r) ){
001047 sqlite3_result_double(context, r);
001048 break;
001049 }
001050 /* fall-through */
001051 }
001052 default: {
001053 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
001054 sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
001055 break;
001056 }
001057 }
001058
001059 }
001060 }
001061
001062 #ifndef SQLITE_OMIT_AUTHORIZATION
001063 /*
001064 ** This is the authentication function. It appends the authentication
001065 ** type code and the two arguments to zCmd[] then invokes the result
001066 ** on the interpreter. The reply is examined to determine if the
001067 ** authentication fails or succeeds.
001068 */
001069 static int auth_callback(
001070 void *pArg,
001071 int code,
001072 const char *zArg1,
001073 const char *zArg2,
001074 const char *zArg3,
001075 const char *zArg4
001076 #ifdef SQLITE_USER_AUTHENTICATION
001077 ,const char *zArg5
001078 #endif
001079 ){
001080 const char *zCode;
001081 Tcl_DString str;
001082 int rc;
001083 const char *zReply;
001084 /* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer
001085 ** callback is a copy of the third parameter to the
001086 ** sqlite3_set_authorizer() interface.
001087 */
001088 SqliteDb *pDb = (SqliteDb*)pArg;
001089 if( pDb->disableAuth ) return SQLITE_OK;
001090
001091 /* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an
001092 ** integer action code that specifies the particular action to be
001093 ** authorized. */
001094 switch( code ){
001095 case SQLITE_COPY : zCode="SQLITE_COPY"; break;
001096 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
001097 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
001098 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
001099 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
001100 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
001101 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
001102 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break;
001103 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break;
001104 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break;
001105 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break;
001106 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break;
001107 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break;
001108 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break;
001109 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
001110 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break;
001111 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break;
001112 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break;
001113 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break;
001114 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break;
001115 case SQLITE_READ : zCode="SQLITE_READ"; break;
001116 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break;
001117 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break;
001118 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break;
001119 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break;
001120 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break;
001121 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break;
001122 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break;
001123 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break;
001124 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break;
001125 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break;
001126 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break;
001127 case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break;
001128 case SQLITE_RECURSIVE : zCode="SQLITE_RECURSIVE"; break;
001129 default : zCode="????"; break;
001130 }
001131 Tcl_DStringInit(&str);
001132 Tcl_DStringAppend(&str, pDb->zAuth, -1);
001133 Tcl_DStringAppendElement(&str, zCode);
001134 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
001135 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
001136 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
001137 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
001138 #ifdef SQLITE_USER_AUTHENTICATION
001139 Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
001140 #endif
001141 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
001142 Tcl_DStringFree(&str);
001143 zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
001144 if( strcmp(zReply,"SQLITE_OK")==0 ){
001145 rc = SQLITE_OK;
001146 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
001147 rc = SQLITE_DENY;
001148 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
001149 rc = SQLITE_IGNORE;
001150 }else{
001151 rc = 999;
001152 }
001153 return rc;
001154 }
001155 #endif /* SQLITE_OMIT_AUTHORIZATION */
001156
001157 /*
001158 ** This routine reads a line of text from FILE in, stores
001159 ** the text in memory obtained from malloc() and returns a pointer
001160 ** to the text. NULL is returned at end of file, or if malloc()
001161 ** fails.
001162 **
001163 ** The interface is like "readline" but no command-line editing
001164 ** is done.
001165 **
001166 ** copied from shell.c from '.import' command
001167 */
001168 static char *local_getline(char *zPrompt, FILE *in){
001169 char *zLine;
001170 int nLine;
001171 int n;
001172
001173 nLine = 100;
001174 zLine = malloc( nLine );
001175 if( zLine==0 ) return 0;
001176 n = 0;
001177 while( 1 ){
001178 if( n+100>nLine ){
001179 nLine = nLine*2 + 100;
001180 zLine = realloc(zLine, nLine);
001181 if( zLine==0 ) return 0;
001182 }
001183 if( fgets(&zLine[n], nLine - n, in)==0 ){
001184 if( n==0 ){
001185 free(zLine);
001186 return 0;
001187 }
001188 zLine[n] = 0;
001189 break;
001190 }
001191 while( zLine[n] ){ n++; }
001192 if( n>0 && zLine[n-1]=='\n' ){
001193 n--;
001194 zLine[n] = 0;
001195 break;
001196 }
001197 }
001198 zLine = realloc( zLine, n+1 );
001199 return zLine;
001200 }
001201
001202
001203 /*
001204 ** This function is part of the implementation of the command:
001205 **
001206 ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT
001207 **
001208 ** It is invoked after evaluating the script SCRIPT to commit or rollback
001209 ** the transaction or savepoint opened by the [transaction] command.
001210 */
001211 static int SQLITE_TCLAPI DbTransPostCmd(
001212 ClientData data[], /* data[0] is the Sqlite3Db* for $db */
001213 Tcl_Interp *interp, /* Tcl interpreter */
001214 int result /* Result of evaluating SCRIPT */
001215 ){
001216 static const char *const azEnd[] = {
001217 "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */
001218 "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */
001219 "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
001220 "ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */
001221 };
001222 SqliteDb *pDb = (SqliteDb*)data[0];
001223 int rc = result;
001224 const char *zEnd;
001225
001226 pDb->nTransaction--;
001227 zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];
001228
001229 pDb->disableAuth++;
001230 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
001231 /* This is a tricky scenario to handle. The most likely cause of an
001232 ** error is that the exec() above was an attempt to commit the
001233 ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
001234 ** that an IO-error has occurred. In either case, throw a Tcl exception
001235 ** and try to rollback the transaction.
001236 **
001237 ** But it could also be that the user executed one or more BEGIN,
001238 ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
001239 ** this method's logic. Not clear how this would be best handled.
001240 */
001241 if( rc!=TCL_ERROR ){
001242 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
001243 rc = TCL_ERROR;
001244 }
001245 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
001246 }
001247 pDb->disableAuth--;
001248
001249 return rc;
001250 }
001251
001252 /*
001253 ** Unless SQLITE_TEST is defined, this function is a simple wrapper around
001254 ** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
001255 ** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
001256 ** on whether or not the [db_use_legacy_prepare] command has been used to
001257 ** configure the connection.
001258 */
001259 static int dbPrepare(
001260 SqliteDb *pDb, /* Database object */
001261 const char *zSql, /* SQL to compile */
001262 sqlite3_stmt **ppStmt, /* OUT: Prepared statement */
001263 const char **pzOut /* OUT: Pointer to next SQL statement */
001264 ){
001265 unsigned int prepFlags = 0;
001266 #ifdef SQLITE_TEST
001267 if( pDb->bLegacyPrepare ){
001268 return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
001269 }
001270 #endif
001271 /* If the statement cache is large, use the SQLITE_PREPARE_PERSISTENT
001272 ** flags, which uses less lookaside memory. But if the cache is small,
001273 ** omit that flag to make full use of lookaside */
001274 if( pDb->maxStmt>5 ) prepFlags = SQLITE_PREPARE_PERSISTENT;
001275
001276 return sqlite3_prepare_v3(pDb->db, zSql, -1, prepFlags, ppStmt, pzOut);
001277 }
001278
001279 /*
001280 ** Search the cache for a prepared-statement object that implements the
001281 ** first SQL statement in the buffer pointed to by parameter zIn. If
001282 ** no such prepared-statement can be found, allocate and prepare a new
001283 ** one. In either case, bind the current values of the relevant Tcl
001284 ** variables to any $var, :var or @var variables in the statement. Before
001285 ** returning, set *ppPreStmt to point to the prepared-statement object.
001286 **
001287 ** Output parameter *pzOut is set to point to the next SQL statement in
001288 ** buffer zIn, or to the '\0' byte at the end of zIn if there is no
001289 ** next statement.
001290 **
001291 ** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned
001292 ** and an error message loaded into interpreter pDb->interp.
001293 */
001294 static int dbPrepareAndBind(
001295 SqliteDb *pDb, /* Database object */
001296 char const *zIn, /* SQL to compile */
001297 char const **pzOut, /* OUT: Pointer to next SQL statement */
001298 SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */
001299 ){
001300 const char *zSql = zIn; /* Pointer to first SQL statement in zIn */
001301 sqlite3_stmt *pStmt = 0; /* Prepared statement object */
001302 SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */
001303 int nSql; /* Length of zSql in bytes */
001304 int nVar = 0; /* Number of variables in statement */
001305 int iParm = 0; /* Next free entry in apParm */
001306 char c;
001307 int i;
001308 int needResultReset = 0; /* Need to invoke Tcl_ResetResult() */
001309 int rc = SQLITE_OK; /* Value to return */
001310 Tcl_Interp *interp = pDb->interp;
001311
001312 *ppPreStmt = 0;
001313
001314 /* Trim spaces from the start of zSql and calculate the remaining length. */
001315 while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; }
001316 nSql = strlen30(zSql);
001317
001318 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
001319 int n = pPreStmt->nSql;
001320 if( nSql>=n
001321 && memcmp(pPreStmt->zSql, zSql, n)==0
001322 && (zSql[n]==0 || zSql[n-1]==';')
001323 ){
001324 pStmt = pPreStmt->pStmt;
001325 *pzOut = &zSql[pPreStmt->nSql];
001326
001327 /* When a prepared statement is found, unlink it from the
001328 ** cache list. It will later be added back to the beginning
001329 ** of the cache list in order to implement LRU replacement.
001330 */
001331 if( pPreStmt->pPrev ){
001332 pPreStmt->pPrev->pNext = pPreStmt->pNext;
001333 }else{
001334 pDb->stmtList = pPreStmt->pNext;
001335 }
001336 if( pPreStmt->pNext ){
001337 pPreStmt->pNext->pPrev = pPreStmt->pPrev;
001338 }else{
001339 pDb->stmtLast = pPreStmt->pPrev;
001340 }
001341 pDb->nStmt--;
001342 nVar = sqlite3_bind_parameter_count(pStmt);
001343 break;
001344 }
001345 }
001346
001347 /* If no prepared statement was found. Compile the SQL text. Also allocate
001348 ** a new SqlPreparedStmt structure. */
001349 if( pPreStmt==0 ){
001350 int nByte;
001351
001352 if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
001353 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
001354 return TCL_ERROR;
001355 }
001356 if( pStmt==0 ){
001357 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
001358 /* A compile-time error in the statement. */
001359 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
001360 return TCL_ERROR;
001361 }else{
001362 /* The statement was a no-op. Continue to the next statement
001363 ** in the SQL string.
001364 */
001365 return TCL_OK;
001366 }
001367 }
001368
001369 assert( pPreStmt==0 );
001370 nVar = sqlite3_bind_parameter_count(pStmt);
001371 nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *);
001372 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte);
001373 memset(pPreStmt, 0, nByte);
001374
001375 pPreStmt->pStmt = pStmt;
001376 pPreStmt->nSql = (int)(*pzOut - zSql);
001377 pPreStmt->zSql = sqlite3_sql(pStmt);
001378 pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
001379 #ifdef SQLITE_TEST
001380 if( pPreStmt->zSql==0 ){
001381 char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
001382 memcpy(zCopy, zSql, pPreStmt->nSql);
001383 zCopy[pPreStmt->nSql] = '\0';
001384 pPreStmt->zSql = zCopy;
001385 }
001386 #endif
001387 }
001388 assert( pPreStmt );
001389 assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
001390 assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
001391
001392 /* Bind values to parameters that begin with $ or : */
001393 for(i=1; i<=nVar; i++){
001394 const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
001395 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
001396 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
001397 if( pVar==0 && pDb->zBindFallback!=0 ){
001398 Tcl_Obj *pCmd;
001399 int rx;
001400 pCmd = Tcl_NewStringObj(pDb->zBindFallback, -1);
001401 Tcl_IncrRefCount(pCmd);
001402 Tcl_ListObjAppendElement(interp, pCmd, Tcl_NewStringObj(zVar,-1));
001403 if( needResultReset ) Tcl_ResetResult(interp);
001404 needResultReset = 1;
001405 rx = Tcl_EvalObjEx(interp, pCmd, TCL_EVAL_DIRECT);
001406 Tcl_DecrRefCount(pCmd);
001407 if( rx==TCL_OK ){
001408 pVar = Tcl_GetObjResult(interp);
001409 }else if( rx==TCL_ERROR ){
001410 rc = TCL_ERROR;
001411 break;
001412 }else{
001413 pVar = 0;
001414 }
001415 }
001416 if( pVar ){
001417 int n;
001418 u8 *data;
001419 const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
001420 c = zType[0];
001421 if( zVar[0]=='@' ||
001422 (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
001423 /* Load a BLOB type if the Tcl variable is a bytearray and
001424 ** it has no string representation or the host
001425 ** parameter name begins with "@". */
001426 data = Tcl_GetByteArrayFromObj(pVar, &n);
001427 sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
001428 Tcl_IncrRefCount(pVar);
001429 pPreStmt->apParm[iParm++] = pVar;
001430 }else if( c=='b' && strcmp(zType,"boolean")==0 ){
001431 Tcl_GetIntFromObj(interp, pVar, &n);
001432 sqlite3_bind_int(pStmt, i, n);
001433 }else if( c=='d' && strcmp(zType,"double")==0 ){
001434 double r;
001435 Tcl_GetDoubleFromObj(interp, pVar, &r);
001436 sqlite3_bind_double(pStmt, i, r);
001437 }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
001438 (c=='i' && strcmp(zType,"int")==0) ){
001439 Tcl_WideInt v;
001440 Tcl_GetWideIntFromObj(interp, pVar, &v);
001441 sqlite3_bind_int64(pStmt, i, v);
001442 }else{
001443 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
001444 sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
001445 Tcl_IncrRefCount(pVar);
001446 pPreStmt->apParm[iParm++] = pVar;
001447 }
001448 }else{
001449 sqlite3_bind_null(pStmt, i);
001450 }
001451 if( needResultReset ) Tcl_ResetResult(pDb->interp);
001452 }
001453 }
001454 pPreStmt->nParm = iParm;
001455 *ppPreStmt = pPreStmt;
001456 if( needResultReset && rc==TCL_OK ) Tcl_ResetResult(pDb->interp);
001457
001458 return rc;
001459 }
001460
001461 /*
001462 ** Release a statement reference obtained by calling dbPrepareAndBind().
001463 ** There should be exactly one call to this function for each call to
001464 ** dbPrepareAndBind().
001465 **
001466 ** If the discard parameter is non-zero, then the statement is deleted
001467 ** immediately. Otherwise it is added to the LRU list and may be returned
001468 ** by a subsequent call to dbPrepareAndBind().
001469 */
001470 static void dbReleaseStmt(
001471 SqliteDb *pDb, /* Database handle */
001472 SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */
001473 int discard /* True to delete (not cache) the pPreStmt */
001474 ){
001475 int i;
001476
001477 /* Free the bound string and blob parameters */
001478 for(i=0; i<pPreStmt->nParm; i++){
001479 Tcl_DecrRefCount(pPreStmt->apParm[i]);
001480 }
001481 pPreStmt->nParm = 0;
001482
001483 if( pDb->maxStmt<=0 || discard ){
001484 /* If the cache is turned off, deallocated the statement */
001485 dbFreeStmt(pPreStmt);
001486 }else{
001487 /* Add the prepared statement to the beginning of the cache list. */
001488 pPreStmt->pNext = pDb->stmtList;
001489 pPreStmt->pPrev = 0;
001490 if( pDb->stmtList ){
001491 pDb->stmtList->pPrev = pPreStmt;
001492 }
001493 pDb->stmtList = pPreStmt;
001494 if( pDb->stmtLast==0 ){
001495 assert( pDb->nStmt==0 );
001496 pDb->stmtLast = pPreStmt;
001497 }else{
001498 assert( pDb->nStmt>0 );
001499 }
001500 pDb->nStmt++;
001501
001502 /* If we have too many statement in cache, remove the surplus from
001503 ** the end of the cache list. */
001504 while( pDb->nStmt>pDb->maxStmt ){
001505 SqlPreparedStmt *pLast = pDb->stmtLast;
001506 pDb->stmtLast = pLast->pPrev;
001507 pDb->stmtLast->pNext = 0;
001508 pDb->nStmt--;
001509 dbFreeStmt(pLast);
001510 }
001511 }
001512 }
001513
001514 /*
001515 ** Structure used with dbEvalXXX() functions:
001516 **
001517 ** dbEvalInit()
001518 ** dbEvalStep()
001519 ** dbEvalFinalize()
001520 ** dbEvalRowInfo()
001521 ** dbEvalColumnValue()
001522 */
001523 typedef struct DbEvalContext DbEvalContext;
001524 struct DbEvalContext {
001525 SqliteDb *pDb; /* Database handle */
001526 Tcl_Obj *pSql; /* Object holding string zSql */
001527 const char *zSql; /* Remaining SQL to execute */
001528 SqlPreparedStmt *pPreStmt; /* Current statement */
001529 int nCol; /* Number of columns returned by pStmt */
001530 int evalFlags; /* Flags used */
001531 Tcl_Obj *pArray; /* Name of array variable */
001532 Tcl_Obj **apColName; /* Array of column names */
001533 };
001534
001535 #define SQLITE_EVAL_WITHOUTNULLS 0x00001 /* Unset array(*) for NULL */
001536
001537 /*
001538 ** Release any cache of column names currently held as part of
001539 ** the DbEvalContext structure passed as the first argument.
001540 */
001541 static void dbReleaseColumnNames(DbEvalContext *p){
001542 if( p->apColName ){
001543 int i;
001544 for(i=0; i<p->nCol; i++){
001545 Tcl_DecrRefCount(p->apColName[i]);
001546 }
001547 Tcl_Free((char *)p->apColName);
001548 p->apColName = 0;
001549 }
001550 p->nCol = 0;
001551 }
001552
001553 /*
001554 ** Initialize a DbEvalContext structure.
001555 **
001556 ** If pArray is not NULL, then it contains the name of a Tcl array
001557 ** variable. The "*" member of this array is set to a list containing
001558 ** the names of the columns returned by the statement as part of each
001559 ** call to dbEvalStep(), in order from left to right. e.g. if the names
001560 ** of the returned columns are a, b and c, it does the equivalent of the
001561 ** tcl command:
001562 **
001563 ** set ${pArray}(*) {a b c}
001564 */
001565 static void dbEvalInit(
001566 DbEvalContext *p, /* Pointer to structure to initialize */
001567 SqliteDb *pDb, /* Database handle */
001568 Tcl_Obj *pSql, /* Object containing SQL script */
001569 Tcl_Obj *pArray, /* Name of Tcl array to set (*) element of */
001570 int evalFlags /* Flags controlling evaluation */
001571 ){
001572 memset(p, 0, sizeof(DbEvalContext));
001573 p->pDb = pDb;
001574 p->zSql = Tcl_GetString(pSql);
001575 p->pSql = pSql;
001576 Tcl_IncrRefCount(pSql);
001577 if( pArray ){
001578 p->pArray = pArray;
001579 Tcl_IncrRefCount(pArray);
001580 }
001581 p->evalFlags = evalFlags;
001582 }
001583
001584 /*
001585 ** Obtain information about the row that the DbEvalContext passed as the
001586 ** first argument currently points to.
001587 */
001588 static void dbEvalRowInfo(
001589 DbEvalContext *p, /* Evaluation context */
001590 int *pnCol, /* OUT: Number of column names */
001591 Tcl_Obj ***papColName /* OUT: Array of column names */
001592 ){
001593 /* Compute column names */
001594 if( 0==p->apColName ){
001595 sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
001596 int i; /* Iterator variable */
001597 int nCol; /* Number of columns returned by pStmt */
001598 Tcl_Obj **apColName = 0; /* Array of column names */
001599
001600 p->nCol = nCol = sqlite3_column_count(pStmt);
001601 if( nCol>0 && (papColName || p->pArray) ){
001602 apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
001603 for(i=0; i<nCol; i++){
001604 apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
001605 Tcl_IncrRefCount(apColName[i]);
001606 }
001607 p->apColName = apColName;
001608 }
001609
001610 /* If results are being stored in an array variable, then create
001611 ** the array(*) entry for that array
001612 */
001613 if( p->pArray ){
001614 Tcl_Interp *interp = p->pDb->interp;
001615 Tcl_Obj *pColList = Tcl_NewObj();
001616 Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
001617
001618 for(i=0; i<nCol; i++){
001619 Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
001620 }
001621 Tcl_IncrRefCount(pStar);
001622 Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0);
001623 Tcl_DecrRefCount(pStar);
001624 }
001625 }
001626
001627 if( papColName ){
001628 *papColName = p->apColName;
001629 }
001630 if( pnCol ){
001631 *pnCol = p->nCol;
001632 }
001633 }
001634
001635 /*
001636 ** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is
001637 ** returned, then an error message is stored in the interpreter before
001638 ** returning.
001639 **
001640 ** A return value of TCL_OK means there is a row of data available. The
001641 ** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
001642 ** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK
001643 ** is returned, then the SQL script has finished executing and there are
001644 ** no further rows available. This is similar to SQLITE_DONE.
001645 */
001646 static int dbEvalStep(DbEvalContext *p){
001647 const char *zPrevSql = 0; /* Previous value of p->zSql */
001648
001649 while( p->zSql[0] || p->pPreStmt ){
001650 int rc;
001651 if( p->pPreStmt==0 ){
001652 zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
001653 rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
001654 if( rc!=TCL_OK ) return rc;
001655 }else{
001656 int rcs;
001657 SqliteDb *pDb = p->pDb;
001658 SqlPreparedStmt *pPreStmt = p->pPreStmt;
001659 sqlite3_stmt *pStmt = pPreStmt->pStmt;
001660
001661 rcs = sqlite3_step(pStmt);
001662 if( rcs==SQLITE_ROW ){
001663 return TCL_OK;
001664 }
001665 if( p->pArray ){
001666 dbEvalRowInfo(p, 0, 0);
001667 }
001668 rcs = sqlite3_reset(pStmt);
001669
001670 pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
001671 pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
001672 pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
001673 pDb->nVMStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_VM_STEP,1);
001674 dbReleaseColumnNames(p);
001675 p->pPreStmt = 0;
001676
001677 if( rcs!=SQLITE_OK ){
001678 /* If a run-time error occurs, report the error and stop reading
001679 ** the SQL. */
001680 dbReleaseStmt(pDb, pPreStmt, 1);
001681 #if SQLITE_TEST
001682 if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
001683 /* If the runtime error was an SQLITE_SCHEMA, and the database
001684 ** handle is configured to use the legacy sqlite3_prepare()
001685 ** interface, retry prepare()/step() on the same SQL statement.
001686 ** This only happens once. If there is a second SQLITE_SCHEMA
001687 ** error, the error will be returned to the caller. */
001688 p->zSql = zPrevSql;
001689 continue;
001690 }
001691 #endif
001692 Tcl_SetObjResult(pDb->interp,
001693 Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
001694 return TCL_ERROR;
001695 }else{
001696 dbReleaseStmt(pDb, pPreStmt, 0);
001697 }
001698 }
001699 }
001700
001701 /* Finished */
001702 return TCL_BREAK;
001703 }
001704
001705 /*
001706 ** Free all resources currently held by the DbEvalContext structure passed
001707 ** as the first argument. There should be exactly one call to this function
001708 ** for each call to dbEvalInit().
001709 */
001710 static void dbEvalFinalize(DbEvalContext *p){
001711 if( p->pPreStmt ){
001712 sqlite3_reset(p->pPreStmt->pStmt);
001713 dbReleaseStmt(p->pDb, p->pPreStmt, 0);
001714 p->pPreStmt = 0;
001715 }
001716 if( p->pArray ){
001717 Tcl_DecrRefCount(p->pArray);
001718 p->pArray = 0;
001719 }
001720 Tcl_DecrRefCount(p->pSql);
001721 dbReleaseColumnNames(p);
001722 }
001723
001724 /*
001725 ** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
001726 ** the value for the iCol'th column of the row currently pointed to by
001727 ** the DbEvalContext structure passed as the first argument.
001728 */
001729 static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
001730 sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
001731 switch( sqlite3_column_type(pStmt, iCol) ){
001732 case SQLITE_BLOB: {
001733 int bytes = sqlite3_column_bytes(pStmt, iCol);
001734 const char *zBlob = sqlite3_column_blob(pStmt, iCol);
001735 if( !zBlob ) bytes = 0;
001736 return Tcl_NewByteArrayObj((u8*)zBlob, bytes);
001737 }
001738 case SQLITE_INTEGER: {
001739 sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
001740 if( v>=-2147483647 && v<=2147483647 ){
001741 return Tcl_NewIntObj((int)v);
001742 }else{
001743 return Tcl_NewWideIntObj(v);
001744 }
001745 }
001746 case SQLITE_FLOAT: {
001747 return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
001748 }
001749 case SQLITE_NULL: {
001750 return Tcl_NewStringObj(p->pDb->zNull, -1);
001751 }
001752 }
001753
001754 return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
001755 }
001756
001757 /*
001758 ** If using Tcl version 8.6 or greater, use the NR functions to avoid
001759 ** recursive evalution of scripts by the [db eval] and [db trans]
001760 ** commands. Even if the headers used while compiling the extension
001761 ** are 8.6 or newer, the code still tests the Tcl version at runtime.
001762 ** This allows stubs-enabled builds to be used with older Tcl libraries.
001763 */
001764 #if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6)
001765 # define SQLITE_TCL_NRE 1
001766 static int DbUseNre(void){
001767 int major, minor;
001768 Tcl_GetVersion(&major, &minor, 0, 0);
001769 return( (major==8 && minor>=6) || major>8 );
001770 }
001771 #else
001772 /*
001773 ** Compiling using headers earlier than 8.6. In this case NR cannot be
001774 ** used, so DbUseNre() to always return zero. Add #defines for the other
001775 ** Tcl_NRxxx() functions to prevent them from causing compilation errors,
001776 ** even though the only invocations of them are within conditional blocks
001777 ** of the form:
001778 **
001779 ** if( DbUseNre() ) { ... }
001780 */
001781 # define SQLITE_TCL_NRE 0
001782 # define DbUseNre() 0
001783 # define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0
001784 # define Tcl_NREvalObj(a,b,c) 0
001785 # define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0
001786 #endif
001787
001788 /*
001789 ** This function is part of the implementation of the command:
001790 **
001791 ** $db eval SQL ?ARRAYNAME? SCRIPT
001792 */
001793 static int SQLITE_TCLAPI DbEvalNextCmd(
001794 ClientData data[], /* data[0] is the (DbEvalContext*) */
001795 Tcl_Interp *interp, /* Tcl interpreter */
001796 int result /* Result so far */
001797 ){
001798 int rc = result; /* Return code */
001799
001800 /* The first element of the data[] array is a pointer to a DbEvalContext
001801 ** structure allocated using Tcl_Alloc(). The second element of data[]
001802 ** is a pointer to a Tcl_Obj containing the script to run for each row
001803 ** returned by the queries encapsulated in data[0]. */
001804 DbEvalContext *p = (DbEvalContext *)data[0];
001805 Tcl_Obj *pScript = (Tcl_Obj *)data[1];
001806 Tcl_Obj *pArray = p->pArray;
001807
001808 while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){
001809 int i;
001810 int nCol;
001811 Tcl_Obj **apColName;
001812 dbEvalRowInfo(p, &nCol, &apColName);
001813 for(i=0; i<nCol; i++){
001814 if( pArray==0 ){
001815 Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0);
001816 }else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0
001817 && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL
001818 ){
001819 Tcl_UnsetVar2(interp, Tcl_GetString(pArray),
001820 Tcl_GetString(apColName[i]), 0);
001821 }else{
001822 Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0);
001823 }
001824 }
001825
001826 /* The required interpreter variables are now populated with the data
001827 ** from the current row. If using NRE, schedule callbacks to evaluate
001828 ** script pScript, then to invoke this function again to fetch the next
001829 ** row (or clean up if there is no next row or the script throws an
001830 ** exception). After scheduling the callbacks, return control to the
001831 ** caller.
001832 **
001833 ** If not using NRE, evaluate pScript directly and continue with the
001834 ** next iteration of this while(...) loop. */
001835 if( DbUseNre() ){
001836 Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0);
001837 return Tcl_NREvalObj(interp, pScript, 0);
001838 }else{
001839 rc = Tcl_EvalObjEx(interp, pScript, 0);
001840 }
001841 }
001842
001843 Tcl_DecrRefCount(pScript);
001844 dbEvalFinalize(p);
001845 Tcl_Free((char *)p);
001846
001847 if( rc==TCL_OK || rc==TCL_BREAK ){
001848 Tcl_ResetResult(interp);
001849 rc = TCL_OK;
001850 }
001851 return rc;
001852 }
001853
001854 /*
001855 ** This function is used by the implementations of the following database
001856 ** handle sub-commands:
001857 **
001858 ** $db update_hook ?SCRIPT?
001859 ** $db wal_hook ?SCRIPT?
001860 ** $db commit_hook ?SCRIPT?
001861 ** $db preupdate hook ?SCRIPT?
001862 */
001863 static void DbHookCmd(
001864 Tcl_Interp *interp, /* Tcl interpreter */
001865 SqliteDb *pDb, /* Database handle */
001866 Tcl_Obj *pArg, /* SCRIPT argument (or NULL) */
001867 Tcl_Obj **ppHook /* Pointer to member of SqliteDb */
001868 ){
001869 sqlite3 *db = pDb->db;
001870
001871 if( *ppHook ){
001872 Tcl_SetObjResult(interp, *ppHook);
001873 if( pArg ){
001874 Tcl_DecrRefCount(*ppHook);
001875 *ppHook = 0;
001876 }
001877 }
001878 if( pArg ){
001879 assert( !(*ppHook) );
001880 if( Tcl_GetCharLength(pArg)>0 ){
001881 *ppHook = pArg;
001882 Tcl_IncrRefCount(*ppHook);
001883 }
001884 }
001885
001886 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
001887 sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb);
001888 #endif
001889 sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
001890 sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb);
001891 sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb);
001892 }
001893
001894 /*
001895 ** The "sqlite" command below creates a new Tcl command for each
001896 ** connection it opens to an SQLite database. This routine is invoked
001897 ** whenever one of those connection-specific commands is executed
001898 ** in Tcl. For example, if you run Tcl code like this:
001899 **
001900 ** sqlite3 db1 "my_database"
001901 ** db1 close
001902 **
001903 ** The first command opens a connection to the "my_database" database
001904 ** and calls that connection "db1". The second command causes this
001905 ** subroutine to be invoked.
001906 */
001907 static int SQLITE_TCLAPI DbObjCmd(
001908 void *cd,
001909 Tcl_Interp *interp,
001910 int objc,
001911 Tcl_Obj *const*objv
001912 ){
001913 SqliteDb *pDb = (SqliteDb*)cd;
001914 int choice;
001915 int rc = TCL_OK;
001916 static const char *DB_strs[] = {
001917 "authorizer", "backup", "bind_fallback",
001918 "busy", "cache", "changes",
001919 "close", "collate", "collation_needed",
001920 "commit_hook", "complete", "config",
001921 "copy", "deserialize", "enable_load_extension",
001922 "errorcode", "eval", "exists",
001923 "function", "incrblob", "interrupt",
001924 "last_insert_rowid", "nullvalue", "onecolumn",
001925 "preupdate", "profile", "progress",
001926 "rekey", "restore", "rollback_hook",
001927 "serialize", "status", "timeout",
001928 "total_changes", "trace", "trace_v2",
001929 "transaction", "unlock_notify", "update_hook",
001930 "version", "wal_hook", 0
001931 };
001932 enum DB_enum {
001933 DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK,
001934 DB_BUSY, DB_CACHE, DB_CHANGES,
001935 DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED,
001936 DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG,
001937 DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,
001938 DB_ERRORCODE, DB_EVAL, DB_EXISTS,
001939 DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
001940 DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
001941 DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
001942 DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
001943 DB_SERIALIZE, DB_STATUS, DB_TIMEOUT,
001944 DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2,
001945 DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK,
001946 DB_VERSION, DB_WAL_HOOK
001947 };
001948 /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
001949
001950 if( objc<2 ){
001951 Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
001952 return TCL_ERROR;
001953 }
001954 if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
001955 return TCL_ERROR;
001956 }
001957
001958 switch( (enum DB_enum)choice ){
001959
001960 /* $db authorizer ?CALLBACK?
001961 **
001962 ** Invoke the given callback to authorize each SQL operation as it is
001963 ** compiled. 5 arguments are appended to the callback before it is
001964 ** invoked:
001965 **
001966 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
001967 ** (2) First descriptive name (depends on authorization type)
001968 ** (3) Second descriptive name
001969 ** (4) Name of the database (ex: "main", "temp")
001970 ** (5) Name of trigger that is doing the access
001971 **
001972 ** The callback should return on of the following strings: SQLITE_OK,
001973 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error.
001974 **
001975 ** If this method is invoked with no arguments, the current authorization
001976 ** callback string is returned.
001977 */
001978 case DB_AUTHORIZER: {
001979 #ifdef SQLITE_OMIT_AUTHORIZATION
001980 Tcl_AppendResult(interp, "authorization not available in this build",
001981 (char*)0);
001982 return TCL_ERROR;
001983 #else
001984 if( objc>3 ){
001985 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
001986 return TCL_ERROR;
001987 }else if( objc==2 ){
001988 if( pDb->zAuth ){
001989 Tcl_AppendResult(interp, pDb->zAuth, (char*)0);
001990 }
001991 }else{
001992 char *zAuth;
001993 int len;
001994 if( pDb->zAuth ){
001995 Tcl_Free(pDb->zAuth);
001996 }
001997 zAuth = Tcl_GetStringFromObj(objv[2], &len);
001998 if( zAuth && len>0 ){
001999 pDb->zAuth = Tcl_Alloc( len + 1 );
002000 memcpy(pDb->zAuth, zAuth, len+1);
002001 }else{
002002 pDb->zAuth = 0;
002003 }
002004 if( pDb->zAuth ){
002005 typedef int (*sqlite3_auth_cb)(
002006 void*,int,const char*,const char*,
002007 const char*,const char*);
002008 pDb->interp = interp;
002009 sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb);
002010 }else{
002011 sqlite3_set_authorizer(pDb->db, 0, 0);
002012 }
002013 }
002014 #endif
002015 break;
002016 }
002017
002018 /* $db backup ?DATABASE? FILENAME
002019 **
002020 ** Open or create a database file named FILENAME. Transfer the
002021 ** content of local database DATABASE (default: "main") into the
002022 ** FILENAME database.
002023 */
002024 case DB_BACKUP: {
002025 const char *zDestFile;
002026 const char *zSrcDb;
002027 sqlite3 *pDest;
002028 sqlite3_backup *pBackup;
002029
002030 if( objc==3 ){
002031 zSrcDb = "main";
002032 zDestFile = Tcl_GetString(objv[2]);
002033 }else if( objc==4 ){
002034 zSrcDb = Tcl_GetString(objv[2]);
002035 zDestFile = Tcl_GetString(objv[3]);
002036 }else{
002037 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
002038 return TCL_ERROR;
002039 }
002040 rc = sqlite3_open_v2(zDestFile, &pDest,
002041 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0);
002042 if( rc!=SQLITE_OK ){
002043 Tcl_AppendResult(interp, "cannot open target database: ",
002044 sqlite3_errmsg(pDest), (char*)0);
002045 sqlite3_close(pDest);
002046 return TCL_ERROR;
002047 }
002048 pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
002049 if( pBackup==0 ){
002050 Tcl_AppendResult(interp, "backup failed: ",
002051 sqlite3_errmsg(pDest), (char*)0);
002052 sqlite3_close(pDest);
002053 return TCL_ERROR;
002054 }
002055 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
002056 sqlite3_backup_finish(pBackup);
002057 if( rc==SQLITE_DONE ){
002058 rc = TCL_OK;
002059 }else{
002060 Tcl_AppendResult(interp, "backup failed: ",
002061 sqlite3_errmsg(pDest), (char*)0);
002062 rc = TCL_ERROR;
002063 }
002064 sqlite3_close(pDest);
002065 break;
002066 }
002067
002068 /* $db bind_fallback ?CALLBACK?
002069 **
002070 ** When resolving bind parameters in an SQL statement, if the parameter
002071 ** cannot be associated with a TCL variable then invoke CALLBACK with a
002072 ** single argument that is the name of the parameter and use the return
002073 ** value of the CALLBACK as the binding. If CALLBACK returns something
002074 ** other than TCL_OK or TCL_ERROR then bind a NULL.
002075 **
002076 ** If CALLBACK is an empty string, then revert to the default behavior
002077 ** which is to set the binding to NULL.
002078 **
002079 ** If CALLBACK returns an error, that causes the statement execution to
002080 ** abort. Hence, to configure a connection so that it throws an error
002081 ** on an attempt to bind an unknown variable, do something like this:
002082 **
002083 ** proc bind_error {name} {error "no such variable: $name"}
002084 ** db bind_fallback bind_error
002085 */
002086 case DB_BIND_FALLBACK: {
002087 if( objc>3 ){
002088 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
002089 return TCL_ERROR;
002090 }else if( objc==2 ){
002091 if( pDb->zBindFallback ){
002092 Tcl_AppendResult(interp, pDb->zBindFallback, (char*)0);
002093 }
002094 }else{
002095 char *zCallback;
002096 int len;
002097 if( pDb->zBindFallback ){
002098 Tcl_Free(pDb->zBindFallback);
002099 }
002100 zCallback = Tcl_GetStringFromObj(objv[2], &len);
002101 if( zCallback && len>0 ){
002102 pDb->zBindFallback = Tcl_Alloc( len + 1 );
002103 memcpy(pDb->zBindFallback, zCallback, len+1);
002104 }else{
002105 pDb->zBindFallback = 0;
002106 }
002107 }
002108 break;
002109 }
002110
002111 /* $db busy ?CALLBACK?
002112 **
002113 ** Invoke the given callback if an SQL statement attempts to open
002114 ** a locked database file.
002115 */
002116 case DB_BUSY: {
002117 if( objc>3 ){
002118 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
002119 return TCL_ERROR;
002120 }else if( objc==2 ){
002121 if( pDb->zBusy ){
002122 Tcl_AppendResult(interp, pDb->zBusy, (char*)0);
002123 }
002124 }else{
002125 char *zBusy;
002126 int len;
002127 if( pDb->zBusy ){
002128 Tcl_Free(pDb->zBusy);
002129 }
002130 zBusy = Tcl_GetStringFromObj(objv[2], &len);
002131 if( zBusy && len>0 ){
002132 pDb->zBusy = Tcl_Alloc( len + 1 );
002133 memcpy(pDb->zBusy, zBusy, len+1);
002134 }else{
002135 pDb->zBusy = 0;
002136 }
002137 if( pDb->zBusy ){
002138 pDb->interp = interp;
002139 sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
002140 }else{
002141 sqlite3_busy_handler(pDb->db, 0, 0);
002142 }
002143 }
002144 break;
002145 }
002146
002147 /* $db cache flush
002148 ** $db cache size n
002149 **
002150 ** Flush the prepared statement cache, or set the maximum number of
002151 ** cached statements.
002152 */
002153 case DB_CACHE: {
002154 char *subCmd;
002155 int n;
002156
002157 if( objc<=2 ){
002158 Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
002159 return TCL_ERROR;
002160 }
002161 subCmd = Tcl_GetStringFromObj( objv[2], 0 );
002162 if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
002163 if( objc!=3 ){
002164 Tcl_WrongNumArgs(interp, 2, objv, "flush");
002165 return TCL_ERROR;
002166 }else{
002167 flushStmtCache( pDb );
002168 }
002169 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
002170 if( objc!=4 ){
002171 Tcl_WrongNumArgs(interp, 2, objv, "size n");
002172 return TCL_ERROR;
002173 }else{
002174 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
002175 Tcl_AppendResult( interp, "cannot convert \"",
002176 Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
002177 return TCL_ERROR;
002178 }else{
002179 if( n<0 ){
002180 flushStmtCache( pDb );
002181 n = 0;
002182 }else if( n>MAX_PREPARED_STMTS ){
002183 n = MAX_PREPARED_STMTS;
002184 }
002185 pDb->maxStmt = n;
002186 }
002187 }
002188 }else{
002189 Tcl_AppendResult( interp, "bad option \"",
002190 Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
002191 (char*)0);
002192 return TCL_ERROR;
002193 }
002194 break;
002195 }
002196
002197 /* $db changes
002198 **
002199 ** Return the number of rows that were modified, inserted, or deleted by
002200 ** the most recent INSERT, UPDATE or DELETE statement, not including
002201 ** any changes made by trigger programs.
002202 */
002203 case DB_CHANGES: {
002204 Tcl_Obj *pResult;
002205 if( objc!=2 ){
002206 Tcl_WrongNumArgs(interp, 2, objv, "");
002207 return TCL_ERROR;
002208 }
002209 pResult = Tcl_GetObjResult(interp);
002210 Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
002211 break;
002212 }
002213
002214 /* $db close
002215 **
002216 ** Shutdown the database
002217 */
002218 case DB_CLOSE: {
002219 Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
002220 break;
002221 }
002222
002223 /*
002224 ** $db collate NAME SCRIPT
002225 **
002226 ** Create a new SQL collation function called NAME. Whenever
002227 ** that function is called, invoke SCRIPT to evaluate the function.
002228 */
002229 case DB_COLLATE: {
002230 SqlCollate *pCollate;
002231 char *zName;
002232 char *zScript;
002233 int nScript;
002234 if( objc!=4 ){
002235 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
002236 return TCL_ERROR;
002237 }
002238 zName = Tcl_GetStringFromObj(objv[2], 0);
002239 zScript = Tcl_GetStringFromObj(objv[3], &nScript);
002240 pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
002241 if( pCollate==0 ) return TCL_ERROR;
002242 pCollate->interp = interp;
002243 pCollate->pNext = pDb->pCollate;
002244 pCollate->zScript = (char*)&pCollate[1];
002245 pDb->pCollate = pCollate;
002246 memcpy(pCollate->zScript, zScript, nScript+1);
002247 if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
002248 pCollate, tclSqlCollate) ){
002249 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
002250 return TCL_ERROR;
002251 }
002252 break;
002253 }
002254
002255 /*
002256 ** $db collation_needed SCRIPT
002257 **
002258 ** Create a new SQL collation function called NAME. Whenever
002259 ** that function is called, invoke SCRIPT to evaluate the function.
002260 */
002261 case DB_COLLATION_NEEDED: {
002262 if( objc!=3 ){
002263 Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
002264 return TCL_ERROR;
002265 }
002266 if( pDb->pCollateNeeded ){
002267 Tcl_DecrRefCount(pDb->pCollateNeeded);
002268 }
002269 pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
002270 Tcl_IncrRefCount(pDb->pCollateNeeded);
002271 sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
002272 break;
002273 }
002274
002275 /* $db commit_hook ?CALLBACK?
002276 **
002277 ** Invoke the given callback just before committing every SQL transaction.
002278 ** If the callback throws an exception or returns non-zero, then the
002279 ** transaction is aborted. If CALLBACK is an empty string, the callback
002280 ** is disabled.
002281 */
002282 case DB_COMMIT_HOOK: {
002283 if( objc>3 ){
002284 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
002285 return TCL_ERROR;
002286 }else if( objc==2 ){
002287 if( pDb->zCommit ){
002288 Tcl_AppendResult(interp, pDb->zCommit, (char*)0);
002289 }
002290 }else{
002291 const char *zCommit;
002292 int len;
002293 if( pDb->zCommit ){
002294 Tcl_Free(pDb->zCommit);
002295 }
002296 zCommit = Tcl_GetStringFromObj(objv[2], &len);
002297 if( zCommit && len>0 ){
002298 pDb->zCommit = Tcl_Alloc( len + 1 );
002299 memcpy(pDb->zCommit, zCommit, len+1);
002300 }else{
002301 pDb->zCommit = 0;
002302 }
002303 if( pDb->zCommit ){
002304 pDb->interp = interp;
002305 sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
002306 }else{
002307 sqlite3_commit_hook(pDb->db, 0, 0);
002308 }
002309 }
002310 break;
002311 }
002312
002313 /* $db complete SQL
002314 **
002315 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if
002316 ** additional lines of input are needed. This is similar to the
002317 ** built-in "info complete" command of Tcl.
002318 */
002319 case DB_COMPLETE: {
002320 #ifndef SQLITE_OMIT_COMPLETE
002321 Tcl_Obj *pResult;
002322 int isComplete;
002323 if( objc!=3 ){
002324 Tcl_WrongNumArgs(interp, 2, objv, "SQL");
002325 return TCL_ERROR;
002326 }
002327 isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
002328 pResult = Tcl_GetObjResult(interp);
002329 Tcl_SetBooleanObj(pResult, isComplete);
002330 #endif
002331 break;
002332 }
002333
002334 /* $db config ?OPTION? ?BOOLEAN?
002335 **
002336 ** Configure the database connection using the sqlite3_db_config()
002337 ** interface.
002338 */
002339 case DB_CONFIG: {
002340 static const struct DbConfigChoices {
002341 const char *zName;
002342 int op;
002343 } aDbConfig[] = {
002344 { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
002345 { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
002346 { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
002347 { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
002348 { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
002349 { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
002350 { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
002351 { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
002352 { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
002353 { "defensive", SQLITE_DBCONFIG_DEFENSIVE },
002354 { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
002355 { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
002356 { "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
002357 { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
002358 };
002359 Tcl_Obj *pResult;
002360 int ii;
002361 if( objc>4 ){
002362 Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?");
002363 return TCL_ERROR;
002364 }
002365 if( objc==2 ){
002366 /* With no arguments, list all configuration options and with the
002367 ** current value */
002368 pResult = Tcl_NewListObj(0,0);
002369 for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
002370 int v = 0;
002371 sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v);
002372 Tcl_ListObjAppendElement(interp, pResult,
002373 Tcl_NewStringObj(aDbConfig[ii].zName,-1));
002374 Tcl_ListObjAppendElement(interp, pResult,
002375 Tcl_NewIntObj(v));
002376 }
002377 }else{
002378 const char *zOpt = Tcl_GetString(objv[2]);
002379 int onoff = -1;
002380 int v = 0;
002381 if( zOpt[0]=='-' ) zOpt++;
002382 for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
002383 if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break;
002384 }
002385 if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){
002386 Tcl_AppendResult(interp, "unknown config option: \"", zOpt,
002387 "\"", (void*)0);
002388 return TCL_ERROR;
002389 }
002390 if( objc==4 ){
002391 if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){
002392 return TCL_ERROR;
002393 }
002394 }
002395 sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v);
002396 pResult = Tcl_NewIntObj(v);
002397 }
002398 Tcl_SetObjResult(interp, pResult);
002399 break;
002400 }
002401
002402 /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
002403 **
002404 ** Copy data into table from filename, optionally using SEPARATOR
002405 ** as column separators. If a column contains a null string, or the
002406 ** value of NULLINDICATOR, a NULL is inserted for the column.
002407 ** conflict-algorithm is one of the sqlite conflict algorithms:
002408 ** rollback, abort, fail, ignore, replace
002409 ** On success, return the number of lines processed, not necessarily same
002410 ** as 'db changes' due to conflict-algorithm selected.
002411 **
002412 ** This code is basically an implementation/enhancement of
002413 ** the sqlite3 shell.c ".import" command.
002414 **
002415 ** This command usage is equivalent to the sqlite2.x COPY statement,
002416 ** which imports file data into a table using the PostgreSQL COPY file format:
002417 ** $db copy $conflit_algo $table_name $filename \t \\N
002418 */
002419 case DB_COPY: {
002420 char *zTable; /* Insert data into this table */
002421 char *zFile; /* The file from which to extract data */
002422 char *zConflict; /* The conflict algorithm to use */
002423 sqlite3_stmt *pStmt; /* A statement */
002424 int nCol; /* Number of columns in the table */
002425 int nByte; /* Number of bytes in an SQL string */
002426 int i, j; /* Loop counters */
002427 int nSep; /* Number of bytes in zSep[] */
002428 int nNull; /* Number of bytes in zNull[] */
002429 char *zSql; /* An SQL statement */
002430 char *zLine; /* A single line of input from the file */
002431 char **azCol; /* zLine[] broken up into columns */
002432 const char *zCommit; /* How to commit changes */
002433 FILE *in; /* The input file */
002434 int lineno = 0; /* Line number of input file */
002435 char zLineNum[80]; /* Line number print buffer */
002436 Tcl_Obj *pResult; /* interp result */
002437
002438 const char *zSep;
002439 const char *zNull;
002440 if( objc<5 || objc>7 ){
002441 Tcl_WrongNumArgs(interp, 2, objv,
002442 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
002443 return TCL_ERROR;
002444 }
002445 if( objc>=6 ){
002446 zSep = Tcl_GetStringFromObj(objv[5], 0);
002447 }else{
002448 zSep = "\t";
002449 }
002450 if( objc>=7 ){
002451 zNull = Tcl_GetStringFromObj(objv[6], 0);
002452 }else{
002453 zNull = "";
002454 }
002455 zConflict = Tcl_GetStringFromObj(objv[2], 0);
002456 zTable = Tcl_GetStringFromObj(objv[3], 0);
002457 zFile = Tcl_GetStringFromObj(objv[4], 0);
002458 nSep = strlen30(zSep);
002459 nNull = strlen30(zNull);
002460 if( nSep==0 ){
002461 Tcl_AppendResult(interp,"Error: non-null separator required for copy",
002462 (char*)0);
002463 return TCL_ERROR;
002464 }
002465 if(strcmp(zConflict, "rollback") != 0 &&
002466 strcmp(zConflict, "abort" ) != 0 &&
002467 strcmp(zConflict, "fail" ) != 0 &&
002468 strcmp(zConflict, "ignore" ) != 0 &&
002469 strcmp(zConflict, "replace" ) != 0 ) {
002470 Tcl_AppendResult(interp, "Error: \"", zConflict,
002471 "\", conflict-algorithm must be one of: rollback, "
002472 "abort, fail, ignore, or replace", (char*)0);
002473 return TCL_ERROR;
002474 }
002475 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
002476 if( zSql==0 ){
002477 Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0);
002478 return TCL_ERROR;
002479 }
002480 nByte = strlen30(zSql);
002481 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
002482 sqlite3_free(zSql);
002483 if( rc ){
002484 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
002485 nCol = 0;
002486 }else{
002487 nCol = sqlite3_column_count(pStmt);
002488 }
002489 sqlite3_finalize(pStmt);
002490 if( nCol==0 ) {
002491 return TCL_ERROR;
002492 }
002493 zSql = malloc( nByte + 50 + nCol*2 );
002494 if( zSql==0 ) {
002495 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
002496 return TCL_ERROR;
002497 }
002498 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
002499 zConflict, zTable);
002500 j = strlen30(zSql);
002501 for(i=1; i<nCol; i++){
002502 zSql[j++] = ',';
002503 zSql[j++] = '?';
002504 }
002505 zSql[j++] = ')';
002506 zSql[j] = 0;
002507 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
002508 free(zSql);
002509 if( rc ){
002510 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
002511 sqlite3_finalize(pStmt);
002512 return TCL_ERROR;
002513 }
002514 in = fopen(zFile, "rb");
002515 if( in==0 ){
002516 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0);
002517 sqlite3_finalize(pStmt);
002518 return TCL_ERROR;
002519 }
002520 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
002521 if( azCol==0 ) {
002522 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
002523 fclose(in);
002524 return TCL_ERROR;
002525 }
002526 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
002527 zCommit = "COMMIT";
002528 while( (zLine = local_getline(0, in))!=0 ){
002529 char *z;
002530 lineno++;
002531 azCol[0] = zLine;
002532 for(i=0, z=zLine; *z; z++){
002533 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
002534 *z = 0;
002535 i++;
002536 if( i<nCol ){
002537 azCol[i] = &z[nSep];
002538 z += nSep-1;
002539 }
002540 }
002541 }
002542 if( i+1!=nCol ){
002543 char *zErr;
002544 int nErr = strlen30(zFile) + 200;
002545 zErr = malloc(nErr);
002546 if( zErr ){
002547 sqlite3_snprintf(nErr, zErr,
002548 "Error: %s line %d: expected %d columns of data but found %d",
002549 zFile, lineno, nCol, i+1);
002550 Tcl_AppendResult(interp, zErr, (char*)0);
002551 free(zErr);
002552 }
002553 zCommit = "ROLLBACK";
002554 break;
002555 }
002556 for(i=0; i<nCol; i++){
002557 /* check for null data, if so, bind as null */
002558 if( (nNull>0 && strcmp(azCol[i], zNull)==0)
002559 || strlen30(azCol[i])==0
002560 ){
002561 sqlite3_bind_null(pStmt, i+1);
002562 }else{
002563 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
002564 }
002565 }
002566 sqlite3_step(pStmt);
002567 rc = sqlite3_reset(pStmt);
002568 free(zLine);
002569 if( rc!=SQLITE_OK ){
002570 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0);
002571 zCommit = "ROLLBACK";
002572 break;
002573 }
002574 }
002575 free(azCol);
002576 fclose(in);
002577 sqlite3_finalize(pStmt);
002578 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
002579
002580 if( zCommit[0] == 'C' ){
002581 /* success, set result as number of lines processed */
002582 pResult = Tcl_GetObjResult(interp);
002583 Tcl_SetIntObj(pResult, lineno);
002584 rc = TCL_OK;
002585 }else{
002586 /* failure, append lineno where failed */
002587 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
002588 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,
002589 (char*)0);
002590 rc = TCL_ERROR;
002591 }
002592 break;
002593 }
002594
002595 /*
002596 ** $db deserialize ?-maxsize N? ?-readonly BOOL? ?DATABASE? VALUE
002597 **
002598 ** Reopen DATABASE (default "main") using the content in $VALUE
002599 */
002600 case DB_DESERIALIZE: {
002601 #ifndef SQLITE_ENABLE_DESERIALIZE
002602 Tcl_AppendResult(interp, "MEMDB not available in this build",
002603 (char*)0);
002604 rc = TCL_ERROR;
002605 #else
002606 const char *zSchema = 0;
002607 Tcl_Obj *pValue = 0;
002608 unsigned char *pBA;
002609 unsigned char *pData;
002610 int len, xrc;
002611 sqlite3_int64 mxSize = 0;
002612 int i;
002613 int isReadonly = 0;
002614
002615
002616 if( objc<3 ){
002617 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
002618 rc = TCL_ERROR;
002619 break;
002620 }
002621 for(i=2; i<objc-1; i++){
002622 const char *z = Tcl_GetString(objv[i]);
002623 if( strcmp(z,"-maxsize")==0 && i<objc-2 ){
002624 rc = Tcl_GetWideIntFromObj(interp, objv[++i], &mxSize);
002625 if( rc ) goto deserialize_error;
002626 continue;
002627 }
002628 if( strcmp(z,"-readonly")==0 && i<objc-2 ){
002629 rc = Tcl_GetBooleanFromObj(interp, objv[++i], &isReadonly);
002630 if( rc ) goto deserialize_error;
002631 continue;
002632 }
002633 if( zSchema==0 && i==objc-2 && z[0]!='-' ){
002634 zSchema = z;
002635 continue;
002636 }
002637 Tcl_AppendResult(interp, "unknown option: ", z, (char*)0);
002638 rc = TCL_ERROR;
002639 goto deserialize_error;
002640 }
002641 pValue = objv[objc-1];
002642 pBA = Tcl_GetByteArrayFromObj(pValue, &len);
002643 pData = sqlite3_malloc64( len );
002644 if( pData==0 && len>0 ){
002645 Tcl_AppendResult(interp, "out of memory", (char*)0);
002646 rc = TCL_ERROR;
002647 }else{
002648 int flags;
002649 if( len>0 ) memcpy(pData, pBA, len);
002650 if( isReadonly ){
002651 flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_READONLY;
002652 }else{
002653 flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE;
002654 }
002655 xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len, flags);
002656 if( xrc ){
002657 Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
002658 rc = TCL_ERROR;
002659 }
002660 if( mxSize>0 ){
002661 sqlite3_file_control(pDb->db, zSchema,SQLITE_FCNTL_SIZE_LIMIT,&mxSize);
002662 }
002663 }
002664 deserialize_error:
002665 #endif
002666 break;
002667 }
002668
002669 /*
002670 ** $db enable_load_extension BOOLEAN
002671 **
002672 ** Turn the extension loading feature on or off. It if off by
002673 ** default.
002674 */
002675 case DB_ENABLE_LOAD_EXTENSION: {
002676 #ifndef SQLITE_OMIT_LOAD_EXTENSION
002677 int onoff;
002678 if( objc!=3 ){
002679 Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");
002680 return TCL_ERROR;
002681 }
002682 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
002683 return TCL_ERROR;
002684 }
002685 sqlite3_enable_load_extension(pDb->db, onoff);
002686 break;
002687 #else
002688 Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
002689 (char*)0);
002690 return TCL_ERROR;
002691 #endif
002692 }
002693
002694 /*
002695 ** $db errorcode
002696 **
002697 ** Return the numeric error code that was returned by the most recent
002698 ** call to sqlite3_exec().
002699 */
002700 case DB_ERRORCODE: {
002701 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
002702 break;
002703 }
002704
002705 /*
002706 ** $db exists $sql
002707 ** $db onecolumn $sql
002708 **
002709 ** The onecolumn method is the equivalent of:
002710 ** lindex [$db eval $sql] 0
002711 */
002712 case DB_EXISTS:
002713 case DB_ONECOLUMN: {
002714 Tcl_Obj *pResult = 0;
002715 DbEvalContext sEval;
002716 if( objc!=3 ){
002717 Tcl_WrongNumArgs(interp, 2, objv, "SQL");
002718 return TCL_ERROR;
002719 }
002720
002721 dbEvalInit(&sEval, pDb, objv[2], 0, 0);
002722 rc = dbEvalStep(&sEval);
002723 if( choice==DB_ONECOLUMN ){
002724 if( rc==TCL_OK ){
002725 pResult = dbEvalColumnValue(&sEval, 0);
002726 }else if( rc==TCL_BREAK ){
002727 Tcl_ResetResult(interp);
002728 }
002729 }else if( rc==TCL_BREAK || rc==TCL_OK ){
002730 pResult = Tcl_NewBooleanObj(rc==TCL_OK);
002731 }
002732 dbEvalFinalize(&sEval);
002733 if( pResult ) Tcl_SetObjResult(interp, pResult);
002734
002735 if( rc==TCL_BREAK ){
002736 rc = TCL_OK;
002737 }
002738 break;
002739 }
002740
002741 /*
002742 ** $db eval ?options? $sql ?array? ?{ ...code... }?
002743 **
002744 ** The SQL statement in $sql is evaluated. For each row, the values are
002745 ** placed in elements of the array named "array" and ...code... is executed.
002746 ** If "array" and "code" are omitted, then no callback is every invoked.
002747 ** If "array" is an empty string, then the values are placed in variables
002748 ** that have the same name as the fields extracted by the query.
002749 */
002750 case DB_EVAL: {
002751 int evalFlags = 0;
002752 const char *zOpt;
002753 while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){
002754 if( strcmp(zOpt, "-withoutnulls")==0 ){
002755 evalFlags |= SQLITE_EVAL_WITHOUTNULLS;
002756 }
002757 else{
002758 Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0);
002759 return TCL_ERROR;
002760 }
002761 objc--;
002762 objv++;
002763 }
002764 if( objc<3 || objc>5 ){
002765 Tcl_WrongNumArgs(interp, 2, objv,
002766 "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?");
002767 return TCL_ERROR;
002768 }
002769
002770 if( objc==3 ){
002771 DbEvalContext sEval;
002772 Tcl_Obj *pRet = Tcl_NewObj();
002773 Tcl_IncrRefCount(pRet);
002774 dbEvalInit(&sEval, pDb, objv[2], 0, 0);
002775 while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
002776 int i;
002777 int nCol;
002778 dbEvalRowInfo(&sEval, &nCol, 0);
002779 for(i=0; i<nCol; i++){
002780 Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
002781 }
002782 }
002783 dbEvalFinalize(&sEval);
002784 if( rc==TCL_BREAK ){
002785 Tcl_SetObjResult(interp, pRet);
002786 rc = TCL_OK;
002787 }
002788 Tcl_DecrRefCount(pRet);
002789 }else{
002790 ClientData cd2[2];
002791 DbEvalContext *p;
002792 Tcl_Obj *pArray = 0;
002793 Tcl_Obj *pScript;
002794
002795 if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){
002796 pArray = objv[3];
002797 }
002798 pScript = objv[objc-1];
002799 Tcl_IncrRefCount(pScript);
002800
002801 p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
002802 dbEvalInit(p, pDb, objv[2], pArray, evalFlags);
002803
002804 cd2[0] = (void *)p;
002805 cd2[1] = (void *)pScript;
002806 rc = DbEvalNextCmd(cd2, interp, TCL_OK);
002807 }
002808 break;
002809 }
002810
002811 /*
002812 ** $db function NAME [OPTIONS] SCRIPT
002813 **
002814 ** Create a new SQL function called NAME. Whenever that function is
002815 ** called, invoke SCRIPT to evaluate the function.
002816 **
002817 ** Options:
002818 ** --argcount N Function has exactly N arguments
002819 ** --deterministic The function is pure
002820 ** --directonly Prohibit use inside triggers and views
002821 ** --returntype TYPE Specify the return type of the function
002822 */
002823 case DB_FUNCTION: {
002824 int flags = SQLITE_UTF8;
002825 SqlFunc *pFunc;
002826 Tcl_Obj *pScript;
002827 char *zName;
002828 int nArg = -1;
002829 int i;
002830 int eType = SQLITE_NULL;
002831 if( objc<4 ){
002832 Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT");
002833 return TCL_ERROR;
002834 }
002835 for(i=3; i<(objc-1); i++){
002836 const char *z = Tcl_GetString(objv[i]);
002837 int n = strlen30(z);
002838 if( n>1 && strncmp(z, "-argcount",n)==0 ){
002839 if( i==(objc-2) ){
002840 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
002841 return TCL_ERROR;
002842 }
002843 if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR;
002844 if( nArg<0 ){
002845 Tcl_AppendResult(interp, "number of arguments must be non-negative",
002846 (char*)0);
002847 return TCL_ERROR;
002848 }
002849 i++;
002850 }else
002851 if( n>1 && strncmp(z, "-deterministic",n)==0 ){
002852 flags |= SQLITE_DETERMINISTIC;
002853 }else
002854 if( n>1 && strncmp(z, "-directonly",n)==0 ){
002855 flags |= SQLITE_DIRECTONLY;
002856 }else
002857 if( n>1 && strncmp(z, "-returntype", n)==0 ){
002858 const char *azType[] = {"integer", "real", "text", "blob", "any", 0};
002859 assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 );
002860 assert( SQLITE_BLOB==4 && SQLITE_NULL==5 );
002861 if( i==(objc-2) ){
002862 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
002863 return TCL_ERROR;
002864 }
002865 i++;
002866 if( Tcl_GetIndexFromObj(interp, objv[i], azType, "type", 0, &eType) ){
002867 return TCL_ERROR;
002868 }
002869 eType++;
002870 }else{
002871 Tcl_AppendResult(interp, "bad option \"", z,
002872 "\": must be -argcount, -deterministic, -directonly,"
002873 " or -returntype", (char*)0
002874 );
002875 return TCL_ERROR;
002876 }
002877 }
002878
002879 pScript = objv[objc-1];
002880 zName = Tcl_GetStringFromObj(objv[2], 0);
002881 pFunc = findSqlFunc(pDb, zName);
002882 if( pFunc==0 ) return TCL_ERROR;
002883 if( pFunc->pScript ){
002884 Tcl_DecrRefCount(pFunc->pScript);
002885 }
002886 pFunc->pScript = pScript;
002887 Tcl_IncrRefCount(pScript);
002888 pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
002889 pFunc->eType = eType;
002890 rc = sqlite3_create_function(pDb->db, zName, nArg, flags,
002891 pFunc, tclSqlFunc, 0, 0);
002892 if( rc!=SQLITE_OK ){
002893 rc = TCL_ERROR;
002894 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
002895 }
002896 break;
002897 }
002898
002899 /*
002900 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID
002901 */
002902 case DB_INCRBLOB: {
002903 #ifdef SQLITE_OMIT_INCRBLOB
002904 Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0);
002905 return TCL_ERROR;
002906 #else
002907 int isReadonly = 0;
002908 const char *zDb = "main";
002909 const char *zTable;
002910 const char *zColumn;
002911 Tcl_WideInt iRow;
002912
002913 /* Check for the -readonly option */
002914 if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
002915 isReadonly = 1;
002916 }
002917
002918 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){
002919 Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");
002920 return TCL_ERROR;
002921 }
002922
002923 if( objc==(6+isReadonly) ){
002924 zDb = Tcl_GetString(objv[2]);
002925 }
002926 zTable = Tcl_GetString(objv[objc-3]);
002927 zColumn = Tcl_GetString(objv[objc-2]);
002928 rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow);
002929
002930 if( rc==TCL_OK ){
002931 rc = createIncrblobChannel(
002932 interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly
002933 );
002934 }
002935 #endif
002936 break;
002937 }
002938
002939 /*
002940 ** $db interrupt
002941 **
002942 ** Interrupt the execution of the inner-most SQL interpreter. This
002943 ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
002944 */
002945 case DB_INTERRUPT: {
002946 sqlite3_interrupt(pDb->db);
002947 break;
002948 }
002949
002950 /*
002951 ** $db nullvalue ?STRING?
002952 **
002953 ** Change text used when a NULL comes back from the database. If ?STRING?
002954 ** is not present, then the current string used for NULL is returned.
002955 ** If STRING is present, then STRING is returned.
002956 **
002957 */
002958 case DB_NULLVALUE: {
002959 if( objc!=2 && objc!=3 ){
002960 Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
002961 return TCL_ERROR;
002962 }
002963 if( objc==3 ){
002964 int len;
002965 char *zNull = Tcl_GetStringFromObj(objv[2], &len);
002966 if( pDb->zNull ){
002967 Tcl_Free(pDb->zNull);
002968 }
002969 if( zNull && len>0 ){
002970 pDb->zNull = Tcl_Alloc( len + 1 );
002971 memcpy(pDb->zNull, zNull, len);
002972 pDb->zNull[len] = '\0';
002973 }else{
002974 pDb->zNull = 0;
002975 }
002976 }
002977 Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
002978 break;
002979 }
002980
002981 /*
002982 ** $db last_insert_rowid
002983 **
002984 ** Return an integer which is the ROWID for the most recent insert.
002985 */
002986 case DB_LAST_INSERT_ROWID: {
002987 Tcl_Obj *pResult;
002988 Tcl_WideInt rowid;
002989 if( objc!=2 ){
002990 Tcl_WrongNumArgs(interp, 2, objv, "");
002991 return TCL_ERROR;
002992 }
002993 rowid = sqlite3_last_insert_rowid(pDb->db);
002994 pResult = Tcl_GetObjResult(interp);
002995 Tcl_SetWideIntObj(pResult, rowid);
002996 break;
002997 }
002998
002999 /*
003000 ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
003001 */
003002
003003 /* $db progress ?N CALLBACK?
003004 **
003005 ** Invoke the given callback every N virtual machine opcodes while executing
003006 ** queries.
003007 */
003008 case DB_PROGRESS: {
003009 if( objc==2 ){
003010 if( pDb->zProgress ){
003011 Tcl_AppendResult(interp, pDb->zProgress, (char*)0);
003012 }
003013 }else if( objc==4 ){
003014 char *zProgress;
003015 int len;
003016 int N;
003017 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
003018 return TCL_ERROR;
003019 };
003020 if( pDb->zProgress ){
003021 Tcl_Free(pDb->zProgress);
003022 }
003023 zProgress = Tcl_GetStringFromObj(objv[3], &len);
003024 if( zProgress && len>0 ){
003025 pDb->zProgress = Tcl_Alloc( len + 1 );
003026 memcpy(pDb->zProgress, zProgress, len+1);
003027 }else{
003028 pDb->zProgress = 0;
003029 }
003030 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
003031 if( pDb->zProgress ){
003032 pDb->interp = interp;
003033 sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
003034 }else{
003035 sqlite3_progress_handler(pDb->db, 0, 0, 0);
003036 }
003037 #endif
003038 }else{
003039 Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
003040 return TCL_ERROR;
003041 }
003042 break;
003043 }
003044
003045 /* $db profile ?CALLBACK?
003046 **
003047 ** Make arrangements to invoke the CALLBACK routine after each SQL statement
003048 ** that has run. The text of the SQL and the amount of elapse time are
003049 ** appended to CALLBACK before the script is run.
003050 */
003051 case DB_PROFILE: {
003052 if( objc>3 ){
003053 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
003054 return TCL_ERROR;
003055 }else if( objc==2 ){
003056 if( pDb->zProfile ){
003057 Tcl_AppendResult(interp, pDb->zProfile, (char*)0);
003058 }
003059 }else{
003060 char *zProfile;
003061 int len;
003062 if( pDb->zProfile ){
003063 Tcl_Free(pDb->zProfile);
003064 }
003065 zProfile = Tcl_GetStringFromObj(objv[2], &len);
003066 if( zProfile && len>0 ){
003067 pDb->zProfile = Tcl_Alloc( len + 1 );
003068 memcpy(pDb->zProfile, zProfile, len+1);
003069 }else{
003070 pDb->zProfile = 0;
003071 }
003072 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
003073 !defined(SQLITE_OMIT_DEPRECATED)
003074 if( pDb->zProfile ){
003075 pDb->interp = interp;
003076 sqlite3_profile(pDb->db, DbProfileHandler, pDb);
003077 }else{
003078 sqlite3_profile(pDb->db, 0, 0);
003079 }
003080 #endif
003081 }
003082 break;
003083 }
003084
003085 /*
003086 ** $db rekey KEY
003087 **
003088 ** Change the encryption key on the currently open database.
003089 */
003090 case DB_REKEY: {
003091 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003092 int nKey;
003093 void *pKey;
003094 #endif
003095 if( objc!=3 ){
003096 Tcl_WrongNumArgs(interp, 2, objv, "KEY");
003097 return TCL_ERROR;
003098 }
003099 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003100 pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
003101 rc = sqlite3_rekey(pDb->db, pKey, nKey);
003102 if( rc ){
003103 Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
003104 rc = TCL_ERROR;
003105 }
003106 #endif
003107 break;
003108 }
003109
003110 /* $db restore ?DATABASE? FILENAME
003111 **
003112 ** Open a database file named FILENAME. Transfer the content
003113 ** of FILENAME into the local database DATABASE (default: "main").
003114 */
003115 case DB_RESTORE: {
003116 const char *zSrcFile;
003117 const char *zDestDb;
003118 sqlite3 *pSrc;
003119 sqlite3_backup *pBackup;
003120 int nTimeout = 0;
003121
003122 if( objc==3 ){
003123 zDestDb = "main";
003124 zSrcFile = Tcl_GetString(objv[2]);
003125 }else if( objc==4 ){
003126 zDestDb = Tcl_GetString(objv[2]);
003127 zSrcFile = Tcl_GetString(objv[3]);
003128 }else{
003129 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
003130 return TCL_ERROR;
003131 }
003132 rc = sqlite3_open_v2(zSrcFile, &pSrc,
003133 SQLITE_OPEN_READONLY | pDb->openFlags, 0);
003134 if( rc!=SQLITE_OK ){
003135 Tcl_AppendResult(interp, "cannot open source database: ",
003136 sqlite3_errmsg(pSrc), (char*)0);
003137 sqlite3_close(pSrc);
003138 return TCL_ERROR;
003139 }
003140 pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
003141 if( pBackup==0 ){
003142 Tcl_AppendResult(interp, "restore failed: ",
003143 sqlite3_errmsg(pDb->db), (char*)0);
003144 sqlite3_close(pSrc);
003145 return TCL_ERROR;
003146 }
003147 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
003148 || rc==SQLITE_BUSY ){
003149 if( rc==SQLITE_BUSY ){
003150 if( nTimeout++ >= 3 ) break;
003151 sqlite3_sleep(100);
003152 }
003153 }
003154 sqlite3_backup_finish(pBackup);
003155 if( rc==SQLITE_DONE ){
003156 rc = TCL_OK;
003157 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
003158 Tcl_AppendResult(interp, "restore failed: source database busy",
003159 (char*)0);
003160 rc = TCL_ERROR;
003161 }else{
003162 Tcl_AppendResult(interp, "restore failed: ",
003163 sqlite3_errmsg(pDb->db), (char*)0);
003164 rc = TCL_ERROR;
003165 }
003166 sqlite3_close(pSrc);
003167 break;
003168 }
003169
003170 /*
003171 ** $db serialize ?DATABASE?
003172 **
003173 ** Return a serialization of a database.
003174 */
003175 case DB_SERIALIZE: {
003176 #ifndef SQLITE_ENABLE_DESERIALIZE
003177 Tcl_AppendResult(interp, "MEMDB not available in this build",
003178 (char*)0);
003179 rc = TCL_ERROR;
003180 #else
003181 const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
003182 sqlite3_int64 sz = 0;
003183 unsigned char *pData;
003184 if( objc!=2 && objc!=3 ){
003185 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
003186 rc = TCL_ERROR;
003187 }else{
003188 int needFree;
003189 pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
003190 if( pData ){
003191 needFree = 0;
003192 }else{
003193 pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
003194 needFree = 1;
003195 }
003196 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
003197 if( needFree ) sqlite3_free(pData);
003198 }
003199 #endif
003200 break;
003201 }
003202
003203 /*
003204 ** $db status (step|sort|autoindex|vmstep)
003205 **
003206 ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
003207 ** SQLITE_STMTSTATUS_SORT for the most recent eval.
003208 */
003209 case DB_STATUS: {
003210 int v;
003211 const char *zOp;
003212 if( objc!=3 ){
003213 Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)");
003214 return TCL_ERROR;
003215 }
003216 zOp = Tcl_GetString(objv[2]);
003217 if( strcmp(zOp, "step")==0 ){
003218 v = pDb->nStep;
003219 }else if( strcmp(zOp, "sort")==0 ){
003220 v = pDb->nSort;
003221 }else if( strcmp(zOp, "autoindex")==0 ){
003222 v = pDb->nIndex;
003223 }else if( strcmp(zOp, "vmstep")==0 ){
003224 v = pDb->nVMStep;
003225 }else{
003226 Tcl_AppendResult(interp,
003227 "bad argument: should be autoindex, step, sort or vmstep",
003228 (char*)0);
003229 return TCL_ERROR;
003230 }
003231 Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
003232 break;
003233 }
003234
003235 /*
003236 ** $db timeout MILLESECONDS
003237 **
003238 ** Delay for the number of milliseconds specified when a file is locked.
003239 */
003240 case DB_TIMEOUT: {
003241 int ms;
003242 if( objc!=3 ){
003243 Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
003244 return TCL_ERROR;
003245 }
003246 if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
003247 sqlite3_busy_timeout(pDb->db, ms);
003248 break;
003249 }
003250
003251 /*
003252 ** $db total_changes
003253 **
003254 ** Return the number of rows that were modified, inserted, or deleted
003255 ** since the database handle was created.
003256 */
003257 case DB_TOTAL_CHANGES: {
003258 Tcl_Obj *pResult;
003259 if( objc!=2 ){
003260 Tcl_WrongNumArgs(interp, 2, objv, "");
003261 return TCL_ERROR;
003262 }
003263 pResult = Tcl_GetObjResult(interp);
003264 Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
003265 break;
003266 }
003267
003268 /* $db trace ?CALLBACK?
003269 **
003270 ** Make arrangements to invoke the CALLBACK routine for each SQL statement
003271 ** that is executed. The text of the SQL is appended to CALLBACK before
003272 ** it is executed.
003273 */
003274 case DB_TRACE: {
003275 if( objc>3 ){
003276 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
003277 return TCL_ERROR;
003278 }else if( objc==2 ){
003279 if( pDb->zTrace ){
003280 Tcl_AppendResult(interp, pDb->zTrace, (char*)0);
003281 }
003282 }else{
003283 char *zTrace;
003284 int len;
003285 if( pDb->zTrace ){
003286 Tcl_Free(pDb->zTrace);
003287 }
003288 zTrace = Tcl_GetStringFromObj(objv[2], &len);
003289 if( zTrace && len>0 ){
003290 pDb->zTrace = Tcl_Alloc( len + 1 );
003291 memcpy(pDb->zTrace, zTrace, len+1);
003292 }else{
003293 pDb->zTrace = 0;
003294 }
003295 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
003296 !defined(SQLITE_OMIT_DEPRECATED)
003297 if( pDb->zTrace ){
003298 pDb->interp = interp;
003299 sqlite3_trace(pDb->db, DbTraceHandler, pDb);
003300 }else{
003301 sqlite3_trace(pDb->db, 0, 0);
003302 }
003303 #endif
003304 }
003305 break;
003306 }
003307
003308 /* $db trace_v2 ?CALLBACK? ?MASK?
003309 **
003310 ** Make arrangements to invoke the CALLBACK routine for each trace event
003311 ** matching the mask that is generated. The parameters are appended to
003312 ** CALLBACK before it is executed.
003313 */
003314 case DB_TRACE_V2: {
003315 if( objc>4 ){
003316 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
003317 return TCL_ERROR;
003318 }else if( objc==2 ){
003319 if( pDb->zTraceV2 ){
003320 Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
003321 }
003322 }else{
003323 char *zTraceV2;
003324 int len;
003325 Tcl_WideInt wMask = 0;
003326 if( objc==4 ){
003327 static const char *TTYPE_strs[] = {
003328 "statement", "profile", "row", "close", 0
003329 };
003330 enum TTYPE_enum {
003331 TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE
003332 };
003333 int i;
003334 if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){
003335 return TCL_ERROR;
003336 }
003337 for(i=0; i<len; i++){
003338 Tcl_Obj *pObj;
003339 int ttype;
003340 if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){
003341 return TCL_ERROR;
003342 }
003343 if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type",
003344 0, &ttype)!=TCL_OK ){
003345 Tcl_WideInt wType;
003346 Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
003347 Tcl_IncrRefCount(pError);
003348 if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){
003349 Tcl_DecrRefCount(pError);
003350 wMask |= wType;
003351 }else{
003352 Tcl_SetObjResult(interp, pError);
003353 Tcl_DecrRefCount(pError);
003354 return TCL_ERROR;
003355 }
003356 }else{
003357 switch( (enum TTYPE_enum)ttype ){
003358 case TTYPE_STMT: wMask |= SQLITE_TRACE_STMT; break;
003359 case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break;
003360 case TTYPE_ROW: wMask |= SQLITE_TRACE_ROW; break;
003361 case TTYPE_CLOSE: wMask |= SQLITE_TRACE_CLOSE; break;
003362 }
003363 }
003364 }
003365 }else{
003366 wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */
003367 }
003368 if( pDb->zTraceV2 ){
003369 Tcl_Free(pDb->zTraceV2);
003370 }
003371 zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
003372 if( zTraceV2 && len>0 ){
003373 pDb->zTraceV2 = Tcl_Alloc( len + 1 );
003374 memcpy(pDb->zTraceV2, zTraceV2, len+1);
003375 }else{
003376 pDb->zTraceV2 = 0;
003377 }
003378 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
003379 if( pDb->zTraceV2 ){
003380 pDb->interp = interp;
003381 sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb);
003382 }else{
003383 sqlite3_trace_v2(pDb->db, 0, 0, 0);
003384 }
003385 #endif
003386 }
003387 break;
003388 }
003389
003390 /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
003391 **
003392 ** Start a new transaction (if we are not already in the midst of a
003393 ** transaction) and execute the TCL script SCRIPT. After SCRIPT
003394 ** completes, either commit the transaction or roll it back if SCRIPT
003395 ** throws an exception. Or if no new transation was started, do nothing.
003396 ** pass the exception on up the stack.
003397 **
003398 ** This command was inspired by Dave Thomas's talk on Ruby at the
003399 ** 2005 O'Reilly Open Source Convention (OSCON).
003400 */
003401 case DB_TRANSACTION: {
003402 Tcl_Obj *pScript;
003403 const char *zBegin = "SAVEPOINT _tcl_transaction";
003404 if( objc!=3 && objc!=4 ){
003405 Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
003406 return TCL_ERROR;
003407 }
003408
003409 if( pDb->nTransaction==0 && objc==4 ){
003410 static const char *TTYPE_strs[] = {
003411 "deferred", "exclusive", "immediate", 0
003412 };
003413 enum TTYPE_enum {
003414 TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
003415 };
003416 int ttype;
003417 if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
003418 0, &ttype) ){
003419 return TCL_ERROR;
003420 }
003421 switch( (enum TTYPE_enum)ttype ){
003422 case TTYPE_DEFERRED: /* no-op */; break;
003423 case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break;
003424 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break;
003425 }
003426 }
003427 pScript = objv[objc-1];
003428
003429 /* Run the SQLite BEGIN command to open a transaction or savepoint. */
003430 pDb->disableAuth++;
003431 rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
003432 pDb->disableAuth--;
003433 if( rc!=SQLITE_OK ){
003434 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
003435 return TCL_ERROR;
003436 }
003437 pDb->nTransaction++;
003438
003439 /* If using NRE, schedule a callback to invoke the script pScript, then
003440 ** a second callback to commit (or rollback) the transaction or savepoint
003441 ** opened above. If not using NRE, evaluate the script directly, then
003442 ** call function DbTransPostCmd() to commit (or rollback) the transaction
003443 ** or savepoint. */
003444 if( DbUseNre() ){
003445 Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
003446 (void)Tcl_NREvalObj(interp, pScript, 0);
003447 }else{
003448 rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
003449 }
003450 break;
003451 }
003452
003453 /*
003454 ** $db unlock_notify ?script?
003455 */
003456 case DB_UNLOCK_NOTIFY: {
003457 #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
003458 Tcl_AppendResult(interp, "unlock_notify not available in this build",
003459 (char*)0);
003460 rc = TCL_ERROR;
003461 #else
003462 if( objc!=2 && objc!=3 ){
003463 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
003464 rc = TCL_ERROR;
003465 }else{
003466 void (*xNotify)(void **, int) = 0;
003467 void *pNotifyArg = 0;
003468
003469 if( pDb->pUnlockNotify ){
003470 Tcl_DecrRefCount(pDb->pUnlockNotify);
003471 pDb->pUnlockNotify = 0;
003472 }
003473
003474 if( objc==3 ){
003475 xNotify = DbUnlockNotify;
003476 pNotifyArg = (void *)pDb;
003477 pDb->pUnlockNotify = objv[2];
003478 Tcl_IncrRefCount(pDb->pUnlockNotify);
003479 }
003480
003481 if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
003482 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
003483 rc = TCL_ERROR;
003484 }
003485 }
003486 #endif
003487 break;
003488 }
003489
003490 /*
003491 ** $db preupdate_hook count
003492 ** $db preupdate_hook hook ?SCRIPT?
003493 ** $db preupdate_hook new INDEX
003494 ** $db preupdate_hook old INDEX
003495 */
003496 case DB_PREUPDATE: {
003497 #ifndef SQLITE_ENABLE_PREUPDATE_HOOK
003498 Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time",
003499 (char*)0);
003500 rc = TCL_ERROR;
003501 #else
003502 static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0};
003503 enum DbPreupdateSubCmd {
003504 PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD
003505 };
003506 int iSub;
003507
003508 if( objc<3 ){
003509 Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?");
003510 }
003511 if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){
003512 return TCL_ERROR;
003513 }
003514
003515 switch( (enum DbPreupdateSubCmd)iSub ){
003516 case PRE_COUNT: {
003517 int nCol = sqlite3_preupdate_count(pDb->db);
003518 Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol));
003519 break;
003520 }
003521
003522 case PRE_HOOK: {
003523 if( objc>4 ){
003524 Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?");
003525 return TCL_ERROR;
003526 }
003527 DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook);
003528 break;
003529 }
003530
003531 case PRE_DEPTH: {
003532 Tcl_Obj *pRet;
003533 if( objc!=3 ){
003534 Tcl_WrongNumArgs(interp, 3, objv, "");
003535 return TCL_ERROR;
003536 }
003537 pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db));
003538 Tcl_SetObjResult(interp, pRet);
003539 break;
003540 }
003541
003542 case PRE_NEW:
003543 case PRE_OLD: {
003544 int iIdx;
003545 sqlite3_value *pValue;
003546 if( objc!=4 ){
003547 Tcl_WrongNumArgs(interp, 3, objv, "INDEX");
003548 return TCL_ERROR;
003549 }
003550 if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){
003551 return TCL_ERROR;
003552 }
003553
003554 if( iSub==PRE_OLD ){
003555 rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue);
003556 }else{
003557 assert( iSub==PRE_NEW );
003558 rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue);
003559 }
003560
003561 if( rc==SQLITE_OK ){
003562 Tcl_Obj *pObj;
003563 pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1);
003564 Tcl_SetObjResult(interp, pObj);
003565 }else{
003566 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
003567 return TCL_ERROR;
003568 }
003569 }
003570 }
003571 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
003572 break;
003573 }
003574
003575 /*
003576 ** $db wal_hook ?script?
003577 ** $db update_hook ?script?
003578 ** $db rollback_hook ?script?
003579 */
003580 case DB_WAL_HOOK:
003581 case DB_UPDATE_HOOK:
003582 case DB_ROLLBACK_HOOK: {
003583 /* set ppHook to point at pUpdateHook or pRollbackHook, depending on
003584 ** whether [$db update_hook] or [$db rollback_hook] was invoked.
003585 */
003586 Tcl_Obj **ppHook = 0;
003587 if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
003588 if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
003589 if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
003590 if( objc>3 ){
003591 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
003592 return TCL_ERROR;
003593 }
003594
003595 DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook);
003596 break;
003597 }
003598
003599 /* $db version
003600 **
003601 ** Return the version string for this database.
003602 */
003603 case DB_VERSION: {
003604 int i;
003605 for(i=2; i<objc; i++){
003606 const char *zArg = Tcl_GetString(objv[i]);
003607 /* Optional arguments to $db version are used for testing purpose */
003608 #ifdef SQLITE_TEST
003609 /* $db version -use-legacy-prepare BOOLEAN
003610 **
003611 ** Turn the use of legacy sqlite3_prepare() on or off.
003612 */
003613 if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){
003614 i++;
003615 if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){
003616 return TCL_ERROR;
003617 }
003618 }else
003619
003620 /* $db version -last-stmt-ptr
003621 **
003622 ** Return a string which is a hex encoding of the pointer to the
003623 ** most recent sqlite3_stmt in the statement cache.
003624 */
003625 if( strcmp(zArg, "-last-stmt-ptr")==0 ){
003626 char zBuf[100];
003627 sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
003628 pDb->stmtList ? pDb->stmtList->pStmt: 0);
003629 Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
003630 }else
003631 #endif /* SQLITE_TEST */
003632 {
003633 Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0);
003634 return TCL_ERROR;
003635 }
003636 }
003637 if( i==2 ){
003638 Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
003639 }
003640 break;
003641 }
003642
003643
003644 } /* End of the SWITCH statement */
003645 return rc;
003646 }
003647
003648 #if SQLITE_TCL_NRE
003649 /*
003650 ** Adaptor that provides an objCmd interface to the NRE-enabled
003651 ** interface implementation.
003652 */
003653 static int SQLITE_TCLAPI DbObjCmdAdaptor(
003654 void *cd,
003655 Tcl_Interp *interp,
003656 int objc,
003657 Tcl_Obj *const*objv
003658 ){
003659 return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv);
003660 }
003661 #endif /* SQLITE_TCL_NRE */
003662
003663 /*
003664 ** Issue the usage message when the "sqlite3" command arguments are
003665 ** incorrect.
003666 */
003667 static int sqliteCmdUsage(
003668 Tcl_Interp *interp,
003669 Tcl_Obj *const*objv
003670 ){
003671 Tcl_WrongNumArgs(interp, 1, objv,
003672 "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
003673 " ?-nofollow BOOLEAN?"
003674 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
003675 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003676 " ?-key CODECKEY?"
003677 #endif
003678 );
003679 return TCL_ERROR;
003680 }
003681
003682 /*
003683 ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
003684 ** ?-create BOOLEAN? ?-nomutex BOOLEAN?
003685 ** ?-nofollow BOOLEAN?
003686 **
003687 ** This is the main Tcl command. When the "sqlite" Tcl command is
003688 ** invoked, this routine runs to process that command.
003689 **
003690 ** The first argument, DBNAME, is an arbitrary name for a new
003691 ** database connection. This command creates a new command named
003692 ** DBNAME that is used to control that connection. The database
003693 ** connection is deleted when the DBNAME command is deleted.
003694 **
003695 ** The second argument is the name of the database file.
003696 **
003697 */
003698 static int SQLITE_TCLAPI DbMain(
003699 void *cd,
003700 Tcl_Interp *interp,
003701 int objc,
003702 Tcl_Obj *const*objv
003703 ){
003704 SqliteDb *p;
003705 const char *zArg;
003706 char *zErrMsg;
003707 int i;
003708 const char *zFile = 0;
003709 const char *zVfs = 0;
003710 int flags;
003711 Tcl_DString translatedFilename;
003712 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003713 void *pKey = 0;
003714 int nKey = 0;
003715 #endif
003716 int rc;
003717
003718 /* In normal use, each TCL interpreter runs in a single thread. So
003719 ** by default, we can turn off mutexing on SQLite database connections.
003720 ** However, for testing purposes it is useful to have mutexes turned
003721 ** on. So, by default, mutexes default off. But if compiled with
003722 ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
003723 */
003724 #ifdef SQLITE_TCL_DEFAULT_FULLMUTEX
003725 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
003726 #else
003727 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
003728 #endif
003729
003730 if( objc==1 ) return sqliteCmdUsage(interp, objv);
003731 if( objc==2 ){
003732 zArg = Tcl_GetStringFromObj(objv[1], 0);
003733 if( strcmp(zArg,"-version")==0 ){
003734 Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
003735 return TCL_OK;
003736 }
003737 if( strcmp(zArg,"-sourceid")==0 ){
003738 Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0);
003739 return TCL_OK;
003740 }
003741 if( strcmp(zArg,"-has-codec")==0 ){
003742 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003743 Tcl_AppendResult(interp,"1",(char*)0);
003744 #else
003745 Tcl_AppendResult(interp,"0",(char*)0);
003746 #endif
003747 return TCL_OK;
003748 }
003749 if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
003750 }
003751 for(i=2; i<objc; i++){
003752 zArg = Tcl_GetString(objv[i]);
003753 if( zArg[0]!='-' ){
003754 if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
003755 zFile = zArg;
003756 continue;
003757 }
003758 if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
003759 i++;
003760 if( strcmp(zArg,"-key")==0 ){
003761 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003762 pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
003763 #endif
003764 }else if( strcmp(zArg, "-vfs")==0 ){
003765 zVfs = Tcl_GetString(objv[i]);
003766 }else if( strcmp(zArg, "-readonly")==0 ){
003767 int b;
003768 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
003769 if( b ){
003770 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
003771 flags |= SQLITE_OPEN_READONLY;
003772 }else{
003773 flags &= ~SQLITE_OPEN_READONLY;
003774 flags |= SQLITE_OPEN_READWRITE;
003775 }
003776 }else if( strcmp(zArg, "-create")==0 ){
003777 int b;
003778 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
003779 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
003780 flags |= SQLITE_OPEN_CREATE;
003781 }else{
003782 flags &= ~SQLITE_OPEN_CREATE;
003783 }
003784 }else if( strcmp(zArg, "-nofollow")==0 ){
003785 int b;
003786 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
003787 if( b ){
003788 flags |= SQLITE_OPEN_NOFOLLOW;
003789 }else{
003790 flags &= ~SQLITE_OPEN_NOFOLLOW;
003791 }
003792 }else if( strcmp(zArg, "-nomutex")==0 ){
003793 int b;
003794 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
003795 if( b ){
003796 flags |= SQLITE_OPEN_NOMUTEX;
003797 flags &= ~SQLITE_OPEN_FULLMUTEX;
003798 }else{
003799 flags &= ~SQLITE_OPEN_NOMUTEX;
003800 }
003801 }else if( strcmp(zArg, "-fullmutex")==0 ){
003802 int b;
003803 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
003804 if( b ){
003805 flags |= SQLITE_OPEN_FULLMUTEX;
003806 flags &= ~SQLITE_OPEN_NOMUTEX;
003807 }else{
003808 flags &= ~SQLITE_OPEN_FULLMUTEX;
003809 }
003810 }else if( strcmp(zArg, "-uri")==0 ){
003811 int b;
003812 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
003813 if( b ){
003814 flags |= SQLITE_OPEN_URI;
003815 }else{
003816 flags &= ~SQLITE_OPEN_URI;
003817 }
003818 }else{
003819 Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
003820 return TCL_ERROR;
003821 }
003822 }
003823 zErrMsg = 0;
003824 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
003825 memset(p, 0, sizeof(*p));
003826 if( zFile==0 ) zFile = "";
003827 zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
003828 rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
003829 Tcl_DStringFree(&translatedFilename);
003830 if( p->db ){
003831 if( SQLITE_OK!=sqlite3_errcode(p->db) ){
003832 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
003833 sqlite3_close(p->db);
003834 p->db = 0;
003835 }
003836 }else{
003837 zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
003838 }
003839 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003840 if( p->db ){
003841 sqlite3_key(p->db, pKey, nKey);
003842 }
003843 #endif
003844 if( p->db==0 ){
003845 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
003846 Tcl_Free((char*)p);
003847 sqlite3_free(zErrMsg);
003848 return TCL_ERROR;
003849 }
003850 p->maxStmt = NUM_PREPARED_STMTS;
003851 p->openFlags = flags & SQLITE_OPEN_URI;
003852 p->interp = interp;
003853 zArg = Tcl_GetStringFromObj(objv[1], 0);
003854 if( DbUseNre() ){
003855 Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
003856 (char*)p, DbDeleteCmd);
003857 }else{
003858 Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
003859 }
003860 return TCL_OK;
003861 }
003862
003863 /*
003864 ** Provide a dummy Tcl_InitStubs if we are using this as a static
003865 ** library.
003866 */
003867 #ifndef USE_TCL_STUBS
003868 # undef Tcl_InitStubs
003869 # define Tcl_InitStubs(a,b,c) TCL_VERSION
003870 #endif
003871
003872 /*
003873 ** Make sure we have a PACKAGE_VERSION macro defined. This will be
003874 ** defined automatically by the TEA makefile. But other makefiles
003875 ** do not define it.
003876 */
003877 #ifndef PACKAGE_VERSION
003878 # define PACKAGE_VERSION SQLITE_VERSION
003879 #endif
003880
003881 /*
003882 ** Initialize this module.
003883 **
003884 ** This Tcl module contains only a single new Tcl command named "sqlite".
003885 ** (Hence there is no namespace. There is no point in using a namespace
003886 ** if the extension only supplies one new name!) The "sqlite" command is
003887 ** used to open a new SQLite database. See the DbMain() routine above
003888 ** for additional information.
003889 **
003890 ** The EXTERN macros are required by TCL in order to work on windows.
003891 */
003892 EXTERN int Sqlite3_Init(Tcl_Interp *interp){
003893 int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR;
003894 if( rc==TCL_OK ){
003895 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
003896 #ifndef SQLITE_3_SUFFIX_ONLY
003897 /* The "sqlite" alias is undocumented. It is here only to support
003898 ** legacy scripts. All new scripts should use only the "sqlite3"
003899 ** command. */
003900 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
003901 #endif
003902 rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
003903 }
003904 return rc;
003905 }
003906 EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
003907 EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
003908 EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
003909
003910 /* Because it accesses the file-system and uses persistent state, SQLite
003911 ** is not considered appropriate for safe interpreters. Hence, we cause
003912 ** the _SafeInit() interfaces return TCL_ERROR.
003913 */
003914 EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; }
003915 EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;}
003916
003917
003918
003919 #ifndef SQLITE_3_SUFFIX_ONLY
003920 int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
003921 int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
003922 int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
003923 int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
003924 #endif
003925
003926 /*
003927 ** If the TCLSH macro is defined, add code to make a stand-alone program.
003928 */
003929 #if defined(TCLSH)
003930
003931 /* This is the main routine for an ordinary TCL shell. If there are
003932 ** are arguments, run the first argument as a script. Otherwise,
003933 ** read TCL commands from standard input
003934 */
003935 static const char *tclsh_main_loop(void){
003936 static const char zMainloop[] =
003937 "if {[llength $argv]>=1} {\n"
003938 "set argv0 [lindex $argv 0]\n"
003939 "set argv [lrange $argv 1 end]\n"
003940 "source $argv0\n"
003941 "} else {\n"
003942 "set line {}\n"
003943 "while {![eof stdin]} {\n"
003944 "if {$line!=\"\"} {\n"
003945 "puts -nonewline \"> \"\n"
003946 "} else {\n"
003947 "puts -nonewline \"% \"\n"
003948 "}\n"
003949 "flush stdout\n"
003950 "append line [gets stdin]\n"
003951 "if {[info complete $line]} {\n"
003952 "if {[catch {uplevel #0 $line} result]} {\n"
003953 "puts stderr \"Error: $result\"\n"
003954 "} elseif {$result!=\"\"} {\n"
003955 "puts $result\n"
003956 "}\n"
003957 "set line {}\n"
003958 "} else {\n"
003959 "append line \\n\n"
003960 "}\n"
003961 "}\n"
003962 "}\n"
003963 ;
003964 return zMainloop;
003965 }
003966
003967 #define TCLSH_MAIN main /* Needed to fake out mktclapp */
003968 int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
003969 Tcl_Interp *interp;
003970 int i;
003971 const char *zScript = 0;
003972 char zArgc[32];
003973 #if defined(TCLSH_INIT_PROC)
003974 extern const char *TCLSH_INIT_PROC(Tcl_Interp*);
003975 #endif
003976
003977 #if !defined(_WIN32_WCE)
003978 if( getenv("SQLITE_DEBUG_BREAK") ){
003979 if( isatty(0) && isatty(2) ){
003980 fprintf(stderr,
003981 "attach debugger to process %d and press any key to continue.\n",
003982 GETPID());
003983 fgetc(stdin);
003984 }else{
003985 #if defined(_WIN32) || defined(WIN32)
003986 DebugBreak();
003987 #elif defined(SIGTRAP)
003988 raise(SIGTRAP);
003989 #endif
003990 }
003991 }
003992 #endif
003993
003994 /* Call sqlite3_shutdown() once before doing anything else. This is to
003995 ** test that sqlite3_shutdown() can be safely called by a process before
003996 ** sqlite3_initialize() is. */
003997 sqlite3_shutdown();
003998
003999 Tcl_FindExecutable(argv[0]);
004000 Tcl_SetSystemEncoding(NULL, "utf-8");
004001 interp = Tcl_CreateInterp();
004002 Sqlite3_Init(interp);
004003
004004 sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1);
004005 Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
004006 Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
004007 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
004008 for(i=1; i<argc; i++){
004009 Tcl_SetVar(interp, "argv", argv[i],
004010 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
004011 }
004012 #if defined(TCLSH_INIT_PROC)
004013 zScript = TCLSH_INIT_PROC(interp);
004014 #endif
004015 if( zScript==0 ){
004016 zScript = tclsh_main_loop();
004017 }
004018 if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){
004019 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
004020 if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
004021 fprintf(stderr,"%s: %s\n", *argv, zInfo);
004022 return 1;
004023 }
004024 return 0;
004025 }
004026 #endif /* TCLSH */