blob: 90f933bec549bfb94c90011d392a0a5ced0648d0 [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*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
14**
drhde7446b2009-05-31 17:16:09 +000015** $Id: shell.c,v 1.210 2009/05/31 17:16:10 drh Exp $
drh75897232000-05-29 14:26:00 +000016*/
shane18e526c2008-12-10 22:30:24 +000017#if defined(_WIN32) || defined(WIN32)
18/* This needs to come before any includes for MSVC compiler */
19#define _CRT_SECURE_NO_WARNINGS
20#endif
21
drh75897232000-05-29 14:26:00 +000022#include <stdlib.h>
23#include <string.h>
24#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000025#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000026#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000027#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000028#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000029
drh454ad582007-11-26 22:54:27 +000030#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000031# include <signal.h>
chw97185482008-11-17 08:05:31 +000032# if !defined(__RTP__) && !defined(_WRS_KERNEL)
33# include <pwd.h>
34# endif
drhdd45df82002-04-18 12:39:03 +000035# include <unistd.h>
36# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000037#endif
drh75897232000-05-29 14:26:00 +000038
drhcdb36b72006-06-12 12:57:45 +000039#ifdef __OS2__
40# include <unistd.h>
41#endif
42
drh16e59552000-07-31 11:57:37 +000043#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000044# include <readline/readline.h>
45# include <readline/history.h>
46#else
drh9347b202003-07-18 01:30:59 +000047# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000048# define add_history(X)
drh67505e72002-04-19 12:34:06 +000049# define read_history(X)
50# define write_history(X)
51# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000052#endif
53
adamd2e8464a2006-09-06 21:39:40 +000054#if defined(_WIN32) || defined(WIN32)
55# include <io.h>
shane18e526c2008-12-10 22:30:24 +000056#define isatty(h) _isatty(h)
57#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000058#else
drh4328c8b2003-04-26 02:50:11 +000059/* Make sure isatty() has a prototype.
60*/
61extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000062#endif
drh4328c8b2003-04-26 02:50:11 +000063
chw65d3c132007-11-12 21:09:10 +000064#if defined(_WIN32_WCE)
65/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
66 * thus we always assume that we have a console. That can be
67 * overridden with the -batch command line option.
68 */
69#define isatty(x) 1
70#endif
71
chw97185482008-11-17 08:05:31 +000072#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000073#include <sys/time.h>
74#include <sys/resource.h>
75
drhda108222009-02-25 19:07:24 +000076/* Saved resource information for the beginning of an operation */
77static struct rusage sBegin;
78
79/* True if the timer is enabled */
80static int enableTimer = 0;
81
82/*
83** Begin timing an operation
84*/
85static void beginTimer(void){
86 if( enableTimer ){
87 getrusage(RUSAGE_SELF, &sBegin);
88 }
89}
90
91/* Return the difference of two time_structs in seconds */
92static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
93 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
94 (double)(pEnd->tv_sec - pStart->tv_sec);
95}
96
97/*
98** Print the timing results.
99*/
100static void endTimer(void){
101 if( enableTimer ){
102 struct rusage sEnd;
103 getrusage(RUSAGE_SELF, &sEnd);
104 printf("CPU Time: user %f sys %f\n",
105 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
106 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
107 }
108}
shaneb320ccd2009-10-21 03:42:58 +0000109
drhda108222009-02-25 19:07:24 +0000110#define BEGIN_TIMER beginTimer()
111#define END_TIMER endTimer()
112#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000113
114#elif (defined(_WIN32) || defined(WIN32))
115
116#include <windows.h>
117
118/* Saved resource information for the beginning of an operation */
119static HANDLE hProcess;
120static FILETIME ftKernelBegin;
121static FILETIME ftUserBegin;
122typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
123static GETPROCTIMES getProcessTimesAddr = NULL;
124
125/* True if the timer is enabled */
126static int enableTimer = 0;
127
128/*
129** Check to see if we have timer support. Return 1 if necessary
130** support found (or found previously).
131*/
132static int hasTimer(void){
133 if( getProcessTimesAddr ){
134 return 1;
135 } else {
136 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
137 ** See if the version we are running on has it, and if it does, save off
138 ** a pointer to it and the current process handle.
139 */
140 hProcess = GetCurrentProcess();
141 if( hProcess ){
142 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
143 if( NULL != hinstLib ){
144 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
145 if( NULL != getProcessTimesAddr ){
146 return 1;
147 }
148 FreeLibrary(hinstLib);
149 }
150 }
151 }
152 return 0;
153}
154
155/*
156** Begin timing an operation
157*/
158static void beginTimer(void){
159 if( enableTimer && getProcessTimesAddr ){
160 FILETIME ftCreation, ftExit;
161 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
162 }
163}
164
165/* Return the difference of two FILETIME structs in seconds */
166static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
167 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
168 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
169 return (double) ((i64End - i64Start) / 10000000.0);
170}
171
172/*
173** Print the timing results.
174*/
175static void endTimer(void){
176 if( enableTimer && getProcessTimesAddr){
177 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
178 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
179 printf("CPU Time: user %f sys %f\n",
180 timeDiff(&ftUserBegin, &ftUserEnd),
181 timeDiff(&ftKernelBegin, &ftKernelEnd));
182 }
183}
184
185#define BEGIN_TIMER beginTimer()
186#define END_TIMER endTimer()
187#define HAS_TIMER hasTimer()
188
drhda108222009-02-25 19:07:24 +0000189#else
190#define BEGIN_TIMER
191#define END_TIMER
192#define HAS_TIMER 0
193#endif
194
shanec0688ea2009-03-05 03:48:06 +0000195/*
196** Used to prevent warnings about unused parameters
197*/
198#define UNUSED_PARAMETER(x) (void)(x)
199
danielk1977c8c70692009-02-25 15:22:02 +0000200
201/**************************************************************************
202***************************************************************************
203** Begin genfkey logic.
204*/
205#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined SQLITE_OMIT_SUBQUERY
206
207#define GENFKEY_ERROR 1
208#define GENFKEY_DROPTRIGGER 2
209#define GENFKEY_CREATETRIGGER 3
210static int genfkey_create_triggers(sqlite3 *, const char *, void *,
211 int (*)(void *, int, const char *)
212);
213
214struct GenfkeyCb {
215 void *pCtx;
216 int eType;
217 int (*xData)(void *, int, const char *);
218};
219typedef struct GenfkeyCb GenfkeyCb;
220
221/* The code in this file defines a sqlite3 virtual-table module that
222** provides a read-only view of the current database schema. There is one
223** row in the schema table for each column in the database schema.
224*/
225#define SCHEMA \
226"CREATE TABLE x(" \
227 "database," /* Name of database (i.e. main, temp etc.) */ \
228 "tablename," /* Name of table */ \
229 "cid," /* Column number (from left-to-right, 0 upward) */ \
230 "name," /* Column name */ \
231 "type," /* Specified type (i.e. VARCHAR(32)) */ \
232 "not_null," /* Boolean. True if NOT NULL was specified */ \
233 "dflt_value," /* Default value for this column */ \
234 "pk" /* True if this column is part of the primary key */ \
235")"
236
237#define SCHEMA2 \
238"CREATE TABLE x(" \
239 "database," /* Name of database (i.e. main, temp etc.) */ \
240 "from_tbl," /* Name of table */ \
241 "fkid," \
242 "seq," \
243 "to_tbl," \
244 "from_col," \
245 "to_col," \
246 "on_update," \
247 "on_delete," \
248 "match" \
249")"
250
251#define SCHEMA3 \
252"CREATE TABLE x(" \
253 "database," /* Name of database (i.e. main, temp etc.) */ \
254 "tablename," /* Name of table */ \
255 "seq," \
256 "name," \
257 "isunique" \
258")"
259
260#define SCHEMA4 \
261"CREATE TABLE x(" \
262 "database," /* Name of database (i.e. main, temp etc.) */ \
263 "indexname," /* Name of table */ \
264 "seqno," \
265 "cid," \
266 "name" \
267")"
268
269#define SCHEMA5 \
270"CREATE TABLE x(" \
271 "database," /* Name of database (i.e. main, temp etc.) */ \
272 "triggername," /* Name of trigger */ \
273 "dummy" /* Unused */ \
274")"
275
276typedef struct SchemaTable SchemaTable;
shane16f954c2009-10-21 13:53:58 +0000277static struct SchemaTable {
danielk1977c8c70692009-02-25 15:22:02 +0000278 const char *zName;
279 const char *zObject;
280 const char *zPragma;
281 const char *zSchema;
282} aSchemaTable[] = {
283 { "table_info", "table", "PRAGMA %Q.table_info(%Q)", SCHEMA },
284 { "foreign_key_list", "table", "PRAGMA %Q.foreign_key_list(%Q)", SCHEMA2 },
285 { "index_list", "table", "PRAGMA %Q.index_list(%Q)", SCHEMA3 },
286 { "index_info", "index", "PRAGMA %Q.index_info(%Q)", SCHEMA4 },
287 { "trigger_list", "trigger", "SELECT 1", SCHEMA5 },
288 { 0, 0, 0, 0 }
289};
290
291typedef struct schema_vtab schema_vtab;
292typedef struct schema_cursor schema_cursor;
293
294/* A schema table object */
295struct schema_vtab {
296 sqlite3_vtab base;
297 sqlite3 *db;
298 SchemaTable *pType;
299};
300
301/* A schema table cursor object */
302struct schema_cursor {
303 sqlite3_vtab_cursor base;
304 sqlite3_stmt *pDbList;
305 sqlite3_stmt *pTableList;
306 sqlite3_stmt *pColumnList;
307 int rowid;
308};
309
310/*
311** Table destructor for the schema module.
312*/
313static int schemaDestroy(sqlite3_vtab *pVtab){
314 sqlite3_free(pVtab);
315 return 0;
316}
317
318/*
319** Table constructor for the schema module.
320*/
321static int schemaCreate(
322 sqlite3 *db,
323 void *pAux,
324 int argc, const char *const*argv,
325 sqlite3_vtab **ppVtab,
326 char **pzErr
327){
328 int rc = SQLITE_NOMEM;
329 schema_vtab *pVtab;
330 SchemaTable *pType = &aSchemaTable[0];
331
shanec0688ea2009-03-05 03:48:06 +0000332 UNUSED_PARAMETER(pzErr);
danielk1977c8c70692009-02-25 15:22:02 +0000333 if( argc>3 ){
334 int i;
335 pType = 0;
336 for(i=0; aSchemaTable[i].zName; i++){
337 if( 0==strcmp(argv[3], aSchemaTable[i].zName) ){
338 pType = &aSchemaTable[i];
339 }
340 }
341 if( !pType ){
342 return SQLITE_ERROR;
343 }
344 }
345
346 pVtab = sqlite3_malloc(sizeof(schema_vtab));
347 if( pVtab ){
348 memset(pVtab, 0, sizeof(schema_vtab));
349 pVtab->db = (sqlite3 *)pAux;
350 pVtab->pType = pType;
351 rc = sqlite3_declare_vtab(db, pType->zSchema);
352 }
353 *ppVtab = (sqlite3_vtab *)pVtab;
354 return rc;
355}
356
357/*
358** Open a new cursor on the schema table.
359*/
360static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
361 int rc = SQLITE_NOMEM;
362 schema_cursor *pCur;
shanec0688ea2009-03-05 03:48:06 +0000363 UNUSED_PARAMETER(pVTab);
danielk1977c8c70692009-02-25 15:22:02 +0000364 pCur = sqlite3_malloc(sizeof(schema_cursor));
365 if( pCur ){
366 memset(pCur, 0, sizeof(schema_cursor));
367 *ppCursor = (sqlite3_vtab_cursor *)pCur;
368 rc = SQLITE_OK;
369 }
370 return rc;
371}
372
373/*
374** Close a schema table cursor.
375*/
376static int schemaClose(sqlite3_vtab_cursor *cur){
377 schema_cursor *pCur = (schema_cursor *)cur;
378 sqlite3_finalize(pCur->pDbList);
379 sqlite3_finalize(pCur->pTableList);
380 sqlite3_finalize(pCur->pColumnList);
381 sqlite3_free(pCur);
382 return SQLITE_OK;
383}
384
385static void columnToResult(sqlite3_context *ctx, sqlite3_stmt *pStmt, int iCol){
386 switch( sqlite3_column_type(pStmt, iCol) ){
387 case SQLITE_NULL:
388 sqlite3_result_null(ctx);
389 break;
390 case SQLITE_INTEGER:
391 sqlite3_result_int64(ctx, sqlite3_column_int64(pStmt, iCol));
392 break;
393 case SQLITE_FLOAT:
394 sqlite3_result_double(ctx, sqlite3_column_double(pStmt, iCol));
395 break;
396 case SQLITE_TEXT: {
397 const char *z = (const char *)sqlite3_column_text(pStmt, iCol);
398 sqlite3_result_text(ctx, z, -1, SQLITE_TRANSIENT);
399 break;
400 }
401 }
402}
403
404/*
405** Retrieve a column of data.
406*/
407static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
408 schema_cursor *pCur = (schema_cursor *)cur;
409 switch( i ){
410 case 0:
411 columnToResult(ctx, pCur->pDbList, 1);
412 break;
413 case 1:
414 columnToResult(ctx, pCur->pTableList, 0);
415 break;
416 default:
417 columnToResult(ctx, pCur->pColumnList, i-2);
418 break;
419 }
420 return SQLITE_OK;
421}
422
423/*
424** Retrieve the current rowid.
425*/
426static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
427 schema_cursor *pCur = (schema_cursor *)cur;
428 *pRowid = pCur->rowid;
429 return SQLITE_OK;
430}
431
432static int finalize(sqlite3_stmt **ppStmt){
433 int rc = sqlite3_finalize(*ppStmt);
434 *ppStmt = 0;
435 return rc;
436}
437
438static int schemaEof(sqlite3_vtab_cursor *cur){
439 schema_cursor *pCur = (schema_cursor *)cur;
440 return (pCur->pDbList ? 0 : 1);
441}
442
443/*
444** Advance the cursor to the next row.
445*/
446static int schemaNext(sqlite3_vtab_cursor *cur){
447 int rc = SQLITE_OK;
448 schema_cursor *pCur = (schema_cursor *)cur;
449 schema_vtab *pVtab = (schema_vtab *)(cur->pVtab);
450 char *zSql = 0;
451
452 while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){
453 if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit;
454
455 while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){
456 if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit;
457
458 assert(pCur->pDbList);
459 while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){
460 rc = finalize(&pCur->pDbList);
461 goto next_exit;
462 }
463
464 /* Set zSql to the SQL to pull the list of tables from the
465 ** sqlite_master (or sqlite_temp_master) table of the database
466 ** identfied by the row pointed to by the SQL statement pCur->pDbList
467 ** (iterating through a "PRAGMA database_list;" statement).
468 */
469 if( sqlite3_column_int(pCur->pDbList, 0)==1 ){
470 zSql = sqlite3_mprintf(
471 "SELECT name FROM sqlite_temp_master WHERE type=%Q",
472 pVtab->pType->zObject
473 );
474 }else{
475 sqlite3_stmt *pDbList = pCur->pDbList;
476 zSql = sqlite3_mprintf(
477 "SELECT name FROM %Q.sqlite_master WHERE type=%Q",
478 sqlite3_column_text(pDbList, 1), pVtab->pType->zObject
479 );
480 }
481 if( !zSql ){
482 rc = SQLITE_NOMEM;
483 goto next_exit;
484 }
485
486 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0);
487 sqlite3_free(zSql);
488 if( rc!=SQLITE_OK ) goto next_exit;
489 }
490
491 /* Set zSql to the SQL to the table_info pragma for the table currently
492 ** identified by the rows pointed to by statements pCur->pDbList and
493 ** pCur->pTableList.
494 */
495 zSql = sqlite3_mprintf(pVtab->pType->zPragma,
496 sqlite3_column_text(pCur->pDbList, 1),
497 sqlite3_column_text(pCur->pTableList, 0)
498 );
499
500 if( !zSql ){
501 rc = SQLITE_NOMEM;
502 goto next_exit;
503 }
504 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0);
505 sqlite3_free(zSql);
506 if( rc!=SQLITE_OK ) goto next_exit;
507 }
508 pCur->rowid++;
509
510next_exit:
511 /* TODO: Handle rc */
512 return rc;
513}
514
515/*
516** Reset a schema table cursor.
517*/
518static int schemaFilter(
519 sqlite3_vtab_cursor *pVtabCursor,
520 int idxNum, const char *idxStr,
521 int argc, sqlite3_value **argv
522){
523 int rc;
524 schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab);
525 schema_cursor *pCur = (schema_cursor *)pVtabCursor;
shanec0688ea2009-03-05 03:48:06 +0000526 UNUSED_PARAMETER(idxNum);
527 UNUSED_PARAMETER(idxStr);
528 UNUSED_PARAMETER(argc);
529 UNUSED_PARAMETER(argv);
danielk1977c8c70692009-02-25 15:22:02 +0000530 pCur->rowid = 0;
531 finalize(&pCur->pTableList);
532 finalize(&pCur->pColumnList);
533 finalize(&pCur->pDbList);
534 rc = sqlite3_prepare(pVtab->db,"SELECT 0, 'main'", -1, &pCur->pDbList, 0);
535 return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc);
536}
537
538/*
539** Analyse the WHERE condition.
540*/
541static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
shanec0688ea2009-03-05 03:48:06 +0000542 UNUSED_PARAMETER(tab);
543 UNUSED_PARAMETER(pIdxInfo);
danielk1977c8c70692009-02-25 15:22:02 +0000544 return SQLITE_OK;
545}
546
547/*
548** A virtual table module that merely echos method calls into TCL
549** variables.
550*/
551static sqlite3_module schemaModule = {
552 0, /* iVersion */
553 schemaCreate,
554 schemaCreate,
555 schemaBestIndex,
556 schemaDestroy,
557 schemaDestroy,
558 schemaOpen, /* xOpen - open a cursor */
559 schemaClose, /* xClose - close a cursor */
560 schemaFilter, /* xFilter - configure scan constraints */
561 schemaNext, /* xNext - advance a cursor */
562 schemaEof, /* xEof */
563 schemaColumn, /* xColumn - read data */
564 schemaRowid, /* xRowid - read data */
565 0, /* xUpdate */
566 0, /* xBegin */
567 0, /* xSync */
568 0, /* xCommit */
569 0, /* xRollback */
570 0, /* xFindMethod */
571 0, /* xRename */
572};
573
574/*
575** Extension load function.
576*/
577static int installSchemaModule(sqlite3 *db, sqlite3 *sdb){
578 sqlite3_create_module(db, "schema", &schemaModule, (void *)sdb);
579 return 0;
580}
581
582/*
583** sj(zValue, zJoin)
584**
585** The following block contains the implementation of an aggregate
586** function that returns a string. Each time the function is stepped,
587** it appends data to an internal buffer. When the aggregate is finalized,
588** the contents of the buffer are returned.
589**
590** The first time the aggregate is stepped the buffer is set to a copy
591** of the first argument. The second time and subsequent times it is
592** stepped a copy of the second argument is appended to the buffer, then
593** a copy of the first.
594**
595** Example:
596**
597** INSERT INTO t1(a) VALUES('1');
598** INSERT INTO t1(a) VALUES('2');
599** INSERT INTO t1(a) VALUES('3');
600** SELECT sj(a, ', ') FROM t1;
601**
602** => "1, 2, 3"
603**
604*/
605struct StrBuffer {
606 char *zBuf;
607};
608typedef struct StrBuffer StrBuffer;
609static void joinFinalize(sqlite3_context *context){
610 StrBuffer *p;
611 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
612 sqlite3_result_text(context, p->zBuf, -1, SQLITE_TRANSIENT);
613 sqlite3_free(p->zBuf);
614}
615static void joinStep(
616 sqlite3_context *context,
617 int argc,
618 sqlite3_value **argv
619){
620 StrBuffer *p;
shanec0688ea2009-03-05 03:48:06 +0000621 UNUSED_PARAMETER(argc);
danielk1977c8c70692009-02-25 15:22:02 +0000622 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
623 if( p->zBuf==0 ){
624 p->zBuf = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
625 }else{
626 char *zTmp = p->zBuf;
627 p->zBuf = sqlite3_mprintf("%s%s%s",
628 zTmp, sqlite3_value_text(argv[1]), sqlite3_value_text(argv[0])
629 );
630 sqlite3_free(zTmp);
631 }
632}
633
634/*
635** dq(zString)
636**
637** This scalar function accepts a single argument and interprets it as
638** a text value. The return value is the argument enclosed in double
639** quotes. If any double quote characters are present in the argument,
640** these are escaped.
641**
642** dq('the raven "Nevermore."') == '"the raven ""Nevermore."""'
643*/
644static void doublequote(
645 sqlite3_context *context,
646 int argc,
647 sqlite3_value **argv
648){
649 int ii;
650 char *zOut;
651 char *zCsr;
652 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
653 int nIn = sqlite3_value_bytes(argv[0]);
654
shanec0688ea2009-03-05 03:48:06 +0000655 UNUSED_PARAMETER(argc);
danielk1977c8c70692009-02-25 15:22:02 +0000656 zOut = sqlite3_malloc(nIn*2+3);
657 zCsr = zOut;
658 *zCsr++ = '"';
659 for(ii=0; ii<nIn; ii++){
660 *zCsr++ = zIn[ii];
661 if( zIn[ii]=='"' ){
662 *zCsr++ = '"';
663 }
664 }
665 *zCsr++ = '"';
666 *zCsr++ = '\0';
667
668 sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT);
669 sqlite3_free(zOut);
670}
671
672/*
673** multireplace(zString, zSearch1, zReplace1, ...)
674*/
675static void multireplace(
676 sqlite3_context *context,
677 int argc,
678 sqlite3_value **argv
679){
680 int i = 0;
681 char *zOut = 0;
682 int nOut = 0;
683 int nMalloc = 0;
684 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
685 int nIn = sqlite3_value_bytes(argv[0]);
686
687 while( i<nIn ){
688 const char *zCopy = &zIn[i];
689 int nCopy = 1;
690 int nReplace = 1;
691 int j;
692 for(j=1; j<(argc-1); j+=2){
693 const char *z = (const char *)sqlite3_value_text(argv[j]);
694 int n = sqlite3_value_bytes(argv[j]);
695 if( n<=(nIn-i) && 0==strncmp(z, zCopy, n) ){
696 zCopy = (const char *)sqlite3_value_text(argv[j+1]);
697 nCopy = sqlite3_value_bytes(argv[j+1]);
698 nReplace = n;
699 break;
700 }
701 }
702 if( (nOut+nCopy)>nMalloc ){
drhde7446b2009-05-31 17:16:09 +0000703 char *zNew;
danielk19779365c672009-03-13 15:32:53 +0000704 nMalloc = 16 + (nOut+nCopy)*2;
drhde7446b2009-05-31 17:16:09 +0000705 zNew = (char*)sqlite3_realloc(zOut, nMalloc);
706 if( zNew==0 ){
707 sqlite3_result_error_nomem(context);
708 return;
709 }else{
710 zOut = zNew;
711 }
danielk1977c8c70692009-02-25 15:22:02 +0000712 }
danielk19779365c672009-03-13 15:32:53 +0000713 assert( nMalloc>=(nOut+nCopy) );
danielk1977c8c70692009-02-25 15:22:02 +0000714 memcpy(&zOut[nOut], zCopy, nCopy);
715 i += nReplace;
716 nOut += nCopy;
717 }
718
719 sqlite3_result_text(context, zOut, nOut, SQLITE_TRANSIENT);
720 sqlite3_free(zOut);
721}
722
723/*
724** A callback for sqlite3_exec() invokes the callback specified by the
725** GenfkeyCb structure pointed to by the void* passed as the first argument.
726*/
727static int invokeCallback(void *p, int nArg, char **azArg, char **azCol){
728 GenfkeyCb *pCb = (GenfkeyCb *)p;
shanec0688ea2009-03-05 03:48:06 +0000729 UNUSED_PARAMETER(nArg);
730 UNUSED_PARAMETER(azCol);
danielk1977c8c70692009-02-25 15:22:02 +0000731 return pCb->xData(pCb->pCtx, pCb->eType, azArg[0]);
732}
733
shane16f954c2009-10-21 13:53:58 +0000734static int detectSchemaProblem(
danielk1977c8c70692009-02-25 15:22:02 +0000735 sqlite3 *db, /* Database connection */
736 const char *zMessage, /* English language error message */
737 const char *zSql, /* SQL statement to run */
738 GenfkeyCb *pCb
739){
740 sqlite3_stmt *pStmt;
741 int rc;
742 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
743 if( rc!=SQLITE_OK ){
744 return rc;
745 }
746 while( SQLITE_ROW==sqlite3_step(pStmt) ){
747 char *zDel;
748 int iFk = sqlite3_column_int(pStmt, 0);
749 const char *zTab = (const char *)sqlite3_column_text(pStmt, 1);
750 zDel = sqlite3_mprintf("Error in table %s: %s", zTab, zMessage);
751 rc = pCb->xData(pCb->pCtx, pCb->eType, zDel);
752 sqlite3_free(zDel);
753 if( rc!=SQLITE_OK ) return rc;
754 zDel = sqlite3_mprintf(
755 "DELETE FROM temp.fkey WHERE from_tbl = %Q AND fkid = %d"
756 , zTab, iFk
757 );
758 sqlite3_exec(db, zDel, 0, 0, 0);
759 sqlite3_free(zDel);
760 }
761 sqlite3_finalize(pStmt);
762 return SQLITE_OK;
763}
764
765/*
766** Create and populate temporary table "fkey".
767*/
768static int populateTempTable(sqlite3 *db, GenfkeyCb *pCallback){
769 int rc;
770
771 rc = sqlite3_exec(db,
772 "CREATE VIRTUAL TABLE temp.v_fkey USING schema(foreign_key_list);"
773 "CREATE VIRTUAL TABLE temp.v_col USING schema(table_info);"
774 "CREATE VIRTUAL TABLE temp.v_idxlist USING schema(index_list);"
775 "CREATE VIRTUAL TABLE temp.v_idxinfo USING schema(index_info);"
776 "CREATE VIRTUAL TABLE temp.v_triggers USING schema(trigger_list);"
777 "CREATE TABLE temp.fkey AS "
778 "SELECT from_tbl, to_tbl, fkid, from_col, to_col, on_update, on_delete "
779 "FROM temp.v_fkey WHERE database = 'main';"
780 , 0, 0, 0
781 );
782 if( rc!=SQLITE_OK ) return rc;
783
784 rc = detectSchemaProblem(db, "foreign key columns do not exist",
785 "SELECT fkid, from_tbl "
786 "FROM temp.fkey "
787 "WHERE to_col IS NOT NULL AND NOT EXISTS (SELECT 1 "
788 "FROM temp.v_col WHERE tablename=to_tbl AND name==to_col"
789 ")", pCallback
790 );
791 if( rc!=SQLITE_OK ) return rc;
792
793 /* At this point the temp.fkey table is mostly populated. If any foreign
794 ** keys were specified so that they implicitly refer to they primary
795 ** key of the parent table, the "to_col" values of the temp.fkey rows
796 ** are still set to NULL.
797 **
798 ** This is easily fixed for single column primary keys, but not for
799 ** composites. With a composite primary key, there is no way to reliably
800 ** query sqlite for the order in which the columns that make up the
801 ** composite key were declared i.e. there is no way to tell if the
802 ** schema actually contains "PRIMARY KEY(a, b)" or "PRIMARY KEY(b, a)".
803 ** Therefore, this case is not handled. The following function call
804 ** detects instances of this case.
805 */
806 rc = detectSchemaProblem(db, "implicit mapping to composite primary key",
807 "SELECT fkid, from_tbl "
808 "FROM temp.fkey "
809 "WHERE to_col IS NULL "
810 "GROUP BY fkid, from_tbl HAVING count(*) > 1", pCallback
811 );
812 if( rc!=SQLITE_OK ) return rc;
813
814 /* Detect attempts to implicitly map to the primary key of a table
815 ** that has no primary key column.
816 */
817 rc = detectSchemaProblem(db, "implicit mapping to non-existant primary key",
818 "SELECT fkid, from_tbl "
819 "FROM temp.fkey "
820 "WHERE to_col IS NULL AND NOT EXISTS "
821 "(SELECT 1 FROM temp.v_col WHERE pk AND tablename = temp.fkey.to_tbl)"
822 , pCallback
823 );
824 if( rc!=SQLITE_OK ) return rc;
825
826 /* Fix all the implicit primary key mappings in the temp.fkey table. */
827 rc = sqlite3_exec(db,
828 "UPDATE temp.fkey SET to_col = "
829 "(SELECT name FROM temp.v_col WHERE pk AND tablename=temp.fkey.to_tbl)"
830 " WHERE to_col IS NULL;"
831 , 0, 0, 0
832 );
833 if( rc!=SQLITE_OK ) return rc;
834
835 /* Now check that all all parent keys are either primary keys or
836 ** subject to a unique constraint.
837 */
838 rc = sqlite3_exec(db,
839 "CREATE TABLE temp.idx2 AS SELECT "
840 "il.tablename AS tablename,"
841 "ii.indexname AS indexname,"
842 "ii.name AS col "
843 "FROM temp.v_idxlist AS il, temp.v_idxinfo AS ii "
844 "WHERE il.isunique AND il.database='main' AND ii.indexname = il.name;"
845 "INSERT INTO temp.idx2 "
846 "SELECT tablename, 'pk', name FROM temp.v_col WHERE pk;"
847
848 "CREATE TABLE temp.idx AS SELECT "
849 "tablename, indexname, sj(dq(col),',') AS cols "
850 "FROM (SELECT * FROM temp.idx2 ORDER BY col) "
851 "GROUP BY tablename, indexname;"
852
853 "CREATE TABLE temp.fkey2 AS SELECT "
854 "fkid, from_tbl, to_tbl, sj(dq(to_col),',') AS cols "
855 "FROM (SELECT * FROM temp.fkey ORDER BY to_col) "
856 "GROUP BY fkid, from_tbl;"
857
858 "CREATE TABLE temp.triggers AS SELECT "
859 "triggername FROM temp.v_triggers WHERE database='main' AND "
860 "triggername LIKE 'genfkey%';"
861 , 0, 0, 0
862 );
863 if( rc!=SQLITE_OK ) return rc;
864 rc = detectSchemaProblem(db, "foreign key is not unique",
865 "SELECT fkid, from_tbl "
866 "FROM temp.fkey2 "
867 "WHERE NOT EXISTS (SELECT 1 "
868 "FROM temp.idx WHERE tablename=to_tbl AND fkey2.cols==idx.cols"
869 ")", pCallback
870 );
871 if( rc!=SQLITE_OK ) return rc;
872
873 return rc;
874}
875
876#define GENFKEY_ERROR 1
877#define GENFKEY_DROPTRIGGER 2
878#define GENFKEY_CREATETRIGGER 3
879static int genfkey_create_triggers(
880 sqlite3 *sdb, /* Connection to read schema from */
881 const char *zDb, /* Name of db to read ("main", "temp") */
882 void *pCtx, /* Context pointer to pass to xData */
883 int (*xData)(void *, int, const char *)
884){
885 const char *zSql =
886 "SELECT multireplace('"
887
888 "-- Triggers for foreign key mapping:\n"
889 "--\n"
890 "-- /from_readable/ REFERENCES /to_readable/\n"
891 "-- on delete /on_delete/\n"
892 "-- on update /on_update/\n"
893 "--\n"
894
895 /* The "BEFORE INSERT ON <referencing>" trigger. This trigger's job is to
896 ** throw an exception if the user tries to insert a row into the
897 ** referencing table for which there is no corresponding row in
898 ** the referenced table.
899 */
900 "CREATE TRIGGER /name/_insert_referencing BEFORE INSERT ON /tbl/ WHEN \n"
901 " /key_notnull/ AND NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
902 "BEGIN\n"
903 " SELECT RAISE(ABORT, ''constraint failed'');\n"
904 "END;\n"
905
906 /* The "BEFORE UPDATE ON <referencing>" trigger. This trigger's job
907 ** is to throw an exception if the user tries to update a row in the
908 ** referencing table causing it to correspond to no row in the
909 ** referenced table.
910 */
911 "CREATE TRIGGER /name/_update_referencing BEFORE\n"
912 " UPDATE OF /rkey_list/ ON /tbl/ WHEN \n"
913 " /key_notnull/ AND \n"
914 " NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
915 "BEGIN\n"
916 " SELECT RAISE(ABORT, ''constraint failed'');\n"
917 "END;\n"
918
919
920 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
921 ** is to detect when a row is deleted from the referenced table to
922 ** which rows in the referencing table correspond. The action taken
923 ** depends on the value of the 'ON DELETE' clause.
924 */
925 "CREATE TRIGGER /name/_delete_referenced BEFORE DELETE ON /ref/ WHEN\n"
926 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
927 "BEGIN\n"
928 " /delete_action/\n"
929 "END;\n"
930
dan1da40a32009-09-19 17:00:31 +0000931 /* The "AFTER UPDATE ON <referenced>" trigger. This trigger's job
danielk1977c8c70692009-02-25 15:22:02 +0000932 ** is to detect when the key columns of a row in the referenced table
933 ** to which one or more rows in the referencing table correspond are
934 ** updated. The action taken depends on the value of the 'ON UPDATE'
935 ** clause.
936 */
937 "CREATE TRIGGER /name/_update_referenced AFTER\n"
938 " UPDATE OF /fkey_list/ ON /ref/ WHEN \n"
939 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
940 "BEGIN\n"
941 " /update_action/\n"
942 "END;\n"
943 "'"
944
945 /* These are used in the SQL comment written above each set of triggers */
946 ", '/from_readable/', from_tbl || '(' || sj(from_col, ', ') || ')'"
947 ", '/to_readable/', to_tbl || '(' || sj(to_col, ', ') || ')'"
948 ", '/on_delete/', on_delete"
949 ", '/on_update/', on_update"
950
951 ", '/name/', 'genfkey' || min(rowid)"
952 ", '/tbl/', dq(from_tbl)"
953 ", '/ref/', dq(to_tbl)"
954 ", '/key_notnull/', sj('new.' || dq(from_col) || ' IS NOT NULL', ' AND ')"
955
dan8b6d37d2009-10-08 13:42:28 +0000956 ", '/fkey_list/', sj(dq(to_col), ', ')"
957 ", '/rkey_list/', sj(dq(from_col), ', ')"
danielk1977c8c70692009-02-25 15:22:02 +0000958
959 ", '/cond1/', sj(multireplace('new./from/ == /to/'"
960 ", '/from/', dq(from_col)"
961 ", '/to/', dq(to_col)"
962 "), ' AND ')"
963 ", '/cond2/', sj(multireplace('old./to/ == /from/'"
964 ", '/from/', dq(from_col)"
965 ", '/to/', dq(to_col)"
966 "), ' AND ')"
967
968 ", '/update_action/', CASE on_update "
969 "WHEN 'SET NULL' THEN "
970 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
dan8b6d37d2009-10-08 13:42:28 +0000971 ", '/setlist/', sj(dq(from_col)||' = NULL',', ')"
danielk1977c8c70692009-02-25 15:22:02 +0000972 ", '/tbl/', dq(from_tbl)"
dan8b6d37d2009-10-08 13:42:28 +0000973 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
danielk1977c8c70692009-02-25 15:22:02 +0000974 ")"
975 "WHEN 'CASCADE' THEN "
976 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
977 ", '/setlist/', sj(dq(from_col)||' = new.'||dq(to_col),', ')"
978 ", '/tbl/', dq(from_tbl)"
979 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
980 ")"
981 "ELSE "
982 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
983 "END "
984
985 ", '/delete_action/', CASE on_delete "
986 "WHEN 'SET NULL' THEN "
987 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
dan8b6d37d2009-10-08 13:42:28 +0000988 ", '/setlist/', sj(dq(from_col)||' = NULL',', ')"
danielk1977c8c70692009-02-25 15:22:02 +0000989 ", '/tbl/', dq(from_tbl)"
dan8b6d37d2009-10-08 13:42:28 +0000990 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
danielk1977c8c70692009-02-25 15:22:02 +0000991 ")"
992 "WHEN 'CASCADE' THEN "
993 "multireplace('DELETE FROM /tbl/ WHERE /where/;' "
994 ", '/tbl/', dq(from_tbl)"
995 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
996 ")"
997 "ELSE "
998 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
999 "END "
1000
1001 ") FROM temp.fkey "
1002 "GROUP BY from_tbl, fkid"
1003 ;
1004
1005 int rc;
1006 const int enc = SQLITE_UTF8;
1007 sqlite3 *db = 0;
1008
1009 GenfkeyCb cb;
1010 cb.xData = xData;
1011 cb.pCtx = pCtx;
1012
shanec0688ea2009-03-05 03:48:06 +00001013 UNUSED_PARAMETER(zDb);
1014
danielk1977c8c70692009-02-25 15:22:02 +00001015 /* Open the working database handle. */
1016 rc = sqlite3_open(":memory:", &db);
1017 if( rc!=SQLITE_OK ) goto genfkey_exit;
1018
1019 /* Create the special scalar and aggregate functions used by this program. */
1020 sqlite3_create_function(db, "dq", 1, enc, 0, doublequote, 0, 0);
1021 sqlite3_create_function(db, "multireplace", -1, enc, db, multireplace, 0, 0);
1022 sqlite3_create_function(db, "sj", 2, enc, 0, 0, joinStep, joinFinalize);
1023
1024 /* Install the "schema" virtual table module */
1025 installSchemaModule(db, sdb);
1026
1027 /* Create and populate a temp table with the information required to
1028 ** build the foreign key triggers. See function populateTempTable()
1029 ** for details.
1030 */
1031 cb.eType = GENFKEY_ERROR;
1032 rc = populateTempTable(db, &cb);
1033 if( rc!=SQLITE_OK ) goto genfkey_exit;
1034
1035 /* Unless the --no-drop option was specified, generate DROP TRIGGER
1036 ** statements to drop any triggers in the database generated by a
1037 ** previous run of this program.
1038 */
1039 cb.eType = GENFKEY_DROPTRIGGER;
1040 rc = sqlite3_exec(db,
1041 "SELECT 'DROP TRIGGER main.' || dq(triggername) || ';' FROM triggers"
1042 ,invokeCallback, (void *)&cb, 0
1043 );
1044 if( rc!=SQLITE_OK ) goto genfkey_exit;
1045
1046 /* Run the main query to create the trigger definitions. */
1047 cb.eType = GENFKEY_CREATETRIGGER;
1048 rc = sqlite3_exec(db, zSql, invokeCallback, (void *)&cb, 0);
1049 if( rc!=SQLITE_OK ) goto genfkey_exit;
1050
1051genfkey_exit:
1052 sqlite3_close(db);
1053 return rc;
1054}
1055
1056
1057#endif
1058/* End genfkey logic. */
1059/*************************************************************************/
1060/*************************************************************************/
1061
drhe91d16b2008-12-08 18:27:31 +00001062/*
drhc49f44e2006-10-26 18:15:42 +00001063** If the following flag is set, then command execution stops
1064** at an error if we are not interactive.
1065*/
1066static int bail_on_error = 0;
1067
1068/*
drhc28490c2006-10-26 14:25:58 +00001069** Threat stdin as an interactive input if the following variable
1070** is true. Otherwise, assume stdin is connected to a file or pipe.
1071*/
1072static int stdin_is_interactive = 1;
1073
1074/*
drh4c504392000-10-16 22:06:40 +00001075** The following is the open SQLite database. We make a pointer
1076** to this database a static variable so that it can be accessed
1077** by the SIGINT handler to interrupt database processing.
1078*/
danielk197792f9a1b2004-06-19 09:08:16 +00001079static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +00001080
1081/*
drh67505e72002-04-19 12:34:06 +00001082** True if an interrupt (Control-C) has been received.
1083*/
drh43617e92006-03-06 20:55:46 +00001084static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +00001085
1086/*
persicom7e2dfdd2002-04-18 02:46:52 +00001087** This is the name of our program. It is set in main(), used
1088** in a number of other places, mostly for error messages.
1089*/
1090static char *Argv0;
1091
1092/*
1093** Prompt strings. Initialized in main. Settable with
1094** .prompt main continue
1095*/
1096static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
1097static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
1098
drhb0603412007-02-28 04:47:26 +00001099/*
1100** Write I/O traces to the following stream.
1101*/
rsebe0a9092007-07-30 18:24:38 +00001102#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001103static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +00001104#endif
drhb0603412007-02-28 04:47:26 +00001105
1106/*
1107** This routine works like printf in that its first argument is a
1108** format string and subsequent arguments are values to be substituted
1109** in place of % fields. The result of formatting this string
1110** is written to iotrace.
1111*/
rsebe0a9092007-07-30 18:24:38 +00001112#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001113static void iotracePrintf(const char *zFormat, ...){
1114 va_list ap;
drhf075cd02007-02-28 06:14:25 +00001115 char *z;
drhb0603412007-02-28 04:47:26 +00001116 if( iotrace==0 ) return;
1117 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +00001118 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +00001119 va_end(ap);
drhf075cd02007-02-28 06:14:25 +00001120 fprintf(iotrace, "%s", z);
1121 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +00001122}
rsebe0a9092007-07-30 18:24:38 +00001123#endif
drhb0603412007-02-28 04:47:26 +00001124
drh44c2eb12003-04-30 11:38:26 +00001125
persicom7e2dfdd2002-04-18 02:46:52 +00001126/*
drh83965662003-04-17 02:54:13 +00001127** Determines if a string is a number of not.
1128*/
danielk19772e588c72005-12-09 14:25:08 +00001129static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +00001130 if( *z=='-' || *z=='+' ) z++;
1131 if( !isdigit(*z) ){
1132 return 0;
1133 }
1134 z++;
1135 if( realnum ) *realnum = 0;
1136 while( isdigit(*z) ){ z++; }
1137 if( *z=='.' ){
1138 z++;
1139 if( !isdigit(*z) ) return 0;
1140 while( isdigit(*z) ){ z++; }
1141 if( realnum ) *realnum = 1;
1142 }
1143 if( *z=='e' || *z=='E' ){
1144 z++;
1145 if( *z=='+' || *z=='-' ) z++;
1146 if( !isdigit(*z) ) return 0;
1147 while( isdigit(*z) ){ z++; }
1148 if( realnum ) *realnum = 1;
1149 }
1150 return *z==0;
1151}
drh83965662003-04-17 02:54:13 +00001152
1153/*
danielk1977bc6ada42004-06-30 08:20:16 +00001154** A global char* and an SQL function to access its current value
1155** from within an SQL statement. This program used to use the
1156** sqlite_exec_printf() API to substitue a string into an SQL statement.
1157** The correct way to do this with sqlite3 is to use the bind API, but
1158** since the shell is built around the callback paradigm it would be a lot
1159** of work. Instead just use this hack, which is quite harmless.
1160*/
1161static const char *zShellStatic = 0;
1162static void shellstaticFunc(
1163 sqlite3_context *context,
1164 int argc,
1165 sqlite3_value **argv
1166){
1167 assert( 0==argc );
1168 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +00001169 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +00001170 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +00001171 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
1172}
1173
1174
1175/*
drhfeac5f82004-08-01 00:10:45 +00001176** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +00001177** the text in memory obtained from malloc() and returns a pointer
1178** to the text. NULL is returned at end of file, or if malloc()
1179** fails.
1180**
1181** The interface is like "readline" but no command-line editing
1182** is done.
1183*/
drh9347b202003-07-18 01:30:59 +00001184static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +00001185 char *zLine;
1186 int nLine;
drh8e7e7a22000-05-30 18:45:23 +00001187 int n;
1188 int eol;
1189
1190 if( zPrompt && *zPrompt ){
1191 printf("%s",zPrompt);
1192 fflush(stdout);
1193 }
1194 nLine = 100;
1195 zLine = malloc( nLine );
1196 if( zLine==0 ) return 0;
1197 n = 0;
1198 eol = 0;
1199 while( !eol ){
1200 if( n+100>nLine ){
1201 nLine = nLine*2 + 100;
1202 zLine = realloc(zLine, nLine);
1203 if( zLine==0 ) return 0;
1204 }
drhdaffd0e2001-04-11 14:28:42 +00001205 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +00001206 if( n==0 ){
1207 free(zLine);
1208 return 0;
1209 }
1210 zLine[n] = 0;
1211 eol = 1;
1212 break;
1213 }
1214 while( zLine[n] ){ n++; }
1215 if( n>0 && zLine[n-1]=='\n' ){
1216 n--;
1217 zLine[n] = 0;
1218 eol = 1;
1219 }
1220 }
1221 zLine = realloc( zLine, n+1 );
1222 return zLine;
1223}
1224
1225/*
drhc28490c2006-10-26 14:25:58 +00001226** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +00001227**
1228** zPrior is a string of prior text retrieved. If not the empty
1229** string, then issue a continuation prompt.
1230*/
drhdaffd0e2001-04-11 14:28:42 +00001231static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +00001232 char *zPrompt;
1233 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +00001234 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +00001235 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +00001236 }
1237 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +00001238 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +00001239 }else{
persicom7e2dfdd2002-04-18 02:46:52 +00001240 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +00001241 }
1242 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +00001243#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +00001244 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +00001245#endif
drh8e7e7a22000-05-30 18:45:23 +00001246 return zResult;
1247}
1248
persicom7e2dfdd2002-04-18 02:46:52 +00001249struct previous_mode_data {
1250 int valid; /* Is there legit data in here? */
1251 int mode;
1252 int showHeader;
1253 int colWidth[100];
1254};
drh45e29d82006-11-20 16:21:10 +00001255
drh8e7e7a22000-05-30 18:45:23 +00001256/*
drh75897232000-05-29 14:26:00 +00001257** An pointer to an instance of this structure is passed from
1258** the main program to the callback. This is used to communicate
1259** state and mode information.
1260*/
1261struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +00001262 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +00001263 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +00001264 int cnt; /* Number of records displayed so far */
1265 FILE *out; /* Write results here */
1266 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +00001267 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +00001268 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +00001269 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +00001270 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +00001271 int colWidth[100]; /* Requested width of each column when in column mode*/
1272 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +00001273 char nullvalue[20]; /* The text to print when a NULL comes back from
1274 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +00001275 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +00001276 /* Holds the mode information just before
1277 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +00001278 char outfile[FILENAME_MAX]; /* Filename for *out */
1279 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +00001280};
1281
1282/*
1283** These are the allowed modes.
1284*/
drh967e8b72000-06-21 13:59:10 +00001285#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +00001286#define MODE_Column 1 /* One record per line in neat columns */
1287#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +00001288#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
1289#define MODE_Html 4 /* Generate an XHTML table */
1290#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +00001291#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +00001292#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +00001293#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +00001294
drh66ce4d02008-02-15 17:38:06 +00001295static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +00001296 "line",
1297 "column",
1298 "list",
1299 "semi",
1300 "html",
drhfeac5f82004-08-01 00:10:45 +00001301 "insert",
1302 "tcl",
drh8e64d1c2004-10-07 00:32:39 +00001303 "csv",
drh66ce4d02008-02-15 17:38:06 +00001304 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +00001305};
drh75897232000-05-29 14:26:00 +00001306
1307/*
1308** Number of elements in an array
1309*/
drh902b9ee2008-12-05 17:17:07 +00001310#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +00001311
1312/*
drhea678832008-12-10 19:26:22 +00001313** Compute a string length that is limited to what can be stored in
1314** lower 30 bits of a 32-bit signed integer.
1315*/
drh4f21c4a2008-12-10 22:15:00 +00001316static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +00001317 const char *z2 = z;
1318 while( *z2 ){ z2++; }
1319 return 0x3fffffff & (int)(z2 - z);
1320}
1321
1322/*
drh28bd4bc2000-06-15 15:57:22 +00001323** Output the given string as a quoted string using SQL quoting conventions.
1324*/
1325static void output_quoted_string(FILE *out, const char *z){
1326 int i;
1327 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +00001328 for(i=0; z[i]; i++){
1329 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +00001330 }
1331 if( nSingle==0 ){
1332 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +00001333 }else{
1334 fprintf(out,"'");
1335 while( *z ){
1336 for(i=0; z[i] && z[i]!='\''; i++){}
1337 if( i==0 ){
1338 fprintf(out,"''");
1339 z++;
1340 }else if( z[i]=='\'' ){
1341 fprintf(out,"%.*s''",i,z);
1342 z += i+1;
1343 }else{
drhcd7d2732002-02-26 23:24:26 +00001344 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +00001345 break;
1346 }
1347 }
drhcd7d2732002-02-26 23:24:26 +00001348 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +00001349 }
1350}
1351
1352/*
drhfeac5f82004-08-01 00:10:45 +00001353** Output the given string as a quoted according to C or TCL quoting rules.
1354*/
1355static void output_c_string(FILE *out, const char *z){
1356 unsigned int c;
1357 fputc('"', out);
1358 while( (c = *(z++))!=0 ){
1359 if( c=='\\' ){
1360 fputc(c, out);
1361 fputc(c, out);
1362 }else if( c=='\t' ){
1363 fputc('\\', out);
1364 fputc('t', out);
1365 }else if( c=='\n' ){
1366 fputc('\\', out);
1367 fputc('n', out);
1368 }else if( c=='\r' ){
1369 fputc('\\', out);
1370 fputc('r', out);
1371 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +00001372 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +00001373 }else{
1374 fputc(c, out);
1375 }
1376 }
1377 fputc('"', out);
1378}
1379
1380/*
drhc08a4f12000-06-15 16:49:48 +00001381** Output the given string with characters that are special to
1382** HTML escaped.
1383*/
1384static void output_html_string(FILE *out, const char *z){
1385 int i;
1386 while( *z ){
shane43d9cb22009-10-21 14:11:48 +00001387 for(i=0; z[i]
1388 && z[i]!='<'
1389 && z[i]!='&'
1390 && z[i]!='>'
1391 && z[i]!='\"'
1392 && z[i]!='\'';
1393 i++){}
drhc08a4f12000-06-15 16:49:48 +00001394 if( i>0 ){
1395 fprintf(out,"%.*s",i,z);
1396 }
1397 if( z[i]=='<' ){
1398 fprintf(out,"&lt;");
1399 }else if( z[i]=='&' ){
1400 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +00001401 }else if( z[i]=='>' ){
1402 fprintf(out,"&gt;");
1403 }else if( z[i]=='\"' ){
1404 fprintf(out,"&quot;");
1405 }else if( z[i]=='\'' ){
1406 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +00001407 }else{
1408 break;
1409 }
1410 z += i + 1;
1411 }
1412}
1413
1414/*
drhc49f44e2006-10-26 18:15:42 +00001415** If a field contains any character identified by a 1 in the following
1416** array, then the string must be quoted for CSV.
1417*/
1418static const char needCsvQuote[] = {
1419 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1420 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1421 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1422 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1423 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1424 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1425 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1426 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1427 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1428 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1429 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1430 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1431 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1432 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1433 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1434 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1435};
1436
1437/*
drh8e64d1c2004-10-07 00:32:39 +00001438** Output a single term of CSV. Actually, p->separator is used for
1439** the separator, which may or may not be a comma. p->nullvalue is
1440** the null value. Strings are quoted using ANSI-C rules. Numbers
1441** appear outside of quotes.
1442*/
1443static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +00001444 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +00001445 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +00001446 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +00001447 }else{
drhc49f44e2006-10-26 18:15:42 +00001448 int i;
drh4f21c4a2008-12-10 22:15:00 +00001449 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +00001450 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +00001451 if( needCsvQuote[((unsigned char*)z)[i]]
1452 || (z[i]==p->separator[0] &&
1453 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +00001454 i = 0;
1455 break;
1456 }
1457 }
1458 if( i==0 ){
1459 putc('"', out);
1460 for(i=0; z[i]; i++){
1461 if( z[i]=='"' ) putc('"', out);
1462 putc(z[i], out);
1463 }
1464 putc('"', out);
1465 }else{
1466 fprintf(out, "%s", z);
1467 }
drh8e64d1c2004-10-07 00:32:39 +00001468 }
1469 if( bSep ){
drhd0e77882008-01-14 15:20:08 +00001470 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +00001471 }
1472}
1473
danielk19774af00c62005-01-23 23:43:21 +00001474#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +00001475/*
drh4c504392000-10-16 22:06:40 +00001476** This routine runs when the user presses Ctrl-C
1477*/
1478static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +00001479 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +00001480 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +00001481 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +00001482}
danielk19774af00c62005-01-23 23:43:21 +00001483#endif
drh4c504392000-10-16 22:06:40 +00001484
1485/*
drh75897232000-05-29 14:26:00 +00001486** This is the callback routine that the SQLite library
1487** invokes for each row of a query result.
1488*/
1489static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1490 int i;
1491 struct callback_data *p = (struct callback_data*)pArg;
1492 switch( p->mode ){
1493 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +00001494 int w = 5;
drh6a535342001-10-19 16:44:56 +00001495 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +00001496 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +00001497 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +00001498 if( len>w ) w = len;
1499 }
drh75897232000-05-29 14:26:00 +00001500 if( p->cnt++>0 ) fprintf(p->out,"\n");
1501 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001502 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +00001503 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +00001504 }
1505 break;
1506 }
danielk19770d78bae2008-01-03 07:09:48 +00001507 case MODE_Explain:
drh75897232000-05-29 14:26:00 +00001508 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +00001509 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +00001510 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +00001511 int w, n;
1512 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +00001513 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +00001514 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001515 w = 0;
drh75897232000-05-29 14:26:00 +00001516 }
drha0c66f52000-07-29 13:20:21 +00001517 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001518 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001519 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +00001520 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +00001521 if( w<n ) w = n;
1522 }
1523 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001524 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001525 }
1526 if( p->showHeader ){
1527 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
1528 }
1529 }
1530 if( p->showHeader ){
1531 for(i=0; i<nArg; i++){
1532 int w;
1533 if( i<ArraySize(p->actualWidth) ){
1534 w = p->actualWidth[i];
1535 }else{
1536 w = 10;
1537 }
1538 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
1539 "----------------------------------------------------------",
1540 i==nArg-1 ? "\n": " ");
1541 }
drh75897232000-05-29 14:26:00 +00001542 }
1543 }
drh6a535342001-10-19 16:44:56 +00001544 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001545 for(i=0; i<nArg; i++){
1546 int w;
drha0c66f52000-07-29 13:20:21 +00001547 if( i<ArraySize(p->actualWidth) ){
1548 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001549 }else{
1550 w = 10;
1551 }
drhea678832008-12-10 19:26:22 +00001552 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +00001553 strlen30(azArg[i])>w ){
1554 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001555 }
drhc61053b2000-06-04 12:58:36 +00001556 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +00001557 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +00001558 }
1559 break;
1560 }
drhe3710332000-09-29 13:30:53 +00001561 case MODE_Semi:
drh75897232000-05-29 14:26:00 +00001562 case MODE_List: {
1563 if( p->cnt++==0 && p->showHeader ){
1564 for(i=0; i<nArg; i++){
1565 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
1566 }
1567 }
drh6a535342001-10-19 16:44:56 +00001568 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001569 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001570 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +00001571 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +00001572 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001573 if( i<nArg-1 ){
1574 fprintf(p->out, "%s", p->separator);
1575 }else if( p->mode==MODE_Semi ){
1576 fprintf(p->out, ";\n");
1577 }else{
1578 fprintf(p->out, "\n");
1579 }
drh75897232000-05-29 14:26:00 +00001580 }
1581 break;
1582 }
drh1e5d0e92000-05-31 23:33:17 +00001583 case MODE_Html: {
1584 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +00001585 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001586 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +00001587 fprintf(p->out,"<TH>");
1588 output_html_string(p->out, azCol[i]);
1589 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001590 }
mihailim57c591a2008-06-23 21:26:05 +00001591 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001592 }
drh6a535342001-10-19 16:44:56 +00001593 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +00001594 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001595 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +00001596 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +00001597 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +00001598 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001599 }
mihailim57c591a2008-06-23 21:26:05 +00001600 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001601 break;
1602 }
drhfeac5f82004-08-01 00:10:45 +00001603 case MODE_Tcl: {
1604 if( p->cnt++==0 && p->showHeader ){
1605 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001606 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +00001607 fprintf(p->out, "%s", p->separator);
1608 }
1609 fprintf(p->out,"\n");
1610 }
1611 if( azArg==0 ) break;
1612 for(i=0; i<nArg; i++){
1613 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
1614 fprintf(p->out, "%s", p->separator);
1615 }
1616 fprintf(p->out,"\n");
1617 break;
1618 }
drh8e64d1c2004-10-07 00:32:39 +00001619 case MODE_Csv: {
1620 if( p->cnt++==0 && p->showHeader ){
1621 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001622 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001623 }
1624 fprintf(p->out,"\n");
1625 }
1626 if( azArg==0 ) break;
1627 for(i=0; i<nArg; i++){
1628 output_csv(p, azArg[i], i<nArg-1);
1629 }
1630 fprintf(p->out,"\n");
1631 break;
1632 }
drh28bd4bc2000-06-15 15:57:22 +00001633 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +00001634 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +00001635 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +00001636 for(i=0; i<nArg; i++){
1637 char *zSep = i>0 ? ",": "";
1638 if( azArg[i]==0 ){
1639 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +00001640 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001641 fprintf(p->out,"%s%s",zSep, azArg[i]);
1642 }else{
1643 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1644 output_quoted_string(p->out, azArg[i]);
1645 }
1646 }
1647 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001648 break;
drh28bd4bc2000-06-15 15:57:22 +00001649 }
persicom1d0b8722002-04-18 02:53:04 +00001650 }
drh75897232000-05-29 14:26:00 +00001651 return 0;
1652}
1653
1654/*
drh33048c02001-10-01 14:29:22 +00001655** Set the destination table field of the callback_data structure to
1656** the name of the table given. Escape any quote characters in the
1657** table name.
1658*/
1659static void set_table_name(struct callback_data *p, const char *zName){
1660 int i, n;
1661 int needQuote;
1662 char *z;
1663
1664 if( p->zDestTable ){
1665 free(p->zDestTable);
1666 p->zDestTable = 0;
1667 }
1668 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001669 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001670 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001671 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001672 needQuote = 1;
1673 if( zName[i]=='\'' ) n++;
1674 }
1675 }
1676 if( needQuote ) n += 2;
1677 z = p->zDestTable = malloc( n+1 );
1678 if( z==0 ){
1679 fprintf(stderr,"Out of memory!\n");
1680 exit(1);
1681 }
1682 n = 0;
1683 if( needQuote ) z[n++] = '\'';
1684 for(i=0; zName[i]; i++){
1685 z[n++] = zName[i];
1686 if( zName[i]=='\'' ) z[n++] = '\'';
1687 }
1688 if( needQuote ) z[n++] = '\'';
1689 z[n] = 0;
1690}
1691
danielk19772a02e332004-06-05 08:04:36 +00001692/* zIn is either a pointer to a NULL-terminated string in memory obtained
1693** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1694** added to zIn, and the result returned in memory obtained from malloc().
1695** zIn, if it was not NULL, is freed.
1696**
1697** If the third argument, quote, is not '\0', then it is used as a
1698** quote character for zAppend.
1699*/
drhc28490c2006-10-26 14:25:58 +00001700static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001701 int len;
1702 int i;
drh4f21c4a2008-12-10 22:15:00 +00001703 int nAppend = strlen30(zAppend);
1704 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001705
1706 len = nAppend+nIn+1;
1707 if( quote ){
1708 len += 2;
1709 for(i=0; i<nAppend; i++){
1710 if( zAppend[i]==quote ) len++;
1711 }
1712 }
1713
1714 zIn = (char *)realloc(zIn, len);
1715 if( !zIn ){
1716 return 0;
1717 }
1718
1719 if( quote ){
1720 char *zCsr = &zIn[nIn];
1721 *zCsr++ = quote;
1722 for(i=0; i<nAppend; i++){
1723 *zCsr++ = zAppend[i];
1724 if( zAppend[i]==quote ) *zCsr++ = quote;
1725 }
1726 *zCsr++ = quote;
1727 *zCsr++ = '\0';
1728 assert( (zCsr-zIn)==len );
1729 }else{
1730 memcpy(&zIn[nIn], zAppend, nAppend);
1731 zIn[len-1] = '\0';
1732 }
1733
1734 return zIn;
1735}
1736
drhdd3d4592004-08-30 01:54:05 +00001737
1738/*
1739** Execute a query statement that has a single result column. Print
1740** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +00001741**
1742** This is used, for example, to show the schema of the database by
1743** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +00001744*/
drh157e29a2009-05-21 15:15:00 +00001745static int run_table_dump_query(
1746 FILE *out, /* Send output here */
1747 sqlite3 *db, /* Database to query */
1748 const char *zSelect, /* SELECT statement to extract content */
1749 const char *zFirstRow /* Print before first row, if not NULL */
1750){
drhdd3d4592004-08-30 01:54:05 +00001751 sqlite3_stmt *pSelect;
1752 int rc;
1753 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
1754 if( rc!=SQLITE_OK || !pSelect ){
1755 return rc;
1756 }
1757 rc = sqlite3_step(pSelect);
1758 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001759 if( zFirstRow ){
1760 fprintf(out, "%s", zFirstRow);
1761 zFirstRow = 0;
1762 }
drhdd3d4592004-08-30 01:54:05 +00001763 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
1764 rc = sqlite3_step(pSelect);
1765 }
1766 return sqlite3_finalize(pSelect);
1767}
1768
1769
drh33048c02001-10-01 14:29:22 +00001770/*
drh4c653a02000-06-07 01:27:47 +00001771** This is a different callback routine used for dumping the database.
1772** Each row received by this callback consists of a table name,
1773** the table type ("index" or "table") and SQL to create the table.
1774** This routine should print text sufficient to recreate the table.
1775*/
1776static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001777 int rc;
1778 const char *zTable;
1779 const char *zType;
1780 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001781 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001782 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001783
drh902b9ee2008-12-05 17:17:07 +00001784 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001785 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001786 zTable = azArg[0];
1787 zType = azArg[1];
1788 zSql = azArg[2];
1789
drh00b950d2005-09-11 02:03:03 +00001790 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001791 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001792 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1793 fprintf(p->out, "ANALYZE sqlite_master;\n");
1794 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1795 return 0;
drh45e29d82006-11-20 16:21:10 +00001796 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1797 char *zIns;
1798 if( !p->writableSchema ){
1799 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1800 p->writableSchema = 1;
1801 }
1802 zIns = sqlite3_mprintf(
1803 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1804 "VALUES('table','%q','%q',0,'%q');",
1805 zTable, zTable, zSql);
1806 fprintf(p->out, "%s\n", zIns);
1807 sqlite3_free(zIns);
1808 return 0;
drh00b950d2005-09-11 02:03:03 +00001809 }else{
1810 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001811 }
danielk19772a02e332004-06-05 08:04:36 +00001812
1813 if( strcmp(zType, "table")==0 ){
1814 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001815 char *zSelect = 0;
1816 char *zTableInfo = 0;
1817 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001818 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001819
1820 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1821 zTableInfo = appendText(zTableInfo, zTable, '"');
1822 zTableInfo = appendText(zTableInfo, ");", 0);
1823
1824 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001825 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001826 if( rc!=SQLITE_OK || !pTableInfo ){
1827 return 1;
1828 }
1829
1830 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1831 zTmp = appendText(zTmp, zTable, '"');
1832 if( zTmp ){
1833 zSelect = appendText(zSelect, zTmp, '\'');
1834 }
1835 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1836 rc = sqlite3_step(pTableInfo);
1837 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001838 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001839 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001840 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001841 rc = sqlite3_step(pTableInfo);
1842 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001843 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001844 }else{
1845 zSelect = appendText(zSelect, ") ", 0);
1846 }
drh157e29a2009-05-21 15:15:00 +00001847 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001848 }
1849 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001850 if( rc!=SQLITE_OK || nRow==0 ){
1851 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001852 return 1;
1853 }
1854 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1855 zSelect = appendText(zSelect, zTable, '"');
1856
drh157e29a2009-05-21 15:15:00 +00001857 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001858 if( rc==SQLITE_CORRUPT ){
1859 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001860 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001861 }
danielk19772a02e332004-06-05 08:04:36 +00001862 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001863 }
drh4c653a02000-06-07 01:27:47 +00001864 return 0;
1865}
1866
1867/*
drh45e29d82006-11-20 16:21:10 +00001868** Run zQuery. Use dump_callback() as the callback routine so that
1869** the contents of the query are output as SQL statements.
1870**
drhdd3d4592004-08-30 01:54:05 +00001871** If we get a SQLITE_CORRUPT error, rerun the query after appending
1872** "ORDER BY rowid DESC" to the end.
1873*/
1874static int run_schema_dump_query(
1875 struct callback_data *p,
1876 const char *zQuery,
1877 char **pzErrMsg
1878){
1879 int rc;
1880 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1881 if( rc==SQLITE_CORRUPT ){
1882 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001883 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001884 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1885 zQ2 = malloc( len+100 );
1886 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001887 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001888 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1889 free(zQ2);
1890 }
1891 return rc;
1892}
1893
danielk1977c8c70692009-02-25 15:22:02 +00001894#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
1895struct GenfkeyCmd {
1896 sqlite3 *db; /* Database handle */
1897 struct callback_data *pCb; /* Callback data */
1898 int isIgnoreErrors; /* True for --ignore-errors */
1899 int isExec; /* True for --exec */
1900 int isNoDrop; /* True for --no-drop */
1901 int nErr; /* Number of errors seen so far */
1902};
1903typedef struct GenfkeyCmd GenfkeyCmd;
1904
1905static int genfkeyParseArgs(GenfkeyCmd *p, char **azArg, int nArg){
1906 int ii;
1907 memset(p, 0, sizeof(GenfkeyCmd));
1908
1909 for(ii=0; ii<nArg; ii++){
drh93a989c2009-03-16 10:59:44 +00001910 int n = strlen30(azArg[ii]);
danielk1977c8c70692009-02-25 15:22:02 +00001911
1912 if( n>2 && n<10 && 0==strncmp(azArg[ii], "--no-drop", n) ){
1913 p->isNoDrop = 1;
1914 }else if( n>2 && n<16 && 0==strncmp(azArg[ii], "--ignore-errors", n) ){
1915 p->isIgnoreErrors = 1;
1916 }else if( n>2 && n<7 && 0==strncmp(azArg[ii], "--exec", n) ){
1917 p->isExec = 1;
1918 }else{
1919 fprintf(stderr, "unknown option: %s\n", azArg[ii]);
1920 return -1;
1921 }
1922 }
1923
1924 return SQLITE_OK;
1925}
1926
1927static int genfkeyCmdCb(void *pCtx, int eType, const char *z){
1928 GenfkeyCmd *p = (GenfkeyCmd *)pCtx;
1929 if( eType==GENFKEY_ERROR && !p->isIgnoreErrors ){
1930 p->nErr++;
1931 fprintf(stderr, "%s\n", z);
1932 }
1933
1934 if( p->nErr==0 && (
1935 (eType==GENFKEY_CREATETRIGGER)
1936 || (eType==GENFKEY_DROPTRIGGER && !p->isNoDrop)
1937 )){
1938 if( p->isExec ){
1939 sqlite3_exec(p->db, z, 0, 0, 0);
1940 }else{
1941 char *zCol = "sql";
1942 callback((void *)p->pCb, 1, (char **)&z, (char **)&zCol);
1943 }
1944 }
1945
1946 return SQLITE_OK;
1947}
1948#endif
1949
drhdd3d4592004-08-30 01:54:05 +00001950/*
drh75897232000-05-29 14:26:00 +00001951** Text of a help message
1952*/
persicom1d0b8722002-04-18 02:53:04 +00001953static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001954 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001955 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001956 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001957 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +00001958 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001959 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001960 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
danielk1977c8c70692009-02-25 15:22:02 +00001961#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
1962 ".genfkey ?OPTIONS? Options are:\n"
1963 " --no-drop: Do not drop old fkey triggers.\n"
1964 " --ignore-errors: Ignore tables with fkey errors\n"
1965 " --exec: Execute generated SQL immediately\n"
danielk1977e6320042009-02-25 15:43:57 +00001966 " See file tool/genfkey.README in the source \n"
1967 " distribution for further information.\n"
danielk1977c8c70692009-02-25 15:22:02 +00001968#endif
persicom7e2dfdd2002-04-18 02:46:52 +00001969 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001970 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001971 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +00001972 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +00001973#ifdef SQLITE_ENABLE_IOTRACE
1974 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1975#endif
drh70df4fe2006-06-13 15:12:21 +00001976#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001977 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001978#endif
danielk19776b77a362005-01-13 11:10:25 +00001979 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001980 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001981 " column Left-aligned columns. (See .width)\n"
1982 " html HTML <table> code\n"
1983 " insert SQL insert statements for TABLE\n"
1984 " line One value per line\n"
1985 " list Values delimited by .separator string\n"
1986 " tabs Tab-separated values\n"
1987 " tcl TCL list elements\n"
1988 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001989 ".output FILENAME Send output to FILENAME\n"
1990 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001991 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001992 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001993 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001994 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001995 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +00001996 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001997 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +00001998 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +00001999 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh75897232000-05-29 14:26:00 +00002000 ".width NUM NUM ... Set column widths for \"column\" mode\n"
2001;
2002
shaneb320ccd2009-10-21 03:42:58 +00002003static char zTimerHelp[] =
2004 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
2005;
2006
drhdaffd0e2001-04-11 14:28:42 +00002007/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00002008static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00002009
drh75897232000-05-29 14:26:00 +00002010/*
drh44c2eb12003-04-30 11:38:26 +00002011** Make sure the database is open. If it is not, then open it. If
2012** the database fails to open, print an error message and exit.
2013*/
2014static void open_db(struct callback_data *p){
2015 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00002016 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00002017 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00002018 if( db && sqlite3_errcode(db)==SQLITE_OK ){
2019 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
2020 shellstaticFunc, 0, 0);
2021 }
2022 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +00002023 fprintf(stderr,"Unable to open database \"%s\": %s\n",
2024 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00002025 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002026 }
drhc2e87a32006-06-27 15:16:14 +00002027#ifndef SQLITE_OMIT_LOAD_EXTENSION
2028 sqlite3_enable_load_extension(p->db, 1);
2029#endif
drh44c2eb12003-04-30 11:38:26 +00002030 }
2031}
2032
2033/*
drhfeac5f82004-08-01 00:10:45 +00002034** Do C-language style dequoting.
2035**
2036** \t -> tab
2037** \n -> newline
2038** \r -> carriage return
2039** \NNN -> ascii character NNN in octal
2040** \\ -> backslash
2041*/
2042static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002043 int i, j;
2044 char c;
drhfeac5f82004-08-01 00:10:45 +00002045 for(i=j=0; (c = z[i])!=0; i++, j++){
2046 if( c=='\\' ){
2047 c = z[++i];
2048 if( c=='n' ){
2049 c = '\n';
2050 }else if( c=='t' ){
2051 c = '\t';
2052 }else if( c=='r' ){
2053 c = '\r';
2054 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002055 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002056 if( z[i+1]>='0' && z[i+1]<='7' ){
2057 i++;
2058 c = (c<<3) + z[i] - '0';
2059 if( z[i+1]>='0' && z[i+1]<='7' ){
2060 i++;
2061 c = (c<<3) + z[i] - '0';
2062 }
2063 }
2064 }
2065 }
2066 z[j] = c;
2067 }
2068 z[j] = 0;
2069}
2070
2071/*
drhc28490c2006-10-26 14:25:58 +00002072** Interpret zArg as a boolean value. Return either 0 or 1.
2073*/
2074static int booleanValue(char *zArg){
2075 int val = atoi(zArg);
2076 int j;
2077 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00002078 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00002079 }
2080 if( strcmp(zArg,"on")==0 ){
2081 val = 1;
2082 }else if( strcmp(zArg,"yes")==0 ){
2083 val = 1;
2084 }
2085 return val;
2086}
2087
2088/*
drh75897232000-05-29 14:26:00 +00002089** If an input line begins with "." then invoke this routine to
2090** process that line.
drh67505e72002-04-19 12:34:06 +00002091**
drh47ad6842006-11-08 12:25:42 +00002092** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002093*/
drh44c2eb12003-04-30 11:38:26 +00002094static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00002095 int i = 1;
2096 int nArg = 0;
2097 int n, c;
drh67505e72002-04-19 12:34:06 +00002098 int rc = 0;
drh75897232000-05-29 14:26:00 +00002099 char *azArg[50];
2100
2101 /* Parse the input line into tokens.
2102 */
2103 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00002104 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002105 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002106 if( zLine[i]=='\'' || zLine[i]=='"' ){
2107 int delim = zLine[i++];
2108 azArg[nArg++] = &zLine[i];
2109 while( zLine[i] && zLine[i]!=delim ){ i++; }
2110 if( zLine[i]==delim ){
2111 zLine[i++] = 0;
2112 }
drhfeac5f82004-08-01 00:10:45 +00002113 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002114 }else{
2115 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00002116 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002117 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002118 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002119 }
2120 }
2121
2122 /* Process the input line.
2123 */
drh67505e72002-04-19 12:34:06 +00002124 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00002125 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002126 c = azArg[0][0];
drh9ff849f2009-02-04 20:55:57 +00002127 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){
2128 const char *zDestFile;
2129 const char *zDb;
2130 sqlite3 *pDest;
2131 sqlite3_backup *pBackup;
2132 int rc;
2133 if( nArg==2 ){
2134 zDestFile = azArg[1];
2135 zDb = "main";
2136 }else{
2137 zDestFile = azArg[2];
2138 zDb = azArg[1];
2139 }
2140 rc = sqlite3_open(zDestFile, &pDest);
2141 if( rc!=SQLITE_OK ){
2142 fprintf(stderr, "Error: cannot open %s\n", zDestFile);
2143 sqlite3_close(pDest);
2144 return 1;
2145 }
drhdc2c4912009-02-04 22:46:47 +00002146 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002147 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2148 if( pBackup==0 ){
2149 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2150 sqlite3_close(pDest);
2151 return 1;
2152 }
2153 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2154 sqlite3_backup_finish(pBackup);
2155 if( rc==SQLITE_DONE ){
2156 rc = SQLITE_OK;
2157 }else{
2158 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2159 }
2160 sqlite3_close(pDest);
2161 }else
2162
2163 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
drhc49f44e2006-10-26 18:15:42 +00002164 bail_on_error = booleanValue(azArg[1]);
2165 }else
2166
jplyon6a65bb32003-05-04 07:25:57 +00002167 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00002168 struct callback_data data;
2169 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00002170 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00002171 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002172 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002173 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002174 data.colWidth[0] = 3;
2175 data.colWidth[1] = 15;
2176 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002177 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002178 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002179 if( zErrMsg ){
2180 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002181 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00002182 }
2183 }else
2184
drh4c653a02000-06-07 01:27:47 +00002185 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
2186 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002187 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00002188 /* When playing back a "dump", the content might appear in an order
2189 ** which causes immediate foreign key constraints to be violated.
2190 ** So disable foreign-key constraint enforcement to prevent problems. */
2191 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002192 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002193 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00002194 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002195 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002196 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002197 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00002198 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
2199 );
2200 run_schema_dump_query(p,
2201 "SELECT name, type, sql FROM sqlite_master "
2202 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00002203 );
2204 run_table_dump_query(p->out, p->db,
2205 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002206 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002207 );
drh4c653a02000-06-07 01:27:47 +00002208 }else{
2209 int i;
drhdd3d4592004-08-30 01:54:05 +00002210 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002211 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002212 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002213 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002214 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00002215 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00002216 run_table_dump_query(p->out, p->db,
2217 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002218 "WHERE sql NOT NULL"
2219 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002220 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002221 );
danielk1977bc6ada42004-06-30 08:20:16 +00002222 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002223 }
2224 }
drh45e29d82006-11-20 16:21:10 +00002225 if( p->writableSchema ){
2226 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
2227 p->writableSchema = 0;
2228 }
drh93f41e52008-08-11 19:12:34 +00002229 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002230 if( zErrMsg ){
2231 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002232 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00002233 }else{
2234 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002235 }
2236 }else
drh75897232000-05-29 14:26:00 +00002237
drhdaffd0e2001-04-11 14:28:42 +00002238 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002239 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00002240 }else
2241
drh75897232000-05-29 14:26:00 +00002242 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002243 rc = 2;
drh75897232000-05-29 14:26:00 +00002244 }else
2245
drhdd45df82002-04-18 12:39:03 +00002246 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002247 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002248 if(val == 1) {
2249 if(!p->explainPrev.valid) {
2250 p->explainPrev.valid = 1;
2251 p->explainPrev.mode = p->mode;
2252 p->explainPrev.showHeader = p->showHeader;
2253 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
2254 }
2255 /* We could put this code under the !p->explainValid
2256 ** condition so that it does not execute if we are already in
2257 ** explain mode. However, always executing it allows us an easy
2258 ** was to reset to explain mode in case the user previously
2259 ** did an .explain followed by a .width, .mode or .header
2260 ** command.
2261 */
danielk19770d78bae2008-01-03 07:09:48 +00002262 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002263 p->showHeader = 1;
2264 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002265 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002266 p->colWidth[1] = 13; /* opcode */
2267 p->colWidth[2] = 4; /* P1 */
2268 p->colWidth[3] = 4; /* P2 */
2269 p->colWidth[4] = 4; /* P3 */
2270 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002271 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002272 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00002273 }else if (p->explainPrev.valid) {
2274 p->explainPrev.valid = 0;
2275 p->mode = p->explainPrev.mode;
2276 p->showHeader = p->explainPrev.showHeader;
2277 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2278 }
drh75897232000-05-29 14:26:00 +00002279 }else
2280
danielk1977c8c70692009-02-25 15:22:02 +00002281#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
2282 if( c=='g' && strncmp(azArg[0], "genfkey", n)==0 ){
2283 GenfkeyCmd cmd;
2284 if( 0==genfkeyParseArgs(&cmd, &azArg[1], nArg-1) ){
2285 cmd.db = p->db;
2286 cmd.pCb = p;
2287 genfkey_create_triggers(p->db, "main", (void *)&cmd, genfkeyCmdCb);
2288 }
2289 }else
2290#endif
2291
drhc28490c2006-10-26 14:25:58 +00002292 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00002293 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002294 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00002295 }else
2296
2297 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00002298 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00002299 if( HAS_TIMER ){
2300 fprintf(stderr,"%s",zTimerHelp);
2301 }
drh75897232000-05-29 14:26:00 +00002302 }else
2303
drhfeac5f82004-08-01 00:10:45 +00002304 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
2305 char *zTable = azArg[2]; /* Insert data into this table */
2306 char *zFile = azArg[1]; /* The file from which to extract data */
2307 sqlite3_stmt *pStmt; /* A statement */
2308 int rc; /* Result code */
2309 int nCol; /* Number of columns in the table */
2310 int nByte; /* Number of bytes in an SQL string */
2311 int i, j; /* Loop counters */
2312 int nSep; /* Number of bytes in p->separator[] */
2313 char *zSql; /* An SQL statement */
2314 char *zLine; /* A single line of input from the file */
2315 char **azCol; /* zLine[] broken up into columns */
2316 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00002317 FILE *in; /* The input file */
2318 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00002319
drha543c822006-06-08 16:10:14 +00002320 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002321 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002322 if( nSep==0 ){
2323 fprintf(stderr, "non-null separator required for import\n");
2324 return 0;
2325 }
2326 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
2327 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00002328 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002329 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002330 sqlite3_free(zSql);
2331 if( rc ){
2332 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2333 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00002334 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002335 }else{
2336 nCol = sqlite3_column_count(pStmt);
2337 }
2338 sqlite3_finalize(pStmt);
2339 if( nCol==0 ) return 0;
2340 zSql = malloc( nByte + 20 + nCol*2 );
2341 if( zSql==0 ) return 0;
2342 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002343 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002344 for(i=1; i<nCol; i++){
2345 zSql[j++] = ',';
2346 zSql[j++] = '?';
2347 }
2348 zSql[j++] = ')';
2349 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002350 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002351 free(zSql);
2352 if( rc ){
2353 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
2354 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00002355 return 1;
drhfeac5f82004-08-01 00:10:45 +00002356 }
2357 in = fopen(zFile, "rb");
2358 if( in==0 ){
2359 fprintf(stderr, "cannot open file: %s\n", zFile);
2360 sqlite3_finalize(pStmt);
2361 return 0;
2362 }
2363 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00002364 if( azCol==0 ){
2365 fclose(in);
2366 return 0;
2367 }
drhfeac5f82004-08-01 00:10:45 +00002368 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
2369 zCommit = "COMMIT";
2370 while( (zLine = local_getline(0, in))!=0 ){
2371 char *z;
2372 i = 0;
drhb860bc92004-08-04 15:16:55 +00002373 lineno++;
drhfeac5f82004-08-01 00:10:45 +00002374 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00002375 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00002376 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
2377 *z = 0;
2378 i++;
drhb860bc92004-08-04 15:16:55 +00002379 if( i<nCol ){
2380 azCol[i] = &z[nSep];
2381 z += nSep-1;
2382 }
drhfeac5f82004-08-01 00:10:45 +00002383 }
2384 }
drh1cd7f832005-08-05 18:50:51 +00002385 *z = 0;
drhb860bc92004-08-04 15:16:55 +00002386 if( i+1!=nCol ){
2387 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
2388 zFile, lineno, nCol, i+1);
2389 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00002390 free(zLine);
drhb860bc92004-08-04 15:16:55 +00002391 break;
2392 }
drhfeac5f82004-08-01 00:10:45 +00002393 for(i=0; i<nCol; i++){
2394 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2395 }
2396 sqlite3_step(pStmt);
2397 rc = sqlite3_reset(pStmt);
2398 free(zLine);
2399 if( rc!=SQLITE_OK ){
2400 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2401 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00002402 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002403 break;
2404 }
2405 }
2406 free(azCol);
2407 fclose(in);
2408 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00002409 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002410 }else
2411
drh75897232000-05-29 14:26:00 +00002412 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
2413 struct callback_data data;
2414 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002415 open_db(p);
drh75897232000-05-29 14:26:00 +00002416 memcpy(&data, p, sizeof(data));
2417 data.showHeader = 0;
2418 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00002419 zShellStatic = azArg[1];
2420 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00002421 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002422 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002423 "UNION ALL "
2424 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002425 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002426 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002427 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002428 );
danielk1977bc6ada42004-06-30 08:20:16 +00002429 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00002430 if( zErrMsg ){
2431 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002432 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002433 }
2434 }else
2435
drhae5e4452007-05-03 17:18:36 +00002436#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002437 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002438 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002439 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2440 iotrace = 0;
2441 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002442 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002443 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002444 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002445 iotrace = stdout;
2446 }else{
2447 iotrace = fopen(azArg[1], "w");
2448 if( iotrace==0 ){
2449 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002450 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002451 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002452 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002453 }
2454 }
2455 }else
drhae5e4452007-05-03 17:18:36 +00002456#endif
drhb0603412007-02-28 04:47:26 +00002457
drh70df4fe2006-06-13 15:12:21 +00002458#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002459 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2460 const char *zFile, *zProc;
2461 char *zErrMsg = 0;
2462 int rc;
2463 zFile = azArg[1];
2464 zProc = nArg>=3 ? azArg[2] : 0;
2465 open_db(p);
2466 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2467 if( rc!=SQLITE_OK ){
2468 fprintf(stderr, "%s\n", zErrMsg);
2469 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002470 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002471 }
2472 }else
drh70df4fe2006-06-13 15:12:21 +00002473#endif
drh1e397f82006-06-08 15:28:43 +00002474
drh28bd4bc2000-06-15 15:57:22 +00002475 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00002476 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002477 if( strncmp(azArg[1],"line",n2)==0
2478 ||
2479 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002480 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00002481 }else if( strncmp(azArg[1],"column",n2)==0
2482 ||
2483 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002484 p->mode = MODE_Column;
2485 }else if( strncmp(azArg[1],"list",n2)==0 ){
2486 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00002487 }else if( strncmp(azArg[1],"html",n2)==0 ){
2488 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00002489 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
2490 p->mode = MODE_Tcl;
2491 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002492 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002493 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00002494 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
2495 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002496 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00002497 }else if( strncmp(azArg[1],"insert",n2)==0 ){
2498 p->mode = MODE_Insert;
2499 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00002500 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00002501 }else{
drh33048c02001-10-01 14:29:22 +00002502 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00002503 }
drhdaffd0e2001-04-11 14:28:42 +00002504 }else {
drhcf68ae92006-12-19 18:47:41 +00002505 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002506 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00002507 }
2508 }else
2509
persicom7e2dfdd2002-04-18 02:46:52 +00002510 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002511 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2512 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002513 }else
2514
drh75897232000-05-29 14:26:00 +00002515 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
2516 if( p->out!=stdout ){
2517 fclose(p->out);
2518 }
2519 if( strcmp(azArg[1],"stdout")==0 ){
2520 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00002521 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00002522 }else{
drha1f9b5e2004-02-14 16:31:02 +00002523 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00002524 if( p->out==0 ){
2525 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
2526 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00002527 } else {
drh5bb3eb92007-05-04 13:15:55 +00002528 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002529 }
2530 }
2531 }else
2532
drhdd45df82002-04-18 12:39:03 +00002533 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002534 if( nArg >= 2) {
2535 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2536 }
2537 if( nArg >= 3) {
2538 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2539 }
2540 }else
2541
2542 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002543 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002544 }else
2545
drh9ff849f2009-02-04 20:55:57 +00002546 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002547 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002548 if( alt==0 ){
2549 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
2550 }else{
2551 process_input(p, alt);
2552 fclose(alt);
2553 }
2554 }else
2555
drh9ff849f2009-02-04 20:55:57 +00002556 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){
2557 const char *zSrcFile;
2558 const char *zDb;
2559 sqlite3 *pSrc;
2560 sqlite3_backup *pBackup;
2561 int rc;
drhdc2c4912009-02-04 22:46:47 +00002562 int nTimeout = 0;
2563
drh9ff849f2009-02-04 20:55:57 +00002564 if( nArg==2 ){
2565 zSrcFile = azArg[1];
2566 zDb = "main";
2567 }else{
2568 zSrcFile = azArg[2];
2569 zDb = azArg[1];
2570 }
2571 rc = sqlite3_open(zSrcFile, &pSrc);
2572 if( rc!=SQLITE_OK ){
2573 fprintf(stderr, "Error: cannot open %s\n", zSrcFile);
2574 sqlite3_close(pSrc);
2575 return 1;
2576 }
drhdc2c4912009-02-04 22:46:47 +00002577 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002578 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2579 if( pBackup==0 ){
2580 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2581 sqlite3_close(pSrc);
2582 return 1;
2583 }
drhdc2c4912009-02-04 22:46:47 +00002584 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2585 || rc==SQLITE_BUSY ){
2586 if( rc==SQLITE_BUSY ){
2587 if( nTimeout++ >= 3 ) break;
2588 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002589 }
2590 }
2591 sqlite3_backup_finish(pBackup);
2592 if( rc==SQLITE_DONE ){
2593 rc = SQLITE_OK;
drhdc2c4912009-02-04 22:46:47 +00002594 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2595 fprintf(stderr, "source database is busy\n");
drh9ff849f2009-02-04 20:55:57 +00002596 }else{
2597 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2598 }
2599 sqlite3_close(pSrc);
2600 }else
2601
drh75897232000-05-29 14:26:00 +00002602 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
2603 struct callback_data data;
2604 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002605 open_db(p);
drh75897232000-05-29 14:26:00 +00002606 memcpy(&data, p, sizeof(data));
2607 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002608 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002609 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002610 int i;
shane7d3846a2008-12-11 02:58:26 +00002611 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002612 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002613 char *new_argv[2], *new_colv[2];
2614 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2615 " type text,\n"
2616 " name text,\n"
2617 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002618 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002619 " sql text\n"
2620 ")";
2621 new_argv[1] = 0;
2622 new_colv[0] = "sql";
2623 new_colv[1] = 0;
2624 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00002625 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002626 char *new_argv[2], *new_colv[2];
2627 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2628 " type text,\n"
2629 " name text,\n"
2630 " tbl_name text,\n"
2631 " rootpage integer,\n"
2632 " sql text\n"
2633 ")";
2634 new_argv[1] = 0;
2635 new_colv[0] = "sql";
2636 new_colv[1] = 0;
2637 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00002638 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002639 zShellStatic = azArg[1];
2640 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002641 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002642 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2643 " FROM sqlite_master UNION ALL"
2644 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002645 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002646 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002647 callback, &data, &zErrMsg);
2648 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002649 }
drh75897232000-05-29 14:26:00 +00002650 }else{
danielk19776f8a5032004-05-10 10:34:51 +00002651 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002652 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002653 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2654 " FROM sqlite_master UNION ALL"
2655 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002656 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002657 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002658 callback, &data, &zErrMsg
2659 );
drh75897232000-05-29 14:26:00 +00002660 }
drh75897232000-05-29 14:26:00 +00002661 if( zErrMsg ){
2662 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002663 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002664 }
2665 }else
2666
2667 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002668 sqlite3_snprintf(sizeof(p->separator), p->separator,
2669 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002670 }else
2671
persicom7e2dfdd2002-04-18 02:46:52 +00002672 if( c=='s' && strncmp(azArg[0], "show", n)==0){
2673 int i;
2674 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002675 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002676 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002677 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002678 fprintf(p->out,"%9.9s: ", "nullvalue");
2679 output_c_string(p->out, p->nullvalue);
2680 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002681 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002682 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002683 fprintf(p->out,"%9.9s: ", "separator");
2684 output_c_string(p->out, p->separator);
2685 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002686 fprintf(p->out,"%9.9s: ","width");
2687 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002688 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002689 }
drhfeac5f82004-08-01 00:10:45 +00002690 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002691 }else
2692
drh2dfbbca2000-07-28 14:32:48 +00002693 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00002694 char **azResult;
2695 int nRow, rc;
2696 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002697 open_db(p);
drha50da102000-08-08 20:19:09 +00002698 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002699 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002700 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00002701 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002702 "UNION ALL "
2703 "SELECT name FROM sqlite_temp_master "
2704 "WHERE type IN ('table','view') "
2705 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002706 &azResult, &nRow, 0, &zErrMsg
2707 );
drha50da102000-08-08 20:19:09 +00002708 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002709 zShellStatic = azArg[1];
2710 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002711 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002712 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002713 "UNION ALL "
2714 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002715 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002716 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002717 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002718 );
danielk1977bc6ada42004-06-30 08:20:16 +00002719 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002720 }
drh75897232000-05-29 14:26:00 +00002721 if( zErrMsg ){
2722 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002723 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002724 }
drhe3710332000-09-29 13:30:53 +00002725 if( rc==SQLITE_OK ){
2726 int len, maxlen = 0;
2727 int i, j;
2728 int nPrintCol, nPrintRow;
2729 for(i=1; i<=nRow; i++){
2730 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002731 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002732 if( len>maxlen ) maxlen = len;
2733 }
2734 nPrintCol = 80/(maxlen+2);
2735 if( nPrintCol<1 ) nPrintCol = 1;
2736 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2737 for(i=0; i<nPrintRow; i++){
2738 for(j=i+1; j<=nRow; j+=nPrintRow){
2739 char *zSp = j<=nPrintRow ? "" : " ";
2740 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2741 }
2742 printf("\n");
2743 }
drh47ad6842006-11-08 12:25:42 +00002744 }else{
2745 rc = 1;
drhe3710332000-09-29 13:30:53 +00002746 }
danielk19776f8a5032004-05-10 10:34:51 +00002747 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002748 }else
2749
drh3b1a9882007-11-02 12:53:03 +00002750 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00002751 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002752 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shaneb320ccd2009-10-21 03:42:58 +00002753 }else if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
drh3b1a9882007-11-02 12:53:03 +00002754 enableTimer = booleanValue(azArg[1]);
shaneb320ccd2009-10-21 03:42:58 +00002755 }else if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00002756 int j;
drh43617e92006-03-06 20:55:46 +00002757 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002758 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2759 p->colWidth[j-1] = atoi(azArg[j]);
2760 }
2761 }else
2762
drh3b1a9882007-11-02 12:53:03 +00002763
drh75897232000-05-29 14:26:00 +00002764 {
drh67505e72002-04-19 12:34:06 +00002765 fprintf(stderr, "unknown command or invalid arguments: "
2766 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00002767 }
drh67505e72002-04-19 12:34:06 +00002768
2769 return rc;
drh75897232000-05-29 14:26:00 +00002770}
2771
drh67505e72002-04-19 12:34:06 +00002772/*
drh91a66392007-09-07 01:12:32 +00002773** Return TRUE if a semicolon occurs anywhere in the first N characters
2774** of string z[].
drh324ccef2003-02-05 14:06:20 +00002775*/
drh91a66392007-09-07 01:12:32 +00002776static int _contains_semicolon(const char *z, int N){
2777 int i;
2778 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2779 return 0;
drh324ccef2003-02-05 14:06:20 +00002780}
2781
2782/*
drh70c7a4b2003-04-26 03:03:06 +00002783** Test to see if a line consists entirely of whitespace.
2784*/
2785static int _all_whitespace(const char *z){
2786 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002787 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002788 if( *z=='/' && z[1]=='*' ){
2789 z += 2;
2790 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2791 if( *z==0 ) return 0;
2792 z++;
2793 continue;
2794 }
2795 if( *z=='-' && z[1]=='-' ){
2796 z += 2;
2797 while( *z && *z!='\n' ){ z++; }
2798 if( *z==0 ) return 1;
2799 continue;
2800 }
2801 return 0;
2802 }
2803 return 1;
2804}
2805
2806/*
drha9b17162003-04-29 18:01:28 +00002807** Return TRUE if the line typed in is an SQL command terminator other
2808** than a semi-colon. The SQL Server style "go" command is understood
2809** as is the Oracle "/".
2810*/
2811static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002812 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002813 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2814 return 1; /* Oracle */
2815 }
drhc8d74412004-08-31 23:41:26 +00002816 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2817 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002818 return 1; /* SQL Server */
2819 }
2820 return 0;
2821}
2822
2823/*
drh233a5312008-12-18 22:25:13 +00002824** Return true if zSql is a complete SQL statement. Return false if it
2825** ends in the middle of a string literal or C-style comment.
2826*/
2827static int _is_complete(char *zSql, int nSql){
2828 int rc;
2829 if( zSql==0 ) return 1;
2830 zSql[nSql] = ';';
2831 zSql[nSql+1] = 0;
2832 rc = sqlite3_complete(zSql);
2833 zSql[nSql] = 0;
2834 return rc;
2835}
2836
2837/*
drh67505e72002-04-19 12:34:06 +00002838** Read input from *in and process it. If *in==0 then input
2839** is interactive - the user is typing it it. Otherwise, input
2840** is coming from a file or device. A prompt is issued and history
2841** is saved only if input is interactive. An interrupt signal will
2842** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002843**
2844** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002845*/
drhc28490c2006-10-26 14:25:58 +00002846static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002847 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002848 char *zSql = 0;
2849 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002850 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002851 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002852 int rc;
2853 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002854 int lineno = 0;
2855 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002856
2857 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2858 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002859 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002860 zLine = one_input_line(zSql, in);
2861 if( zLine==0 ){
2862 break; /* We have reached EOF */
2863 }
drh67505e72002-04-19 12:34:06 +00002864 if( seenInterrupt ){
2865 if( in!=0 ) break;
2866 seenInterrupt = 0;
2867 }
drhc28490c2006-10-26 14:25:58 +00002868 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00002869 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00002870 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002871 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00002872 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00002873 if( rc==2 ){
2874 break;
2875 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002876 errCnt++;
2877 }
drhdaffd0e2001-04-11 14:28:42 +00002878 continue;
2879 }
drh233a5312008-12-18 22:25:13 +00002880 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002881 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002882 }
drh91a66392007-09-07 01:12:32 +00002883 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002884 if( zSql==0 ){
2885 int i;
drh4c755c02004-08-08 20:22:17 +00002886 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002887 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002888 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002889 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002890 if( zSql==0 ){
2891 fprintf(stderr, "out of memory\n");
2892 exit(1);
2893 }
drh5bb3eb92007-05-04 13:15:55 +00002894 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002895 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002896 }
2897 }else{
drh4f21c4a2008-12-10 22:15:00 +00002898 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002899 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002900 if( zSql==0 ){
2901 fprintf(stderr,"%s: out of memory!\n", Argv0);
2902 exit(1);
2903 }
drh5bb3eb92007-05-04 13:15:55 +00002904 zSql[nSql++] = '\n';
2905 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002906 nSql += len;
2907 }
drh91a66392007-09-07 01:12:32 +00002908 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2909 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002910 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002911 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002912 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00002913 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002914 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002915 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002916 char zPrefix[100];
2917 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002918 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
2919 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002920 }else{
drh5bb3eb92007-05-04 13:15:55 +00002921 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00002922 }
drh7f953e22002-07-13 17:33:45 +00002923 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002924 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002925 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002926 zErrMsg = 0;
2927 }else{
shaned2bed1c2009-10-21 03:56:54 +00002928 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002929 }
drhc49f44e2006-10-26 18:15:42 +00002930 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002931 }
2932 free(zSql);
2933 zSql = 0;
2934 nSql = 0;
2935 }
2936 }
2937 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00002938 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002939 free(zSql);
2940 }
danielk19772ac27622007-07-03 05:31:16 +00002941 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002942 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002943}
2944
drh67505e72002-04-19 12:34:06 +00002945/*
2946** Return a pathname which is the user's home directory. A
2947** 0 return indicates an error of some kind. Space to hold the
2948** resulting string is obtained from malloc(). The calling
2949** function should free the result.
2950*/
2951static char *find_home_dir(void){
2952 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002953
chw97185482008-11-17 08:05:31 +00002954#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002955 struct passwd *pwent;
2956 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002957 if( (pwent=getpwuid(uid)) != NULL) {
2958 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002959 }
2960#endif
2961
chw65d3c132007-11-12 21:09:10 +00002962#if defined(_WIN32_WCE)
2963 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2964 */
2965 home_dir = strdup("/");
2966#else
2967
drh164a1b62006-08-19 11:15:20 +00002968#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2969 if (!home_dir) {
2970 home_dir = getenv("USERPROFILE");
2971 }
2972#endif
2973
drh67505e72002-04-19 12:34:06 +00002974 if (!home_dir) {
2975 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002976 }
2977
drhcdb36b72006-06-12 12:57:45 +00002978#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002979 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002980 char *zDrive, *zPath;
2981 int n;
2982 zDrive = getenv("HOMEDRIVE");
2983 zPath = getenv("HOMEPATH");
2984 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002985 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002986 home_dir = malloc( n );
2987 if( home_dir==0 ) return 0;
2988 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2989 return home_dir;
2990 }
2991 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002992 }
2993#endif
2994
chw65d3c132007-11-12 21:09:10 +00002995#endif /* !_WIN32_WCE */
2996
drh67505e72002-04-19 12:34:06 +00002997 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002998 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002999 char *z = malloc( n );
3000 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00003001 home_dir = z;
3002 }
drhe98d4fa2002-04-21 19:06:22 +00003003
drh67505e72002-04-19 12:34:06 +00003004 return home_dir;
3005}
3006
3007/*
3008** Read input from the file given by sqliterc_override. Or if that
3009** parameter is NULL, take input from ~/.sqliterc
3010*/
drh22fbcb82004-02-01 01:22:50 +00003011static void process_sqliterc(
3012 struct callback_data *p, /* Configuration data */
3013 const char *sqliterc_override /* Name of config file. NULL to use default */
3014){
persicom7e2dfdd2002-04-18 02:46:52 +00003015 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00003016 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00003017 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003018 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00003019 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003020
3021 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00003022 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00003023 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00003024#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00003025 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00003026#endif
drhe98d4fa2002-04-21 19:06:22 +00003027 return;
3028 }
drh4f21c4a2008-12-10 22:15:00 +00003029 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00003030 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00003031 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003032 fprintf(stderr,"%s: out of memory!\n", Argv0);
3033 exit(1);
3034 }
drha959ac42007-06-20 13:10:00 +00003035 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00003036 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00003037 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003038 }
drha1f9b5e2004-02-14 16:31:02 +00003039 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00003040 if( in ){
drhc28490c2006-10-26 14:25:58 +00003041 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00003042 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00003043 }
persicom7e2dfdd2002-04-18 02:46:52 +00003044 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00003045 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00003046 }
drh43617e92006-03-06 20:55:46 +00003047 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00003048 return;
3049}
3050
drh67505e72002-04-19 12:34:06 +00003051/*
drhe1e38c42003-05-04 18:30:59 +00003052** Show available command line options
3053*/
3054static const char zOptions[] =
3055 " -init filename read/process named file\n"
3056 " -echo print commands before execution\n"
3057 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00003058 " -bail stop after hitting an error\n"
3059 " -interactive force interactive I/O\n"
3060 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003061 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00003062 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00003063 " -html set output mode to HTML\n"
3064 " -line set output mode to 'line'\n"
3065 " -list set output mode to 'list'\n"
3066 " -separator 'x' set output field separator (|)\n"
3067 " -nullvalue 'text' set text string for NULL values\n"
3068 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00003069;
3070static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00003071 fprintf(stderr,
3072 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3073 "FILENAME is the name of an SQLite database. A new database is created\n"
3074 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00003075 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00003076 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00003077 }else{
3078 fprintf(stderr, "Use the -help option for additional information\n");
3079 }
3080 exit(1);
3081}
3082
3083/*
drh67505e72002-04-19 12:34:06 +00003084** Initialize the state information in data
3085*/
drh0850b532006-01-31 19:31:43 +00003086static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00003087 memset(data, 0, sizeof(*data));
3088 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00003089 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00003090 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00003091 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3092 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00003093}
3094
drh75897232000-05-29 14:26:00 +00003095int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003096 char *zErrMsg = 0;
3097 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00003098 const char *zInitFile = 0;
3099 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003100 int i;
drhc28490c2006-10-26 14:25:58 +00003101 int rc = 0;
drh75897232000-05-29 14:26:00 +00003102
drhdaffd0e2001-04-11 14:28:42 +00003103 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003104 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003105 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003106
drh44c2eb12003-04-30 11:38:26 +00003107 /* Make sure we have a valid signal handler early, before anything
3108 ** else is done.
3109 */
drh4c504392000-10-16 22:06:40 +00003110#ifdef SIGINT
3111 signal(SIGINT, interrupt_handler);
3112#endif
drh44c2eb12003-04-30 11:38:26 +00003113
drh22fbcb82004-02-01 01:22:50 +00003114 /* Do an initial pass through the command-line argument to locate
3115 ** the name of the database file, the name of the initialization file,
3116 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003117 */
drh22fbcb82004-02-01 01:22:50 +00003118 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00003119 char *z;
drh44c2eb12003-04-30 11:38:26 +00003120 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00003121 z = argv[i];
3122 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00003123 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
3124 i++;
drh22fbcb82004-02-01 01:22:50 +00003125 }else if( strcmp(argv[i],"-init")==0 ){
3126 i++;
3127 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00003128 }
3129 }
drh22fbcb82004-02-01 01:22:50 +00003130 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00003131#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00003132 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
3133#else
drh22fbcb82004-02-01 01:22:50 +00003134 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00003135#endif
drh22fbcb82004-02-01 01:22:50 +00003136 }else{
danielk197703aded42004-11-22 05:26:27 +00003137#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003138 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003139#else
3140 data.zDbFilename = 0;
3141#endif
drh22fbcb82004-02-01 01:22:50 +00003142 }
3143 if( i<argc ){
3144 zFirstCmd = argv[i++];
3145 }
drh44c2eb12003-04-30 11:38:26 +00003146 data.out = stdout;
3147
drh01b41712005-08-29 23:06:23 +00003148#ifdef SQLITE_OMIT_MEMORYDB
3149 if( data.zDbFilename==0 ){
3150 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
3151 exit(1);
3152 }
3153#endif
3154
drh44c2eb12003-04-30 11:38:26 +00003155 /* Go ahead and open the database file if it already exists. If the
3156 ** file does not exist, delay opening it. This prevents empty database
3157 ** files from being created if a user mistypes the database name argument
3158 ** to the sqlite command-line tool.
3159 */
drhc8d74412004-08-31 23:41:26 +00003160 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003161 open_db(&data);
3162 }
3163
drh22fbcb82004-02-01 01:22:50 +00003164 /* Process the initialization file if there is one. If no -init option
3165 ** is given on the command line, look for a file named ~/.sqliterc and
3166 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003167 */
drh22fbcb82004-02-01 01:22:50 +00003168 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00003169
drh22fbcb82004-02-01 01:22:50 +00003170 /* Make a second pass through the command-line argument and set
3171 ** options. This second pass is delayed until after the initialization
3172 ** file is processed so that the command-line arguments will override
3173 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003174 */
drh22fbcb82004-02-01 01:22:50 +00003175 for(i=1; i<argc && argv[i][0]=='-'; i++){
3176 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00003177 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003178 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003179 i++;
3180 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003181 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003182 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003183 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003184 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003185 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003186 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003187 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003188 }else if( strcmp(z,"-csv")==0 ){
3189 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003190 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003191 }else if( strcmp(z,"-separator")==0 ){
3192 i++;
drh5bb3eb92007-05-04 13:15:55 +00003193 sqlite3_snprintf(sizeof(data.separator), data.separator,
3194 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003195 }else if( strcmp(z,"-nullvalue")==0 ){
3196 i++;
drh5bb3eb92007-05-04 13:15:55 +00003197 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
3198 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003199 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003200 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003201 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003202 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003203 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003204 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003205 }else if( strcmp(z,"-bail")==0 ){
3206 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003207 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00003208 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00003209 return 0;
drhc28490c2006-10-26 14:25:58 +00003210 }else if( strcmp(z,"-interactive")==0 ){
3211 stdin_is_interactive = 1;
3212 }else if( strcmp(z,"-batch")==0 ){
3213 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00003214 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003215 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00003216 }else{
drh22fbcb82004-02-01 01:22:50 +00003217 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003218 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003219 return 1;
3220 }
3221 }
drh44c2eb12003-04-30 11:38:26 +00003222
drh22fbcb82004-02-01 01:22:50 +00003223 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003224 /* Run just the command that follows the database name
3225 */
drh22fbcb82004-02-01 01:22:50 +00003226 if( zFirstCmd[0]=='.' ){
3227 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003228 exit(0);
3229 }else{
3230 int rc;
drh44c2eb12003-04-30 11:38:26 +00003231 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00003232 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00003233 if( rc!=0 && zErrMsg!=0 ){
3234 fprintf(stderr,"SQL error: %s\n", zErrMsg);
3235 exit(1);
3236 }
drh75897232000-05-29 14:26:00 +00003237 }
3238 }else{
drh44c2eb12003-04-30 11:38:26 +00003239 /* Run commands received from standard input
3240 */
drhc28490c2006-10-26 14:25:58 +00003241 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003242 char *zHome;
3243 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003244 int nHistory;
drh75897232000-05-29 14:26:00 +00003245 printf(
drhb217a572000-08-22 13:40:18 +00003246 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00003247 "Enter \".help\" for instructions\n"
3248 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00003249 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00003250 );
drh67505e72002-04-19 12:34:06 +00003251 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003252 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003253 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003254 if( (zHistory = malloc(nHistory))!=0 ){
3255 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3256 }
drh67505e72002-04-19 12:34:06 +00003257 }
danielk19774af00c62005-01-23 23:43:21 +00003258#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003259 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003260#endif
drhc28490c2006-10-26 14:25:58 +00003261 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003262 if( zHistory ){
3263 stifle_history(100);
3264 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003265 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003266 }
adamd0a3daa32006-07-28 20:16:14 +00003267 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00003268 }else{
drhc28490c2006-10-26 14:25:58 +00003269 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003270 }
3271 }
drh33048c02001-10-01 14:29:22 +00003272 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00003273 if( db ){
3274 if( sqlite3_close(db)!=SQLITE_OK ){
3275 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
3276 }
3277 }
drhc28490c2006-10-26 14:25:58 +00003278 return rc;
drh75897232000-05-29 14:26:00 +00003279}