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 */