blob: f12e6a98fc16117606d5fce5ac215b567560821c [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 {
shane626a6e42009-10-22 17:30:15 +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 */
shane626a6e42009-10-22 17:30:15 +00001280 sqlite3_stmt *pStmt; /* Current statement if any. */
drh75897232000-05-29 14:26:00 +00001281};
1282
1283/*
1284** These are the allowed modes.
1285*/
drh967e8b72000-06-21 13:59:10 +00001286#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +00001287#define MODE_Column 1 /* One record per line in neat columns */
1288#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +00001289#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
1290#define MODE_Html 4 /* Generate an XHTML table */
1291#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +00001292#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +00001293#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +00001294#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +00001295
drh66ce4d02008-02-15 17:38:06 +00001296static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +00001297 "line",
1298 "column",
1299 "list",
1300 "semi",
1301 "html",
drhfeac5f82004-08-01 00:10:45 +00001302 "insert",
1303 "tcl",
drh8e64d1c2004-10-07 00:32:39 +00001304 "csv",
drh66ce4d02008-02-15 17:38:06 +00001305 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +00001306};
drh75897232000-05-29 14:26:00 +00001307
1308/*
1309** Number of elements in an array
1310*/
drh902b9ee2008-12-05 17:17:07 +00001311#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +00001312
1313/*
drhea678832008-12-10 19:26:22 +00001314** Compute a string length that is limited to what can be stored in
1315** lower 30 bits of a 32-bit signed integer.
1316*/
drh4f21c4a2008-12-10 22:15:00 +00001317static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +00001318 const char *z2 = z;
1319 while( *z2 ){ z2++; }
1320 return 0x3fffffff & (int)(z2 - z);
1321}
1322
1323/*
shane626a6e42009-10-22 17:30:15 +00001324** Output the given string as a hex-encoded blob (eg. X'1234' )
1325*/
1326static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
1327 int i;
1328 char *zBlob = (char *)pBlob;
1329 fprintf(out,"X'");
1330 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
1331 fprintf(out,"'");
1332}
1333
1334/*
drh28bd4bc2000-06-15 15:57:22 +00001335** Output the given string as a quoted string using SQL quoting conventions.
1336*/
1337static void output_quoted_string(FILE *out, const char *z){
1338 int i;
1339 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +00001340 for(i=0; z[i]; i++){
1341 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +00001342 }
1343 if( nSingle==0 ){
1344 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +00001345 }else{
1346 fprintf(out,"'");
1347 while( *z ){
1348 for(i=0; z[i] && z[i]!='\''; i++){}
1349 if( i==0 ){
1350 fprintf(out,"''");
1351 z++;
1352 }else if( z[i]=='\'' ){
1353 fprintf(out,"%.*s''",i,z);
1354 z += i+1;
1355 }else{
drhcd7d2732002-02-26 23:24:26 +00001356 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +00001357 break;
1358 }
1359 }
drhcd7d2732002-02-26 23:24:26 +00001360 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +00001361 }
1362}
1363
1364/*
drhfeac5f82004-08-01 00:10:45 +00001365** Output the given string as a quoted according to C or TCL quoting rules.
1366*/
1367static void output_c_string(FILE *out, const char *z){
1368 unsigned int c;
1369 fputc('"', out);
1370 while( (c = *(z++))!=0 ){
1371 if( c=='\\' ){
1372 fputc(c, out);
1373 fputc(c, out);
1374 }else if( c=='\t' ){
1375 fputc('\\', out);
1376 fputc('t', out);
1377 }else if( c=='\n' ){
1378 fputc('\\', out);
1379 fputc('n', out);
1380 }else if( c=='\r' ){
1381 fputc('\\', out);
1382 fputc('r', out);
1383 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +00001384 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +00001385 }else{
1386 fputc(c, out);
1387 }
1388 }
1389 fputc('"', out);
1390}
1391
1392/*
drhc08a4f12000-06-15 16:49:48 +00001393** Output the given string with characters that are special to
1394** HTML escaped.
1395*/
1396static void output_html_string(FILE *out, const char *z){
1397 int i;
1398 while( *z ){
shane43d9cb22009-10-21 14:11:48 +00001399 for(i=0; z[i]
1400 && z[i]!='<'
1401 && z[i]!='&'
1402 && z[i]!='>'
1403 && z[i]!='\"'
1404 && z[i]!='\'';
1405 i++){}
drhc08a4f12000-06-15 16:49:48 +00001406 if( i>0 ){
1407 fprintf(out,"%.*s",i,z);
1408 }
1409 if( z[i]=='<' ){
1410 fprintf(out,"&lt;");
1411 }else if( z[i]=='&' ){
1412 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +00001413 }else if( z[i]=='>' ){
1414 fprintf(out,"&gt;");
1415 }else if( z[i]=='\"' ){
1416 fprintf(out,"&quot;");
1417 }else if( z[i]=='\'' ){
1418 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +00001419 }else{
1420 break;
1421 }
1422 z += i + 1;
1423 }
1424}
1425
1426/*
drhc49f44e2006-10-26 18:15:42 +00001427** If a field contains any character identified by a 1 in the following
1428** array, then the string must be quoted for CSV.
1429*/
1430static const char needCsvQuote[] = {
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, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1434 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1435 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1436 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1437 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1438 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1439 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1440 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1441 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1442 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1443 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1444 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1445 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1446 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1447};
1448
1449/*
drh8e64d1c2004-10-07 00:32:39 +00001450** Output a single term of CSV. Actually, p->separator is used for
1451** the separator, which may or may not be a comma. p->nullvalue is
1452** the null value. Strings are quoted using ANSI-C rules. Numbers
1453** appear outside of quotes.
1454*/
1455static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +00001456 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +00001457 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +00001458 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +00001459 }else{
drhc49f44e2006-10-26 18:15:42 +00001460 int i;
drh4f21c4a2008-12-10 22:15:00 +00001461 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +00001462 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +00001463 if( needCsvQuote[((unsigned char*)z)[i]]
1464 || (z[i]==p->separator[0] &&
1465 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +00001466 i = 0;
1467 break;
1468 }
1469 }
1470 if( i==0 ){
1471 putc('"', out);
1472 for(i=0; z[i]; i++){
1473 if( z[i]=='"' ) putc('"', out);
1474 putc(z[i], out);
1475 }
1476 putc('"', out);
1477 }else{
1478 fprintf(out, "%s", z);
1479 }
drh8e64d1c2004-10-07 00:32:39 +00001480 }
1481 if( bSep ){
drhd0e77882008-01-14 15:20:08 +00001482 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +00001483 }
1484}
1485
danielk19774af00c62005-01-23 23:43:21 +00001486#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +00001487/*
drh4c504392000-10-16 22:06:40 +00001488** This routine runs when the user presses Ctrl-C
1489*/
1490static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +00001491 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +00001492 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +00001493 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +00001494}
danielk19774af00c62005-01-23 23:43:21 +00001495#endif
drh4c504392000-10-16 22:06:40 +00001496
1497/*
shane626a6e42009-10-22 17:30:15 +00001498** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +00001499** invokes for each row of a query result.
1500*/
shane626a6e42009-10-22 17:30:15 +00001501static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +00001502 int i;
1503 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +00001504
1505 if( p->echoOn && p->cnt==0 && p->pStmt){
1506 printf("%s\n", sqlite3_sql(p->pStmt));
1507 }
1508
drh75897232000-05-29 14:26:00 +00001509 switch( p->mode ){
1510 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +00001511 int w = 5;
drh6a535342001-10-19 16:44:56 +00001512 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +00001513 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +00001514 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +00001515 if( len>w ) w = len;
1516 }
drh75897232000-05-29 14:26:00 +00001517 if( p->cnt++>0 ) fprintf(p->out,"\n");
1518 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001519 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +00001520 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +00001521 }
1522 break;
1523 }
danielk19770d78bae2008-01-03 07:09:48 +00001524 case MODE_Explain:
drh75897232000-05-29 14:26:00 +00001525 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +00001526 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +00001527 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +00001528 int w, n;
1529 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +00001530 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +00001531 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001532 w = 0;
drh75897232000-05-29 14:26:00 +00001533 }
drha0c66f52000-07-29 13:20:21 +00001534 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001535 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001536 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +00001537 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +00001538 if( w<n ) w = n;
1539 }
1540 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001541 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001542 }
1543 if( p->showHeader ){
1544 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
1545 }
1546 }
1547 if( p->showHeader ){
1548 for(i=0; i<nArg; i++){
1549 int w;
1550 if( i<ArraySize(p->actualWidth) ){
1551 w = p->actualWidth[i];
1552 }else{
1553 w = 10;
1554 }
1555 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
1556 "----------------------------------------------------------",
1557 i==nArg-1 ? "\n": " ");
1558 }
drh75897232000-05-29 14:26:00 +00001559 }
1560 }
drh6a535342001-10-19 16:44:56 +00001561 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001562 for(i=0; i<nArg; i++){
1563 int w;
drha0c66f52000-07-29 13:20:21 +00001564 if( i<ArraySize(p->actualWidth) ){
1565 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001566 }else{
1567 w = 10;
1568 }
drhea678832008-12-10 19:26:22 +00001569 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +00001570 strlen30(azArg[i])>w ){
1571 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001572 }
drhc61053b2000-06-04 12:58:36 +00001573 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +00001574 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +00001575 }
1576 break;
1577 }
drhe3710332000-09-29 13:30:53 +00001578 case MODE_Semi:
drh75897232000-05-29 14:26:00 +00001579 case MODE_List: {
1580 if( p->cnt++==0 && p->showHeader ){
1581 for(i=0; i<nArg; i++){
1582 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
1583 }
1584 }
drh6a535342001-10-19 16:44:56 +00001585 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001586 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001587 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +00001588 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +00001589 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001590 if( i<nArg-1 ){
1591 fprintf(p->out, "%s", p->separator);
1592 }else if( p->mode==MODE_Semi ){
1593 fprintf(p->out, ";\n");
1594 }else{
1595 fprintf(p->out, "\n");
1596 }
drh75897232000-05-29 14:26:00 +00001597 }
1598 break;
1599 }
drh1e5d0e92000-05-31 23:33:17 +00001600 case MODE_Html: {
1601 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +00001602 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001603 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +00001604 fprintf(p->out,"<TH>");
1605 output_html_string(p->out, azCol[i]);
1606 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001607 }
mihailim57c591a2008-06-23 21:26:05 +00001608 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001609 }
drh6a535342001-10-19 16:44:56 +00001610 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +00001611 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001612 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +00001613 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +00001614 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +00001615 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001616 }
mihailim57c591a2008-06-23 21:26:05 +00001617 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001618 break;
1619 }
drhfeac5f82004-08-01 00:10:45 +00001620 case MODE_Tcl: {
1621 if( p->cnt++==0 && p->showHeader ){
1622 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001623 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +00001624 fprintf(p->out, "%s", p->separator);
1625 }
1626 fprintf(p->out,"\n");
1627 }
1628 if( azArg==0 ) break;
1629 for(i=0; i<nArg; i++){
1630 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
1631 fprintf(p->out, "%s", p->separator);
1632 }
1633 fprintf(p->out,"\n");
1634 break;
1635 }
drh8e64d1c2004-10-07 00:32:39 +00001636 case MODE_Csv: {
1637 if( p->cnt++==0 && p->showHeader ){
1638 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001639 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001640 }
1641 fprintf(p->out,"\n");
1642 }
1643 if( azArg==0 ) break;
1644 for(i=0; i<nArg; i++){
1645 output_csv(p, azArg[i], i<nArg-1);
1646 }
1647 fprintf(p->out,"\n");
1648 break;
1649 }
drh28bd4bc2000-06-15 15:57:22 +00001650 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001651 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001652 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +00001653 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +00001654 for(i=0; i<nArg; i++){
1655 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001656 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +00001657 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001658 }else if( aiType && aiType[i]==SQLITE_TEXT ){
1659 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1660 output_quoted_string(p->out, azArg[i]);
1661 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
1662 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001663 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1664 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1665 int nBlob = sqlite3_column_bytes(p->pStmt, i);
1666 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1667 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001668 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001669 fprintf(p->out,"%s%s",zSep, azArg[i]);
1670 }else{
1671 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1672 output_quoted_string(p->out, azArg[i]);
1673 }
1674 }
1675 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001676 break;
drh28bd4bc2000-06-15 15:57:22 +00001677 }
persicom1d0b8722002-04-18 02:53:04 +00001678 }
drh75897232000-05-29 14:26:00 +00001679 return 0;
1680}
1681
1682/*
shane626a6e42009-10-22 17:30:15 +00001683** This is the callback routine that the SQLite library
1684** invokes for each row of a query result.
1685*/
1686static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1687 /* since we don't have type info, call the shell_callback with a NULL value */
1688 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1689}
1690
1691/*
drh33048c02001-10-01 14:29:22 +00001692** Set the destination table field of the callback_data structure to
1693** the name of the table given. Escape any quote characters in the
1694** table name.
1695*/
1696static void set_table_name(struct callback_data *p, const char *zName){
1697 int i, n;
1698 int needQuote;
1699 char *z;
1700
1701 if( p->zDestTable ){
1702 free(p->zDestTable);
1703 p->zDestTable = 0;
1704 }
1705 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001706 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001707 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001708 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001709 needQuote = 1;
1710 if( zName[i]=='\'' ) n++;
1711 }
1712 }
1713 if( needQuote ) n += 2;
1714 z = p->zDestTable = malloc( n+1 );
1715 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001716 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001717 exit(1);
1718 }
1719 n = 0;
1720 if( needQuote ) z[n++] = '\'';
1721 for(i=0; zName[i]; i++){
1722 z[n++] = zName[i];
1723 if( zName[i]=='\'' ) z[n++] = '\'';
1724 }
1725 if( needQuote ) z[n++] = '\'';
1726 z[n] = 0;
1727}
1728
danielk19772a02e332004-06-05 08:04:36 +00001729/* zIn is either a pointer to a NULL-terminated string in memory obtained
1730** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1731** added to zIn, and the result returned in memory obtained from malloc().
1732** zIn, if it was not NULL, is freed.
1733**
1734** If the third argument, quote, is not '\0', then it is used as a
1735** quote character for zAppend.
1736*/
drhc28490c2006-10-26 14:25:58 +00001737static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001738 int len;
1739 int i;
drh4f21c4a2008-12-10 22:15:00 +00001740 int nAppend = strlen30(zAppend);
1741 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001742
1743 len = nAppend+nIn+1;
1744 if( quote ){
1745 len += 2;
1746 for(i=0; i<nAppend; i++){
1747 if( zAppend[i]==quote ) len++;
1748 }
1749 }
1750
1751 zIn = (char *)realloc(zIn, len);
1752 if( !zIn ){
1753 return 0;
1754 }
1755
1756 if( quote ){
1757 char *zCsr = &zIn[nIn];
1758 *zCsr++ = quote;
1759 for(i=0; i<nAppend; i++){
1760 *zCsr++ = zAppend[i];
1761 if( zAppend[i]==quote ) *zCsr++ = quote;
1762 }
1763 *zCsr++ = quote;
1764 *zCsr++ = '\0';
1765 assert( (zCsr-zIn)==len );
1766 }else{
1767 memcpy(&zIn[nIn], zAppend, nAppend);
1768 zIn[len-1] = '\0';
1769 }
1770
1771 return zIn;
1772}
1773
drhdd3d4592004-08-30 01:54:05 +00001774
1775/*
1776** Execute a query statement that has a single result column. Print
1777** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +00001778**
1779** This is used, for example, to show the schema of the database by
1780** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +00001781*/
drh157e29a2009-05-21 15:15:00 +00001782static int run_table_dump_query(
1783 FILE *out, /* Send output here */
1784 sqlite3 *db, /* Database to query */
1785 const char *zSelect, /* SELECT statement to extract content */
1786 const char *zFirstRow /* Print before first row, if not NULL */
1787){
drhdd3d4592004-08-30 01:54:05 +00001788 sqlite3_stmt *pSelect;
1789 int rc;
1790 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
1791 if( rc!=SQLITE_OK || !pSelect ){
1792 return rc;
1793 }
1794 rc = sqlite3_step(pSelect);
1795 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001796 if( zFirstRow ){
1797 fprintf(out, "%s", zFirstRow);
1798 zFirstRow = 0;
1799 }
drhdd3d4592004-08-30 01:54:05 +00001800 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
1801 rc = sqlite3_step(pSelect);
1802 }
1803 return sqlite3_finalize(pSelect);
1804}
1805
shane626a6e42009-10-22 17:30:15 +00001806/*
1807** Allocate space and save off current error string.
1808*/
1809static char *save_err_msg(
1810 sqlite3 *db /* Database to query */
1811){
1812 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1813 char *zErrMsg = sqlite3_malloc(nErrMsg);
1814 if( zErrMsg ){
1815 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1816 }
1817 return zErrMsg;
1818}
1819
1820/*
1821** Execute a statement or set of statements. Print
1822** any result rows/columns depending on the current mode
1823** set via the supplied callback.
1824**
1825** This is very similar to SQLite's built-in sqlite3_exec()
1826** function except it takes a slightly different callback
1827** and callback data argument.
1828*/
1829static int shell_exec(
1830 sqlite3 *db, /* An open database */
1831 const char *zSql, /* SQL to be evaluated */
1832 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1833 /* (not the same as sqlite3_exec) */
1834 struct callback_data *pArg, /* Pointer to struct callback_data */
1835 char **pzErrMsg /* Error msg written here */
1836){
1837 sqlite3_stmt *pStmt = NULL;
shaneb9fc17d2009-10-22 21:23:35 +00001838 int rc = SQLITE_OK;
1839 int rc2;
1840 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001841
1842 if( pzErrMsg ){
1843 *pzErrMsg = NULL;
1844 }
1845
shaneb9fc17d2009-10-22 21:23:35 +00001846 while( zSql[0] && (SQLITE_OK == rc) ){
1847 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1848 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001849 if( pzErrMsg ){
1850 *pzErrMsg = save_err_msg(db);
1851 }
1852 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001853 if( !pStmt ){
1854 /* this happens for a comment or white-space */
1855 zSql = zLeftover;
1856 while( isspace(zSql[0]) ) zSql++;
1857 continue;
1858 }
shane626a6e42009-10-22 17:30:15 +00001859
shaneb9fc17d2009-10-22 21:23:35 +00001860 /* perform the first step. this will tell us if we
1861 ** have a result set or not and how wide it is.
1862 */
1863 rc = sqlite3_step(pStmt);
1864 /* if we have a result set... */
1865 if( SQLITE_ROW == rc ){
1866 /* if we have a callback... */
1867 if( xCallback ){
1868 /* allocate space for col name ptr, value ptr, and type */
1869 int nCol = sqlite3_column_count(pStmt);
1870 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1871 if( !pData ){
1872 rc = SQLITE_NOMEM;
1873 }else{
1874 char **azCols = (char **)pData; /* Names of result columns */
1875 char **azVals = &azCols[nCol]; /* Results */
1876 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1877 int i;
1878 assert(sizeof(int) <= sizeof(char *));
1879 /* save off ptrs to column names */
1880 for(i=0; i<nCol; i++){
1881 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1882 }
1883 /* save off the prepared statment handle and reset row count */
1884 if( pArg ){
1885 pArg->pStmt = pStmt;
1886 pArg->cnt = 0;
1887 }
1888 do{
1889 /* extract the data and data types */
1890 for(i=0; i<nCol; i++){
1891 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1892 aiTypes[i] = sqlite3_column_type(pStmt, i);
1893 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1894 rc = SQLITE_NOMEM;
1895 break; /* from for */
1896 }
1897 } /* end for */
1898
1899 /* if data and types extracted successfully... */
1900 if( SQLITE_ROW == rc ){
1901 /* call the supplied callback with the result row data */
1902 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1903 rc = SQLITE_ABORT;
1904 }else{
1905 rc = sqlite3_step(pStmt);
1906 }
1907 }
1908 } while( SQLITE_ROW == rc );
1909 sqlite3_free(pData);
1910 if( pArg ){
1911 pArg->pStmt = NULL;
1912 }
1913 }
1914 }else{
1915 do{
1916 rc = sqlite3_step(pStmt);
1917 } while( rc == SQLITE_ROW );
1918 }
1919 }
1920
1921 /* if the last sqlite3_step() didn't complete successfully... */
1922 if( (SQLITE_OK != rc) && (SQLITE_DONE != rc) ){
1923 if( pzErrMsg ){
1924 *pzErrMsg = save_err_msg(db);
1925 }
1926 }else{
1927 rc = SQLITE_OK;
1928 }
1929
1930 rc2 = sqlite3_finalize(pStmt);
1931 /* if the last sqlite3_finalize() didn't complete successfully
shane86f5bdb2009-10-24 02:00:07 +00001932 ** AND we don't have a saved error from sqlite3_step ... */
shaneb9fc17d2009-10-22 21:23:35 +00001933 if( (SQLITE_OK != rc2) && (SQLITE_OK == rc) ){
1934 rc = rc2;
1935 if( pzErrMsg ){
1936 *pzErrMsg = save_err_msg(db);
1937 }
1938 }
1939
1940 if( SQLITE_OK == rc ){
1941 zSql = zLeftover;
1942 while( isspace(zSql[0]) ) zSql++;
shane626a6e42009-10-22 17:30:15 +00001943 }
1944 }
shaneb9fc17d2009-10-22 21:23:35 +00001945 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001946
1947 return rc;
1948}
1949
drhdd3d4592004-08-30 01:54:05 +00001950
drh33048c02001-10-01 14:29:22 +00001951/*
drh4c653a02000-06-07 01:27:47 +00001952** This is a different callback routine used for dumping the database.
1953** Each row received by this callback consists of a table name,
1954** the table type ("index" or "table") and SQL to create the table.
1955** This routine should print text sufficient to recreate the table.
1956*/
1957static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001958 int rc;
1959 const char *zTable;
1960 const char *zType;
1961 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001962 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001963 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001964
drh902b9ee2008-12-05 17:17:07 +00001965 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001966 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001967 zTable = azArg[0];
1968 zType = azArg[1];
1969 zSql = azArg[2];
1970
drh00b950d2005-09-11 02:03:03 +00001971 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001972 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001973 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1974 fprintf(p->out, "ANALYZE sqlite_master;\n");
1975 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1976 return 0;
drh45e29d82006-11-20 16:21:10 +00001977 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1978 char *zIns;
1979 if( !p->writableSchema ){
1980 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1981 p->writableSchema = 1;
1982 }
1983 zIns = sqlite3_mprintf(
1984 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1985 "VALUES('table','%q','%q',0,'%q');",
1986 zTable, zTable, zSql);
1987 fprintf(p->out, "%s\n", zIns);
1988 sqlite3_free(zIns);
1989 return 0;
drh00b950d2005-09-11 02:03:03 +00001990 }else{
1991 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001992 }
danielk19772a02e332004-06-05 08:04:36 +00001993
1994 if( strcmp(zType, "table")==0 ){
1995 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001996 char *zSelect = 0;
1997 char *zTableInfo = 0;
1998 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001999 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00002000
2001 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2002 zTableInfo = appendText(zTableInfo, zTable, '"');
2003 zTableInfo = appendText(zTableInfo, ");", 0);
2004
2005 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002006 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002007 if( rc!=SQLITE_OK || !pTableInfo ){
2008 return 1;
2009 }
2010
2011 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
2012 zTmp = appendText(zTmp, zTable, '"');
2013 if( zTmp ){
2014 zSelect = appendText(zSelect, zTmp, '\'');
2015 }
2016 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2017 rc = sqlite3_step(pTableInfo);
2018 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002019 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002020 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002021 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002022 rc = sqlite3_step(pTableInfo);
2023 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00002024 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002025 }else{
2026 zSelect = appendText(zSelect, ") ", 0);
2027 }
drh157e29a2009-05-21 15:15:00 +00002028 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002029 }
2030 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002031 if( rc!=SQLITE_OK || nRow==0 ){
2032 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002033 return 1;
2034 }
2035 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2036 zSelect = appendText(zSelect, zTable, '"');
2037
drh157e29a2009-05-21 15:15:00 +00002038 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002039 if( rc==SQLITE_CORRUPT ){
2040 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00002041 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002042 }
danielk19772a02e332004-06-05 08:04:36 +00002043 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002044 }
drh4c653a02000-06-07 01:27:47 +00002045 return 0;
2046}
2047
2048/*
drh45e29d82006-11-20 16:21:10 +00002049** Run zQuery. Use dump_callback() as the callback routine so that
2050** the contents of the query are output as SQL statements.
2051**
drhdd3d4592004-08-30 01:54:05 +00002052** If we get a SQLITE_CORRUPT error, rerun the query after appending
2053** "ORDER BY rowid DESC" to the end.
2054*/
2055static int run_schema_dump_query(
2056 struct callback_data *p,
2057 const char *zQuery,
2058 char **pzErrMsg
2059){
2060 int rc;
2061 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
2062 if( rc==SQLITE_CORRUPT ){
2063 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002064 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00002065 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
2066 zQ2 = malloc( len+100 );
2067 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00002068 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00002069 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
2070 free(zQ2);
2071 }
2072 return rc;
2073}
2074
danielk1977c8c70692009-02-25 15:22:02 +00002075#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
2076struct GenfkeyCmd {
2077 sqlite3 *db; /* Database handle */
2078 struct callback_data *pCb; /* Callback data */
2079 int isIgnoreErrors; /* True for --ignore-errors */
2080 int isExec; /* True for --exec */
2081 int isNoDrop; /* True for --no-drop */
2082 int nErr; /* Number of errors seen so far */
2083};
2084typedef struct GenfkeyCmd GenfkeyCmd;
2085
2086static int genfkeyParseArgs(GenfkeyCmd *p, char **azArg, int nArg){
2087 int ii;
2088 memset(p, 0, sizeof(GenfkeyCmd));
2089
2090 for(ii=0; ii<nArg; ii++){
drh93a989c2009-03-16 10:59:44 +00002091 int n = strlen30(azArg[ii]);
danielk1977c8c70692009-02-25 15:22:02 +00002092
2093 if( n>2 && n<10 && 0==strncmp(azArg[ii], "--no-drop", n) ){
2094 p->isNoDrop = 1;
2095 }else if( n>2 && n<16 && 0==strncmp(azArg[ii], "--ignore-errors", n) ){
2096 p->isIgnoreErrors = 1;
2097 }else if( n>2 && n<7 && 0==strncmp(azArg[ii], "--exec", n) ){
2098 p->isExec = 1;
2099 }else{
2100 fprintf(stderr, "unknown option: %s\n", azArg[ii]);
2101 return -1;
2102 }
2103 }
2104
2105 return SQLITE_OK;
2106}
2107
2108static int genfkeyCmdCb(void *pCtx, int eType, const char *z){
2109 GenfkeyCmd *p = (GenfkeyCmd *)pCtx;
2110 if( eType==GENFKEY_ERROR && !p->isIgnoreErrors ){
2111 p->nErr++;
2112 fprintf(stderr, "%s\n", z);
2113 }
2114
2115 if( p->nErr==0 && (
2116 (eType==GENFKEY_CREATETRIGGER)
2117 || (eType==GENFKEY_DROPTRIGGER && !p->isNoDrop)
2118 )){
2119 if( p->isExec ){
2120 sqlite3_exec(p->db, z, 0, 0, 0);
2121 }else{
2122 char *zCol = "sql";
2123 callback((void *)p->pCb, 1, (char **)&z, (char **)&zCol);
2124 }
2125 }
2126
2127 return SQLITE_OK;
2128}
2129#endif
2130
drhdd3d4592004-08-30 01:54:05 +00002131/*
drh75897232000-05-29 14:26:00 +00002132** Text of a help message
2133*/
persicom1d0b8722002-04-18 02:53:04 +00002134static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00002135 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00002136 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00002137 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00002138 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002139 " If TABLE specified, only dump tables matching\n"
2140 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00002141 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00002142 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00002143 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
2144 " With no args, it turns EXPLAIN on.\n"
danielk1977c8c70692009-02-25 15:22:02 +00002145#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
2146 ".genfkey ?OPTIONS? Options are:\n"
2147 " --no-drop: Do not drop old fkey triggers.\n"
2148 " --ignore-errors: Ignore tables with fkey errors\n"
2149 " --exec: Execute generated SQL immediately\n"
danielk1977e6320042009-02-25 15:43:57 +00002150 " See file tool/genfkey.README in the source \n"
2151 " distribution for further information.\n"
danielk1977c8c70692009-02-25 15:22:02 +00002152#endif
persicom7e2dfdd2002-04-18 02:46:52 +00002153 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002154 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002155 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00002156 ".indices ?TABLE? Show names of all indices\n"
2157 " If TABLE specified, only show indices for tables\n"
2158 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002159#ifdef SQLITE_ENABLE_IOTRACE
2160 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2161#endif
drh70df4fe2006-06-13 15:12:21 +00002162#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002163 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002164#endif
danielk19776b77a362005-01-13 11:10:25 +00002165 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00002166 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002167 " column Left-aligned columns. (See .width)\n"
2168 " html HTML <table> code\n"
2169 " insert SQL insert statements for TABLE\n"
2170 " line One value per line\n"
2171 " list Values delimited by .separator string\n"
2172 " tabs Tab-separated values\n"
2173 " tcl TCL list elements\n"
2174 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00002175 ".output FILENAME Send output to FILENAME\n"
2176 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002177 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002178 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002179 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002180 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00002181 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00002182 " If TABLE specified, only show tables matching\n"
2183 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00002184 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00002185 ".show Show the current values for various settings\n"
shane86f5bdb2009-10-24 02:00:07 +00002186 ".tables ?TABLE? List names of tables\n"
2187 " If TABLE specified, only list tables matching\n"
2188 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00002189 ".timeout MS Try opening locked tables for MS milliseconds\n"
shanehe2aa9d72009-11-06 17:20:17 +00002190 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00002191;
2192
shaneb320ccd2009-10-21 03:42:58 +00002193static char zTimerHelp[] =
2194 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
2195;
2196
drhdaffd0e2001-04-11 14:28:42 +00002197/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00002198static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00002199
drh75897232000-05-29 14:26:00 +00002200/*
drh44c2eb12003-04-30 11:38:26 +00002201** Make sure the database is open. If it is not, then open it. If
2202** the database fails to open, print an error message and exit.
2203*/
2204static void open_db(struct callback_data *p){
2205 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00002206 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00002207 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00002208 if( db && sqlite3_errcode(db)==SQLITE_OK ){
2209 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
2210 shellstaticFunc, 0, 0);
2211 }
2212 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00002213 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00002214 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00002215 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002216 }
drhc2e87a32006-06-27 15:16:14 +00002217#ifndef SQLITE_OMIT_LOAD_EXTENSION
2218 sqlite3_enable_load_extension(p->db, 1);
2219#endif
drh44c2eb12003-04-30 11:38:26 +00002220 }
2221}
2222
2223/*
drhfeac5f82004-08-01 00:10:45 +00002224** Do C-language style dequoting.
2225**
2226** \t -> tab
2227** \n -> newline
2228** \r -> carriage return
2229** \NNN -> ascii character NNN in octal
2230** \\ -> backslash
2231*/
2232static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002233 int i, j;
2234 char c;
drhfeac5f82004-08-01 00:10:45 +00002235 for(i=j=0; (c = z[i])!=0; i++, j++){
2236 if( c=='\\' ){
2237 c = z[++i];
2238 if( c=='n' ){
2239 c = '\n';
2240 }else if( c=='t' ){
2241 c = '\t';
2242 }else if( c=='r' ){
2243 c = '\r';
2244 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002245 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002246 if( z[i+1]>='0' && z[i+1]<='7' ){
2247 i++;
2248 c = (c<<3) + z[i] - '0';
2249 if( z[i+1]>='0' && z[i+1]<='7' ){
2250 i++;
2251 c = (c<<3) + z[i] - '0';
2252 }
2253 }
2254 }
2255 }
2256 z[j] = c;
2257 }
2258 z[j] = 0;
2259}
2260
2261/*
drhc28490c2006-10-26 14:25:58 +00002262** Interpret zArg as a boolean value. Return either 0 or 1.
2263*/
2264static int booleanValue(char *zArg){
2265 int val = atoi(zArg);
2266 int j;
2267 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00002268 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00002269 }
2270 if( strcmp(zArg,"on")==0 ){
2271 val = 1;
2272 }else if( strcmp(zArg,"yes")==0 ){
2273 val = 1;
2274 }
2275 return val;
2276}
2277
2278/*
drh75897232000-05-29 14:26:00 +00002279** If an input line begins with "." then invoke this routine to
2280** process that line.
drh67505e72002-04-19 12:34:06 +00002281**
drh47ad6842006-11-08 12:25:42 +00002282** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002283*/
drh44c2eb12003-04-30 11:38:26 +00002284static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00002285 int i = 1;
2286 int nArg = 0;
2287 int n, c;
drh67505e72002-04-19 12:34:06 +00002288 int rc = 0;
drh75897232000-05-29 14:26:00 +00002289 char *azArg[50];
2290
2291 /* Parse the input line into tokens.
2292 */
2293 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00002294 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002295 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002296 if( zLine[i]=='\'' || zLine[i]=='"' ){
2297 int delim = zLine[i++];
2298 azArg[nArg++] = &zLine[i];
2299 while( zLine[i] && zLine[i]!=delim ){ i++; }
2300 if( zLine[i]==delim ){
2301 zLine[i++] = 0;
2302 }
drhfeac5f82004-08-01 00:10:45 +00002303 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002304 }else{
2305 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00002306 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002307 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002308 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002309 }
2310 }
2311
2312 /* Process the input line.
2313 */
shane9bd1b442009-10-23 01:27:39 +00002314 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002315 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002316 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00002317 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002318 const char *zDestFile;
2319 const char *zDb;
2320 sqlite3 *pDest;
2321 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00002322 if( nArg==2 ){
2323 zDestFile = azArg[1];
2324 zDb = "main";
2325 }else{
2326 zDestFile = azArg[2];
2327 zDb = azArg[1];
2328 }
2329 rc = sqlite3_open(zDestFile, &pDest);
2330 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002331 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002332 sqlite3_close(pDest);
2333 return 1;
2334 }
drhdc2c4912009-02-04 22:46:47 +00002335 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002336 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2337 if( pBackup==0 ){
2338 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2339 sqlite3_close(pDest);
2340 return 1;
2341 }
2342 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2343 sqlite3_backup_finish(pBackup);
2344 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002345 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002346 }else{
2347 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002348 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002349 }
2350 sqlite3_close(pDest);
2351 }else
2352
shanehe2aa9d72009-11-06 17:20:17 +00002353 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00002354 bail_on_error = booleanValue(azArg[1]);
2355 }else
2356
shanehe2aa9d72009-11-06 17:20:17 +00002357 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00002358 struct callback_data data;
2359 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00002360 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00002361 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002362 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002363 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002364 data.colWidth[0] = 3;
2365 data.colWidth[1] = 15;
2366 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002367 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002368 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002369 if( zErrMsg ){
2370 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002371 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002372 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002373 }
2374 }else
2375
shanehe2aa9d72009-11-06 17:20:17 +00002376 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh4c653a02000-06-07 01:27:47 +00002377 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002378 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00002379 /* When playing back a "dump", the content might appear in an order
2380 ** which causes immediate foreign key constraints to be violated.
2381 ** So disable foreign-key constraint enforcement to prevent problems. */
2382 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002383 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002384 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00002385 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002386 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002387 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002388 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00002389 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
2390 );
2391 run_schema_dump_query(p,
2392 "SELECT name, type, sql FROM sqlite_master "
2393 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00002394 );
2395 run_table_dump_query(p->out, p->db,
2396 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002397 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002398 );
drh4c653a02000-06-07 01:27:47 +00002399 }else{
2400 int i;
drhdd3d4592004-08-30 01:54:05 +00002401 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002402 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002403 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002404 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002405 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00002406 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00002407 run_table_dump_query(p->out, p->db,
2408 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002409 "WHERE sql NOT NULL"
2410 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002411 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002412 );
danielk1977bc6ada42004-06-30 08:20:16 +00002413 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002414 }
2415 }
drh45e29d82006-11-20 16:21:10 +00002416 if( p->writableSchema ){
2417 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
2418 p->writableSchema = 0;
2419 }
drh93f41e52008-08-11 19:12:34 +00002420 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002421 if( zErrMsg ){
2422 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002423 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00002424 }else{
2425 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002426 }
2427 }else
drh75897232000-05-29 14:26:00 +00002428
shanehe2aa9d72009-11-06 17:20:17 +00002429 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00002430 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00002431 }else
2432
shanehe2aa9d72009-11-06 17:20:17 +00002433 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002434 rc = 2;
drh75897232000-05-29 14:26:00 +00002435 }else
2436
shanehe2aa9d72009-11-06 17:20:17 +00002437 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00002438 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002439 if(val == 1) {
2440 if(!p->explainPrev.valid) {
2441 p->explainPrev.valid = 1;
2442 p->explainPrev.mode = p->mode;
2443 p->explainPrev.showHeader = p->showHeader;
2444 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
2445 }
2446 /* We could put this code under the !p->explainValid
2447 ** condition so that it does not execute if we are already in
2448 ** explain mode. However, always executing it allows us an easy
2449 ** was to reset to explain mode in case the user previously
2450 ** did an .explain followed by a .width, .mode or .header
2451 ** command.
2452 */
danielk19770d78bae2008-01-03 07:09:48 +00002453 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002454 p->showHeader = 1;
2455 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002456 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002457 p->colWidth[1] = 13; /* opcode */
2458 p->colWidth[2] = 4; /* P1 */
2459 p->colWidth[3] = 4; /* P2 */
2460 p->colWidth[4] = 4; /* P3 */
2461 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002462 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002463 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00002464 }else if (p->explainPrev.valid) {
2465 p->explainPrev.valid = 0;
2466 p->mode = p->explainPrev.mode;
2467 p->showHeader = p->explainPrev.showHeader;
2468 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2469 }
drh75897232000-05-29 14:26:00 +00002470 }else
2471
danielk1977c8c70692009-02-25 15:22:02 +00002472#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
2473 if( c=='g' && strncmp(azArg[0], "genfkey", n)==0 ){
2474 GenfkeyCmd cmd;
2475 if( 0==genfkeyParseArgs(&cmd, &azArg[1], nArg-1) ){
2476 cmd.db = p->db;
2477 cmd.pCb = p;
2478 genfkey_create_triggers(p->db, "main", (void *)&cmd, genfkeyCmdCb);
2479 }
2480 }else
2481#endif
2482
drhc28490c2006-10-26 14:25:58 +00002483 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00002484 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00002485 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00002486 }else
2487
2488 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00002489 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00002490 if( HAS_TIMER ){
2491 fprintf(stderr,"%s",zTimerHelp);
2492 }
drh75897232000-05-29 14:26:00 +00002493 }else
2494
shanehe2aa9d72009-11-06 17:20:17 +00002495 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00002496 char *zTable = azArg[2]; /* Insert data into this table */
2497 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00002498 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002499 int nCol; /* Number of columns in the table */
2500 int nByte; /* Number of bytes in an SQL string */
2501 int i, j; /* Loop counters */
2502 int nSep; /* Number of bytes in p->separator[] */
2503 char *zSql; /* An SQL statement */
2504 char *zLine; /* A single line of input from the file */
2505 char **azCol; /* zLine[] broken up into columns */
2506 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00002507 FILE *in; /* The input file */
2508 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00002509
drha543c822006-06-08 16:10:14 +00002510 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002511 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002512 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00002513 fprintf(stderr, "Error: non-null separator required for import\n");
2514 return 1;
drhfeac5f82004-08-01 00:10:45 +00002515 }
2516 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
shane916f9612009-10-23 00:37:15 +00002517 if( zSql==0 ){
2518 fprintf(stderr, "Error: out of memory\n");
2519 return 1;
2520 }
drh4f21c4a2008-12-10 22:15:00 +00002521 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002522 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002523 sqlite3_free(zSql);
2524 if( rc ){
shane916f9612009-10-23 00:37:15 +00002525 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002526 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002527 return 1;
drhfeac5f82004-08-01 00:10:45 +00002528 }
shane916f9612009-10-23 00:37:15 +00002529 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002530 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002531 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002532 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00002533 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002534 if( zSql==0 ){
2535 fprintf(stderr, "Error: out of memory\n");
2536 return 1;
2537 }
drhfeac5f82004-08-01 00:10:45 +00002538 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002539 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002540 for(i=1; i<nCol; i++){
2541 zSql[j++] = ',';
2542 zSql[j++] = '?';
2543 }
2544 zSql[j++] = ')';
2545 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002546 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002547 free(zSql);
2548 if( rc ){
2549 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002550 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00002551 return 1;
drhfeac5f82004-08-01 00:10:45 +00002552 }
2553 in = fopen(zFile, "rb");
2554 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00002555 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00002556 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002557 return 1;
drhfeac5f82004-08-01 00:10:45 +00002558 }
2559 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00002560 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00002561 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00002562 fclose(in);
shane916f9612009-10-23 00:37:15 +00002563 sqlite3_finalize(pStmt);
2564 return 1;
drh43617e92006-03-06 20:55:46 +00002565 }
drhfeac5f82004-08-01 00:10:45 +00002566 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
2567 zCommit = "COMMIT";
2568 while( (zLine = local_getline(0, in))!=0 ){
2569 char *z;
2570 i = 0;
drhb860bc92004-08-04 15:16:55 +00002571 lineno++;
drhfeac5f82004-08-01 00:10:45 +00002572 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00002573 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00002574 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
2575 *z = 0;
2576 i++;
drhb860bc92004-08-04 15:16:55 +00002577 if( i<nCol ){
2578 azCol[i] = &z[nSep];
2579 z += nSep-1;
2580 }
drhfeac5f82004-08-01 00:10:45 +00002581 }
shane916f9612009-10-23 00:37:15 +00002582 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00002583 *z = 0;
drhb860bc92004-08-04 15:16:55 +00002584 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00002585 fprintf(stderr,
2586 "Error: %s line %d: expected %d columns of data but found %d\n",
2587 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00002588 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00002589 free(zLine);
shane916f9612009-10-23 00:37:15 +00002590 rc = 1;
2591 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00002592 }
drhfeac5f82004-08-01 00:10:45 +00002593 for(i=0; i<nCol; i++){
2594 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2595 }
2596 sqlite3_step(pStmt);
2597 rc = sqlite3_reset(pStmt);
2598 free(zLine);
2599 if( rc!=SQLITE_OK ){
2600 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2601 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00002602 rc = 1;
shane916f9612009-10-23 00:37:15 +00002603 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00002604 }
shane916f9612009-10-23 00:37:15 +00002605 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00002606 free(azCol);
2607 fclose(in);
2608 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00002609 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002610 }else
2611
shanehe2aa9d72009-11-06 17:20:17 +00002612 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002613 struct callback_data data;
2614 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002615 open_db(p);
drh75897232000-05-29 14:26:00 +00002616 memcpy(&data, p, sizeof(data));
2617 data.showHeader = 0;
2618 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002619 if( nArg==1 ){
2620 rc = sqlite3_exec(p->db,
2621 "SELECT name FROM sqlite_master "
2622 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2623 "UNION ALL "
2624 "SELECT name FROM sqlite_temp_master "
2625 "WHERE type='index' "
2626 "ORDER BY 1",
2627 callback, &data, &zErrMsg
2628 );
2629 }else{
2630 zShellStatic = azArg[1];
2631 rc = sqlite3_exec(p->db,
2632 "SELECT name FROM sqlite_master "
2633 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2634 "UNION ALL "
2635 "SELECT name FROM sqlite_temp_master "
2636 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2637 "ORDER BY 1",
2638 callback, &data, &zErrMsg
2639 );
2640 zShellStatic = 0;
2641 }
drh75897232000-05-29 14:26:00 +00002642 if( zErrMsg ){
2643 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002644 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002645 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002646 }else if( rc != SQLITE_OK ){
2647 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2648 rc = 1;
drh75897232000-05-29 14:26:00 +00002649 }
2650 }else
2651
drhae5e4452007-05-03 17:18:36 +00002652#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002653 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002654 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002655 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2656 iotrace = 0;
2657 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002658 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002659 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002660 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002661 iotrace = stdout;
2662 }else{
2663 iotrace = fopen(azArg[1], "w");
2664 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002665 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002666 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002667 rc = 1;
drhb0603412007-02-28 04:47:26 +00002668 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002669 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002670 }
2671 }
2672 }else
drhae5e4452007-05-03 17:18:36 +00002673#endif
drhb0603412007-02-28 04:47:26 +00002674
drh70df4fe2006-06-13 15:12:21 +00002675#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002676 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2677 const char *zFile, *zProc;
2678 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00002679 zFile = azArg[1];
2680 zProc = nArg>=3 ? azArg[2] : 0;
2681 open_db(p);
2682 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2683 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002684 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002685 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002686 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002687 }
2688 }else
drh70df4fe2006-06-13 15:12:21 +00002689#endif
drh1e397f82006-06-08 15:28:43 +00002690
shanehe2aa9d72009-11-06 17:20:17 +00002691 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00002692 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002693 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002694 ||
shanehe2aa9d72009-11-06 17:20:17 +00002695 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002696 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002697 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002698 ||
shanehe2aa9d72009-11-06 17:20:17 +00002699 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002700 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002701 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002702 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002703 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002704 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002705 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002706 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00002707 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002708 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002709 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002710 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002711 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002712 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002713 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002714 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002715 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002716 }else {
shane9bd1b442009-10-23 01:27:39 +00002717 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002718 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002719 rc = 1;
drh75897232000-05-29 14:26:00 +00002720 }
2721 }else
2722
shanehe2aa9d72009-11-06 17:20:17 +00002723 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2724 int n2 = strlen30(azArg[1]);
2725 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2726 p->mode = MODE_Insert;
2727 set_table_name(p, azArg[2]);
2728 }else {
2729 fprintf(stderr, "Error: invalid arguments: "
2730 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2731 rc = 1;
2732 }
2733 }else
2734
persicom7e2dfdd2002-04-18 02:46:52 +00002735 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002736 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2737 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002738 }else
2739
drh75897232000-05-29 14:26:00 +00002740 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
2741 if( p->out!=stdout ){
2742 fclose(p->out);
2743 }
2744 if( strcmp(azArg[1],"stdout")==0 ){
2745 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00002746 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00002747 }else{
drha1f9b5e2004-02-14 16:31:02 +00002748 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00002749 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00002750 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00002751 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002752 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002753 } else {
drh5bb3eb92007-05-04 13:15:55 +00002754 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002755 }
2756 }
2757 }else
2758
drhdd45df82002-04-18 12:39:03 +00002759 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002760 if( nArg >= 2) {
2761 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2762 }
2763 if( nArg >= 3) {
2764 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2765 }
2766 }else
2767
shanehe2aa9d72009-11-06 17:20:17 +00002768 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002769 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002770 }else
2771
drh9ff849f2009-02-04 20:55:57 +00002772 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002773 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002774 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002775 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2776 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002777 }else{
shane9bd1b442009-10-23 01:27:39 +00002778 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002779 fclose(alt);
2780 }
2781 }else
2782
shanehe2aa9d72009-11-06 17:20:17 +00002783 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002784 const char *zSrcFile;
2785 const char *zDb;
2786 sqlite3 *pSrc;
2787 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002788 int nTimeout = 0;
2789
drh9ff849f2009-02-04 20:55:57 +00002790 if( nArg==2 ){
2791 zSrcFile = azArg[1];
2792 zDb = "main";
2793 }else{
2794 zSrcFile = azArg[2];
2795 zDb = azArg[1];
2796 }
2797 rc = sqlite3_open(zSrcFile, &pSrc);
2798 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002799 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002800 sqlite3_close(pSrc);
2801 return 1;
2802 }
drhdc2c4912009-02-04 22:46:47 +00002803 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002804 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2805 if( pBackup==0 ){
2806 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2807 sqlite3_close(pSrc);
2808 return 1;
2809 }
drhdc2c4912009-02-04 22:46:47 +00002810 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2811 || rc==SQLITE_BUSY ){
2812 if( rc==SQLITE_BUSY ){
2813 if( nTimeout++ >= 3 ) break;
2814 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002815 }
2816 }
2817 sqlite3_backup_finish(pBackup);
2818 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002819 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002820 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002821 fprintf(stderr, "Error: source database is busy\n");
2822 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002823 }else{
2824 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002825 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002826 }
2827 sqlite3_close(pSrc);
2828 }else
2829
shanehe2aa9d72009-11-06 17:20:17 +00002830 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002831 struct callback_data data;
2832 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002833 open_db(p);
drh75897232000-05-29 14:26:00 +00002834 memcpy(&data, p, sizeof(data));
2835 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002836 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002837 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002838 int i;
shane7d3846a2008-12-11 02:58:26 +00002839 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002840 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002841 char *new_argv[2], *new_colv[2];
2842 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2843 " type text,\n"
2844 " name text,\n"
2845 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002846 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002847 " sql text\n"
2848 ")";
2849 new_argv[1] = 0;
2850 new_colv[0] = "sql";
2851 new_colv[1] = 0;
2852 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002853 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002854 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002855 char *new_argv[2], *new_colv[2];
2856 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2857 " type text,\n"
2858 " name text,\n"
2859 " tbl_name text,\n"
2860 " rootpage integer,\n"
2861 " sql text\n"
2862 ")";
2863 new_argv[1] = 0;
2864 new_colv[0] = "sql";
2865 new_colv[1] = 0;
2866 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002867 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002868 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002869 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002870 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002871 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002872 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2873 " FROM sqlite_master UNION ALL"
2874 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002875 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002876 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002877 callback, &data, &zErrMsg);
2878 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002879 }
drh75897232000-05-29 14:26:00 +00002880 }else{
shane9bd1b442009-10-23 01:27:39 +00002881 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002882 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002883 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2884 " FROM sqlite_master UNION ALL"
2885 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002886 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002887 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002888 callback, &data, &zErrMsg
2889 );
drh75897232000-05-29 14:26:00 +00002890 }
drh75897232000-05-29 14:26:00 +00002891 if( zErrMsg ){
2892 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002893 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002894 rc = 1;
2895 }else if( rc != SQLITE_OK ){
2896 fprintf(stderr,"Error: querying schema information\n");
2897 rc = 1;
2898 }else{
2899 rc = 0;
drh75897232000-05-29 14:26:00 +00002900 }
2901 }else
2902
2903 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002904 sqlite3_snprintf(sizeof(p->separator), p->separator,
2905 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002906 }else
2907
shanehe2aa9d72009-11-06 17:20:17 +00002908 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002909 int i;
2910 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002911 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002912 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002913 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002914 fprintf(p->out,"%9.9s: ", "nullvalue");
2915 output_c_string(p->out, p->nullvalue);
2916 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002917 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002918 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002919 fprintf(p->out,"%9.9s: ", "separator");
2920 output_c_string(p->out, p->separator);
2921 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002922 fprintf(p->out,"%9.9s: ","width");
2923 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002924 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002925 }
drhfeac5f82004-08-01 00:10:45 +00002926 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002927 }else
2928
shanehe2aa9d72009-11-06 17:20:17 +00002929 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002930 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002931 int nRow;
drhe3710332000-09-29 13:30:53 +00002932 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002933 open_db(p);
drha50da102000-08-08 20:19:09 +00002934 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002935 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002936 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002937 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002938 "UNION ALL "
2939 "SELECT name FROM sqlite_temp_master "
2940 "WHERE type IN ('table','view') "
2941 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002942 &azResult, &nRow, 0, &zErrMsg
2943 );
drha50da102000-08-08 20:19:09 +00002944 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002945 zShellStatic = azArg[1];
2946 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002947 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002948 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002949 "UNION ALL "
2950 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002951 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002952 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002953 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002954 );
danielk1977bc6ada42004-06-30 08:20:16 +00002955 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002956 }
drh75897232000-05-29 14:26:00 +00002957 if( zErrMsg ){
2958 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002959 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002960 rc = 1;
2961 }else if( rc != SQLITE_OK ){
2962 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2963 rc = 1;
2964 }else{
drhe3710332000-09-29 13:30:53 +00002965 int len, maxlen = 0;
2966 int i, j;
2967 int nPrintCol, nPrintRow;
2968 for(i=1; i<=nRow; i++){
2969 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002970 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002971 if( len>maxlen ) maxlen = len;
2972 }
2973 nPrintCol = 80/(maxlen+2);
2974 if( nPrintCol<1 ) nPrintCol = 1;
2975 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2976 for(i=0; i<nPrintRow; i++){
2977 for(j=i+1; j<=nRow; j+=nPrintRow){
2978 char *zSp = j<=nPrintRow ? "" : " ";
2979 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2980 }
2981 printf("\n");
2982 }
2983 }
danielk19776f8a5032004-05-10 10:34:51 +00002984 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002985 }else
2986
shanehe2aa9d72009-11-06 17:20:17 +00002987 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002988 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002989 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002990 }else
2991
2992 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
drh3b1a9882007-11-02 12:53:03 +00002993 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002994 }else
2995
2996 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002997 int j;
drh43617e92006-03-06 20:55:46 +00002998 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002999 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
3000 p->colWidth[j-1] = atoi(azArg[j]);
3001 }
3002 }else
3003
3004 {
shane9bd1b442009-10-23 01:27:39 +00003005 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003006 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003007 rc = 1;
drh75897232000-05-29 14:26:00 +00003008 }
drh67505e72002-04-19 12:34:06 +00003009
3010 return rc;
drh75897232000-05-29 14:26:00 +00003011}
3012
drh67505e72002-04-19 12:34:06 +00003013/*
drh91a66392007-09-07 01:12:32 +00003014** Return TRUE if a semicolon occurs anywhere in the first N characters
3015** of string z[].
drh324ccef2003-02-05 14:06:20 +00003016*/
drh91a66392007-09-07 01:12:32 +00003017static int _contains_semicolon(const char *z, int N){
3018 int i;
3019 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3020 return 0;
drh324ccef2003-02-05 14:06:20 +00003021}
3022
3023/*
drh70c7a4b2003-04-26 03:03:06 +00003024** Test to see if a line consists entirely of whitespace.
3025*/
3026static int _all_whitespace(const char *z){
3027 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00003028 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003029 if( *z=='/' && z[1]=='*' ){
3030 z += 2;
3031 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3032 if( *z==0 ) return 0;
3033 z++;
3034 continue;
3035 }
3036 if( *z=='-' && z[1]=='-' ){
3037 z += 2;
3038 while( *z && *z!='\n' ){ z++; }
3039 if( *z==0 ) return 1;
3040 continue;
3041 }
3042 return 0;
3043 }
3044 return 1;
3045}
3046
3047/*
drha9b17162003-04-29 18:01:28 +00003048** Return TRUE if the line typed in is an SQL command terminator other
3049** than a semi-colon. The SQL Server style "go" command is understood
3050** as is the Oracle "/".
3051*/
3052static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00003053 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00003054 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3055 return 1; /* Oracle */
3056 }
drhc8d74412004-08-31 23:41:26 +00003057 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
3058 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00003059 return 1; /* SQL Server */
3060 }
3061 return 0;
3062}
3063
3064/*
drh233a5312008-12-18 22:25:13 +00003065** Return true if zSql is a complete SQL statement. Return false if it
3066** ends in the middle of a string literal or C-style comment.
3067*/
3068static int _is_complete(char *zSql, int nSql){
3069 int rc;
3070 if( zSql==0 ) return 1;
3071 zSql[nSql] = ';';
3072 zSql[nSql+1] = 0;
3073 rc = sqlite3_complete(zSql);
3074 zSql[nSql] = 0;
3075 return rc;
3076}
3077
3078/*
drh67505e72002-04-19 12:34:06 +00003079** Read input from *in and process it. If *in==0 then input
3080** is interactive - the user is typing it it. Otherwise, input
3081** is coming from a file or device. A prompt is issued and history
3082** is saved only if input is interactive. An interrupt signal will
3083** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00003084**
3085** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00003086*/
drhc28490c2006-10-26 14:25:58 +00003087static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00003088 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00003089 char *zSql = 0;
3090 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00003091 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00003092 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00003093 int rc;
3094 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00003095 int lineno = 0;
3096 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00003097
3098 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
3099 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00003100 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00003101 zLine = one_input_line(zSql, in);
3102 if( zLine==0 ){
3103 break; /* We have reached EOF */
3104 }
drh67505e72002-04-19 12:34:06 +00003105 if( seenInterrupt ){
3106 if( in!=0 ) break;
3107 seenInterrupt = 0;
3108 }
drhc28490c2006-10-26 14:25:58 +00003109 lineno++;
drhf817b6b2003-06-16 00:16:41 +00003110 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00003111 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00003112 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00003113 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00003114 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00003115 break;
3116 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00003117 errCnt++;
3118 }
drhdaffd0e2001-04-11 14:28:42 +00003119 continue;
3120 }
drh233a5312008-12-18 22:25:13 +00003121 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00003122 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00003123 }
drh91a66392007-09-07 01:12:32 +00003124 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00003125 if( zSql==0 ){
3126 int i;
drh4c755c02004-08-08 20:22:17 +00003127 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00003128 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00003129 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00003130 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00003131 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00003132 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00003133 exit(1);
3134 }
drh5bb3eb92007-05-04 13:15:55 +00003135 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00003136 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00003137 }
3138 }else{
drh4f21c4a2008-12-10 22:15:00 +00003139 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00003140 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00003141 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00003142 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00003143 exit(1);
3144 }
drh5bb3eb92007-05-04 13:15:55 +00003145 zSql[nSql++] = '\n';
3146 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00003147 nSql += len;
3148 }
drh91a66392007-09-07 01:12:32 +00003149 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
3150 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00003151 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00003152 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00003153 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00003154 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00003155 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00003156 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00003157 char zPrefix[100];
3158 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00003159 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00003160 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00003161 }else{
shane9bd1b442009-10-23 01:27:39 +00003162 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00003163 }
drh7f953e22002-07-13 17:33:45 +00003164 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00003165 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003166 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00003167 zErrMsg = 0;
3168 }else{
shaned2bed1c2009-10-21 03:56:54 +00003169 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00003170 }
drhc49f44e2006-10-26 18:15:42 +00003171 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00003172 }
3173 free(zSql);
3174 zSql = 0;
3175 nSql = 0;
3176 }
3177 }
3178 if( zSql ){
shane86f5bdb2009-10-24 02:00:07 +00003179 if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00003180 free(zSql);
3181 }
danielk19772ac27622007-07-03 05:31:16 +00003182 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00003183 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00003184}
3185
drh67505e72002-04-19 12:34:06 +00003186/*
3187** Return a pathname which is the user's home directory. A
3188** 0 return indicates an error of some kind. Space to hold the
3189** resulting string is obtained from malloc(). The calling
3190** function should free the result.
3191*/
3192static char *find_home_dir(void){
3193 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00003194
chw97185482008-11-17 08:05:31 +00003195#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00003196 struct passwd *pwent;
3197 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00003198 if( (pwent=getpwuid(uid)) != NULL) {
3199 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00003200 }
3201#endif
3202
chw65d3c132007-11-12 21:09:10 +00003203#if defined(_WIN32_WCE)
3204 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
3205 */
3206 home_dir = strdup("/");
3207#else
3208
drh164a1b62006-08-19 11:15:20 +00003209#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
3210 if (!home_dir) {
3211 home_dir = getenv("USERPROFILE");
3212 }
3213#endif
3214
drh67505e72002-04-19 12:34:06 +00003215 if (!home_dir) {
3216 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00003217 }
3218
drhcdb36b72006-06-12 12:57:45 +00003219#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00003220 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00003221 char *zDrive, *zPath;
3222 int n;
3223 zDrive = getenv("HOMEDRIVE");
3224 zPath = getenv("HOMEPATH");
3225 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00003226 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00003227 home_dir = malloc( n );
3228 if( home_dir==0 ) return 0;
3229 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3230 return home_dir;
3231 }
3232 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00003233 }
3234#endif
3235
chw65d3c132007-11-12 21:09:10 +00003236#endif /* !_WIN32_WCE */
3237
drh67505e72002-04-19 12:34:06 +00003238 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00003239 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00003240 char *z = malloc( n );
3241 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00003242 home_dir = z;
3243 }
drhe98d4fa2002-04-21 19:06:22 +00003244
drh67505e72002-04-19 12:34:06 +00003245 return home_dir;
3246}
3247
3248/*
3249** Read input from the file given by sqliterc_override. Or if that
3250** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00003251**
3252** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00003253*/
shane9bd1b442009-10-23 01:27:39 +00003254static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00003255 struct callback_data *p, /* Configuration data */
3256 const char *sqliterc_override /* Name of config file. NULL to use default */
3257){
persicom7e2dfdd2002-04-18 02:46:52 +00003258 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00003259 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00003260 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003261 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00003262 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00003263 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003264
3265 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00003266 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00003267 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00003268#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00003269 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00003270#endif
shane9bd1b442009-10-23 01:27:39 +00003271 return 1;
drhe98d4fa2002-04-21 19:06:22 +00003272 }
drh4f21c4a2008-12-10 22:15:00 +00003273 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00003274 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00003275 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00003276 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
3277 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003278 }
drha959ac42007-06-20 13:10:00 +00003279 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00003280 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00003281 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003282 }
drha1f9b5e2004-02-14 16:31:02 +00003283 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00003284 if( in ){
drhc28490c2006-10-26 14:25:58 +00003285 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00003286 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00003287 }
shane9bd1b442009-10-23 01:27:39 +00003288 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00003289 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00003290 }
drh43617e92006-03-06 20:55:46 +00003291 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00003292 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00003293}
3294
drh67505e72002-04-19 12:34:06 +00003295/*
drhe1e38c42003-05-04 18:30:59 +00003296** Show available command line options
3297*/
3298static const char zOptions[] =
3299 " -init filename read/process named file\n"
3300 " -echo print commands before execution\n"
3301 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00003302 " -bail stop after hitting an error\n"
3303 " -interactive force interactive I/O\n"
3304 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003305 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00003306 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00003307 " -html set output mode to HTML\n"
3308 " -line set output mode to 'line'\n"
3309 " -list set output mode to 'list'\n"
3310 " -separator 'x' set output field separator (|)\n"
3311 " -nullvalue 'text' set text string for NULL values\n"
3312 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00003313;
3314static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00003315 fprintf(stderr,
3316 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3317 "FILENAME is the name of an SQLite database. A new database is created\n"
3318 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00003319 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00003320 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00003321 }else{
3322 fprintf(stderr, "Use the -help option for additional information\n");
3323 }
3324 exit(1);
3325}
3326
3327/*
drh67505e72002-04-19 12:34:06 +00003328** Initialize the state information in data
3329*/
drh0850b532006-01-31 19:31:43 +00003330static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00003331 memset(data, 0, sizeof(*data));
3332 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00003333 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00003334 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00003335 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3336 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00003337}
3338
drh75897232000-05-29 14:26:00 +00003339int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003340 char *zErrMsg = 0;
3341 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00003342 const char *zInitFile = 0;
3343 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003344 int i;
drhc28490c2006-10-26 14:25:58 +00003345 int rc = 0;
drh75897232000-05-29 14:26:00 +00003346
drhdaffd0e2001-04-11 14:28:42 +00003347 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003348 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003349 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003350
drh44c2eb12003-04-30 11:38:26 +00003351 /* Make sure we have a valid signal handler early, before anything
3352 ** else is done.
3353 */
drh4c504392000-10-16 22:06:40 +00003354#ifdef SIGINT
3355 signal(SIGINT, interrupt_handler);
3356#endif
drh44c2eb12003-04-30 11:38:26 +00003357
drh22fbcb82004-02-01 01:22:50 +00003358 /* Do an initial pass through the command-line argument to locate
3359 ** the name of the database file, the name of the initialization file,
3360 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003361 */
drh22fbcb82004-02-01 01:22:50 +00003362 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00003363 char *z;
drh44c2eb12003-04-30 11:38:26 +00003364 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00003365 z = argv[i];
3366 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00003367 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
3368 i++;
drh22fbcb82004-02-01 01:22:50 +00003369 }else if( strcmp(argv[i],"-init")==0 ){
3370 i++;
3371 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00003372 /* Need to check for batch mode here to so we can avoid printing
3373 ** informational messages (like from process_sqliterc) before
3374 ** we do the actual processing of arguments later in a second pass.
3375 */
3376 }else if( strcmp(argv[i],"-batch")==0 ){
3377 i++;
3378 stdin_is_interactive = 0;
drh44c2eb12003-04-30 11:38:26 +00003379 }
3380 }
drh22fbcb82004-02-01 01:22:50 +00003381 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00003382#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00003383 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
3384#else
drh22fbcb82004-02-01 01:22:50 +00003385 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00003386#endif
drh22fbcb82004-02-01 01:22:50 +00003387 }else{
danielk197703aded42004-11-22 05:26:27 +00003388#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003389 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003390#else
3391 data.zDbFilename = 0;
3392#endif
drh22fbcb82004-02-01 01:22:50 +00003393 }
3394 if( i<argc ){
3395 zFirstCmd = argv[i++];
3396 }
drh44c2eb12003-04-30 11:38:26 +00003397 data.out = stdout;
3398
drh01b41712005-08-29 23:06:23 +00003399#ifdef SQLITE_OMIT_MEMORYDB
3400 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00003401 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3402 return 1;
drh01b41712005-08-29 23:06:23 +00003403 }
3404#endif
3405
drh44c2eb12003-04-30 11:38:26 +00003406 /* Go ahead and open the database file if it already exists. If the
3407 ** file does not exist, delay opening it. This prevents empty database
3408 ** files from being created if a user mistypes the database name argument
3409 ** to the sqlite command-line tool.
3410 */
drhc8d74412004-08-31 23:41:26 +00003411 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003412 open_db(&data);
3413 }
3414
drh22fbcb82004-02-01 01:22:50 +00003415 /* Process the initialization file if there is one. If no -init option
3416 ** is given on the command line, look for a file named ~/.sqliterc and
3417 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003418 */
shane86f5bdb2009-10-24 02:00:07 +00003419 rc = process_sqliterc(&data,zInitFile);
3420 if( rc>0 ){
3421 return rc;
3422 }
drh44c2eb12003-04-30 11:38:26 +00003423
drh22fbcb82004-02-01 01:22:50 +00003424 /* Make a second pass through the command-line argument and set
3425 ** options. This second pass is delayed until after the initialization
3426 ** file is processed so that the command-line arguments will override
3427 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003428 */
drh22fbcb82004-02-01 01:22:50 +00003429 for(i=1; i<argc && argv[i][0]=='-'; i++){
3430 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00003431 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003432 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003433 i++;
3434 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003435 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003436 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003437 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003438 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003439 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003440 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003441 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003442 }else if( strcmp(z,"-csv")==0 ){
3443 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003444 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003445 }else if( strcmp(z,"-separator")==0 ){
3446 i++;
drh5bb3eb92007-05-04 13:15:55 +00003447 sqlite3_snprintf(sizeof(data.separator), data.separator,
3448 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003449 }else if( strcmp(z,"-nullvalue")==0 ){
3450 i++;
drh5bb3eb92007-05-04 13:15:55 +00003451 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
3452 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003453 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003454 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003455 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003456 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003457 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003458 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003459 }else if( strcmp(z,"-bail")==0 ){
3460 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003461 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00003462 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00003463 return 0;
drhc28490c2006-10-26 14:25:58 +00003464 }else if( strcmp(z,"-interactive")==0 ){
3465 stdin_is_interactive = 1;
3466 }else if( strcmp(z,"-batch")==0 ){
3467 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00003468 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003469 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00003470 }else{
shane86f5bdb2009-10-24 02:00:07 +00003471 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003472 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003473 return 1;
3474 }
3475 }
drh44c2eb12003-04-30 11:38:26 +00003476
drh22fbcb82004-02-01 01:22:50 +00003477 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003478 /* Run just the command that follows the database name
3479 */
drh22fbcb82004-02-01 01:22:50 +00003480 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003481 rc = do_meta_command(zFirstCmd, &data);
shane86f5bdb2009-10-24 02:00:07 +00003482 return rc;
drh6ff13852001-11-25 13:18:23 +00003483 }else{
drh44c2eb12003-04-30 11:38:26 +00003484 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003485 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003486 if( zErrMsg!=0 ){
3487 fprintf(stderr,"Error: %s\n", zErrMsg);
3488 return rc!=0 ? rc : 1;
3489 }else if( rc!=0 ){
3490 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3491 return rc;
drh6ff13852001-11-25 13:18:23 +00003492 }
drh75897232000-05-29 14:26:00 +00003493 }
3494 }else{
drh44c2eb12003-04-30 11:38:26 +00003495 /* Run commands received from standard input
3496 */
drhc28490c2006-10-26 14:25:58 +00003497 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003498 char *zHome;
3499 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003500 int nHistory;
drh75897232000-05-29 14:26:00 +00003501 printf(
drhb217a572000-08-22 13:40:18 +00003502 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00003503 "Enter \".help\" for instructions\n"
3504 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00003505 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00003506 );
drh67505e72002-04-19 12:34:06 +00003507 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003508 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003509 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003510 if( (zHistory = malloc(nHistory))!=0 ){
3511 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3512 }
drh67505e72002-04-19 12:34:06 +00003513 }
danielk19774af00c62005-01-23 23:43:21 +00003514#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003515 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003516#endif
drhc28490c2006-10-26 14:25:58 +00003517 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003518 if( zHistory ){
3519 stifle_history(100);
3520 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003521 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003522 }
adamd0a3daa32006-07-28 20:16:14 +00003523 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00003524 }else{
drhc28490c2006-10-26 14:25:58 +00003525 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003526 }
3527 }
drh33048c02001-10-01 14:29:22 +00003528 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00003529 if( db ){
3530 if( sqlite3_close(db)!=SQLITE_OK ){
shane86f5bdb2009-10-24 02:00:07 +00003531 fprintf(stderr,"Error: cannot close database \"%s\"\n", sqlite3_errmsg(db));
3532 rc++;
adamd0a3daa32006-07-28 20:16:14 +00003533 }
3534 }
drhc28490c2006-10-26 14:25:58 +00003535 return rc;
drh75897232000-05-29 14:26:00 +00003536}