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 #else 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_Interp *interp, 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' && strcmp(zType,"boolean")==0) 001101 || (c=='w' && strcmp(zType,"wideInt")==0) 001102 || (c=='i' && strcmp(zType,"int")==0) 001103 ){ 001104 eType = SQLITE_INTEGER; 001105 }else if( c=='d' && strcmp(zType,"double")==0 ){ 001106 eType = SQLITE_FLOAT; 001107 }else{ 001108 eType = SQLITE_TEXT; 001109 } 001110 } 001111 001112 switch( eType ){ 001113 case SQLITE_BLOB: { 001114 data = Tcl_GetByteArrayFromObj(pVar, &n); 001115 sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT); 001116 break; 001117 } 001118 case SQLITE_INTEGER: { 001119 Tcl_WideInt v; 001120 if( TCL_OK==Tcl_GetWideIntFromObj(0, pVar, &v) ){ 001121 sqlite3_result_int64(context, v); 001122 break; 001123 } 001124 /* fall-through */ 001125 } 001126 case SQLITE_FLOAT: { 001127 double r; 001128 if( TCL_OK==Tcl_GetDoubleFromObj(0, pVar, &r) ){ 001129 sqlite3_result_double(context, r); 001130 break; 001131 } 001132 /* fall-through */ 001133 } 001134 default: { 001135 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); 001136 sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT); 001137 break; 001138 } 001139 } 001140 001141 } 001142 } 001143 001144 #ifndef SQLITE_OMIT_AUTHORIZATION 001145 /* 001146 ** This is the authentication function. It appends the authentication 001147 ** type code and the two arguments to zCmd[] then invokes the result 001148 ** on the interpreter. The reply is examined to determine if the 001149 ** authentication fails or succeeds. 001150 */ 001151 static int auth_callback( 001152 void *pArg, 001153 int code, 001154 const char *zArg1, 001155 const char *zArg2, 001156 const char *zArg3, 001157 const char *zArg4 001158 #ifdef SQLITE_USER_AUTHENTICATION 001159 ,const char *zArg5 001160 #endif 001161 ){ 001162 const char *zCode; 001163 Tcl_DString str; 001164 int rc; 001165 const char *zReply; 001166 /* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer 001167 ** callback is a copy of the third parameter to the 001168 ** sqlite3_set_authorizer() interface. 001169 */ 001170 SqliteDb *pDb = (SqliteDb*)pArg; 001171 if( pDb->disableAuth ) return SQLITE_OK; 001172 001173 /* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an 001174 ** integer action code that specifies the particular action to be 001175 ** authorized. */ 001176 switch( code ){ 001177 case SQLITE_COPY : zCode="SQLITE_COPY"; break; 001178 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; 001179 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; 001180 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break; 001181 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break; 001182 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break; 001183 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break; 001184 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break; 001185 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break; 001186 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break; 001187 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break; 001188 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break; 001189 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break; 001190 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break; 001191 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break; 001192 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break; 001193 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break; 001194 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break; 001195 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break; 001196 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break; 001197 case SQLITE_READ : zCode="SQLITE_READ"; break; 001198 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break; 001199 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break; 001200 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; 001201 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; 001202 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; 001203 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; 001204 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; 001205 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; 001206 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; 001207 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; 001208 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; 001209 case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break; 001210 case SQLITE_RECURSIVE : zCode="SQLITE_RECURSIVE"; break; 001211 default : zCode="????"; break; 001212 } 001213 Tcl_DStringInit(&str); 001214 Tcl_DStringAppend(&str, pDb->zAuth, -1); 001215 Tcl_DStringAppendElement(&str, zCode); 001216 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : ""); 001217 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); 001218 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); 001219 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); 001220 #ifdef SQLITE_USER_AUTHENTICATION 001221 Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); 001222 #endif 001223 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); 001224 Tcl_DStringFree(&str); 001225 zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; 001226 if( strcmp(zReply,"SQLITE_OK")==0 ){ 001227 rc = SQLITE_OK; 001228 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){ 001229 rc = SQLITE_DENY; 001230 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){ 001231 rc = SQLITE_IGNORE; 001232 }else{ 001233 rc = 999; 001234 } 001235 return rc; 001236 } 001237 #endif /* SQLITE_OMIT_AUTHORIZATION */ 001238 001239 /* 001240 ** This routine reads a line of text from FILE in, stores 001241 ** the text in memory obtained from malloc() and returns a pointer 001242 ** to the text. NULL is returned at end of file, or if malloc() 001243 ** fails. 001244 ** 001245 ** The interface is like "readline" but no command-line editing 001246 ** is done. 001247 ** 001248 ** copied from shell.c from '.import' command 001249 */ 001250 static char *local_getline(char *zPrompt, FILE *in){ 001251 char *zLine; 001252 int nLine; 001253 int n; 001254 001255 nLine = 100; 001256 zLine = malloc( nLine ); 001257 if( zLine==0 ) return 0; 001258 n = 0; 001259 while( 1 ){ 001260 if( n+100>nLine ){ 001261 nLine = nLine*2 + 100; 001262 zLine = realloc(zLine, nLine); 001263 if( zLine==0 ) return 0; 001264 } 001265 if( fgets(&zLine[n], nLine - n, in)==0 ){ 001266 if( n==0 ){ 001267 free(zLine); 001268 return 0; 001269 } 001270 zLine[n] = 0; 001271 break; 001272 } 001273 while( zLine[n] ){ n++; } 001274 if( n>0 && zLine[n-1]=='\n' ){ 001275 n--; 001276 zLine[n] = 0; 001277 break; 001278 } 001279 } 001280 zLine = realloc( zLine, n+1 ); 001281 return zLine; 001282 } 001283 001284 001285 /* 001286 ** This function is part of the implementation of the command: 001287 ** 001288 ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT 001289 ** 001290 ** It is invoked after evaluating the script SCRIPT to commit or rollback 001291 ** the transaction or savepoint opened by the [transaction] command. 001292 */ 001293 static int SQLITE_TCLAPI DbTransPostCmd( 001294 ClientData data[], /* data[0] is the Sqlite3Db* for $db */ 001295 Tcl_Interp *interp, /* Tcl interpreter */ 001296 int result /* Result of evaluating SCRIPT */ 001297 ){ 001298 static const char *const azEnd[] = { 001299 "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */ 001300 "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */ 001301 "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction", 001302 "ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */ 001303 }; 001304 SqliteDb *pDb = (SqliteDb*)data[0]; 001305 int rc = result; 001306 const char *zEnd; 001307 001308 pDb->nTransaction--; 001309 zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)]; 001310 001311 pDb->disableAuth++; 001312 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){ 001313 /* This is a tricky scenario to handle. The most likely cause of an 001314 ** error is that the exec() above was an attempt to commit the 001315 ** top-level transaction that returned SQLITE_BUSY. Or, less likely, 001316 ** that an IO-error has occurred. In either case, throw a Tcl exception 001317 ** and try to rollback the transaction. 001318 ** 001319 ** But it could also be that the user executed one or more BEGIN, 001320 ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing 001321 ** this method's logic. Not clear how this would be best handled. 001322 */ 001323 if( rc!=TCL_ERROR ){ 001324 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); 001325 rc = TCL_ERROR; 001326 } 001327 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0); 001328 } 001329 pDb->disableAuth--; 001330 001331 delDatabaseRef(pDb); 001332 return rc; 001333 } 001334 001335 /* 001336 ** Unless SQLITE_TEST is defined, this function is a simple wrapper around 001337 ** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either 001338 ** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending 001339 ** on whether or not the [db_use_legacy_prepare] command has been used to 001340 ** configure the connection. 001341 */ 001342 static int dbPrepare( 001343 SqliteDb *pDb, /* Database object */ 001344 const char *zSql, /* SQL to compile */ 001345 sqlite3_stmt **ppStmt, /* OUT: Prepared statement */ 001346 const char **pzOut /* OUT: Pointer to next SQL statement */ 001347 ){ 001348 unsigned int prepFlags = 0; 001349 #ifdef SQLITE_TEST 001350 if( pDb->bLegacyPrepare ){ 001351 return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut); 001352 } 001353 #endif 001354 /* If the statement cache is large, use the SQLITE_PREPARE_PERSISTENT 001355 ** flags, which uses less lookaside memory. But if the cache is small, 001356 ** omit that flag to make full use of lookaside */ 001357 if( pDb->maxStmt>5 ) prepFlags = SQLITE_PREPARE_PERSISTENT; 001358 001359 return sqlite3_prepare_v3(pDb->db, zSql, -1, prepFlags, ppStmt, pzOut); 001360 } 001361 001362 /* 001363 ** Search the cache for a prepared-statement object that implements the 001364 ** first SQL statement in the buffer pointed to by parameter zIn. If 001365 ** no such prepared-statement can be found, allocate and prepare a new 001366 ** one. In either case, bind the current values of the relevant Tcl 001367 ** variables to any $var, :var or @var variables in the statement. Before 001368 ** returning, set *ppPreStmt to point to the prepared-statement object. 001369 ** 001370 ** Output parameter *pzOut is set to point to the next SQL statement in 001371 ** buffer zIn, or to the '\0' byte at the end of zIn if there is no 001372 ** next statement. 001373 ** 001374 ** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned 001375 ** and an error message loaded into interpreter pDb->interp. 001376 */ 001377 static int dbPrepareAndBind( 001378 SqliteDb *pDb, /* Database object */ 001379 char const *zIn, /* SQL to compile */ 001380 char const **pzOut, /* OUT: Pointer to next SQL statement */ 001381 SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */ 001382 ){ 001383 const char *zSql = zIn; /* Pointer to first SQL statement in zIn */ 001384 sqlite3_stmt *pStmt = 0; /* Prepared statement object */ 001385 SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */ 001386 int nSql; /* Length of zSql in bytes */ 001387 int nVar = 0; /* Number of variables in statement */ 001388 int iParm = 0; /* Next free entry in apParm */ 001389 char c; 001390 int i; 001391 int needResultReset = 0; /* Need to invoke Tcl_ResetResult() */ 001392 int rc = SQLITE_OK; /* Value to return */ 001393 Tcl_Interp *interp = pDb->interp; 001394 001395 *ppPreStmt = 0; 001396 001397 /* Trim spaces from the start of zSql and calculate the remaining length. */ 001398 while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; } 001399 nSql = strlen30(zSql); 001400 001401 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ 001402 int n = pPreStmt->nSql; 001403 if( nSql>=n 001404 && memcmp(pPreStmt->zSql, zSql, n)==0 001405 && (zSql[n]==0 || zSql[n-1]==';') 001406 ){ 001407 pStmt = pPreStmt->pStmt; 001408 *pzOut = &zSql[pPreStmt->nSql]; 001409 001410 /* When a prepared statement is found, unlink it from the 001411 ** cache list. It will later be added back to the beginning 001412 ** of the cache list in order to implement LRU replacement. 001413 */ 001414 if( pPreStmt->pPrev ){ 001415 pPreStmt->pPrev->pNext = pPreStmt->pNext; 001416 }else{ 001417 pDb->stmtList = pPreStmt->pNext; 001418 } 001419 if( pPreStmt->pNext ){ 001420 pPreStmt->pNext->pPrev = pPreStmt->pPrev; 001421 }else{ 001422 pDb->stmtLast = pPreStmt->pPrev; 001423 } 001424 pDb->nStmt--; 001425 nVar = sqlite3_bind_parameter_count(pStmt); 001426 break; 001427 } 001428 } 001429 001430 /* If no prepared statement was found. Compile the SQL text. Also allocate 001431 ** a new SqlPreparedStmt structure. */ 001432 if( pPreStmt==0 ){ 001433 int nByte; 001434 001435 if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){ 001436 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); 001437 return TCL_ERROR; 001438 } 001439 if( pStmt==0 ){ 001440 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ 001441 /* A compile-time error in the statement. */ 001442 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); 001443 return TCL_ERROR; 001444 }else{ 001445 /* The statement was a no-op. Continue to the next statement 001446 ** in the SQL string. 001447 */ 001448 return TCL_OK; 001449 } 001450 } 001451 001452 assert( pPreStmt==0 ); 001453 nVar = sqlite3_bind_parameter_count(pStmt); 001454 nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *); 001455 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte); 001456 memset(pPreStmt, 0, nByte); 001457 001458 pPreStmt->pStmt = pStmt; 001459 pPreStmt->nSql = (int)(*pzOut - zSql); 001460 pPreStmt->zSql = sqlite3_sql(pStmt); 001461 pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1]; 001462 #ifdef SQLITE_TEST 001463 if( pPreStmt->zSql==0 ){ 001464 char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1); 001465 memcpy(zCopy, zSql, pPreStmt->nSql); 001466 zCopy[pPreStmt->nSql] = '\0'; 001467 pPreStmt->zSql = zCopy; 001468 } 001469 #endif 001470 } 001471 assert( pPreStmt ); 001472 assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql ); 001473 assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) ); 001474 001475 /* Bind values to parameters that begin with $ or : */ 001476 for(i=1; i<=nVar; i++){ 001477 const char *zVar = sqlite3_bind_parameter_name(pStmt, i); 001478 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){ 001479 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0); 001480 if( pVar==0 && pDb->zBindFallback!=0 ){ 001481 Tcl_Obj *pCmd; 001482 int rx; 001483 pCmd = Tcl_NewStringObj(pDb->zBindFallback, -1); 001484 Tcl_IncrRefCount(pCmd); 001485 Tcl_ListObjAppendElement(interp, pCmd, Tcl_NewStringObj(zVar,-1)); 001486 if( needResultReset ) Tcl_ResetResult(interp); 001487 needResultReset = 1; 001488 rx = Tcl_EvalObjEx(interp, pCmd, TCL_EVAL_DIRECT); 001489 Tcl_DecrRefCount(pCmd); 001490 if( rx==TCL_OK ){ 001491 pVar = Tcl_GetObjResult(interp); 001492 }else if( rx==TCL_ERROR ){ 001493 rc = TCL_ERROR; 001494 break; 001495 }else{ 001496 pVar = 0; 001497 } 001498 } 001499 if( pVar ){ 001500 Tcl_Size n; 001501 u8 *data; 001502 const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); 001503 c = zType[0]; 001504 if( zVar[0]=='@' || 001505 (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){ 001506 /* Load a BLOB type if the Tcl variable is a bytearray and 001507 ** it has no string representation or the host 001508 ** parameter name begins with "@". */ 001509 data = Tcl_GetByteArrayFromObj(pVar, &n); 001510 sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); 001511 Tcl_IncrRefCount(pVar); 001512 pPreStmt->apParm[iParm++] = pVar; 001513 }else if( c=='b' && strcmp(zType,"boolean")==0 ){ 001514 int nn; 001515 Tcl_GetIntFromObj(interp, pVar, &nn); 001516 sqlite3_bind_int(pStmt, i, nn); 001517 }else if( c=='d' && strcmp(zType,"double")==0 ){ 001518 double r; 001519 Tcl_GetDoubleFromObj(interp, pVar, &r); 001520 sqlite3_bind_double(pStmt, i, r); 001521 }else if( (c=='w' && strcmp(zType,"wideInt")==0) || 001522 (c=='i' && strcmp(zType,"int")==0) ){ 001523 Tcl_WideInt v; 001524 Tcl_GetWideIntFromObj(interp, pVar, &v); 001525 sqlite3_bind_int64(pStmt, i, v); 001526 }else{ 001527 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); 001528 sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC); 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 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6) 001851 # define SQLITE_TCL_NRE 1 001852 static int DbUseNre(void){ 001853 int major, minor; 001854 Tcl_GetVersion(&major, &minor, 0, 0); 001855 return( (major==8 && minor>=6) || major>8 ); 001856 } 001857 #else 001858 /* 001859 ** Compiling using headers earlier than 8.6. In this case NR cannot be 001860 ** used, so DbUseNre() to always return zero. Add #defines for the other 001861 ** Tcl_NRxxx() functions to prevent them from causing compilation errors, 001862 ** even though the only invocations of them are within conditional blocks 001863 ** of the form: 001864 ** 001865 ** if( DbUseNre() ) { ... } 001866 */ 001867 # define SQLITE_TCL_NRE 0 001868 # define DbUseNre() 0 001869 # define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0 001870 # define Tcl_NREvalObj(a,b,c) 0 001871 # define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0 001872 #endif 001873 001874 /* 001875 ** This function is part of the implementation of the command: 001876 ** 001877 ** $db eval SQL ?ARRAYNAME? SCRIPT 001878 */ 001879 static int SQLITE_TCLAPI DbEvalNextCmd( 001880 ClientData data[], /* data[0] is the (DbEvalContext*) */ 001881 Tcl_Interp *interp, /* Tcl interpreter */ 001882 int result /* Result so far */ 001883 ){ 001884 int rc = result; /* Return code */ 001885 001886 /* The first element of the data[] array is a pointer to a DbEvalContext 001887 ** structure allocated using Tcl_Alloc(). The second element of data[] 001888 ** is a pointer to a Tcl_Obj containing the script to run for each row 001889 ** returned by the queries encapsulated in data[0]. */ 001890 DbEvalContext *p = (DbEvalContext *)data[0]; 001891 Tcl_Obj *pScript = (Tcl_Obj *)data[1]; 001892 Tcl_Obj *pArray = p->pArray; 001893 001894 while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){ 001895 int i; 001896 int nCol; 001897 Tcl_Obj **apColName; 001898 dbEvalRowInfo(p, &nCol, &apColName); 001899 for(i=0; i<nCol; i++){ 001900 if( pArray==0 ){ 001901 Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0); 001902 }else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0 001903 && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL 001904 ){ 001905 Tcl_UnsetVar2(interp, Tcl_GetString(pArray), 001906 Tcl_GetString(apColName[i]), 0); 001907 }else{ 001908 Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0); 001909 } 001910 } 001911 001912 /* The required interpreter variables are now populated with the data 001913 ** from the current row. If using NRE, schedule callbacks to evaluate 001914 ** script pScript, then to invoke this function again to fetch the next 001915 ** row (or clean up if there is no next row or the script throws an 001916 ** exception). After scheduling the callbacks, return control to the 001917 ** caller. 001918 ** 001919 ** If not using NRE, evaluate pScript directly and continue with the 001920 ** next iteration of this while(...) loop. */ 001921 if( DbUseNre() ){ 001922 Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0); 001923 return Tcl_NREvalObj(interp, pScript, 0); 001924 }else{ 001925 rc = Tcl_EvalObjEx(interp, pScript, 0); 001926 } 001927 } 001928 001929 Tcl_DecrRefCount(pScript); 001930 dbEvalFinalize(p); 001931 Tcl_Free((char *)p); 001932 001933 if( rc==TCL_OK || rc==TCL_BREAK ){ 001934 Tcl_ResetResult(interp); 001935 rc = TCL_OK; 001936 } 001937 return rc; 001938 } 001939 001940 /* 001941 ** This function is used by the implementations of the following database 001942 ** handle sub-commands: 001943 ** 001944 ** $db update_hook ?SCRIPT? 001945 ** $db wal_hook ?SCRIPT? 001946 ** $db commit_hook ?SCRIPT? 001947 ** $db preupdate hook ?SCRIPT? 001948 */ 001949 static void DbHookCmd( 001950 Tcl_Interp *interp, /* Tcl interpreter */ 001951 SqliteDb *pDb, /* Database handle */ 001952 Tcl_Obj *pArg, /* SCRIPT argument (or NULL) */ 001953 Tcl_Obj **ppHook /* Pointer to member of SqliteDb */ 001954 ){ 001955 sqlite3 *db = pDb->db; 001956 001957 if( *ppHook ){ 001958 Tcl_SetObjResult(interp, *ppHook); 001959 if( pArg ){ 001960 Tcl_DecrRefCount(*ppHook); 001961 *ppHook = 0; 001962 } 001963 } 001964 if( pArg ){ 001965 assert( !(*ppHook) ); 001966 if( Tcl_GetCharLength(pArg)>0 ){ 001967 *ppHook = pArg; 001968 Tcl_IncrRefCount(*ppHook); 001969 } 001970 } 001971 001972 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK 001973 sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb); 001974 #endif 001975 sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); 001976 sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb); 001977 sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb); 001978 } 001979 001980 /* 001981 ** The "sqlite" command below creates a new Tcl command for each 001982 ** connection it opens to an SQLite database. This routine is invoked 001983 ** whenever one of those connection-specific commands is executed 001984 ** in Tcl. For example, if you run Tcl code like this: 001985 ** 001986 ** sqlite3 db1 "my_database" 001987 ** db1 close 001988 ** 001989 ** The first command opens a connection to the "my_database" database 001990 ** and calls that connection "db1". The second command causes this 001991 ** subroutine to be invoked. 001992 */ 001993 static int SQLITE_TCLAPI DbObjCmd( 001994 void *cd, 001995 Tcl_Interp *interp, 001996 int objc, 001997 Tcl_Obj *const*objv 001998 ){ 001999 SqliteDb *pDb = (SqliteDb*)cd; 002000 int choice; 002001 int rc = TCL_OK; 002002 static const char *DB_strs[] = { 002003 "authorizer", "backup", "bind_fallback", 002004 "busy", "cache", "changes", 002005 "close", "collate", "collation_needed", 002006 "commit_hook", "complete", "config", 002007 "copy", "deserialize", "enable_load_extension", 002008 "errorcode", "erroroffset", "eval", 002009 "exists", "function", "incrblob", 002010 "interrupt", "last_insert_rowid", "nullvalue", 002011 "onecolumn", "preupdate", "profile", 002012 "progress", "rekey", "restore", 002013 "rollback_hook", "serialize", "status", 002014 "timeout", "total_changes", "trace", 002015 "trace_v2", "transaction", "unlock_notify", 002016 "update_hook", "version", "wal_hook", 002017 0 002018 }; 002019 enum DB_enum { 002020 DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, 002021 DB_BUSY, DB_CACHE, DB_CHANGES, 002022 DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, 002023 DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG, 002024 DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION, 002025 DB_ERRORCODE, DB_ERROROFFSET, DB_EVAL, 002026 DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, 002027 DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, 002028 DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE, 002029 DB_PROGRESS, DB_REKEY, DB_RESTORE, 002030 DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS, 002031 DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, 002032 DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY, 002033 DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK, 002034 }; 002035 /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ 002036 002037 if( objc<2 ){ 002038 Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); 002039 return TCL_ERROR; 002040 } 002041 if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){ 002042 return TCL_ERROR; 002043 } 002044 002045 switch( (enum DB_enum)choice ){ 002046 002047 /* $db authorizer ?CALLBACK? 002048 ** 002049 ** Invoke the given callback to authorize each SQL operation as it is 002050 ** compiled. 5 arguments are appended to the callback before it is 002051 ** invoked: 002052 ** 002053 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...) 002054 ** (2) First descriptive name (depends on authorization type) 002055 ** (3) Second descriptive name 002056 ** (4) Name of the database (ex: "main", "temp") 002057 ** (5) Name of trigger that is doing the access 002058 ** 002059 ** The callback should return on of the following strings: SQLITE_OK, 002060 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error. 002061 ** 002062 ** If this method is invoked with no arguments, the current authorization 002063 ** callback string is returned. 002064 */ 002065 case DB_AUTHORIZER: { 002066 #ifdef SQLITE_OMIT_AUTHORIZATION 002067 Tcl_AppendResult(interp, "authorization not available in this build", 002068 (char*)0); 002069 return TCL_ERROR; 002070 #else 002071 if( objc>3 ){ 002072 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 002073 return TCL_ERROR; 002074 }else if( objc==2 ){ 002075 if( pDb->zAuth ){ 002076 Tcl_AppendResult(interp, pDb->zAuth, (char*)0); 002077 } 002078 }else{ 002079 char *zAuth; 002080 Tcl_Size len; 002081 if( pDb->zAuth ){ 002082 Tcl_Free(pDb->zAuth); 002083 } 002084 zAuth = Tcl_GetStringFromObj(objv[2], &len); 002085 if( zAuth && len>0 ){ 002086 pDb->zAuth = Tcl_Alloc( len + 1 ); 002087 memcpy(pDb->zAuth, zAuth, len+1); 002088 }else{ 002089 pDb->zAuth = 0; 002090 } 002091 if( pDb->zAuth ){ 002092 typedef int (*sqlite3_auth_cb)( 002093 void*,int,const char*,const char*, 002094 const char*,const char*); 002095 pDb->interp = interp; 002096 sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb); 002097 }else{ 002098 sqlite3_set_authorizer(pDb->db, 0, 0); 002099 } 002100 } 002101 #endif 002102 break; 002103 } 002104 002105 /* $db backup ?DATABASE? FILENAME 002106 ** 002107 ** Open or create a database file named FILENAME. Transfer the 002108 ** content of local database DATABASE (default: "main") into the 002109 ** FILENAME database. 002110 */ 002111 case DB_BACKUP: { 002112 const char *zDestFile; 002113 const char *zSrcDb; 002114 sqlite3 *pDest; 002115 sqlite3_backup *pBackup; 002116 002117 if( objc==3 ){ 002118 zSrcDb = "main"; 002119 zDestFile = Tcl_GetString(objv[2]); 002120 }else if( objc==4 ){ 002121 zSrcDb = Tcl_GetString(objv[2]); 002122 zDestFile = Tcl_GetString(objv[3]); 002123 }else{ 002124 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME"); 002125 return TCL_ERROR; 002126 } 002127 rc = sqlite3_open_v2(zDestFile, &pDest, 002128 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0); 002129 if( rc!=SQLITE_OK ){ 002130 Tcl_AppendResult(interp, "cannot open target database: ", 002131 sqlite3_errmsg(pDest), (char*)0); 002132 sqlite3_close(pDest); 002133 return TCL_ERROR; 002134 } 002135 pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb); 002136 if( pBackup==0 ){ 002137 Tcl_AppendResult(interp, "backup failed: ", 002138 sqlite3_errmsg(pDest), (char*)0); 002139 sqlite3_close(pDest); 002140 return TCL_ERROR; 002141 } 002142 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} 002143 sqlite3_backup_finish(pBackup); 002144 if( rc==SQLITE_DONE ){ 002145 rc = TCL_OK; 002146 }else{ 002147 Tcl_AppendResult(interp, "backup failed: ", 002148 sqlite3_errmsg(pDest), (char*)0); 002149 rc = TCL_ERROR; 002150 } 002151 sqlite3_close(pDest); 002152 break; 002153 } 002154 002155 /* $db bind_fallback ?CALLBACK? 002156 ** 002157 ** When resolving bind parameters in an SQL statement, if the parameter 002158 ** cannot be associated with a TCL variable then invoke CALLBACK with a 002159 ** single argument that is the name of the parameter and use the return 002160 ** value of the CALLBACK as the binding. If CALLBACK returns something 002161 ** other than TCL_OK or TCL_ERROR then bind a NULL. 002162 ** 002163 ** If CALLBACK is an empty string, then revert to the default behavior 002164 ** which is to set the binding to NULL. 002165 ** 002166 ** If CALLBACK returns an error, that causes the statement execution to 002167 ** abort. Hence, to configure a connection so that it throws an error 002168 ** on an attempt to bind an unknown variable, do something like this: 002169 ** 002170 ** proc bind_error {name} {error "no such variable: $name"} 002171 ** db bind_fallback bind_error 002172 */ 002173 case DB_BIND_FALLBACK: { 002174 if( objc>3 ){ 002175 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 002176 return TCL_ERROR; 002177 }else if( objc==2 ){ 002178 if( pDb->zBindFallback ){ 002179 Tcl_AppendResult(interp, pDb->zBindFallback, (char*)0); 002180 } 002181 }else{ 002182 char *zCallback; 002183 Tcl_Size len; 002184 if( pDb->zBindFallback ){ 002185 Tcl_Free(pDb->zBindFallback); 002186 } 002187 zCallback = Tcl_GetStringFromObj(objv[2], &len); 002188 if( zCallback && len>0 ){ 002189 pDb->zBindFallback = Tcl_Alloc( len + 1 ); 002190 memcpy(pDb->zBindFallback, zCallback, len+1); 002191 }else{ 002192 pDb->zBindFallback = 0; 002193 } 002194 } 002195 break; 002196 } 002197 002198 /* $db busy ?CALLBACK? 002199 ** 002200 ** Invoke the given callback if an SQL statement attempts to open 002201 ** a locked database file. 002202 */ 002203 case DB_BUSY: { 002204 if( objc>3 ){ 002205 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK"); 002206 return TCL_ERROR; 002207 }else if( objc==2 ){ 002208 if( pDb->zBusy ){ 002209 Tcl_AppendResult(interp, pDb->zBusy, (char*)0); 002210 } 002211 }else{ 002212 char *zBusy; 002213 Tcl_Size len; 002214 if( pDb->zBusy ){ 002215 Tcl_Free(pDb->zBusy); 002216 } 002217 zBusy = Tcl_GetStringFromObj(objv[2], &len); 002218 if( zBusy && len>0 ){ 002219 pDb->zBusy = Tcl_Alloc( len + 1 ); 002220 memcpy(pDb->zBusy, zBusy, len+1); 002221 }else{ 002222 pDb->zBusy = 0; 002223 } 002224 if( pDb->zBusy ){ 002225 pDb->interp = interp; 002226 sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb); 002227 }else{ 002228 sqlite3_busy_handler(pDb->db, 0, 0); 002229 } 002230 } 002231 break; 002232 } 002233 002234 /* $db cache flush 002235 ** $db cache size n 002236 ** 002237 ** Flush the prepared statement cache, or set the maximum number of 002238 ** cached statements. 002239 */ 002240 case DB_CACHE: { 002241 char *subCmd; 002242 int n; 002243 002244 if( objc<=2 ){ 002245 Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?"); 002246 return TCL_ERROR; 002247 } 002248 subCmd = Tcl_GetStringFromObj( objv[2], 0 ); 002249 if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){ 002250 if( objc!=3 ){ 002251 Tcl_WrongNumArgs(interp, 2, objv, "flush"); 002252 return TCL_ERROR; 002253 }else{ 002254 flushStmtCache( pDb ); 002255 } 002256 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){ 002257 if( objc!=4 ){ 002258 Tcl_WrongNumArgs(interp, 2, objv, "size n"); 002259 return TCL_ERROR; 002260 }else{ 002261 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ 002262 Tcl_AppendResult( interp, "cannot convert \"", 002263 Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0); 002264 return TCL_ERROR; 002265 }else{ 002266 if( n<0 ){ 002267 flushStmtCache( pDb ); 002268 n = 0; 002269 }else if( n>MAX_PREPARED_STMTS ){ 002270 n = MAX_PREPARED_STMTS; 002271 } 002272 pDb->maxStmt = n; 002273 } 002274 } 002275 }else{ 002276 Tcl_AppendResult( interp, "bad option \"", 002277 Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 002278 (char*)0); 002279 return TCL_ERROR; 002280 } 002281 break; 002282 } 002283 002284 /* $db changes 002285 ** 002286 ** Return the number of rows that were modified, inserted, or deleted by 002287 ** the most recent INSERT, UPDATE or DELETE statement, not including 002288 ** any changes made by trigger programs. 002289 */ 002290 case DB_CHANGES: { 002291 Tcl_Obj *pResult; 002292 if( objc!=2 ){ 002293 Tcl_WrongNumArgs(interp, 2, objv, ""); 002294 return TCL_ERROR; 002295 } 002296 pResult = Tcl_GetObjResult(interp); 002297 Tcl_SetWideIntObj(pResult, sqlite3_changes64(pDb->db)); 002298 break; 002299 } 002300 002301 /* $db close 002302 ** 002303 ** Shutdown the database 002304 */ 002305 case DB_CLOSE: { 002306 Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0)); 002307 break; 002308 } 002309 002310 /* 002311 ** $db collate NAME SCRIPT 002312 ** 002313 ** Create a new SQL collation function called NAME. Whenever 002314 ** that function is called, invoke SCRIPT to evaluate the function. 002315 */ 002316 case DB_COLLATE: { 002317 SqlCollate *pCollate; 002318 char *zName; 002319 char *zScript; 002320 Tcl_Size nScript; 002321 if( objc!=4 ){ 002322 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); 002323 return TCL_ERROR; 002324 } 002325 zName = Tcl_GetStringFromObj(objv[2], 0); 002326 zScript = Tcl_GetStringFromObj(objv[3], &nScript); 002327 pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 ); 002328 if( pCollate==0 ) return TCL_ERROR; 002329 pCollate->interp = interp; 002330 pCollate->pNext = pDb->pCollate; 002331 pCollate->zScript = (char*)&pCollate[1]; 002332 pDb->pCollate = pCollate; 002333 memcpy(pCollate->zScript, zScript, nScript+1); 002334 if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, 002335 pCollate, tclSqlCollate) ){ 002336 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); 002337 return TCL_ERROR; 002338 } 002339 break; 002340 } 002341 002342 /* 002343 ** $db collation_needed SCRIPT 002344 ** 002345 ** Create a new SQL collation function called NAME. Whenever 002346 ** that function is called, invoke SCRIPT to evaluate the function. 002347 */ 002348 case DB_COLLATION_NEEDED: { 002349 if( objc!=3 ){ 002350 Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT"); 002351 return TCL_ERROR; 002352 } 002353 if( pDb->pCollateNeeded ){ 002354 Tcl_DecrRefCount(pDb->pCollateNeeded); 002355 } 002356 pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]); 002357 Tcl_IncrRefCount(pDb->pCollateNeeded); 002358 sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded); 002359 break; 002360 } 002361 002362 /* $db commit_hook ?CALLBACK? 002363 ** 002364 ** Invoke the given callback just before committing every SQL transaction. 002365 ** If the callback throws an exception or returns non-zero, then the 002366 ** transaction is aborted. If CALLBACK is an empty string, the callback 002367 ** is disabled. 002368 */ 002369 case DB_COMMIT_HOOK: { 002370 if( objc>3 ){ 002371 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 002372 return TCL_ERROR; 002373 }else if( objc==2 ){ 002374 if( pDb->zCommit ){ 002375 Tcl_AppendResult(interp, pDb->zCommit, (char*)0); 002376 } 002377 }else{ 002378 const char *zCommit; 002379 Tcl_Size len; 002380 if( pDb->zCommit ){ 002381 Tcl_Free(pDb->zCommit); 002382 } 002383 zCommit = Tcl_GetStringFromObj(objv[2], &len); 002384 if( zCommit && len>0 ){ 002385 pDb->zCommit = Tcl_Alloc( len + 1 ); 002386 memcpy(pDb->zCommit, zCommit, len+1); 002387 }else{ 002388 pDb->zCommit = 0; 002389 } 002390 if( pDb->zCommit ){ 002391 pDb->interp = interp; 002392 sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb); 002393 }else{ 002394 sqlite3_commit_hook(pDb->db, 0, 0); 002395 } 002396 } 002397 break; 002398 } 002399 002400 /* $db complete SQL 002401 ** 002402 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if 002403 ** additional lines of input are needed. This is similar to the 002404 ** built-in "info complete" command of Tcl. 002405 */ 002406 case DB_COMPLETE: { 002407 #ifndef SQLITE_OMIT_COMPLETE 002408 Tcl_Obj *pResult; 002409 int isComplete; 002410 if( objc!=3 ){ 002411 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); 002412 return TCL_ERROR; 002413 } 002414 isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) ); 002415 pResult = Tcl_GetObjResult(interp); 002416 Tcl_SetBooleanObj(pResult, isComplete); 002417 #endif 002418 break; 002419 } 002420 002421 /* $db config ?OPTION? ?BOOLEAN? 002422 ** 002423 ** Configure the database connection using the sqlite3_db_config() 002424 ** interface. 002425 */ 002426 case DB_CONFIG: { 002427 static const struct DbConfigChoices { 002428 const char *zName; 002429 int op; 002430 } aDbConfig[] = { 002431 { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, 002432 { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, 002433 { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, 002434 { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, 002435 { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, 002436 { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, 002437 { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, 002438 { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, 002439 { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, 002440 { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, 002441 { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, 002442 { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, 002443 { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, 002444 { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, 002445 { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA }, 002446 { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, 002447 }; 002448 Tcl_Obj *pResult; 002449 int ii; 002450 if( objc>4 ){ 002451 Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?"); 002452 return TCL_ERROR; 002453 } 002454 if( objc==2 ){ 002455 /* With no arguments, list all configuration options and with the 002456 ** current value */ 002457 pResult = Tcl_NewListObj(0,0); 002458 for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){ 002459 int v = 0; 002460 sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v); 002461 Tcl_ListObjAppendElement(interp, pResult, 002462 Tcl_NewStringObj(aDbConfig[ii].zName,-1)); 002463 Tcl_ListObjAppendElement(interp, pResult, 002464 Tcl_NewIntObj(v)); 002465 } 002466 }else{ 002467 const char *zOpt = Tcl_GetString(objv[2]); 002468 int onoff = -1; 002469 int v = 0; 002470 if( zOpt[0]=='-' ) zOpt++; 002471 for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){ 002472 if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break; 002473 } 002474 if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){ 002475 Tcl_AppendResult(interp, "unknown config option: \"", zOpt, 002476 "\"", (void*)0); 002477 return TCL_ERROR; 002478 } 002479 if( objc==4 ){ 002480 if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){ 002481 return TCL_ERROR; 002482 } 002483 } 002484 sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); 002485 pResult = Tcl_NewIntObj(v); 002486 } 002487 Tcl_SetObjResult(interp, pResult); 002488 break; 002489 } 002490 002491 /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? 002492 ** 002493 ** Copy data into table from filename, optionally using SEPARATOR 002494 ** as column separators. If a column contains a null string, or the 002495 ** value of NULLINDICATOR, a NULL is inserted for the column. 002496 ** conflict-algorithm is one of the sqlite conflict algorithms: 002497 ** rollback, abort, fail, ignore, replace 002498 ** On success, return the number of lines processed, not necessarily same 002499 ** as 'db changes' due to conflict-algorithm selected. 002500 ** 002501 ** This code is basically an implementation/enhancement of 002502 ** the sqlite3 shell.c ".import" command. 002503 ** 002504 ** This command usage is equivalent to the sqlite2.x COPY statement, 002505 ** which imports file data into a table using the PostgreSQL COPY file format: 002506 ** $db copy $conflict_algorithm $table_name $filename \t \\N 002507 */ 002508 case DB_COPY: { 002509 char *zTable; /* Insert data into this table */ 002510 char *zFile; /* The file from which to extract data */ 002511 char *zConflict; /* The conflict algorithm to use */ 002512 sqlite3_stmt *pStmt; /* A statement */ 002513 int nCol; /* Number of columns in the table */ 002514 int nByte; /* Number of bytes in an SQL string */ 002515 int i, j; /* Loop counters */ 002516 int nSep; /* Number of bytes in zSep[] */ 002517 int nNull; /* Number of bytes in zNull[] */ 002518 char *zSql; /* An SQL statement */ 002519 char *zLine; /* A single line of input from the file */ 002520 char **azCol; /* zLine[] broken up into columns */ 002521 const char *zCommit; /* How to commit changes */ 002522 FILE *in; /* The input file */ 002523 int lineno = 0; /* Line number of input file */ 002524 char zLineNum[80]; /* Line number print buffer */ 002525 Tcl_Obj *pResult; /* interp result */ 002526 002527 const char *zSep; 002528 const char *zNull; 002529 if( objc<5 || objc>7 ){ 002530 Tcl_WrongNumArgs(interp, 2, objv, 002531 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); 002532 return TCL_ERROR; 002533 } 002534 if( objc>=6 ){ 002535 zSep = Tcl_GetStringFromObj(objv[5], 0); 002536 }else{ 002537 zSep = "\t"; 002538 } 002539 if( objc>=7 ){ 002540 zNull = Tcl_GetStringFromObj(objv[6], 0); 002541 }else{ 002542 zNull = ""; 002543 } 002544 zConflict = Tcl_GetStringFromObj(objv[2], 0); 002545 zTable = Tcl_GetStringFromObj(objv[3], 0); 002546 zFile = Tcl_GetStringFromObj(objv[4], 0); 002547 nSep = strlen30(zSep); 002548 nNull = strlen30(zNull); 002549 if( nSep==0 ){ 002550 Tcl_AppendResult(interp,"Error: non-null separator required for copy", 002551 (char*)0); 002552 return TCL_ERROR; 002553 } 002554 if(strcmp(zConflict, "rollback") != 0 && 002555 strcmp(zConflict, "abort" ) != 0 && 002556 strcmp(zConflict, "fail" ) != 0 && 002557 strcmp(zConflict, "ignore" ) != 0 && 002558 strcmp(zConflict, "replace" ) != 0 ) { 002559 Tcl_AppendResult(interp, "Error: \"", zConflict, 002560 "\", conflict-algorithm must be one of: rollback, " 002561 "abort, fail, ignore, or replace", (char*)0); 002562 return TCL_ERROR; 002563 } 002564 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); 002565 if( zSql==0 ){ 002566 Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0); 002567 return TCL_ERROR; 002568 } 002569 nByte = strlen30(zSql); 002570 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); 002571 sqlite3_free(zSql); 002572 if( rc ){ 002573 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); 002574 nCol = 0; 002575 }else{ 002576 nCol = sqlite3_column_count(pStmt); 002577 } 002578 sqlite3_finalize(pStmt); 002579 if( nCol==0 ) { 002580 return TCL_ERROR; 002581 } 002582 zSql = malloc( nByte + 50 + nCol*2 ); 002583 if( zSql==0 ) { 002584 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); 002585 return TCL_ERROR; 002586 } 002587 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?", 002588 zConflict, zTable); 002589 j = strlen30(zSql); 002590 for(i=1; i<nCol; i++){ 002591 zSql[j++] = ','; 002592 zSql[j++] = '?'; 002593 } 002594 zSql[j++] = ')'; 002595 zSql[j] = 0; 002596 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); 002597 free(zSql); 002598 if( rc ){ 002599 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); 002600 sqlite3_finalize(pStmt); 002601 return TCL_ERROR; 002602 } 002603 in = fopen(zFile, "rb"); 002604 if( in==0 ){ 002605 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0); 002606 sqlite3_finalize(pStmt); 002607 return TCL_ERROR; 002608 } 002609 azCol = malloc( sizeof(azCol[0])*(nCol+1) ); 002610 if( azCol==0 ) { 002611 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); 002612 fclose(in); 002613 return TCL_ERROR; 002614 } 002615 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0); 002616 zCommit = "COMMIT"; 002617 while( (zLine = local_getline(0, in))!=0 ){ 002618 char *z; 002619 lineno++; 002620 azCol[0] = zLine; 002621 for(i=0, z=zLine; *z; z++){ 002622 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){ 002623 *z = 0; 002624 i++; 002625 if( i<nCol ){ 002626 azCol[i] = &z[nSep]; 002627 z += nSep-1; 002628 } 002629 } 002630 } 002631 if( i+1!=nCol ){ 002632 char *zErr; 002633 int nErr = strlen30(zFile) + 200; 002634 zErr = malloc(nErr); 002635 if( zErr ){ 002636 sqlite3_snprintf(nErr, zErr, 002637 "Error: %s line %d: expected %d columns of data but found %d", 002638 zFile, lineno, nCol, i+1); 002639 Tcl_AppendResult(interp, zErr, (char*)0); 002640 free(zErr); 002641 } 002642 zCommit = "ROLLBACK"; 002643 break; 002644 } 002645 for(i=0; i<nCol; i++){ 002646 /* check for null data, if so, bind as null */ 002647 if( (nNull>0 && strcmp(azCol[i], zNull)==0) 002648 || strlen30(azCol[i])==0 002649 ){ 002650 sqlite3_bind_null(pStmt, i+1); 002651 }else{ 002652 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); 002653 } 002654 } 002655 sqlite3_step(pStmt); 002656 rc = sqlite3_reset(pStmt); 002657 free(zLine); 002658 if( rc!=SQLITE_OK ){ 002659 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0); 002660 zCommit = "ROLLBACK"; 002661 break; 002662 } 002663 } 002664 free(azCol); 002665 fclose(in); 002666 sqlite3_finalize(pStmt); 002667 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0); 002668 002669 if( zCommit[0] == 'C' ){ 002670 /* success, set result as number of lines processed */ 002671 pResult = Tcl_GetObjResult(interp); 002672 Tcl_SetIntObj(pResult, lineno); 002673 rc = TCL_OK; 002674 }else{ 002675 /* failure, append lineno where failed */ 002676 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno); 002677 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum, 002678 (char*)0); 002679 rc = TCL_ERROR; 002680 } 002681 break; 002682 } 002683 002684 /* 002685 ** $db deserialize ?-maxsize N? ?-readonly BOOL? ?DATABASE? VALUE 002686 ** 002687 ** Reopen DATABASE (default "main") using the content in $VALUE 002688 */ 002689 case DB_DESERIALIZE: { 002690 #ifdef SQLITE_OMIT_DESERIALIZE 002691 Tcl_AppendResult(interp, "MEMDB not available in this build", 002692 (char*)0); 002693 rc = TCL_ERROR; 002694 #else 002695 const char *zSchema = 0; 002696 Tcl_Obj *pValue = 0; 002697 unsigned char *pBA; 002698 unsigned char *pData; 002699 Tcl_Size len; 002700 int xrc; 002701 sqlite3_int64 mxSize = 0; 002702 int i; 002703 int isReadonly = 0; 002704 002705 002706 if( objc<3 ){ 002707 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE"); 002708 rc = TCL_ERROR; 002709 break; 002710 } 002711 for(i=2; i<objc-1; i++){ 002712 const char *z = Tcl_GetString(objv[i]); 002713 if( strcmp(z,"-maxsize")==0 && i<objc-2 ){ 002714 Tcl_WideInt x; 002715 rc = Tcl_GetWideIntFromObj(interp, objv[++i], &x); 002716 if( rc ) goto deserialize_error; 002717 mxSize = x; 002718 continue; 002719 } 002720 if( strcmp(z,"-readonly")==0 && i<objc-2 ){ 002721 rc = Tcl_GetBooleanFromObj(interp, objv[++i], &isReadonly); 002722 if( rc ) goto deserialize_error; 002723 continue; 002724 } 002725 if( zSchema==0 && i==objc-2 && z[0]!='-' ){ 002726 zSchema = z; 002727 continue; 002728 } 002729 Tcl_AppendResult(interp, "unknown option: ", z, (char*)0); 002730 rc = TCL_ERROR; 002731 goto deserialize_error; 002732 } 002733 pValue = objv[objc-1]; 002734 pBA = Tcl_GetByteArrayFromObj(pValue, &len); 002735 pData = sqlite3_malloc64( len ); 002736 if( pData==0 && len>0 ){ 002737 Tcl_AppendResult(interp, "out of memory", (char*)0); 002738 rc = TCL_ERROR; 002739 }else{ 002740 int flags; 002741 if( len>0 ) memcpy(pData, pBA, len); 002742 if( isReadonly ){ 002743 flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_READONLY; 002744 }else{ 002745 flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE; 002746 } 002747 xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len, flags); 002748 if( xrc ){ 002749 Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0); 002750 rc = TCL_ERROR; 002751 } 002752 if( mxSize>0 ){ 002753 sqlite3_file_control(pDb->db, zSchema,SQLITE_FCNTL_SIZE_LIMIT,&mxSize); 002754 } 002755 } 002756 deserialize_error: 002757 #endif 002758 break; 002759 } 002760 002761 /* 002762 ** $db enable_load_extension BOOLEAN 002763 ** 002764 ** Turn the extension loading feature on or off. It if off by 002765 ** default. 002766 */ 002767 case DB_ENABLE_LOAD_EXTENSION: { 002768 #ifndef SQLITE_OMIT_LOAD_EXTENSION 002769 int onoff; 002770 if( objc!=3 ){ 002771 Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN"); 002772 return TCL_ERROR; 002773 } 002774 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){ 002775 return TCL_ERROR; 002776 } 002777 sqlite3_enable_load_extension(pDb->db, onoff); 002778 break; 002779 #else 002780 Tcl_AppendResult(interp, "extension loading is turned off at compile-time", 002781 (char*)0); 002782 return TCL_ERROR; 002783 #endif 002784 } 002785 002786 /* 002787 ** $db errorcode 002788 ** 002789 ** Return the numeric error code that was returned by the most recent 002790 ** call to sqlite3_exec(). 002791 */ 002792 case DB_ERRORCODE: { 002793 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db))); 002794 break; 002795 } 002796 002797 /* 002798 ** $db erroroffset 002799 ** 002800 ** Return the numeric error code that was returned by the most recent 002801 ** call to sqlite3_exec(). 002802 */ 002803 case DB_ERROROFFSET: { 002804 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_error_offset(pDb->db))); 002805 break; 002806 } 002807 002808 /* 002809 ** $db exists $sql 002810 ** $db onecolumn $sql 002811 ** 002812 ** The onecolumn method is the equivalent of: 002813 ** lindex [$db eval $sql] 0 002814 */ 002815 case DB_EXISTS: 002816 case DB_ONECOLUMN: { 002817 Tcl_Obj *pResult = 0; 002818 DbEvalContext sEval; 002819 if( objc!=3 ){ 002820 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); 002821 return TCL_ERROR; 002822 } 002823 002824 dbEvalInit(&sEval, pDb, objv[2], 0, 0); 002825 rc = dbEvalStep(&sEval); 002826 if( choice==DB_ONECOLUMN ){ 002827 if( rc==TCL_OK ){ 002828 pResult = dbEvalColumnValue(&sEval, 0); 002829 }else if( rc==TCL_BREAK ){ 002830 Tcl_ResetResult(interp); 002831 } 002832 }else if( rc==TCL_BREAK || rc==TCL_OK ){ 002833 pResult = Tcl_NewBooleanObj(rc==TCL_OK); 002834 } 002835 dbEvalFinalize(&sEval); 002836 if( pResult ) Tcl_SetObjResult(interp, pResult); 002837 002838 if( rc==TCL_BREAK ){ 002839 rc = TCL_OK; 002840 } 002841 break; 002842 } 002843 002844 /* 002845 ** $db eval ?options? $sql ?array? ?{ ...code... }? 002846 ** 002847 ** The SQL statement in $sql is evaluated. For each row, the values are 002848 ** placed in elements of the array named "array" and ...code... is executed. 002849 ** If "array" and "code" are omitted, then no callback is every invoked. 002850 ** If "array" is an empty string, then the values are placed in variables 002851 ** that have the same name as the fields extracted by the query. 002852 */ 002853 case DB_EVAL: { 002854 int evalFlags = 0; 002855 const char *zOpt; 002856 while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){ 002857 if( strcmp(zOpt, "-withoutnulls")==0 ){ 002858 evalFlags |= SQLITE_EVAL_WITHOUTNULLS; 002859 } 002860 else{ 002861 Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0); 002862 return TCL_ERROR; 002863 } 002864 objc--; 002865 objv++; 002866 } 002867 if( objc<3 || objc>5 ){ 002868 Tcl_WrongNumArgs(interp, 2, objv, 002869 "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"); 002870 return TCL_ERROR; 002871 } 002872 002873 if( objc==3 ){ 002874 DbEvalContext sEval; 002875 Tcl_Obj *pRet = Tcl_NewObj(); 002876 Tcl_IncrRefCount(pRet); 002877 dbEvalInit(&sEval, pDb, objv[2], 0, 0); 002878 while( TCL_OK==(rc = dbEvalStep(&sEval)) ){ 002879 int i; 002880 int nCol; 002881 dbEvalRowInfo(&sEval, &nCol, 0); 002882 for(i=0; i<nCol; i++){ 002883 Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i)); 002884 } 002885 } 002886 dbEvalFinalize(&sEval); 002887 if( rc==TCL_BREAK ){ 002888 Tcl_SetObjResult(interp, pRet); 002889 rc = TCL_OK; 002890 } 002891 Tcl_DecrRefCount(pRet); 002892 }else{ 002893 ClientData cd2[2]; 002894 DbEvalContext *p; 002895 Tcl_Obj *pArray = 0; 002896 Tcl_Obj *pScript; 002897 002898 if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){ 002899 pArray = objv[3]; 002900 } 002901 pScript = objv[objc-1]; 002902 Tcl_IncrRefCount(pScript); 002903 002904 p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext)); 002905 dbEvalInit(p, pDb, objv[2], pArray, evalFlags); 002906 002907 cd2[0] = (void *)p; 002908 cd2[1] = (void *)pScript; 002909 rc = DbEvalNextCmd(cd2, interp, TCL_OK); 002910 } 002911 break; 002912 } 002913 002914 /* 002915 ** $db function NAME [OPTIONS] SCRIPT 002916 ** 002917 ** Create a new SQL function called NAME. Whenever that function is 002918 ** called, invoke SCRIPT to evaluate the function. 002919 ** 002920 ** Options: 002921 ** --argcount N Function has exactly N arguments 002922 ** --deterministic The function is pure 002923 ** --directonly Prohibit use inside triggers and views 002924 ** --innocuous Has no side effects or information leaks 002925 ** --returntype TYPE Specify the return type of the function 002926 */ 002927 case DB_FUNCTION: { 002928 int flags = SQLITE_UTF8; 002929 SqlFunc *pFunc; 002930 Tcl_Obj *pScript; 002931 char *zName; 002932 int nArg = -1; 002933 int i; 002934 int eType = SQLITE_NULL; 002935 if( objc<4 ){ 002936 Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT"); 002937 return TCL_ERROR; 002938 } 002939 for(i=3; i<(objc-1); i++){ 002940 const char *z = Tcl_GetString(objv[i]); 002941 int n = strlen30(z); 002942 if( n>1 && strncmp(z, "-argcount",n)==0 ){ 002943 if( i==(objc-2) ){ 002944 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0); 002945 return TCL_ERROR; 002946 } 002947 if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR; 002948 if( nArg<0 ){ 002949 Tcl_AppendResult(interp, "number of arguments must be non-negative", 002950 (char*)0); 002951 return TCL_ERROR; 002952 } 002953 i++; 002954 }else 002955 if( n>1 && strncmp(z, "-deterministic",n)==0 ){ 002956 flags |= SQLITE_DETERMINISTIC; 002957 }else 002958 if( n>1 && strncmp(z, "-directonly",n)==0 ){ 002959 flags |= SQLITE_DIRECTONLY; 002960 }else 002961 if( n>1 && strncmp(z, "-innocuous",n)==0 ){ 002962 flags |= SQLITE_INNOCUOUS; 002963 }else 002964 if( n>1 && strncmp(z, "-returntype", n)==0 ){ 002965 const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; 002966 assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); 002967 assert( SQLITE_BLOB==4 && SQLITE_NULL==5 ); 002968 if( i==(objc-2) ){ 002969 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0); 002970 return TCL_ERROR; 002971 } 002972 i++; 002973 if( Tcl_GetIndexFromObj(interp, objv[i], azType, "type", 0, &eType) ){ 002974 return TCL_ERROR; 002975 } 002976 eType++; 002977 }else{ 002978 Tcl_AppendResult(interp, "bad option \"", z, 002979 "\": must be -argcount, -deterministic, -directonly," 002980 " -innocuous, or -returntype", (char*)0 002981 ); 002982 return TCL_ERROR; 002983 } 002984 } 002985 002986 pScript = objv[objc-1]; 002987 zName = Tcl_GetStringFromObj(objv[2], 0); 002988 pFunc = findSqlFunc(pDb, zName); 002989 if( pFunc==0 ) return TCL_ERROR; 002990 if( pFunc->pScript ){ 002991 Tcl_DecrRefCount(pFunc->pScript); 002992 } 002993 pFunc->pScript = pScript; 002994 Tcl_IncrRefCount(pScript); 002995 pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript); 002996 pFunc->eType = eType; 002997 rc = sqlite3_create_function(pDb->db, zName, nArg, flags, 002998 pFunc, tclSqlFunc, 0, 0); 002999 if( rc!=SQLITE_OK ){ 003000 rc = TCL_ERROR; 003001 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); 003002 } 003003 break; 003004 } 003005 003006 /* 003007 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID 003008 */ 003009 case DB_INCRBLOB: { 003010 #ifdef SQLITE_OMIT_INCRBLOB 003011 Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0); 003012 return TCL_ERROR; 003013 #else 003014 int isReadonly = 0; 003015 const char *zDb = "main"; 003016 const char *zTable; 003017 const char *zColumn; 003018 Tcl_WideInt iRow; 003019 003020 /* Check for the -readonly option */ 003021 if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){ 003022 isReadonly = 1; 003023 } 003024 003025 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){ 003026 Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID"); 003027 return TCL_ERROR; 003028 } 003029 003030 if( objc==(6+isReadonly) ){ 003031 zDb = Tcl_GetString(objv[2+isReadonly]); 003032 } 003033 zTable = Tcl_GetString(objv[objc-3]); 003034 zColumn = Tcl_GetString(objv[objc-2]); 003035 rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow); 003036 003037 if( rc==TCL_OK ){ 003038 rc = createIncrblobChannel( 003039 interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly 003040 ); 003041 } 003042 #endif 003043 break; 003044 } 003045 003046 /* 003047 ** $db interrupt 003048 ** 003049 ** Interrupt the execution of the inner-most SQL interpreter. This 003050 ** causes the SQL statement to return an error of SQLITE_INTERRUPT. 003051 */ 003052 case DB_INTERRUPT: { 003053 sqlite3_interrupt(pDb->db); 003054 break; 003055 } 003056 003057 /* 003058 ** $db nullvalue ?STRING? 003059 ** 003060 ** Change text used when a NULL comes back from the database. If ?STRING? 003061 ** is not present, then the current string used for NULL is returned. 003062 ** If STRING is present, then STRING is returned. 003063 ** 003064 */ 003065 case DB_NULLVALUE: { 003066 if( objc!=2 && objc!=3 ){ 003067 Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE"); 003068 return TCL_ERROR; 003069 } 003070 if( objc==3 ){ 003071 Tcl_Size len; 003072 char *zNull = Tcl_GetStringFromObj(objv[2], &len); 003073 if( pDb->zNull ){ 003074 Tcl_Free(pDb->zNull); 003075 } 003076 if( zNull && len>0 ){ 003077 pDb->zNull = Tcl_Alloc( len + 1 ); 003078 memcpy(pDb->zNull, zNull, len); 003079 pDb->zNull[len] = '\0'; 003080 }else{ 003081 pDb->zNull = 0; 003082 } 003083 } 003084 Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1)); 003085 break; 003086 } 003087 003088 /* 003089 ** $db last_insert_rowid 003090 ** 003091 ** Return an integer which is the ROWID for the most recent insert. 003092 */ 003093 case DB_LAST_INSERT_ROWID: { 003094 Tcl_Obj *pResult; 003095 Tcl_WideInt rowid; 003096 if( objc!=2 ){ 003097 Tcl_WrongNumArgs(interp, 2, objv, ""); 003098 return TCL_ERROR; 003099 } 003100 rowid = sqlite3_last_insert_rowid(pDb->db); 003101 pResult = Tcl_GetObjResult(interp); 003102 Tcl_SetWideIntObj(pResult, rowid); 003103 break; 003104 } 003105 003106 /* 003107 ** The DB_ONECOLUMN method is implemented together with DB_EXISTS. 003108 */ 003109 003110 /* $db progress ?N CALLBACK? 003111 ** 003112 ** Invoke the given callback every N virtual machine opcodes while executing 003113 ** queries. 003114 */ 003115 case DB_PROGRESS: { 003116 if( objc==2 ){ 003117 if( pDb->zProgress ){ 003118 Tcl_AppendResult(interp, pDb->zProgress, (char*)0); 003119 } 003120 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 003121 sqlite3_progress_handler(pDb->db, 0, 0, 0); 003122 #endif 003123 }else if( objc==4 ){ 003124 char *zProgress; 003125 Tcl_Size len; 003126 int N; 003127 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ 003128 return TCL_ERROR; 003129 }; 003130 if( pDb->zProgress ){ 003131 Tcl_Free(pDb->zProgress); 003132 } 003133 zProgress = Tcl_GetStringFromObj(objv[3], &len); 003134 if( zProgress && len>0 ){ 003135 pDb->zProgress = Tcl_Alloc( len + 1 ); 003136 memcpy(pDb->zProgress, zProgress, len+1); 003137 }else{ 003138 pDb->zProgress = 0; 003139 } 003140 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 003141 if( pDb->zProgress ){ 003142 pDb->interp = interp; 003143 sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb); 003144 }else{ 003145 sqlite3_progress_handler(pDb->db, 0, 0, 0); 003146 } 003147 #endif 003148 }else{ 003149 Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK"); 003150 return TCL_ERROR; 003151 } 003152 break; 003153 } 003154 003155 /* $db profile ?CALLBACK? 003156 ** 003157 ** Make arrangements to invoke the CALLBACK routine after each SQL statement 003158 ** that has run. The text of the SQL and the amount of elapse time are 003159 ** appended to CALLBACK before the script is run. 003160 */ 003161 case DB_PROFILE: { 003162 if( objc>3 ){ 003163 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 003164 return TCL_ERROR; 003165 }else if( objc==2 ){ 003166 if( pDb->zProfile ){ 003167 Tcl_AppendResult(interp, pDb->zProfile, (char*)0); 003168 } 003169 }else{ 003170 char *zProfile; 003171 Tcl_Size len; 003172 if( pDb->zProfile ){ 003173 Tcl_Free(pDb->zProfile); 003174 } 003175 zProfile = Tcl_GetStringFromObj(objv[2], &len); 003176 if( zProfile && len>0 ){ 003177 pDb->zProfile = Tcl_Alloc( len + 1 ); 003178 memcpy(pDb->zProfile, zProfile, len+1); 003179 }else{ 003180 pDb->zProfile = 0; 003181 } 003182 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ 003183 !defined(SQLITE_OMIT_DEPRECATED) 003184 if( pDb->zProfile ){ 003185 pDb->interp = interp; 003186 sqlite3_profile(pDb->db, DbProfileHandler, pDb); 003187 }else{ 003188 sqlite3_profile(pDb->db, 0, 0); 003189 } 003190 #endif 003191 } 003192 break; 003193 } 003194 003195 /* 003196 ** $db rekey KEY 003197 ** 003198 ** Change the encryption key on the currently open database. 003199 */ 003200 case DB_REKEY: { 003201 if( objc!=3 ){ 003202 Tcl_WrongNumArgs(interp, 2, objv, "KEY"); 003203 return TCL_ERROR; 003204 } 003205 break; 003206 } 003207 003208 /* $db restore ?DATABASE? FILENAME 003209 ** 003210 ** Open a database file named FILENAME. Transfer the content 003211 ** of FILENAME into the local database DATABASE (default: "main"). 003212 */ 003213 case DB_RESTORE: { 003214 const char *zSrcFile; 003215 const char *zDestDb; 003216 sqlite3 *pSrc; 003217 sqlite3_backup *pBackup; 003218 int nTimeout = 0; 003219 003220 if( objc==3 ){ 003221 zDestDb = "main"; 003222 zSrcFile = Tcl_GetString(objv[2]); 003223 }else if( objc==4 ){ 003224 zDestDb = Tcl_GetString(objv[2]); 003225 zSrcFile = Tcl_GetString(objv[3]); 003226 }else{ 003227 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME"); 003228 return TCL_ERROR; 003229 } 003230 rc = sqlite3_open_v2(zSrcFile, &pSrc, 003231 SQLITE_OPEN_READONLY | pDb->openFlags, 0); 003232 if( rc!=SQLITE_OK ){ 003233 Tcl_AppendResult(interp, "cannot open source database: ", 003234 sqlite3_errmsg(pSrc), (char*)0); 003235 sqlite3_close(pSrc); 003236 return TCL_ERROR; 003237 } 003238 pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main"); 003239 if( pBackup==0 ){ 003240 Tcl_AppendResult(interp, "restore failed: ", 003241 sqlite3_errmsg(pDb->db), (char*)0); 003242 sqlite3_close(pSrc); 003243 return TCL_ERROR; 003244 } 003245 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK 003246 || rc==SQLITE_BUSY ){ 003247 if( rc==SQLITE_BUSY ){ 003248 if( nTimeout++ >= 3 ) break; 003249 sqlite3_sleep(100); 003250 } 003251 } 003252 sqlite3_backup_finish(pBackup); 003253 if( rc==SQLITE_DONE ){ 003254 rc = TCL_OK; 003255 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ 003256 Tcl_AppendResult(interp, "restore failed: source database busy", 003257 (char*)0); 003258 rc = TCL_ERROR; 003259 }else{ 003260 Tcl_AppendResult(interp, "restore failed: ", 003261 sqlite3_errmsg(pDb->db), (char*)0); 003262 rc = TCL_ERROR; 003263 } 003264 sqlite3_close(pSrc); 003265 break; 003266 } 003267 003268 /* 003269 ** $db serialize ?DATABASE? 003270 ** 003271 ** Return a serialization of a database. 003272 */ 003273 case DB_SERIALIZE: { 003274 #ifdef SQLITE_OMIT_DESERIALIZE 003275 Tcl_AppendResult(interp, "MEMDB not available in this build", 003276 (char*)0); 003277 rc = TCL_ERROR; 003278 #else 003279 const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main"; 003280 sqlite3_int64 sz = 0; 003281 unsigned char *pData; 003282 if( objc!=2 && objc!=3 ){ 003283 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?"); 003284 rc = TCL_ERROR; 003285 }else{ 003286 int needFree; 003287 pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY); 003288 if( pData ){ 003289 needFree = 0; 003290 }else{ 003291 pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0); 003292 needFree = 1; 003293 } 003294 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz)); 003295 if( needFree ) sqlite3_free(pData); 003296 } 003297 #endif 003298 break; 003299 } 003300 003301 /* 003302 ** $db status (step|sort|autoindex|vmstep) 003303 ** 003304 ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or 003305 ** SQLITE_STMTSTATUS_SORT for the most recent eval. 003306 */ 003307 case DB_STATUS: { 003308 int v; 003309 const char *zOp; 003310 if( objc!=3 ){ 003311 Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)"); 003312 return TCL_ERROR; 003313 } 003314 zOp = Tcl_GetString(objv[2]); 003315 if( strcmp(zOp, "step")==0 ){ 003316 v = pDb->nStep; 003317 }else if( strcmp(zOp, "sort")==0 ){ 003318 v = pDb->nSort; 003319 }else if( strcmp(zOp, "autoindex")==0 ){ 003320 v = pDb->nIndex; 003321 }else if( strcmp(zOp, "vmstep")==0 ){ 003322 v = pDb->nVMStep; 003323 }else{ 003324 Tcl_AppendResult(interp, 003325 "bad argument: should be autoindex, step, sort or vmstep", 003326 (char*)0); 003327 return TCL_ERROR; 003328 } 003329 Tcl_SetObjResult(interp, Tcl_NewIntObj(v)); 003330 break; 003331 } 003332 003333 /* 003334 ** $db timeout MILLESECONDS 003335 ** 003336 ** Delay for the number of milliseconds specified when a file is locked. 003337 */ 003338 case DB_TIMEOUT: { 003339 int ms; 003340 if( objc!=3 ){ 003341 Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS"); 003342 return TCL_ERROR; 003343 } 003344 if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR; 003345 sqlite3_busy_timeout(pDb->db, ms); 003346 break; 003347 } 003348 003349 /* 003350 ** $db total_changes 003351 ** 003352 ** Return the number of rows that were modified, inserted, or deleted 003353 ** since the database handle was created. 003354 */ 003355 case DB_TOTAL_CHANGES: { 003356 Tcl_Obj *pResult; 003357 if( objc!=2 ){ 003358 Tcl_WrongNumArgs(interp, 2, objv, ""); 003359 return TCL_ERROR; 003360 } 003361 pResult = Tcl_GetObjResult(interp); 003362 Tcl_SetWideIntObj(pResult, sqlite3_total_changes64(pDb->db)); 003363 break; 003364 } 003365 003366 /* $db trace ?CALLBACK? 003367 ** 003368 ** Make arrangements to invoke the CALLBACK routine for each SQL statement 003369 ** that is executed. The text of the SQL is appended to CALLBACK before 003370 ** it is executed. 003371 */ 003372 case DB_TRACE: { 003373 if( objc>3 ){ 003374 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 003375 return TCL_ERROR; 003376 }else if( objc==2 ){ 003377 if( pDb->zTrace ){ 003378 Tcl_AppendResult(interp, pDb->zTrace, (char*)0); 003379 } 003380 }else{ 003381 char *zTrace; 003382 Tcl_Size len; 003383 if( pDb->zTrace ){ 003384 Tcl_Free(pDb->zTrace); 003385 } 003386 zTrace = Tcl_GetStringFromObj(objv[2], &len); 003387 if( zTrace && len>0 ){ 003388 pDb->zTrace = Tcl_Alloc( len + 1 ); 003389 memcpy(pDb->zTrace, zTrace, len+1); 003390 }else{ 003391 pDb->zTrace = 0; 003392 } 003393 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ 003394 !defined(SQLITE_OMIT_DEPRECATED) 003395 if( pDb->zTrace ){ 003396 pDb->interp = interp; 003397 sqlite3_trace(pDb->db, DbTraceHandler, pDb); 003398 }else{ 003399 sqlite3_trace(pDb->db, 0, 0); 003400 } 003401 #endif 003402 } 003403 break; 003404 } 003405 003406 /* $db trace_v2 ?CALLBACK? ?MASK? 003407 ** 003408 ** Make arrangements to invoke the CALLBACK routine for each trace event 003409 ** matching the mask that is generated. The parameters are appended to 003410 ** CALLBACK before it is executed. 003411 */ 003412 case DB_TRACE_V2: { 003413 if( objc>4 ){ 003414 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?"); 003415 return TCL_ERROR; 003416 }else if( objc==2 ){ 003417 if( pDb->zTraceV2 ){ 003418 Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0); 003419 } 003420 }else{ 003421 char *zTraceV2; 003422 Tcl_Size len; 003423 Tcl_WideInt wMask = 0; 003424 if( objc==4 ){ 003425 static const char *TTYPE_strs[] = { 003426 "statement", "profile", "row", "close", 0 003427 }; 003428 enum TTYPE_enum { 003429 TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE 003430 }; 003431 int i; 003432 if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){ 003433 return TCL_ERROR; 003434 } 003435 for(i=0; i<len; i++){ 003436 Tcl_Obj *pObj; 003437 int ttype; 003438 if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){ 003439 return TCL_ERROR; 003440 } 003441 if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type", 003442 0, &ttype)!=TCL_OK ){ 003443 Tcl_WideInt wType; 003444 Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); 003445 Tcl_IncrRefCount(pError); 003446 if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){ 003447 Tcl_DecrRefCount(pError); 003448 wMask |= wType; 003449 }else{ 003450 Tcl_SetObjResult(interp, pError); 003451 Tcl_DecrRefCount(pError); 003452 return TCL_ERROR; 003453 } 003454 }else{ 003455 switch( (enum TTYPE_enum)ttype ){ 003456 case TTYPE_STMT: wMask |= SQLITE_TRACE_STMT; break; 003457 case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break; 003458 case TTYPE_ROW: wMask |= SQLITE_TRACE_ROW; break; 003459 case TTYPE_CLOSE: wMask |= SQLITE_TRACE_CLOSE; break; 003460 } 003461 } 003462 } 003463 }else{ 003464 wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */ 003465 } 003466 if( pDb->zTraceV2 ){ 003467 Tcl_Free(pDb->zTraceV2); 003468 } 003469 zTraceV2 = Tcl_GetStringFromObj(objv[2], &len); 003470 if( zTraceV2 && len>0 ){ 003471 pDb->zTraceV2 = Tcl_Alloc( len + 1 ); 003472 memcpy(pDb->zTraceV2, zTraceV2, len+1); 003473 }else{ 003474 pDb->zTraceV2 = 0; 003475 } 003476 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) 003477 if( pDb->zTraceV2 ){ 003478 pDb->interp = interp; 003479 sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb); 003480 }else{ 003481 sqlite3_trace_v2(pDb->db, 0, 0, 0); 003482 } 003483 #endif 003484 } 003485 break; 003486 } 003487 003488 /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT 003489 ** 003490 ** Start a new transaction (if we are not already in the midst of a 003491 ** transaction) and execute the TCL script SCRIPT. After SCRIPT 003492 ** completes, either commit the transaction or roll it back if SCRIPT 003493 ** throws an exception. Or if no new transaction was started, do nothing. 003494 ** pass the exception on up the stack. 003495 ** 003496 ** This command was inspired by Dave Thomas's talk on Ruby at the 003497 ** 2005 O'Reilly Open Source Convention (OSCON). 003498 */ 003499 case DB_TRANSACTION: { 003500 Tcl_Obj *pScript; 003501 const char *zBegin = "SAVEPOINT _tcl_transaction"; 003502 if( objc!=3 && objc!=4 ){ 003503 Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT"); 003504 return TCL_ERROR; 003505 } 003506 003507 if( pDb->nTransaction==0 && objc==4 ){ 003508 static const char *TTYPE_strs[] = { 003509 "deferred", "exclusive", "immediate", 0 003510 }; 003511 enum TTYPE_enum { 003512 TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE 003513 }; 003514 int ttype; 003515 if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type", 003516 0, &ttype) ){ 003517 return TCL_ERROR; 003518 } 003519 switch( (enum TTYPE_enum)ttype ){ 003520 case TTYPE_DEFERRED: /* no-op */; break; 003521 case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break; 003522 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break; 003523 } 003524 } 003525 pScript = objv[objc-1]; 003526 003527 /* Run the SQLite BEGIN command to open a transaction or savepoint. */ 003528 pDb->disableAuth++; 003529 rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0); 003530 pDb->disableAuth--; 003531 if( rc!=SQLITE_OK ){ 003532 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); 003533 return TCL_ERROR; 003534 } 003535 pDb->nTransaction++; 003536 003537 /* If using NRE, schedule a callback to invoke the script pScript, then 003538 ** a second callback to commit (or rollback) the transaction or savepoint 003539 ** opened above. If not using NRE, evaluate the script directly, then 003540 ** call function DbTransPostCmd() to commit (or rollback) the transaction 003541 ** or savepoint. */ 003542 addDatabaseRef(pDb); /* DbTransPostCmd() calls delDatabaseRef() */ 003543 if( DbUseNre() ){ 003544 Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); 003545 (void)Tcl_NREvalObj(interp, pScript, 0); 003546 }else{ 003547 rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0)); 003548 } 003549 break; 003550 } 003551 003552 /* 003553 ** $db unlock_notify ?script? 003554 */ 003555 case DB_UNLOCK_NOTIFY: { 003556 #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY 003557 Tcl_AppendResult(interp, "unlock_notify not available in this build", 003558 (char*)0); 003559 rc = TCL_ERROR; 003560 #else 003561 if( objc!=2 && objc!=3 ){ 003562 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); 003563 rc = TCL_ERROR; 003564 }else{ 003565 void (*xNotify)(void **, int) = 0; 003566 void *pNotifyArg = 0; 003567 003568 if( pDb->pUnlockNotify ){ 003569 Tcl_DecrRefCount(pDb->pUnlockNotify); 003570 pDb->pUnlockNotify = 0; 003571 } 003572 003573 if( objc==3 ){ 003574 xNotify = DbUnlockNotify; 003575 pNotifyArg = (void *)pDb; 003576 pDb->pUnlockNotify = objv[2]; 003577 Tcl_IncrRefCount(pDb->pUnlockNotify); 003578 } 003579 003580 if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ 003581 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); 003582 rc = TCL_ERROR; 003583 } 003584 } 003585 #endif 003586 break; 003587 } 003588 003589 /* 003590 ** $db preupdate_hook count 003591 ** $db preupdate_hook hook ?SCRIPT? 003592 ** $db preupdate_hook new INDEX 003593 ** $db preupdate_hook old INDEX 003594 */ 003595 case DB_PREUPDATE: { 003596 #ifndef SQLITE_ENABLE_PREUPDATE_HOOK 003597 Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time", 003598 (char*)0); 003599 rc = TCL_ERROR; 003600 #else 003601 static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0}; 003602 enum DbPreupdateSubCmd { 003603 PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD 003604 }; 003605 int iSub; 003606 003607 if( objc<3 ){ 003608 Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?"); 003609 } 003610 if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){ 003611 return TCL_ERROR; 003612 } 003613 003614 switch( (enum DbPreupdateSubCmd)iSub ){ 003615 case PRE_COUNT: { 003616 int nCol = sqlite3_preupdate_count(pDb->db); 003617 Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol)); 003618 break; 003619 } 003620 003621 case PRE_HOOK: { 003622 if( objc>4 ){ 003623 Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?"); 003624 return TCL_ERROR; 003625 } 003626 DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook); 003627 break; 003628 } 003629 003630 case PRE_DEPTH: { 003631 Tcl_Obj *pRet; 003632 if( objc!=3 ){ 003633 Tcl_WrongNumArgs(interp, 3, objv, ""); 003634 return TCL_ERROR; 003635 } 003636 pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db)); 003637 Tcl_SetObjResult(interp, pRet); 003638 break; 003639 } 003640 003641 case PRE_NEW: 003642 case PRE_OLD: { 003643 int iIdx; 003644 sqlite3_value *pValue; 003645 if( objc!=4 ){ 003646 Tcl_WrongNumArgs(interp, 3, objv, "INDEX"); 003647 return TCL_ERROR; 003648 } 003649 if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){ 003650 return TCL_ERROR; 003651 } 003652 003653 if( iSub==PRE_OLD ){ 003654 rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue); 003655 }else{ 003656 assert( iSub==PRE_NEW ); 003657 rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue); 003658 } 003659 003660 if( rc==SQLITE_OK ){ 003661 Tcl_Obj *pObj; 003662 pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1); 003663 Tcl_SetObjResult(interp, pObj); 003664 }else{ 003665 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); 003666 return TCL_ERROR; 003667 } 003668 } 003669 } 003670 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ 003671 break; 003672 } 003673 003674 /* 003675 ** $db wal_hook ?script? 003676 ** $db update_hook ?script? 003677 ** $db rollback_hook ?script? 003678 */ 003679 case DB_WAL_HOOK: 003680 case DB_UPDATE_HOOK: 003681 case DB_ROLLBACK_HOOK: { 003682 /* set ppHook to point at pUpdateHook or pRollbackHook, depending on 003683 ** whether [$db update_hook] or [$db rollback_hook] was invoked. 003684 */ 003685 Tcl_Obj **ppHook = 0; 003686 if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook; 003687 if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook; 003688 if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook; 003689 if( objc>3 ){ 003690 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); 003691 return TCL_ERROR; 003692 } 003693 003694 DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook); 003695 break; 003696 } 003697 003698 /* $db version 003699 ** 003700 ** Return the version string for this database. 003701 */ 003702 case DB_VERSION: { 003703 int i; 003704 for(i=2; i<objc; i++){ 003705 const char *zArg = Tcl_GetString(objv[i]); 003706 /* Optional arguments to $db version are used for testing purpose */ 003707 #ifdef SQLITE_TEST 003708 /* $db version -use-legacy-prepare BOOLEAN 003709 ** 003710 ** Turn the use of legacy sqlite3_prepare() on or off. 003711 */ 003712 if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){ 003713 i++; 003714 if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){ 003715 return TCL_ERROR; 003716 } 003717 }else 003718 003719 /* $db version -last-stmt-ptr 003720 ** 003721 ** Return a string which is a hex encoding of the pointer to the 003722 ** most recent sqlite3_stmt in the statement cache. 003723 */ 003724 if( strcmp(zArg, "-last-stmt-ptr")==0 ){ 003725 char zBuf[100]; 003726 sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", 003727 pDb->stmtList ? pDb->stmtList->pStmt: 0); 003728 Tcl_SetResult(interp, zBuf, TCL_VOLATILE); 003729 }else 003730 #endif /* SQLITE_TEST */ 003731 { 003732 Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0); 003733 return TCL_ERROR; 003734 } 003735 } 003736 if( i==2 ){ 003737 Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC); 003738 } 003739 break; 003740 } 003741 003742 003743 } /* End of the SWITCH statement */ 003744 return rc; 003745 } 003746 003747 #if SQLITE_TCL_NRE 003748 /* 003749 ** Adaptor that provides an objCmd interface to the NRE-enabled 003750 ** interface implementation. 003751 */ 003752 static int SQLITE_TCLAPI DbObjCmdAdaptor( 003753 void *cd, 003754 Tcl_Interp *interp, 003755 int objc, 003756 Tcl_Obj *const*objv 003757 ){ 003758 return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv); 003759 } 003760 #endif /* SQLITE_TCL_NRE */ 003761 003762 /* 003763 ** Issue the usage message when the "sqlite3" command arguments are 003764 ** incorrect. 003765 */ 003766 static int sqliteCmdUsage( 003767 Tcl_Interp *interp, 003768 Tcl_Obj *const*objv 003769 ){ 003770 Tcl_WrongNumArgs(interp, 1, objv, 003771 "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" 003772 " ?-nofollow BOOLEAN?" 003773 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" 003774 ); 003775 return TCL_ERROR; 003776 } 003777 003778 /* 003779 ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? 003780 ** ?-create BOOLEAN? ?-nomutex BOOLEAN? 003781 ** ?-nofollow BOOLEAN? 003782 ** 003783 ** This is the main Tcl command. When the "sqlite" Tcl command is 003784 ** invoked, this routine runs to process that command. 003785 ** 003786 ** The first argument, DBNAME, is an arbitrary name for a new 003787 ** database connection. This command creates a new command named 003788 ** DBNAME that is used to control that connection. The database 003789 ** connection is deleted when the DBNAME command is deleted. 003790 ** 003791 ** The second argument is the name of the database file. 003792 ** 003793 */ 003794 static int SQLITE_TCLAPI DbMain( 003795 void *cd, 003796 Tcl_Interp *interp, 003797 int objc, 003798 Tcl_Obj *const*objv 003799 ){ 003800 SqliteDb *p; 003801 const char *zArg; 003802 char *zErrMsg; 003803 int i; 003804 const char *zFile = 0; 003805 const char *zVfs = 0; 003806 int flags; 003807 int bTranslateFileName = 1; 003808 Tcl_DString translatedFilename; 003809 int rc; 003810 003811 /* In normal use, each TCL interpreter runs in a single thread. So 003812 ** by default, we can turn off mutexing on SQLite database connections. 003813 ** However, for testing purposes it is useful to have mutexes turned 003814 ** on. So, by default, mutexes default off. But if compiled with 003815 ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. 003816 */ 003817 #ifdef SQLITE_TCL_DEFAULT_FULLMUTEX 003818 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX; 003819 #else 003820 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; 003821 #endif 003822 003823 if( objc==1 ) return sqliteCmdUsage(interp, objv); 003824 if( objc==2 ){ 003825 zArg = Tcl_GetStringFromObj(objv[1], 0); 003826 if( strcmp(zArg,"-version")==0 ){ 003827 Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0); 003828 return TCL_OK; 003829 } 003830 if( strcmp(zArg,"-sourceid")==0 ){ 003831 Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0); 003832 return TCL_OK; 003833 } 003834 if( strcmp(zArg,"-has-codec")==0 ){ 003835 Tcl_AppendResult(interp,"0",(char*)0); 003836 return TCL_OK; 003837 } 003838 if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv); 003839 } 003840 for(i=2; i<objc; i++){ 003841 zArg = Tcl_GetString(objv[i]); 003842 if( zArg[0]!='-' ){ 003843 if( zFile!=0 ) return sqliteCmdUsage(interp, objv); 003844 zFile = zArg; 003845 continue; 003846 } 003847 if( i==objc-1 ) return sqliteCmdUsage(interp, objv); 003848 i++; 003849 if( strcmp(zArg,"-key")==0 ){ 003850 /* no-op */ 003851 }else if( strcmp(zArg, "-vfs")==0 ){ 003852 zVfs = Tcl_GetString(objv[i]); 003853 }else if( strcmp(zArg, "-readonly")==0 ){ 003854 int b; 003855 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003856 if( b ){ 003857 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); 003858 flags |= SQLITE_OPEN_READONLY; 003859 }else{ 003860 flags &= ~SQLITE_OPEN_READONLY; 003861 flags |= SQLITE_OPEN_READWRITE; 003862 } 003863 }else if( strcmp(zArg, "-create")==0 ){ 003864 int b; 003865 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003866 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){ 003867 flags |= SQLITE_OPEN_CREATE; 003868 }else{ 003869 flags &= ~SQLITE_OPEN_CREATE; 003870 } 003871 }else if( strcmp(zArg, "-nofollow")==0 ){ 003872 int b; 003873 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003874 if( b ){ 003875 flags |= SQLITE_OPEN_NOFOLLOW; 003876 }else{ 003877 flags &= ~SQLITE_OPEN_NOFOLLOW; 003878 } 003879 }else if( strcmp(zArg, "-nomutex")==0 ){ 003880 int b; 003881 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003882 if( b ){ 003883 flags |= SQLITE_OPEN_NOMUTEX; 003884 flags &= ~SQLITE_OPEN_FULLMUTEX; 003885 }else{ 003886 flags &= ~SQLITE_OPEN_NOMUTEX; 003887 } 003888 }else if( strcmp(zArg, "-fullmutex")==0 ){ 003889 int b; 003890 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003891 if( b ){ 003892 flags |= SQLITE_OPEN_FULLMUTEX; 003893 flags &= ~SQLITE_OPEN_NOMUTEX; 003894 }else{ 003895 flags &= ~SQLITE_OPEN_FULLMUTEX; 003896 } 003897 }else if( strcmp(zArg, "-uri")==0 ){ 003898 int b; 003899 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003900 if( b ){ 003901 flags |= SQLITE_OPEN_URI; 003902 }else{ 003903 flags &= ~SQLITE_OPEN_URI; 003904 } 003905 }else if( strcmp(zArg, "-translatefilename")==0 ){ 003906 if( Tcl_GetBooleanFromObj(interp, objv[i], &bTranslateFileName) ){ 003907 return TCL_ERROR; 003908 } 003909 }else{ 003910 Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); 003911 return TCL_ERROR; 003912 } 003913 } 003914 zErrMsg = 0; 003915 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); 003916 memset(p, 0, sizeof(*p)); 003917 if( zFile==0 ) zFile = ""; 003918 if( bTranslateFileName ){ 003919 zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); 003920 } 003921 rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); 003922 if( bTranslateFileName ){ 003923 Tcl_DStringFree(&translatedFilename); 003924 } 003925 if( p->db ){ 003926 if( SQLITE_OK!=sqlite3_errcode(p->db) ){ 003927 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); 003928 sqlite3_close(p->db); 003929 p->db = 0; 003930 } 003931 }else{ 003932 zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc)); 003933 } 003934 if( p->db==0 ){ 003935 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); 003936 Tcl_Free((char*)p); 003937 sqlite3_free(zErrMsg); 003938 return TCL_ERROR; 003939 } 003940 p->maxStmt = NUM_PREPARED_STMTS; 003941 p->openFlags = flags & SQLITE_OPEN_URI; 003942 p->interp = interp; 003943 zArg = Tcl_GetStringFromObj(objv[1], 0); 003944 if( DbUseNre() ){ 003945 Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd, 003946 (char*)p, DbDeleteCmd); 003947 }else{ 003948 Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd); 003949 } 003950 p->nRef = 1; 003951 return TCL_OK; 003952 } 003953 003954 /* 003955 ** Provide a dummy Tcl_InitStubs if we are using this as a static 003956 ** library. 003957 */ 003958 #ifndef USE_TCL_STUBS 003959 # undef Tcl_InitStubs 003960 # define Tcl_InitStubs(a,b,c) TCL_VERSION 003961 #endif 003962 003963 /* 003964 ** Make sure we have a PACKAGE_VERSION macro defined. This will be 003965 ** defined automatically by the TEA makefile. But other makefiles 003966 ** do not define it. 003967 */ 003968 #ifndef PACKAGE_VERSION 003969 # define PACKAGE_VERSION SQLITE_VERSION 003970 #endif 003971 003972 /* 003973 ** Initialize this module. 003974 ** 003975 ** This Tcl module contains only a single new Tcl command named "sqlite". 003976 ** (Hence there is no namespace. There is no point in using a namespace 003977 ** if the extension only supplies one new name!) The "sqlite" command is 003978 ** used to open a new SQLite database. See the DbMain() routine above 003979 ** for additional information. 003980 ** 003981 ** The EXTERN macros are required by TCL in order to work on windows. 003982 */ 003983 EXTERN int Sqlite3_Init(Tcl_Interp *interp){ 003984 int rc = Tcl_InitStubs(interp, "8.5-", 0) ? TCL_OK : TCL_ERROR; 003985 if( rc==TCL_OK ){ 003986 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); 003987 #ifndef SQLITE_3_SUFFIX_ONLY 003988 /* The "sqlite" alias is undocumented. It is here only to support 003989 ** legacy scripts. All new scripts should use only the "sqlite3" 003990 ** command. */ 003991 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); 003992 #endif 003993 rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); 003994 } 003995 return rc; 003996 } 003997 EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } 003998 EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 003999 EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 004000 004001 /* Because it accesses the file-system and uses persistent state, SQLite 004002 ** is not considered appropriate for safe interpreters. Hence, we cause 004003 ** the _SafeInit() interfaces return TCL_ERROR. 004004 */ 004005 EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } 004006 EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} 004007 004008 /* 004009 ** Versions of all of the above entry points that omit the "3" at the end 004010 ** of the name. Years ago (circa 2004) the "3" was necessary to distinguish 004011 ** SQLite version 3 from Sqlite version 2. But two decades have elapsed. 004012 ** SQLite2 is not longer a conflict. So it is ok to omit the "3". 004013 ** 004014 ** Omitting the "3" helps TCL find the entry point. 004015 */ 004016 EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} 004017 EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } 004018 EXTERN int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 004019 EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 004020 EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } 004021 EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} 004022 004023 /* Also variants with a lowercase "s" */ 004024 EXTERN int sqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} 004025 EXTERN int sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} 004026 004027 004028 /* 004029 ** If the TCLSH macro is defined, add code to make a stand-alone program. 004030 */ 004031 #if defined(TCLSH) 004032 004033 /* This is the main routine for an ordinary TCL shell. If there are 004034 ** are arguments, run the first argument as a script. Otherwise, 004035 ** read TCL commands from standard input 004036 */ 004037 static const char *tclsh_main_loop(void){ 004038 static const char zMainloop[] = 004039 "if {[llength $argv]>=1} {\n" 004040 #ifdef WIN32 004041 "set new [list]\n" 004042 "foreach arg $argv {\n" 004043 "if {[string match -* $arg] || [file exists $arg]} {\n" 004044 "lappend new $arg\n" 004045 "} else {\n" 004046 "set once 0\n" 004047 "foreach match [lsort [glob -nocomplain $arg]] {\n" 004048 "lappend new $match\n" 004049 "set once 1\n" 004050 "}\n" 004051 "if {!$once} {lappend new $arg}\n" 004052 "}\n" 004053 "}\n" 004054 "set argv $new\n" 004055 "unset new\n" 004056 #endif 004057 "set argv0 [lindex $argv 0]\n" 004058 "set argv [lrange $argv 1 end]\n" 004059 "source $argv0\n" 004060 "} else {\n" 004061 "set line {}\n" 004062 "while {![eof stdin]} {\n" 004063 "if {$line!=\"\"} {\n" 004064 "puts -nonewline \"> \"\n" 004065 "} else {\n" 004066 "puts -nonewline \"% \"\n" 004067 "}\n" 004068 "flush stdout\n" 004069 "append line [gets stdin]\n" 004070 "if {[info complete $line]} {\n" 004071 "if {[catch {uplevel #0 $line} result]} {\n" 004072 "puts stderr \"Error: $result\"\n" 004073 "} elseif {$result!=\"\"} {\n" 004074 "puts $result\n" 004075 "}\n" 004076 "set line {}\n" 004077 "} else {\n" 004078 "append line \\n\n" 004079 "}\n" 004080 "}\n" 004081 "}\n" 004082 ; 004083 return zMainloop; 004084 } 004085 004086 #ifndef TCLSH_MAIN 004087 # define TCLSH_MAIN main 004088 #endif 004089 int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){ 004090 Tcl_Interp *interp; 004091 int i; 004092 const char *zScript = 0; 004093 char zArgc[32]; 004094 #if defined(TCLSH_INIT_PROC) 004095 extern const char *TCLSH_INIT_PROC(Tcl_Interp*); 004096 #endif 004097 004098 #if !defined(_WIN32_WCE) 004099 if( getenv("SQLITE_DEBUG_BREAK") ){ 004100 if( isatty(0) && isatty(2) ){ 004101 fprintf(stderr, 004102 "attach debugger to process %d and press any key to continue.\n", 004103 GETPID()); 004104 fgetc(stdin); 004105 }else{ 004106 #if defined(_WIN32) || defined(WIN32) 004107 DebugBreak(); 004108 #elif defined(SIGTRAP) 004109 raise(SIGTRAP); 004110 #endif 004111 } 004112 } 004113 #endif 004114 004115 /* Call sqlite3_shutdown() once before doing anything else. This is to 004116 ** test that sqlite3_shutdown() can be safely called by a process before 004117 ** sqlite3_initialize() is. */ 004118 sqlite3_shutdown(); 004119 004120 Tcl_FindExecutable(argv[0]); 004121 Tcl_SetSystemEncoding(NULL, "utf-8"); 004122 interp = Tcl_CreateInterp(); 004123 Sqlite3_Init(interp); 004124 004125 sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1); 004126 Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); 004127 Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY); 004128 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); 004129 for(i=1; i<argc; i++){ 004130 Tcl_SetVar(interp, "argv", argv[i], 004131 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); 004132 } 004133 #if defined(TCLSH_INIT_PROC) 004134 zScript = TCLSH_INIT_PROC(interp); 004135 #endif 004136 if( zScript==0 ){ 004137 zScript = tclsh_main_loop(); 004138 } 004139 if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){ 004140 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); 004141 if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp); 004142 fprintf(stderr,"%s: %s\n", *argv, zInfo); 004143 return 1; 004144 } 004145 return 0; 004146 } 004147 #endif /* TCLSH */