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