blob: 1b0086c7d532265465f34f3b5a735522a763b2cd [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.
dan89d24932019-02-27 16:38:19 +000096**
97** Variable eType may be set to SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT,
98** SQLITE_BLOB or SQLITE_NULL. If it is SQLITE_NULL, then the implementation
99** attempts to determine the type of the result based on the Tcl object.
100** If it is SQLITE_TEXT or SQLITE_BLOB, then a text (sqlite3_result_text())
101** or blob (sqlite3_result_blob()) is returned. If it is SQLITE_INTEGER
102** or SQLITE_FLOAT, then an attempt is made to return an integer or float
103** value, falling back to float and then text if this is not possible.
drhcabb0812002-09-14 13:47:32 +0000104*/
105typedef struct SqlFunc SqlFunc;
106struct SqlFunc {
107 Tcl_Interp *interp; /* The TCL interpret to execute the function */
drhd1e47332005-06-26 17:55:33 +0000108 Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
drhc45e6712012-10-03 11:02:33 +0000109 SqliteDb *pDb; /* Database connection that owns this function */
drhd1e47332005-06-26 17:55:33 +0000110 int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
dan89d24932019-02-27 16:38:19 +0000111 int eType; /* Type of value to return */
drhd1e47332005-06-26 17:55:33 +0000112 char *zName; /* Name of this function */
drhcabb0812002-09-14 13:47:32 +0000113 SqlFunc *pNext; /* Next function on the list of them all */
114};
115
116/*
danielk19770202b292004-06-09 09:55:16 +0000117** New collation sequences function can be created as TCL scripts. Each such
118** function is described by an instance of the following structure.
119*/
120typedef struct SqlCollate SqlCollate;
121struct SqlCollate {
122 Tcl_Interp *interp; /* The TCL interpret to execute the function */
123 char *zScript; /* The script to be run */
drhd1e47332005-06-26 17:55:33 +0000124 SqlCollate *pNext; /* Next function on the list of them all */
danielk19770202b292004-06-09 09:55:16 +0000125};
126
127/*
drhfb7e7652005-01-24 00:28:42 +0000128** Prepared statements are cached for faster execution. Each prepared
129** statement is described by an instance of the following structure.
130*/
131typedef struct SqlPreparedStmt SqlPreparedStmt;
132struct SqlPreparedStmt {
133 SqlPreparedStmt *pNext; /* Next in linked list */
134 SqlPreparedStmt *pPrev; /* Previous on the list */
135 sqlite3_stmt *pStmt; /* The prepared statement */
136 int nSql; /* chars in zSql[] */
danielk1977d0e2a852007-11-14 06:48:48 +0000137 const char *zSql; /* Text of the SQL statement */
dan4a4c11a2009-10-06 14:59:02 +0000138 int nParm; /* Size of apParm array */
139 Tcl_Obj **apParm; /* Array of referenced object pointers */
drhfb7e7652005-01-24 00:28:42 +0000140};
141
danielk1977d04417962007-05-02 13:16:30 +0000142typedef struct IncrblobChannel IncrblobChannel;
143
drhfb7e7652005-01-24 00:28:42 +0000144/*
drhbec3f402000-08-04 13:49:02 +0000145** There is one instance of this structure for each SQLite database
146** that has been opened by the SQLite TCL interface.
danc431fd52011-06-27 16:55:50 +0000147**
148** If this module is built with SQLITE_TEST defined (to create the SQLite
149** testfixture executable), then it may be configured to use either
150** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
151** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
drhbec3f402000-08-04 13:49:02 +0000152*/
drhbec3f402000-08-04 13:49:02 +0000153struct SqliteDb {
drhdddca282006-01-03 00:33:50 +0000154 sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
drhd1e47332005-06-26 17:55:33 +0000155 Tcl_Interp *interp; /* The interpreter used for this database */
156 char *zBusy; /* The busy callback routine */
157 char *zCommit; /* The commit hook callback routine */
158 char *zTrace; /* The trace callback routine */
mistachkinb56660f2016-07-14 21:26:09 +0000159 char *zTraceV2; /* The trace_v2 callback routine */
drh19e2d372005-08-29 23:00:03 +0000160 char *zProfile; /* The profile callback routine */
drhd1e47332005-06-26 17:55:33 +0000161 char *zProgress; /* The progress callback routine */
162 char *zAuth; /* The authorization callback routine */
drh1f1549f2008-08-26 21:33:34 +0000163 int disableAuth; /* Disable the authorizer if it exists */
drhd1e47332005-06-26 17:55:33 +0000164 char *zNull; /* Text to substitute for an SQL NULL value */
165 SqlFunc *pFunc; /* List of SQL functions */
danielk197794eb6a12005-12-15 15:22:08 +0000166 Tcl_Obj *pUpdateHook; /* Update hook script (if any) */
dan46c47d42011-03-01 18:42:07 +0000167 Tcl_Obj *pPreUpdateHook; /* Pre-update hook script (if any) */
danielk197771fd80b2005-12-16 06:54:01 +0000168 Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */
drh5def0842010-05-05 20:00:25 +0000169 Tcl_Obj *pWalHook; /* WAL hook script (if any) */
danielk1977404ca072009-03-16 13:19:36 +0000170 Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */
drhd1e47332005-06-26 17:55:33 +0000171 SqlCollate *pCollate; /* List of SQL collation functions */
172 int rc; /* Return code of most recent sqlite3_exec() */
173 Tcl_Obj *pCollateNeeded; /* Collation needed script */
drhfb7e7652005-01-24 00:28:42 +0000174 SqlPreparedStmt *stmtList; /* List of prepared statements*/
175 SqlPreparedStmt *stmtLast; /* Last statement in the list */
176 int maxStmt; /* The next maximum number of stmtList */
177 int nStmt; /* Number of statements in stmtList */
danielk1977d04417962007-05-02 13:16:30 +0000178 IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
drh3c379b02010-04-07 19:31:59 +0000179 int nStep, nSort, nIndex; /* Statistics for most recent operation */
danc456a762017-06-22 16:51:16 +0000180 int nVMStep; /* Another statistic for most recent operation */
danielk1977cd38d522009-01-02 17:33:46 +0000181 int nTransaction; /* Number of nested [transaction] methods */
drh147ef392016-01-22 23:17:51 +0000182 int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */
danc431fd52011-06-27 16:55:50 +0000183#ifdef SQLITE_TEST
184 int bLegacyPrepare; /* True to use sqlite3_prepare() */
185#endif
drh98808ba2001-10-18 12:34:46 +0000186};
drh297ecf12001-04-05 15:57:13 +0000187
danielk1977b4e9af92007-05-01 17:49:49 +0000188struct IncrblobChannel {
danielk1977d04417962007-05-02 13:16:30 +0000189 sqlite3_blob *pBlob; /* sqlite3 blob handle */
danielk1977dcbb5d32007-05-04 18:36:44 +0000190 SqliteDb *pDb; /* Associated database connection */
danielk1977d04417962007-05-02 13:16:30 +0000191 int iSeek; /* Current seek offset */
danielk1977d04417962007-05-02 13:16:30 +0000192 Tcl_Channel channel; /* Channel identifier */
193 IncrblobChannel *pNext; /* Linked list of all open incrblob channels */
194 IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */
danielk1977b4e9af92007-05-01 17:49:49 +0000195};
196
drhea678832008-12-10 19:26:22 +0000197/*
198** Compute a string length that is limited to what can be stored in
199** lower 30 bits of a 32-bit signed integer.
200*/
drh4f21c4a2008-12-10 22:15:00 +0000201static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000202 const char *z2 = z;
203 while( *z2 ){ z2++; }
204 return 0x3fffffff & (int)(z2 - z);
205}
drhea678832008-12-10 19:26:22 +0000206
207
danielk197732a0d8b2007-05-04 19:03:02 +0000208#ifndef SQLITE_OMIT_INCRBLOB
danielk1977b4e9af92007-05-01 17:49:49 +0000209/*
danielk1977d04417962007-05-02 13:16:30 +0000210** Close all incrblob channels opened using database connection pDb.
211** This is called when shutting down the database connection.
212*/
213static void closeIncrblobChannels(SqliteDb *pDb){
214 IncrblobChannel *p;
215 IncrblobChannel *pNext;
216
217 for(p=pDb->pIncrblob; p; p=pNext){
218 pNext = p->pNext;
219
mistachkinb56660f2016-07-14 21:26:09 +0000220 /* Note: Calling unregister here call Tcl_Close on the incrblob channel,
danielk1977d04417962007-05-02 13:16:30 +0000221 ** which deletes the IncrblobChannel structure at *p. So do not
222 ** call Tcl_Free() here.
223 */
224 Tcl_UnregisterChannel(pDb->interp, p->channel);
225 }
226}
227
228/*
danielk1977b4e9af92007-05-01 17:49:49 +0000229** Close an incremental blob channel.
230*/
mistachkin7617e4a2016-07-28 17:11:20 +0000231static int SQLITE_TCLAPI incrblobClose(
232 ClientData instanceData,
233 Tcl_Interp *interp
234){
danielk1977b4e9af92007-05-01 17:49:49 +0000235 IncrblobChannel *p = (IncrblobChannel *)instanceData;
danielk197792d4d7a2007-05-04 12:05:56 +0000236 int rc = sqlite3_blob_close(p->pBlob);
237 sqlite3 *db = p->pDb->db;
danielk1977d04417962007-05-02 13:16:30 +0000238
239 /* Remove the channel from the SqliteDb.pIncrblob list. */
240 if( p->pNext ){
241 p->pNext->pPrev = p->pPrev;
242 }
243 if( p->pPrev ){
244 p->pPrev->pNext = p->pNext;
245 }
246 if( p->pDb->pIncrblob==p ){
247 p->pDb->pIncrblob = p->pNext;
248 }
249
danielk197792d4d7a2007-05-04 12:05:56 +0000250 /* Free the IncrblobChannel structure */
danielk1977b4e9af92007-05-01 17:49:49 +0000251 Tcl_Free((char *)p);
danielk197792d4d7a2007-05-04 12:05:56 +0000252
253 if( rc!=SQLITE_OK ){
254 Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
255 return TCL_ERROR;
256 }
danielk1977b4e9af92007-05-01 17:49:49 +0000257 return TCL_OK;
258}
259
260/*
261** Read data from an incremental blob channel.
262*/
mistachkin7617e4a2016-07-28 17:11:20 +0000263static int SQLITE_TCLAPI incrblobInput(
mistachkinb56660f2016-07-14 21:26:09 +0000264 ClientData instanceData,
265 char *buf,
danielk1977b4e9af92007-05-01 17:49:49 +0000266 int bufSize,
267 int *errorCodePtr
268){
269 IncrblobChannel *p = (IncrblobChannel *)instanceData;
270 int nRead = bufSize; /* Number of bytes to read */
271 int nBlob; /* Total size of the blob */
272 int rc; /* sqlite error code */
273
274 nBlob = sqlite3_blob_bytes(p->pBlob);
275 if( (p->iSeek+nRead)>nBlob ){
276 nRead = nBlob-p->iSeek;
277 }
278 if( nRead<=0 ){
279 return 0;
280 }
281
282 rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek);
283 if( rc!=SQLITE_OK ){
284 *errorCodePtr = rc;
285 return -1;
286 }
287
288 p->iSeek += nRead;
289 return nRead;
290}
291
danielk1977d04417962007-05-02 13:16:30 +0000292/*
293** Write data to an incremental blob channel.
294*/
mistachkin7617e4a2016-07-28 17:11:20 +0000295static int SQLITE_TCLAPI incrblobOutput(
mistachkinb56660f2016-07-14 21:26:09 +0000296 ClientData instanceData,
297 CONST char *buf,
danielk1977b4e9af92007-05-01 17:49:49 +0000298 int toWrite,
299 int *errorCodePtr
300){
301 IncrblobChannel *p = (IncrblobChannel *)instanceData;
302 int nWrite = toWrite; /* Number of bytes to write */
303 int nBlob; /* Total size of the blob */
304 int rc; /* sqlite error code */
305
306 nBlob = sqlite3_blob_bytes(p->pBlob);
307 if( (p->iSeek+nWrite)>nBlob ){
308 *errorCodePtr = EINVAL;
309 return -1;
310 }
311 if( nWrite<=0 ){
312 return 0;
313 }
314
315 rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek);
316 if( rc!=SQLITE_OK ){
317 *errorCodePtr = EIO;
318 return -1;
319 }
320
321 p->iSeek += nWrite;
322 return nWrite;
323}
324
325/*
326** Seek an incremental blob channel.
327*/
mistachkin7617e4a2016-07-28 17:11:20 +0000328static int SQLITE_TCLAPI incrblobSeek(
mistachkinb56660f2016-07-14 21:26:09 +0000329 ClientData instanceData,
danielk1977b4e9af92007-05-01 17:49:49 +0000330 long offset,
331 int seekMode,
332 int *errorCodePtr
333){
334 IncrblobChannel *p = (IncrblobChannel *)instanceData;
335
336 switch( seekMode ){
337 case SEEK_SET:
338 p->iSeek = offset;
339 break;
340 case SEEK_CUR:
341 p->iSeek += offset;
342 break;
343 case SEEK_END:
344 p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset;
345 break;
346
347 default: assert(!"Bad seekMode");
348 }
349
350 return p->iSeek;
351}
352
353
mistachkin7617e4a2016-07-28 17:11:20 +0000354static void SQLITE_TCLAPI incrblobWatch(
355 ClientData instanceData,
356 int mode
357){
mistachkinb56660f2016-07-14 21:26:09 +0000358 /* NO-OP */
danielk1977b4e9af92007-05-01 17:49:49 +0000359}
mistachkin7617e4a2016-07-28 17:11:20 +0000360static int SQLITE_TCLAPI incrblobHandle(
361 ClientData instanceData,
362 int dir,
363 ClientData *hPtr
364){
danielk1977b4e9af92007-05-01 17:49:49 +0000365 return TCL_ERROR;
366}
367
368static Tcl_ChannelType IncrblobChannelType = {
369 "incrblob", /* typeName */
370 TCL_CHANNEL_VERSION_2, /* version */
371 incrblobClose, /* closeProc */
372 incrblobInput, /* inputProc */
373 incrblobOutput, /* outputProc */
374 incrblobSeek, /* seekProc */
375 0, /* setOptionProc */
376 0, /* getOptionProc */
377 incrblobWatch, /* watchProc (this is a no-op) */
378 incrblobHandle, /* getHandleProc (always returns error) */
379 0, /* close2Proc */
380 0, /* blockModeProc */
381 0, /* flushProc */
382 0, /* handlerProc */
383 0, /* wideSeekProc */
danielk1977b4e9af92007-05-01 17:49:49 +0000384};
385
386/*
387** Create a new incrblob channel.
388*/
389static int createIncrblobChannel(
mistachkinb56660f2016-07-14 21:26:09 +0000390 Tcl_Interp *interp,
391 SqliteDb *pDb,
danielk1977b4e9af92007-05-01 17:49:49 +0000392 const char *zDb,
mistachkinb56660f2016-07-14 21:26:09 +0000393 const char *zTable,
394 const char *zColumn,
danielk19778cbadb02007-05-03 16:31:26 +0000395 sqlite_int64 iRow,
396 int isReadonly
danielk1977b4e9af92007-05-01 17:49:49 +0000397){
398 IncrblobChannel *p;
danielk19778cbadb02007-05-03 16:31:26 +0000399 sqlite3 *db = pDb->db;
danielk1977b4e9af92007-05-01 17:49:49 +0000400 sqlite3_blob *pBlob;
401 int rc;
danielk19778cbadb02007-05-03 16:31:26 +0000402 int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE);
danielk1977b4e9af92007-05-01 17:49:49 +0000403
404 /* This variable is used to name the channels: "incrblob_[incr count]" */
405 static int count = 0;
406 char zChannel[64];
407
danielk19778cbadb02007-05-03 16:31:26 +0000408 rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob);
danielk1977b4e9af92007-05-01 17:49:49 +0000409 if( rc!=SQLITE_OK ){
410 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
411 return TCL_ERROR;
412 }
413
414 p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel));
415 p->iSeek = 0;
416 p->pBlob = pBlob;
417
drh5bb3eb92007-05-04 13:15:55 +0000418 sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count);
danielk1977d04417962007-05-02 13:16:30 +0000419 p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags);
420 Tcl_RegisterChannel(interp, p->channel);
danielk1977b4e9af92007-05-01 17:49:49 +0000421
danielk1977d04417962007-05-02 13:16:30 +0000422 /* Link the new channel into the SqliteDb.pIncrblob list. */
423 p->pNext = pDb->pIncrblob;
424 p->pPrev = 0;
425 if( p->pNext ){
426 p->pNext->pPrev = p;
427 }
428 pDb->pIncrblob = p;
429 p->pDb = pDb;
430
431 Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE);
danielk1977b4e9af92007-05-01 17:49:49 +0000432 return TCL_OK;
433}
danielk197732a0d8b2007-05-04 19:03:02 +0000434#else /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */
435 #define closeIncrblobChannels(pDb)
436#endif
danielk1977b4e9af92007-05-01 17:49:49 +0000437
drh6d313162000-09-21 13:01:35 +0000438/*
drhd1e47332005-06-26 17:55:33 +0000439** Look at the script prefix in pCmd. We will be executing this script
440** after first appending one or more arguments. This routine analyzes
441** the script to see if it is safe to use Tcl_EvalObjv() on the script
442** rather than the more general Tcl_EvalEx(). Tcl_EvalObjv() is much
443** faster.
444**
445** Scripts that are safe to use with Tcl_EvalObjv() consists of a
446** command name followed by zero or more arguments with no [...] or $
447** or {...} or ; to be seen anywhere. Most callback scripts consist
448** of just a single procedure name and they meet this requirement.
449*/
450static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
451 /* We could try to do something with Tcl_Parse(). But we will instead
452 ** just do a search for forbidden characters. If any of the forbidden
453 ** characters appear in pCmd, we will report the string as unsafe.
454 */
455 const char *z;
456 int n;
457 z = Tcl_GetStringFromObj(pCmd, &n);
458 while( n-- > 0 ){
459 int c = *(z++);
460 if( c=='$' || c=='[' || c==';' ) return 0;
461 }
462 return 1;
463}
464
465/*
466** Find an SqlFunc structure with the given name. Or create a new
467** one if an existing one cannot be found. Return a pointer to the
468** structure.
469*/
470static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
471 SqlFunc *p, *pNew;
drh0425f182013-11-26 16:48:04 +0000472 int nName = strlen30(zName);
473 pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 );
drhd1e47332005-06-26 17:55:33 +0000474 pNew->zName = (char*)&pNew[1];
drh0425f182013-11-26 16:48:04 +0000475 memcpy(pNew->zName, zName, nName+1);
mistachkinb56660f2016-07-14 21:26:09 +0000476 for(p=pDb->pFunc; p; p=p->pNext){
drh0425f182013-11-26 16:48:04 +0000477 if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){
drhd1e47332005-06-26 17:55:33 +0000478 Tcl_Free((char*)pNew);
479 return p;
480 }
481 }
482 pNew->interp = pDb->interp;
drhc45e6712012-10-03 11:02:33 +0000483 pNew->pDb = pDb;
drhd1e47332005-06-26 17:55:33 +0000484 pNew->pScript = 0;
485 pNew->pNext = pDb->pFunc;
486 pDb->pFunc = pNew;
487 return pNew;
488}
489
490/*
danc431fd52011-06-27 16:55:50 +0000491** Free a single SqlPreparedStmt object.
492*/
493static void dbFreeStmt(SqlPreparedStmt *pStmt){
494#ifdef SQLITE_TEST
495 if( sqlite3_sql(pStmt->pStmt)==0 ){
496 Tcl_Free((char *)pStmt->zSql);
497 }
498#endif
499 sqlite3_finalize(pStmt->pStmt);
500 Tcl_Free((char *)pStmt);
501}
502
503/*
drhfb7e7652005-01-24 00:28:42 +0000504** Finalize and free a list of prepared statements
505*/
danc431fd52011-06-27 16:55:50 +0000506static void flushStmtCache(SqliteDb *pDb){
drhfb7e7652005-01-24 00:28:42 +0000507 SqlPreparedStmt *pPreStmt;
danc431fd52011-06-27 16:55:50 +0000508 SqlPreparedStmt *pNext;
drhfb7e7652005-01-24 00:28:42 +0000509
danc431fd52011-06-27 16:55:50 +0000510 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
511 pNext = pPreStmt->pNext;
512 dbFreeStmt(pPreStmt);
drhfb7e7652005-01-24 00:28:42 +0000513 }
514 pDb->nStmt = 0;
515 pDb->stmtLast = 0;
danc431fd52011-06-27 16:55:50 +0000516 pDb->stmtList = 0;
drhfb7e7652005-01-24 00:28:42 +0000517}
518
519/*
drh895d7472004-08-20 16:02:39 +0000520** TCL calls this procedure when an sqlite3 database command is
521** deleted.
drh75897232000-05-29 14:26:00 +0000522*/
mistachkin7617e4a2016-07-28 17:11:20 +0000523static void SQLITE_TCLAPI DbDeleteCmd(void *db){
drhbec3f402000-08-04 13:49:02 +0000524 SqliteDb *pDb = (SqliteDb*)db;
drhfb7e7652005-01-24 00:28:42 +0000525 flushStmtCache(pDb);
danielk1977d04417962007-05-02 13:16:30 +0000526 closeIncrblobChannels(pDb);
danielk19776f8a5032004-05-10 10:34:51 +0000527 sqlite3_close(pDb->db);
drhcabb0812002-09-14 13:47:32 +0000528 while( pDb->pFunc ){
529 SqlFunc *pFunc = pDb->pFunc;
530 pDb->pFunc = pFunc->pNext;
drhc45e6712012-10-03 11:02:33 +0000531 assert( pFunc->pDb==pDb );
drhd1e47332005-06-26 17:55:33 +0000532 Tcl_DecrRefCount(pFunc->pScript);
drhcabb0812002-09-14 13:47:32 +0000533 Tcl_Free((char*)pFunc);
534 }
danielk19770202b292004-06-09 09:55:16 +0000535 while( pDb->pCollate ){
536 SqlCollate *pCollate = pDb->pCollate;
537 pDb->pCollate = pCollate->pNext;
538 Tcl_Free((char*)pCollate);
539 }
drhbec3f402000-08-04 13:49:02 +0000540 if( pDb->zBusy ){
541 Tcl_Free(pDb->zBusy);
542 }
drhb5a20d32003-04-23 12:25:23 +0000543 if( pDb->zTrace ){
544 Tcl_Free(pDb->zTrace);
drh0d1a6432003-04-03 15:46:04 +0000545 }
mistachkinb56660f2016-07-14 21:26:09 +0000546 if( pDb->zTraceV2 ){
547 Tcl_Free(pDb->zTraceV2);
548 }
drh19e2d372005-08-29 23:00:03 +0000549 if( pDb->zProfile ){
550 Tcl_Free(pDb->zProfile);
551 }
drhe22a3342003-04-22 20:30:37 +0000552 if( pDb->zAuth ){
553 Tcl_Free(pDb->zAuth);
554 }
danielk197755c45f22005-04-03 23:54:43 +0000555 if( pDb->zNull ){
556 Tcl_Free(pDb->zNull);
557 }
danielk197794eb6a12005-12-15 15:22:08 +0000558 if( pDb->pUpdateHook ){
559 Tcl_DecrRefCount(pDb->pUpdateHook);
560 }
dan46c47d42011-03-01 18:42:07 +0000561 if( pDb->pPreUpdateHook ){
562 Tcl_DecrRefCount(pDb->pPreUpdateHook);
563 }
danielk197771fd80b2005-12-16 06:54:01 +0000564 if( pDb->pRollbackHook ){
565 Tcl_DecrRefCount(pDb->pRollbackHook);
566 }
drh5def0842010-05-05 20:00:25 +0000567 if( pDb->pWalHook ){
568 Tcl_DecrRefCount(pDb->pWalHook);
dan8d22a172010-04-19 18:03:51 +0000569 }
danielk197794eb6a12005-12-15 15:22:08 +0000570 if( pDb->pCollateNeeded ){
571 Tcl_DecrRefCount(pDb->pCollateNeeded);
572 }
drhbec3f402000-08-04 13:49:02 +0000573 Tcl_Free((char*)pDb);
574}
575
576/*
577** This routine is called when a database file is locked while trying
578** to execute SQL.
579*/
danielk19772a764eb2004-06-12 01:43:26 +0000580static int DbBusyHandler(void *cd, int nTries){
drhbec3f402000-08-04 13:49:02 +0000581 SqliteDb *pDb = (SqliteDb*)cd;
582 int rc;
583 char zVal[30];
drhbec3f402000-08-04 13:49:02 +0000584
drh5bb3eb92007-05-04 13:15:55 +0000585 sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);
drhd1e47332005-06-26 17:55:33 +0000586 rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);
drhbec3f402000-08-04 13:49:02 +0000587 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
588 return 0;
589 }
590 return 1;
drh75897232000-05-29 14:26:00 +0000591}
592
drh26e4a8b2008-05-01 17:16:52 +0000593#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
drh75897232000-05-29 14:26:00 +0000594/*
danielk1977348bb5d2003-10-18 09:37:26 +0000595** This routine is invoked as the 'progress callback' for the database.
596*/
597static int DbProgressHandler(void *cd){
598 SqliteDb *pDb = (SqliteDb*)cd;
599 int rc;
600
601 assert( pDb->zProgress );
602 rc = Tcl_Eval(pDb->interp, pDb->zProgress);
603 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
604 return 1;
605 }
606 return 0;
607}
drh26e4a8b2008-05-01 17:16:52 +0000608#endif
danielk1977348bb5d2003-10-18 09:37:26 +0000609
drh2eb22af2016-09-10 19:51:40 +0000610#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
611 !defined(SQLITE_OMIT_DEPRECATED)
danielk1977348bb5d2003-10-18 09:37:26 +0000612/*
drhb5a20d32003-04-23 12:25:23 +0000613** This routine is called by the SQLite trace handler whenever a new
614** block of SQL is executed. The TCL script in pDb->zTrace is executed.
drh0d1a6432003-04-03 15:46:04 +0000615*/
drhb5a20d32003-04-23 12:25:23 +0000616static void DbTraceHandler(void *cd, const char *zSql){
drh0d1a6432003-04-03 15:46:04 +0000617 SqliteDb *pDb = (SqliteDb*)cd;
drhb5a20d32003-04-23 12:25:23 +0000618 Tcl_DString str;
drh0d1a6432003-04-03 15:46:04 +0000619
drhb5a20d32003-04-23 12:25:23 +0000620 Tcl_DStringInit(&str);
621 Tcl_DStringAppend(&str, pDb->zTrace, -1);
622 Tcl_DStringAppendElement(&str, zSql);
623 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
624 Tcl_DStringFree(&str);
625 Tcl_ResetResult(pDb->interp);
drh0d1a6432003-04-03 15:46:04 +0000626}
drhd1167392006-01-23 13:00:35 +0000627#endif
drh0d1a6432003-04-03 15:46:04 +0000628
drhd1167392006-01-23 13:00:35 +0000629#ifndef SQLITE_OMIT_TRACE
drh0d1a6432003-04-03 15:46:04 +0000630/*
mistachkinb56660f2016-07-14 21:26:09 +0000631** This routine is called by the SQLite trace_v2 handler whenever a new
632** supported event is generated. Unsupported event types are ignored.
633** The TCL script in pDb->zTraceV2 is executed, with the arguments for
634** the event appended to it (as list elements).
635*/
636static int DbTraceV2Handler(
637 unsigned type, /* One of the SQLITE_TRACE_* event types. */
638 void *cd, /* The original context data pointer. */
639 void *pd, /* Primary event data, depends on event type. */
640 void *xd /* Extra event data, depends on event type. */
641){
642 SqliteDb *pDb = (SqliteDb*)cd;
643 Tcl_Obj *pCmd;
644
645 switch( type ){
646 case SQLITE_TRACE_STMT: {
647 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
648 char *zSql = (char *)xd;
649
650 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
651 Tcl_IncrRefCount(pCmd);
652 Tcl_ListObjAppendElement(pDb->interp, pCmd,
653 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
654 Tcl_ListObjAppendElement(pDb->interp, pCmd,
655 Tcl_NewStringObj(zSql, -1));
656 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
657 Tcl_DecrRefCount(pCmd);
658 Tcl_ResetResult(pDb->interp);
659 break;
660 }
661 case SQLITE_TRACE_PROFILE: {
662 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
drhffdab722018-03-10 20:25:08 +0000663 sqlite3_int64 ns = *(sqlite3_int64*)xd;
mistachkinb56660f2016-07-14 21:26:09 +0000664
665 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
666 Tcl_IncrRefCount(pCmd);
667 Tcl_ListObjAppendElement(pDb->interp, pCmd,
668 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
669 Tcl_ListObjAppendElement(pDb->interp, pCmd,
670 Tcl_NewWideIntObj((Tcl_WideInt)ns));
671 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
672 Tcl_DecrRefCount(pCmd);
673 Tcl_ResetResult(pDb->interp);
674 break;
675 }
676 case SQLITE_TRACE_ROW: {
677 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
678
679 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
680 Tcl_IncrRefCount(pCmd);
681 Tcl_ListObjAppendElement(pDb->interp, pCmd,
682 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
683 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
684 Tcl_DecrRefCount(pCmd);
685 Tcl_ResetResult(pDb->interp);
686 break;
687 }
688 case SQLITE_TRACE_CLOSE: {
689 sqlite3 *db = (sqlite3 *)pd;
690
691 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
692 Tcl_IncrRefCount(pCmd);
693 Tcl_ListObjAppendElement(pDb->interp, pCmd,
694 Tcl_NewWideIntObj((Tcl_WideInt)db));
695 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
696 Tcl_DecrRefCount(pCmd);
697 Tcl_ResetResult(pDb->interp);
698 break;
699 }
700 }
701 return SQLITE_OK;
702}
703#endif
704
drh2eb22af2016-09-10 19:51:40 +0000705#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
706 !defined(SQLITE_OMIT_DEPRECATED)
mistachkinb56660f2016-07-14 21:26:09 +0000707/*
drh19e2d372005-08-29 23:00:03 +0000708** This routine is called by the SQLite profile handler after a statement
709** SQL has executed. The TCL script in pDb->zProfile is evaluated.
710*/
711static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
712 SqliteDb *pDb = (SqliteDb*)cd;
713 Tcl_DString str;
714 char zTm[100];
715
716 sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
717 Tcl_DStringInit(&str);
718 Tcl_DStringAppend(&str, pDb->zProfile, -1);
719 Tcl_DStringAppendElement(&str, zSql);
720 Tcl_DStringAppendElement(&str, zTm);
721 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
722 Tcl_DStringFree(&str);
723 Tcl_ResetResult(pDb->interp);
724}
drhd1167392006-01-23 13:00:35 +0000725#endif
drh19e2d372005-08-29 23:00:03 +0000726
727/*
drhaa940ea2004-01-15 02:44:03 +0000728** This routine is called when a transaction is committed. The
729** TCL script in pDb->zCommit is executed. If it returns non-zero or
730** if it throws an exception, the transaction is rolled back instead
731** of being committed.
732*/
733static int DbCommitHandler(void *cd){
734 SqliteDb *pDb = (SqliteDb*)cd;
735 int rc;
736
737 rc = Tcl_Eval(pDb->interp, pDb->zCommit);
738 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
739 return 1;
740 }
741 return 0;
742}
743
danielk197771fd80b2005-12-16 06:54:01 +0000744static void DbRollbackHandler(void *clientData){
745 SqliteDb *pDb = (SqliteDb*)clientData;
746 assert(pDb->pRollbackHook);
747 if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){
748 Tcl_BackgroundError(pDb->interp);
749 }
750}
751
drh5def0842010-05-05 20:00:25 +0000752/*
753** This procedure handles wal_hook callbacks.
754*/
755static int DbWalHandler(
mistachkinb56660f2016-07-14 21:26:09 +0000756 void *clientData,
757 sqlite3 *db,
758 const char *zDb,
dan8d22a172010-04-19 18:03:51 +0000759 int nEntry
760){
drh5def0842010-05-05 20:00:25 +0000761 int ret = SQLITE_OK;
dan8d22a172010-04-19 18:03:51 +0000762 Tcl_Obj *p;
763 SqliteDb *pDb = (SqliteDb*)clientData;
764 Tcl_Interp *interp = pDb->interp;
drh5def0842010-05-05 20:00:25 +0000765 assert(pDb->pWalHook);
dan8d22a172010-04-19 18:03:51 +0000766
dan6e45e0c2014-12-10 20:29:49 +0000767 assert( db==pDb->db );
drh5def0842010-05-05 20:00:25 +0000768 p = Tcl_DuplicateObj(pDb->pWalHook);
dan8d22a172010-04-19 18:03:51 +0000769 Tcl_IncrRefCount(p);
770 Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
771 Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
mistachkinb56660f2016-07-14 21:26:09 +0000772 if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
dan8d22a172010-04-19 18:03:51 +0000773 || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
774 ){
775 Tcl_BackgroundError(interp);
776 }
777 Tcl_DecrRefCount(p);
778
779 return ret;
780}
781
drhbcf4f482009-03-27 12:44:35 +0000782#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
danielk1977404ca072009-03-16 13:19:36 +0000783static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
784 char zBuf[64];
drh65545b52015-01-19 00:35:53 +0000785 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iArg);
danielk1977404ca072009-03-16 13:19:36 +0000786 Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
drh65545b52015-01-19 00:35:53 +0000787 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nArg);
danielk1977404ca072009-03-16 13:19:36 +0000788 Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
789}
790#else
drhbcf4f482009-03-27 12:44:35 +0000791# define setTestUnlockNotifyVars(x,y,z)
danielk1977404ca072009-03-16 13:19:36 +0000792#endif
793
drh69910da2009-03-27 12:32:54 +0000794#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
danielk1977404ca072009-03-16 13:19:36 +0000795static void DbUnlockNotify(void **apArg, int nArg){
796 int i;
797 for(i=0; i<nArg; i++){
798 const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
799 SqliteDb *pDb = (SqliteDb *)apArg[i];
800 setTestUnlockNotifyVars(pDb->interp, i, nArg);
801 assert( pDb->pUnlockNotify);
802 Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
803 Tcl_DecrRefCount(pDb->pUnlockNotify);
804 pDb->pUnlockNotify = 0;
805 }
806}
drh69910da2009-03-27 12:32:54 +0000807#endif
danielk1977404ca072009-03-16 13:19:36 +0000808
drh9b1c62d2011-03-30 21:04:43 +0000809#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
dan46c47d42011-03-01 18:42:07 +0000810/*
811** Pre-update hook callback.
812*/
813static void DbPreUpdateHandler(
mistachkinb56660f2016-07-14 21:26:09 +0000814 void *p,
dan46c47d42011-03-01 18:42:07 +0000815 sqlite3 *db,
816 int op,
mistachkinb56660f2016-07-14 21:26:09 +0000817 const char *zDb,
818 const char *zTbl,
dan46c47d42011-03-01 18:42:07 +0000819 sqlite_int64 iKey1,
820 sqlite_int64 iKey2
821){
822 SqliteDb *pDb = (SqliteDb *)p;
823 Tcl_Obj *pCmd;
824 static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
825
826 assert( (SQLITE_DELETE-1)/9 == 0 );
827 assert( (SQLITE_INSERT-1)/9 == 1 );
828 assert( (SQLITE_UPDATE-1)/9 == 2 );
829 assert( pDb->pPreUpdateHook );
830 assert( db==pDb->db );
831 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
832
833 pCmd = Tcl_DuplicateObj(pDb->pPreUpdateHook);
834 Tcl_IncrRefCount(pCmd);
835 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
836 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
837 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
838 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey1));
839 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey2));
840 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
841 Tcl_DecrRefCount(pCmd);
842}
drh9b1c62d2011-03-30 21:04:43 +0000843#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
dan46c47d42011-03-01 18:42:07 +0000844
danielk197794eb6a12005-12-15 15:22:08 +0000845static void DbUpdateHandler(
mistachkinb56660f2016-07-14 21:26:09 +0000846 void *p,
danielk197794eb6a12005-12-15 15:22:08 +0000847 int op,
mistachkinb56660f2016-07-14 21:26:09 +0000848 const char *zDb,
849 const char *zTbl,
danielk197794eb6a12005-12-15 15:22:08 +0000850 sqlite_int64 rowid
851){
852 SqliteDb *pDb = (SqliteDb *)p;
853 Tcl_Obj *pCmd;
dan46c47d42011-03-01 18:42:07 +0000854 static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
855
856 assert( (SQLITE_DELETE-1)/9 == 0 );
857 assert( (SQLITE_INSERT-1)/9 == 1 );
858 assert( (SQLITE_UPDATE-1)/9 == 2 );
danielk197794eb6a12005-12-15 15:22:08 +0000859
860 assert( pDb->pUpdateHook );
861 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
862
863 pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
864 Tcl_IncrRefCount(pCmd);
dan46c47d42011-03-01 18:42:07 +0000865 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
danielk197794eb6a12005-12-15 15:22:08 +0000866 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
867 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
868 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
869 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
drhefdde162010-10-27 15:36:21 +0000870 Tcl_DecrRefCount(pCmd);
danielk197794eb6a12005-12-15 15:22:08 +0000871}
872
danielk19777cedc8d2004-06-10 10:50:08 +0000873static void tclCollateNeeded(
874 void *pCtx,
drh9bb575f2004-09-06 17:24:11 +0000875 sqlite3 *db,
danielk19777cedc8d2004-06-10 10:50:08 +0000876 int enc,
877 const char *zName
878){
879 SqliteDb *pDb = (SqliteDb *)pCtx;
880 Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
881 Tcl_IncrRefCount(pScript);
882 Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
883 Tcl_EvalObjEx(pDb->interp, pScript, 0);
884 Tcl_DecrRefCount(pScript);
885}
886
drhaa940ea2004-01-15 02:44:03 +0000887/*
danielk19770202b292004-06-09 09:55:16 +0000888** This routine is called to evaluate an SQL collation function implemented
889** using TCL script.
890*/
891static int tclSqlCollate(
892 void *pCtx,
893 int nA,
894 const void *zA,
895 int nB,
896 const void *zB
897){
898 SqlCollate *p = (SqlCollate *)pCtx;
899 Tcl_Obj *pCmd;
900
901 pCmd = Tcl_NewStringObj(p->zScript, -1);
902 Tcl_IncrRefCount(pCmd);
903 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
904 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
drhd1e47332005-06-26 17:55:33 +0000905 Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
danielk19770202b292004-06-09 09:55:16 +0000906 Tcl_DecrRefCount(pCmd);
907 return (atoi(Tcl_GetStringResult(p->interp)));
908}
909
910/*
drhcabb0812002-09-14 13:47:32 +0000911** This routine is called to evaluate an SQL function implemented
912** using TCL script.
913*/
drhfb7e7652005-01-24 00:28:42 +0000914static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
danielk19776f8a5032004-05-10 10:34:51 +0000915 SqlFunc *p = sqlite3_user_data(context);
drhd1e47332005-06-26 17:55:33 +0000916 Tcl_Obj *pCmd;
drhcabb0812002-09-14 13:47:32 +0000917 int i;
918 int rc;
919
drhd1e47332005-06-26 17:55:33 +0000920 if( argc==0 ){
921 /* If there are no arguments to the function, call Tcl_EvalObjEx on the
922 ** script object directly. This allows the TCL compiler to generate
923 ** bytecode for the command on the first invocation and thus make
924 ** subsequent invocations much faster. */
925 pCmd = p->pScript;
926 Tcl_IncrRefCount(pCmd);
927 rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
928 Tcl_DecrRefCount(pCmd);
929 }else{
930 /* If there are arguments to the function, make a shallow copy of the
931 ** script object, lappend the arguments, then evaluate the copy.
932 **
peter.d.reid60ec9142014-09-06 16:39:46 +0000933 ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated.
mistachkinb56660f2016-07-14 21:26:09 +0000934 ** The new Tcl_Obj contains pointers to the original list elements.
drhd1e47332005-06-26 17:55:33 +0000935 ** That way, when Tcl_EvalObjv() is run and shimmers the first element
936 ** of the list to tclCmdNameType, that alternate representation will
937 ** be preserved and reused on the next invocation.
938 */
939 Tcl_Obj **aArg;
940 int nArg;
941 if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
mistachkinb56660f2016-07-14 21:26:09 +0000942 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
drhd1e47332005-06-26 17:55:33 +0000943 return;
mistachkinb56660f2016-07-14 21:26:09 +0000944 }
drhd1e47332005-06-26 17:55:33 +0000945 pCmd = Tcl_NewListObj(nArg, aArg);
946 Tcl_IncrRefCount(pCmd);
947 for(i=0; i<argc; i++){
948 sqlite3_value *pIn = argv[i];
949 Tcl_Obj *pVal;
mistachkinb56660f2016-07-14 21:26:09 +0000950
drhd1e47332005-06-26 17:55:33 +0000951 /* Set pVal to contain the i'th column of this row. */
952 switch( sqlite3_value_type(pIn) ){
953 case SQLITE_BLOB: {
954 int bytes = sqlite3_value_bytes(pIn);
955 pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
956 break;
957 }
958 case SQLITE_INTEGER: {
959 sqlite_int64 v = sqlite3_value_int64(pIn);
960 if( v>=-2147483647 && v<=2147483647 ){
drh7fd33922011-06-20 19:00:30 +0000961 pVal = Tcl_NewIntObj((int)v);
drhd1e47332005-06-26 17:55:33 +0000962 }else{
963 pVal = Tcl_NewWideIntObj(v);
964 }
965 break;
966 }
967 case SQLITE_FLOAT: {
968 double r = sqlite3_value_double(pIn);
969 pVal = Tcl_NewDoubleObj(r);
970 break;
971 }
972 case SQLITE_NULL: {
drhc45e6712012-10-03 11:02:33 +0000973 pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
drhd1e47332005-06-26 17:55:33 +0000974 break;
975 }
976 default: {
977 int bytes = sqlite3_value_bytes(pIn);
danielk197700fd9572005-12-07 06:27:43 +0000978 pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
drhd1e47332005-06-26 17:55:33 +0000979 break;
980 }
981 }
982 rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
983 if( rc ){
984 Tcl_DecrRefCount(pCmd);
mistachkinb56660f2016-07-14 21:26:09 +0000985 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
drhd1e47332005-06-26 17:55:33 +0000986 return;
987 }
danielk197751ad0ec2004-05-24 12:39:02 +0000988 }
drhd1e47332005-06-26 17:55:33 +0000989 if( !p->useEvalObjv ){
990 /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
991 ** is a list without a string representation. To prevent this from
992 ** happening, make sure pCmd has a valid string representation */
993 Tcl_GetString(pCmd);
994 }
995 rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
996 Tcl_DecrRefCount(pCmd);
drhcabb0812002-09-14 13:47:32 +0000997 }
danielk1977562e8d32005-05-20 09:40:55 +0000998
drhc7f269d2005-05-05 10:30:29 +0000999 if( rc && rc!=TCL_RETURN ){
mistachkinb56660f2016-07-14 21:26:09 +00001000 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
drhcabb0812002-09-14 13:47:32 +00001001 }else{
drhc7f269d2005-05-05 10:30:29 +00001002 Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
1003 int n;
1004 u8 *data;
dan4a4c11a2009-10-06 14:59:02 +00001005 const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
drhc7f269d2005-05-05 10:30:29 +00001006 char c = zType[0];
dan89d24932019-02-27 16:38:19 +00001007 int eType = p->eType;
1008
1009 if( eType==SQLITE_NULL ){
1010 if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
1011 /* Only return a BLOB type if the Tcl variable is a bytearray and
1012 ** has no string representation. */
1013 eType = SQLITE_BLOB;
1014 }else if( (c=='b' && strcmp(zType,"boolean")==0)
1015 || (c=='w' && strcmp(zType,"wideInt")==0)
1016 || (c=='i' && strcmp(zType,"int")==0)
1017 ){
1018 eType = SQLITE_INTEGER;
1019 }else if( c=='d' && strcmp(zType,"double")==0 ){
1020 eType = SQLITE_FLOAT;
1021 }else{
1022 eType = SQLITE_TEXT;
1023 }
drhc7f269d2005-05-05 10:30:29 +00001024 }
dan89d24932019-02-27 16:38:19 +00001025
1026 switch( eType ){
1027 case SQLITE_BLOB: {
1028 data = Tcl_GetByteArrayFromObj(pVar, &n);
1029 sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
1030 break;
1031 }
1032 case SQLITE_INTEGER: {
1033 Tcl_WideInt v;
1034 if( TCL_OK==Tcl_GetWideIntFromObj(0, pVar, &v) ){
1035 sqlite3_result_int64(context, v);
1036 break;
1037 }
1038 /* fall-through */
1039 }
1040 case SQLITE_FLOAT: {
1041 double r;
1042 if( TCL_OK==Tcl_GetDoubleFromObj(0, pVar, &r) ){
1043 sqlite3_result_double(context, r);
1044 break;
1045 }
1046 /* fall-through */
1047 }
1048 default: {
1049 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
1050 sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
1051 break;
1052 }
1053 }
1054
drhcabb0812002-09-14 13:47:32 +00001055 }
1056}
drh895d7472004-08-20 16:02:39 +00001057
drhe22a3342003-04-22 20:30:37 +00001058#ifndef SQLITE_OMIT_AUTHORIZATION
1059/*
1060** This is the authentication function. It appends the authentication
1061** type code and the two arguments to zCmd[] then invokes the result
1062** on the interpreter. The reply is examined to determine if the
1063** authentication fails or succeeds.
1064*/
1065static int auth_callback(
1066 void *pArg,
1067 int code,
1068 const char *zArg1,
1069 const char *zArg2,
1070 const char *zArg3,
1071 const char *zArg4
drh32c6a482014-09-11 13:44:52 +00001072#ifdef SQLITE_USER_AUTHENTICATION
1073 ,const char *zArg5
1074#endif
drhe22a3342003-04-22 20:30:37 +00001075){
mistachkin6ef5e122014-01-24 17:03:55 +00001076 const char *zCode;
drhe22a3342003-04-22 20:30:37 +00001077 Tcl_DString str;
1078 int rc;
1079 const char *zReply;
drh94189212017-05-11 13:43:57 +00001080 /* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer
1081 ** callback is a copy of the third parameter to the
1082 ** sqlite3_set_authorizer() interface.
1083 */
drhe22a3342003-04-22 20:30:37 +00001084 SqliteDb *pDb = (SqliteDb*)pArg;
drh1f1549f2008-08-26 21:33:34 +00001085 if( pDb->disableAuth ) return SQLITE_OK;
drhe22a3342003-04-22 20:30:37 +00001086
drh94189212017-05-11 13:43:57 +00001087 /* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an
1088 ** integer action code that specifies the particular action to be
1089 ** authorized. */
drhe22a3342003-04-22 20:30:37 +00001090 switch( code ){
1091 case SQLITE_COPY : zCode="SQLITE_COPY"; break;
1092 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
1093 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
1094 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
1095 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
1096 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
1097 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
1098 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break;
1099 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break;
1100 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break;
1101 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break;
1102 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break;
1103 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break;
1104 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break;
1105 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
1106 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break;
1107 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break;
1108 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break;
1109 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break;
1110 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break;
1111 case SQLITE_READ : zCode="SQLITE_READ"; break;
1112 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break;
1113 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break;
1114 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break;
drh81e293b2003-06-06 19:00:42 +00001115 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break;
1116 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break;
danielk19771c8c23c2004-11-12 15:53:37 +00001117 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break;
danielk19771d54df82004-11-23 15:41:16 +00001118 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break;
drhe6e04962005-07-23 02:17:03 +00001119 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break;
danielk1977f1a381e2006-06-16 08:01:02 +00001120 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break;
1121 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break;
drh5169bbc2006-08-24 14:59:45 +00001122 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break;
danielk1977ab9b7032008-12-30 06:24:58 +00001123 case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break;
drh65a2aaa2014-01-16 22:40:02 +00001124 case SQLITE_RECURSIVE : zCode="SQLITE_RECURSIVE"; break;
drhe22a3342003-04-22 20:30:37 +00001125 default : zCode="????"; break;
1126 }
1127 Tcl_DStringInit(&str);
1128 Tcl_DStringAppend(&str, pDb->zAuth, -1);
1129 Tcl_DStringAppendElement(&str, zCode);
1130 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
1131 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
1132 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
1133 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
drh32c6a482014-09-11 13:44:52 +00001134#ifdef SQLITE_USER_AUTHENTICATION
1135 Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
mistachkinb56660f2016-07-14 21:26:09 +00001136#endif
drhe22a3342003-04-22 20:30:37 +00001137 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
1138 Tcl_DStringFree(&str);
drhb07028f2011-10-14 21:49:18 +00001139 zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
drhe22a3342003-04-22 20:30:37 +00001140 if( strcmp(zReply,"SQLITE_OK")==0 ){
1141 rc = SQLITE_OK;
1142 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
1143 rc = SQLITE_DENY;
1144 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
1145 rc = SQLITE_IGNORE;
1146 }else{
1147 rc = 999;
1148 }
1149 return rc;
1150}
1151#endif /* SQLITE_OMIT_AUTHORIZATION */
drhcabb0812002-09-14 13:47:32 +00001152
1153/*
tpoindex1067fe12004-12-17 15:41:11 +00001154** This routine reads a line of text from FILE in, stores
1155** the text in memory obtained from malloc() and returns a pointer
1156** to the text. NULL is returned at end of file, or if malloc()
1157** fails.
1158**
1159** The interface is like "readline" but no command-line editing
1160** is done.
1161**
1162** copied from shell.c from '.import' command
1163*/
1164static char *local_getline(char *zPrompt, FILE *in){
1165 char *zLine;
1166 int nLine;
1167 int n;
tpoindex1067fe12004-12-17 15:41:11 +00001168
1169 nLine = 100;
1170 zLine = malloc( nLine );
1171 if( zLine==0 ) return 0;
1172 n = 0;
drhb07028f2011-10-14 21:49:18 +00001173 while( 1 ){
tpoindex1067fe12004-12-17 15:41:11 +00001174 if( n+100>nLine ){
1175 nLine = nLine*2 + 100;
1176 zLine = realloc(zLine, nLine);
1177 if( zLine==0 ) return 0;
1178 }
1179 if( fgets(&zLine[n], nLine - n, in)==0 ){
1180 if( n==0 ){
1181 free(zLine);
1182 return 0;
1183 }
1184 zLine[n] = 0;
tpoindex1067fe12004-12-17 15:41:11 +00001185 break;
1186 }
1187 while( zLine[n] ){ n++; }
1188 if( n>0 && zLine[n-1]=='\n' ){
1189 n--;
1190 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +00001191 break;
tpoindex1067fe12004-12-17 15:41:11 +00001192 }
1193 }
1194 zLine = realloc( zLine, n+1 );
1195 return zLine;
1196}
1197
danielk19778e556522007-11-13 10:30:24 +00001198
1199/*
dan4a4c11a2009-10-06 14:59:02 +00001200** This function is part of the implementation of the command:
danielk19778e556522007-11-13 10:30:24 +00001201**
dan4a4c11a2009-10-06 14:59:02 +00001202** $db transaction [-deferred|-immediate|-exclusive] SCRIPT
danielk19778e556522007-11-13 10:30:24 +00001203**
dan4a4c11a2009-10-06 14:59:02 +00001204** It is invoked after evaluating the script SCRIPT to commit or rollback
1205** the transaction or savepoint opened by the [transaction] command.
1206*/
mistachkina121cc72016-07-28 18:06:52 +00001207static int SQLITE_TCLAPI DbTransPostCmd(
dan4a4c11a2009-10-06 14:59:02 +00001208 ClientData data[], /* data[0] is the Sqlite3Db* for $db */
1209 Tcl_Interp *interp, /* Tcl interpreter */
1210 int result /* Result of evaluating SCRIPT */
1211){
mistachkin6ef5e122014-01-24 17:03:55 +00001212 static const char *const azEnd[] = {
dan4a4c11a2009-10-06 14:59:02 +00001213 "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */
1214 "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */
1215 "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
1216 "ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */
1217 };
1218 SqliteDb *pDb = (SqliteDb*)data[0];
1219 int rc = result;
1220 const char *zEnd;
1221
1222 pDb->nTransaction--;
1223 zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];
1224
1225 pDb->disableAuth++;
1226 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
1227 /* This is a tricky scenario to handle. The most likely cause of an
mistachkinb56660f2016-07-14 21:26:09 +00001228 ** error is that the exec() above was an attempt to commit the
dan4a4c11a2009-10-06 14:59:02 +00001229 ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
mistachkin48864df2013-03-21 21:20:32 +00001230 ** that an IO-error has occurred. In either case, throw a Tcl exception
dan4a4c11a2009-10-06 14:59:02 +00001231 ** and try to rollback the transaction.
1232 **
mistachkinb56660f2016-07-14 21:26:09 +00001233 ** But it could also be that the user executed one or more BEGIN,
dan4a4c11a2009-10-06 14:59:02 +00001234 ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
1235 ** this method's logic. Not clear how this would be best handled.
1236 */
1237 if( rc!=TCL_ERROR ){
drha198f2b2014-02-07 19:26:13 +00001238 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
dan4a4c11a2009-10-06 14:59:02 +00001239 rc = TCL_ERROR;
1240 }
1241 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
1242 }
1243 pDb->disableAuth--;
1244
1245 return rc;
1246}
1247
1248/*
danc431fd52011-06-27 16:55:50 +00001249** Unless SQLITE_TEST is defined, this function is a simple wrapper around
1250** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
1251** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
mistachkinb56660f2016-07-14 21:26:09 +00001252** on whether or not the [db_use_legacy_prepare] command has been used to
danc431fd52011-06-27 16:55:50 +00001253** configure the connection.
1254*/
1255static int dbPrepare(
1256 SqliteDb *pDb, /* Database object */
1257 const char *zSql, /* SQL to compile */
1258 sqlite3_stmt **ppStmt, /* OUT: Prepared statement */
1259 const char **pzOut /* OUT: Pointer to next SQL statement */
1260){
drh2c2f3922017-06-01 00:54:35 +00001261 unsigned int prepFlags = 0;
danc431fd52011-06-27 16:55:50 +00001262#ifdef SQLITE_TEST
1263 if( pDb->bLegacyPrepare ){
1264 return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
1265 }
1266#endif
drh2c2f3922017-06-01 00:54:35 +00001267 /* If the statement cache is large, use the SQLITE_PREPARE_PERSISTENT
1268 ** flags, which uses less lookaside memory. But if the cache is small,
1269 ** omit that flag to make full use of lookaside */
1270 if( pDb->maxStmt>5 ) prepFlags = SQLITE_PREPARE_PERSISTENT;
1271
1272 return sqlite3_prepare_v3(pDb->db, zSql, -1, prepFlags, ppStmt, pzOut);
danc431fd52011-06-27 16:55:50 +00001273}
1274
1275/*
dan4a4c11a2009-10-06 14:59:02 +00001276** Search the cache for a prepared-statement object that implements the
1277** first SQL statement in the buffer pointed to by parameter zIn. If
1278** no such prepared-statement can be found, allocate and prepare a new
1279** one. In either case, bind the current values of the relevant Tcl
1280** variables to any $var, :var or @var variables in the statement. Before
1281** returning, set *ppPreStmt to point to the prepared-statement object.
1282**
1283** Output parameter *pzOut is set to point to the next SQL statement in
1284** buffer zIn, or to the '\0' byte at the end of zIn if there is no
1285** next statement.
1286**
1287** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned
1288** and an error message loaded into interpreter pDb->interp.
1289*/
1290static int dbPrepareAndBind(
1291 SqliteDb *pDb, /* Database object */
1292 char const *zIn, /* SQL to compile */
1293 char const **pzOut, /* OUT: Pointer to next SQL statement */
1294 SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */
1295){
1296 const char *zSql = zIn; /* Pointer to first SQL statement in zIn */
mistachkin7bb22ac2015-01-12 19:59:12 +00001297 sqlite3_stmt *pStmt = 0; /* Prepared statement object */
dan4a4c11a2009-10-06 14:59:02 +00001298 SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */
1299 int nSql; /* Length of zSql in bytes */
mistachkin7bb22ac2015-01-12 19:59:12 +00001300 int nVar = 0; /* Number of variables in statement */
dan4a4c11a2009-10-06 14:59:02 +00001301 int iParm = 0; /* Next free entry in apParm */
drh0425f182013-11-26 16:48:04 +00001302 char c;
dan4a4c11a2009-10-06 14:59:02 +00001303 int i;
1304 Tcl_Interp *interp = pDb->interp;
1305
1306 *ppPreStmt = 0;
1307
1308 /* Trim spaces from the start of zSql and calculate the remaining length. */
drh0425f182013-11-26 16:48:04 +00001309 while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; }
dan4a4c11a2009-10-06 14:59:02 +00001310 nSql = strlen30(zSql);
1311
1312 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
1313 int n = pPreStmt->nSql;
mistachkinb56660f2016-07-14 21:26:09 +00001314 if( nSql>=n
dan4a4c11a2009-10-06 14:59:02 +00001315 && memcmp(pPreStmt->zSql, zSql, n)==0
1316 && (zSql[n]==0 || zSql[n-1]==';')
1317 ){
1318 pStmt = pPreStmt->pStmt;
1319 *pzOut = &zSql[pPreStmt->nSql];
1320
1321 /* When a prepared statement is found, unlink it from the
1322 ** cache list. It will later be added back to the beginning
1323 ** of the cache list in order to implement LRU replacement.
1324 */
1325 if( pPreStmt->pPrev ){
1326 pPreStmt->pPrev->pNext = pPreStmt->pNext;
1327 }else{
1328 pDb->stmtList = pPreStmt->pNext;
1329 }
1330 if( pPreStmt->pNext ){
1331 pPreStmt->pNext->pPrev = pPreStmt->pPrev;
1332 }else{
1333 pDb->stmtLast = pPreStmt->pPrev;
1334 }
1335 pDb->nStmt--;
1336 nVar = sqlite3_bind_parameter_count(pStmt);
1337 break;
1338 }
1339 }
mistachkinb56660f2016-07-14 21:26:09 +00001340
dan4a4c11a2009-10-06 14:59:02 +00001341 /* If no prepared statement was found. Compile the SQL text. Also allocate
1342 ** a new SqlPreparedStmt structure. */
1343 if( pPreStmt==0 ){
1344 int nByte;
1345
danc431fd52011-06-27 16:55:50 +00001346 if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
drhc45e6712012-10-03 11:02:33 +00001347 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
dan4a4c11a2009-10-06 14:59:02 +00001348 return TCL_ERROR;
1349 }
1350 if( pStmt==0 ){
1351 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
1352 /* A compile-time error in the statement. */
drhc45e6712012-10-03 11:02:33 +00001353 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
dan4a4c11a2009-10-06 14:59:02 +00001354 return TCL_ERROR;
1355 }else{
1356 /* The statement was a no-op. Continue to the next statement
1357 ** in the SQL string.
1358 */
1359 return TCL_OK;
1360 }
1361 }
1362
1363 assert( pPreStmt==0 );
1364 nVar = sqlite3_bind_parameter_count(pStmt);
1365 nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *);
1366 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte);
1367 memset(pPreStmt, 0, nByte);
1368
1369 pPreStmt->pStmt = pStmt;
drh7ed243b2012-04-19 17:19:51 +00001370 pPreStmt->nSql = (int)(*pzOut - zSql);
dan4a4c11a2009-10-06 14:59:02 +00001371 pPreStmt->zSql = sqlite3_sql(pStmt);
1372 pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
danc431fd52011-06-27 16:55:50 +00001373#ifdef SQLITE_TEST
1374 if( pPreStmt->zSql==0 ){
1375 char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
1376 memcpy(zCopy, zSql, pPreStmt->nSql);
1377 zCopy[pPreStmt->nSql] = '\0';
1378 pPreStmt->zSql = zCopy;
1379 }
1380#endif
dan4a4c11a2009-10-06 14:59:02 +00001381 }
1382 assert( pPreStmt );
1383 assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
1384 assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
1385
mistachkinb56660f2016-07-14 21:26:09 +00001386 /* Bind values to parameters that begin with $ or : */
dan4a4c11a2009-10-06 14:59:02 +00001387 for(i=1; i<=nVar; i++){
1388 const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
1389 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
1390 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
1391 if( pVar ){
1392 int n;
1393 u8 *data;
1394 const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
mistachkin8e189222015-04-19 21:43:16 +00001395 c = zType[0];
dan4a4c11a2009-10-06 14:59:02 +00001396 if( zVar[0]=='@' ||
1397 (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
1398 /* Load a BLOB type if the Tcl variable is a bytearray and
1399 ** it has no string representation or the host
1400 ** parameter name begins with "@". */
1401 data = Tcl_GetByteArrayFromObj(pVar, &n);
1402 sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
1403 Tcl_IncrRefCount(pVar);
1404 pPreStmt->apParm[iParm++] = pVar;
1405 }else if( c=='b' && strcmp(zType,"boolean")==0 ){
1406 Tcl_GetIntFromObj(interp, pVar, &n);
1407 sqlite3_bind_int(pStmt, i, n);
1408 }else if( c=='d' && strcmp(zType,"double")==0 ){
1409 double r;
1410 Tcl_GetDoubleFromObj(interp, pVar, &r);
1411 sqlite3_bind_double(pStmt, i, r);
1412 }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
1413 (c=='i' && strcmp(zType,"int")==0) ){
1414 Tcl_WideInt v;
1415 Tcl_GetWideIntFromObj(interp, pVar, &v);
1416 sqlite3_bind_int64(pStmt, i, v);
1417 }else{
1418 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
1419 sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
1420 Tcl_IncrRefCount(pVar);
1421 pPreStmt->apParm[iParm++] = pVar;
1422 }
1423 }else{
1424 sqlite3_bind_null(pStmt, i);
1425 }
1426 }
1427 }
1428 pPreStmt->nParm = iParm;
1429 *ppPreStmt = pPreStmt;
dan937d0de2009-10-15 18:35:38 +00001430
dan4a4c11a2009-10-06 14:59:02 +00001431 return TCL_OK;
1432}
1433
dan4a4c11a2009-10-06 14:59:02 +00001434/*
1435** Release a statement reference obtained by calling dbPrepareAndBind().
1436** There should be exactly one call to this function for each call to
1437** dbPrepareAndBind().
1438**
1439** If the discard parameter is non-zero, then the statement is deleted
1440** immediately. Otherwise it is added to the LRU list and may be returned
1441** by a subsequent call to dbPrepareAndBind().
1442*/
1443static void dbReleaseStmt(
1444 SqliteDb *pDb, /* Database handle */
1445 SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */
1446 int discard /* True to delete (not cache) the pPreStmt */
1447){
1448 int i;
1449
1450 /* Free the bound string and blob parameters */
1451 for(i=0; i<pPreStmt->nParm; i++){
1452 Tcl_DecrRefCount(pPreStmt->apParm[i]);
1453 }
1454 pPreStmt->nParm = 0;
1455
1456 if( pDb->maxStmt<=0 || discard ){
1457 /* If the cache is turned off, deallocated the statement */
danc431fd52011-06-27 16:55:50 +00001458 dbFreeStmt(pPreStmt);
dan4a4c11a2009-10-06 14:59:02 +00001459 }else{
1460 /* Add the prepared statement to the beginning of the cache list. */
1461 pPreStmt->pNext = pDb->stmtList;
1462 pPreStmt->pPrev = 0;
1463 if( pDb->stmtList ){
1464 pDb->stmtList->pPrev = pPreStmt;
1465 }
1466 pDb->stmtList = pPreStmt;
1467 if( pDb->stmtLast==0 ){
1468 assert( pDb->nStmt==0 );
1469 pDb->stmtLast = pPreStmt;
1470 }else{
1471 assert( pDb->nStmt>0 );
1472 }
1473 pDb->nStmt++;
mistachkinb56660f2016-07-14 21:26:09 +00001474
1475 /* If we have too many statement in cache, remove the surplus from
dan4a4c11a2009-10-06 14:59:02 +00001476 ** the end of the cache list. */
1477 while( pDb->nStmt>pDb->maxStmt ){
danc431fd52011-06-27 16:55:50 +00001478 SqlPreparedStmt *pLast = pDb->stmtLast;
1479 pDb->stmtLast = pLast->pPrev;
dan4a4c11a2009-10-06 14:59:02 +00001480 pDb->stmtLast->pNext = 0;
1481 pDb->nStmt--;
danc431fd52011-06-27 16:55:50 +00001482 dbFreeStmt(pLast);
dan4a4c11a2009-10-06 14:59:02 +00001483 }
1484 }
1485}
1486
1487/*
1488** Structure used with dbEvalXXX() functions:
1489**
1490** dbEvalInit()
1491** dbEvalStep()
1492** dbEvalFinalize()
1493** dbEvalRowInfo()
1494** dbEvalColumnValue()
1495*/
1496typedef struct DbEvalContext DbEvalContext;
1497struct DbEvalContext {
1498 SqliteDb *pDb; /* Database handle */
1499 Tcl_Obj *pSql; /* Object holding string zSql */
1500 const char *zSql; /* Remaining SQL to execute */
1501 SqlPreparedStmt *pPreStmt; /* Current statement */
1502 int nCol; /* Number of columns returned by pStmt */
drhaf38cdb2017-06-26 21:08:32 +00001503 int evalFlags; /* Flags used */
dan4a4c11a2009-10-06 14:59:02 +00001504 Tcl_Obj *pArray; /* Name of array variable */
1505 Tcl_Obj **apColName; /* Array of column names */
1506};
1507
drhaf38cdb2017-06-26 21:08:32 +00001508#define SQLITE_EVAL_WITHOUTNULLS 0x00001 /* Unset array(*) for NULL */
1509
dan4a4c11a2009-10-06 14:59:02 +00001510/*
1511** Release any cache of column names currently held as part of
1512** the DbEvalContext structure passed as the first argument.
1513*/
1514static void dbReleaseColumnNames(DbEvalContext *p){
1515 if( p->apColName ){
1516 int i;
1517 for(i=0; i<p->nCol; i++){
1518 Tcl_DecrRefCount(p->apColName[i]);
1519 }
1520 Tcl_Free((char *)p->apColName);
1521 p->apColName = 0;
1522 }
1523 p->nCol = 0;
1524}
1525
1526/*
1527** Initialize a DbEvalContext structure.
danielk19778e556522007-11-13 10:30:24 +00001528**
1529** If pArray is not NULL, then it contains the name of a Tcl array
1530** variable. The "*" member of this array is set to a list containing
dan4a4c11a2009-10-06 14:59:02 +00001531** the names of the columns returned by the statement as part of each
mistachkinb56660f2016-07-14 21:26:09 +00001532** call to dbEvalStep(), in order from left to right. e.g. if the names
1533** of the returned columns are a, b and c, it does the equivalent of the
dan4a4c11a2009-10-06 14:59:02 +00001534** tcl command:
danielk19778e556522007-11-13 10:30:24 +00001535**
1536** set ${pArray}(*) {a b c}
1537*/
dan4a4c11a2009-10-06 14:59:02 +00001538static void dbEvalInit(
1539 DbEvalContext *p, /* Pointer to structure to initialize */
1540 SqliteDb *pDb, /* Database handle */
1541 Tcl_Obj *pSql, /* Object containing SQL script */
drhaf38cdb2017-06-26 21:08:32 +00001542 Tcl_Obj *pArray, /* Name of Tcl array to set (*) element of */
1543 int evalFlags /* Flags controlling evaluation */
danielk19778e556522007-11-13 10:30:24 +00001544){
dan4a4c11a2009-10-06 14:59:02 +00001545 memset(p, 0, sizeof(DbEvalContext));
1546 p->pDb = pDb;
1547 p->zSql = Tcl_GetString(pSql);
1548 p->pSql = pSql;
1549 Tcl_IncrRefCount(pSql);
1550 if( pArray ){
1551 p->pArray = pArray;
1552 Tcl_IncrRefCount(pArray);
1553 }
drhaf38cdb2017-06-26 21:08:32 +00001554 p->evalFlags = evalFlags;
dan4a4c11a2009-10-06 14:59:02 +00001555}
danielk19778e556522007-11-13 10:30:24 +00001556
dan4a4c11a2009-10-06 14:59:02 +00001557/*
1558** Obtain information about the row that the DbEvalContext passed as the
1559** first argument currently points to.
1560*/
1561static void dbEvalRowInfo(
1562 DbEvalContext *p, /* Evaluation context */
1563 int *pnCol, /* OUT: Number of column names */
1564 Tcl_Obj ***papColName /* OUT: Array of column names */
1565){
danielk19778e556522007-11-13 10:30:24 +00001566 /* Compute column names */
dan4a4c11a2009-10-06 14:59:02 +00001567 if( 0==p->apColName ){
1568 sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
1569 int i; /* Iterator variable */
1570 int nCol; /* Number of columns returned by pStmt */
1571 Tcl_Obj **apColName = 0; /* Array of column names */
1572
1573 p->nCol = nCol = sqlite3_column_count(pStmt);
1574 if( nCol>0 && (papColName || p->pArray) ){
1575 apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
1576 for(i=0; i<nCol; i++){
drhc45e6712012-10-03 11:02:33 +00001577 apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
dan4a4c11a2009-10-06 14:59:02 +00001578 Tcl_IncrRefCount(apColName[i]);
1579 }
1580 p->apColName = apColName;
danielk19778e556522007-11-13 10:30:24 +00001581 }
1582
1583 /* If results are being stored in an array variable, then create
1584 ** the array(*) entry for that array
1585 */
dan4a4c11a2009-10-06 14:59:02 +00001586 if( p->pArray ){
1587 Tcl_Interp *interp = p->pDb->interp;
danielk19778e556522007-11-13 10:30:24 +00001588 Tcl_Obj *pColList = Tcl_NewObj();
1589 Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
dan4a4c11a2009-10-06 14:59:02 +00001590
danielk19778e556522007-11-13 10:30:24 +00001591 for(i=0; i<nCol; i++){
1592 Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
1593 }
1594 Tcl_IncrRefCount(pStar);
dan4a4c11a2009-10-06 14:59:02 +00001595 Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0);
danielk19778e556522007-11-13 10:30:24 +00001596 Tcl_DecrRefCount(pStar);
1597 }
danielk19778e556522007-11-13 10:30:24 +00001598 }
1599
dan4a4c11a2009-10-06 14:59:02 +00001600 if( papColName ){
1601 *papColName = p->apColName;
1602 }
1603 if( pnCol ){
1604 *pnCol = p->nCol;
1605 }
1606}
1607
1608/*
1609** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is
1610** returned, then an error message is stored in the interpreter before
1611** returning.
1612**
1613** A return value of TCL_OK means there is a row of data available. The
1614** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
1615** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK
1616** is returned, then the SQL script has finished executing and there are
1617** no further rows available. This is similar to SQLITE_DONE.
1618*/
1619static int dbEvalStep(DbEvalContext *p){
danc431fd52011-06-27 16:55:50 +00001620 const char *zPrevSql = 0; /* Previous value of p->zSql */
1621
dan4a4c11a2009-10-06 14:59:02 +00001622 while( p->zSql[0] || p->pPreStmt ){
1623 int rc;
1624 if( p->pPreStmt==0 ){
danc431fd52011-06-27 16:55:50 +00001625 zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
dan4a4c11a2009-10-06 14:59:02 +00001626 rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
1627 if( rc!=TCL_OK ) return rc;
1628 }else{
1629 int rcs;
1630 SqliteDb *pDb = p->pDb;
1631 SqlPreparedStmt *pPreStmt = p->pPreStmt;
1632 sqlite3_stmt *pStmt = pPreStmt->pStmt;
1633
1634 rcs = sqlite3_step(pStmt);
1635 if( rcs==SQLITE_ROW ){
1636 return TCL_OK;
1637 }
1638 if( p->pArray ){
1639 dbEvalRowInfo(p, 0, 0);
1640 }
1641 rcs = sqlite3_reset(pStmt);
1642
1643 pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
1644 pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
drh3c379b02010-04-07 19:31:59 +00001645 pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
danc456a762017-06-22 16:51:16 +00001646 pDb->nVMStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_VM_STEP,1);
dan4a4c11a2009-10-06 14:59:02 +00001647 dbReleaseColumnNames(p);
1648 p->pPreStmt = 0;
1649
1650 if( rcs!=SQLITE_OK ){
1651 /* If a run-time error occurs, report the error and stop reading
1652 ** the SQL. */
dan4a4c11a2009-10-06 14:59:02 +00001653 dbReleaseStmt(pDb, pPreStmt, 1);
danc431fd52011-06-27 16:55:50 +00001654#if SQLITE_TEST
1655 if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
1656 /* If the runtime error was an SQLITE_SCHEMA, and the database
mistachkinb56660f2016-07-14 21:26:09 +00001657 ** handle is configured to use the legacy sqlite3_prepare()
danc431fd52011-06-27 16:55:50 +00001658 ** interface, retry prepare()/step() on the same SQL statement.
1659 ** This only happens once. If there is a second SQLITE_SCHEMA
1660 ** error, the error will be returned to the caller. */
1661 p->zSql = zPrevSql;
1662 continue;
1663 }
1664#endif
drhc45e6712012-10-03 11:02:33 +00001665 Tcl_SetObjResult(pDb->interp,
1666 Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
dan4a4c11a2009-10-06 14:59:02 +00001667 return TCL_ERROR;
1668 }else{
1669 dbReleaseStmt(pDb, pPreStmt, 0);
1670 }
1671 }
1672 }
1673
1674 /* Finished */
1675 return TCL_BREAK;
1676}
1677
1678/*
1679** Free all resources currently held by the DbEvalContext structure passed
1680** as the first argument. There should be exactly one call to this function
1681** for each call to dbEvalInit().
1682*/
1683static void dbEvalFinalize(DbEvalContext *p){
1684 if( p->pPreStmt ){
1685 sqlite3_reset(p->pPreStmt->pStmt);
1686 dbReleaseStmt(p->pDb, p->pPreStmt, 0);
1687 p->pPreStmt = 0;
1688 }
1689 if( p->pArray ){
1690 Tcl_DecrRefCount(p->pArray);
1691 p->pArray = 0;
1692 }
1693 Tcl_DecrRefCount(p->pSql);
1694 dbReleaseColumnNames(p);
1695}
1696
1697/*
1698** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
1699** the value for the iCol'th column of the row currently pointed to by
1700** the DbEvalContext structure passed as the first argument.
1701*/
1702static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
1703 sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
1704 switch( sqlite3_column_type(pStmt, iCol) ){
1705 case SQLITE_BLOB: {
1706 int bytes = sqlite3_column_bytes(pStmt, iCol);
1707 const char *zBlob = sqlite3_column_blob(pStmt, iCol);
1708 if( !zBlob ) bytes = 0;
1709 return Tcl_NewByteArrayObj((u8*)zBlob, bytes);
1710 }
1711 case SQLITE_INTEGER: {
1712 sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
1713 if( v>=-2147483647 && v<=2147483647 ){
drh7fd33922011-06-20 19:00:30 +00001714 return Tcl_NewIntObj((int)v);
dan4a4c11a2009-10-06 14:59:02 +00001715 }else{
1716 return Tcl_NewWideIntObj(v);
1717 }
1718 }
1719 case SQLITE_FLOAT: {
1720 return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
1721 }
1722 case SQLITE_NULL: {
drhc45e6712012-10-03 11:02:33 +00001723 return Tcl_NewStringObj(p->pDb->zNull, -1);
dan4a4c11a2009-10-06 14:59:02 +00001724 }
1725 }
1726
drh325eff52012-10-03 12:56:18 +00001727 return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
dan4a4c11a2009-10-06 14:59:02 +00001728}
1729
1730/*
1731** If using Tcl version 8.6 or greater, use the NR functions to avoid
1732** recursive evalution of scripts by the [db eval] and [db trans]
1733** commands. Even if the headers used while compiling the extension
1734** are 8.6 or newer, the code still tests the Tcl version at runtime.
1735** This allows stubs-enabled builds to be used with older Tcl libraries.
1736*/
1737#if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6)
drha2c8a952009-10-13 18:38:34 +00001738# define SQLITE_TCL_NRE 1
dan4a4c11a2009-10-06 14:59:02 +00001739static int DbUseNre(void){
1740 int major, minor;
1741 Tcl_GetVersion(&major, &minor, 0, 0);
1742 return( (major==8 && minor>=6) || major>8 );
1743}
1744#else
mistachkinb56660f2016-07-14 21:26:09 +00001745/*
dan4a4c11a2009-10-06 14:59:02 +00001746** Compiling using headers earlier than 8.6. In this case NR cannot be
1747** used, so DbUseNre() to always return zero. Add #defines for the other
1748** Tcl_NRxxx() functions to prevent them from causing compilation errors,
mistachkinb56660f2016-07-14 21:26:09 +00001749** even though the only invocations of them are within conditional blocks
dan4a4c11a2009-10-06 14:59:02 +00001750** of the form:
1751**
1752** if( DbUseNre() ) { ... }
1753*/
drha2c8a952009-10-13 18:38:34 +00001754# define SQLITE_TCL_NRE 0
dan4a4c11a2009-10-06 14:59:02 +00001755# define DbUseNre() 0
drha47941f2013-12-20 18:57:44 +00001756# define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0
dan4a4c11a2009-10-06 14:59:02 +00001757# define Tcl_NREvalObj(a,b,c) 0
drha47941f2013-12-20 18:57:44 +00001758# define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0
dan4a4c11a2009-10-06 14:59:02 +00001759#endif
1760
1761/*
1762** This function is part of the implementation of the command:
1763**
1764** $db eval SQL ?ARRAYNAME? SCRIPT
1765*/
mistachkina121cc72016-07-28 18:06:52 +00001766static int SQLITE_TCLAPI DbEvalNextCmd(
dan4a4c11a2009-10-06 14:59:02 +00001767 ClientData data[], /* data[0] is the (DbEvalContext*) */
1768 Tcl_Interp *interp, /* Tcl interpreter */
1769 int result /* Result so far */
1770){
1771 int rc = result; /* Return code */
1772
1773 /* The first element of the data[] array is a pointer to a DbEvalContext
1774 ** structure allocated using Tcl_Alloc(). The second element of data[]
1775 ** is a pointer to a Tcl_Obj containing the script to run for each row
1776 ** returned by the queries encapsulated in data[0]. */
1777 DbEvalContext *p = (DbEvalContext *)data[0];
1778 Tcl_Obj *pScript = (Tcl_Obj *)data[1];
1779 Tcl_Obj *pArray = p->pArray;
1780
1781 while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){
1782 int i;
1783 int nCol;
1784 Tcl_Obj **apColName;
1785 dbEvalRowInfo(p, &nCol, &apColName);
1786 for(i=0; i<nCol; i++){
dan4a4c11a2009-10-06 14:59:02 +00001787 if( pArray==0 ){
drhaf38cdb2017-06-26 21:08:32 +00001788 Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0);
1789 }else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0
1790 && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL
1791 ){
1792 Tcl_UnsetVar2(interp, Tcl_GetString(pArray),
1793 Tcl_GetString(apColName[i]), 0);
dan4a4c11a2009-10-06 14:59:02 +00001794 }else{
drhaf38cdb2017-06-26 21:08:32 +00001795 Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0);
dan4a4c11a2009-10-06 14:59:02 +00001796 }
1797 }
1798
mistachkinb56660f2016-07-14 21:26:09 +00001799 /* The required interpreter variables are now populated with the data
dan4a4c11a2009-10-06 14:59:02 +00001800 ** from the current row. If using NRE, schedule callbacks to evaluate
1801 ** script pScript, then to invoke this function again to fetch the next
1802 ** row (or clean up if there is no next row or the script throws an
mistachkinb56660f2016-07-14 21:26:09 +00001803 ** exception). After scheduling the callbacks, return control to the
dan4a4c11a2009-10-06 14:59:02 +00001804 ** caller.
1805 **
1806 ** If not using NRE, evaluate pScript directly and continue with the
1807 ** next iteration of this while(...) loop. */
1808 if( DbUseNre() ){
1809 Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0);
1810 return Tcl_NREvalObj(interp, pScript, 0);
1811 }else{
1812 rc = Tcl_EvalObjEx(interp, pScript, 0);
1813 }
1814 }
1815
1816 Tcl_DecrRefCount(pScript);
1817 dbEvalFinalize(p);
1818 Tcl_Free((char *)p);
1819
1820 if( rc==TCL_OK || rc==TCL_BREAK ){
1821 Tcl_ResetResult(interp);
1822 rc = TCL_OK;
1823 }
1824 return rc;
danielk19778e556522007-11-13 10:30:24 +00001825}
1826
tpoindex1067fe12004-12-17 15:41:11 +00001827/*
mistachkinb56660f2016-07-14 21:26:09 +00001828** This function is used by the implementations of the following database
dan46c47d42011-03-01 18:42:07 +00001829** handle sub-commands:
1830**
1831** $db update_hook ?SCRIPT?
1832** $db wal_hook ?SCRIPT?
1833** $db commit_hook ?SCRIPT?
1834** $db preupdate hook ?SCRIPT?
1835*/
1836static void DbHookCmd(
1837 Tcl_Interp *interp, /* Tcl interpreter */
1838 SqliteDb *pDb, /* Database handle */
1839 Tcl_Obj *pArg, /* SCRIPT argument (or NULL) */
1840 Tcl_Obj **ppHook /* Pointer to member of SqliteDb */
1841){
1842 sqlite3 *db = pDb->db;
1843
1844 if( *ppHook ){
1845 Tcl_SetObjResult(interp, *ppHook);
1846 if( pArg ){
1847 Tcl_DecrRefCount(*ppHook);
1848 *ppHook = 0;
1849 }
1850 }
1851 if( pArg ){
1852 assert( !(*ppHook) );
1853 if( Tcl_GetCharLength(pArg)>0 ){
1854 *ppHook = pArg;
1855 Tcl_IncrRefCount(*ppHook);
1856 }
1857 }
1858
drh9b1c62d2011-03-30 21:04:43 +00001859#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
dan46c47d42011-03-01 18:42:07 +00001860 sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb);
drh9b1c62d2011-03-30 21:04:43 +00001861#endif
dan46c47d42011-03-01 18:42:07 +00001862 sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
1863 sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb);
1864 sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb);
1865}
1866
1867/*
drh75897232000-05-29 14:26:00 +00001868** The "sqlite" command below creates a new Tcl command for each
1869** connection it opens to an SQLite database. This routine is invoked
1870** whenever one of those connection-specific commands is executed
1871** in Tcl. For example, if you run Tcl code like this:
1872**
drh9bb575f2004-09-06 17:24:11 +00001873** sqlite3 db1 "my_database"
drh75897232000-05-29 14:26:00 +00001874** db1 close
1875**
1876** The first command opens a connection to the "my_database" database
1877** and calls that connection "db1". The second command causes this
1878** subroutine to be invoked.
1879*/
mistachkin7617e4a2016-07-28 17:11:20 +00001880static int SQLITE_TCLAPI DbObjCmd(
1881 void *cd,
1882 Tcl_Interp *interp,
1883 int objc,
1884 Tcl_Obj *const*objv
1885){
drhbec3f402000-08-04 13:49:02 +00001886 SqliteDb *pDb = (SqliteDb*)cd;
drh6d313162000-09-21 13:01:35 +00001887 int choice;
drh22fbcb82004-02-01 01:22:50 +00001888 int rc = TCL_OK;
drh0de8c112002-07-06 16:32:14 +00001889 static const char *DB_strs[] = {
drhcb7d5412018-01-03 16:49:52 +00001890 "authorizer", "backup", "busy",
1891 "cache", "changes", "close",
1892 "collate", "collation_needed", "commit_hook",
1893 "complete", "copy", "deserialize",
1894 "enable_load_extension", "errorcode", "eval",
1895 "exists", "function", "incrblob",
drh3ec86652018-01-03 19:03:31 +00001896 "interrupt", "last_insert_rowid", "nullvalue",
1897 "onecolumn", "preupdate", "profile",
1898 "progress", "rekey", "restore",
1899 "rollback_hook", "serialize", "status",
1900 "timeout", "total_changes", "trace",
1901 "trace_v2", "transaction", "unlock_notify",
1902 "update_hook", "version", "wal_hook",
1903 0
drh6d313162000-09-21 13:01:35 +00001904 };
drh411995d2002-06-25 19:31:18 +00001905 enum DB_enum {
drhcb7d5412018-01-03 16:49:52 +00001906 DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
1907 DB_CACHE, DB_CHANGES, DB_CLOSE,
1908 DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
1909 DB_COMPLETE, DB_COPY, DB_DESERIALIZE,
1910 DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL,
1911 DB_EXISTS, DB_FUNCTION, DB_INCRBLOB,
drh3ec86652018-01-03 19:03:31 +00001912 DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE,
1913 DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE,
1914 DB_PROGRESS, DB_REKEY, DB_RESTORE,
1915 DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS,
1916 DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
1917 DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
1918 DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK
drh6d313162000-09-21 13:01:35 +00001919 };
tpoindex1067fe12004-12-17 15:41:11 +00001920 /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
drh6d313162000-09-21 13:01:35 +00001921
1922 if( objc<2 ){
1923 Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
drh75897232000-05-29 14:26:00 +00001924 return TCL_ERROR;
1925 }
drh411995d2002-06-25 19:31:18 +00001926 if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
drh6d313162000-09-21 13:01:35 +00001927 return TCL_ERROR;
1928 }
1929
drh411995d2002-06-25 19:31:18 +00001930 switch( (enum DB_enum)choice ){
drh75897232000-05-29 14:26:00 +00001931
drhe22a3342003-04-22 20:30:37 +00001932 /* $db authorizer ?CALLBACK?
1933 **
1934 ** Invoke the given callback to authorize each SQL operation as it is
1935 ** compiled. 5 arguments are appended to the callback before it is
1936 ** invoked:
1937 **
1938 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
1939 ** (2) First descriptive name (depends on authorization type)
1940 ** (3) Second descriptive name
1941 ** (4) Name of the database (ex: "main", "temp")
1942 ** (5) Name of trigger that is doing the access
1943 **
1944 ** The callback should return on of the following strings: SQLITE_OK,
1945 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error.
1946 **
1947 ** If this method is invoked with no arguments, the current authorization
1948 ** callback string is returned.
1949 */
1950 case DB_AUTHORIZER: {
drh1211de32004-07-26 12:24:22 +00001951#ifdef SQLITE_OMIT_AUTHORIZATION
drha198f2b2014-02-07 19:26:13 +00001952 Tcl_AppendResult(interp, "authorization not available in this build",
1953 (char*)0);
drh1211de32004-07-26 12:24:22 +00001954 return TCL_ERROR;
1955#else
drhe22a3342003-04-22 20:30:37 +00001956 if( objc>3 ){
1957 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
drh0f14e2e2004-06-29 12:39:08 +00001958 return TCL_ERROR;
drhe22a3342003-04-22 20:30:37 +00001959 }else if( objc==2 ){
drhb5a20d32003-04-23 12:25:23 +00001960 if( pDb->zAuth ){
drha198f2b2014-02-07 19:26:13 +00001961 Tcl_AppendResult(interp, pDb->zAuth, (char*)0);
drhe22a3342003-04-22 20:30:37 +00001962 }
1963 }else{
1964 char *zAuth;
1965 int len;
1966 if( pDb->zAuth ){
1967 Tcl_Free(pDb->zAuth);
1968 }
1969 zAuth = Tcl_GetStringFromObj(objv[2], &len);
1970 if( zAuth && len>0 ){
1971 pDb->zAuth = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00001972 memcpy(pDb->zAuth, zAuth, len+1);
drhe22a3342003-04-22 20:30:37 +00001973 }else{
1974 pDb->zAuth = 0;
1975 }
drhe22a3342003-04-22 20:30:37 +00001976 if( pDb->zAuth ){
drh32c6a482014-09-11 13:44:52 +00001977 typedef int (*sqlite3_auth_cb)(
1978 void*,int,const char*,const char*,
1979 const char*,const char*);
drhe22a3342003-04-22 20:30:37 +00001980 pDb->interp = interp;
drh32c6a482014-09-11 13:44:52 +00001981 sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb);
drhe22a3342003-04-22 20:30:37 +00001982 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001983 sqlite3_set_authorizer(pDb->db, 0, 0);
drhe22a3342003-04-22 20:30:37 +00001984 }
drhe22a3342003-04-22 20:30:37 +00001985 }
drh1211de32004-07-26 12:24:22 +00001986#endif
drhe22a3342003-04-22 20:30:37 +00001987 break;
1988 }
1989
drhdc2c4912009-02-04 22:46:47 +00001990 /* $db backup ?DATABASE? FILENAME
1991 **
1992 ** Open or create a database file named FILENAME. Transfer the
1993 ** content of local database DATABASE (default: "main") into the
1994 ** FILENAME database.
1995 */
1996 case DB_BACKUP: {
1997 const char *zDestFile;
1998 const char *zSrcDb;
1999 sqlite3 *pDest;
2000 sqlite3_backup *pBackup;
2001
2002 if( objc==3 ){
2003 zSrcDb = "main";
2004 zDestFile = Tcl_GetString(objv[2]);
2005 }else if( objc==4 ){
2006 zSrcDb = Tcl_GetString(objv[2]);
2007 zDestFile = Tcl_GetString(objv[3]);
2008 }else{
2009 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
2010 return TCL_ERROR;
2011 }
drh147ef392016-01-22 23:17:51 +00002012 rc = sqlite3_open_v2(zDestFile, &pDest,
2013 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0);
drhdc2c4912009-02-04 22:46:47 +00002014 if( rc!=SQLITE_OK ){
2015 Tcl_AppendResult(interp, "cannot open target database: ",
2016 sqlite3_errmsg(pDest), (char*)0);
2017 sqlite3_close(pDest);
2018 return TCL_ERROR;
2019 }
2020 pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
2021 if( pBackup==0 ){
2022 Tcl_AppendResult(interp, "backup failed: ",
2023 sqlite3_errmsg(pDest), (char*)0);
2024 sqlite3_close(pDest);
2025 return TCL_ERROR;
2026 }
2027 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2028 sqlite3_backup_finish(pBackup);
2029 if( rc==SQLITE_DONE ){
2030 rc = TCL_OK;
2031 }else{
2032 Tcl_AppendResult(interp, "backup failed: ",
2033 sqlite3_errmsg(pDest), (char*)0);
2034 rc = TCL_ERROR;
2035 }
2036 sqlite3_close(pDest);
2037 break;
2038 }
2039
drhbec3f402000-08-04 13:49:02 +00002040 /* $db busy ?CALLBACK?
2041 **
2042 ** Invoke the given callback if an SQL statement attempts to open
2043 ** a locked database file.
2044 */
drh6d313162000-09-21 13:01:35 +00002045 case DB_BUSY: {
2046 if( objc>3 ){
2047 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
drhbec3f402000-08-04 13:49:02 +00002048 return TCL_ERROR;
drh6d313162000-09-21 13:01:35 +00002049 }else if( objc==2 ){
drhbec3f402000-08-04 13:49:02 +00002050 if( pDb->zBusy ){
drha198f2b2014-02-07 19:26:13 +00002051 Tcl_AppendResult(interp, pDb->zBusy, (char*)0);
drhbec3f402000-08-04 13:49:02 +00002052 }
2053 }else{
drh6d313162000-09-21 13:01:35 +00002054 char *zBusy;
2055 int len;
drhbec3f402000-08-04 13:49:02 +00002056 if( pDb->zBusy ){
2057 Tcl_Free(pDb->zBusy);
drhbec3f402000-08-04 13:49:02 +00002058 }
drh6d313162000-09-21 13:01:35 +00002059 zBusy = Tcl_GetStringFromObj(objv[2], &len);
2060 if( zBusy && len>0 ){
2061 pDb->zBusy = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00002062 memcpy(pDb->zBusy, zBusy, len+1);
drh6d313162000-09-21 13:01:35 +00002063 }else{
2064 pDb->zBusy = 0;
drhbec3f402000-08-04 13:49:02 +00002065 }
2066 if( pDb->zBusy ){
2067 pDb->interp = interp;
danielk19776f8a5032004-05-10 10:34:51 +00002068 sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
drh6d313162000-09-21 13:01:35 +00002069 }else{
danielk19776f8a5032004-05-10 10:34:51 +00002070 sqlite3_busy_handler(pDb->db, 0, 0);
drhbec3f402000-08-04 13:49:02 +00002071 }
2072 }
drh6d313162000-09-21 13:01:35 +00002073 break;
2074 }
drhbec3f402000-08-04 13:49:02 +00002075
drhfb7e7652005-01-24 00:28:42 +00002076 /* $db cache flush
2077 ** $db cache size n
2078 **
2079 ** Flush the prepared statement cache, or set the maximum number of
2080 ** cached statements.
2081 */
2082 case DB_CACHE: {
2083 char *subCmd;
2084 int n;
2085
2086 if( objc<=2 ){
2087 Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
2088 return TCL_ERROR;
2089 }
2090 subCmd = Tcl_GetStringFromObj( objv[2], 0 );
2091 if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
2092 if( objc!=3 ){
2093 Tcl_WrongNumArgs(interp, 2, objv, "flush");
2094 return TCL_ERROR;
2095 }else{
2096 flushStmtCache( pDb );
2097 }
2098 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
2099 if( objc!=4 ){
2100 Tcl_WrongNumArgs(interp, 2, objv, "size n");
2101 return TCL_ERROR;
2102 }else{
2103 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
mistachkinb56660f2016-07-14 21:26:09 +00002104 Tcl_AppendResult( interp, "cannot convert \"",
drha198f2b2014-02-07 19:26:13 +00002105 Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
drhfb7e7652005-01-24 00:28:42 +00002106 return TCL_ERROR;
2107 }else{
2108 if( n<0 ){
2109 flushStmtCache( pDb );
2110 n = 0;
2111 }else if( n>MAX_PREPARED_STMTS ){
2112 n = MAX_PREPARED_STMTS;
2113 }
2114 pDb->maxStmt = n;
2115 }
2116 }
2117 }else{
mistachkinb56660f2016-07-14 21:26:09 +00002118 Tcl_AppendResult( interp, "bad option \"",
drha198f2b2014-02-07 19:26:13 +00002119 Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
2120 (char*)0);
drhfb7e7652005-01-24 00:28:42 +00002121 return TCL_ERROR;
2122 }
2123 break;
2124 }
2125
danielk1977b28af712004-06-21 06:50:26 +00002126 /* $db changes
drhc8d30ac2002-04-12 10:08:59 +00002127 **
2128 ** Return the number of rows that were modified, inserted, or deleted by
mistachkinb56660f2016-07-14 21:26:09 +00002129 ** the most recent INSERT, UPDATE or DELETE statement, not including
danielk1977b28af712004-06-21 06:50:26 +00002130 ** any changes made by trigger programs.
drhc8d30ac2002-04-12 10:08:59 +00002131 */
2132 case DB_CHANGES: {
2133 Tcl_Obj *pResult;
drhc8d30ac2002-04-12 10:08:59 +00002134 if( objc!=2 ){
2135 Tcl_WrongNumArgs(interp, 2, objv, "");
2136 return TCL_ERROR;
2137 }
drhc8d30ac2002-04-12 10:08:59 +00002138 pResult = Tcl_GetObjResult(interp);
danielk1977b28af712004-06-21 06:50:26 +00002139 Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
rdcf146a772004-02-25 22:51:06 +00002140 break;
2141 }
2142
drh75897232000-05-29 14:26:00 +00002143 /* $db close
2144 **
2145 ** Shutdown the database
2146 */
drh6d313162000-09-21 13:01:35 +00002147 case DB_CLOSE: {
2148 Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
2149 break;
2150 }
drh75897232000-05-29 14:26:00 +00002151
drh0f14e2e2004-06-29 12:39:08 +00002152 /*
2153 ** $db collate NAME SCRIPT
2154 **
2155 ** Create a new SQL collation function called NAME. Whenever
2156 ** that function is called, invoke SCRIPT to evaluate the function.
2157 */
2158 case DB_COLLATE: {
2159 SqlCollate *pCollate;
2160 char *zName;
2161 char *zScript;
2162 int nScript;
2163 if( objc!=4 ){
2164 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
2165 return TCL_ERROR;
2166 }
2167 zName = Tcl_GetStringFromObj(objv[2], 0);
2168 zScript = Tcl_GetStringFromObj(objv[3], &nScript);
2169 pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
2170 if( pCollate==0 ) return TCL_ERROR;
2171 pCollate->interp = interp;
2172 pCollate->pNext = pDb->pCollate;
2173 pCollate->zScript = (char*)&pCollate[1];
2174 pDb->pCollate = pCollate;
drh5bb3eb92007-05-04 13:15:55 +00002175 memcpy(pCollate->zScript, zScript, nScript+1);
mistachkinb56660f2016-07-14 21:26:09 +00002176 if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
drh0f14e2e2004-06-29 12:39:08 +00002177 pCollate, tclSqlCollate) ){
danielk19779636c4e2005-01-25 04:27:54 +00002178 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
drh0f14e2e2004-06-29 12:39:08 +00002179 return TCL_ERROR;
2180 }
2181 break;
2182 }
2183
2184 /*
2185 ** $db collation_needed SCRIPT
2186 **
2187 ** Create a new SQL collation function called NAME. Whenever
2188 ** that function is called, invoke SCRIPT to evaluate the function.
2189 */
2190 case DB_COLLATION_NEEDED: {
2191 if( objc!=3 ){
2192 Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
2193 return TCL_ERROR;
2194 }
2195 if( pDb->pCollateNeeded ){
2196 Tcl_DecrRefCount(pDb->pCollateNeeded);
2197 }
2198 pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
2199 Tcl_IncrRefCount(pDb->pCollateNeeded);
2200 sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
2201 break;
2202 }
2203
drh19e2d372005-08-29 23:00:03 +00002204 /* $db commit_hook ?CALLBACK?
2205 **
2206 ** Invoke the given callback just before committing every SQL transaction.
2207 ** If the callback throws an exception or returns non-zero, then the
2208 ** transaction is aborted. If CALLBACK is an empty string, the callback
2209 ** is disabled.
2210 */
2211 case DB_COMMIT_HOOK: {
2212 if( objc>3 ){
2213 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
2214 return TCL_ERROR;
2215 }else if( objc==2 ){
2216 if( pDb->zCommit ){
drha198f2b2014-02-07 19:26:13 +00002217 Tcl_AppendResult(interp, pDb->zCommit, (char*)0);
drh19e2d372005-08-29 23:00:03 +00002218 }
2219 }else{
mistachkin6ef5e122014-01-24 17:03:55 +00002220 const char *zCommit;
drh19e2d372005-08-29 23:00:03 +00002221 int len;
2222 if( pDb->zCommit ){
2223 Tcl_Free(pDb->zCommit);
2224 }
2225 zCommit = Tcl_GetStringFromObj(objv[2], &len);
2226 if( zCommit && len>0 ){
2227 pDb->zCommit = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00002228 memcpy(pDb->zCommit, zCommit, len+1);
drh19e2d372005-08-29 23:00:03 +00002229 }else{
2230 pDb->zCommit = 0;
2231 }
2232 if( pDb->zCommit ){
2233 pDb->interp = interp;
2234 sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
2235 }else{
2236 sqlite3_commit_hook(pDb->db, 0, 0);
2237 }
2238 }
2239 break;
2240 }
2241
drh75897232000-05-29 14:26:00 +00002242 /* $db complete SQL
2243 **
2244 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if
2245 ** additional lines of input are needed. This is similar to the
2246 ** built-in "info complete" command of Tcl.
2247 */
drh6d313162000-09-21 13:01:35 +00002248 case DB_COMPLETE: {
drhccae6022005-02-26 17:31:26 +00002249#ifndef SQLITE_OMIT_COMPLETE
drh6d313162000-09-21 13:01:35 +00002250 Tcl_Obj *pResult;
2251 int isComplete;
2252 if( objc!=3 ){
2253 Tcl_WrongNumArgs(interp, 2, objv, "SQL");
drh75897232000-05-29 14:26:00 +00002254 return TCL_ERROR;
2255 }
danielk19776f8a5032004-05-10 10:34:51 +00002256 isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
drh6d313162000-09-21 13:01:35 +00002257 pResult = Tcl_GetObjResult(interp);
2258 Tcl_SetBooleanObj(pResult, isComplete);
drhccae6022005-02-26 17:31:26 +00002259#endif
drh6d313162000-09-21 13:01:35 +00002260 break;
2261 }
drhdcd997e2003-01-31 17:21:49 +00002262
drh19e2d372005-08-29 23:00:03 +00002263 /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
2264 **
2265 ** Copy data into table from filename, optionally using SEPARATOR
2266 ** as column separators. If a column contains a null string, or the
2267 ** value of NULLINDICATOR, a NULL is inserted for the column.
2268 ** conflict-algorithm is one of the sqlite conflict algorithms:
2269 ** rollback, abort, fail, ignore, replace
2270 ** On success, return the number of lines processed, not necessarily same
2271 ** as 'db changes' due to conflict-algorithm selected.
2272 **
2273 ** This code is basically an implementation/enhancement of
2274 ** the sqlite3 shell.c ".import" command.
2275 **
2276 ** This command usage is equivalent to the sqlite2.x COPY statement,
2277 ** which imports file data into a table using the PostgreSQL COPY file format:
2278 ** $db copy $conflit_algo $table_name $filename \t \\N
2279 */
2280 case DB_COPY: {
2281 char *zTable; /* Insert data into this table */
2282 char *zFile; /* The file from which to extract data */
2283 char *zConflict; /* The conflict algorithm to use */
2284 sqlite3_stmt *pStmt; /* A statement */
drh19e2d372005-08-29 23:00:03 +00002285 int nCol; /* Number of columns in the table */
2286 int nByte; /* Number of bytes in an SQL string */
2287 int i, j; /* Loop counters */
2288 int nSep; /* Number of bytes in zSep[] */
2289 int nNull; /* Number of bytes in zNull[] */
2290 char *zSql; /* An SQL statement */
2291 char *zLine; /* A single line of input from the file */
2292 char **azCol; /* zLine[] broken up into columns */
mistachkin6ef5e122014-01-24 17:03:55 +00002293 const char *zCommit; /* How to commit changes */
drh19e2d372005-08-29 23:00:03 +00002294 FILE *in; /* The input file */
2295 int lineno = 0; /* Line number of input file */
2296 char zLineNum[80]; /* Line number print buffer */
2297 Tcl_Obj *pResult; /* interp result */
2298
mistachkin6ef5e122014-01-24 17:03:55 +00002299 const char *zSep;
2300 const char *zNull;
drh19e2d372005-08-29 23:00:03 +00002301 if( objc<5 || objc>7 ){
mistachkinb56660f2016-07-14 21:26:09 +00002302 Tcl_WrongNumArgs(interp, 2, objv,
drh19e2d372005-08-29 23:00:03 +00002303 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
2304 return TCL_ERROR;
2305 }
2306 if( objc>=6 ){
2307 zSep = Tcl_GetStringFromObj(objv[5], 0);
2308 }else{
2309 zSep = "\t";
2310 }
2311 if( objc>=7 ){
2312 zNull = Tcl_GetStringFromObj(objv[6], 0);
2313 }else{
2314 zNull = "";
2315 }
2316 zConflict = Tcl_GetStringFromObj(objv[2], 0);
2317 zTable = Tcl_GetStringFromObj(objv[3], 0);
2318 zFile = Tcl_GetStringFromObj(objv[4], 0);
drh4f21c4a2008-12-10 22:15:00 +00002319 nSep = strlen30(zSep);
2320 nNull = strlen30(zNull);
drh19e2d372005-08-29 23:00:03 +00002321 if( nSep==0 ){
drha198f2b2014-02-07 19:26:13 +00002322 Tcl_AppendResult(interp,"Error: non-null separator required for copy",
2323 (char*)0);
drh19e2d372005-08-29 23:00:03 +00002324 return TCL_ERROR;
2325 }
drh3e59c012008-09-23 10:12:13 +00002326 if(strcmp(zConflict, "rollback") != 0 &&
2327 strcmp(zConflict, "abort" ) != 0 &&
2328 strcmp(zConflict, "fail" ) != 0 &&
2329 strcmp(zConflict, "ignore" ) != 0 &&
2330 strcmp(zConflict, "replace" ) != 0 ) {
mistachkinb56660f2016-07-14 21:26:09 +00002331 Tcl_AppendResult(interp, "Error: \"", zConflict,
drh19e2d372005-08-29 23:00:03 +00002332 "\", conflict-algorithm must be one of: rollback, "
drha198f2b2014-02-07 19:26:13 +00002333 "abort, fail, ignore, or replace", (char*)0);
drh19e2d372005-08-29 23:00:03 +00002334 return TCL_ERROR;
2335 }
2336 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
2337 if( zSql==0 ){
drha198f2b2014-02-07 19:26:13 +00002338 Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0);
drh19e2d372005-08-29 23:00:03 +00002339 return TCL_ERROR;
2340 }
drh4f21c4a2008-12-10 22:15:00 +00002341 nByte = strlen30(zSql);
drh3e701a12007-02-01 01:53:44 +00002342 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
drh19e2d372005-08-29 23:00:03 +00002343 sqlite3_free(zSql);
2344 if( rc ){
drha198f2b2014-02-07 19:26:13 +00002345 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
drh19e2d372005-08-29 23:00:03 +00002346 nCol = 0;
2347 }else{
2348 nCol = sqlite3_column_count(pStmt);
2349 }
2350 sqlite3_finalize(pStmt);
2351 if( nCol==0 ) {
2352 return TCL_ERROR;
2353 }
2354 zSql = malloc( nByte + 50 + nCol*2 );
2355 if( zSql==0 ) {
drha198f2b2014-02-07 19:26:13 +00002356 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
drh19e2d372005-08-29 23:00:03 +00002357 return TCL_ERROR;
2358 }
2359 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
2360 zConflict, zTable);
drh4f21c4a2008-12-10 22:15:00 +00002361 j = strlen30(zSql);
drh19e2d372005-08-29 23:00:03 +00002362 for(i=1; i<nCol; i++){
2363 zSql[j++] = ',';
2364 zSql[j++] = '?';
2365 }
2366 zSql[j++] = ')';
2367 zSql[j] = 0;
drh3e701a12007-02-01 01:53:44 +00002368 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
drh19e2d372005-08-29 23:00:03 +00002369 free(zSql);
2370 if( rc ){
drha198f2b2014-02-07 19:26:13 +00002371 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
drh19e2d372005-08-29 23:00:03 +00002372 sqlite3_finalize(pStmt);
2373 return TCL_ERROR;
2374 }
2375 in = fopen(zFile, "rb");
2376 if( in==0 ){
drhea8f0a12017-01-12 11:50:08 +00002377 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0);
drh19e2d372005-08-29 23:00:03 +00002378 sqlite3_finalize(pStmt);
2379 return TCL_ERROR;
2380 }
2381 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
2382 if( azCol==0 ) {
drha198f2b2014-02-07 19:26:13 +00002383 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
drh43617e92006-03-06 20:55:46 +00002384 fclose(in);
drh19e2d372005-08-29 23:00:03 +00002385 return TCL_ERROR;
2386 }
drh37527852006-03-16 16:19:56 +00002387 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
drh19e2d372005-08-29 23:00:03 +00002388 zCommit = "COMMIT";
2389 while( (zLine = local_getline(0, in))!=0 ){
2390 char *z;
drh19e2d372005-08-29 23:00:03 +00002391 lineno++;
2392 azCol[0] = zLine;
2393 for(i=0, z=zLine; *z; z++){
2394 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
2395 *z = 0;
2396 i++;
2397 if( i<nCol ){
2398 azCol[i] = &z[nSep];
2399 z += nSep-1;
2400 }
2401 }
2402 }
2403 if( i+1!=nCol ){
2404 char *zErr;
drh4f21c4a2008-12-10 22:15:00 +00002405 int nErr = strlen30(zFile) + 200;
drh5bb3eb92007-05-04 13:15:55 +00002406 zErr = malloc(nErr);
drhc1f44942006-05-10 14:39:13 +00002407 if( zErr ){
drh5bb3eb92007-05-04 13:15:55 +00002408 sqlite3_snprintf(nErr, zErr,
drhc1f44942006-05-10 14:39:13 +00002409 "Error: %s line %d: expected %d columns of data but found %d",
2410 zFile, lineno, nCol, i+1);
drha198f2b2014-02-07 19:26:13 +00002411 Tcl_AppendResult(interp, zErr, (char*)0);
drhc1f44942006-05-10 14:39:13 +00002412 free(zErr);
2413 }
drh19e2d372005-08-29 23:00:03 +00002414 zCommit = "ROLLBACK";
2415 break;
2416 }
2417 for(i=0; i<nCol; i++){
2418 /* check for null data, if so, bind as null */
drhea678832008-12-10 19:26:22 +00002419 if( (nNull>0 && strcmp(azCol[i], zNull)==0)
mistachkinb56660f2016-07-14 21:26:09 +00002420 || strlen30(azCol[i])==0
drhea678832008-12-10 19:26:22 +00002421 ){
drh19e2d372005-08-29 23:00:03 +00002422 sqlite3_bind_null(pStmt, i+1);
2423 }else{
2424 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2425 }
2426 }
2427 sqlite3_step(pStmt);
2428 rc = sqlite3_reset(pStmt);
2429 free(zLine);
2430 if( rc!=SQLITE_OK ){
drha198f2b2014-02-07 19:26:13 +00002431 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0);
drh19e2d372005-08-29 23:00:03 +00002432 zCommit = "ROLLBACK";
2433 break;
2434 }
2435 }
2436 free(azCol);
2437 fclose(in);
2438 sqlite3_finalize(pStmt);
drh37527852006-03-16 16:19:56 +00002439 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
drh19e2d372005-08-29 23:00:03 +00002440
2441 if( zCommit[0] == 'C' ){
2442 /* success, set result as number of lines processed */
2443 pResult = Tcl_GetObjResult(interp);
2444 Tcl_SetIntObj(pResult, lineno);
2445 rc = TCL_OK;
2446 }else{
2447 /* failure, append lineno where failed */
drh5bb3eb92007-05-04 13:15:55 +00002448 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
drha198f2b2014-02-07 19:26:13 +00002449 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,
2450 (char*)0);
drh19e2d372005-08-29 23:00:03 +00002451 rc = TCL_ERROR;
2452 }
2453 break;
2454 }
2455
drhdcd997e2003-01-31 17:21:49 +00002456 /*
drh6ca64482019-01-22 16:06:20 +00002457 ** $db deserialize ?-maxsize N? ?-readonly BOOL? ?DATABASE? VALUE
drhcb7d5412018-01-03 16:49:52 +00002458 **
2459 ** Reopen DATABASE (default "main") using the content in $VALUE
2460 */
2461 case DB_DESERIALIZE: {
drh9c6396e2018-03-06 21:43:19 +00002462#ifndef SQLITE_ENABLE_DESERIALIZE
drh3ec86652018-01-03 19:03:31 +00002463 Tcl_AppendResult(interp, "MEMDB not available in this build",
2464 (char*)0);
2465 rc = TCL_ERROR;
2466#else
drh6ca64482019-01-22 16:06:20 +00002467 const char *zSchema = 0;
2468 Tcl_Obj *pValue = 0;
drh3ec86652018-01-03 19:03:31 +00002469 unsigned char *pBA;
2470 unsigned char *pData;
2471 int len, xrc;
drh6ca64482019-01-22 16:06:20 +00002472 sqlite3_int64 mxSize = 0;
2473 int i;
2474 int isReadonly = 0;
2475
2476
2477 if( objc<3 ){
drh3ec86652018-01-03 19:03:31 +00002478 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
2479 rc = TCL_ERROR;
2480 break;
2481 }
drh6ca64482019-01-22 16:06:20 +00002482 for(i=2; i<objc-1; i++){
2483 const char *z = Tcl_GetString(objv[i]);
2484 if( strcmp(z,"-maxsize")==0 && i<objc-2 ){
2485 rc = Tcl_GetWideIntFromObj(interp, objv[++i], &mxSize);
2486 if( rc ) goto deserialize_error;
2487 continue;
2488 }
2489 if( strcmp(z,"-readonly")==0 && i<objc-2 ){
2490 rc = Tcl_GetBooleanFromObj(interp, objv[++i], &isReadonly);
2491 if( rc ) goto deserialize_error;
2492 continue;
2493 }
2494 if( zSchema==0 && i==objc-2 && z[0]!='-' ){
2495 zSchema = z;
2496 continue;
2497 }
2498 Tcl_AppendResult(interp, "unknown option: ", z, (char*)0);
2499 rc = TCL_ERROR;
2500 goto deserialize_error;
2501 }
2502 pValue = objv[objc-1];
drh3ec86652018-01-03 19:03:31 +00002503 pBA = Tcl_GetByteArrayFromObj(pValue, &len);
2504 pData = sqlite3_malloc64( len );
drha5bb4352018-01-03 23:40:02 +00002505 if( pData==0 && len>0 ){
drh3ec86652018-01-03 19:03:31 +00002506 Tcl_AppendResult(interp, "out of memory", (char*)0);
2507 rc = TCL_ERROR;
2508 }else{
drh6ca64482019-01-22 16:06:20 +00002509 int flags;
drha5bb4352018-01-03 23:40:02 +00002510 if( len>0 ) memcpy(pData, pBA, len);
drh6ca64482019-01-22 16:06:20 +00002511 if( isReadonly ){
2512 flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_READONLY;
2513 }else{
2514 flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE;
2515 }
2516 xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len, flags);
drh3ec86652018-01-03 19:03:31 +00002517 if( xrc ){
2518 Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
2519 rc = TCL_ERROR;
2520 }
drh6ca64482019-01-22 16:06:20 +00002521 if( mxSize>0 ){
2522 sqlite3_file_control(pDb->db, zSchema,SQLITE_FCNTL_SIZE_LIMIT,&mxSize);
2523 }
drh3ec86652018-01-03 19:03:31 +00002524 }
drh6ca64482019-01-22 16:06:20 +00002525deserialize_error:
drh3ec86652018-01-03 19:03:31 +00002526#endif
drhcb7d5412018-01-03 16:49:52 +00002527 break;
2528 }
2529
2530 /*
drh41449052006-07-06 17:08:48 +00002531 ** $db enable_load_extension BOOLEAN
2532 **
2533 ** Turn the extension loading feature on or off. It if off by
2534 ** default.
2535 */
2536 case DB_ENABLE_LOAD_EXTENSION: {
drhf533acc2006-12-19 18:57:11 +00002537#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh41449052006-07-06 17:08:48 +00002538 int onoff;
2539 if( objc!=3 ){
2540 Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");
2541 return TCL_ERROR;
2542 }
2543 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
2544 return TCL_ERROR;
2545 }
2546 sqlite3_enable_load_extension(pDb->db, onoff);
2547 break;
drhf533acc2006-12-19 18:57:11 +00002548#else
2549 Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
drha198f2b2014-02-07 19:26:13 +00002550 (char*)0);
drhf533acc2006-12-19 18:57:11 +00002551 return TCL_ERROR;
2552#endif
drh41449052006-07-06 17:08:48 +00002553 }
2554
2555 /*
drhdcd997e2003-01-31 17:21:49 +00002556 ** $db errorcode
2557 **
2558 ** Return the numeric error code that was returned by the most recent
danielk19776f8a5032004-05-10 10:34:51 +00002559 ** call to sqlite3_exec().
drhdcd997e2003-01-31 17:21:49 +00002560 */
2561 case DB_ERRORCODE: {
danielk1977f3ce83f2004-06-14 11:43:46 +00002562 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
drhdcd997e2003-01-31 17:21:49 +00002563 break;
2564 }
dan4a4c11a2009-10-06 14:59:02 +00002565
2566 /*
2567 ** $db exists $sql
2568 ** $db onecolumn $sql
2569 **
2570 ** The onecolumn method is the equivalent of:
2571 ** lindex [$db eval $sql] 0
2572 */
mistachkinb56660f2016-07-14 21:26:09 +00002573 case DB_EXISTS:
dan4a4c11a2009-10-06 14:59:02 +00002574 case DB_ONECOLUMN: {
drhedc40242016-06-13 12:34:38 +00002575 Tcl_Obj *pResult = 0;
dan4a4c11a2009-10-06 14:59:02 +00002576 DbEvalContext sEval;
2577 if( objc!=3 ){
2578 Tcl_WrongNumArgs(interp, 2, objv, "SQL");
2579 return TCL_ERROR;
2580 }
2581
drhaf38cdb2017-06-26 21:08:32 +00002582 dbEvalInit(&sEval, pDb, objv[2], 0, 0);
dan4a4c11a2009-10-06 14:59:02 +00002583 rc = dbEvalStep(&sEval);
2584 if( choice==DB_ONECOLUMN ){
2585 if( rc==TCL_OK ){
drhedc40242016-06-13 12:34:38 +00002586 pResult = dbEvalColumnValue(&sEval, 0);
dand5f12cd2011-08-18 17:47:57 +00002587 }else if( rc==TCL_BREAK ){
2588 Tcl_ResetResult(interp);
dan4a4c11a2009-10-06 14:59:02 +00002589 }
2590 }else if( rc==TCL_BREAK || rc==TCL_OK ){
drhedc40242016-06-13 12:34:38 +00002591 pResult = Tcl_NewBooleanObj(rc==TCL_OK);
dan4a4c11a2009-10-06 14:59:02 +00002592 }
2593 dbEvalFinalize(&sEval);
drhedc40242016-06-13 12:34:38 +00002594 if( pResult ) Tcl_SetObjResult(interp, pResult);
dan4a4c11a2009-10-06 14:59:02 +00002595
2596 if( rc==TCL_BREAK ){
2597 rc = TCL_OK;
2598 }
2599 break;
2600 }
mistachkinb56660f2016-07-14 21:26:09 +00002601
drh75897232000-05-29 14:26:00 +00002602 /*
drhaf38cdb2017-06-26 21:08:32 +00002603 ** $db eval ?options? $sql ?array? ?{ ...code... }?
drh75897232000-05-29 14:26:00 +00002604 **
2605 ** The SQL statement in $sql is evaluated. For each row, the values are
drhbec3f402000-08-04 13:49:02 +00002606 ** placed in elements of the array named "array" and ...code... is executed.
drh75897232000-05-29 14:26:00 +00002607 ** If "array" and "code" are omitted, then no callback is every invoked.
2608 ** If "array" is an empty string, then the values are placed in variables
2609 ** that have the same name as the fields extracted by the query.
2610 */
dan4a4c11a2009-10-06 14:59:02 +00002611 case DB_EVAL: {
drhaf38cdb2017-06-26 21:08:32 +00002612 int evalFlags = 0;
2613 const char *zOpt;
2614 while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){
2615 if( strcmp(zOpt, "-withoutnulls")==0 ){
2616 evalFlags |= SQLITE_EVAL_WITHOUTNULLS;
2617 }
2618 else{
2619 Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0);
2620 return TCL_ERROR;
2621 }
2622 objc--;
2623 objv++;
2624 }
dan4a4c11a2009-10-06 14:59:02 +00002625 if( objc<3 || objc>5 ){
drhaf38cdb2017-06-26 21:08:32 +00002626 Tcl_WrongNumArgs(interp, 2, objv,
2627 "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?");
dan4a4c11a2009-10-06 14:59:02 +00002628 return TCL_ERROR;
danielk197730ccda12004-05-27 12:11:31 +00002629 }
dan4a4c11a2009-10-06 14:59:02 +00002630
drh92febd92004-08-20 18:34:20 +00002631 if( objc==3 ){
dan4a4c11a2009-10-06 14:59:02 +00002632 DbEvalContext sEval;
2633 Tcl_Obj *pRet = Tcl_NewObj();
2634 Tcl_IncrRefCount(pRet);
drhaf38cdb2017-06-26 21:08:32 +00002635 dbEvalInit(&sEval, pDb, objv[2], 0, 0);
dan4a4c11a2009-10-06 14:59:02 +00002636 while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
2637 int i;
2638 int nCol;
2639 dbEvalRowInfo(&sEval, &nCol, 0);
drh92febd92004-08-20 18:34:20 +00002640 for(i=0; i<nCol; i++){
dan4a4c11a2009-10-06 14:59:02 +00002641 Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
danielk197730ccda12004-05-27 12:11:31 +00002642 }
2643 }
dan4a4c11a2009-10-06 14:59:02 +00002644 dbEvalFinalize(&sEval);
drh90b6bb12004-09-13 13:16:31 +00002645 if( rc==TCL_BREAK ){
dan4a4c11a2009-10-06 14:59:02 +00002646 Tcl_SetObjResult(interp, pRet);
drh90b6bb12004-09-13 13:16:31 +00002647 rc = TCL_OK;
2648 }
drh1807ce32004-09-07 13:20:35 +00002649 Tcl_DecrRefCount(pRet);
dan4a4c11a2009-10-06 14:59:02 +00002650 }else{
mistachkin8e189222015-04-19 21:43:16 +00002651 ClientData cd2[2];
dan4a4c11a2009-10-06 14:59:02 +00002652 DbEvalContext *p;
2653 Tcl_Obj *pArray = 0;
2654 Tcl_Obj *pScript;
2655
drhaf38cdb2017-06-26 21:08:32 +00002656 if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){
dan4a4c11a2009-10-06 14:59:02 +00002657 pArray = objv[3];
2658 }
2659 pScript = objv[objc-1];
2660 Tcl_IncrRefCount(pScript);
mistachkinb56660f2016-07-14 21:26:09 +00002661
dan4a4c11a2009-10-06 14:59:02 +00002662 p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
drhaf38cdb2017-06-26 21:08:32 +00002663 dbEvalInit(p, pDb, objv[2], pArray, evalFlags);
dan4a4c11a2009-10-06 14:59:02 +00002664
mistachkin8e189222015-04-19 21:43:16 +00002665 cd2[0] = (void *)p;
2666 cd2[1] = (void *)pScript;
2667 rc = DbEvalNextCmd(cd2, interp, TCL_OK);
danielk197730ccda12004-05-27 12:11:31 +00002668 }
danielk197730ccda12004-05-27 12:11:31 +00002669 break;
2670 }
drhbec3f402000-08-04 13:49:02 +00002671
2672 /*
dan3df30592015-03-13 08:31:54 +00002673 ** $db function NAME [-argcount N] [-deterministic] SCRIPT
drhcabb0812002-09-14 13:47:32 +00002674 **
2675 ** Create a new SQL function called NAME. Whenever that function is
2676 ** called, invoke SCRIPT to evaluate the function.
2677 */
2678 case DB_FUNCTION: {
dan3df30592015-03-13 08:31:54 +00002679 int flags = SQLITE_UTF8;
drhcabb0812002-09-14 13:47:32 +00002680 SqlFunc *pFunc;
drhd1e47332005-06-26 17:55:33 +00002681 Tcl_Obj *pScript;
drhcabb0812002-09-14 13:47:32 +00002682 char *zName;
drhe3602be2008-09-09 12:31:33 +00002683 int nArg = -1;
dan3df30592015-03-13 08:31:54 +00002684 int i;
dan89d24932019-02-27 16:38:19 +00002685 int eType = SQLITE_NULL;
dan3df30592015-03-13 08:31:54 +00002686 if( objc<4 ){
2687 Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT");
2688 return TCL_ERROR;
2689 }
2690 for(i=3; i<(objc-1); i++){
2691 const char *z = Tcl_GetString(objv[i]);
drh4f21c4a2008-12-10 22:15:00 +00002692 int n = strlen30(z);
dan89d24932019-02-27 16:38:19 +00002693 if( n>1 && strncmp(z, "-argcount",n)==0 ){
dan3df30592015-03-13 08:31:54 +00002694 if( i==(objc-2) ){
drhea8f0a12017-01-12 11:50:08 +00002695 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
dan3df30592015-03-13 08:31:54 +00002696 return TCL_ERROR;
2697 }
2698 if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR;
drhe3602be2008-09-09 12:31:33 +00002699 if( nArg<0 ){
2700 Tcl_AppendResult(interp, "number of arguments must be non-negative",
2701 (char*)0);
2702 return TCL_ERROR;
2703 }
dan3df30592015-03-13 08:31:54 +00002704 i++;
2705 }else
dan89d24932019-02-27 16:38:19 +00002706 if( n>1 && strncmp(z, "-deterministic",n)==0 ){
dan3df30592015-03-13 08:31:54 +00002707 flags |= SQLITE_DETERMINISTIC;
dan89d24932019-02-27 16:38:19 +00002708 }else
2709 if( n>1 && strncmp(z, "-returntype", n)==0 ){
2710 const char *azType[] = {"integer", "real", "text", "blob", "any", 0};
2711 assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 );
2712 assert( SQLITE_BLOB==4 && SQLITE_NULL==5 );
2713 if( i==(objc-2) ){
2714 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
2715 return TCL_ERROR;
2716 }
2717 i++;
2718 if( Tcl_GetIndexFromObj(interp, objv[i], azType, "type", 0, &eType) ){
2719 return TCL_ERROR;
2720 }
2721 eType++;
dan3df30592015-03-13 08:31:54 +00002722 }else{
mistachkinb56660f2016-07-14 21:26:09 +00002723 Tcl_AppendResult(interp, "bad option \"", z,
dan89d24932019-02-27 16:38:19 +00002724 "\": must be -argcount, -deterministic or -returntype", (char*)0
dan3df30592015-03-13 08:31:54 +00002725 );
2726 return TCL_ERROR;
drhe3602be2008-09-09 12:31:33 +00002727 }
drhcabb0812002-09-14 13:47:32 +00002728 }
dan3df30592015-03-13 08:31:54 +00002729
2730 pScript = objv[objc-1];
drhcabb0812002-09-14 13:47:32 +00002731 zName = Tcl_GetStringFromObj(objv[2], 0);
drhd1e47332005-06-26 17:55:33 +00002732 pFunc = findSqlFunc(pDb, zName);
drhcabb0812002-09-14 13:47:32 +00002733 if( pFunc==0 ) return TCL_ERROR;
drhd1e47332005-06-26 17:55:33 +00002734 if( pFunc->pScript ){
2735 Tcl_DecrRefCount(pFunc->pScript);
2736 }
2737 pFunc->pScript = pScript;
2738 Tcl_IncrRefCount(pScript);
2739 pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
dan89d24932019-02-27 16:38:19 +00002740 pFunc->eType = eType;
dan3df30592015-03-13 08:31:54 +00002741 rc = sqlite3_create_function(pDb->db, zName, nArg, flags,
danielk1977d8123362004-06-12 09:25:12 +00002742 pFunc, tclSqlFunc, 0, 0);
drhfb7e7652005-01-24 00:28:42 +00002743 if( rc!=SQLITE_OK ){
danielk19779636c4e2005-01-25 04:27:54 +00002744 rc = TCL_ERROR;
2745 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
drhfb7e7652005-01-24 00:28:42 +00002746 }
drhcabb0812002-09-14 13:47:32 +00002747 break;
2748 }
2749
2750 /*
danielk19778cbadb02007-05-03 16:31:26 +00002751 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID
danielk1977b4e9af92007-05-01 17:49:49 +00002752 */
2753 case DB_INCRBLOB: {
danielk197732a0d8b2007-05-04 19:03:02 +00002754#ifdef SQLITE_OMIT_INCRBLOB
drha198f2b2014-02-07 19:26:13 +00002755 Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0);
danielk197732a0d8b2007-05-04 19:03:02 +00002756 return TCL_ERROR;
2757#else
danielk19778cbadb02007-05-03 16:31:26 +00002758 int isReadonly = 0;
danielk1977b4e9af92007-05-01 17:49:49 +00002759 const char *zDb = "main";
2760 const char *zTable;
2761 const char *zColumn;
drhb3f787f2012-09-29 14:45:54 +00002762 Tcl_WideInt iRow;
danielk1977b4e9af92007-05-01 17:49:49 +00002763
danielk19778cbadb02007-05-03 16:31:26 +00002764 /* Check for the -readonly option */
2765 if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
2766 isReadonly = 1;
2767 }
2768
2769 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){
2770 Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");
danielk1977b4e9af92007-05-01 17:49:49 +00002771 return TCL_ERROR;
2772 }
2773
danielk19778cbadb02007-05-03 16:31:26 +00002774 if( objc==(6+isReadonly) ){
danielk1977b4e9af92007-05-01 17:49:49 +00002775 zDb = Tcl_GetString(objv[2]);
2776 }
2777 zTable = Tcl_GetString(objv[objc-3]);
2778 zColumn = Tcl_GetString(objv[objc-2]);
2779 rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow);
2780
2781 if( rc==TCL_OK ){
danielk19778cbadb02007-05-03 16:31:26 +00002782 rc = createIncrblobChannel(
danedf5b162014-08-19 09:15:41 +00002783 interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly
danielk19778cbadb02007-05-03 16:31:26 +00002784 );
danielk1977b4e9af92007-05-01 17:49:49 +00002785 }
danielk197732a0d8b2007-05-04 19:03:02 +00002786#endif
danielk1977b4e9af92007-05-01 17:49:49 +00002787 break;
2788 }
2789
2790 /*
drhf11bded2006-07-17 00:02:44 +00002791 ** $db interrupt
2792 **
2793 ** Interrupt the execution of the inner-most SQL interpreter. This
2794 ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
2795 */
2796 case DB_INTERRUPT: {
2797 sqlite3_interrupt(pDb->db);
2798 break;
2799 }
2800
2801 /*
drh19e2d372005-08-29 23:00:03 +00002802 ** $db nullvalue ?STRING?
2803 **
2804 ** Change text used when a NULL comes back from the database. If ?STRING?
2805 ** is not present, then the current string used for NULL is returned.
2806 ** If STRING is present, then STRING is returned.
2807 **
2808 */
2809 case DB_NULLVALUE: {
2810 if( objc!=2 && objc!=3 ){
2811 Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
2812 return TCL_ERROR;
2813 }
2814 if( objc==3 ){
2815 int len;
2816 char *zNull = Tcl_GetStringFromObj(objv[2], &len);
2817 if( pDb->zNull ){
2818 Tcl_Free(pDb->zNull);
2819 }
2820 if( zNull && len>0 ){
2821 pDb->zNull = Tcl_Alloc( len + 1 );
drh7fd33922011-06-20 19:00:30 +00002822 memcpy(pDb->zNull, zNull, len);
drh19e2d372005-08-29 23:00:03 +00002823 pDb->zNull[len] = '\0';
2824 }else{
2825 pDb->zNull = 0;
2826 }
2827 }
drhc45e6712012-10-03 11:02:33 +00002828 Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
drh19e2d372005-08-29 23:00:03 +00002829 break;
2830 }
2831
2832 /*
mistachkinb56660f2016-07-14 21:26:09 +00002833 ** $db last_insert_rowid
drhaf9ff332002-01-16 21:00:27 +00002834 **
2835 ** Return an integer which is the ROWID for the most recent insert.
2836 */
2837 case DB_LAST_INSERT_ROWID: {
2838 Tcl_Obj *pResult;
drhf7e678d2006-06-21 19:30:34 +00002839 Tcl_WideInt rowid;
drhaf9ff332002-01-16 21:00:27 +00002840 if( objc!=2 ){
2841 Tcl_WrongNumArgs(interp, 2, objv, "");
2842 return TCL_ERROR;
2843 }
danielk19776f8a5032004-05-10 10:34:51 +00002844 rowid = sqlite3_last_insert_rowid(pDb->db);
drhaf9ff332002-01-16 21:00:27 +00002845 pResult = Tcl_GetObjResult(interp);
drhf7e678d2006-06-21 19:30:34 +00002846 Tcl_SetWideIntObj(pResult, rowid);
drhaf9ff332002-01-16 21:00:27 +00002847 break;
2848 }
2849
2850 /*
dan4a4c11a2009-10-06 14:59:02 +00002851 ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
drh5d9d7572003-08-19 14:31:01 +00002852 */
drh1807ce32004-09-07 13:20:35 +00002853
2854 /* $db progress ?N CALLBACK?
mistachkinb56660f2016-07-14 21:26:09 +00002855 **
drh1807ce32004-09-07 13:20:35 +00002856 ** Invoke the given callback every N virtual machine opcodes while executing
2857 ** queries.
2858 */
2859 case DB_PROGRESS: {
2860 if( objc==2 ){
2861 if( pDb->zProgress ){
drha198f2b2014-02-07 19:26:13 +00002862 Tcl_AppendResult(interp, pDb->zProgress, (char*)0);
drh1807ce32004-09-07 13:20:35 +00002863 }
2864 }else if( objc==4 ){
2865 char *zProgress;
2866 int len;
2867 int N;
2868 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
drhfd131da2007-08-07 17:13:03 +00002869 return TCL_ERROR;
drh1807ce32004-09-07 13:20:35 +00002870 };
2871 if( pDb->zProgress ){
2872 Tcl_Free(pDb->zProgress);
2873 }
2874 zProgress = Tcl_GetStringFromObj(objv[3], &len);
2875 if( zProgress && len>0 ){
2876 pDb->zProgress = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00002877 memcpy(pDb->zProgress, zProgress, len+1);
drh1807ce32004-09-07 13:20:35 +00002878 }else{
2879 pDb->zProgress = 0;
2880 }
2881#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
2882 if( pDb->zProgress ){
2883 pDb->interp = interp;
2884 sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
2885 }else{
2886 sqlite3_progress_handler(pDb->db, 0, 0, 0);
2887 }
2888#endif
2889 }else{
2890 Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
drh5d9d7572003-08-19 14:31:01 +00002891 return TCL_ERROR;
2892 }
drh5d9d7572003-08-19 14:31:01 +00002893 break;
2894 }
2895
drh19e2d372005-08-29 23:00:03 +00002896 /* $db profile ?CALLBACK?
2897 **
2898 ** Make arrangements to invoke the CALLBACK routine after each SQL statement
2899 ** that has run. The text of the SQL and the amount of elapse time are
2900 ** appended to CALLBACK before the script is run.
2901 */
2902 case DB_PROFILE: {
2903 if( objc>3 ){
2904 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
2905 return TCL_ERROR;
2906 }else if( objc==2 ){
2907 if( pDb->zProfile ){
drha198f2b2014-02-07 19:26:13 +00002908 Tcl_AppendResult(interp, pDb->zProfile, (char*)0);
drh19e2d372005-08-29 23:00:03 +00002909 }
2910 }else{
2911 char *zProfile;
2912 int len;
2913 if( pDb->zProfile ){
2914 Tcl_Free(pDb->zProfile);
2915 }
2916 zProfile = Tcl_GetStringFromObj(objv[2], &len);
2917 if( zProfile && len>0 ){
2918 pDb->zProfile = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00002919 memcpy(pDb->zProfile, zProfile, len+1);
drh19e2d372005-08-29 23:00:03 +00002920 }else{
2921 pDb->zProfile = 0;
2922 }
drh2eb22af2016-09-10 19:51:40 +00002923#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
2924 !defined(SQLITE_OMIT_DEPRECATED)
drh19e2d372005-08-29 23:00:03 +00002925 if( pDb->zProfile ){
2926 pDb->interp = interp;
2927 sqlite3_profile(pDb->db, DbProfileHandler, pDb);
2928 }else{
2929 sqlite3_profile(pDb->db, 0, 0);
2930 }
2931#endif
2932 }
2933 break;
2934 }
2935
drh5d9d7572003-08-19 14:31:01 +00002936 /*
drh22fbcb82004-02-01 01:22:50 +00002937 ** $db rekey KEY
2938 **
2939 ** Change the encryption key on the currently open database.
2940 */
2941 case DB_REKEY: {
drh32f57d42016-03-16 01:03:10 +00002942#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drh22fbcb82004-02-01 01:22:50 +00002943 int nKey;
2944 void *pKey;
drhb07028f2011-10-14 21:49:18 +00002945#endif
drh22fbcb82004-02-01 01:22:50 +00002946 if( objc!=3 ){
2947 Tcl_WrongNumArgs(interp, 2, objv, "KEY");
2948 return TCL_ERROR;
2949 }
drh32f57d42016-03-16 01:03:10 +00002950#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drhb07028f2011-10-14 21:49:18 +00002951 pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
drh2011d5f2004-07-22 02:40:37 +00002952 rc = sqlite3_rekey(pDb->db, pKey, nKey);
drh22fbcb82004-02-01 01:22:50 +00002953 if( rc ){
drha198f2b2014-02-07 19:26:13 +00002954 Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
drh22fbcb82004-02-01 01:22:50 +00002955 rc = TCL_ERROR;
2956 }
2957#endif
2958 break;
2959 }
2960
drhdc2c4912009-02-04 22:46:47 +00002961 /* $db restore ?DATABASE? FILENAME
2962 **
mistachkinb56660f2016-07-14 21:26:09 +00002963 ** Open a database file named FILENAME. Transfer the content
drhdc2c4912009-02-04 22:46:47 +00002964 ** of FILENAME into the local database DATABASE (default: "main").
2965 */
2966 case DB_RESTORE: {
2967 const char *zSrcFile;
2968 const char *zDestDb;
2969 sqlite3 *pSrc;
2970 sqlite3_backup *pBackup;
2971 int nTimeout = 0;
2972
2973 if( objc==3 ){
2974 zDestDb = "main";
2975 zSrcFile = Tcl_GetString(objv[2]);
2976 }else if( objc==4 ){
2977 zDestDb = Tcl_GetString(objv[2]);
2978 zSrcFile = Tcl_GetString(objv[3]);
2979 }else{
2980 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
2981 return TCL_ERROR;
2982 }
drh147ef392016-01-22 23:17:51 +00002983 rc = sqlite3_open_v2(zSrcFile, &pSrc,
2984 SQLITE_OPEN_READONLY | pDb->openFlags, 0);
drhdc2c4912009-02-04 22:46:47 +00002985 if( rc!=SQLITE_OK ){
2986 Tcl_AppendResult(interp, "cannot open source database: ",
2987 sqlite3_errmsg(pSrc), (char*)0);
2988 sqlite3_close(pSrc);
2989 return TCL_ERROR;
2990 }
2991 pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
2992 if( pBackup==0 ){
2993 Tcl_AppendResult(interp, "restore failed: ",
2994 sqlite3_errmsg(pDb->db), (char*)0);
2995 sqlite3_close(pSrc);
2996 return TCL_ERROR;
2997 }
2998 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2999 || rc==SQLITE_BUSY ){
3000 if( rc==SQLITE_BUSY ){
3001 if( nTimeout++ >= 3 ) break;
3002 sqlite3_sleep(100);
3003 }
3004 }
3005 sqlite3_backup_finish(pBackup);
3006 if( rc==SQLITE_DONE ){
3007 rc = TCL_OK;
3008 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
3009 Tcl_AppendResult(interp, "restore failed: source database busy",
3010 (char*)0);
3011 rc = TCL_ERROR;
3012 }else{
3013 Tcl_AppendResult(interp, "restore failed: ",
3014 sqlite3_errmsg(pDb->db), (char*)0);
3015 rc = TCL_ERROR;
3016 }
3017 sqlite3_close(pSrc);
3018 break;
3019 }
3020
drh22fbcb82004-02-01 01:22:50 +00003021 /*
drhcb7d5412018-01-03 16:49:52 +00003022 ** $db serialize ?DATABASE?
3023 **
3024 ** Return a serialization of a database.
3025 */
3026 case DB_SERIALIZE: {
drh9c6396e2018-03-06 21:43:19 +00003027#ifndef SQLITE_ENABLE_DESERIALIZE
drhcb7d5412018-01-03 16:49:52 +00003028 Tcl_AppendResult(interp, "MEMDB not available in this build",
3029 (char*)0);
3030 rc = TCL_ERROR;
3031#else
3032 const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
3033 sqlite3_int64 sz = 0;
3034 unsigned char *pData;
3035 if( objc!=2 && objc!=3 ){
3036 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
3037 rc = TCL_ERROR;
3038 }else{
3039 int needFree;
3040 pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
3041 if( pData ){
3042 needFree = 0;
3043 }else{
3044 pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
3045 needFree = 1;
3046 }
3047 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
3048 if( needFree ) sqlite3_free(pData);
3049 }
3050#endif
3051 break;
3052 }
3053
3054 /*
danc456a762017-06-22 16:51:16 +00003055 ** $db status (step|sort|autoindex|vmstep)
drhd1d38482008-10-07 23:46:38 +00003056 **
mistachkinb56660f2016-07-14 21:26:09 +00003057 ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
drhd1d38482008-10-07 23:46:38 +00003058 ** SQLITE_STMTSTATUS_SORT for the most recent eval.
3059 */
3060 case DB_STATUS: {
drhd1d38482008-10-07 23:46:38 +00003061 int v;
3062 const char *zOp;
3063 if( objc!=3 ){
drh1c320a42010-08-01 22:41:32 +00003064 Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)");
drhd1d38482008-10-07 23:46:38 +00003065 return TCL_ERROR;
3066 }
3067 zOp = Tcl_GetString(objv[2]);
3068 if( strcmp(zOp, "step")==0 ){
3069 v = pDb->nStep;
3070 }else if( strcmp(zOp, "sort")==0 ){
3071 v = pDb->nSort;
drh3c379b02010-04-07 19:31:59 +00003072 }else if( strcmp(zOp, "autoindex")==0 ){
3073 v = pDb->nIndex;
danc456a762017-06-22 16:51:16 +00003074 }else if( strcmp(zOp, "vmstep")==0 ){
3075 v = pDb->nVMStep;
drhd1d38482008-10-07 23:46:38 +00003076 }else{
mistachkinb56660f2016-07-14 21:26:09 +00003077 Tcl_AppendResult(interp,
danc456a762017-06-22 16:51:16 +00003078 "bad argument: should be autoindex, step, sort or vmstep",
drhd1d38482008-10-07 23:46:38 +00003079 (char*)0);
3080 return TCL_ERROR;
3081 }
3082 Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
3083 break;
3084 }
mistachkinb56660f2016-07-14 21:26:09 +00003085
drhd1d38482008-10-07 23:46:38 +00003086 /*
drhbec3f402000-08-04 13:49:02 +00003087 ** $db timeout MILLESECONDS
3088 **
3089 ** Delay for the number of milliseconds specified when a file is locked.
3090 */
drh6d313162000-09-21 13:01:35 +00003091 case DB_TIMEOUT: {
drhbec3f402000-08-04 13:49:02 +00003092 int ms;
drh6d313162000-09-21 13:01:35 +00003093 if( objc!=3 ){
3094 Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
drhbec3f402000-08-04 13:49:02 +00003095 return TCL_ERROR;
3096 }
drh6d313162000-09-21 13:01:35 +00003097 if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
danielk19776f8a5032004-05-10 10:34:51 +00003098 sqlite3_busy_timeout(pDb->db, ms);
drh6d313162000-09-21 13:01:35 +00003099 break;
drh75897232000-05-29 14:26:00 +00003100 }
mistachkinb56660f2016-07-14 21:26:09 +00003101
danielk197755c45f22005-04-03 23:54:43 +00003102 /*
drh0f14e2e2004-06-29 12:39:08 +00003103 ** $db total_changes
3104 **
mistachkinb56660f2016-07-14 21:26:09 +00003105 ** Return the number of rows that were modified, inserted, or deleted
drh0f14e2e2004-06-29 12:39:08 +00003106 ** since the database handle was created.
3107 */
3108 case DB_TOTAL_CHANGES: {
3109 Tcl_Obj *pResult;
3110 if( objc!=2 ){
3111 Tcl_WrongNumArgs(interp, 2, objv, "");
3112 return TCL_ERROR;
3113 }
3114 pResult = Tcl_GetObjResult(interp);
3115 Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
3116 break;
3117 }
3118
drhb5a20d32003-04-23 12:25:23 +00003119 /* $db trace ?CALLBACK?
3120 **
3121 ** Make arrangements to invoke the CALLBACK routine for each SQL statement
3122 ** that is executed. The text of the SQL is appended to CALLBACK before
3123 ** it is executed.
3124 */
3125 case DB_TRACE: {
3126 if( objc>3 ){
3127 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
drhb97759e2004-06-29 11:26:59 +00003128 return TCL_ERROR;
drhb5a20d32003-04-23 12:25:23 +00003129 }else if( objc==2 ){
3130 if( pDb->zTrace ){
drha198f2b2014-02-07 19:26:13 +00003131 Tcl_AppendResult(interp, pDb->zTrace, (char*)0);
drhb5a20d32003-04-23 12:25:23 +00003132 }
3133 }else{
3134 char *zTrace;
3135 int len;
3136 if( pDb->zTrace ){
3137 Tcl_Free(pDb->zTrace);
3138 }
3139 zTrace = Tcl_GetStringFromObj(objv[2], &len);
3140 if( zTrace && len>0 ){
3141 pDb->zTrace = Tcl_Alloc( len + 1 );
drh5bb3eb92007-05-04 13:15:55 +00003142 memcpy(pDb->zTrace, zTrace, len+1);
drhb5a20d32003-04-23 12:25:23 +00003143 }else{
3144 pDb->zTrace = 0;
3145 }
drh2eb22af2016-09-10 19:51:40 +00003146#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
3147 !defined(SQLITE_OMIT_DEPRECATED)
drhb5a20d32003-04-23 12:25:23 +00003148 if( pDb->zTrace ){
3149 pDb->interp = interp;
danielk19776f8a5032004-05-10 10:34:51 +00003150 sqlite3_trace(pDb->db, DbTraceHandler, pDb);
drhb5a20d32003-04-23 12:25:23 +00003151 }else{
danielk19776f8a5032004-05-10 10:34:51 +00003152 sqlite3_trace(pDb->db, 0, 0);
drhb5a20d32003-04-23 12:25:23 +00003153 }
drh19e2d372005-08-29 23:00:03 +00003154#endif
drhb5a20d32003-04-23 12:25:23 +00003155 }
3156 break;
3157 }
3158
mistachkinb56660f2016-07-14 21:26:09 +00003159 /* $db trace_v2 ?CALLBACK? ?MASK?
3160 **
3161 ** Make arrangements to invoke the CALLBACK routine for each trace event
3162 ** matching the mask that is generated. The parameters are appended to
3163 ** CALLBACK before it is executed.
3164 */
3165 case DB_TRACE_V2: {
3166 if( objc>4 ){
3167 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
3168 return TCL_ERROR;
3169 }else if( objc==2 ){
3170 if( pDb->zTraceV2 ){
3171 Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
3172 }
3173 }else{
mistachkinb56660f2016-07-14 21:26:09 +00003174 char *zTraceV2;
3175 int len;
mistachkinb52dcd82016-07-14 23:17:03 +00003176 Tcl_WideInt wMask = 0;
mistachkinb56660f2016-07-14 21:26:09 +00003177 if( objc==4 ){
mistachkinb52dcd82016-07-14 23:17:03 +00003178 static const char *TTYPE_strs[] = {
3179 "statement", "profile", "row", "close", 0
3180 };
3181 enum TTYPE_enum {
3182 TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE
3183 };
3184 int i;
3185 if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){
mistachkinb56660f2016-07-14 21:26:09 +00003186 return TCL_ERROR;
3187 }
mistachkinb52dcd82016-07-14 23:17:03 +00003188 for(i=0; i<len; i++){
3189 Tcl_Obj *pObj;
3190 int ttype;
3191 if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){
3192 return TCL_ERROR;
3193 }
3194 if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type",
3195 0, &ttype)!=TCL_OK ){
3196 Tcl_WideInt wType;
3197 Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
3198 Tcl_IncrRefCount(pError);
3199 if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){
3200 Tcl_DecrRefCount(pError);
3201 wMask |= wType;
3202 }else{
3203 Tcl_SetObjResult(interp, pError);
3204 Tcl_DecrRefCount(pError);
3205 return TCL_ERROR;
3206 }
3207 }else{
3208 switch( (enum TTYPE_enum)ttype ){
3209 case TTYPE_STMT: wMask |= SQLITE_TRACE_STMT; break;
3210 case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break;
3211 case TTYPE_ROW: wMask |= SQLITE_TRACE_ROW; break;
3212 case TTYPE_CLOSE: wMask |= SQLITE_TRACE_CLOSE; break;
3213 }
3214 }
3215 }
mistachkinb56660f2016-07-14 21:26:09 +00003216 }else{
mistachkinb52dcd82016-07-14 23:17:03 +00003217 wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */
mistachkinb56660f2016-07-14 21:26:09 +00003218 }
3219 if( pDb->zTraceV2 ){
3220 Tcl_Free(pDb->zTraceV2);
3221 }
3222 zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
3223 if( zTraceV2 && len>0 ){
3224 pDb->zTraceV2 = Tcl_Alloc( len + 1 );
3225 memcpy(pDb->zTraceV2, zTraceV2, len+1);
3226 }else{
3227 pDb->zTraceV2 = 0;
3228 }
3229#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
3230 if( pDb->zTraceV2 ){
3231 pDb->interp = interp;
3232 sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb);
3233 }else{
3234 sqlite3_trace_v2(pDb->db, 0, 0, 0);
3235 }
3236#endif
3237 }
3238 break;
3239 }
3240
drh3d214232005-08-02 12:21:08 +00003241 /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
3242 **
3243 ** Start a new transaction (if we are not already in the midst of a
3244 ** transaction) and execute the TCL script SCRIPT. After SCRIPT
3245 ** completes, either commit the transaction or roll it back if SCRIPT
3246 ** throws an exception. Or if no new transation was started, do nothing.
3247 ** pass the exception on up the stack.
3248 **
3249 ** This command was inspired by Dave Thomas's talk on Ruby at the
3250 ** 2005 O'Reilly Open Source Convention (OSCON).
3251 */
3252 case DB_TRANSACTION: {
drh3d214232005-08-02 12:21:08 +00003253 Tcl_Obj *pScript;
danielk1977cd38d522009-01-02 17:33:46 +00003254 const char *zBegin = "SAVEPOINT _tcl_transaction";
drh3d214232005-08-02 12:21:08 +00003255 if( objc!=3 && objc!=4 ){
3256 Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
3257 return TCL_ERROR;
3258 }
danielk1977cd38d522009-01-02 17:33:46 +00003259
dan4a4c11a2009-10-06 14:59:02 +00003260 if( pDb->nTransaction==0 && objc==4 ){
drh3d214232005-08-02 12:21:08 +00003261 static const char *TTYPE_strs[] = {
drhce604012005-08-16 11:11:34 +00003262 "deferred", "exclusive", "immediate", 0
drh3d214232005-08-02 12:21:08 +00003263 };
3264 enum TTYPE_enum {
3265 TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
3266 };
3267 int ttype;
drhb5555e72005-08-02 17:15:14 +00003268 if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
drh3d214232005-08-02 12:21:08 +00003269 0, &ttype) ){
3270 return TCL_ERROR;
3271 }
3272 switch( (enum TTYPE_enum)ttype ){
3273 case TTYPE_DEFERRED: /* no-op */; break;
3274 case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break;
3275 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break;
3276 }
drh3d214232005-08-02 12:21:08 +00003277 }
danielk1977cd38d522009-01-02 17:33:46 +00003278 pScript = objv[objc-1];
3279
dan4a4c11a2009-10-06 14:59:02 +00003280 /* Run the SQLite BEGIN command to open a transaction or savepoint. */
danielk1977cd38d522009-01-02 17:33:46 +00003281 pDb->disableAuth++;
3282 rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
3283 pDb->disableAuth--;
3284 if( rc!=SQLITE_OK ){
drha198f2b2014-02-07 19:26:13 +00003285 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
danielk1977cd38d522009-01-02 17:33:46 +00003286 return TCL_ERROR;
drh3d214232005-08-02 12:21:08 +00003287 }
danielk1977cd38d522009-01-02 17:33:46 +00003288 pDb->nTransaction++;
danielk1977cd38d522009-01-02 17:33:46 +00003289
dan4a4c11a2009-10-06 14:59:02 +00003290 /* If using NRE, schedule a callback to invoke the script pScript, then
3291 ** a second callback to commit (or rollback) the transaction or savepoint
3292 ** opened above. If not using NRE, evaluate the script directly, then
mistachkinb56660f2016-07-14 21:26:09 +00003293 ** call function DbTransPostCmd() to commit (or rollback) the transaction
dan4a4c11a2009-10-06 14:59:02 +00003294 ** or savepoint. */
3295 if( DbUseNre() ){
3296 Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
drha47941f2013-12-20 18:57:44 +00003297 (void)Tcl_NREvalObj(interp, pScript, 0);
danielk1977cd38d522009-01-02 17:33:46 +00003298 }else{
dan4a4c11a2009-10-06 14:59:02 +00003299 rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
drh3d214232005-08-02 12:21:08 +00003300 }
3301 break;
3302 }
3303
danielk197794eb6a12005-12-15 15:22:08 +00003304 /*
danielk1977404ca072009-03-16 13:19:36 +00003305 ** $db unlock_notify ?script?
3306 */
3307 case DB_UNLOCK_NOTIFY: {
3308#ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
drha198f2b2014-02-07 19:26:13 +00003309 Tcl_AppendResult(interp, "unlock_notify not available in this build",
3310 (char*)0);
danielk1977404ca072009-03-16 13:19:36 +00003311 rc = TCL_ERROR;
3312#else
3313 if( objc!=2 && objc!=3 ){
3314 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
3315 rc = TCL_ERROR;
3316 }else{
3317 void (*xNotify)(void **, int) = 0;
3318 void *pNotifyArg = 0;
3319
3320 if( pDb->pUnlockNotify ){
3321 Tcl_DecrRefCount(pDb->pUnlockNotify);
3322 pDb->pUnlockNotify = 0;
3323 }
mistachkinb56660f2016-07-14 21:26:09 +00003324
danielk1977404ca072009-03-16 13:19:36 +00003325 if( objc==3 ){
3326 xNotify = DbUnlockNotify;
3327 pNotifyArg = (void *)pDb;
3328 pDb->pUnlockNotify = objv[2];
3329 Tcl_IncrRefCount(pDb->pUnlockNotify);
3330 }
mistachkinb56660f2016-07-14 21:26:09 +00003331
danielk1977404ca072009-03-16 13:19:36 +00003332 if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
drha198f2b2014-02-07 19:26:13 +00003333 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
danielk1977404ca072009-03-16 13:19:36 +00003334 rc = TCL_ERROR;
3335 }
3336 }
3337#endif
3338 break;
3339 }
3340
drh304637c2011-03-18 16:47:27 +00003341 /*
3342 ** $db preupdate_hook count
3343 ** $db preupdate_hook hook ?SCRIPT?
3344 ** $db preupdate_hook new INDEX
3345 ** $db preupdate_hook old INDEX
3346 */
dan46c47d42011-03-01 18:42:07 +00003347 case DB_PREUPDATE: {
drh9b1c62d2011-03-30 21:04:43 +00003348#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
dan2b519ab2016-12-06 19:33:42 +00003349 Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time",
3350 (char*)0);
drh9b1c62d2011-03-30 21:04:43 +00003351 rc = TCL_ERROR;
3352#else
dan1e7a2d42011-03-22 18:45:29 +00003353 static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0};
dan46c47d42011-03-01 18:42:07 +00003354 enum DbPreupdateSubCmd {
dan1e7a2d42011-03-22 18:45:29 +00003355 PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD
dan46c47d42011-03-01 18:42:07 +00003356 };
3357 int iSub;
3358
3359 if( objc<3 ){
3360 Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?");
3361 }
3362 if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){
3363 return TCL_ERROR;
3364 }
3365
3366 switch( (enum DbPreupdateSubCmd)iSub ){
3367 case PRE_COUNT: {
3368 int nCol = sqlite3_preupdate_count(pDb->db);
3369 Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol));
3370 break;
3371 }
3372
3373 case PRE_HOOK: {
3374 if( objc>4 ){
3375 Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?");
3376 return TCL_ERROR;
3377 }
3378 DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook);
3379 break;
3380 }
3381
dan1e7a2d42011-03-22 18:45:29 +00003382 case PRE_DEPTH: {
3383 Tcl_Obj *pRet;
3384 if( objc!=3 ){
3385 Tcl_WrongNumArgs(interp, 3, objv, "");
3386 return TCL_ERROR;
3387 }
3388 pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db));
3389 Tcl_SetObjResult(interp, pRet);
3390 break;
3391 }
3392
dan37db03b2011-03-16 19:59:18 +00003393 case PRE_NEW:
dan46c47d42011-03-01 18:42:07 +00003394 case PRE_OLD: {
3395 int iIdx;
dan37db03b2011-03-16 19:59:18 +00003396 sqlite3_value *pValue;
dan46c47d42011-03-01 18:42:07 +00003397 if( objc!=4 ){
3398 Tcl_WrongNumArgs(interp, 3, objv, "INDEX");
3399 return TCL_ERROR;
3400 }
3401 if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){
3402 return TCL_ERROR;
3403 }
3404
dan37db03b2011-03-16 19:59:18 +00003405 if( iSub==PRE_OLD ){
dan46c47d42011-03-01 18:42:07 +00003406 rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue);
dan37db03b2011-03-16 19:59:18 +00003407 }else{
3408 assert( iSub==PRE_NEW );
3409 rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue);
dan46c47d42011-03-01 18:42:07 +00003410 }
3411
dan37db03b2011-03-16 19:59:18 +00003412 if( rc==SQLITE_OK ){
drh304637c2011-03-18 16:47:27 +00003413 Tcl_Obj *pObj;
3414 pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1);
dan37db03b2011-03-16 19:59:18 +00003415 Tcl_SetObjResult(interp, pObj);
3416 }else{
drhea8f0a12017-01-12 11:50:08 +00003417 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
dan46c47d42011-03-01 18:42:07 +00003418 return TCL_ERROR;
3419 }
3420 }
3421 }
drh9b1c62d2011-03-30 21:04:43 +00003422#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
dan46c47d42011-03-01 18:42:07 +00003423 break;
3424 }
3425
danielk1977404ca072009-03-16 13:19:36 +00003426 /*
drh833bf962010-04-28 14:42:19 +00003427 ** $db wal_hook ?script?
danielk197794eb6a12005-12-15 15:22:08 +00003428 ** $db update_hook ?script?
danielk197771fd80b2005-12-16 06:54:01 +00003429 ** $db rollback_hook ?script?
danielk197794eb6a12005-12-15 15:22:08 +00003430 */
mistachkinb56660f2016-07-14 21:26:09 +00003431 case DB_WAL_HOOK:
3432 case DB_UPDATE_HOOK:
dan6566ebe2011-03-16 09:49:14 +00003433 case DB_ROLLBACK_HOOK: {
mistachkinb56660f2016-07-14 21:26:09 +00003434 /* set ppHook to point at pUpdateHook or pRollbackHook, depending on
danielk197771fd80b2005-12-16 06:54:01 +00003435 ** whether [$db update_hook] or [$db rollback_hook] was invoked.
3436 */
mistachkinb56660f2016-07-14 21:26:09 +00003437 Tcl_Obj **ppHook = 0;
dan46c47d42011-03-01 18:42:07 +00003438 if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
3439 if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
3440 if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
3441 if( objc>3 ){
danielk197794eb6a12005-12-15 15:22:08 +00003442 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
3443 return TCL_ERROR;
3444 }
danielk197771fd80b2005-12-16 06:54:01 +00003445
dan46c47d42011-03-01 18:42:07 +00003446 DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook);
danielk197794eb6a12005-12-15 15:22:08 +00003447 break;
3448 }
3449
danielk19774397de52005-01-12 12:44:03 +00003450 /* $db version
3451 **
3452 ** Return the version string for this database.
3453 */
3454 case DB_VERSION: {
drh1df64702017-10-13 15:56:26 +00003455 int i;
3456 for(i=2; i<objc; i++){
3457 const char *zArg = Tcl_GetString(objv[i]);
3458 /* Optional arguments to $db version are used for testing purpose */
3459#ifdef SQLITE_TEST
3460 /* $db version -use-legacy-prepare BOOLEAN
3461 **
3462 ** Turn the use of legacy sqlite3_prepare() on or off.
3463 */
3464 if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){
3465 i++;
3466 if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){
3467 return TCL_ERROR;
3468 }
3469 }else
3470
3471 /* $db version -last-stmt-ptr
3472 **
3473 ** Return a string which is a hex encoding of the pointer to the
3474 ** most recent sqlite3_stmt in the statement cache.
3475 */
3476 if( strcmp(zArg, "-last-stmt-ptr")==0 ){
3477 char zBuf[100];
3478 sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
3479 pDb->stmtList ? pDb->stmtList->pStmt: 0);
3480 Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
3481 }else
3482#endif /* SQLITE_TEST */
3483 {
3484 Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0);
3485 return TCL_ERROR;
3486 }
3487 }
3488 if( i==2 ){
3489 Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
3490 }
danielk19774397de52005-01-12 12:44:03 +00003491 break;
3492 }
3493
tpoindex1067fe12004-12-17 15:41:11 +00003494
drh6d313162000-09-21 13:01:35 +00003495 } /* End of the SWITCH statement */
drh22fbcb82004-02-01 01:22:50 +00003496 return rc;
drh75897232000-05-29 14:26:00 +00003497}
3498
drha2c8a952009-10-13 18:38:34 +00003499#if SQLITE_TCL_NRE
3500/*
3501** Adaptor that provides an objCmd interface to the NRE-enabled
3502** interface implementation.
3503*/
mistachkina121cc72016-07-28 18:06:52 +00003504static int SQLITE_TCLAPI DbObjCmdAdaptor(
drha2c8a952009-10-13 18:38:34 +00003505 void *cd,
3506 Tcl_Interp *interp,
3507 int objc,
3508 Tcl_Obj *const*objv
3509){
3510 return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv);
3511}
3512#endif /* SQLITE_TCL_NRE */
3513
drh75897232000-05-29 14:26:00 +00003514/*
drh4dcac402018-01-03 13:20:02 +00003515** Issue the usage message when the "sqlite3" command arguments are
3516** incorrect.
3517*/
3518static int sqliteCmdUsage(
3519 Tcl_Interp *interp,
3520 Tcl_Obj *const*objv
3521){
3522 Tcl_WrongNumArgs(interp, 1, objv,
3523 "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
3524 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
3525#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
3526 " ?-key CODECKEY?"
3527#endif
3528 );
3529 return TCL_ERROR;
3530}
3531
3532/*
drh3570ad92007-08-31 14:31:44 +00003533** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
danielk19779a6284c2008-07-10 17:52:49 +00003534** ?-create BOOLEAN? ?-nomutex BOOLEAN?
drh75897232000-05-29 14:26:00 +00003535**
3536** This is the main Tcl command. When the "sqlite" Tcl command is
3537** invoked, this routine runs to process that command.
3538**
3539** The first argument, DBNAME, is an arbitrary name for a new
3540** database connection. This command creates a new command named
3541** DBNAME that is used to control that connection. The database
3542** connection is deleted when the DBNAME command is deleted.
3543**
drh3570ad92007-08-31 14:31:44 +00003544** The second argument is the name of the database file.
drhfbc3eab2001-04-06 16:13:42 +00003545**
drh75897232000-05-29 14:26:00 +00003546*/
mistachkin7617e4a2016-07-28 17:11:20 +00003547static int SQLITE_TCLAPI DbMain(
3548 void *cd,
3549 Tcl_Interp *interp,
3550 int objc,
3551 Tcl_Obj *const*objv
3552){
drhbec3f402000-08-04 13:49:02 +00003553 SqliteDb *p;
drh22fbcb82004-02-01 01:22:50 +00003554 const char *zArg;
drh75897232000-05-29 14:26:00 +00003555 char *zErrMsg;
drh3570ad92007-08-31 14:31:44 +00003556 int i;
drh4dcac402018-01-03 13:20:02 +00003557 const char *zFile = 0;
drh3570ad92007-08-31 14:31:44 +00003558 const char *zVfs = 0;
drhd9da78a2009-03-24 15:08:09 +00003559 int flags;
drh882e8e42006-08-24 02:42:27 +00003560 Tcl_DString translatedFilename;
drh32f57d42016-03-16 01:03:10 +00003561#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drhb07028f2011-10-14 21:49:18 +00003562 void *pKey = 0;
3563 int nKey = 0;
3564#endif
mistachkin540ebf82012-09-10 07:29:29 +00003565 int rc;
drhd9da78a2009-03-24 15:08:09 +00003566
3567 /* In normal use, each TCL interpreter runs in a single thread. So
drh4dcac402018-01-03 13:20:02 +00003568 ** by default, we can turn off mutexing on SQLite database connections.
drhd9da78a2009-03-24 15:08:09 +00003569 ** However, for testing purposes it is useful to have mutexes turned
3570 ** on. So, by default, mutexes default off. But if compiled with
3571 ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
3572 */
3573#ifdef SQLITE_TCL_DEFAULT_FULLMUTEX
3574 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
3575#else
3576 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
3577#endif
3578
drhc6727c82018-09-19 15:08:21 +00003579 if( objc==1 ) return sqliteCmdUsage(interp, objv);
drh22fbcb82004-02-01 01:22:50 +00003580 if( objc==2 ){
3581 zArg = Tcl_GetStringFromObj(objv[1], 0);
drh22fbcb82004-02-01 01:22:50 +00003582 if( strcmp(zArg,"-version")==0 ){
drha198f2b2014-02-07 19:26:13 +00003583 Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
drh647cb0e2002-11-04 19:32:25 +00003584 return TCL_OK;
3585 }
drh72bf6a32016-01-07 02:06:55 +00003586 if( strcmp(zArg,"-sourceid")==0 ){
3587 Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0);
3588 return TCL_OK;
3589 }
drh9eb9e262004-02-11 02:18:05 +00003590 if( strcmp(zArg,"-has-codec")==0 ){
drh32f57d42016-03-16 01:03:10 +00003591#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drha198f2b2014-02-07 19:26:13 +00003592 Tcl_AppendResult(interp,"1",(char*)0);
drh22fbcb82004-02-01 01:22:50 +00003593#else
drha198f2b2014-02-07 19:26:13 +00003594 Tcl_AppendResult(interp,"0",(char*)0);
drh22fbcb82004-02-01 01:22:50 +00003595#endif
3596 return TCL_OK;
3597 }
drh4dcac402018-01-03 13:20:02 +00003598 if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
drhfbc3eab2001-04-06 16:13:42 +00003599 }
drh4dcac402018-01-03 13:20:02 +00003600 for(i=2; i<objc; i++){
drh3570ad92007-08-31 14:31:44 +00003601 zArg = Tcl_GetString(objv[i]);
drh4dcac402018-01-03 13:20:02 +00003602 if( zArg[0]!='-' ){
3603 if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
3604 zFile = zArg;
3605 continue;
3606 }
3607 if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
3608 i++;
drh22fbcb82004-02-01 01:22:50 +00003609 if( strcmp(zArg,"-key")==0 ){
drh32f57d42016-03-16 01:03:10 +00003610#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drh4dcac402018-01-03 13:20:02 +00003611 pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
drhb07028f2011-10-14 21:49:18 +00003612#endif
drh3570ad92007-08-31 14:31:44 +00003613 }else if( strcmp(zArg, "-vfs")==0 ){
drh4dcac402018-01-03 13:20:02 +00003614 zVfs = Tcl_GetString(objv[i]);
drh3570ad92007-08-31 14:31:44 +00003615 }else if( strcmp(zArg, "-readonly")==0 ){
3616 int b;
drh4dcac402018-01-03 13:20:02 +00003617 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
drh3570ad92007-08-31 14:31:44 +00003618 if( b ){
drh33f4e022007-09-03 15:19:34 +00003619 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
drh3570ad92007-08-31 14:31:44 +00003620 flags |= SQLITE_OPEN_READONLY;
3621 }else{
3622 flags &= ~SQLITE_OPEN_READONLY;
3623 flags |= SQLITE_OPEN_READWRITE;
3624 }
3625 }else if( strcmp(zArg, "-create")==0 ){
3626 int b;
drh4dcac402018-01-03 13:20:02 +00003627 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
drh33f4e022007-09-03 15:19:34 +00003628 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
drh3570ad92007-08-31 14:31:44 +00003629 flags |= SQLITE_OPEN_CREATE;
3630 }else{
3631 flags &= ~SQLITE_OPEN_CREATE;
3632 }
danielk19779a6284c2008-07-10 17:52:49 +00003633 }else if( strcmp(zArg, "-nomutex")==0 ){
3634 int b;
drh4dcac402018-01-03 13:20:02 +00003635 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
danielk19779a6284c2008-07-10 17:52:49 +00003636 if( b ){
3637 flags |= SQLITE_OPEN_NOMUTEX;
drh039963a2008-09-03 00:43:15 +00003638 flags &= ~SQLITE_OPEN_FULLMUTEX;
danielk19779a6284c2008-07-10 17:52:49 +00003639 }else{
3640 flags &= ~SQLITE_OPEN_NOMUTEX;
3641 }
danc431fd52011-06-27 16:55:50 +00003642 }else if( strcmp(zArg, "-fullmutex")==0 ){
drh039963a2008-09-03 00:43:15 +00003643 int b;
drh4dcac402018-01-03 13:20:02 +00003644 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
drh039963a2008-09-03 00:43:15 +00003645 if( b ){
3646 flags |= SQLITE_OPEN_FULLMUTEX;
3647 flags &= ~SQLITE_OPEN_NOMUTEX;
3648 }else{
3649 flags &= ~SQLITE_OPEN_FULLMUTEX;
3650 }
drhf12b3f62011-12-21 14:42:29 +00003651 }else if( strcmp(zArg, "-uri")==0 ){
3652 int b;
drh4dcac402018-01-03 13:20:02 +00003653 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
drhf12b3f62011-12-21 14:42:29 +00003654 if( b ){
3655 flags |= SQLITE_OPEN_URI;
3656 }else{
3657 flags &= ~SQLITE_OPEN_URI;
3658 }
drh3570ad92007-08-31 14:31:44 +00003659 }else{
3660 Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
3661 return TCL_ERROR;
drh22fbcb82004-02-01 01:22:50 +00003662 }
3663 }
drh75897232000-05-29 14:26:00 +00003664 zErrMsg = 0;
drh4cdc9e82000-08-04 14:56:24 +00003665 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
drhbec3f402000-08-04 13:49:02 +00003666 memset(p, 0, sizeof(*p));
drh3ec86652018-01-03 19:03:31 +00003667 if( zFile==0 ) zFile = "";
3668 zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
3669 rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
3670 Tcl_DStringFree(&translatedFilename);
mistachkin540ebf82012-09-10 07:29:29 +00003671 if( p->db ){
3672 if( SQLITE_OK!=sqlite3_errcode(p->db) ){
3673 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
3674 sqlite3_close(p->db);
3675 p->db = 0;
3676 }
3677 }else{
mistachkin5dac8432012-09-11 02:00:25 +00003678 zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
danielk197780290862004-05-22 09:21:21 +00003679 }
drh32f57d42016-03-16 01:03:10 +00003680#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
drhf3a65f72007-08-22 20:18:21 +00003681 if( p->db ){
3682 sqlite3_key(p->db, pKey, nKey);
3683 }
drheb8ed702004-02-11 10:37:23 +00003684#endif
drhbec3f402000-08-04 13:49:02 +00003685 if( p->db==0 ){
drh75897232000-05-29 14:26:00 +00003686 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
drhbec3f402000-08-04 13:49:02 +00003687 Tcl_Free((char*)p);
drh9404d502006-12-19 18:46:08 +00003688 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00003689 return TCL_ERROR;
3690 }
drhfb7e7652005-01-24 00:28:42 +00003691 p->maxStmt = NUM_PREPARED_STMTS;
drh147ef392016-01-22 23:17:51 +00003692 p->openFlags = flags & SQLITE_OPEN_URI;
drh5169bbc2006-08-24 14:59:45 +00003693 p->interp = interp;
drh22fbcb82004-02-01 01:22:50 +00003694 zArg = Tcl_GetStringFromObj(objv[1], 0);
dan4a4c11a2009-10-06 14:59:02 +00003695 if( DbUseNre() ){
drha2c8a952009-10-13 18:38:34 +00003696 Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
3697 (char*)p, DbDeleteCmd);
dan4a4c11a2009-10-06 14:59:02 +00003698 }else{
3699 Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
3700 }
drh75897232000-05-29 14:26:00 +00003701 return TCL_OK;
3702}
3703
3704/*
drh90ca9752001-09-28 17:47:14 +00003705** Provide a dummy Tcl_InitStubs if we are using this as a static
3706** library.
3707*/
3708#ifndef USE_TCL_STUBS
3709# undef Tcl_InitStubs
drh0e85ccf2013-06-03 12:34:46 +00003710# define Tcl_InitStubs(a,b,c) TCL_VERSION
drh90ca9752001-09-28 17:47:14 +00003711#endif
3712
3713/*
drh29bc4612005-10-05 10:40:15 +00003714** Make sure we have a PACKAGE_VERSION macro defined. This will be
3715** defined automatically by the TEA makefile. But other makefiles
3716** do not define it.
3717*/
3718#ifndef PACKAGE_VERSION
3719# define PACKAGE_VERSION SQLITE_VERSION
3720#endif
3721
3722/*
drh75897232000-05-29 14:26:00 +00003723** Initialize this module.
3724**
3725** This Tcl module contains only a single new Tcl command named "sqlite".
3726** (Hence there is no namespace. There is no point in using a namespace
3727** if the extension only supplies one new name!) The "sqlite" command is
3728** used to open a new SQLite database. See the DbMain() routine above
3729** for additional information.
drhb652f432010-08-26 16:46:57 +00003730**
3731** The EXTERN macros are required by TCL in order to work on windows.
drh75897232000-05-29 14:26:00 +00003732*/
drhb652f432010-08-26 16:46:57 +00003733EXTERN int Sqlite3_Init(Tcl_Interp *interp){
mistachkin27b2f052015-01-12 19:49:46 +00003734 int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR;
drh6dc8cbe2013-05-31 15:36:07 +00003735 if( rc==TCL_OK ){
3736 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
drh1cca0d22010-08-25 20:35:51 +00003737#ifndef SQLITE_3_SUFFIX_ONLY
drh6dc8cbe2013-05-31 15:36:07 +00003738 /* The "sqlite" alias is undocumented. It is here only to support
3739 ** legacy scripts. All new scripts should use only the "sqlite3"
3740 ** command. */
3741 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
drh4c0f1642010-08-25 19:39:19 +00003742#endif
drh6dc8cbe2013-05-31 15:36:07 +00003743 rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
3744 }
3745 return rc;
drh90ca9752001-09-28 17:47:14 +00003746}
drhb652f432010-08-26 16:46:57 +00003747EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
drhb652f432010-08-26 16:46:57 +00003748EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3749EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
drhe2c3a652008-09-23 09:58:46 +00003750
drhd878cab2012-03-20 15:10:42 +00003751/* Because it accesses the file-system and uses persistent state, SQLite
drhe75a9eb2016-02-13 18:54:10 +00003752** is not considered appropriate for safe interpreters. Hence, we cause
3753** the _SafeInit() interfaces return TCL_ERROR.
drhd878cab2012-03-20 15:10:42 +00003754*/
drhe75a9eb2016-02-13 18:54:10 +00003755EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; }
3756EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;}
3757
3758
drh49766d62005-01-08 18:42:28 +00003759
3760#ifndef SQLITE_3_SUFFIX_ONLY
dana3e63c42010-08-20 12:33:59 +00003761int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
3762int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
dana3e63c42010-08-20 12:33:59 +00003763int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3764int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
drh49766d62005-01-08 18:42:28 +00003765#endif
drh75897232000-05-29 14:26:00 +00003766
drhc318f732017-10-13 15:06:06 +00003767/*
drh96a206f2017-10-13 20:14:06 +00003768** If the TCLSH macro is defined, add code to make a stand-alone program.
drhc318f732017-10-13 15:06:06 +00003769*/
drh96a206f2017-10-13 20:14:06 +00003770#if defined(TCLSH)
drh57a02272009-10-22 20:52:05 +00003771
drh96a206f2017-10-13 20:14:06 +00003772/* This is the main routine for an ordinary TCL shell. If there are
3773** are arguments, run the first argument as a script. Otherwise,
3774** read TCL commands from standard input
drh348784e2000-05-29 20:41:49 +00003775*/
dan0ae479d2011-09-21 16:43:07 +00003776static const char *tclsh_main_loop(void){
3777 static const char zMainloop[] =
drh96a206f2017-10-13 20:14:06 +00003778 "if {[llength $argv]>=1} {\n"
3779 "set argv0 [lindex $argv 0]\n"
3780 "set argv [lrange $argv 1 end]\n"
3781 "source $argv0\n"
3782 "} else {\n"
3783 "set line {}\n"
3784 "while {![eof stdin]} {\n"
3785 "if {$line!=\"\"} {\n"
3786 "puts -nonewline \"> \"\n"
3787 "} else {\n"
3788 "puts -nonewline \"% \"\n"
dan0ae479d2011-09-21 16:43:07 +00003789 "}\n"
drh96a206f2017-10-13 20:14:06 +00003790 "flush stdout\n"
3791 "append line [gets stdin]\n"
3792 "if {[info complete $line]} {\n"
3793 "if {[catch {uplevel #0 $line} result]} {\n"
3794 "puts stderr \"Error: $result\"\n"
3795 "} elseif {$result!=\"\"} {\n"
3796 "puts $result\n"
3797 "}\n"
3798 "set line {}\n"
3799 "} else {\n"
3800 "append line \\n\n"
3801 "}\n"
dan0ae479d2011-09-21 16:43:07 +00003802 "}\n"
drh348784e2000-05-29 20:41:49 +00003803 "}\n"
dan0ae479d2011-09-21 16:43:07 +00003804 ;
3805 return zMainloop;
3806}
drh3e27c022004-07-23 00:01:38 +00003807
danc1a60c52010-06-07 14:28:16 +00003808#define TCLSH_MAIN main /* Needed to fake out mktclapp */
mistachkin69def7f2016-07-28 04:14:37 +00003809int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
danc1a60c52010-06-07 14:28:16 +00003810 Tcl_Interp *interp;
drh96a206f2017-10-13 20:14:06 +00003811 int i;
3812 const char *zScript = 0;
3813 char zArgc[32];
3814#if defined(TCLSH_INIT_PROC)
3815 extern const char *TCLSH_INIT_PROC(Tcl_Interp*);
3816#endif
mistachkin1f28e072013-08-15 08:06:15 +00003817
3818#if !defined(_WIN32_WCE)
mistachkin1e8487d2018-07-22 06:25:35 +00003819 if( getenv("SQLITE_DEBUG_BREAK") ){
3820 if( isatty(0) && isatty(2) ){
3821 fprintf(stderr,
3822 "attach debugger to process %d and press any key to continue.\n",
3823 GETPID());
3824 fgetc(stdin);
3825 }else{
3826#if defined(_WIN32) || defined(WIN32)
3827 DebugBreak();
3828#elif defined(SIGTRAP)
3829 raise(SIGTRAP);
3830#endif
3831 }
mistachkin1f28e072013-08-15 08:06:15 +00003832 }
3833#endif
3834
danc1a60c52010-06-07 14:28:16 +00003835 /* Call sqlite3_shutdown() once before doing anything else. This is to
3836 ** test that sqlite3_shutdown() can be safely called by a process before
3837 ** sqlite3_initialize() is. */
3838 sqlite3_shutdown();
3839
dan0ae479d2011-09-21 16:43:07 +00003840 Tcl_FindExecutable(argv[0]);
mistachkin2953ba92014-02-14 00:25:03 +00003841 Tcl_SetSystemEncoding(NULL, "utf-8");
dan0ae479d2011-09-21 16:43:07 +00003842 interp = Tcl_CreateInterp();
drhc318f732017-10-13 15:06:06 +00003843 Sqlite3_Init(interp);
drh96a206f2017-10-13 20:14:06 +00003844
3845 sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1);
3846 Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
3847 Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
3848 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
3849 for(i=1; i<argc; i++){
3850 Tcl_SetVar(interp, "argv", argv[i],
3851 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
drhc318f732017-10-13 15:06:06 +00003852 }
drh96a206f2017-10-13 20:14:06 +00003853#if defined(TCLSH_INIT_PROC)
3854 zScript = TCLSH_INIT_PROC(interp);
3855#endif
3856 if( zScript==0 ){
3857 zScript = tclsh_main_loop();
drh3e27c022004-07-23 00:01:38 +00003858 }
drh96a206f2017-10-13 20:14:06 +00003859 if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){
3860 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
3861 if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
3862 fprintf(stderr,"%s: %s\n", *argv, zInfo);
3863 return 1;
drh348784e2000-05-29 20:41:49 +00003864 }
3865 return 0;
3866}
3867#endif /* TCLSH */