blob: d0b4634d45eb9de48ab722f2e8caf8498eb481b9 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
drhbd08af42007-04-05 21:58:33 +000012** A TCL Interface to SQLite. Append this file to sqlite3.c and
13** compile the whole thing to build a TCL-enabled version of SQLite.
drh57a02272009-10-22 20:52:05 +000014**
15** Compile-time options:
16**
drh96a206f2017-10-13 20:14:06 +000017** -DTCLSH Add a "main()" routine that works as a tclsh.
drh57a02272009-10-22 20:52:05 +000018**
drh96a206f2017-10-13 20:14:06 +000019** -DTCLSH_INIT_PROC=name
drh57a02272009-10-22 20:52:05 +000020**
drh96a206f2017-10-13 20:14:06 +000021** Invoke name(interp) to initialize the Tcl interpreter.
22** If name(interp) returns a non-NULL string, then run
23** that string as a Tcl script to launch the application.
24** If name(interp) returns NULL, then run the regular
25** tclsh-emulator code.
drh75897232000-05-29 14:26:00 +000026*/
drh96a206f2017-10-13 20:14:06 +000027#ifdef TCLSH_INIT_PROC
28# define TCLSH 1
29#endif
mistachkin27b2f052015-01-12 19:49:46 +000030
31/*
32** If requested, include the SQLite compiler options file for MSVC.
33*/
34#if defined(INCLUDE_MSVC_H)
mistachkin52b1dbb2016-07-28 14:37:04 +000035# include "msvc.h"
mistachkin27b2f052015-01-12 19:49:46 +000036#endif
37
mistachkin52b1dbb2016-07-28 14:37:04 +000038#if defined(INCLUDE_SQLITE_TCL_H)
39# include "sqlite_tcl.h"
40#else
41# include "tcl.h"
mistachkin7617e4a2016-07-28 17:11:20 +000042# ifndef SQLITE_TCLAPI
43# define SQLITE_TCLAPI
44# endif
mistachkin52b1dbb2016-07-28 14:37:04 +000045#endif
danielk1977b4e9af92007-05-01 17:49:49 +000046#include <errno.h>
drhbd08af42007-04-05 21:58:33 +000047
48/*
49** Some additional include files are needed if this file is not
50** appended to the amalgamation.
51*/
52#ifndef SQLITE_AMALGAMATION
drh65e8c822009-12-01 13:57:48 +000053# include "sqlite3.h"
drhbd08af42007-04-05 21:58:33 +000054# include <stdlib.h>
55# include <string.h>
56# include <assert.h>
drh65e8c822009-12-01 13:57:48 +000057 typedef unsigned char u8;
drhbd08af42007-04-05 21:58:33 +000058#endif
drheb206382009-10-24 15:51:33 +000059#include <ctype.h>
drh75897232000-05-29 14:26:00 +000060
mistachkin1f28e072013-08-15 08:06:15 +000061/* Used to get the current process ID */
62#if !defined(_WIN32)
mistachkin1e8487d2018-07-22 06:25:35 +000063# include <signal.h>
mistachkin1f28e072013-08-15 08:06:15 +000064# include <unistd.h>
65# define GETPID getpid
66#elif !defined(_WIN32_WCE)
67# ifndef SQLITE_AMALGAMATION
mistachkin176b3a02018-01-23 07:11:05 +000068# ifndef WIN32_LEAN_AND_MEAN
69# define WIN32_LEAN_AND_MEAN
70# endif
mistachkin1f28e072013-08-15 08:06:15 +000071# include <windows.h>
72# endif
mistachkin1e8487d2018-07-22 06:25:35 +000073# include <io.h>
74# define isatty(h) _isatty(h)
mistachkin1f28e072013-08-15 08:06:15 +000075# define GETPID (int)GetCurrentProcessId
76#endif
77
drhad6e1372006-07-10 21:15:51 +000078/*
79 * Windows needs to know which symbols to export. Unix does not.
80 * BUILD_sqlite should be undefined for Unix.
81 */
82#ifdef BUILD_sqlite
83#undef TCL_STORAGE_CLASS
84#define TCL_STORAGE_CLASS DLLEXPORT
85#endif /* BUILD_sqlite */
drh29bc4612005-10-05 10:40:15 +000086
danielk1977a21c6b62005-01-24 10:25:59 +000087#define NUM_PREPARED_STMTS 10
drhfb7e7652005-01-24 00:28:42 +000088#define MAX_PREPARED_STMTS 100
89
drhc45e6712012-10-03 11:02:33 +000090/* Forward declaration */
91typedef struct SqliteDb SqliteDb;
drh98808ba2001-10-18 12:34:46 +000092
93/*
drhcabb0812002-09-14 13:47:32 +000094** New SQL functions can be created as TCL scripts. Each such function
95** is described by an instance of the following structure.
96*/
97typedef struct SqlFunc SqlFunc;
98struct SqlFunc {
99 Tcl_Interp *interp; /* The TCL interpret to execute the function */
drhd1e47332005-06-26 17:55:33 +0000100 Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
drhc45e6712012-10-03 11:02:33 +0000101 SqliteDb *pDb; /* Database connection that owns this function */
drhd1e47332005-06-26 17:55:33 +0000102 int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
103 char *zName; /* Name of this function */
drhcabb0812002-09-14 13:47:32 +0000104 SqlFunc *pNext; /* Next function on the list of them all */
105};
106
107/*
danielk19770202b292004-06-09 09:55:16 +0000108** New collation sequences function can be created as TCL scripts. Each such
109** function is described by an instance of the following structure.
110*/
111typedef struct SqlCollate SqlCollate;
112struct SqlCollate {
113 Tcl_Interp *interp; /* The TCL interpret to execute the function */
114 char *zScript; /* The script to be run */
drhd1e47332005-06-26 17:55:33 +0000115 SqlCollate *pNext; /* Next function on the list of them all */
danielk19770202b292004-06-09 09:55:16 +0000116};
117
118/*
drhfb7e7652005-01-24 00:28:42 +0000119** Prepared statements are cached for faster execution. Each prepared
120** statement is described by an instance of the following structure.
121*/
122typedef struct SqlPreparedStmt SqlPreparedStmt;
123struct SqlPreparedStmt {
124 SqlPreparedStmt *pNext; /* Next in linked list */
125 SqlPreparedStmt *pPrev; /* Previous on the list */
126 sqlite3_stmt *pStmt; /* The prepared statement */
127 int nSql; /* chars in zSql[] */
danielk1977d0e2a852007-11-14 06:48:48 +0000128 const char *zSql; /* Text of the SQL statement */
dan4a4c11a2009-10-06 14:59:02 +0000129 int nParm; /* Size of apParm array */
130 Tcl_Obj **apParm; /* Array of referenced object pointers */
drhfb7e7652005-01-24 00:28:42 +0000131};
132
danielk1977d04417962007-05-02 13:16:30 +0000133typedef struct IncrblobChannel IncrblobChannel;
134
drhfb7e7652005-01-24 00:28:42 +0000135/*
drhbec3f402000-08-04 13:49:02 +0000136** There is one instance of this structure for each SQLite database
137** that has been opened by the SQLite TCL interface.
danc431fd52011-06-27 16:55:50 +0000138**
139** If this module is built with SQLITE_TEST defined (to create the SQLite
140** testfixture executable), then it may be configured to use either
141** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
142** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
drhbec3f402000-08-04 13:49:02 +0000143*/
drhbec3f402000-08-04 13:49:02 +0000144struct SqliteDb {
drhdddca282006-01-03 00:33:50 +0000145 sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
drhd1e47332005-06-26 17:55:33 +0000146 Tcl_Interp *interp; /* The interpreter used for this database */
147 char *zBusy; /* The busy callback routine */
148 char *zCommit; /* The commit hook callback routine */
149 char *zTrace; /* The trace callback routine */
mistachkinb56660f2016-07-14 21:26:09 +0000150 char *zTraceV2; /* The trace_v2 callback routine */
drh19e2d372005-08-29 23:00:03 +0000151 char *zProfile; /* The profile callback routine */
drhd1e47332005-06-26 17:55:33 +0000152 char *zProgress; /* The progress callback routine */
153 char *zAuth; /* The authorization callback routine */
drh1f1549f2008-08-26 21:33:34 +0000154 int disableAuth; /* Disable the authorizer if it exists */
drhd1e47332005-06-26 17:55:33 +0000155 char *zNull; /* Text to substitute for an SQL NULL value */
156 SqlFunc *pFunc; /* List of SQL functions */
danielk197794eb6a12005-12-15 15:22:08 +0000157 Tcl_Obj *pUpdateHook; /* Update hook script (if any) */
dan46c47d42011-03-01 18:42:07 +0000158 Tcl_Obj *pPreUpdateHook; /* Pre-update hook script (if any) */
danielk197771fd80b2005-12-16 06:54:01 +0000159 Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */
drh5def0842010-05-05 20:00:25 +0000160 Tcl_Obj *pWalHook; /* WAL hook script (if any) */
danielk1977404ca072009-03-16 13:19:36 +0000161 Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */
drhd1e47332005-06-26 17:55:33 +0000162 SqlCollate *pCollate; /* List of SQL collation functions */
163 int rc; /* Return code of most recent sqlite3_exec() */
164 Tcl_Obj *pCollateNeeded; /* Collation needed script */
drhfb7e7652005-01-24 00:28:42 +0000165 SqlPreparedStmt *stmtList; /* List of prepared statements*/
166 SqlPreparedStmt *stmtLast; /* Last statement in the list */
167 int maxStmt; /* The next maximum number of stmtList */
168 int nStmt; /* Number of statements in stmtList */
danielk1977d04417962007-05-02 13:16:30 +0000169 IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
drh3c379b02010-04-07 19:31:59 +0000170 int nStep, nSort, nIndex; /* Statistics for most recent operation */
danc456a762017-06-22 16:51:16 +0000171 int nVMStep; /* Another statistic for most recent operation */
danielk1977cd38d522009-01-02 17:33:46 +0000172 int nTransaction; /* Number of nested [transaction] methods */
drh147ef392016-01-22 23:17:51 +0000173 int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */
danc431fd52011-06-27 16:55:50 +0000174#ifdef SQLITE_TEST
175 int bLegacyPrepare; /* True to use sqlite3_prepare() */
176#endif
drh98808ba2001-10-18 12:34:46 +0000177};
drh297ecf12001-04-05 15:57:13 +0000178
danielk1977b4e9af92007-05-01 17:49:49 +0000179struct IncrblobChannel {
danielk1977d04417962007-05-02 13:16:30 +0000180 sqlite3_blob *pBlob; /* sqlite3 blob handle */
danielk1977dcbb5d32007-05-04 18:36:44 +0000181 SqliteDb *pDb; /* Associated database connection */
danielk1977d04417962007-05-02 13:16:30 +0000182 int iSeek; /* Current seek offset */
danielk1977d04417962007-05-02 13:16:30 +0000183 Tcl_Channel channel; /* Channel identifier */
184 IncrblobChannel *pNext; /* Linked list of all open incrblob channels */
185 IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */
danielk1977b4e9af92007-05-01 17:49:49 +0000186};
187
drhea678832008-12-10 19:26:22 +0000188/*
189** Compute a string length that is limited to what can be stored in
190** lower 30 bits of a 32-bit signed integer.
191*/
drh4f21c4a2008-12-10 22:15:00 +0000192static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000193 const char *z2 = z;
194 while( *z2 ){ z2++; }
195 return 0x3fffffff & (int)(z2 - z);
196}
drhea678832008-12-10 19:26:22 +0000197
198
danielk197732a0d8b2007-05-04 19:03:02 +0000199#ifndef SQLITE_OMIT_INCRBLOB
danielk1977b4e9af92007-05-01 17:49:49 +0000200/*
danielk1977d04417962007-05-02 13:16:30 +0000201** Close all incrblob channels opened using database connection pDb.
202** This is called when shutting down the database connection.
203*/
204static void closeIncrblobChannels(SqliteDb *pDb){
205 IncrblobChannel *p;
206 IncrblobChannel *pNext;
207
208 for(p=pDb->pIncrblob; p; p=pNext){
209 pNext = p->pNext;
210
mistachkinb56660f2016-07-14 21:26:09 +0000211 /* Note: Calling unregister here call Tcl_Close on the incrblob channel,
danielk1977d04417962007-05-02 13:16:30 +0000212 ** which deletes the IncrblobChannel structure at *p. So do not
213 ** call Tcl_Free() here.
214 */
215 Tcl_UnregisterChannel(pDb->interp, p->channel);
216 }
217}
218
219/*
danielk1977b4e9af92007-05-01 17:49:49 +0000220** Close an incremental blob channel.
221*/
mistachkin7617e4a2016-07-28 17:11:20 +0000222static int SQLITE_TCLAPI incrblobClose(
223 ClientData instanceData,
224 Tcl_Interp *interp
225){
danielk1977b4e9af92007-05-01 17:49:49 +0000226 IncrblobChannel *p = (IncrblobChannel *)instanceData;
danielk197792d4d7a2007-05-04 12:05:56 +0000227 int rc = sqlite3_blob_close(p->pBlob);
228 sqlite3 *db = p->pDb->db;
danielk1977d04417962007-05-02 13:16:30 +0000229
230 /* Remove the channel from the SqliteDb.pIncrblob list. */
231 if( p->pNext ){
232 p->pNext->pPrev = p->pPrev;
233 }
234 if( p->pPrev ){
235 p->pPrev->pNext = p->pNext;
236 }
237 if( p->pDb->pIncrblob==p ){
238 p->pDb->pIncrblob = p->pNext;
239 }
240
danielk197792d4d7a2007-05-04 12:05:56 +0000241 /* Free the IncrblobChannel structure */
danielk1977b4e9af92007-05-01 17:49:49 +0000242 Tcl_Free((char *)p);
danielk197792d4d7a2007-05-04 12:05:56 +0000243
244 if( rc!=SQLITE_OK ){
245 Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
246 return TCL_ERROR;
247 }
danielk1977b4e9af92007-05-01 17:49:49 +0000248 return TCL_OK;
249}
250
251/*
252** Read data from an incremental blob channel.
253*/
mistachkin7617e4a2016-07-28 17:11:20 +0000254static int SQLITE_TCLAPI incrblobInput(
mistachkinb56660f2016-07-14 21:26:09 +0000255 ClientData instanceData,
256 char *buf,
danielk1977b4e9af92007-05-01 17:49:49 +0000257 int bufSize,
258 int *errorCodePtr
259){
260 IncrblobChannel *p = (IncrblobChannel *)instanceData;
261 int nRead = bufSize; /* Number of bytes to read */
262 int nBlob; /* Total size of the blob */
263 int rc; /* sqlite error code */
264
265 nBlob = sqlite3_blob_bytes(p->pBlob);
266 if( (p->iSeek+nRead)>nBlob ){
267 nRead = nBlob-p->iSeek;
268 }
269 if( nRead<=0 ){
270 return 0;
271 }
272
273 rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek);
274 if( rc!=SQLITE_OK ){
275 *errorCodePtr = rc;
276 return -1;
277 }
278
279 p->iSeek += nRead;
280 return nRead;
281}
282
danielk1977d04417962007-05-02 13:16:30 +0000283/*
284** Write data to an incremental blob channel.
285*/
mistachkin7617e4a2016-07-28 17:11:20 +0000286static int SQLITE_TCLAPI incrblobOutput(
mistachkinb56660f2016-07-14 21:26:09 +0000287 ClientData instanceData,
288 CONST char *buf,
danielk1977b4e9af92007-05-01 17:49:49 +0000289 int toWrite,
290 int *errorCodePtr
291){
292 IncrblobChannel *p = (IncrblobChannel *)instanceData;
293 int nWrite = toWrite; /* Number of bytes to write */
294 int nBlob; /* Total size of the blob */
295 int rc; /* sqlite error code */
296
297 nBlob = sqlite3_blob_bytes(p->pBlob);
298 if( (p->iSeek+nWrite)>nBlob ){
299 *errorCodePtr = EINVAL;
300 return -1;
301 }
302 if( nWrite<=0 ){
303 return 0;
304 }
305
306 rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek);
307 if( rc!=SQLITE_OK ){
308 *errorCodePtr = EIO;
309 return -1;
310 }
311
312 p->iSeek += nWrite;
313 return nWrite;
314}
315
316/*
317** Seek an incremental blob channel.
318*/
mistachkin7617e4a2016-07-28 17:11:20 +0000319static int SQLITE_TCLAPI incrblobSeek(
mistachkinb56660f2016-07-14 21:26:09 +0000320 ClientData instanceData,
danielk1977b4e9af92007-05-01 17:49:49 +0000321 long offset,
322 int seekMode,
323 int *errorCodePtr
324){
325 IncrblobChannel *p = (IncrblobChannel *)instanceData;
326
327 switch( seekMode ){
328 case SEEK_SET:
329 p->iSeek = offset;
330 break;
331 case SEEK_CUR:
332 p->iSeek += offset;
333 break;
334 case SEEK_END:
335 p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset;
336 break;
337
338 default: assert(!"Bad seekMode");
339 }
340
341 return p->iSeek;
342}
343
344
mistachkin7617e4a2016-07-28 17:11:20 +0000345static void SQLITE_TCLAPI incrblobWatch(
346 ClientData instanceData,
347 int mode
348){
mistachkinb56660f2016-07-14 21:26:09 +0000349 /* NO-OP */
danielk1977b4e9af92007-05-01 17:49:49 +0000350}
mistachkin7617e4a2016-07-28 17:11:20 +0000351static int SQLITE_TCLAPI incrblobHandle(
352 ClientData instanceData,
353 int dir,
354 ClientData *hPtr
355){
danielk1977b4e9af92007-05-01 17:49:49 +0000356 return TCL_ERROR;
357}
358
359static Tcl_ChannelType IncrblobChannelType = {
360 "incrblob", /* typeName */
361 TCL_CHANNEL_VERSION_2, /* version */
362 incrblobClose, /* closeProc */
363 incrblobInput, /* inputProc */
364 incrblobOutput, /* outputProc */
365 incrblobSeek, /* seekProc */
366 0, /* setOptionProc */
367 0, /* getOptionProc */
368 incrblobWatch, /* watchProc (this is a no-op) */
369 incrblobHandle, /* getHandleProc (always returns error) */
370 0, /* close2Proc */
371 0, /* blockModeProc */
372 0, /* flushProc */
373 0, /* handlerProc */
374 0, /* wideSeekProc */
danielk1977b4e9af92007-05-01 17:49:49 +0000375};
376
377/*
378** Create a new incrblob channel.
379*/
380static int createIncrblobChannel(
mistachkinb56660f2016-07-14 21:26:09 +0000381 Tcl_Interp *interp,
382 SqliteDb *pDb,
danielk1977b4e9af92007-05-01 17:49:49 +0000383 const char *zDb,
mistachkinb56660f2016-07-14 21:26:09 +0000384 const char *zTable,
385 const char *zColumn,
danielk19778cbadb02007-05-03 16:31:26 +0000386 sqlite_int64 iRow,
387 int isReadonly
danielk1977b4e9af92007-05-01 17:49:49 +0000388){
389 IncrblobChannel *p;
danielk19778cbadb02007-05-03 16:31:26 +0000390 sqlite3 *db = pDb->db;
danielk1977b4e9af92007-05-01 17:49:49 +0000391 sqlite3_blob *pBlob;
392 int rc;
danielk19778cbadb02007-05-03 16:31:26 +0000393 int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE);
danielk1977b4e9af92007-05-01 17:49:49 +0000394
395 /* This variable is used to name the channels: "incrblob_[incr count]" */
396 static int count = 0;
397 char zChannel[64];
398
danielk19778cbadb02007-05-03 16:31:26 +0000399 rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob);
danielk1977b4e9af92007-05-01 17:49:49 +0000400 if( rc!=SQLITE_OK ){
401 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
402 return TCL_ERROR;
403 }
404
405 p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel));
406 p->iSeek = 0;
407 p->pBlob = pBlob;
408
drh5bb3eb92007-05-04 13:15:55 +0000409 sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count);
danielk1977d04417962007-05-02 13:16:30 +0000410 p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags);
411 Tcl_RegisterChannel(interp, p->channel);
danielk1977b4e9af92007-05-01 17:49:49 +0000412
danielk1977d04417962007-05-02 13:16:30 +0000413 /* Link the new channel into the SqliteDb.pIncrblob list. */
414 p->pNext = pDb->pIncrblob;
415 p->pPrev = 0;
416 if( p->pNext ){
417 p->pNext->pPrev = p;
418 }
419 pDb->pIncrblob = p;
420 p->pDb = pDb;
421
422 Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE);
danielk1977b4e9af92007-05-01 17:49:49 +0000423 return TCL_OK;
424}
danielk197732a0d8b2007-05-04 19:03:02 +0000425#else /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */
426 #define closeIncrblobChannels(pDb)
427#endif
danielk1977b4e9af92007-05-01 17:49:49 +0000428
drh6d313162000-09-21 13:01:35 +0000429/*
drhd1e47332005-06-26 17:55:33 +0000430** Look at the script prefix in pCmd. We will be executing this script
431** after first appending one or more arguments. This routine analyzes
432** the script to see if it is safe to use Tcl_EvalObjv() on the script
433** rather than the more general Tcl_EvalEx(). Tcl_EvalObjv() is much
434** faster.
435**
436** Scripts that are safe to use with Tcl_EvalObjv() consists of a
437** command name followed by zero or more arguments with no [...] or $
438** or {...} or ; to be seen anywhere. Most callback scripts consist
439** of just a single procedure name and they meet this requirement.
440*/
441static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
442 /* We could try to do something with Tcl_Parse(). But we will instead
443 ** just do a search for forbidden characters. If any of the forbidden
444 ** characters appear in pCmd, we will report the string as unsafe.
445 */
446 const char *z;
447 int n;
448 z = Tcl_GetStringFromObj(pCmd, &n);
449 while( n-- > 0 ){
450 int c = *(z++);
451 if( c=='$' || c=='[' || c==';' ) return 0;
452 }
453 return 1;
454}
455
456/*
457** Find an SqlFunc structure with the given name. Or create a new
458** one if an existing one cannot be found. Return a pointer to the
459** structure.
460*/
461static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
462 SqlFunc *p, *pNew;
drh0425f182013-11-26 16:48:04 +0000463 int nName = strlen30(zName);
464 pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 );
drhd1e47332005-06-26 17:55:33 +0000465 pNew->zName = (char*)&pNew[1];
drh0425f182013-11-26 16:48:04 +0000466 memcpy(pNew->zName, zName, nName+1);
mistachkinb56660f2016-07-14 21:26:09 +0000467 for(p=pDb->pFunc; p; p=p->pNext){
drh0425f182013-11-26 16:48:04 +0000468 if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){
drhd1e47332005-06-26 17:55:33 +0000469 Tcl_Free((char*)pNew);
470 return p;
471 }
472 }
473 pNew->interp = pDb->interp;
drhc45e6712012-10-03 11:02:33 +0000474 pNew->pDb = pDb;
drhd1e47332005-06-26 17:55:33 +0000475 pNew->pScript = 0;
476 pNew->pNext = pDb->pFunc;
477 pDb->pFunc = pNew;
478 return pNew;
479}
480
481/*
danc431fd52011-06-27 16:55:50 +0000482** Free a single SqlPreparedStmt object.
483*/
484static void dbFreeStmt(SqlPreparedStmt *pStmt){
485#ifdef SQLITE_TEST
486 if( sqlite3_sql(pStmt->pStmt)==0 ){
487 Tcl_Free((char *)pStmt->zSql);
488 }
489#endif
490 sqlite3_finalize(pStmt->pStmt);
491 Tcl_Free((char *)pStmt);
492}
493
494/*
drhfb7e7652005-01-24 00:28:42 +0000495** Finalize and free a list of prepared statements
496*/
danc431fd52011-06-27 16:55:50 +0000497static void flushStmtCache(SqliteDb *pDb){
drhfb7e7652005-01-24 00:28:42 +0000498 SqlPreparedStmt *pPreStmt;
danc431fd52011-06-27 16:55:50 +0000499 SqlPreparedStmt *pNext;
drhfb7e7652005-01-24 00:28:42 +0000500
danc431fd52011-06-27 16:55:50 +0000501 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
502 pNext = pPreStmt->pNext;
503 dbFreeStmt(pPreStmt);
drhfb7e7652005-01-24 00:28:42 +0000504 }
505 pDb->nStmt = 0;
506 pDb->stmtLast = 0;
danc431fd52011-06-27 16:55:50 +0000507 pDb->stmtList = 0;
drhfb7e7652005-01-24 00:28:42 +0000508}
509
510/*
drh895d7472004-08-20 16:02:39 +0000511** TCL calls this procedure when an sqlite3 database command is
512** deleted.
drh75897232000-05-29 14:26:00 +0000513*/
mistachkin7617e4a2016-07-28 17:11:20 +0000514static void SQLITE_TCLAPI DbDeleteCmd(void *db){
drhbec3f402000-08-04 13:49:02 +0000515 SqliteDb *pDb = (SqliteDb*)db;
drhfb7e7652005-01-24 00:28:42 +0000516 flushStmtCache(pDb);
danielk1977d04417962007-05-02 13:16:30 +0000517 closeIncrblobChannels(pDb);
danielk19776f8a5032004-05-10 10:34:51 +0000518 sqlite3_close(pDb->db);
drhcabb0812002-09-14 13:47:32 +0000519 while( pDb->pFunc ){
520 SqlFunc *pFunc = pDb->pFunc;
521 pDb->pFunc = pFunc->pNext;
drhc45e6712012-10-03 11:02:33 +0000522 assert( pFunc->pDb==pDb );
drhd1e47332005-06-26 17:55:33 +0000523 Tcl_DecrRefCount(pFunc->pScript);
drhcabb0812002-09-14 13:47:32 +0000524 Tcl_Free((char*)pFunc);
525 }
danielk19770202b292004-06-09 09:55:16 +0000526 while( pDb->pCollate ){
527 SqlCollate *pCollate = pDb->pCollate;
528 pDb->pCollate = pCollate->pNext;
529 Tcl_Free((char*)pCollate);
530 }
drhbec3f402000-08-04 13:49:02 +0000531 if( pDb->zBusy ){
532 Tcl_Free(pDb->zBusy);
533 }
drhb5a20d32003-04-23 12:25:23 +0000534 if( pDb->zTrace ){
535 Tcl_Free(pDb->zTrace);
drh0d1a6432003-04-03 15:46:04 +0000536 }
mistachkinb56660f2016-07-14 21:26:09 +0000537 if( pDb->zTraceV2 ){
538 Tcl_Free(pDb->zTraceV2);
539 }
drh19e2d372005-08-29 23:00:03 +0000540 if( pDb->zProfile ){
541 Tcl_Free(pDb->zProfile);
542 }
drhe22a3342003-04-22 20:30:37 +0000543 if( pDb->zAuth ){
544 Tcl_Free(pDb->zAuth);
545 }
danielk197755c45f22005-04-03 23:54:43 +0000546 if( pDb->zNull ){
547 Tcl_Free(pDb->zNull);
548 }
danielk197794eb6a12005-12-15 15:22:08 +0000549 if( pDb->pUpdateHook ){
550 Tcl_DecrRefCount(pDb->pUpdateHook);
551 }
dan46c47d42011-03-01 18:42:07 +0000552 if( pDb->pPreUpdateHook ){
553 Tcl_DecrRefCount(pDb->pPreUpdateHook);
554 }
danielk197771fd80b2005-12-16 06:54:01 +0000555 if( pDb->pRollbackHook ){
556 Tcl_DecrRefCount(pDb->pRollbackHook);
557 }
drh5def0842010-05-05 20:00:25 +0000558 if( pDb->pWalHook ){
559 Tcl_DecrRefCount(pDb->pWalHook);
dan8d22a172010-04-19 18:03:51 +0000560 }
danielk197794eb6a12005-12-15 15:22:08 +0000561 if( pDb->pCollateNeeded ){
562 Tcl_DecrRefCount(pDb->pCollateNeeded);
563 }
drhbec3f402000-08-04 13:49:02 +0000564 Tcl_Free((char*)pDb);
565}
566
567/*
568** This routine is called when a database file is locked while trying
569** to execute SQL.
570*/
danielk19772a764eb2004-06-12 01:43:26 +0000571static int DbBusyHandler(void *cd, int nTries){
drhbec3f402000-08-04 13:49:02 +0000572 SqliteDb *pDb = (SqliteDb*)cd;
573 int rc;
574 char zVal[30];
drhbec3f402000-08-04 13:49:02 +0000575
drh5bb3eb92007-05-04 13:15:55 +0000576 sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);
drhd1e47332005-06-26 17:55:33 +0000577 rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);
drhbec3f402000-08-04 13:49:02 +0000578 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
579 return 0;
580 }
581 return 1;
drh75897232000-05-29 14:26:00 +0000582}
583
drh26e4a8b2008-05-01 17:16:52 +0000584#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
drh75897232000-05-29 14:26:00 +0000585/*
danielk1977348bb5d2003-10-18 09:37:26 +0000586** This routine is invoked as the 'progress callback' for the database.
587*/
588static int DbProgressHandler(void *cd){
589 SqliteDb *pDb = (SqliteDb*)cd;
590 int rc;
591
592 assert( pDb->zProgress );
593 rc = Tcl_Eval(pDb->interp, pDb->zProgress);
594 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
595 return 1;
596 }
597 return 0;
598}
drh26e4a8b2008-05-01 17:16:52 +0000599#endif
danielk1977348bb5d2003-10-18 09:37:26 +0000600
drh2eb22af2016-09-10 19:51:40 +0000601#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
602 !defined(SQLITE_OMIT_DEPRECATED)
danielk1977348bb5d2003-10-18 09:37:26 +0000603/*
drhb5a20d32003-04-23 12:25:23 +0000604** This routine is called by the SQLite trace handler whenever a new
605** block of SQL is executed. The TCL script in pDb->zTrace is executed.
drh0d1a6432003-04-03 15:46:04 +0000606*/
drhb5a20d32003-04-23 12:25:23 +0000607static void DbTraceHandler(void *cd, const char *zSql){
drh0d1a6432003-04-03 15:46:04 +0000608 SqliteDb *pDb = (SqliteDb*)cd;
drhb5a20d32003-04-23 12:25:23 +0000609 Tcl_DString str;
drh0d1a6432003-04-03 15:46:04 +0000610
drhb5a20d32003-04-23 12:25:23 +0000611 Tcl_DStringInit(&str);
612 Tcl_DStringAppend(&str, pDb->zTrace, -1);
613 Tcl_DStringAppendElement(&str, zSql);
614 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
615 Tcl_DStringFree(&str);
616 Tcl_ResetResult(pDb->interp);
drh0d1a6432003-04-03 15:46:04 +0000617}
drhd1167392006-01-23 13:00:35 +0000618#endif
drh0d1a6432003-04-03 15:46:04 +0000619
drhd1167392006-01-23 13:00:35 +0000620#ifndef SQLITE_OMIT_TRACE
drh0d1a6432003-04-03 15:46:04 +0000621/*
mistachkinb56660f2016-07-14 21:26:09 +0000622** This routine is called by the SQLite trace_v2 handler whenever a new
623** supported event is generated. Unsupported event types are ignored.
624** The TCL script in pDb->zTraceV2 is executed, with the arguments for
625** the event appended to it (as list elements).
626*/
627static int DbTraceV2Handler(
628 unsigned type, /* One of the SQLITE_TRACE_* event types. */
629 void *cd, /* The original context data pointer. */
630 void *pd, /* Primary event data, depends on event type. */
631 void *xd /* Extra event data, depends on event type. */
632){
633 SqliteDb *pDb = (SqliteDb*)cd;
634 Tcl_Obj *pCmd;
635
636 switch( type ){
637 case SQLITE_TRACE_STMT: {
638 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
639 char *zSql = (char *)xd;
640
641 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
642 Tcl_IncrRefCount(pCmd);
643 Tcl_ListObjAppendElement(pDb->interp, pCmd,
644 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
645 Tcl_ListObjAppendElement(pDb->interp, pCmd,
646 Tcl_NewStringObj(zSql, -1));
647 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
648 Tcl_DecrRefCount(pCmd);
649 Tcl_ResetResult(pDb->interp);
650 break;
651 }
652 case SQLITE_TRACE_PROFILE: {
653 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
drhffdab722018-03-10 20:25:08 +0000654 sqlite3_int64 ns = *(sqlite3_int64*)xd;
mistachkinb56660f2016-07-14 21:26:09 +0000655
656 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
657 Tcl_IncrRefCount(pCmd);
658 Tcl_ListObjAppendElement(pDb->interp, pCmd,
659 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
660 Tcl_ListObjAppendElement(pDb->interp, pCmd,
661 Tcl_NewWideIntObj((Tcl_WideInt)ns));
662 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
663 Tcl_DecrRefCount(pCmd);
664 Tcl_ResetResult(pDb->interp);
665 break;
666 }
667 case SQLITE_TRACE_ROW: {
668 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
669
670 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
671 Tcl_IncrRefCount(pCmd);
672 Tcl_ListObjAppendElement(pDb->interp, pCmd,
673 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
674 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
675 Tcl_DecrRefCount(pCmd);
676 Tcl_ResetResult(pDb->interp);
677 break;
678 }
679 case SQLITE_TRACE_CLOSE: {
680 sqlite3 *db = (sqlite3 *)pd;
681
682 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
683 Tcl_IncrRefCount(pCmd);
684 Tcl_ListObjAppendElement(pDb->interp, pCmd,
685 Tcl_NewWideIntObj((Tcl_WideInt)db));
686 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
687 Tcl_DecrRefCount(pCmd);
688 Tcl_ResetResult(pDb->interp);
689 break;
690 }
691 }
692 return SQLITE_OK;
693}
694#endif
695
drh2eb22af2016-09-10 19:51:40 +0000696#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
697 !defined(SQLITE_OMIT_DEPRECATED)
mistachkinb56660f2016-07-14 21:26:09 +0000698/*
drh19e2d372005-08-29 23:00:03 +0000699** This routine is called by the SQLite profile handler after a statement
700** SQL has executed. The TCL script in pDb->zProfile is evaluated.
701*/
702static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
703 SqliteDb *pDb = (SqliteDb*)cd;
704 Tcl_DString str;
705 char zTm[100];
706
707 sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
708 Tcl_DStringInit(&str);
709 Tcl_DStringAppend(&str, pDb->zProfile, -1);
710 Tcl_DStringAppendElement(&str, zSql);
711 Tcl_DStringAppendElement(&str, zTm);
712 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
713 Tcl_DStringFree(&str);
714 Tcl_ResetResult(pDb->interp);
715}
drhd1167392006-01-23 13:00:35 +0000716#endif
drh19e2d372005-08-29 23:00:03 +0000717
718/*
drhaa940ea2004-01-15 02:44:03 +0000719** This routine is called when a transaction is committed. The
720** TCL script in pDb->zCommit is executed. If it returns non-zero or
721** if it throws an exception, the transaction is rolled back instead
722** of being committed.
723*/
724static int DbCommitHandler(void *cd){
725 SqliteDb *pDb = (SqliteDb*)cd;
726 int rc;
727
728 rc = Tcl_Eval(pDb->interp, pDb->zCommit);
729 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
730 return 1;
731 }
732 return 0;
733}
734
danielk197771fd80b2005-12-16 06:54:01 +0000735static void DbRollbackHandler(void *clientData){
736 SqliteDb *pDb = (SqliteDb*)clientData;
737 assert(pDb->pRollbackHook);
738 if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){
739 Tcl_BackgroundError(pDb->interp);
740 }
741}
742
drh5def0842010-05-05 20:00:25 +0000743/*
744** This procedure handles wal_hook callbacks.
745*/
746static int DbWalHandler(
mistachkinb56660f2016-07-14 21:26:09 +0000747 void *clientData,
748 sqlite3 *db,
749 const char *zDb,
dan8d22a172010-04-19 18:03:51 +0000750 int nEntry
751){
drh5def0842010-05-05 20:00:25 +0000752 int ret = SQLITE_OK;
dan8d22a172010-04-19 18:03:51 +0000753 Tcl_Obj *p;
754 SqliteDb *pDb = (SqliteDb*)clientData;
755 Tcl_Interp *interp = pDb->interp;
drh5def0842010-05-05 20:00:25 +0000756 assert(pDb->pWalHook);
dan8d22a172010-04-19 18:03:51 +0000757
dan6e45e0c2014-12-10 20:29:49 +0000758 assert( db==pDb->db );
drh5def0842010-05-05 20:00:25 +0000759 p = Tcl_DuplicateObj(pDb->pWalHook);
dan8d22a172010-04-19 18:03:51 +0000760 Tcl_IncrRefCount(p);
761 Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
762 Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
mistachkinb56660f2016-07-14 21:26:09 +0000763 if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
dan8d22a172010-04-19 18:03:51 +0000764 || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
765 ){
766 Tcl_BackgroundError(interp);
767 }
768 Tcl_DecrRefCount(p);
769
770 return ret;
771}
772
drhbcf4f482009-03-27 12:44:35 +0000773#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
danielk1977404ca072009-03-16 13:19:36 +0000774static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
775 char zBuf[64];
drh65545b52015-01-19 00:35:53 +0000776 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iArg);
danielk1977404ca072009-03-16 13:19:36 +0000777 Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
drh65545b52015-01-19 00:35:53 +0000778 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nArg);
danielk1977404ca072009-03-16 13:19:36 +0000779 Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
780}
781#else
drhbcf4f482009-03-27 12:44:35 +0000782# define setTestUnlockNotifyVars(x,y,z)
danielk1977404ca072009-03-16 13:19:36 +0000783#endif
784
drh69910da2009-03-27 12:32:54 +0000785#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
danielk1977404ca072009-03-16 13:19:36 +0000786static void DbUnlockNotify(void **apArg, int nArg){
787 int i;
788 for(i=0; i<nArg; i++){
789 const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
790 SqliteDb *pDb = (SqliteDb *)apArg[i];
791 setTestUnlockNotifyVars(pDb->interp, i, nArg);
792 assert( pDb->pUnlockNotify);
793 Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
794 Tcl_DecrRefCount(pDb->pUnlockNotify);
795 pDb->pUnlockNotify = 0;
796 }
797}
drh69910da2009-03-27 12:32:54 +0000798#endif
danielk1977404ca072009-03-16 13:19:36 +0000799
drh9b1c62d2011-03-30 21:04:43 +0000800#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
dan46c47d42011-03-01 18:42:07 +0000801/*
802** Pre-update hook callback.
803*/
804static void DbPreUpdateHandler(
mistachkinb56660f2016-07-14 21:26:09 +0000805 void *p,
dan46c47d42011-03-01 18:42:07 +0000806 sqlite3 *db,
807 int op,
mistachkinb56660f2016-07-14 21:26:09 +0000808 const char *zDb,
809 const char *zTbl,
dan46c47d42011-03-01 18:42:07 +0000810 sqlite_int64 iKey1,
811 sqlite_int64 iKey2
812){
813 SqliteDb *pDb = (SqliteDb *)p;
814 Tcl_Obj *pCmd;
815 static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
816
817 assert( (SQLITE_DELETE-1)/9 == 0 );
818 assert( (SQLITE_INSERT-1)/9 == 1 );
819 assert( (SQLITE_UPDATE-1)/9 == 2 );
820 assert( pDb->pPreUpdateHook );
821 assert( db==pDb->db );
822 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
823
824 pCmd = Tcl_DuplicateObj(pDb->pPreUpdateHook);
825 Tcl_IncrRefCount(pCmd);
826 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
827 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
828 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
829 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey1));
830 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey2));
831 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
832 Tcl_DecrRefCount(pCmd);
833}
drh9b1c62d2011-03-30 21:04:43 +0000834#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
dan46c47d42011-03-01 18:42:07 +0000835
danielk197794eb6a12005-12-15 15:22:08 +0000836static void DbUpdateHandler(
mistachkinb56660f2016-07-14 21:26:09 +0000837 void *p,
danielk197794eb6a12005-12-15 15:22:08 +0000838 int op,
mistachkinb56660f2016-07-14 21:26:09 +0000839 const char *zDb,
840 const char *zTbl,
danielk197794eb6a12005-12-15 15:22:08 +0000841 sqlite_int64 rowid
842){
843 SqliteDb *pDb = (SqliteDb *)p;
844 Tcl_Obj *pCmd;
dan46c47d42011-03-01 18:42:07 +0000845 static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
846
847 assert( (SQLITE_DELETE-1)/9 == 0 );
848 assert( (SQLITE_INSERT-1)/9 == 1 );
849 assert( (SQLITE_UPDATE-1)/9 == 2 );
danielk197794eb6a12005-12-15 15:22:08 +0000850
851 assert( pDb->pUpdateHook );
852 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
853
854 pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
855 Tcl_IncrRefCount(pCmd);
dan46c47d42011-03-01 18:42:07 +0000856 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
danielk197794eb6a12005-12-15 15:22:08 +0000857 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
858 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
859 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
860 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
drhefdde162010-10-27 15:36:21 +0000861 Tcl_DecrRefCount(pCmd);
danielk197794eb6a12005-12-15 15:22:08 +0000862}
863
danielk19777cedc8d2004-06-10 10:50:08 +0000864static void tclCollateNeeded(
865 void *pCtx,
drh9bb575f2004-09-06 17:24:11 +0000866 sqlite3 *db,
danielk19777cedc8d2004-06-10 10:50:08 +0000867 int enc,
868 const char *zName
869){
870 SqliteDb *pDb = (SqliteDb *)pCtx;
871 Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
872 Tcl_IncrRefCount(pScript);
873 Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
874 Tcl_EvalObjEx(pDb->interp, pScript, 0);
875 Tcl_DecrRefCount(pScript);
876}
877
drhaa940ea2004-01-15 02:44:03 +0000878/*
danielk19770202b292004-06-09 09:55:16 +0000879** This routine is called to evaluate an SQL collation function implemented
880** using TCL script.
881*/
882static int tclSqlCollate(
883 void *pCtx,
884 int nA,
885 const void *zA,
886 int nB,
887 const void *zB
888){
889 SqlCollate *p = (SqlCollate *)pCtx;
890 Tcl_Obj *pCmd;
891
892 pCmd = Tcl_NewStringObj(p->zScript, -1);
893 Tcl_IncrRefCount(pCmd);
894 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
895 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
drhd1e47332005-06-26 17:55:33 +0000896 Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
danielk19770202b292004-06-09 09:55:16 +0000897 Tcl_DecrRefCount(pCmd);
898 return (atoi(Tcl_GetStringResult(p->interp)));
899}
900
901/*
drhcabb0812002-09-14 13:47:32 +0000902** This routine is called to evaluate an SQL function implemented
903** using TCL script.
904*/
drhfb7e7652005-01-24 00:28:42 +0000905static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
danielk19776f8a5032004-05-10 10:34:51 +0000906 SqlFunc *p = sqlite3_user_data(context);
drhd1e47332005-06-26 17:55:33 +0000907 Tcl_Obj *pCmd;
drhcabb0812002-09-14 13:47:32 +0000908 int i;
909 int rc;
910
drhd1e47332005-06-26 17:55:33 +0000911 if( argc==0 ){
912 /* If there are no arguments to the function, call Tcl_EvalObjEx on the
913 ** script object directly. This allows the TCL compiler to generate
914 ** bytecode for the command on the first invocation and thus make
915 ** subsequent invocations much faster. */
916 pCmd = p->pScript;
917 Tcl_IncrRefCount(pCmd);
918 rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
919 Tcl_DecrRefCount(pCmd);
920 }else{
921 /* If there are arguments to the function, make a shallow copy of the
922 ** script object, lappend the arguments, then evaluate the copy.
923 **
peter.d.reid60ec9142014-09-06 16:39:46 +0000924 ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated.
mistachkinb56660f2016-07-14 21:26:09 +0000925 ** The new Tcl_Obj contains pointers to the original list elements.
drhd1e47332005-06-26 17:55:33 +0000926 ** That way, when Tcl_EvalObjv() is run and shimmers the first element
927 ** of the list to tclCmdNameType, that alternate representation will
928 ** be preserved and reused on the next invocation.
929 */
930 Tcl_Obj **aArg;
931 int nArg;
932 if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
mistachkinb56660f2016-07-14 21:26:09 +0000933 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
drhd1e47332005-06-26 17:55:33 +0000934 return;
mistachkinb56660f2016-07-14 21:26:09 +0000935 }
drhd1e47332005-06-26 17:55:33 +0000936 pCmd = Tcl_NewListObj(nArg, aArg);
937 Tcl_IncrRefCount(pCmd);
938 for(i=0; i<argc; i++){
939 sqlite3_value *pIn = argv[i];
940 Tcl_Obj *pVal;
mistachkinb56660f2016-07-14 21:26:09 +0000941
drhd1e47332005-06-26 17:55:33 +0000942 /* Set pVal to contain the i'th column of this row. */
943 switch( sqlite3_value_type(pIn) ){
944 case SQLITE_BLOB: {
945 int bytes = sqlite3_value_bytes(pIn);
946 pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
947 break;
948 }
949 case SQLITE_INTEGER: {
950 sqlite_int64 v = sqlite3_value_int64(pIn);
951 if( v>=-2147483647 && v<=2147483647 ){
drh7fd33922011-06-20 19:00:30 +0000952 pVal = Tcl_NewIntObj((int)v);
drhd1e47332005-06-26 17:55:33 +0000953 }else{
954 pVal = Tcl_NewWideIntObj(v);
955 }
956 break;
957 }
958 case SQLITE_FLOAT: {
959 double r = sqlite3_value_double(pIn);
960 pVal = Tcl_NewDoubleObj(r);
961 break;
962 }
963 case SQLITE_NULL: {
drhc45e6712012-10-03 11:02:33 +0000964 pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
drhd1e47332005-06-26 17:55:33 +0000965 break;
966 }
967 default: {
968 int bytes = sqlite3_value_bytes(pIn);
danielk197700fd9572005-12-07 06:27:43 +0000969 pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
drhd1e47332005-06-26 17:55:33 +0000970 break;
971 }
972 }
973 rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
974 if( rc ){
975 Tcl_DecrRefCount(pCmd);
mistachkinb56660f2016-07-14 21:26:09 +0000976 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
drhd1e47332005-06-26 17:55:33 +0000977 return;
978 }
danielk197751ad0ec2004-05-24 12:39:02 +0000979 }
drhd1e47332005-06-26 17:55:33 +0000980 if( !p->useEvalObjv ){
981 /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
982 ** is a list without a string representation. To prevent this from
983 ** happening, make sure pCmd has a valid string representation */
984 Tcl_GetString(pCmd);
985 }
986 rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
987 Tcl_DecrRefCount(pCmd);
drhcabb0812002-09-14 13:47:32 +0000988 }
danielk1977562e8d32005-05-20 09:40:55 +0000989
drhc7f269d2005-05-05 10:30:29 +0000990 if( rc && rc!=TCL_RETURN ){
mistachkinb56660f2016-07-14 21:26:09 +0000991 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
drhcabb0812002-09-14 13:47:32 +0000992 }else{
drhc7f269d2005-05-05 10:30:29 +0000993 Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
994 int n;
995 u8 *data;
dan4a4c11a2009-10-06 14:59:02 +0000996 const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
drhc7f269d2005-05-05 10:30:29 +0000997 char c = zType[0];
drhdf0bdda2005-06-25 19:31:48 +0000998 if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
drhd1e47332005-06-26 17:55:33 +0000999 /* Only return a BLOB type if the Tcl variable is a bytearray and
drhdf0bdda2005-06-25 19:31:48 +00001000 ** has no string representation. */
drhc7f269d2005-05-05 10:30:29 +00001001 data = Tcl_GetByteArrayFromObj(pVar, &n);
1002 sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
drh985e0c62007-06-26 22:55:37 +00001003 }else if( c=='b' && strcmp(zType,"boolean")==0 ){
drhc7f269d2005-05-05 10:30:29 +00001004 Tcl_GetIntFromObj(0, pVar, &n);
1005 sqlite3_result_int(context, n);
1006 }else if( c=='d' && strcmp(zType,"double")==0 ){
1007 double r;
1008 Tcl_GetDoubleFromObj(0, pVar, &r);
1009 sqlite3_result_double(context, r);
drh985e0c62007-06-26 22:55:37 +00001010 }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
1011 (c=='i' && strcmp(zType,"int")==0) ){
drhdf0bdda2005-06-25 19:31:48 +00001012 Tcl_WideInt v;
1013 Tcl_GetWideIntFromObj(0, pVar, &v);
1014 sqlite3_result_int64(context, v);
drhc7f269d2005-05-05 10:30:29 +00001015 }else{
danielk197700fd9572005-12-07 06:27:43 +00001016 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
1017 sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
drhc7f269d2005-05-05 10:30:29 +00001018 }
drhcabb0812002-09-14 13:47:32 +00001019 }
1020}
drh895d7472004-08-20 16:02:39 +00001021
drhe22a3342003-04-22 20:30:37 +00001022#ifndef SQLITE_OMIT_AUTHORIZATION
1023/*
1024** This is the authentication function. It appends the authentication
1025** type code and the two arguments to zCmd[] then invokes the result
1026** on the interpreter. The reply is examined to determine if the
1027** authentication fails or succeeds.
1028*/
1029static int auth_callback(
1030 void *pArg,
1031 int code,
1032 const char *zArg1,
1033 const char *zArg2,
1034 const char *zArg3,
1035 const char *zArg4
drh32c6a482014-09-11 13:44:52 +00001036#ifdef SQLITE_USER_AUTHENTICATION
1037 ,const char *zArg5
1038#endif
drhe22a3342003-04-22 20:30:37 +00001039){
mistachkin6ef5e122014-01-24 17:03:55 +00001040 const char *zCode;
drhe22a3342003-04-22 20:30:37 +00001041 Tcl_DString str;
1042 int rc;
1043 const char *zReply;
drh94189212017-05-11 13:43:57 +00001044 /* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer
1045 ** callback is a copy of the third parameter to the
1046 ** sqlite3_set_authorizer() interface.
1047 */
drhe22a3342003-04-22 20:30:37 +00001048 SqliteDb *pDb = (SqliteDb*)pArg;
drh1f1549f2008-08-26 21:33:34 +00001049 if( pDb->disableAuth ) return SQLITE_OK;
drhe22a3342003-04-22 20:30:37 +00001050
drh94189212017-05-11 13:43:57 +00001051 /* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an
1052 ** integer action code that specifies the particular action to be
1053 ** authorized. */
drhe22a3342003-04-22 20:30:37 +00001054 switch( code ){
1055 case SQLITE_COPY : zCode="SQLITE_COPY"; break;
1056 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
1057 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
1058 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
1059 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
1060 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
1061 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
1062 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break;
1063 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break;
1064 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break;
1065 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break;
1066 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break;
1067 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break;
1068 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break;
1069 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
1070 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break;
1071 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break;
1072 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break;
1073 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break;
1074 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break;
1075 case SQLITE_READ : zCode="SQLITE_READ"; break;
1076 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break;
1077 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break;
1078 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break;
drh81e293b2003-06-06 19:00:42 +00001079 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break;
1080 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break;
danielk19771c8c23c2004-11-12 15:53:37 +00001081 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break;
danielk19771d54df82004-11-23 15:41:16 +00001082 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break;
drhe6e04962005-07-23 02:17:03 +00001083 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break;
danielk1977f1a381e2006-06-16 08:01:02 +00001084 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break;
1085 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break;
drh5169bbc2006-08-24 14:59:45 +00001086 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break;
danielk1977ab9b7032008-12-30 06:24:58 +00001087 case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break;
drh65a2aaa2014-01-16 22:40:02 +00001088 case SQLITE_RECURSIVE : zCode="SQLITE_RECURSIVE"; break;
drhe22a3342003-04-22 20:30:37 +00001089 default : zCode="????"; break;
1090 }
1091 Tcl_DStringInit(&str);
1092 Tcl_DStringAppend(&str, pDb->zAuth, -1);
1093 Tcl_DStringAppendElement(&str, zCode);
1094 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
1095 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
1096 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
1097 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
drh32c6a482014-09-11 13:44:52 +00001098#ifdef SQLITE_USER_AUTHENTICATION
1099 Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
mistachkinb56660f2016-07-14 21:26:09 +00001100#endif
drhe22a3342003-04-22 20:30:37 +00001101 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
1102 Tcl_DStringFree(&str);
drhb07028f2011-10-14 21:49:18 +00001103 zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
drhe22a3342003-04-22 20:30:37 +00001104 if( strcmp(zReply,"SQLITE_OK")==0 ){
1105 rc = SQLITE_OK;
1106 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
1107 rc = SQLITE_DENY;
1108 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
1109 rc = SQLITE_IGNORE;
1110 }else{
1111 rc = 999;
1112 }
1113 return rc;
1114}
1115#endif /* SQLITE_OMIT_AUTHORIZATION */
drhcabb0812002-09-14 13:47:32 +00001116
1117/*
tpoindex1067fe12004-12-17 15:41:11 +00001118** This routine reads a line of text from FILE in, stores
1119** the text in memory obtained from malloc() and returns a pointer
1120** to the text. NULL is returned at end of file, or if malloc()
1121** fails.
1122**
1123** The interface is like "readline" but no command-line editing
1124** is done.
1125**
1126** copied from shell.c from '.import' command
1127*/
1128static char *local_getline(char *zPrompt, FILE *in){
1129 char *zLine;
1130 int nLine;
1131 int n;
tpoindex1067fe12004-12-17 15:41:11 +00001132
1133 nLine = 100;
1134 zLine = malloc( nLine );
1135 if( zLine==0 ) return 0;
1136 n = 0;
drhb07028f2011-10-14 21:49:18 +00001137 while( 1 ){
tpoindex1067fe12004-12-17 15:41:11 +00001138 if( n+100>nLine ){
1139 nLine = nLine*2 + 100;
1140 zLine = realloc(zLine, nLine);
1141 if( zLine==0 ) return 0;
1142 }
1143 if( fgets(&zLine[n], nLine - n, in)==0 ){
1144 if( n==0 ){
1145 free(zLine);
1146 return 0;
1147 }
1148 zLine[n] = 0;
tpoindex1067fe12004-12-17 15:41:11 +00001149 break;
1150 }
1151 while( zLine[n] ){ n++; }
1152 if( n>0 && zLine[n-1]=='\n' ){
1153 n--;
1154 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +00001155 break;
tpoindex1067fe12004-12-17 15:41:11 +00001156 }
1157 }
1158 zLine = realloc( zLine, n+1 );
1159 return zLine;
1160}
1161
danielk19778e556522007-11-13 10:30:24 +00001162
1163/*
dan4a4c11a2009-10-06 14:59:02 +00001164** This function is part of the implementation of the command:
danielk19778e556522007-11-13 10:30:24 +00001165**
dan4a4c11a2009-10-06 14:59:02 +00001166** $db transaction [-deferred|-immediate|-exclusive] SCRIPT
danielk19778e556522007-11-13 10:30:24 +00001167**
dan4a4c11a2009-10-06 14:59:02 +00001168** It is invoked after evaluating the script SCRIPT to commit or rollback
1169** the transaction or savepoint opened by the [transaction] command.
1170*/
mistachkina121cc72016-07-28 18:06:52 +00001171static int SQLITE_TCLAPI DbTransPostCmd(
dan4a4c11a2009-10-06 14:59:02 +00001172 ClientData data[], /* data[0] is the Sqlite3Db* for $db */
1173 Tcl_Interp *interp, /* Tcl interpreter */
1174 int result /* Result of evaluating SCRIPT */
1175){
mistachkin6ef5e122014-01-24 17:03:55 +00001176 static const char *const azEnd[] = {
dan4a4c11a2009-10-06 14:59:02 +00001177 "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */
1178 "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */
1179 "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
1180 "ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */
1181 };
1182 SqliteDb *pDb = (SqliteDb*)data[0];
1183 int rc = result;
1184 const char *zEnd;
1185
1186 pDb->nTransaction--;
1187 zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];
1188
1189 pDb->disableAuth++;
1190 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
1191 /* This is a tricky scenario to handle. The most likely cause of an
mistachkinb56660f2016-07-14 21:26:09 +00001192 ** error is that the exec() above was an attempt to commit the
dan4a4c11a2009-10-06 14:59:02 +00001193 ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
mistachkin48864df2013-03-21 21:20:32 +00001194 ** that an IO-error has occurred. In either case, throw a Tcl exception
dan4a4c11a2009-10-06 14:59:02 +00001195 ** and try to rollback the transaction.
1196 **
mistachkinb56660f2016-07-14 21:26:09 +00001197 ** But it could also be that the user executed one or more BEGIN,
dan4a4c11a2009-10-06 14:59:02 +00001198 ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
1199 ** this method's logic. Not clear how this would be best handled.
1200 */
1201 if( rc!=TCL_ERROR ){
drha198f2b2014-02-07 19:26:13 +00001202 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
dan4a4c11a2009-10-06 14:59:02 +00001203 rc = TCL_ERROR;
1204 }
1205 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
1206 }
1207 pDb->disableAuth--;
1208
1209 return rc;
1210}
1211
1212/*
danc431fd52011-06-27 16:55:50 +00001213** Unless SQLITE_TEST is defined, this function is a simple wrapper around
1214** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
1215** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
mistachkinb56660f2016-07-14 21:26:09 +00001216** on whether or not the [db_use_legacy_prepare] command has been used to
danc431fd52011-06-27 16:55:50 +00001217** configure the connection.
1218*/
1219static int dbPrepare(
1220 SqliteDb *pDb, /* Database object */
1221 const char *zSql, /* SQL to compile */
1222 sqlite3_stmt **ppStmt, /* OUT: Prepared statement */
1223 const char **pzOut /* OUT: Pointer to next SQL statement */
1224){
drh2c2f3922017-06-01 00:54:35 +00001225 unsigned int prepFlags = 0;
danc431fd52011-06-27 16:55:50 +00001226#ifdef SQLITE_TEST
1227 if( pDb->bLegacyPrepare ){
1228 return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
1229 }
1230#endif
drh2c2f3922017-06-01 00:54:35 +00001231 /* If the statement cache is large, use the SQLITE_PREPARE_PERSISTENT
1232 ** flags, which uses less lookaside memory. But if the cache is small,
1233 ** omit that flag to make full use of lookaside */
1234 if( pDb->maxStmt>5 ) prepFlags = SQLITE_PREPARE_PERSISTENT;
1235
1236 return sqlite3_prepare_v3(pDb->db, zSql, -1, prepFlags, ppStmt, pzOut);
danc431fd52011-06-27 16:55:50 +00001237}
1238
1239/*
dan4a4c11a2009-10-06 14:59:02 +00001240** Search the cache for a prepared-statement object that implements the
1241** first SQL statement in the buffer pointed to by parameter zIn. If
1242** no such prepared-statement can be found, allocate and prepare a new
1243** one. In either case, bind the current values of the relevant Tcl
1244** variables to any $var, :var or @var variables in the statement. Before
1245** returning, set *ppPreStmt to point to the prepared-statement object.
1246**
1247** Output parameter *pzOut is set to point to the next SQL statement in
1248** buffer zIn, or to the '\0' byte at the end of zIn if there is no
1249** next statement.
1250**
1251** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned
1252** and an error message loaded into interpreter pDb->interp.
1253*/
1254static int dbPrepareAndBind(
1255 SqliteDb *pDb, /* Database object */
1256 char const *zIn, /* SQL to compile */
1257 char const **pzOut, /* OUT: Pointer to next SQL statement */
1258 SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */
1259){
1260 const char *zSql = zIn; /* Pointer to first SQL statement in zIn */
mistachkin7bb22ac2015-01-12 19:59:12 +00001261 sqlite3_stmt *pStmt = 0; /* Prepared statement object */
dan4a4c11a2009-10-06 14:59:02 +00001262 SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */
1263 int nSql; /* Length of zSql in bytes */
mistachkin7bb22ac2015-01-12 19:59:12 +00001264 int nVar = 0; /* Number of variables in statement */
dan4a4c11a2009-10-06 14:59:02 +00001265 int iParm = 0; /* Next free entry in apParm */
drh0425f182013-11-26 16:48:04 +00001266 char c;
dan4a4c11a2009-10-06 14:59:02 +00001267 int i;
1268 Tcl_Interp *interp = pDb->interp;
1269
1270 *ppPreStmt = 0;
1271
1272 /* Trim spaces from the start of zSql and calculate the remaining length. */
drh0425f182013-11-26 16:48:04 +00001273 while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; }
dan4a4c11a2009-10-06 14:59:02 +00001274 nSql = strlen30(zSql);
1275
1276 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
1277 int n = pPreStmt->nSql;
mistachkinb56660f2016-07-14 21:26:09 +00001278 if( nSql>=n
dan4a4c11a2009-10-06 14:59:02 +00001279 && memcmp(pPreStmt->zSql, zSql, n)==0
1280 && (zSql[n]==0 || zSql[n-1]==';')
1281 ){
1282 pStmt = pPreStmt->pStmt;
1283 *pzOut = &zSql[pPreStmt->nSql];
1284
1285 /* When a prepared statement is found, unlink it from the
1286 ** cache list. It will later be added back to the beginning
1287 ** of the cache list in order to implement LRU replacement.
1288 */
1289 if( pPreStmt->pPrev ){
1290 pPreStmt->pPrev->pNext = pPreStmt->pNext;
1291 }else{
1292 pDb->stmtList = pPreStmt->pNext;
1293 }
1294 if( pPreStmt->pNext ){
1295 pPreStmt->pNext->pPrev = pPreStmt->pPrev;
1296 }else{
1297 pDb->stmtLast = pPreStmt->pPrev;
1298 }
1299 pDb->nStmt--;
1300 nVar = sqlite3_bind_parameter_count(pStmt);
1301 break;
1302 }
1303 }
mistachkinb56660f2016-07-14 21:26:09 +00001304
dan4a4c11a2009-10-06 14:59:02 +00001305 /* If no prepared statement was found. Compile the SQL text. Also allocate
1306 ** a new SqlPreparedStmt structure. */
1307 if( pPreStmt==0 ){
1308 int nByte;
1309
danc431fd52011-06-27 16:55:50 +00001310 if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
drhc45e6712012-10-03 11:02:33 +00001311 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
dan4a4c11a2009-10-06 14:59:02 +00001312 return TCL_ERROR;
1313 }
1314 if( pStmt==0 ){
1315 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
1316 /* A compile-time error in the statement. */
drhc45e6712012-10-03 11:02:33 +00001317 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
dan4a4c11a2009-10-06 14:59:02 +00001318 return TCL_ERROR;
1319 }else{
1320 /* The statement was a no-op. Continue to the next statement
1321 ** in the SQL string.
1322 */
1323 return TCL_OK;
1324 }
1325 }
1326
1327 assert( pPreStmt==0 );
1328 nVar = sqlite3_bind_parameter_count(pStmt);
1329 nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *);
1330 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte);
1331 memset(pPreStmt, 0, nByte);
1332
1333 pPreStmt->pStmt = pStmt;
drh7ed243b2012-04-19 17:19:51 +00001334 pPreStmt->nSql = (int)(*pzOut - zSql);
dan4a4c11a2009-10-06 14:59:02 +00001335 pPreStmt->zSql = sqlite3_sql(pStmt);
1336 pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
danc431fd52011-06-27 16:55:50 +00001337#ifdef SQLITE_TEST
1338 if( pPreStmt->zSql==0 ){
1339 char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
1340 memcpy(zCopy, zSql, pPreStmt->nSql);
1341 zCopy[pPreStmt->nSql] = '\0';
1342 pPreStmt->zSql = zCopy;
1343 }
1344#endif
dan4a4c11a2009-10-06 14:59:02 +00001345 }
1346 assert( pPreStmt );
1347 assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
1348 assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
1349
mistachkinb56660f2016-07-14 21:26:09 +00001350 /* Bind values to parameters that begin with $ or : */
dan4a4c11a2009-10-06 14:59:02 +00001351 for(i=1; i<=nVar; i++){
1352 const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
1353 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
1354 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
1355 if( pVar ){
1356 int n;
1357 u8 *data;
1358 const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
mistachkin8e189222015-04-19 21:43:16 +00001359 c = zType[0];
dan4a4c11a2009-10-06 14:59:02 +00001360 if( zVar[0]=='@' ||
1361 (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
1362 /* Load a BLOB type if the Tcl variable is a bytearray and
1363 ** it has no string representation or the host
1364 ** parameter name begins with "@". */
1365 data = Tcl_GetByteArrayFromObj(pVar, &n);
1366 sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
1367 Tcl_IncrRefCount(pVar);
1368 pPreStmt->apParm[iParm++] = pVar;
1369 }else if( c=='b' && strcmp(zType,"boolean")==0 ){
1370 Tcl_GetIntFromObj(interp, pVar, &n);
1371 sqlite3_bind_int(pStmt, i, n);
1372 }else if( c=='d' && strcmp(zType,"double")==0 ){
1373 double r;
1374 Tcl_GetDoubleFromObj(interp, pVar, &r);
1375 sqlite3_bind_double(pStmt, i, r);
1376 }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
1377 (c=='i' && strcmp(zType,"int")==0) ){
1378 Tcl_WideInt v;
1379 Tcl_GetWideIntFromObj(interp, pVar, &v);
1380 sqlite3_bind_int64(pStmt, i, v);
1381 }else{
1382 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
1383 sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
1384 Tcl_IncrRefCount(pVar);
1385 pPreStmt->apParm[iParm++] = pVar;
1386 }
1387 }else{
1388 sqlite3_bind_null(pStmt, i);
1389 }
1390 }
1391 }
1392 pPreStmt->nParm = iParm;
1393 *ppPreStmt = pPreStmt;
dan937d0de2009-10-15 18:35:38 +00001394
dan4a4c11a2009-10-06 14:59:02 +00001395 return TCL_OK;
1396}
1397
dan4a4c11a2009-10-06 14:59:02 +00001398/*
1399** Release a statement reference obtained by calling dbPrepareAndBind().
1400** There should be exactly one call to this function for each call to
1401** dbPrepareAndBind().
1402**
1403** If the discard parameter is non-zero, then the statement is deleted
1404** immediately. Otherwise it is added to the LRU list and may be returned
1405** by a subsequent call to dbPrepareAndBind().
1406*/
1407static void dbReleaseStmt(
1408 SqliteDb *pDb, /* Database handle */
1409 SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */
1410 int discard /* True to delete (not cache) the pPreStmt */
1411){
1412 int i;
1413
1414 /* Free the bound string and blob parameters */
1415 for(i=0; i<pPreStmt->nParm; i++){
1416 Tcl_DecrRefCount(pPreStmt->apParm[i]);
1417 }
1418 pPreStmt->nParm = 0;
1419
1420 if( pDb->maxStmt<=0 || discard ){
1421 /* If the cache is turned off, deallocated the statement */
danc431fd52011-06-27 16:55:50 +00001422 dbFreeStmt(pPreStmt);
dan4a4c11a2009-10-06 14:59:02 +00001423 }else{
1424 /* Add the prepared statement to the beginning of the cache list. */
1425 pPreStmt->pNext = pDb->stmtList;
1426 pPreStmt->pPrev = 0;
1427 if( pDb->stmtList ){
1428 pDb->stmtList->pPrev = pPreStmt;
1429 }
1430 pDb->stmtList = pPreStmt;
1431 if( pDb->stmtLast==0 ){
1432 assert( pDb->nStmt==0 );
1433 pDb->stmtLast = pPreStmt;
1434 }else{
1435 assert( pDb->nStmt>0 );
1436 }
1437 pDb->nStmt++;
mistachkinb56660f2016-07-14 21:26:09 +00001438
1439 /* If we have too many statement in cache, remove the surplus from
dan4a4c11a2009-10-06 14:59:02 +00001440 ** the end of the cache list. */
1441 while( pDb->nStmt>pDb->maxStmt ){
danc431fd52011-06-27 16:55:50 +00001442 SqlPreparedStmt *pLast = pDb->stmtLast;
1443 pDb->stmtLast = pLast->pPrev;
dan4a4c11a2009-10-06 14:59:02 +00001444 pDb->stmtLast->pNext = 0;
1445 pDb->nStmt--;
danc431fd52011-06-27 16:55:50 +00001446 dbFreeStmt(pLast);
dan4a4c11a2009-10-06 14:59:02 +00001447 }
1448 }
1449}
1450
1451/*
1452** Structure used with dbEvalXXX() functions:
1453**
1454** dbEvalInit()
1455** dbEvalStep()
1456** dbEvalFinalize()
1457** dbEvalRowInfo()
1458** dbEvalColumnValue()
1459*/
1460typedef struct DbEvalContext DbEvalContext;
1461struct DbEvalContext {
1462 SqliteDb *pDb; /* Database handle */
1463 Tcl_Obj *pSql; /* Object holding string zSql */
1464 const char *zSql; /* Remaining SQL to execute */
1465 SqlPreparedStmt *pPreStmt; /* Current statement */
1466 int nCol; /* Number of columns returned by pStmt */
drhaf38cdb2017-06-26 21:08:32 +00001467 int evalFlags; /* Flags used */
dan4a4c11a2009-10-06 14:59:02 +00001468 Tcl_Obj *pArray; /* Name of array variable */
1469 Tcl_Obj **apColName; /* Array of column names */
1470};
1471
drhaf38cdb2017-06-26 21:08:32 +00001472#define SQLITE_EVAL_WITHOUTNULLS 0x00001 /* Unset array(*) for NULL */
1473
dan4a4c11a2009-10-06 14:59:02 +00001474/*
1475** Release any cache of column names currently held as part of
1476** the DbEvalContext structure passed as the first argument.
1477*/
1478static void dbReleaseColumnNames(DbEvalContext *p){
1479 if( p->apColName ){
1480 int i;
1481 for(i=0; i<p->nCol; i++){
1482 Tcl_DecrRefCount(p->apColName[i]);
1483 }
1484 Tcl_Free((char *)p->apColName);
1485 p->apColName = 0;
1486 }
1487 p->nCol = 0;
1488}
1489
1490/*
1491** Initialize a DbEvalContext structure.
danielk19778e556522007-11-13 10:30:24 +00001492**
1493** If pArray is not NULL, then it contains the name of a Tcl array
1494** variable. The "*" member of this array is set to a list containing
dan4a4c11a2009-10-06 14:59:02 +00001495** the names of the columns returned by the statement as part of each
mistachkinb56660f2016-07-14 21:26:09 +00001496** call to dbEvalStep(), in order from left to right. e.g. if the names
1497** of the returned columns are a, b and c, it does the equivalent of the
dan4a4c11a2009-10-06 14:59:02 +00001498** tcl command:
danielk19778e556522007-11-13 10:30:24 +00001499**
1500** set ${pArray}(*) {a b c}
1501*/
dan4a4c11a2009-10-06 14:59:02 +00001502static void dbEvalInit(
1503 DbEvalContext *p, /* Pointer to structure to initialize */
1504 SqliteDb *pDb, /* Database handle */
1505 Tcl_Obj *pSql, /* Object containing SQL script */
drhaf38cdb2017-06-26 21:08:32 +00001506 Tcl_Obj *pArray, /* Name of Tcl array to set (*) element of */
1507 int evalFlags /* Flags controlling evaluation */
danielk19778e556522007-11-13 10:30:24 +00001508){
dan4a4c11a2009-10-06 14:59:02 +00001509 memset(p, 0, sizeof(DbEvalContext));
1510 p->pDb = pDb;
1511 p->zSql = Tcl_GetString(pSql);
1512 p->pSql = pSql;
1513 Tcl_IncrRefCount(pSql);
1514 if( pArray ){
1515 p->pArray = pArray;
1516 Tcl_IncrRefCount(pArray);
1517 }
drhaf38cdb2017-06-26 21:08:32 +00001518 p->evalFlags = evalFlags;
dan4a4c11a2009-10-06 14:59:02 +00001519}
danielk19778e556522007-11-13 10:30:24 +00001520
dan4a4c11a2009-10-06 14:59:02 +00001521/*
1522** Obtain information about the row that the DbEvalContext passed as the
1523** first argument currently points to.
1524*/
1525static void dbEvalRowInfo(
1526 DbEvalContext *p, /* Evaluation context */
1527 int *pnCol, /* OUT: Number of column names */
1528 Tcl_Obj ***papColName /* OUT: Array of column names */
1529){
danielk19778e556522007-11-13 10:30:24 +00001530 /* Compute column names */
dan4a4c11a2009-10-06 14:59:02 +00001531 if( 0==p->apColName ){
1532 sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
1533 int i; /* Iterator variable */
1534 int nCol; /* Number of columns returned by pStmt */
1535 Tcl_Obj **apColName = 0; /* Array of column names */
1536
1537 p->nCol = nCol = sqlite3_column_count(pStmt);
1538 if( nCol>0 && (papColName || p->pArray) ){
1539 apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
1540 for(i=0; i<nCol; i++){
drhc45e6712012-10-03 11:02:33 +00001541 apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
dan4a4c11a2009-10-06 14:59:02 +00001542 Tcl_IncrRefCount(apColName[i]);
1543 }
1544 p->apColName = apColName;
danielk19778e556522007-11-13 10:30:24 +00001545 }
1546
1547 /* If results are being stored in an array variable, then create
1548 ** the array(*) entry for that array
1549 */
dan4a4c11a2009-10-06 14:59:02 +00001550 if( p->pArray ){
1551 Tcl_Interp *interp = p->pDb->interp;
danielk19778e556522007-11-13 10:30:24 +00001552 Tcl_Obj *pColList = Tcl_NewObj();
1553 Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
dan4a4c11a2009-10-06 14:59:02 +00001554
danielk19778e556522007-11-13 10:30:24 +00001555 for(i=0; i<nCol; i++){
1556 Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
1557 }
1558 Tcl_IncrRefCount(pStar);
dan4a4c11a2009-10-06 14:59:02 +00001559 Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0);
danielk19778e556522007-11-13 10:30:24 +00001560 Tcl_DecrRefCount(pStar);
1561 }
danielk19778e556522007-11-13 10:30:24 +00001562 }
1563
dan4a4c11a2009-10-06 14:59:02 +00001564 if( papColName ){
1565 *papColName = p->apColName;
1566 }
1567 if( pnCol ){
1568 *pnCol = p->nCol;
1569 }
1570}
1571
1572/*
1573** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is
1574** returned, then an error message is stored in the interpreter before
1575** returning.
1576**
1577** A return value of TCL_OK means there is a row of data available. The
1578** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
1579** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK
1580** is returned, then the SQL script has finished executing and there are
1581** no further rows available. This is similar to SQLITE_DONE.
1582*/
1583static int dbEvalStep(DbEvalContext *p){
danc431fd52011-06-27 16:55:50 +00001584 const char *zPrevSql = 0; /* Previous value of p->zSql */
1585
dan4a4c11a2009-10-06 14:59:02 +00001586 while( p->zSql[0] || p->pPreStmt ){
1587 int rc;
1588 if( p->pPreStmt==0 ){
danc431fd52011-06-27 16:55:50 +00001589 zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
dan4a4c11a2009-10-06 14:59:02 +00001590 rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
1591 if( rc!=TCL_OK ) return rc;
1592 }else{
1593 int rcs;
1594 SqliteDb *pDb = p->pDb;
1595 SqlPreparedStmt *pPreStmt = p->pPreStmt;
1596 sqlite3_stmt *pStmt = pPreStmt->pStmt;
1597
1598 rcs = sqlite3_step(pStmt);
1599 if( rcs==SQLITE_ROW ){
1600 return TCL_OK;
1601 }
1602 if( p->pArray ){
1603 dbEvalRowInfo(p, 0, 0);
1604 }
1605 rcs = sqlite3_reset(pStmt);
1606
1607 pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
1608 pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
drh3c379b02010-04-07 19:31:59 +00001609 pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
danc456a762017-06-22 16:51:16 +00001610 pDb->nVMStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_VM_STEP,1);
dan4a4c11a2009-10-06 14:59:02 +00001611 dbReleaseColumnNames(p);
1612 p->pPreStmt = 0;
1613
1614 if( rcs!=SQLITE_OK ){
1615 /* If a run-time error occurs, report the error and stop reading
1616 ** the SQL. */
dan4a4c11a2009-10-06 14:59:02 +00001617 dbReleaseStmt(pDb, pPreStmt, 1);
danc431fd52011-06-27 16:55:50 +00001618#if SQLITE_TEST
1619 if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
1620 /* If the runtime error was an SQLITE_SCHEMA, and the database
mistachkinb56660f2016-07-14 21:26:09 +00001621 ** handle is configured to use the legacy sqlite3_prepare()
danc431fd52011-06-27 16:55:50 +00001622 ** interface, retry prepare()/step() on the same SQL statement.
1623 ** This only happens once. If there is a second SQLITE_SCHEMA
1624 ** error, the error will be returned to the caller. */
1625 p->zSql = zPrevSql;
1626 continue;
1627 }
1628#endif
drhc45e6712012-10-03 11:02:33 +00001629 Tcl_SetObjResult(pDb->interp,
1630 Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
dan4a4c11a2009-10-06 14:59:02 +00001631 return TCL_ERROR;
1632 }else{
1633 dbReleaseStmt(pDb, pPreStmt, 0);
1634 }
1635 }
1636 }
1637
1638 /* Finished */
1639 return TCL_BREAK;
1640}
1641
1642/*
1643** Free all resources currently held by the DbEvalContext structure passed
1644** as the first argument. There should be exactly one call to this function
1645** for each call to dbEvalInit().
1646*/
1647static void dbEvalFinalize(DbEvalContext *p){
1648 if( p->pPreStmt ){
1649 sqlite3_reset(p->pPreStmt->pStmt);
1650 dbReleaseStmt(p->pDb, p->pPreStmt, 0);
1651 p->pPreStmt = 0;
1652 }
1653 if( p->pArray ){
1654 Tcl_DecrRefCount(p->pArray);
1655 p->pArray = 0;
1656 }
1657 Tcl_DecrRefCount(p->pSql);
1658 dbReleaseColumnNames(p);
1659}
1660
1661/*
1662** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
1663** the value for the iCol'th column of the row currently pointed to by
1664** the DbEvalContext structure passed as the first argument.
1665*/
1666static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
1667 sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
1668 switch( sqlite3_column_type(pStmt, iCol) ){
1669 case SQLITE_BLOB: {
1670 int bytes = sqlite3_column_bytes(pStmt, iCol);
1671 const char *zBlob = sqlite3_column_blob(pStmt, iCol);
1672 if( !zBlob ) bytes = 0;
1673 return Tcl_NewByteArrayObj((u8*)zBlob, bytes);
1674 }
1675 case SQLITE_INTEGER: {
1676 sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
1677 if( v>=-2147483647 && v<=2147483647 ){
drh7fd33922011-06-20 19:00:30 +00001678 return Tcl_NewIntObj((int)v);
dan4a4c11a2009-10-06 14:59:02 +00001679 }else{
1680 return Tcl_NewWideIntObj(v);
1681 }
1682 }
1683 case SQLITE_FLOAT: {
1684 return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
1685 }
1686 case SQLITE_NULL: {
drhc45e6712012-10-03 11:02:33 +00001687 return Tcl_NewStringObj(p->pDb->zNull, -1);
dan4a4c11a2009-10-06 14:59:02 +00001688 }
1689 }
1690
drh325eff52012-10-03 12:56:18 +00001691 return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
dan4a4c11a2009-10-06 14:59:02 +00001692}
1693
1694/*
1695** If using Tcl version 8.6 or greater, use the NR functions to avoid
1696** recursive evalution of scripts by the [db eval] and [db trans]
1697** commands. Even if the headers used while compiling the extension
1698** are 8.6 or newer, the code still tests the Tcl version at runtime.
1699** This allows stubs-enabled builds to be used with older Tcl libraries.
1700*/
1701#if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6)
drha2c8a952009-10-13 18:38:34 +00001702# define SQLITE_TCL_NRE 1
dan4a4c11a2009-10-06 14:59:02 +00001703static int DbUseNre(void){
1704 int major, minor;
1705 Tcl_GetVersion(&major, &minor, 0, 0);
1706 return( (major==8 && minor>=6) || major>8 );
1707}
1708#else
mistachkinb56660f2016-07-14 21:26:09 +00001709/*
dan4a4c11a2009-10-06 14:59:02 +00001710** Compiling using headers earlier than 8.6. In this case NR cannot be
1711** used, so DbUseNre() to always return zero. Add #defines for the other
1712** Tcl_NRxxx() functions to prevent them from causing compilation errors,
mistachkinb56660f2016-07-14 21:26:09 +00001713** even though the only invocations of them are within conditional blocks
dan4a4c11a2009-10-06 14:59:02 +00001714** of the form:
1715**
1716** if( DbUseNre() ) { ... }
1717*/
drha2c8a952009-10-13 18:38:34 +00001718# define SQLITE_TCL_NRE 0
dan4a4c11a2009-10-06 14:59:02 +00001719# define DbUseNre() 0
drha47941f2013-12-20 18:57:44 +00001720# define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0
dan4a4c11a2009-10-06 14:59:02 +00001721# define Tcl_NREvalObj(a,b,c) 0
drha47941f2013-12-20 18:57:44 +00001722# define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0
dan4a4c11a2009-10-06 14:59:02 +00001723#endif
1724
1725/*
1726** This function is part of the implementation of the command:
1727**
1728** $db eval SQL ?ARRAYNAME? SCRIPT
1729*/
mistachkina121cc72016-07-28 18:06:52 +00001730static int SQLITE_TCLAPI DbEvalNextCmd(
dan4a4c11a2009-10-06 14:59:02 +00001731 ClientData data[], /* data[0] is the (DbEvalContext*) */
1732 Tcl_Interp *interp, /* Tcl interpreter */
1733 int result /* Result so far */
1734){
1735 int rc = result; /* Return code */
1736
1737 /* The first element of the data[] array is a pointer to a DbEvalContext
1738 ** structure allocated using Tcl_Alloc(). The second element of data[]
1739 ** is a pointer to a Tcl_Obj containing the script to run for each row
1740 ** returned by the queries encapsulated in data[0]. */
1741 DbEvalContext *p = (DbEvalContext *)data[0];
1742 Tcl_Obj *pScript = (Tcl_Obj *)data[1];
1743 Tcl_Obj *pArray = p->pArray;
1744
1745 while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){
1746 int i;
1747 int nCol;
1748 Tcl_Obj **apColName;
1749 dbEvalRowInfo(p, &nCol, &apColName);
1750 for(i=0; i<nCol; i++){
dan4a4c11a2009-10-06 14:59:02 +00001751 if( pArray==0 ){
drhaf38cdb2017-06-26 21:08:32 +00001752 Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0);
1753 }else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0
1754 && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL
1755 ){
1756 Tcl_UnsetVar2(interp, Tcl_GetString(pArray),
1757 Tcl_GetString(apColName[i]), 0);
dan4a4c11a2009-10-06 14:59:02 +00001758 }else{
drhaf38cdb2017-06-26 21:08:32 +00001759 Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0);
dan4a4c11a2009-10-06 14:59:02 +00001760 }
1761 }
1762
mistachkinb56660f2016-07-14 21:26:09 +00001763 /* The required interpreter variables are now populated with the data
dan4a4c11a2009-10-06 14:59:02 +00001764 ** from the current row. If using NRE, schedule callbacks to evaluate
1765 ** script pScript, then to invoke this function again to fetch the next
1766 ** row (or clean up if there is no next row or the script throws an
mistachkinb56660f2016-07-14 21:26:09 +00001767 ** exception). After scheduling the callbacks, return control to the
dan4a4c11a2009-10-06 14:59:02 +00001768 ** caller.
1769 **
1770 ** If not using NRE, evaluate pScript directly and continue with the
1771 ** next iteration of this while(...) loop. */
1772 if( DbUseNre() ){
1773 Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0);
1774 return Tcl_NREvalObj(interp, pScript, 0);
1775 }else{
1776 rc = Tcl_EvalObjEx(interp, pScript, 0);
1777 }
1778 }
1779
1780 Tcl_DecrRefCount(pScript);
1781 dbEvalFinalize(p);
1782 Tcl_Free((char *)p);
1783
1784 if( rc==TCL_OK || rc==TCL_BREAK ){
1785 Tcl_ResetResult(interp);
1786 rc = TCL_OK;
1787 }
1788 return rc;
danielk19778e556522007-11-13 10:30:24 +00001789}
1790
tpoindex1067fe12004-12-17 15:41:11 +00001791/*
mistachkinb56660f2016-07-14 21:26:09 +00001792** This function is used by the implementations of the following database
dan46c47d42011-03-01 18:42:07 +00001793** handle sub-commands:
1794**
1795** $db update_hook ?SCRIPT?
1796** $db wal_hook ?SCRIPT?
1797** $db commit_hook ?SCRIPT?
1798** $db preupdate hook ?SCRIPT?
1799*/
1800static void DbHookCmd(
1801 Tcl_Interp *interp, /* Tcl interpreter */
1802 SqliteDb *pDb, /* Database handle */
1803 Tcl_Obj *pArg, /* SCRIPT argument (or NULL) */
1804 Tcl_Obj **ppHook /* Pointer to member of SqliteDb */
1805){
1806 sqlite3 *db = pDb->db;
1807
1808 if( *ppHook ){
1809 Tcl_SetObjResult(interp, *ppHook);
1810 if( pArg ){
1811 Tcl_DecrRefCount(*ppHook);
1812 *ppHook = 0;
1813 }
1814 }
1815 if( pArg ){
1816 assert( !(*ppHook) );
1817 if( Tcl_GetCharLength(pArg)>0 ){
1818 *ppHook = pArg;
1819 Tcl_IncrRefCount(*ppHook);
1820 }
1821 }
1822
drh9b1c62d2011-03-30 21:04:43 +00001823#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
dan46c47d42011-03-01 18:42:07 +00001824 sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb);
drh9b1c62d2011-03-30 21:04:43 +00001825#endif
dan46c47d42011-03-01 18:42:07 +00001826 sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
1827 sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb);
1828 sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb);
1829}
1830
1831/*
drh75897232000-05-29 14:26:00 +00001832** The "sqlite" command below creates a new Tcl command for each
1833** connection it opens to an SQLite database. This routine is invoked
1834** whenever one of those connection-specific commands is executed
1835** in Tcl. For example, if you run Tcl code like this:
1836**
drh9bb575f2004-09-06 17:24:11 +00001837** sqlite3 db1 "my_database"
drh75897232000-05-29 14:26:00 +00001838** db1 close
1839**
1840** The first command opens a connection to the "my_database" database
1841** and calls that connection "db1". The second command causes this
1842** subroutine to be invoked.
1843*/
mistachkin7617e4a2016-07-28 17:11:20 +00001844static int SQLITE_TCLAPI DbObjCmd(
1845 void *cd,
1846 Tcl_Interp *interp,
1847 int objc,
1848 Tcl_Obj *const*objv
1849){
drhbec3f402000-08-04 13:49:02 +00001850 SqliteDb *pDb = (SqliteDb*)cd;
drh6d313162000-09-21 13:01:35 +00001851 int choice;
drh22fbcb82004-02-01 01:22:50 +00001852 int rc = TCL_OK;
drh0de8c112002-07-06 16:32:14 +00001853 static const char *DB_strs[] = {
drhcb7d5412018-01-03 16:49:52 +00001854 "authorizer", "backup", "busy",
1855 "cache", "changes", "close",
1856 "collate", "collation_needed", "commit_hook",
1857 "complete", "copy", "deserialize",
1858 "enable_load_extension", "errorcode", "eval",
1859 "exists", "function", "incrblob",
drh3ec86652018-01-03 19:03:31 +00001860 "interrupt", "last_insert_rowid", "nullvalue",
1861 "onecolumn", "preupdate", "profile",
1862 "progress", "rekey", "restore",
1863 "rollback_hook", "serialize", "status",
1864 "timeout", "total_changes", "trace",
1865 "trace_v2", "transaction", "unlock_notify",
1866 "update_hook", "version", "wal_hook",
1867 0
drh6d313162000-09-21 13:01:35 +00001868 };
drh411995d2002-06-25 19:31:18 +00001869 enum DB_enum {
drhcb7d5412018-01-03 16:49:52 +00001870 DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
1871 DB_CACHE, DB_CHANGES, DB_CLOSE,
1872 DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
1873 DB_COMPLETE, DB_COPY, DB_DESERIALIZE,
1874 DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL,
1875 DB_EXISTS, DB_FUNCTION, DB_INCRBLOB,
drh3ec86652018-01-03 19:03:31 +00001876 DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE,
1877 DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE,
1878 DB_PROGRESS, DB_REKEY, DB_RESTORE,
1879 DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS,
1880 DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
1881 DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
1882 DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK
drh6d313162000-09-21 13:01:35 +00001883 };
tpoindex1067fe12004-12-17 15:41:11 +00001884 /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
drh6d313162000-09-21 13:01:35 +00001885
1886 if( objc<2 ){
1887 Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
drh75897232000-05-29 14:26:00 +00001888 return TCL_ERROR;
1889 }
drh411995d2002-06-25 19:31:18 +00001890 if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
drh6d313162000-09-21 13:01:35 +00001891 return TCL_ERROR;
1892 }
1893
drh411995d2002-06-25 19:31:18 +00001894 switch( (enum DB_enum)choice ){
drh75897232000-05-29 14:26:00 +00001895
drhe22a3342003-04-22 20:30:37 +00001896 /* $db authorizer ?CALLBACK?
1897 **
1898 ** Invoke the given callback to authorize each SQL operation as it is
1899 ** compiled. 5 arguments are appended to the callback before it is
1900 ** invoked:
1901 **
1902 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
1903 ** (2) First descriptive name (depends on authorization type)
1904 ** (3) Second descriptive name
1905 ** (4) Name of the database (ex: "main", "temp")
1906 ** (5) Name of trigger that is doing the access
1907 **
1908 ** The callback should return on of the following strings: SQLITE_OK,
1909 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error.
1910 **
1911 ** If this method is invoked with no arguments, the current authorization
1912 ** callback string is returned.
1913 */
1914 case DB_AUTHORIZER: {
drh1211de32004-07-26 12:24:22 +00001915#ifdef SQLITE_OMIT_AUTHORIZATION
drha198f2b2014-02-07 19:26:13 +00001916 Tcl_AppendResult(interp, "authorization not available in this build",
1917 (char*)0);
drh1211de32004-07-26 12:24:22 +00001918 return TCL_ERROR;
1919#else
drhe22a3342003-04-22 20:30:37 +00001920 if( objc>3 ){
1921 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
drh0f14e2e2004-06-29 12:39:08 +00001922 return TCL_ERROR;
drhe22a3342003-04-22 20:30:37 +00001923 }else if( objc==2 ){
drhb5a20d32003-04-23 12:25:23 +00001924 if( pDb->zAuth ){
drha198f2b2014-02-07 19:26:13 +00001925 Tcl_AppendResult(interp, pDb->zAuth, (char*)0);
drhe22a3342003-04-22 20:30:37 +00001926 }
1927 }else{
1928 char *zAuth;
1929 int len;
1930 if( pDb->zAuth ){
1931 Tcl_Free(pDb->zAuth);
1932 }
1933 zAuth = Tcl_GetStringFromObj(objv[2], &len);
1934 if( zAuth && len>0 ){
1935 pDb->zAuth = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00001936 memcpy(pDb->zAuth, zAuth, len+1);
drhe22a3342003-04-22 20:30:37 +00001937 }else{
1938 pDb->zAuth = 0;
1939 }
drhe22a3342003-04-22 20:30:37 +00001940 if( pDb->zAuth ){
drh32c6a482014-09-11 13:44:52 +00001941 typedef int (*sqlite3_auth_cb)(
1942 void*,int,const char*,const char*,
1943 const char*,const char*);
drhe22a3342003-04-22 20:30:37 +00001944 pDb->interp = interp;
drh32c6a482014-09-11 13:44:52 +00001945 sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb);
drhe22a3342003-04-22 20:30:37 +00001946 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001947 sqlite3_set_authorizer(pDb->db, 0, 0);
drhe22a3342003-04-22 20:30:37 +00001948 }
drhe22a3342003-04-22 20:30:37 +00001949 }
drh1211de32004-07-26 12:24:22 +00001950#endif
drhe22a3342003-04-22 20:30:37 +00001951 break;
1952 }
1953
drhdc2c4912009-02-04 22:46:47 +00001954 /* $db backup ?DATABASE? FILENAME
1955 **
1956 ** Open or create a database file named FILENAME. Transfer the
1957 ** content of local database DATABASE (default: "main") into the
1958 ** FILENAME database.
1959 */
1960 case DB_BACKUP: {
1961 const char *zDestFile;
1962 const char *zSrcDb;
1963 sqlite3 *pDest;
1964 sqlite3_backup *pBackup;
1965
1966 if( objc==3 ){
1967 zSrcDb = "main";
1968 zDestFile = Tcl_GetString(objv[2]);
1969 }else if( objc==4 ){
1970 zSrcDb = Tcl_GetString(objv[2]);
1971 zDestFile = Tcl_GetString(objv[3]);
1972 }else{
1973 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
1974 return TCL_ERROR;
1975 }
drh147ef392016-01-22 23:17:51 +00001976 rc = sqlite3_open_v2(zDestFile, &pDest,
1977 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0);
drhdc2c4912009-02-04 22:46:47 +00001978 if( rc!=SQLITE_OK ){
1979 Tcl_AppendResult(interp, "cannot open target database: ",
1980 sqlite3_errmsg(pDest), (char*)0);
1981 sqlite3_close(pDest);
1982 return TCL_ERROR;
1983 }
1984 pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
1985 if( pBackup==0 ){
1986 Tcl_AppendResult(interp, "backup failed: ",
1987 sqlite3_errmsg(pDest), (char*)0);
1988 sqlite3_close(pDest);
1989 return TCL_ERROR;
1990 }
1991 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1992 sqlite3_backup_finish(pBackup);
1993 if( rc==SQLITE_DONE ){
1994 rc = TCL_OK;
1995 }else{
1996 Tcl_AppendResult(interp, "backup failed: ",
1997 sqlite3_errmsg(pDest), (char*)0);
1998 rc = TCL_ERROR;
1999 }
2000 sqlite3_close(pDest);
2001 break;
2002 }
2003
drhbec3f402000-08-04 13:49:02 +00002004 /* $db busy ?CALLBACK?
2005 **
2006 ** Invoke the given callback if an SQL statement attempts to open
2007 ** a locked database file.
2008 */
drh6d313162000-09-21 13:01:35 +00002009 case DB_BUSY: {
2010 if( objc>3 ){
2011 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
drhbec3f402000-08-04 13:49:02 +00002012 return TCL_ERROR;
drh6d313162000-09-21 13:01:35 +00002013 }else if( objc==2 ){
drhbec3f402000-08-04 13:49:02 +00002014 if( pDb->zBusy ){
drha198f2b2014-02-07 19:26:13 +00002015 Tcl_AppendResult(interp, pDb->zBusy, (char*)0);
drhbec3f402000-08-04 13:49:02 +00002016 }
2017 }else{
drh6d313162000-09-21 13:01:35 +00002018 char *zBusy;
2019 int len;
drhbec3f402000-08-04 13:49:02 +00002020 if( pDb->zBusy ){
2021 Tcl_Free(pDb->zBusy);
drhbec3f402000-08-04 13:49:02 +00002022 }
drh6d313162000-09-21 13:01:35 +00002023 zBusy = Tcl_GetStringFromObj(objv[2], &len);
2024 if( zBusy && len>0 ){
2025 pDb->zBusy = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00002026 memcpy(pDb->zBusy, zBusy, len+1);
drh6d313162000-09-21 13:01:35 +00002027 }else{
2028 pDb->zBusy = 0;
drhbec3f402000-08-04 13:49:02 +00002029 }
2030 if( pDb->zBusy ){
2031 pDb->interp = interp;
danielk19776f8a5032004-05-10 10:34:51 +00002032 sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
drh6d313162000-09-21 13:01:35 +00002033 }else{
danielk19776f8a5032004-05-10 10:34:51 +00002034 sqlite3_busy_handler(pDb->db, 0, 0);
drhbec3f402000-08-04 13:49:02 +00002035 }
2036 }
drh6d313162000-09-21 13:01:35 +00002037 break;
2038 }
drhbec3f402000-08-04 13:49:02 +00002039
drhfb7e7652005-01-24 00:28:42 +00002040 /* $db cache flush
2041 ** $db cache size n
2042 **
2043 ** Flush the prepared statement cache, or set the maximum number of
2044 ** cached statements.
2045 */
2046 case DB_CACHE: {
2047 char *subCmd;
2048 int n;
2049
2050 if( objc<=2 ){
2051 Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
2052 return TCL_ERROR;
2053 }
2054 subCmd = Tcl_GetStringFromObj( objv[2], 0 );
2055 if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
2056 if( objc!=3 ){
2057 Tcl_WrongNumArgs(interp, 2, objv, "flush");
2058 return TCL_ERROR;
2059 }else{
2060 flushStmtCache( pDb );
2061 }
2062 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
2063 if( objc!=4 ){
2064 Tcl_WrongNumArgs(interp, 2, objv, "size n");
2065 return TCL_ERROR;
2066 }else{
2067 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
mistachkinb56660f2016-07-14 21:26:09 +00002068 Tcl_AppendResult( interp, "cannot convert \"",
drha198f2b2014-02-07 19:26:13 +00002069 Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
drhfb7e7652005-01-24 00:28:42 +00002070 return TCL_ERROR;
2071 }else{
2072 if( n<0 ){
2073 flushStmtCache( pDb );
2074 n = 0;
2075 }else if( n>MAX_PREPARED_STMTS ){
2076 n = MAX_PREPARED_STMTS;
2077 }
2078 pDb->maxStmt = n;
2079 }
2080 }
2081 }else{
mistachkinb56660f2016-07-14 21:26:09 +00002082 Tcl_AppendResult( interp, "bad option \"",
drha198f2b2014-02-07 19:26:13 +00002083 Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
2084 (char*)0);
drhfb7e7652005-01-24 00:28:42 +00002085 return TCL_ERROR;
2086 }
2087 break;
2088 }
2089
danielk1977b28af712004-06-21 06:50:26 +00002090 /* $db changes
drhc8d30ac2002-04-12 10:08:59 +00002091 **
2092 ** Return the number of rows that were modified, inserted, or deleted by
mistachkinb56660f2016-07-14 21:26:09 +00002093 ** the most recent INSERT, UPDATE or DELETE statement, not including
danielk1977b28af712004-06-21 06:50:26 +00002094 ** any changes made by trigger programs.
drhc8d30ac2002-04-12 10:08:59 +00002095 */
2096 case DB_CHANGES: {
2097 Tcl_Obj *pResult;
drhc8d30ac2002-04-12 10:08:59 +00002098 if( objc!=2 ){
2099 Tcl_WrongNumArgs(interp, 2, objv, "");
2100 return TCL_ERROR;
2101 }
drhc8d30ac2002-04-12 10:08:59 +00002102 pResult = Tcl_GetObjResult(interp);
danielk1977b28af712004-06-21 06:50:26 +00002103 Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
rdcf146a772004-02-25 22:51:06 +00002104 break;
2105 }
2106
drh75897232000-05-29 14:26:00 +00002107 /* $db close
2108 **
2109 ** Shutdown the database
2110 */
drh6d313162000-09-21 13:01:35 +00002111 case DB_CLOSE: {
2112 Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
2113 break;
2114 }
drh75897232000-05-29 14:26:00 +00002115
drh0f14e2e2004-06-29 12:39:08 +00002116 /*
2117 ** $db collate NAME SCRIPT
2118 **
2119 ** Create a new SQL collation function called NAME. Whenever
2120 ** that function is called, invoke SCRIPT to evaluate the function.
2121 */
2122 case DB_COLLATE: {
2123 SqlCollate *pCollate;
2124 char *zName;
2125 char *zScript;
2126 int nScript;
2127 if( objc!=4 ){
2128 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
2129 return TCL_ERROR;
2130 }
2131 zName = Tcl_GetStringFromObj(objv[2], 0);
2132 zScript = Tcl_GetStringFromObj(objv[3], &nScript);
2133 pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
2134 if( pCollate==0 ) return TCL_ERROR;
2135 pCollate->interp = interp;
2136 pCollate->pNext = pDb->pCollate;
2137 pCollate->zScript = (char*)&pCollate[1];
2138 pDb->pCollate = pCollate;
drh5bb3eb92007-05-04 13:15:55 +00002139 memcpy(pCollate->zScript, zScript, nScript+1);
mistachkinb56660f2016-07-14 21:26:09 +00002140 if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
drh0f14e2e2004-06-29 12:39:08 +00002141 pCollate, tclSqlCollate) ){
danielk19779636c4e2005-01-25 04:27:54 +00002142 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
drh0f14e2e2004-06-29 12:39:08 +00002143 return TCL_ERROR;
2144 }
2145 break;
2146 }
2147
2148 /*
2149 ** $db collation_needed SCRIPT
2150 **
2151 ** Create a new SQL collation function called NAME. Whenever
2152 ** that function is called, invoke SCRIPT to evaluate the function.
2153 */
2154 case DB_COLLATION_NEEDED: {
2155 if( objc!=3 ){
2156 Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
2157 return TCL_ERROR;
2158 }
2159 if( pDb->pCollateNeeded ){
2160 Tcl_DecrRefCount(pDb->pCollateNeeded);
2161 }
2162 pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
2163 Tcl_IncrRefCount(pDb->pCollateNeeded);
2164 sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
2165 break;
2166 }
2167
drh19e2d372005-08-29 23:00:03 +00002168 /* $db commit_hook ?CALLBACK?
2169 **
2170 ** Invoke the given callback just before committing every SQL transaction.
2171 ** If the callback throws an exception or returns non-zero, then the
2172 ** transaction is aborted. If CALLBACK is an empty string, the callback
2173 ** is disabled.
2174 */
2175 case DB_COMMIT_HOOK: {
2176 if( objc>3 ){
2177 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
2178 return TCL_ERROR;
2179 }else if( objc==2 ){
2180 if( pDb->zCommit ){
drha198f2b2014-02-07 19:26:13 +00002181 Tcl_AppendResult(interp, pDb->zCommit, (char*)0);
drh19e2d372005-08-29 23:00:03 +00002182 }
2183 }else{
mistachkin6ef5e122014-01-24 17:03:55 +00002184 const char *zCommit;
drh19e2d372005-08-29 23:00:03 +00002185 int len;
2186 if( pDb->zCommit ){
2187 Tcl_Free(pDb->zCommit);
2188 }
2189 zCommit = Tcl_GetStringFromObj(objv[2], &len);
2190 if( zCommit && len>0 ){
2191 pDb->zCommit = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00002192 memcpy(pDb->zCommit, zCommit, len+1);
drh19e2d372005-08-29 23:00:03 +00002193 }else{
2194 pDb->zCommit = 0;
2195 }
2196 if( pDb->zCommit ){
2197 pDb->interp = interp;
2198 sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
2199 }else{
2200 sqlite3_commit_hook(pDb->db, 0, 0);
2201 }
2202 }
2203 break;
2204 }
2205
drh75897232000-05-29 14:26:00 +00002206 /* $db complete SQL
2207 **
2208 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if
2209 ** additional lines of input are needed. This is similar to the
2210 ** built-in "info complete" command of Tcl.
2211 */
drh6d313162000-09-21 13:01:35 +00002212 case DB_COMPLETE: {
drhccae6022005-02-26 17:31:26 +00002213#ifndef SQLITE_OMIT_COMPLETE
drh6d313162000-09-21 13:01:35 +00002214 Tcl_Obj *pResult;
2215 int isComplete;
2216 if( objc!=3 ){
2217 Tcl_WrongNumArgs(interp, 2, objv, "SQL");
drh75897232000-05-29 14:26:00 +00002218 return TCL_ERROR;
2219 }
danielk19776f8a5032004-05-10 10:34:51 +00002220 isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
drh6d313162000-09-21 13:01:35 +00002221 pResult = Tcl_GetObjResult(interp);
2222 Tcl_SetBooleanObj(pResult, isComplete);
drhccae6022005-02-26 17:31:26 +00002223#endif
drh6d313162000-09-21 13:01:35 +00002224 break;
2225 }
drhdcd997e2003-01-31 17:21:49 +00002226
drh19e2d372005-08-29 23:00:03 +00002227 /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
2228 **
2229 ** Copy data into table from filename, optionally using SEPARATOR
2230 ** as column separators. If a column contains a null string, or the
2231 ** value of NULLINDICATOR, a NULL is inserted for the column.
2232 ** conflict-algorithm is one of the sqlite conflict algorithms:
2233 ** rollback, abort, fail, ignore, replace
2234 ** On success, return the number of lines processed, not necessarily same
2235 ** as 'db changes' due to conflict-algorithm selected.
2236 **
2237 ** This code is basically an implementation/enhancement of
2238 ** the sqlite3 shell.c ".import" command.
2239 **
2240 ** This command usage is equivalent to the sqlite2.x COPY statement,
2241 ** which imports file data into a table using the PostgreSQL COPY file format:
2242 ** $db copy $conflit_algo $table_name $filename \t \\N
2243 */
2244 case DB_COPY: {
2245 char *zTable; /* Insert data into this table */
2246 char *zFile; /* The file from which to extract data */
2247 char *zConflict; /* The conflict algorithm to use */
2248 sqlite3_stmt *pStmt; /* A statement */
drh19e2d372005-08-29 23:00:03 +00002249 int nCol; /* Number of columns in the table */
2250 int nByte; /* Number of bytes in an SQL string */
2251 int i, j; /* Loop counters */
2252 int nSep; /* Number of bytes in zSep[] */
2253 int nNull; /* Number of bytes in zNull[] */
2254 char *zSql; /* An SQL statement */
2255 char *zLine; /* A single line of input from the file */
2256 char **azCol; /* zLine[] broken up into columns */
mistachkin6ef5e122014-01-24 17:03:55 +00002257 const char *zCommit; /* How to commit changes */
drh19e2d372005-08-29 23:00:03 +00002258 FILE *in; /* The input file */
2259 int lineno = 0; /* Line number of input file */
2260 char zLineNum[80]; /* Line number print buffer */
2261 Tcl_Obj *pResult; /* interp result */
2262
mistachkin6ef5e122014-01-24 17:03:55 +00002263 const char *zSep;
2264 const char *zNull;
drh19e2d372005-08-29 23:00:03 +00002265 if( objc<5 || objc>7 ){
mistachkinb56660f2016-07-14 21:26:09 +00002266 Tcl_WrongNumArgs(interp, 2, objv,
drh19e2d372005-08-29 23:00:03 +00002267 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
2268 return TCL_ERROR;
2269 }
2270 if( objc>=6 ){
2271 zSep = Tcl_GetStringFromObj(objv[5], 0);
2272 }else{
2273 zSep = "\t";
2274 }
2275 if( objc>=7 ){
2276 zNull = Tcl_GetStringFromObj(objv[6], 0);
2277 }else{
2278 zNull = "";
2279 }
2280 zConflict = Tcl_GetStringFromObj(objv[2], 0);
2281 zTable = Tcl_GetStringFromObj(objv[3], 0);
2282 zFile = Tcl_GetStringFromObj(objv[4], 0);
drh4f21c4a2008-12-10 22:15:00 +00002283 nSep = strlen30(zSep);
2284 nNull = strlen30(zNull);
drh19e2d372005-08-29 23:00:03 +00002285 if( nSep==0 ){
drha198f2b2014-02-07 19:26:13 +00002286 Tcl_AppendResult(interp,"Error: non-null separator required for copy",
2287 (char*)0);
drh19e2d372005-08-29 23:00:03 +00002288 return TCL_ERROR;
2289 }
drh3e59c012008-09-23 10:12:13 +00002290 if(strcmp(zConflict, "rollback") != 0 &&
2291 strcmp(zConflict, "abort" ) != 0 &&
2292 strcmp(zConflict, "fail" ) != 0 &&
2293 strcmp(zConflict, "ignore" ) != 0 &&
2294 strcmp(zConflict, "replace" ) != 0 ) {
mistachkinb56660f2016-07-14 21:26:09 +00002295 Tcl_AppendResult(interp, "Error: \"", zConflict,
drh19e2d372005-08-29 23:00:03 +00002296 "\", conflict-algorithm must be one of: rollback, "
drha198f2b2014-02-07 19:26:13 +00002297 "abort, fail, ignore, or replace", (char*)0);
drh19e2d372005-08-29 23:00:03 +00002298 return TCL_ERROR;
2299 }
2300 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
2301 if( zSql==0 ){
drha198f2b2014-02-07 19:26:13 +00002302 Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0);
drh19e2d372005-08-29 23:00:03 +00002303 return TCL_ERROR;
2304 }
drh4f21c4a2008-12-10 22:15:00 +00002305 nByte = strlen30(zSql);
drh3e701a12007-02-01 01:53:44 +00002306 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
drh19e2d372005-08-29 23:00:03 +00002307 sqlite3_free(zSql);
2308 if( rc ){
drha198f2b2014-02-07 19:26:13 +00002309 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
drh19e2d372005-08-29 23:00:03 +00002310 nCol = 0;
2311 }else{
2312 nCol = sqlite3_column_count(pStmt);
2313 }
2314 sqlite3_finalize(pStmt);
2315 if( nCol==0 ) {
2316 return TCL_ERROR;
2317 }
2318 zSql = malloc( nByte + 50 + nCol*2 );
2319 if( zSql==0 ) {
drha198f2b2014-02-07 19:26:13 +00002320 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
drh19e2d372005-08-29 23:00:03 +00002321 return TCL_ERROR;
2322 }
2323 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
2324 zConflict, zTable);
drh4f21c4a2008-12-10 22:15:00 +00002325 j = strlen30(zSql);
drh19e2d372005-08-29 23:00:03 +00002326 for(i=1; i<nCol; i++){
2327 zSql[j++] = ',';
2328 zSql[j++] = '?';
2329 }
2330 zSql[j++] = ')';
2331 zSql[j] = 0;
drh3e701a12007-02-01 01:53:44 +00002332 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
drh19e2d372005-08-29 23:00:03 +00002333 free(zSql);
2334 if( rc ){
drha198f2b2014-02-07 19:26:13 +00002335 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
drh19e2d372005-08-29 23:00:03 +00002336 sqlite3_finalize(pStmt);
2337 return TCL_ERROR;
2338 }
2339 in = fopen(zFile, "rb");
2340 if( in==0 ){
drhea8f0a12017-01-12 11:50:08 +00002341 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0);
drh19e2d372005-08-29 23:00:03 +00002342 sqlite3_finalize(pStmt);
2343 return TCL_ERROR;
2344 }
2345 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
2346 if( azCol==0 ) {
drha198f2b2014-02-07 19:26:13 +00002347 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
drh43617e92006-03-06 20:55:46 +00002348 fclose(in);
drh19e2d372005-08-29 23:00:03 +00002349 return TCL_ERROR;
2350 }
drh37527852006-03-16 16:19:56 +00002351 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
drh19e2d372005-08-29 23:00:03 +00002352 zCommit = "COMMIT";
2353 while( (zLine = local_getline(0, in))!=0 ){
2354 char *z;
drh19e2d372005-08-29 23:00:03 +00002355 lineno++;
2356 azCol[0] = zLine;
2357 for(i=0, z=zLine; *z; z++){
2358 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
2359 *z = 0;
2360 i++;
2361 if( i<nCol ){
2362 azCol[i] = &z[nSep];
2363 z += nSep-1;
2364 }
2365 }
2366 }
2367 if( i+1!=nCol ){
2368 char *zErr;
drh4f21c4a2008-12-10 22:15:00 +00002369 int nErr = strlen30(zFile) + 200;
drh5bb3eb92007-05-04 13:15:55 +00002370 zErr = malloc(nErr);
drhc1f44942006-05-10 14:39:13 +00002371 if( zErr ){
drh5bb3eb92007-05-04 13:15:55 +00002372 sqlite3_snprintf(nErr, zErr,
drhc1f44942006-05-10 14:39:13 +00002373 "Error: %s line %d: expected %d columns of data but found %d",
2374 zFile, lineno, nCol, i+1);
drha198f2b2014-02-07 19:26:13 +00002375 Tcl_AppendResult(interp, zErr, (char*)0);
drhc1f44942006-05-10 14:39:13 +00002376 free(zErr);
2377 }
drh19e2d372005-08-29 23:00:03 +00002378 zCommit = "ROLLBACK";
2379 break;
2380 }
2381 for(i=0; i<nCol; i++){
2382 /* check for null data, if so, bind as null */
drhea678832008-12-10 19:26:22 +00002383 if( (nNull>0 && strcmp(azCol[i], zNull)==0)
mistachkinb56660f2016-07-14 21:26:09 +00002384 || strlen30(azCol[i])==0
drhea678832008-12-10 19:26:22 +00002385 ){
drh19e2d372005-08-29 23:00:03 +00002386 sqlite3_bind_null(pStmt, i+1);
2387 }else{
2388 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2389 }
2390 }
2391 sqlite3_step(pStmt);
2392 rc = sqlite3_reset(pStmt);
2393 free(zLine);
2394 if( rc!=SQLITE_OK ){
drha198f2b2014-02-07 19:26:13 +00002395 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0);
drh19e2d372005-08-29 23:00:03 +00002396 zCommit = "ROLLBACK";
2397 break;
2398 }
2399 }
2400 free(azCol);
2401 fclose(in);
2402 sqlite3_finalize(pStmt);
drh37527852006-03-16 16:19:56 +00002403 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
drh19e2d372005-08-29 23:00:03 +00002404
2405 if( zCommit[0] == 'C' ){
2406 /* success, set result as number of lines processed */
2407 pResult = Tcl_GetObjResult(interp);
2408 Tcl_SetIntObj(pResult, lineno);
2409 rc = TCL_OK;
2410 }else{
2411 /* failure, append lineno where failed */
drh5bb3eb92007-05-04 13:15:55 +00002412 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
drha198f2b2014-02-07 19:26:13 +00002413 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,
2414 (char*)0);
drh19e2d372005-08-29 23:00:03 +00002415 rc = TCL_ERROR;
2416 }
2417 break;
2418 }
2419
drhdcd997e2003-01-31 17:21:49 +00002420 /*
drhcb7d5412018-01-03 16:49:52 +00002421 ** $db deserialize ?DATABASE? VALUE
2422 **
2423 ** Reopen DATABASE (default "main") using the content in $VALUE
2424 */
2425 case DB_DESERIALIZE: {
drh9c6396e2018-03-06 21:43:19 +00002426#ifndef SQLITE_ENABLE_DESERIALIZE
drh3ec86652018-01-03 19:03:31 +00002427 Tcl_AppendResult(interp, "MEMDB not available in this build",
2428 (char*)0);
2429 rc = TCL_ERROR;
2430#else
2431 const char *zSchema;
2432 Tcl_Obj *pValue;
2433 unsigned char *pBA;
2434 unsigned char *pData;
2435 int len, xrc;
2436
2437 if( objc==3 ){
2438 zSchema = 0;
2439 pValue = objv[2];
2440 }else if( objc==4 ){
2441 zSchema = Tcl_GetString(objv[2]);
2442 pValue = objv[3];
2443 }else{
2444 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
2445 rc = TCL_ERROR;
2446 break;
2447 }
2448 pBA = Tcl_GetByteArrayFromObj(pValue, &len);
2449 pData = sqlite3_malloc64( len );
drha5bb4352018-01-03 23:40:02 +00002450 if( pData==0 && len>0 ){
drh3ec86652018-01-03 19:03:31 +00002451 Tcl_AppendResult(interp, "out of memory", (char*)0);
2452 rc = TCL_ERROR;
2453 }else{
drha5bb4352018-01-03 23:40:02 +00002454 if( len>0 ) memcpy(pData, pBA, len);
drh3ec86652018-01-03 19:03:31 +00002455 xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len,
2456 SQLITE_DESERIALIZE_FREEONCLOSE |
2457 SQLITE_DESERIALIZE_RESIZEABLE);
2458 if( xrc ){
2459 Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
2460 rc = TCL_ERROR;
2461 }
2462 }
2463#endif
drhcb7d5412018-01-03 16:49:52 +00002464 break;
2465 }
2466
2467 /*
drh41449052006-07-06 17:08:48 +00002468 ** $db enable_load_extension BOOLEAN
2469 **
2470 ** Turn the extension loading feature on or off. It if off by
2471 ** default.
2472 */
2473 case DB_ENABLE_LOAD_EXTENSION: {
drhf533acc2006-12-19 18:57:11 +00002474#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh41449052006-07-06 17:08:48 +00002475 int onoff;
2476 if( objc!=3 ){
2477 Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");
2478 return TCL_ERROR;
2479 }
2480 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
2481 return TCL_ERROR;
2482 }
2483 sqlite3_enable_load_extension(pDb->db, onoff);
2484 break;
drhf533acc2006-12-19 18:57:11 +00002485#else
2486 Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
drha198f2b2014-02-07 19:26:13 +00002487 (char*)0);
drhf533acc2006-12-19 18:57:11 +00002488 return TCL_ERROR;
2489#endif
drh41449052006-07-06 17:08:48 +00002490 }
2491
2492 /*
drhdcd997e2003-01-31 17:21:49 +00002493 ** $db errorcode
2494 **
2495 ** Return the numeric error code that was returned by the most recent
danielk19776f8a5032004-05-10 10:34:51 +00002496 ** call to sqlite3_exec().
drhdcd997e2003-01-31 17:21:49 +00002497 */
2498 case DB_ERRORCODE: {
danielk1977f3ce83f2004-06-14 11:43:46 +00002499 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
drhdcd997e2003-01-31 17:21:49 +00002500 break;
2501 }
dan4a4c11a2009-10-06 14:59:02 +00002502
2503 /*
2504 ** $db exists $sql
2505 ** $db onecolumn $sql
2506 **
2507 ** The onecolumn method is the equivalent of:
2508 ** lindex [$db eval $sql] 0
2509 */
mistachkinb56660f2016-07-14 21:26:09 +00002510 case DB_EXISTS:
dan4a4c11a2009-10-06 14:59:02 +00002511 case DB_ONECOLUMN: {
drhedc40242016-06-13 12:34:38 +00002512 Tcl_Obj *pResult = 0;
dan4a4c11a2009-10-06 14:59:02 +00002513 DbEvalContext sEval;
2514 if( objc!=3 ){
2515 Tcl_WrongNumArgs(interp, 2, objv, "SQL");
2516 return TCL_ERROR;
2517 }
2518
drhaf38cdb2017-06-26 21:08:32 +00002519 dbEvalInit(&sEval, pDb, objv[2], 0, 0);
dan4a4c11a2009-10-06 14:59:02 +00002520 rc = dbEvalStep(&sEval);
2521 if( choice==DB_ONECOLUMN ){
2522 if( rc==TCL_OK ){
drhedc40242016-06-13 12:34:38 +00002523 pResult = dbEvalColumnValue(&sEval, 0);
dand5f12cd2011-08-18 17:47:57 +00002524 }else if( rc==TCL_BREAK ){
2525 Tcl_ResetResult(interp);
dan4a4c11a2009-10-06 14:59:02 +00002526 }
2527 }else if( rc==TCL_BREAK || rc==TCL_OK ){
drhedc40242016-06-13 12:34:38 +00002528 pResult = Tcl_NewBooleanObj(rc==TCL_OK);
dan4a4c11a2009-10-06 14:59:02 +00002529 }
2530 dbEvalFinalize(&sEval);
drhedc40242016-06-13 12:34:38 +00002531 if( pResult ) Tcl_SetObjResult(interp, pResult);
dan4a4c11a2009-10-06 14:59:02 +00002532
2533 if( rc==TCL_BREAK ){
2534 rc = TCL_OK;
2535 }
2536 break;
2537 }
mistachkinb56660f2016-07-14 21:26:09 +00002538
drh75897232000-05-29 14:26:00 +00002539 /*
drhaf38cdb2017-06-26 21:08:32 +00002540 ** $db eval ?options? $sql ?array? ?{ ...code... }?
drh75897232000-05-29 14:26:00 +00002541 **
2542 ** The SQL statement in $sql is evaluated. For each row, the values are
drhbec3f402000-08-04 13:49:02 +00002543 ** placed in elements of the array named "array" and ...code... is executed.
drh75897232000-05-29 14:26:00 +00002544 ** If "array" and "code" are omitted, then no callback is every invoked.
2545 ** If "array" is an empty string, then the values are placed in variables
2546 ** that have the same name as the fields extracted by the query.
2547 */
dan4a4c11a2009-10-06 14:59:02 +00002548 case DB_EVAL: {
drhaf38cdb2017-06-26 21:08:32 +00002549 int evalFlags = 0;
2550 const char *zOpt;
2551 while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){
2552 if( strcmp(zOpt, "-withoutnulls")==0 ){
2553 evalFlags |= SQLITE_EVAL_WITHOUTNULLS;
2554 }
2555 else{
2556 Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0);
2557 return TCL_ERROR;
2558 }
2559 objc--;
2560 objv++;
2561 }
dan4a4c11a2009-10-06 14:59:02 +00002562 if( objc<3 || objc>5 ){
drhaf38cdb2017-06-26 21:08:32 +00002563 Tcl_WrongNumArgs(interp, 2, objv,
2564 "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?");
dan4a4c11a2009-10-06 14:59:02 +00002565 return TCL_ERROR;
danielk197730ccda12004-05-27 12:11:31 +00002566 }
dan4a4c11a2009-10-06 14:59:02 +00002567
drh92febd92004-08-20 18:34:20 +00002568 if( objc==3 ){
dan4a4c11a2009-10-06 14:59:02 +00002569 DbEvalContext sEval;
2570 Tcl_Obj *pRet = Tcl_NewObj();
2571 Tcl_IncrRefCount(pRet);
drhaf38cdb2017-06-26 21:08:32 +00002572 dbEvalInit(&sEval, pDb, objv[2], 0, 0);
dan4a4c11a2009-10-06 14:59:02 +00002573 while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
2574 int i;
2575 int nCol;
2576 dbEvalRowInfo(&sEval, &nCol, 0);
drh92febd92004-08-20 18:34:20 +00002577 for(i=0; i<nCol; i++){
dan4a4c11a2009-10-06 14:59:02 +00002578 Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
danielk197730ccda12004-05-27 12:11:31 +00002579 }
2580 }
dan4a4c11a2009-10-06 14:59:02 +00002581 dbEvalFinalize(&sEval);
drh90b6bb12004-09-13 13:16:31 +00002582 if( rc==TCL_BREAK ){
dan4a4c11a2009-10-06 14:59:02 +00002583 Tcl_SetObjResult(interp, pRet);
drh90b6bb12004-09-13 13:16:31 +00002584 rc = TCL_OK;
2585 }
drh1807ce32004-09-07 13:20:35 +00002586 Tcl_DecrRefCount(pRet);
dan4a4c11a2009-10-06 14:59:02 +00002587 }else{
mistachkin8e189222015-04-19 21:43:16 +00002588 ClientData cd2[2];
dan4a4c11a2009-10-06 14:59:02 +00002589 DbEvalContext *p;
2590 Tcl_Obj *pArray = 0;
2591 Tcl_Obj *pScript;
2592
drhaf38cdb2017-06-26 21:08:32 +00002593 if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){
dan4a4c11a2009-10-06 14:59:02 +00002594 pArray = objv[3];
2595 }
2596 pScript = objv[objc-1];
2597 Tcl_IncrRefCount(pScript);
mistachkinb56660f2016-07-14 21:26:09 +00002598
dan4a4c11a2009-10-06 14:59:02 +00002599 p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
drhaf38cdb2017-06-26 21:08:32 +00002600 dbEvalInit(p, pDb, objv[2], pArray, evalFlags);
dan4a4c11a2009-10-06 14:59:02 +00002601
mistachkin8e189222015-04-19 21:43:16 +00002602 cd2[0] = (void *)p;
2603 cd2[1] = (void *)pScript;
2604 rc = DbEvalNextCmd(cd2, interp, TCL_OK);
danielk197730ccda12004-05-27 12:11:31 +00002605 }
danielk197730ccda12004-05-27 12:11:31 +00002606 break;
2607 }
drhbec3f402000-08-04 13:49:02 +00002608
2609 /*
dan3df30592015-03-13 08:31:54 +00002610 ** $db function NAME [-argcount N] [-deterministic] SCRIPT
drhcabb0812002-09-14 13:47:32 +00002611 **
2612 ** Create a new SQL function called NAME. Whenever that function is
2613 ** called, invoke SCRIPT to evaluate the function.
2614 */
2615 case DB_FUNCTION: {
dan3df30592015-03-13 08:31:54 +00002616 int flags = SQLITE_UTF8;
drhcabb0812002-09-14 13:47:32 +00002617 SqlFunc *pFunc;
drhd1e47332005-06-26 17:55:33 +00002618 Tcl_Obj *pScript;
drhcabb0812002-09-14 13:47:32 +00002619 char *zName;
drhe3602be2008-09-09 12:31:33 +00002620 int nArg = -1;
dan3df30592015-03-13 08:31:54 +00002621 int i;
2622 if( objc<4 ){
2623 Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT");
2624 return TCL_ERROR;
2625 }
2626 for(i=3; i<(objc-1); i++){
2627 const char *z = Tcl_GetString(objv[i]);
drh4f21c4a2008-12-10 22:15:00 +00002628 int n = strlen30(z);
drhe3602be2008-09-09 12:31:33 +00002629 if( n>2 && strncmp(z, "-argcount",n)==0 ){
dan3df30592015-03-13 08:31:54 +00002630 if( i==(objc-2) ){
drhea8f0a12017-01-12 11:50:08 +00002631 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
dan3df30592015-03-13 08:31:54 +00002632 return TCL_ERROR;
2633 }
2634 if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR;
drhe3602be2008-09-09 12:31:33 +00002635 if( nArg<0 ){
2636 Tcl_AppendResult(interp, "number of arguments must be non-negative",
2637 (char*)0);
2638 return TCL_ERROR;
2639 }
dan3df30592015-03-13 08:31:54 +00002640 i++;
2641 }else
2642 if( n>2 && strncmp(z, "-deterministic",n)==0 ){
2643 flags |= SQLITE_DETERMINISTIC;
2644 }else{
mistachkinb56660f2016-07-14 21:26:09 +00002645 Tcl_AppendResult(interp, "bad option \"", z,
drhea8f0a12017-01-12 11:50:08 +00002646 "\": must be -argcount or -deterministic", (char*)0
dan3df30592015-03-13 08:31:54 +00002647 );
2648 return TCL_ERROR;
drhe3602be2008-09-09 12:31:33 +00002649 }
drhcabb0812002-09-14 13:47:32 +00002650 }
dan3df30592015-03-13 08:31:54 +00002651
2652 pScript = objv[objc-1];
drhcabb0812002-09-14 13:47:32 +00002653 zName = Tcl_GetStringFromObj(objv[2], 0);
drhd1e47332005-06-26 17:55:33 +00002654 pFunc = findSqlFunc(pDb, zName);
drhcabb0812002-09-14 13:47:32 +00002655 if( pFunc==0 ) return TCL_ERROR;
drhd1e47332005-06-26 17:55:33 +00002656 if( pFunc->pScript ){
2657 Tcl_DecrRefCount(pFunc->pScript);
2658 }
2659 pFunc->pScript = pScript;
2660 Tcl_IncrRefCount(pScript);
2661 pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
dan3df30592015-03-13 08:31:54 +00002662 rc = sqlite3_create_function(pDb->db, zName, nArg, flags,
danielk1977d8123362004-06-12 09:25:12 +00002663 pFunc, tclSqlFunc, 0, 0);
drhfb7e7652005-01-24 00:28:42 +00002664 if( rc!=SQLITE_OK ){
danielk19779636c4e2005-01-25 04:27:54 +00002665 rc = TCL_ERROR;
2666 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
drhfb7e7652005-01-24 00:28:42 +00002667 }
drhcabb0812002-09-14 13:47:32 +00002668 break;
2669 }
2670
2671 /*
danielk19778cbadb02007-05-03 16:31:26 +00002672 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID
danielk1977b4e9af92007-05-01 17:49:49 +00002673 */
2674 case DB_INCRBLOB: {
danielk197732a0d8b2007-05-04 19:03:02 +00002675#ifdef SQLITE_OMIT_INCRBLOB
drha198f2b2014-02-07 19:26:13 +00002676 Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0);
danielk197732a0d8b2007-05-04 19:03:02 +00002677 return TCL_ERROR;
2678#else
danielk19778cbadb02007-05-03 16:31:26 +00002679 int isReadonly = 0;
danielk1977b4e9af92007-05-01 17:49:49 +00002680 const char *zDb = "main";
2681 const char *zTable;
2682 const char *zColumn;
drhb3f787f2012-09-29 14:45:54 +00002683 Tcl_WideInt iRow;
danielk1977b4e9af92007-05-01 17:49:49 +00002684
danielk19778cbadb02007-05-03 16:31:26 +00002685 /* Check for the -readonly option */
2686 if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
2687 isReadonly = 1;
2688 }
2689
2690 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){
2691 Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");
danielk1977b4e9af92007-05-01 17:49:49 +00002692 return TCL_ERROR;
2693 }
2694
danielk19778cbadb02007-05-03 16:31:26 +00002695 if( objc==(6+isReadonly) ){
danielk1977b4e9af92007-05-01 17:49:49 +00002696 zDb = Tcl_GetString(objv[2]);
2697 }
2698 zTable = Tcl_GetString(objv[objc-3]);
2699 zColumn = Tcl_GetString(objv[objc-2]);
2700 rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow);
2701
2702 if( rc==TCL_OK ){
danielk19778cbadb02007-05-03 16:31:26 +00002703 rc = createIncrblobChannel(
danedf5b162014-08-19 09:15:41 +00002704 interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly
danielk19778cbadb02007-05-03 16:31:26 +00002705 );
danielk1977b4e9af92007-05-01 17:49:49 +00002706 }
danielk197732a0d8b2007-05-04 19:03:02 +00002707#endif
danielk1977b4e9af92007-05-01 17:49:49 +00002708 break;
2709 }
2710
2711 /*
drhf11bded2006-07-17 00:02:44 +00002712 ** $db interrupt
2713 **
2714 ** Interrupt the execution of the inner-most SQL interpreter. This
2715 ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
2716 */
2717 case DB_INTERRUPT: {
2718 sqlite3_interrupt(pDb->db);
2719 break;
2720 }
2721
2722 /*
drh19e2d372005-08-29 23:00:03 +00002723 ** $db nullvalue ?STRING?
2724 **
2725 ** Change text used when a NULL comes back from the database. If ?STRING?
2726 ** is not present, then the current string used for NULL is returned.
2727 ** If STRING is present, then STRING is returned.
2728 **
2729 */
2730 case DB_NULLVALUE: {
2731 if( objc!=2 && objc!=3 ){
2732 Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
2733 return TCL_ERROR;
2734 }
2735 if( objc==3 ){
2736 int len;
2737 char *zNull = Tcl_GetStringFromObj(objv[2], &len);
2738 if( pDb->zNull ){
2739 Tcl_Free(pDb->zNull);
2740 }
2741 if( zNull && len>0 ){
2742 pDb->zNull = Tcl_Alloc( len + 1 );
drh7fd33922011-06-20 19:00:30 +00002743 memcpy(pDb->zNull, zNull, len);
drh19e2d372005-08-29 23:00:03 +00002744 pDb->zNull[len] = '\0';
2745 }else{
2746 pDb->zNull = 0;
2747 }
2748 }
drhc45e6712012-10-03 11:02:33 +00002749 Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
drh19e2d372005-08-29 23:00:03 +00002750 break;
2751 }
2752
2753 /*
mistachkinb56660f2016-07-14 21:26:09 +00002754 ** $db last_insert_rowid
drhaf9ff332002-01-16 21:00:27 +00002755 **
2756 ** Return an integer which is the ROWID for the most recent insert.
2757 */
2758 case DB_LAST_INSERT_ROWID: {
2759 Tcl_Obj *pResult;
drhf7e678d2006-06-21 19:30:34 +00002760 Tcl_WideInt rowid;
drhaf9ff332002-01-16 21:00:27 +00002761 if( objc!=2 ){
2762 Tcl_WrongNumArgs(interp, 2, objv, "");
2763 return TCL_ERROR;
2764 }
danielk19776f8a5032004-05-10 10:34:51 +00002765 rowid = sqlite3_last_insert_rowid(pDb->db);
drhaf9ff332002-01-16 21:00:27 +00002766 pResult = Tcl_GetObjResult(interp);
drhf7e678d2006-06-21 19:30:34 +00002767 Tcl_SetWideIntObj(pResult, rowid);
drhaf9ff332002-01-16 21:00:27 +00002768 break;
2769 }
2770
2771 /*
dan4a4c11a2009-10-06 14:59:02 +00002772 ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
drh5d9d7572003-08-19 14:31:01 +00002773 */
drh1807ce32004-09-07 13:20:35 +00002774
2775 /* $db progress ?N CALLBACK?
mistachkinb56660f2016-07-14 21:26:09 +00002776 **
drh1807ce32004-09-07 13:20:35 +00002777 ** Invoke the given callback every N virtual machine opcodes while executing
2778 ** queries.
2779 */
2780 case DB_PROGRESS: {
2781 if( objc==2 ){
2782 if( pDb->zProgress ){
drha198f2b2014-02-07 19:26:13 +00002783 Tcl_AppendResult(interp, pDb->zProgress, (char*)0);
drh1807ce32004-09-07 13:20:35 +00002784 }
2785 }else if( objc==4 ){
2786 char *zProgress;
2787 int len;
2788 int N;
2789 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
drhfd131da2007-08-07 17:13:03 +00002790 return TCL_ERROR;
drh1807ce32004-09-07 13:20:35 +00002791 };
2792 if( pDb->zProgress ){
2793 Tcl_Free(pDb->zProgress);
2794 }
2795 zProgress = Tcl_GetStringFromObj(objv[3], &len);
2796 if( zProgress && len>0 ){
2797 pDb->zProgress = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00002798 memcpy(pDb->zProgress, zProgress, len+1);
drh1807ce32004-09-07 13:20:35 +00002799 }else{
2800 pDb->zProgress = 0;
2801 }
2802#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
2803 if( pDb->zProgress ){
2804 pDb->interp = interp;
2805 sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
2806 }else{
2807 sqlite3_progress_handler(pDb->db, 0, 0, 0);
2808 }
2809#endif
2810 }else{
2811 Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
drh5d9d7572003-08-19 14:31:01 +00002812 return TCL_ERROR;
2813 }
drh5d9d7572003-08-19 14:31:01 +00002814 break;
2815 }
2816
drh19e2d372005-08-29 23:00:03 +00002817 /* $db profile ?CALLBACK?
2818 **
2819 ** Make arrangements to invoke the CALLBACK routine after each SQL statement
2820 ** that has run. The text of the SQL and the amount of elapse time are
2821 ** appended to CALLBACK before the script is run.
2822 */
2823 case DB_PROFILE: {
2824 if( objc>3 ){
2825 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
2826 return TCL_ERROR;
2827 }else if( objc==2 ){
2828 if( pDb->zProfile ){
drha198f2b2014-02-07 19:26:13 +00002829 Tcl_AppendResult(interp, pDb->zProfile, (char*)0);
drh19e2d372005-08-29 23:00:03 +00002830 }
2831 }else{
2832 char *zProfile;
2833 int len;
2834 if( pDb->zProfile ){
2835 Tcl_Free(pDb->zProfile);
2836 }
2837 zProfile = Tcl_GetStringFromObj(objv[2], &len);
2838 if( zProfile && len>0 ){
2839 pDb->zProfile = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00002840 memcpy(pDb->zProfile, zProfile, len+1);
drh19e2d372005-08-29 23:00:03 +00002841 }else{
2842 pDb->zProfile = 0;
2843 }
drh2eb22af2016-09-10 19:51:40 +00002844#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
2845 !defined(SQLITE_OMIT_DEPRECATED)
drh19e2d372005-08-29 23:00:03 +00002846 if( pDb->zProfile ){
2847 pDb->interp = interp;
2848 sqlite3_profile(pDb->db, DbProfileHandler, pDb);
2849 }else{
2850 sqlite3_profile(pDb->db, 0, 0);
2851 }
2852#endif
2853 }
2854 break;
2855 }
2856
drh5d9d7572003-08-19 14:31:01 +00002857 /*
drh22fbcb82004-02-01 01:22:50 +00002858 ** $db rekey KEY
2859 **
2860 ** Change the encryption key on the currently open database.
2861 */
2862 case DB_REKEY: {
drh32f57d42016-03-16 01:03:10 +00002863#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drh22fbcb82004-02-01 01:22:50 +00002864 int nKey;
2865 void *pKey;
drhb07028f2011-10-14 21:49:18 +00002866#endif
drh22fbcb82004-02-01 01:22:50 +00002867 if( objc!=3 ){
2868 Tcl_WrongNumArgs(interp, 2, objv, "KEY");
2869 return TCL_ERROR;
2870 }
drh32f57d42016-03-16 01:03:10 +00002871#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drhb07028f2011-10-14 21:49:18 +00002872 pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
drh2011d5f2004-07-22 02:40:37 +00002873 rc = sqlite3_rekey(pDb->db, pKey, nKey);
drh22fbcb82004-02-01 01:22:50 +00002874 if( rc ){
drha198f2b2014-02-07 19:26:13 +00002875 Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
drh22fbcb82004-02-01 01:22:50 +00002876 rc = TCL_ERROR;
2877 }
2878#endif
2879 break;
2880 }
2881
drhdc2c4912009-02-04 22:46:47 +00002882 /* $db restore ?DATABASE? FILENAME
2883 **
mistachkinb56660f2016-07-14 21:26:09 +00002884 ** Open a database file named FILENAME. Transfer the content
drhdc2c4912009-02-04 22:46:47 +00002885 ** of FILENAME into the local database DATABASE (default: "main").
2886 */
2887 case DB_RESTORE: {
2888 const char *zSrcFile;
2889 const char *zDestDb;
2890 sqlite3 *pSrc;
2891 sqlite3_backup *pBackup;
2892 int nTimeout = 0;
2893
2894 if( objc==3 ){
2895 zDestDb = "main";
2896 zSrcFile = Tcl_GetString(objv[2]);
2897 }else if( objc==4 ){
2898 zDestDb = Tcl_GetString(objv[2]);
2899 zSrcFile = Tcl_GetString(objv[3]);
2900 }else{
2901 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
2902 return TCL_ERROR;
2903 }
drh147ef392016-01-22 23:17:51 +00002904 rc = sqlite3_open_v2(zSrcFile, &pSrc,
2905 SQLITE_OPEN_READONLY | pDb->openFlags, 0);
drhdc2c4912009-02-04 22:46:47 +00002906 if( rc!=SQLITE_OK ){
2907 Tcl_AppendResult(interp, "cannot open source database: ",
2908 sqlite3_errmsg(pSrc), (char*)0);
2909 sqlite3_close(pSrc);
2910 return TCL_ERROR;
2911 }
2912 pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
2913 if( pBackup==0 ){
2914 Tcl_AppendResult(interp, "restore failed: ",
2915 sqlite3_errmsg(pDb->db), (char*)0);
2916 sqlite3_close(pSrc);
2917 return TCL_ERROR;
2918 }
2919 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2920 || rc==SQLITE_BUSY ){
2921 if( rc==SQLITE_BUSY ){
2922 if( nTimeout++ >= 3 ) break;
2923 sqlite3_sleep(100);
2924 }
2925 }
2926 sqlite3_backup_finish(pBackup);
2927 if( rc==SQLITE_DONE ){
2928 rc = TCL_OK;
2929 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2930 Tcl_AppendResult(interp, "restore failed: source database busy",
2931 (char*)0);
2932 rc = TCL_ERROR;
2933 }else{
2934 Tcl_AppendResult(interp, "restore failed: ",
2935 sqlite3_errmsg(pDb->db), (char*)0);
2936 rc = TCL_ERROR;
2937 }
2938 sqlite3_close(pSrc);
2939 break;
2940 }
2941
drh22fbcb82004-02-01 01:22:50 +00002942 /*
drhcb7d5412018-01-03 16:49:52 +00002943 ** $db serialize ?DATABASE?
2944 **
2945 ** Return a serialization of a database.
2946 */
2947 case DB_SERIALIZE: {
drh9c6396e2018-03-06 21:43:19 +00002948#ifndef SQLITE_ENABLE_DESERIALIZE
drhcb7d5412018-01-03 16:49:52 +00002949 Tcl_AppendResult(interp, "MEMDB not available in this build",
2950 (char*)0);
2951 rc = TCL_ERROR;
2952#else
2953 const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
2954 sqlite3_int64 sz = 0;
2955 unsigned char *pData;
2956 if( objc!=2 && objc!=3 ){
2957 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
2958 rc = TCL_ERROR;
2959 }else{
2960 int needFree;
2961 pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
2962 if( pData ){
2963 needFree = 0;
2964 }else{
2965 pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
2966 needFree = 1;
2967 }
2968 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
2969 if( needFree ) sqlite3_free(pData);
2970 }
2971#endif
2972 break;
2973 }
2974
2975 /*
danc456a762017-06-22 16:51:16 +00002976 ** $db status (step|sort|autoindex|vmstep)
drhd1d38482008-10-07 23:46:38 +00002977 **
mistachkinb56660f2016-07-14 21:26:09 +00002978 ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
drhd1d38482008-10-07 23:46:38 +00002979 ** SQLITE_STMTSTATUS_SORT for the most recent eval.
2980 */
2981 case DB_STATUS: {
drhd1d38482008-10-07 23:46:38 +00002982 int v;
2983 const char *zOp;
2984 if( objc!=3 ){
drh1c320a42010-08-01 22:41:32 +00002985 Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)");
drhd1d38482008-10-07 23:46:38 +00002986 return TCL_ERROR;
2987 }
2988 zOp = Tcl_GetString(objv[2]);
2989 if( strcmp(zOp, "step")==0 ){
2990 v = pDb->nStep;
2991 }else if( strcmp(zOp, "sort")==0 ){
2992 v = pDb->nSort;
drh3c379b02010-04-07 19:31:59 +00002993 }else if( strcmp(zOp, "autoindex")==0 ){
2994 v = pDb->nIndex;
danc456a762017-06-22 16:51:16 +00002995 }else if( strcmp(zOp, "vmstep")==0 ){
2996 v = pDb->nVMStep;
drhd1d38482008-10-07 23:46:38 +00002997 }else{
mistachkinb56660f2016-07-14 21:26:09 +00002998 Tcl_AppendResult(interp,
danc456a762017-06-22 16:51:16 +00002999 "bad argument: should be autoindex, step, sort or vmstep",
drhd1d38482008-10-07 23:46:38 +00003000 (char*)0);
3001 return TCL_ERROR;
3002 }
3003 Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
3004 break;
3005 }
mistachkinb56660f2016-07-14 21:26:09 +00003006
drhd1d38482008-10-07 23:46:38 +00003007 /*
drhbec3f402000-08-04 13:49:02 +00003008 ** $db timeout MILLESECONDS
3009 **
3010 ** Delay for the number of milliseconds specified when a file is locked.
3011 */
drh6d313162000-09-21 13:01:35 +00003012 case DB_TIMEOUT: {
drhbec3f402000-08-04 13:49:02 +00003013 int ms;
drh6d313162000-09-21 13:01:35 +00003014 if( objc!=3 ){
3015 Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
drhbec3f402000-08-04 13:49:02 +00003016 return TCL_ERROR;
3017 }
drh6d313162000-09-21 13:01:35 +00003018 if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
danielk19776f8a5032004-05-10 10:34:51 +00003019 sqlite3_busy_timeout(pDb->db, ms);
drh6d313162000-09-21 13:01:35 +00003020 break;
drh75897232000-05-29 14:26:00 +00003021 }
mistachkinb56660f2016-07-14 21:26:09 +00003022
danielk197755c45f22005-04-03 23:54:43 +00003023 /*
drh0f14e2e2004-06-29 12:39:08 +00003024 ** $db total_changes
3025 **
mistachkinb56660f2016-07-14 21:26:09 +00003026 ** Return the number of rows that were modified, inserted, or deleted
drh0f14e2e2004-06-29 12:39:08 +00003027 ** since the database handle was created.
3028 */
3029 case DB_TOTAL_CHANGES: {
3030 Tcl_Obj *pResult;
3031 if( objc!=2 ){
3032 Tcl_WrongNumArgs(interp, 2, objv, "");
3033 return TCL_ERROR;
3034 }
3035 pResult = Tcl_GetObjResult(interp);
3036 Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
3037 break;
3038 }
3039
drhb5a20d32003-04-23 12:25:23 +00003040 /* $db trace ?CALLBACK?
3041 **
3042 ** Make arrangements to invoke the CALLBACK routine for each SQL statement
3043 ** that is executed. The text of the SQL is appended to CALLBACK before
3044 ** it is executed.
3045 */
3046 case DB_TRACE: {
3047 if( objc>3 ){
3048 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
drhb97759e2004-06-29 11:26:59 +00003049 return TCL_ERROR;
drhb5a20d32003-04-23 12:25:23 +00003050 }else if( objc==2 ){
3051 if( pDb->zTrace ){
drha198f2b2014-02-07 19:26:13 +00003052 Tcl_AppendResult(interp, pDb->zTrace, (char*)0);
drhb5a20d32003-04-23 12:25:23 +00003053 }
3054 }else{
3055 char *zTrace;
3056 int len;
3057 if( pDb->zTrace ){
3058 Tcl_Free(pDb->zTrace);
3059 }
3060 zTrace = Tcl_GetStringFromObj(objv[2], &len);
3061 if( zTrace && len>0 ){
3062 pDb->zTrace = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00003063 memcpy(pDb->zTrace, zTrace, len+1);
drhb5a20d32003-04-23 12:25:23 +00003064 }else{
3065 pDb->zTrace = 0;
3066 }
drh2eb22af2016-09-10 19:51:40 +00003067#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
3068 !defined(SQLITE_OMIT_DEPRECATED)
drhb5a20d32003-04-23 12:25:23 +00003069 if( pDb->zTrace ){
3070 pDb->interp = interp;
danielk19776f8a5032004-05-10 10:34:51 +00003071 sqlite3_trace(pDb->db, DbTraceHandler, pDb);
drhb5a20d32003-04-23 12:25:23 +00003072 }else{
danielk19776f8a5032004-05-10 10:34:51 +00003073 sqlite3_trace(pDb->db, 0, 0);
drhb5a20d32003-04-23 12:25:23 +00003074 }
drh19e2d372005-08-29 23:00:03 +00003075#endif
drhb5a20d32003-04-23 12:25:23 +00003076 }
3077 break;
3078 }
3079
mistachkinb56660f2016-07-14 21:26:09 +00003080 /* $db trace_v2 ?CALLBACK? ?MASK?
3081 **
3082 ** Make arrangements to invoke the CALLBACK routine for each trace event
3083 ** matching the mask that is generated. The parameters are appended to
3084 ** CALLBACK before it is executed.
3085 */
3086 case DB_TRACE_V2: {
3087 if( objc>4 ){
3088 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
3089 return TCL_ERROR;
3090 }else if( objc==2 ){
3091 if( pDb->zTraceV2 ){
3092 Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
3093 }
3094 }else{
mistachkinb56660f2016-07-14 21:26:09 +00003095 char *zTraceV2;
3096 int len;
mistachkinb52dcd82016-07-14 23:17:03 +00003097 Tcl_WideInt wMask = 0;
mistachkinb56660f2016-07-14 21:26:09 +00003098 if( objc==4 ){
mistachkinb52dcd82016-07-14 23:17:03 +00003099 static const char *TTYPE_strs[] = {
3100 "statement", "profile", "row", "close", 0
3101 };
3102 enum TTYPE_enum {
3103 TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE
3104 };
3105 int i;
3106 if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){
mistachkinb56660f2016-07-14 21:26:09 +00003107 return TCL_ERROR;
3108 }
mistachkinb52dcd82016-07-14 23:17:03 +00003109 for(i=0; i<len; i++){
3110 Tcl_Obj *pObj;
3111 int ttype;
3112 if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){
3113 return TCL_ERROR;
3114 }
3115 if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type",
3116 0, &ttype)!=TCL_OK ){
3117 Tcl_WideInt wType;
3118 Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
3119 Tcl_IncrRefCount(pError);
3120 if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){
3121 Tcl_DecrRefCount(pError);
3122 wMask |= wType;
3123 }else{
3124 Tcl_SetObjResult(interp, pError);
3125 Tcl_DecrRefCount(pError);
3126 return TCL_ERROR;
3127 }
3128 }else{
3129 switch( (enum TTYPE_enum)ttype ){
3130 case TTYPE_STMT: wMask |= SQLITE_TRACE_STMT; break;
3131 case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break;
3132 case TTYPE_ROW: wMask |= SQLITE_TRACE_ROW; break;
3133 case TTYPE_CLOSE: wMask |= SQLITE_TRACE_CLOSE; break;
3134 }
3135 }
3136 }
mistachkinb56660f2016-07-14 21:26:09 +00003137 }else{
mistachkinb52dcd82016-07-14 23:17:03 +00003138 wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */
mistachkinb56660f2016-07-14 21:26:09 +00003139 }
3140 if( pDb->zTraceV2 ){
3141 Tcl_Free(pDb->zTraceV2);
3142 }
3143 zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
3144 if( zTraceV2 && len>0 ){
3145 pDb->zTraceV2 = Tcl_Alloc( len + 1 );
3146 memcpy(pDb->zTraceV2, zTraceV2, len+1);
3147 }else{
3148 pDb->zTraceV2 = 0;
3149 }
3150#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
3151 if( pDb->zTraceV2 ){
3152 pDb->interp = interp;
3153 sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb);
3154 }else{
3155 sqlite3_trace_v2(pDb->db, 0, 0, 0);
3156 }
3157#endif
3158 }
3159 break;
3160 }
3161
drh3d214232005-08-02 12:21:08 +00003162 /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
3163 **
3164 ** Start a new transaction (if we are not already in the midst of a
3165 ** transaction) and execute the TCL script SCRIPT. After SCRIPT
3166 ** completes, either commit the transaction or roll it back if SCRIPT
3167 ** throws an exception. Or if no new transation was started, do nothing.
3168 ** pass the exception on up the stack.
3169 **
3170 ** This command was inspired by Dave Thomas's talk on Ruby at the
3171 ** 2005 O'Reilly Open Source Convention (OSCON).
3172 */
3173 case DB_TRANSACTION: {
drh3d214232005-08-02 12:21:08 +00003174 Tcl_Obj *pScript;
danielk1977cd38d522009-01-02 17:33:46 +00003175 const char *zBegin = "SAVEPOINT _tcl_transaction";
drh3d214232005-08-02 12:21:08 +00003176 if( objc!=3 && objc!=4 ){
3177 Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
3178 return TCL_ERROR;
3179 }
danielk1977cd38d522009-01-02 17:33:46 +00003180
dan4a4c11a2009-10-06 14:59:02 +00003181 if( pDb->nTransaction==0 && objc==4 ){
drh3d214232005-08-02 12:21:08 +00003182 static const char *TTYPE_strs[] = {
drhce604012005-08-16 11:11:34 +00003183 "deferred", "exclusive", "immediate", 0
drh3d214232005-08-02 12:21:08 +00003184 };
3185 enum TTYPE_enum {
3186 TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
3187 };
3188 int ttype;
drhb5555e72005-08-02 17:15:14 +00003189 if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
drh3d214232005-08-02 12:21:08 +00003190 0, &ttype) ){
3191 return TCL_ERROR;
3192 }
3193 switch( (enum TTYPE_enum)ttype ){
3194 case TTYPE_DEFERRED: /* no-op */; break;
3195 case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break;
3196 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break;
3197 }
drh3d214232005-08-02 12:21:08 +00003198 }
danielk1977cd38d522009-01-02 17:33:46 +00003199 pScript = objv[objc-1];
3200
dan4a4c11a2009-10-06 14:59:02 +00003201 /* Run the SQLite BEGIN command to open a transaction or savepoint. */
danielk1977cd38d522009-01-02 17:33:46 +00003202 pDb->disableAuth++;
3203 rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
3204 pDb->disableAuth--;
3205 if( rc!=SQLITE_OK ){
drha198f2b2014-02-07 19:26:13 +00003206 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
danielk1977cd38d522009-01-02 17:33:46 +00003207 return TCL_ERROR;
drh3d214232005-08-02 12:21:08 +00003208 }
danielk1977cd38d522009-01-02 17:33:46 +00003209 pDb->nTransaction++;
danielk1977cd38d522009-01-02 17:33:46 +00003210
dan4a4c11a2009-10-06 14:59:02 +00003211 /* If using NRE, schedule a callback to invoke the script pScript, then
3212 ** a second callback to commit (or rollback) the transaction or savepoint
3213 ** opened above. If not using NRE, evaluate the script directly, then
mistachkinb56660f2016-07-14 21:26:09 +00003214 ** call function DbTransPostCmd() to commit (or rollback) the transaction
dan4a4c11a2009-10-06 14:59:02 +00003215 ** or savepoint. */
3216 if( DbUseNre() ){
3217 Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
drha47941f2013-12-20 18:57:44 +00003218 (void)Tcl_NREvalObj(interp, pScript, 0);
danielk1977cd38d522009-01-02 17:33:46 +00003219 }else{
dan4a4c11a2009-10-06 14:59:02 +00003220 rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
drh3d214232005-08-02 12:21:08 +00003221 }
3222 break;
3223 }
3224
danielk197794eb6a12005-12-15 15:22:08 +00003225 /*
danielk1977404ca072009-03-16 13:19:36 +00003226 ** $db unlock_notify ?script?
3227 */
3228 case DB_UNLOCK_NOTIFY: {
3229#ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
drha198f2b2014-02-07 19:26:13 +00003230 Tcl_AppendResult(interp, "unlock_notify not available in this build",
3231 (char*)0);
danielk1977404ca072009-03-16 13:19:36 +00003232 rc = TCL_ERROR;
3233#else
3234 if( objc!=2 && objc!=3 ){
3235 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
3236 rc = TCL_ERROR;
3237 }else{
3238 void (*xNotify)(void **, int) = 0;
3239 void *pNotifyArg = 0;
3240
3241 if( pDb->pUnlockNotify ){
3242 Tcl_DecrRefCount(pDb->pUnlockNotify);
3243 pDb->pUnlockNotify = 0;
3244 }
mistachkinb56660f2016-07-14 21:26:09 +00003245
danielk1977404ca072009-03-16 13:19:36 +00003246 if( objc==3 ){
3247 xNotify = DbUnlockNotify;
3248 pNotifyArg = (void *)pDb;
3249 pDb->pUnlockNotify = objv[2];
3250 Tcl_IncrRefCount(pDb->pUnlockNotify);
3251 }
mistachkinb56660f2016-07-14 21:26:09 +00003252
danielk1977404ca072009-03-16 13:19:36 +00003253 if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
drha198f2b2014-02-07 19:26:13 +00003254 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
danielk1977404ca072009-03-16 13:19:36 +00003255 rc = TCL_ERROR;
3256 }
3257 }
3258#endif
3259 break;
3260 }
3261
drh304637c2011-03-18 16:47:27 +00003262 /*
3263 ** $db preupdate_hook count
3264 ** $db preupdate_hook hook ?SCRIPT?
3265 ** $db preupdate_hook new INDEX
3266 ** $db preupdate_hook old INDEX
3267 */
dan46c47d42011-03-01 18:42:07 +00003268 case DB_PREUPDATE: {
drh9b1c62d2011-03-30 21:04:43 +00003269#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
dan2b519ab2016-12-06 19:33:42 +00003270 Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time",
3271 (char*)0);
drh9b1c62d2011-03-30 21:04:43 +00003272 rc = TCL_ERROR;
3273#else
dan1e7a2d42011-03-22 18:45:29 +00003274 static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0};
dan46c47d42011-03-01 18:42:07 +00003275 enum DbPreupdateSubCmd {
dan1e7a2d42011-03-22 18:45:29 +00003276 PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD
dan46c47d42011-03-01 18:42:07 +00003277 };
3278 int iSub;
3279
3280 if( objc<3 ){
3281 Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?");
3282 }
3283 if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){
3284 return TCL_ERROR;
3285 }
3286
3287 switch( (enum DbPreupdateSubCmd)iSub ){
3288 case PRE_COUNT: {
3289 int nCol = sqlite3_preupdate_count(pDb->db);
3290 Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol));
3291 break;
3292 }
3293
3294 case PRE_HOOK: {
3295 if( objc>4 ){
3296 Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?");
3297 return TCL_ERROR;
3298 }
3299 DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook);
3300 break;
3301 }
3302
dan1e7a2d42011-03-22 18:45:29 +00003303 case PRE_DEPTH: {
3304 Tcl_Obj *pRet;
3305 if( objc!=3 ){
3306 Tcl_WrongNumArgs(interp, 3, objv, "");
3307 return TCL_ERROR;
3308 }
3309 pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db));
3310 Tcl_SetObjResult(interp, pRet);
3311 break;
3312 }
3313
dan37db03b2011-03-16 19:59:18 +00003314 case PRE_NEW:
dan46c47d42011-03-01 18:42:07 +00003315 case PRE_OLD: {
3316 int iIdx;
dan37db03b2011-03-16 19:59:18 +00003317 sqlite3_value *pValue;
dan46c47d42011-03-01 18:42:07 +00003318 if( objc!=4 ){
3319 Tcl_WrongNumArgs(interp, 3, objv, "INDEX");
3320 return TCL_ERROR;
3321 }
3322 if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){
3323 return TCL_ERROR;
3324 }
3325
dan37db03b2011-03-16 19:59:18 +00003326 if( iSub==PRE_OLD ){
dan46c47d42011-03-01 18:42:07 +00003327 rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue);
dan37db03b2011-03-16 19:59:18 +00003328 }else{
3329 assert( iSub==PRE_NEW );
3330 rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue);
dan46c47d42011-03-01 18:42:07 +00003331 }
3332
dan37db03b2011-03-16 19:59:18 +00003333 if( rc==SQLITE_OK ){
drh304637c2011-03-18 16:47:27 +00003334 Tcl_Obj *pObj;
3335 pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1);
dan37db03b2011-03-16 19:59:18 +00003336 Tcl_SetObjResult(interp, pObj);
3337 }else{
drhea8f0a12017-01-12 11:50:08 +00003338 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
dan46c47d42011-03-01 18:42:07 +00003339 return TCL_ERROR;
3340 }
3341 }
3342 }
drh9b1c62d2011-03-30 21:04:43 +00003343#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
dan46c47d42011-03-01 18:42:07 +00003344 break;
3345 }
3346
danielk1977404ca072009-03-16 13:19:36 +00003347 /*
drh833bf962010-04-28 14:42:19 +00003348 ** $db wal_hook ?script?
danielk197794eb6a12005-12-15 15:22:08 +00003349 ** $db update_hook ?script?
danielk197771fd80b2005-12-16 06:54:01 +00003350 ** $db rollback_hook ?script?
danielk197794eb6a12005-12-15 15:22:08 +00003351 */
mistachkinb56660f2016-07-14 21:26:09 +00003352 case DB_WAL_HOOK:
3353 case DB_UPDATE_HOOK:
dan6566ebe2011-03-16 09:49:14 +00003354 case DB_ROLLBACK_HOOK: {
mistachkinb56660f2016-07-14 21:26:09 +00003355 /* set ppHook to point at pUpdateHook or pRollbackHook, depending on
danielk197771fd80b2005-12-16 06:54:01 +00003356 ** whether [$db update_hook] or [$db rollback_hook] was invoked.
3357 */
mistachkinb56660f2016-07-14 21:26:09 +00003358 Tcl_Obj **ppHook = 0;
dan46c47d42011-03-01 18:42:07 +00003359 if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
3360 if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
3361 if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
3362 if( objc>3 ){
danielk197794eb6a12005-12-15 15:22:08 +00003363 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
3364 return TCL_ERROR;
3365 }
danielk197771fd80b2005-12-16 06:54:01 +00003366
dan46c47d42011-03-01 18:42:07 +00003367 DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook);
danielk197794eb6a12005-12-15 15:22:08 +00003368 break;
3369 }
3370
danielk19774397de52005-01-12 12:44:03 +00003371 /* $db version
3372 **
3373 ** Return the version string for this database.
3374 */
3375 case DB_VERSION: {
drh1df64702017-10-13 15:56:26 +00003376 int i;
3377 for(i=2; i<objc; i++){
3378 const char *zArg = Tcl_GetString(objv[i]);
3379 /* Optional arguments to $db version are used for testing purpose */
3380#ifdef SQLITE_TEST
3381 /* $db version -use-legacy-prepare BOOLEAN
3382 **
3383 ** Turn the use of legacy sqlite3_prepare() on or off.
3384 */
3385 if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){
3386 i++;
3387 if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){
3388 return TCL_ERROR;
3389 }
3390 }else
3391
3392 /* $db version -last-stmt-ptr
3393 **
3394 ** Return a string which is a hex encoding of the pointer to the
3395 ** most recent sqlite3_stmt in the statement cache.
3396 */
3397 if( strcmp(zArg, "-last-stmt-ptr")==0 ){
3398 char zBuf[100];
3399 sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
3400 pDb->stmtList ? pDb->stmtList->pStmt: 0);
3401 Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
3402 }else
3403#endif /* SQLITE_TEST */
3404 {
3405 Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0);
3406 return TCL_ERROR;
3407 }
3408 }
3409 if( i==2 ){
3410 Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
3411 }
danielk19774397de52005-01-12 12:44:03 +00003412 break;
3413 }
3414
tpoindex1067fe12004-12-17 15:41:11 +00003415
drh6d313162000-09-21 13:01:35 +00003416 } /* End of the SWITCH statement */
drh22fbcb82004-02-01 01:22:50 +00003417 return rc;
drh75897232000-05-29 14:26:00 +00003418}
3419
drha2c8a952009-10-13 18:38:34 +00003420#if SQLITE_TCL_NRE
3421/*
3422** Adaptor that provides an objCmd interface to the NRE-enabled
3423** interface implementation.
3424*/
mistachkina121cc72016-07-28 18:06:52 +00003425static int SQLITE_TCLAPI DbObjCmdAdaptor(
drha2c8a952009-10-13 18:38:34 +00003426 void *cd,
3427 Tcl_Interp *interp,
3428 int objc,
3429 Tcl_Obj *const*objv
3430){
3431 return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv);
3432}
3433#endif /* SQLITE_TCL_NRE */
3434
drh75897232000-05-29 14:26:00 +00003435/*
drh4dcac402018-01-03 13:20:02 +00003436** Issue the usage message when the "sqlite3" command arguments are
3437** incorrect.
3438*/
3439static int sqliteCmdUsage(
3440 Tcl_Interp *interp,
3441 Tcl_Obj *const*objv
3442){
3443 Tcl_WrongNumArgs(interp, 1, objv,
3444 "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
3445 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
3446#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
3447 " ?-key CODECKEY?"
3448#endif
3449 );
3450 return TCL_ERROR;
3451}
3452
3453/*
drh3570ad92007-08-31 14:31:44 +00003454** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
danielk19779a6284c2008-07-10 17:52:49 +00003455** ?-create BOOLEAN? ?-nomutex BOOLEAN?
drh75897232000-05-29 14:26:00 +00003456**
3457** This is the main Tcl command. When the "sqlite" Tcl command is
3458** invoked, this routine runs to process that command.
3459**
3460** The first argument, DBNAME, is an arbitrary name for a new
3461** database connection. This command creates a new command named
3462** DBNAME that is used to control that connection. The database
3463** connection is deleted when the DBNAME command is deleted.
3464**
drh3570ad92007-08-31 14:31:44 +00003465** The second argument is the name of the database file.
drhfbc3eab2001-04-06 16:13:42 +00003466**
drh75897232000-05-29 14:26:00 +00003467*/
mistachkin7617e4a2016-07-28 17:11:20 +00003468static int SQLITE_TCLAPI DbMain(
3469 void *cd,
3470 Tcl_Interp *interp,
3471 int objc,
3472 Tcl_Obj *const*objv
3473){
drhbec3f402000-08-04 13:49:02 +00003474 SqliteDb *p;
drh22fbcb82004-02-01 01:22:50 +00003475 const char *zArg;
drh75897232000-05-29 14:26:00 +00003476 char *zErrMsg;
drh3570ad92007-08-31 14:31:44 +00003477 int i;
drh4dcac402018-01-03 13:20:02 +00003478 const char *zFile = 0;
drh3570ad92007-08-31 14:31:44 +00003479 const char *zVfs = 0;
drhd9da78a2009-03-24 15:08:09 +00003480 int flags;
drh882e8e42006-08-24 02:42:27 +00003481 Tcl_DString translatedFilename;
drh32f57d42016-03-16 01:03:10 +00003482#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drhb07028f2011-10-14 21:49:18 +00003483 void *pKey = 0;
3484 int nKey = 0;
3485#endif
mistachkin540ebf82012-09-10 07:29:29 +00003486 int rc;
drhd9da78a2009-03-24 15:08:09 +00003487
3488 /* In normal use, each TCL interpreter runs in a single thread. So
drh4dcac402018-01-03 13:20:02 +00003489 ** by default, we can turn off mutexing on SQLite database connections.
drhd9da78a2009-03-24 15:08:09 +00003490 ** However, for testing purposes it is useful to have mutexes turned
3491 ** on. So, by default, mutexes default off. But if compiled with
3492 ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
3493 */
3494#ifdef SQLITE_TCL_DEFAULT_FULLMUTEX
3495 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
3496#else
3497 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
3498#endif
3499
drh22fbcb82004-02-01 01:22:50 +00003500 if( objc==2 ){
3501 zArg = Tcl_GetStringFromObj(objv[1], 0);
drh22fbcb82004-02-01 01:22:50 +00003502 if( strcmp(zArg,"-version")==0 ){
drha198f2b2014-02-07 19:26:13 +00003503 Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
drh647cb0e2002-11-04 19:32:25 +00003504 return TCL_OK;
3505 }
drh72bf6a32016-01-07 02:06:55 +00003506 if( strcmp(zArg,"-sourceid")==0 ){
3507 Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0);
3508 return TCL_OK;
3509 }
drh9eb9e262004-02-11 02:18:05 +00003510 if( strcmp(zArg,"-has-codec")==0 ){
drh32f57d42016-03-16 01:03:10 +00003511#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drha198f2b2014-02-07 19:26:13 +00003512 Tcl_AppendResult(interp,"1",(char*)0);
drh22fbcb82004-02-01 01:22:50 +00003513#else
drha198f2b2014-02-07 19:26:13 +00003514 Tcl_AppendResult(interp,"0",(char*)0);
drh22fbcb82004-02-01 01:22:50 +00003515#endif
3516 return TCL_OK;
3517 }
drh4dcac402018-01-03 13:20:02 +00003518 if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
drhfbc3eab2001-04-06 16:13:42 +00003519 }
drh4dcac402018-01-03 13:20:02 +00003520 for(i=2; i<objc; i++){
drh3570ad92007-08-31 14:31:44 +00003521 zArg = Tcl_GetString(objv[i]);
drh4dcac402018-01-03 13:20:02 +00003522 if( zArg[0]!='-' ){
3523 if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
3524 zFile = zArg;
3525 continue;
3526 }
3527 if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
3528 i++;
drh22fbcb82004-02-01 01:22:50 +00003529 if( strcmp(zArg,"-key")==0 ){
drh32f57d42016-03-16 01:03:10 +00003530#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drh4dcac402018-01-03 13:20:02 +00003531 pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
drhb07028f2011-10-14 21:49:18 +00003532#endif
drh3570ad92007-08-31 14:31:44 +00003533 }else if( strcmp(zArg, "-vfs")==0 ){
drh4dcac402018-01-03 13:20:02 +00003534 zVfs = Tcl_GetString(objv[i]);
drh3570ad92007-08-31 14:31:44 +00003535 }else if( strcmp(zArg, "-readonly")==0 ){
3536 int b;
drh4dcac402018-01-03 13:20:02 +00003537 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
drh3570ad92007-08-31 14:31:44 +00003538 if( b ){
drh33f4e022007-09-03 15:19:34 +00003539 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
drh3570ad92007-08-31 14:31:44 +00003540 flags |= SQLITE_OPEN_READONLY;
3541 }else{
3542 flags &= ~SQLITE_OPEN_READONLY;
3543 flags |= SQLITE_OPEN_READWRITE;
3544 }
3545 }else if( strcmp(zArg, "-create")==0 ){
3546 int b;
drh4dcac402018-01-03 13:20:02 +00003547 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
drh33f4e022007-09-03 15:19:34 +00003548 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
drh3570ad92007-08-31 14:31:44 +00003549 flags |= SQLITE_OPEN_CREATE;
3550 }else{
3551 flags &= ~SQLITE_OPEN_CREATE;
3552 }
danielk19779a6284c2008-07-10 17:52:49 +00003553 }else if( strcmp(zArg, "-nomutex")==0 ){
3554 int b;
drh4dcac402018-01-03 13:20:02 +00003555 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
danielk19779a6284c2008-07-10 17:52:49 +00003556 if( b ){
3557 flags |= SQLITE_OPEN_NOMUTEX;
drh039963a2008-09-03 00:43:15 +00003558 flags &= ~SQLITE_OPEN_FULLMUTEX;
danielk19779a6284c2008-07-10 17:52:49 +00003559 }else{
3560 flags &= ~SQLITE_OPEN_NOMUTEX;
3561 }
danc431fd52011-06-27 16:55:50 +00003562 }else if( strcmp(zArg, "-fullmutex")==0 ){
drh039963a2008-09-03 00:43:15 +00003563 int b;
drh4dcac402018-01-03 13:20:02 +00003564 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
drh039963a2008-09-03 00:43:15 +00003565 if( b ){
3566 flags |= SQLITE_OPEN_FULLMUTEX;
3567 flags &= ~SQLITE_OPEN_NOMUTEX;
3568 }else{
3569 flags &= ~SQLITE_OPEN_FULLMUTEX;
3570 }
drhf12b3f62011-12-21 14:42:29 +00003571 }else if( strcmp(zArg, "-uri")==0 ){
3572 int b;
drh4dcac402018-01-03 13:20:02 +00003573 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
drhf12b3f62011-12-21 14:42:29 +00003574 if( b ){
3575 flags |= SQLITE_OPEN_URI;
3576 }else{
3577 flags &= ~SQLITE_OPEN_URI;
3578 }
drh3570ad92007-08-31 14:31:44 +00003579 }else{
3580 Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
3581 return TCL_ERROR;
drh22fbcb82004-02-01 01:22:50 +00003582 }
3583 }
drh75897232000-05-29 14:26:00 +00003584 zErrMsg = 0;
drh4cdc9e82000-08-04 14:56:24 +00003585 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
drhbec3f402000-08-04 13:49:02 +00003586 memset(p, 0, sizeof(*p));
drh3ec86652018-01-03 19:03:31 +00003587 if( zFile==0 ) zFile = "";
3588 zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
3589 rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
3590 Tcl_DStringFree(&translatedFilename);
mistachkin540ebf82012-09-10 07:29:29 +00003591 if( p->db ){
3592 if( SQLITE_OK!=sqlite3_errcode(p->db) ){
3593 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
3594 sqlite3_close(p->db);
3595 p->db = 0;
3596 }
3597 }else{
mistachkin5dac8432012-09-11 02:00:25 +00003598 zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
danielk197780290862004-05-22 09:21:21 +00003599 }
drh32f57d42016-03-16 01:03:10 +00003600#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drhf3a65f72007-08-22 20:18:21 +00003601 if( p->db ){
3602 sqlite3_key(p->db, pKey, nKey);
3603 }
drheb8ed702004-02-11 10:37:23 +00003604#endif
drhbec3f402000-08-04 13:49:02 +00003605 if( p->db==0 ){
drh75897232000-05-29 14:26:00 +00003606 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
drhbec3f402000-08-04 13:49:02 +00003607 Tcl_Free((char*)p);
drh9404d502006-12-19 18:46:08 +00003608 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00003609 return TCL_ERROR;
3610 }
drhfb7e7652005-01-24 00:28:42 +00003611 p->maxStmt = NUM_PREPARED_STMTS;
drh147ef392016-01-22 23:17:51 +00003612 p->openFlags = flags & SQLITE_OPEN_URI;
drh5169bbc2006-08-24 14:59:45 +00003613 p->interp = interp;
drh22fbcb82004-02-01 01:22:50 +00003614 zArg = Tcl_GetStringFromObj(objv[1], 0);
dan4a4c11a2009-10-06 14:59:02 +00003615 if( DbUseNre() ){
drha2c8a952009-10-13 18:38:34 +00003616 Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
3617 (char*)p, DbDeleteCmd);
dan4a4c11a2009-10-06 14:59:02 +00003618 }else{
3619 Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
3620 }
drh75897232000-05-29 14:26:00 +00003621 return TCL_OK;
3622}
3623
3624/*
drh90ca9752001-09-28 17:47:14 +00003625** Provide a dummy Tcl_InitStubs if we are using this as a static
3626** library.
3627*/
3628#ifndef USE_TCL_STUBS
3629# undef Tcl_InitStubs
drh0e85ccf2013-06-03 12:34:46 +00003630# define Tcl_InitStubs(a,b,c) TCL_VERSION
drh90ca9752001-09-28 17:47:14 +00003631#endif
3632
3633/*
drh29bc4612005-10-05 10:40:15 +00003634** Make sure we have a PACKAGE_VERSION macro defined. This will be
3635** defined automatically by the TEA makefile. But other makefiles
3636** do not define it.
3637*/
3638#ifndef PACKAGE_VERSION
3639# define PACKAGE_VERSION SQLITE_VERSION
3640#endif
3641
3642/*
drh75897232000-05-29 14:26:00 +00003643** Initialize this module.
3644**
3645** This Tcl module contains only a single new Tcl command named "sqlite".
3646** (Hence there is no namespace. There is no point in using a namespace
3647** if the extension only supplies one new name!) The "sqlite" command is
3648** used to open a new SQLite database. See the DbMain() routine above
3649** for additional information.
drhb652f432010-08-26 16:46:57 +00003650**
3651** The EXTERN macros are required by TCL in order to work on windows.
drh75897232000-05-29 14:26:00 +00003652*/
drhb652f432010-08-26 16:46:57 +00003653EXTERN int Sqlite3_Init(Tcl_Interp *interp){
mistachkin27b2f052015-01-12 19:49:46 +00003654 int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR;
drh6dc8cbe2013-05-31 15:36:07 +00003655 if( rc==TCL_OK ){
3656 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
drh1cca0d22010-08-25 20:35:51 +00003657#ifndef SQLITE_3_SUFFIX_ONLY
drh6dc8cbe2013-05-31 15:36:07 +00003658 /* The "sqlite" alias is undocumented. It is here only to support
3659 ** legacy scripts. All new scripts should use only the "sqlite3"
3660 ** command. */
3661 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
drh4c0f1642010-08-25 19:39:19 +00003662#endif
drh6dc8cbe2013-05-31 15:36:07 +00003663 rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
3664 }
3665 return rc;
drh90ca9752001-09-28 17:47:14 +00003666}
drhb652f432010-08-26 16:46:57 +00003667EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
drhb652f432010-08-26 16:46:57 +00003668EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3669EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
drhe2c3a652008-09-23 09:58:46 +00003670
drhd878cab2012-03-20 15:10:42 +00003671/* Because it accesses the file-system and uses persistent state, SQLite
drhe75a9eb2016-02-13 18:54:10 +00003672** is not considered appropriate for safe interpreters. Hence, we cause
3673** the _SafeInit() interfaces return TCL_ERROR.
drhd878cab2012-03-20 15:10:42 +00003674*/
drhe75a9eb2016-02-13 18:54:10 +00003675EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; }
3676EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;}
3677
3678
drh49766d62005-01-08 18:42:28 +00003679
3680#ifndef SQLITE_3_SUFFIX_ONLY
dana3e63c42010-08-20 12:33:59 +00003681int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
3682int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
dana3e63c42010-08-20 12:33:59 +00003683int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3684int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
drh49766d62005-01-08 18:42:28 +00003685#endif
drh75897232000-05-29 14:26:00 +00003686
drhc318f732017-10-13 15:06:06 +00003687/*
drh96a206f2017-10-13 20:14:06 +00003688** If the TCLSH macro is defined, add code to make a stand-alone program.
drhc318f732017-10-13 15:06:06 +00003689*/
drh96a206f2017-10-13 20:14:06 +00003690#if defined(TCLSH)
drh57a02272009-10-22 20:52:05 +00003691
drh96a206f2017-10-13 20:14:06 +00003692/* This is the main routine for an ordinary TCL shell. If there are
3693** are arguments, run the first argument as a script. Otherwise,
3694** read TCL commands from standard input
drh348784e2000-05-29 20:41:49 +00003695*/
dan0ae479d2011-09-21 16:43:07 +00003696static const char *tclsh_main_loop(void){
3697 static const char zMainloop[] =
drh96a206f2017-10-13 20:14:06 +00003698 "if {[llength $argv]>=1} {\n"
3699 "set argv0 [lindex $argv 0]\n"
3700 "set argv [lrange $argv 1 end]\n"
3701 "source $argv0\n"
3702 "} else {\n"
3703 "set line {}\n"
3704 "while {![eof stdin]} {\n"
3705 "if {$line!=\"\"} {\n"
3706 "puts -nonewline \"> \"\n"
3707 "} else {\n"
3708 "puts -nonewline \"% \"\n"
dan0ae479d2011-09-21 16:43:07 +00003709 "}\n"
drh96a206f2017-10-13 20:14:06 +00003710 "flush stdout\n"
3711 "append line [gets stdin]\n"
3712 "if {[info complete $line]} {\n"
3713 "if {[catch {uplevel #0 $line} result]} {\n"
3714 "puts stderr \"Error: $result\"\n"
3715 "} elseif {$result!=\"\"} {\n"
3716 "puts $result\n"
3717 "}\n"
3718 "set line {}\n"
3719 "} else {\n"
3720 "append line \\n\n"
3721 "}\n"
dan0ae479d2011-09-21 16:43:07 +00003722 "}\n"
drh348784e2000-05-29 20:41:49 +00003723 "}\n"
dan0ae479d2011-09-21 16:43:07 +00003724 ;
3725 return zMainloop;
3726}
drh3e27c022004-07-23 00:01:38 +00003727
danc1a60c52010-06-07 14:28:16 +00003728#define TCLSH_MAIN main /* Needed to fake out mktclapp */
mistachkin69def7f2016-07-28 04:14:37 +00003729int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
danc1a60c52010-06-07 14:28:16 +00003730 Tcl_Interp *interp;
drh96a206f2017-10-13 20:14:06 +00003731 int i;
3732 const char *zScript = 0;
3733 char zArgc[32];
3734#if defined(TCLSH_INIT_PROC)
3735 extern const char *TCLSH_INIT_PROC(Tcl_Interp*);
3736#endif
mistachkin1f28e072013-08-15 08:06:15 +00003737
3738#if !defined(_WIN32_WCE)
mistachkin1e8487d2018-07-22 06:25:35 +00003739 if( getenv("SQLITE_DEBUG_BREAK") ){
3740 if( isatty(0) && isatty(2) ){
3741 fprintf(stderr,
3742 "attach debugger to process %d and press any key to continue.\n",
3743 GETPID());
3744 fgetc(stdin);
3745 }else{
3746#if defined(_WIN32) || defined(WIN32)
3747 DebugBreak();
3748#elif defined(SIGTRAP)
3749 raise(SIGTRAP);
3750#endif
3751 }
mistachkin1f28e072013-08-15 08:06:15 +00003752 }
3753#endif
3754
danc1a60c52010-06-07 14:28:16 +00003755 /* Call sqlite3_shutdown() once before doing anything else. This is to
3756 ** test that sqlite3_shutdown() can be safely called by a process before
3757 ** sqlite3_initialize() is. */
3758 sqlite3_shutdown();
3759
dan0ae479d2011-09-21 16:43:07 +00003760 Tcl_FindExecutable(argv[0]);
mistachkin2953ba92014-02-14 00:25:03 +00003761 Tcl_SetSystemEncoding(NULL, "utf-8");
dan0ae479d2011-09-21 16:43:07 +00003762 interp = Tcl_CreateInterp();
drhc318f732017-10-13 15:06:06 +00003763 Sqlite3_Init(interp);
drh96a206f2017-10-13 20:14:06 +00003764
3765 sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1);
3766 Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
3767 Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
3768 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
3769 for(i=1; i<argc; i++){
3770 Tcl_SetVar(interp, "argv", argv[i],
3771 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
drhc318f732017-10-13 15:06:06 +00003772 }
drh96a206f2017-10-13 20:14:06 +00003773#if defined(TCLSH_INIT_PROC)
3774 zScript = TCLSH_INIT_PROC(interp);
3775#endif
3776 if( zScript==0 ){
3777 zScript = tclsh_main_loop();
drh3e27c022004-07-23 00:01:38 +00003778 }
drh96a206f2017-10-13 20:14:06 +00003779 if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){
3780 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
3781 if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
3782 fprintf(stderr,"%s: %s\n", *argv, zInfo);
3783 return 1;
drh348784e2000-05-29 20:41:49 +00003784 }
3785 return 0;
3786}
3787#endif /* TCLSH */