blob: 64d286cde022f8a55302b45cf7c2a280e8df7bf3 [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**
shanec0688ea2009-03-05 03:48:06 +000015** $Id: shell.c,v 1.205 2009/03/05 03:48:07 shane 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}
109#define BEGIN_TIMER beginTimer()
110#define END_TIMER endTimer()
111#define HAS_TIMER 1
112#else
113#define BEGIN_TIMER
114#define END_TIMER
115#define HAS_TIMER 0
116#endif
117
shanec0688ea2009-03-05 03:48:06 +0000118/*
119** Used to prevent warnings about unused parameters
120*/
121#define UNUSED_PARAMETER(x) (void)(x)
122
danielk1977c8c70692009-02-25 15:22:02 +0000123
124/**************************************************************************
125***************************************************************************
126** Begin genfkey logic.
127*/
128#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined SQLITE_OMIT_SUBQUERY
129
130#define GENFKEY_ERROR 1
131#define GENFKEY_DROPTRIGGER 2
132#define GENFKEY_CREATETRIGGER 3
133static int genfkey_create_triggers(sqlite3 *, const char *, void *,
134 int (*)(void *, int, const char *)
135);
136
137struct GenfkeyCb {
138 void *pCtx;
139 int eType;
140 int (*xData)(void *, int, const char *);
141};
142typedef struct GenfkeyCb GenfkeyCb;
143
144/* The code in this file defines a sqlite3 virtual-table module that
145** provides a read-only view of the current database schema. There is one
146** row in the schema table for each column in the database schema.
147*/
148#define SCHEMA \
149"CREATE TABLE x(" \
150 "database," /* Name of database (i.e. main, temp etc.) */ \
151 "tablename," /* Name of table */ \
152 "cid," /* Column number (from left-to-right, 0 upward) */ \
153 "name," /* Column name */ \
154 "type," /* Specified type (i.e. VARCHAR(32)) */ \
155 "not_null," /* Boolean. True if NOT NULL was specified */ \
156 "dflt_value," /* Default value for this column */ \
157 "pk" /* True if this column is part of the primary key */ \
158")"
159
160#define SCHEMA2 \
161"CREATE TABLE x(" \
162 "database," /* Name of database (i.e. main, temp etc.) */ \
163 "from_tbl," /* Name of table */ \
164 "fkid," \
165 "seq," \
166 "to_tbl," \
167 "from_col," \
168 "to_col," \
169 "on_update," \
170 "on_delete," \
171 "match" \
172")"
173
174#define SCHEMA3 \
175"CREATE TABLE x(" \
176 "database," /* Name of database (i.e. main, temp etc.) */ \
177 "tablename," /* Name of table */ \
178 "seq," \
179 "name," \
180 "isunique" \
181")"
182
183#define SCHEMA4 \
184"CREATE TABLE x(" \
185 "database," /* Name of database (i.e. main, temp etc.) */ \
186 "indexname," /* Name of table */ \
187 "seqno," \
188 "cid," \
189 "name" \
190")"
191
192#define SCHEMA5 \
193"CREATE TABLE x(" \
194 "database," /* Name of database (i.e. main, temp etc.) */ \
195 "triggername," /* Name of trigger */ \
196 "dummy" /* Unused */ \
197")"
198
199typedef struct SchemaTable SchemaTable;
200struct SchemaTable {
201 const char *zName;
202 const char *zObject;
203 const char *zPragma;
204 const char *zSchema;
205} aSchemaTable[] = {
206 { "table_info", "table", "PRAGMA %Q.table_info(%Q)", SCHEMA },
207 { "foreign_key_list", "table", "PRAGMA %Q.foreign_key_list(%Q)", SCHEMA2 },
208 { "index_list", "table", "PRAGMA %Q.index_list(%Q)", SCHEMA3 },
209 { "index_info", "index", "PRAGMA %Q.index_info(%Q)", SCHEMA4 },
210 { "trigger_list", "trigger", "SELECT 1", SCHEMA5 },
211 { 0, 0, 0, 0 }
212};
213
214typedef struct schema_vtab schema_vtab;
215typedef struct schema_cursor schema_cursor;
216
217/* A schema table object */
218struct schema_vtab {
219 sqlite3_vtab base;
220 sqlite3 *db;
221 SchemaTable *pType;
222};
223
224/* A schema table cursor object */
225struct schema_cursor {
226 sqlite3_vtab_cursor base;
227 sqlite3_stmt *pDbList;
228 sqlite3_stmt *pTableList;
229 sqlite3_stmt *pColumnList;
230 int rowid;
231};
232
233/*
234** Table destructor for the schema module.
235*/
236static int schemaDestroy(sqlite3_vtab *pVtab){
237 sqlite3_free(pVtab);
238 return 0;
239}
240
241/*
242** Table constructor for the schema module.
243*/
244static int schemaCreate(
245 sqlite3 *db,
246 void *pAux,
247 int argc, const char *const*argv,
248 sqlite3_vtab **ppVtab,
249 char **pzErr
250){
251 int rc = SQLITE_NOMEM;
252 schema_vtab *pVtab;
253 SchemaTable *pType = &aSchemaTable[0];
254
shanec0688ea2009-03-05 03:48:06 +0000255 UNUSED_PARAMETER(pzErr);
256
danielk1977c8c70692009-02-25 15:22:02 +0000257 if( argc>3 ){
258 int i;
259 pType = 0;
260 for(i=0; aSchemaTable[i].zName; i++){
261 if( 0==strcmp(argv[3], aSchemaTable[i].zName) ){
262 pType = &aSchemaTable[i];
263 }
264 }
265 if( !pType ){
266 return SQLITE_ERROR;
267 }
268 }
269
270 pVtab = sqlite3_malloc(sizeof(schema_vtab));
271 if( pVtab ){
272 memset(pVtab, 0, sizeof(schema_vtab));
273 pVtab->db = (sqlite3 *)pAux;
274 pVtab->pType = pType;
275 rc = sqlite3_declare_vtab(db, pType->zSchema);
276 }
277 *ppVtab = (sqlite3_vtab *)pVtab;
278 return rc;
279}
280
281/*
282** Open a new cursor on the schema table.
283*/
284static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
285 int rc = SQLITE_NOMEM;
286 schema_cursor *pCur;
shanec0688ea2009-03-05 03:48:06 +0000287 UNUSED_PARAMETER(pVTab);
danielk1977c8c70692009-02-25 15:22:02 +0000288 pCur = sqlite3_malloc(sizeof(schema_cursor));
289 if( pCur ){
290 memset(pCur, 0, sizeof(schema_cursor));
291 *ppCursor = (sqlite3_vtab_cursor *)pCur;
292 rc = SQLITE_OK;
293 }
294 return rc;
295}
296
297/*
298** Close a schema table cursor.
299*/
300static int schemaClose(sqlite3_vtab_cursor *cur){
301 schema_cursor *pCur = (schema_cursor *)cur;
302 sqlite3_finalize(pCur->pDbList);
303 sqlite3_finalize(pCur->pTableList);
304 sqlite3_finalize(pCur->pColumnList);
305 sqlite3_free(pCur);
306 return SQLITE_OK;
307}
308
309static void columnToResult(sqlite3_context *ctx, sqlite3_stmt *pStmt, int iCol){
310 switch( sqlite3_column_type(pStmt, iCol) ){
311 case SQLITE_NULL:
312 sqlite3_result_null(ctx);
313 break;
314 case SQLITE_INTEGER:
315 sqlite3_result_int64(ctx, sqlite3_column_int64(pStmt, iCol));
316 break;
317 case SQLITE_FLOAT:
318 sqlite3_result_double(ctx, sqlite3_column_double(pStmt, iCol));
319 break;
320 case SQLITE_TEXT: {
321 const char *z = (const char *)sqlite3_column_text(pStmt, iCol);
322 sqlite3_result_text(ctx, z, -1, SQLITE_TRANSIENT);
323 break;
324 }
325 }
326}
327
328/*
329** Retrieve a column of data.
330*/
331static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
332 schema_cursor *pCur = (schema_cursor *)cur;
333 switch( i ){
334 case 0:
335 columnToResult(ctx, pCur->pDbList, 1);
336 break;
337 case 1:
338 columnToResult(ctx, pCur->pTableList, 0);
339 break;
340 default:
341 columnToResult(ctx, pCur->pColumnList, i-2);
342 break;
343 }
344 return SQLITE_OK;
345}
346
347/*
348** Retrieve the current rowid.
349*/
350static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
351 schema_cursor *pCur = (schema_cursor *)cur;
352 *pRowid = pCur->rowid;
353 return SQLITE_OK;
354}
355
356static int finalize(sqlite3_stmt **ppStmt){
357 int rc = sqlite3_finalize(*ppStmt);
358 *ppStmt = 0;
359 return rc;
360}
361
362static int schemaEof(sqlite3_vtab_cursor *cur){
363 schema_cursor *pCur = (schema_cursor *)cur;
364 return (pCur->pDbList ? 0 : 1);
365}
366
367/*
368** Advance the cursor to the next row.
369*/
370static int schemaNext(sqlite3_vtab_cursor *cur){
371 int rc = SQLITE_OK;
372 schema_cursor *pCur = (schema_cursor *)cur;
373 schema_vtab *pVtab = (schema_vtab *)(cur->pVtab);
374 char *zSql = 0;
375
376 while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){
377 if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit;
378
379 while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){
380 if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit;
381
382 assert(pCur->pDbList);
383 while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){
384 rc = finalize(&pCur->pDbList);
385 goto next_exit;
386 }
387
388 /* Set zSql to the SQL to pull the list of tables from the
389 ** sqlite_master (or sqlite_temp_master) table of the database
390 ** identfied by the row pointed to by the SQL statement pCur->pDbList
391 ** (iterating through a "PRAGMA database_list;" statement).
392 */
393 if( sqlite3_column_int(pCur->pDbList, 0)==1 ){
394 zSql = sqlite3_mprintf(
395 "SELECT name FROM sqlite_temp_master WHERE type=%Q",
396 pVtab->pType->zObject
397 );
398 }else{
399 sqlite3_stmt *pDbList = pCur->pDbList;
400 zSql = sqlite3_mprintf(
401 "SELECT name FROM %Q.sqlite_master WHERE type=%Q",
402 sqlite3_column_text(pDbList, 1), pVtab->pType->zObject
403 );
404 }
405 if( !zSql ){
406 rc = SQLITE_NOMEM;
407 goto next_exit;
408 }
409
410 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0);
411 sqlite3_free(zSql);
412 if( rc!=SQLITE_OK ) goto next_exit;
413 }
414
415 /* Set zSql to the SQL to the table_info pragma for the table currently
416 ** identified by the rows pointed to by statements pCur->pDbList and
417 ** pCur->pTableList.
418 */
419 zSql = sqlite3_mprintf(pVtab->pType->zPragma,
420 sqlite3_column_text(pCur->pDbList, 1),
421 sqlite3_column_text(pCur->pTableList, 0)
422 );
423
424 if( !zSql ){
425 rc = SQLITE_NOMEM;
426 goto next_exit;
427 }
428 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0);
429 sqlite3_free(zSql);
430 if( rc!=SQLITE_OK ) goto next_exit;
431 }
432 pCur->rowid++;
433
434next_exit:
435 /* TODO: Handle rc */
436 return rc;
437}
438
439/*
440** Reset a schema table cursor.
441*/
442static int schemaFilter(
443 sqlite3_vtab_cursor *pVtabCursor,
444 int idxNum, const char *idxStr,
445 int argc, sqlite3_value **argv
446){
447 int rc;
448 schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab);
449 schema_cursor *pCur = (schema_cursor *)pVtabCursor;
shanec0688ea2009-03-05 03:48:06 +0000450 UNUSED_PARAMETER(idxNum);
451 UNUSED_PARAMETER(idxStr);
452 UNUSED_PARAMETER(argc);
453 UNUSED_PARAMETER(argv);
danielk1977c8c70692009-02-25 15:22:02 +0000454 pCur->rowid = 0;
455 finalize(&pCur->pTableList);
456 finalize(&pCur->pColumnList);
457 finalize(&pCur->pDbList);
458 rc = sqlite3_prepare(pVtab->db,"SELECT 0, 'main'", -1, &pCur->pDbList, 0);
459 return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc);
460}
461
462/*
463** Analyse the WHERE condition.
464*/
465static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
shanec0688ea2009-03-05 03:48:06 +0000466 UNUSED_PARAMETER(tab);
467 UNUSED_PARAMETER(pIdxInfo);
danielk1977c8c70692009-02-25 15:22:02 +0000468 return SQLITE_OK;
469}
470
471/*
472** A virtual table module that merely echos method calls into TCL
473** variables.
474*/
475static sqlite3_module schemaModule = {
476 0, /* iVersion */
477 schemaCreate,
478 schemaCreate,
479 schemaBestIndex,
480 schemaDestroy,
481 schemaDestroy,
482 schemaOpen, /* xOpen - open a cursor */
483 schemaClose, /* xClose - close a cursor */
484 schemaFilter, /* xFilter - configure scan constraints */
485 schemaNext, /* xNext - advance a cursor */
486 schemaEof, /* xEof */
487 schemaColumn, /* xColumn - read data */
488 schemaRowid, /* xRowid - read data */
489 0, /* xUpdate */
490 0, /* xBegin */
491 0, /* xSync */
492 0, /* xCommit */
493 0, /* xRollback */
494 0, /* xFindMethod */
495 0, /* xRename */
496};
497
498/*
499** Extension load function.
500*/
501static int installSchemaModule(sqlite3 *db, sqlite3 *sdb){
502 sqlite3_create_module(db, "schema", &schemaModule, (void *)sdb);
503 return 0;
504}
505
506/*
507** sj(zValue, zJoin)
508**
509** The following block contains the implementation of an aggregate
510** function that returns a string. Each time the function is stepped,
511** it appends data to an internal buffer. When the aggregate is finalized,
512** the contents of the buffer are returned.
513**
514** The first time the aggregate is stepped the buffer is set to a copy
515** of the first argument. The second time and subsequent times it is
516** stepped a copy of the second argument is appended to the buffer, then
517** a copy of the first.
518**
519** Example:
520**
521** INSERT INTO t1(a) VALUES('1');
522** INSERT INTO t1(a) VALUES('2');
523** INSERT INTO t1(a) VALUES('3');
524** SELECT sj(a, ', ') FROM t1;
525**
526** => "1, 2, 3"
527**
528*/
529struct StrBuffer {
530 char *zBuf;
531};
532typedef struct StrBuffer StrBuffer;
533static void joinFinalize(sqlite3_context *context){
534 StrBuffer *p;
535 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
536 sqlite3_result_text(context, p->zBuf, -1, SQLITE_TRANSIENT);
537 sqlite3_free(p->zBuf);
538}
539static void joinStep(
540 sqlite3_context *context,
541 int argc,
542 sqlite3_value **argv
543){
544 StrBuffer *p;
shanec0688ea2009-03-05 03:48:06 +0000545 UNUSED_PARAMETER(argc);
danielk1977c8c70692009-02-25 15:22:02 +0000546 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
547 if( p->zBuf==0 ){
548 p->zBuf = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
549 }else{
550 char *zTmp = p->zBuf;
551 p->zBuf = sqlite3_mprintf("%s%s%s",
552 zTmp, sqlite3_value_text(argv[1]), sqlite3_value_text(argv[0])
553 );
554 sqlite3_free(zTmp);
555 }
556}
557
558/*
559** dq(zString)
560**
561** This scalar function accepts a single argument and interprets it as
562** a text value. The return value is the argument enclosed in double
563** quotes. If any double quote characters are present in the argument,
564** these are escaped.
565**
566** dq('the raven "Nevermore."') == '"the raven ""Nevermore."""'
567*/
568static void doublequote(
569 sqlite3_context *context,
570 int argc,
571 sqlite3_value **argv
572){
573 int ii;
574 char *zOut;
575 char *zCsr;
576 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
577 int nIn = sqlite3_value_bytes(argv[0]);
578
shanec0688ea2009-03-05 03:48:06 +0000579 UNUSED_PARAMETER(argc);
580
danielk1977c8c70692009-02-25 15:22:02 +0000581 zOut = sqlite3_malloc(nIn*2+3);
582 zCsr = zOut;
583 *zCsr++ = '"';
584 for(ii=0; ii<nIn; ii++){
585 *zCsr++ = zIn[ii];
586 if( zIn[ii]=='"' ){
587 *zCsr++ = '"';
588 }
589 }
590 *zCsr++ = '"';
591 *zCsr++ = '\0';
592
593 sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT);
594 sqlite3_free(zOut);
595}
596
597/*
598** multireplace(zString, zSearch1, zReplace1, ...)
599*/
600static void multireplace(
601 sqlite3_context *context,
602 int argc,
603 sqlite3_value **argv
604){
605 int i = 0;
606 char *zOut = 0;
607 int nOut = 0;
608 int nMalloc = 0;
609 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
610 int nIn = sqlite3_value_bytes(argv[0]);
611
612 while( i<nIn ){
613 const char *zCopy = &zIn[i];
614 int nCopy = 1;
615 int nReplace = 1;
616 int j;
617 for(j=1; j<(argc-1); j+=2){
618 const char *z = (const char *)sqlite3_value_text(argv[j]);
619 int n = sqlite3_value_bytes(argv[j]);
620 if( n<=(nIn-i) && 0==strncmp(z, zCopy, n) ){
621 zCopy = (const char *)sqlite3_value_text(argv[j+1]);
622 nCopy = sqlite3_value_bytes(argv[j+1]);
623 nReplace = n;
624 break;
625 }
626 }
627 if( (nOut+nCopy)>nMalloc ){
628 nMalloc += (nMalloc + 16);
629 zOut = (char *)sqlite3_realloc(zOut, nMalloc);
630 }
631 memcpy(&zOut[nOut], zCopy, nCopy);
632 i += nReplace;
633 nOut += nCopy;
634 }
635
636 sqlite3_result_text(context, zOut, nOut, SQLITE_TRANSIENT);
637 sqlite3_free(zOut);
638}
639
640/*
641** A callback for sqlite3_exec() invokes the callback specified by the
642** GenfkeyCb structure pointed to by the void* passed as the first argument.
643*/
644static int invokeCallback(void *p, int nArg, char **azArg, char **azCol){
645 GenfkeyCb *pCb = (GenfkeyCb *)p;
shanec0688ea2009-03-05 03:48:06 +0000646 UNUSED_PARAMETER(nArg);
647 UNUSED_PARAMETER(azCol);
danielk1977c8c70692009-02-25 15:22:02 +0000648 return pCb->xData(pCb->pCtx, pCb->eType, azArg[0]);
649}
650
651int detectSchemaProblem(
652 sqlite3 *db, /* Database connection */
653 const char *zMessage, /* English language error message */
654 const char *zSql, /* SQL statement to run */
655 GenfkeyCb *pCb
656){
657 sqlite3_stmt *pStmt;
658 int rc;
659 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
660 if( rc!=SQLITE_OK ){
661 return rc;
662 }
663 while( SQLITE_ROW==sqlite3_step(pStmt) ){
664 char *zDel;
665 int iFk = sqlite3_column_int(pStmt, 0);
666 const char *zTab = (const char *)sqlite3_column_text(pStmt, 1);
667 zDel = sqlite3_mprintf("Error in table %s: %s", zTab, zMessage);
668 rc = pCb->xData(pCb->pCtx, pCb->eType, zDel);
669 sqlite3_free(zDel);
670 if( rc!=SQLITE_OK ) return rc;
671 zDel = sqlite3_mprintf(
672 "DELETE FROM temp.fkey WHERE from_tbl = %Q AND fkid = %d"
673 , zTab, iFk
674 );
675 sqlite3_exec(db, zDel, 0, 0, 0);
676 sqlite3_free(zDel);
677 }
678 sqlite3_finalize(pStmt);
679 return SQLITE_OK;
680}
681
682/*
683** Create and populate temporary table "fkey".
684*/
685static int populateTempTable(sqlite3 *db, GenfkeyCb *pCallback){
686 int rc;
687
688 rc = sqlite3_exec(db,
689 "CREATE VIRTUAL TABLE temp.v_fkey USING schema(foreign_key_list);"
690 "CREATE VIRTUAL TABLE temp.v_col USING schema(table_info);"
691 "CREATE VIRTUAL TABLE temp.v_idxlist USING schema(index_list);"
692 "CREATE VIRTUAL TABLE temp.v_idxinfo USING schema(index_info);"
693 "CREATE VIRTUAL TABLE temp.v_triggers USING schema(trigger_list);"
694 "CREATE TABLE temp.fkey AS "
695 "SELECT from_tbl, to_tbl, fkid, from_col, to_col, on_update, on_delete "
696 "FROM temp.v_fkey WHERE database = 'main';"
697 , 0, 0, 0
698 );
699 if( rc!=SQLITE_OK ) return rc;
700
701 rc = detectSchemaProblem(db, "foreign key columns do not exist",
702 "SELECT fkid, from_tbl "
703 "FROM temp.fkey "
704 "WHERE to_col IS NOT NULL AND NOT EXISTS (SELECT 1 "
705 "FROM temp.v_col WHERE tablename=to_tbl AND name==to_col"
706 ")", pCallback
707 );
708 if( rc!=SQLITE_OK ) return rc;
709
710 /* At this point the temp.fkey table is mostly populated. If any foreign
711 ** keys were specified so that they implicitly refer to they primary
712 ** key of the parent table, the "to_col" values of the temp.fkey rows
713 ** are still set to NULL.
714 **
715 ** This is easily fixed for single column primary keys, but not for
716 ** composites. With a composite primary key, there is no way to reliably
717 ** query sqlite for the order in which the columns that make up the
718 ** composite key were declared i.e. there is no way to tell if the
719 ** schema actually contains "PRIMARY KEY(a, b)" or "PRIMARY KEY(b, a)".
720 ** Therefore, this case is not handled. The following function call
721 ** detects instances of this case.
722 */
723 rc = detectSchemaProblem(db, "implicit mapping to composite primary key",
724 "SELECT fkid, from_tbl "
725 "FROM temp.fkey "
726 "WHERE to_col IS NULL "
727 "GROUP BY fkid, from_tbl HAVING count(*) > 1", pCallback
728 );
729 if( rc!=SQLITE_OK ) return rc;
730
731 /* Detect attempts to implicitly map to the primary key of a table
732 ** that has no primary key column.
733 */
734 rc = detectSchemaProblem(db, "implicit mapping to non-existant primary key",
735 "SELECT fkid, from_tbl "
736 "FROM temp.fkey "
737 "WHERE to_col IS NULL AND NOT EXISTS "
738 "(SELECT 1 FROM temp.v_col WHERE pk AND tablename = temp.fkey.to_tbl)"
739 , pCallback
740 );
741 if( rc!=SQLITE_OK ) return rc;
742
743 /* Fix all the implicit primary key mappings in the temp.fkey table. */
744 rc = sqlite3_exec(db,
745 "UPDATE temp.fkey SET to_col = "
746 "(SELECT name FROM temp.v_col WHERE pk AND tablename=temp.fkey.to_tbl)"
747 " WHERE to_col IS NULL;"
748 , 0, 0, 0
749 );
750 if( rc!=SQLITE_OK ) return rc;
751
752 /* Now check that all all parent keys are either primary keys or
753 ** subject to a unique constraint.
754 */
755 rc = sqlite3_exec(db,
756 "CREATE TABLE temp.idx2 AS SELECT "
757 "il.tablename AS tablename,"
758 "ii.indexname AS indexname,"
759 "ii.name AS col "
760 "FROM temp.v_idxlist AS il, temp.v_idxinfo AS ii "
761 "WHERE il.isunique AND il.database='main' AND ii.indexname = il.name;"
762 "INSERT INTO temp.idx2 "
763 "SELECT tablename, 'pk', name FROM temp.v_col WHERE pk;"
764
765 "CREATE TABLE temp.idx AS SELECT "
766 "tablename, indexname, sj(dq(col),',') AS cols "
767 "FROM (SELECT * FROM temp.idx2 ORDER BY col) "
768 "GROUP BY tablename, indexname;"
769
770 "CREATE TABLE temp.fkey2 AS SELECT "
771 "fkid, from_tbl, to_tbl, sj(dq(to_col),',') AS cols "
772 "FROM (SELECT * FROM temp.fkey ORDER BY to_col) "
773 "GROUP BY fkid, from_tbl;"
774
775 "CREATE TABLE temp.triggers AS SELECT "
776 "triggername FROM temp.v_triggers WHERE database='main' AND "
777 "triggername LIKE 'genfkey%';"
778 , 0, 0, 0
779 );
780 if( rc!=SQLITE_OK ) return rc;
781 rc = detectSchemaProblem(db, "foreign key is not unique",
782 "SELECT fkid, from_tbl "
783 "FROM temp.fkey2 "
784 "WHERE NOT EXISTS (SELECT 1 "
785 "FROM temp.idx WHERE tablename=to_tbl AND fkey2.cols==idx.cols"
786 ")", pCallback
787 );
788 if( rc!=SQLITE_OK ) return rc;
789
790 return rc;
791}
792
793#define GENFKEY_ERROR 1
794#define GENFKEY_DROPTRIGGER 2
795#define GENFKEY_CREATETRIGGER 3
796static int genfkey_create_triggers(
797 sqlite3 *sdb, /* Connection to read schema from */
798 const char *zDb, /* Name of db to read ("main", "temp") */
799 void *pCtx, /* Context pointer to pass to xData */
800 int (*xData)(void *, int, const char *)
801){
802 const char *zSql =
803 "SELECT multireplace('"
804
805 "-- Triggers for foreign key mapping:\n"
806 "--\n"
807 "-- /from_readable/ REFERENCES /to_readable/\n"
808 "-- on delete /on_delete/\n"
809 "-- on update /on_update/\n"
810 "--\n"
811
812 /* The "BEFORE INSERT ON <referencing>" trigger. This trigger's job is to
813 ** throw an exception if the user tries to insert a row into the
814 ** referencing table for which there is no corresponding row in
815 ** the referenced table.
816 */
817 "CREATE TRIGGER /name/_insert_referencing BEFORE INSERT ON /tbl/ WHEN \n"
818 " /key_notnull/ AND NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
819 "BEGIN\n"
820 " SELECT RAISE(ABORT, ''constraint failed'');\n"
821 "END;\n"
822
823 /* The "BEFORE UPDATE ON <referencing>" trigger. This trigger's job
824 ** is to throw an exception if the user tries to update a row in the
825 ** referencing table causing it to correspond to no row in the
826 ** referenced table.
827 */
828 "CREATE TRIGGER /name/_update_referencing BEFORE\n"
829 " UPDATE OF /rkey_list/ ON /tbl/ WHEN \n"
830 " /key_notnull/ AND \n"
831 " NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
832 "BEGIN\n"
833 " SELECT RAISE(ABORT, ''constraint failed'');\n"
834 "END;\n"
835
836
837 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
838 ** is to detect when a row is deleted from the referenced table to
839 ** which rows in the referencing table correspond. The action taken
840 ** depends on the value of the 'ON DELETE' clause.
841 */
842 "CREATE TRIGGER /name/_delete_referenced BEFORE DELETE ON /ref/ WHEN\n"
843 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
844 "BEGIN\n"
845 " /delete_action/\n"
846 "END;\n"
847
848 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
849 ** is to detect when the key columns of a row in the referenced table
850 ** to which one or more rows in the referencing table correspond are
851 ** updated. The action taken depends on the value of the 'ON UPDATE'
852 ** clause.
853 */
854 "CREATE TRIGGER /name/_update_referenced AFTER\n"
855 " UPDATE OF /fkey_list/ ON /ref/ WHEN \n"
856 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
857 "BEGIN\n"
858 " /update_action/\n"
859 "END;\n"
860 "'"
861
862 /* These are used in the SQL comment written above each set of triggers */
863 ", '/from_readable/', from_tbl || '(' || sj(from_col, ', ') || ')'"
864 ", '/to_readable/', to_tbl || '(' || sj(to_col, ', ') || ')'"
865 ", '/on_delete/', on_delete"
866 ", '/on_update/', on_update"
867
868 ", '/name/', 'genfkey' || min(rowid)"
869 ", '/tbl/', dq(from_tbl)"
870 ", '/ref/', dq(to_tbl)"
871 ", '/key_notnull/', sj('new.' || dq(from_col) || ' IS NOT NULL', ' AND ')"
872
873 ", '/fkey_list/', sj(to_col, ', ')"
874 ", '/rkey_list/', sj(from_col, ', ')"
875
876 ", '/cond1/', sj(multireplace('new./from/ == /to/'"
877 ", '/from/', dq(from_col)"
878 ", '/to/', dq(to_col)"
879 "), ' AND ')"
880 ", '/cond2/', sj(multireplace('old./to/ == /from/'"
881 ", '/from/', dq(from_col)"
882 ", '/to/', dq(to_col)"
883 "), ' AND ')"
884
885 ", '/update_action/', CASE on_update "
886 "WHEN 'SET NULL' THEN "
887 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
888 ", '/setlist/', sj(from_col||' = NULL',', ')"
889 ", '/tbl/', dq(from_tbl)"
890 ", '/where/', sj(from_col||' = old.'||dq(to_col),' AND ')"
891 ")"
892 "WHEN 'CASCADE' THEN "
893 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
894 ", '/setlist/', sj(dq(from_col)||' = new.'||dq(to_col),', ')"
895 ", '/tbl/', dq(from_tbl)"
896 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
897 ")"
898 "ELSE "
899 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
900 "END "
901
902 ", '/delete_action/', CASE on_delete "
903 "WHEN 'SET NULL' THEN "
904 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
905 ", '/setlist/', sj(from_col||' = NULL',', ')"
906 ", '/tbl/', dq(from_tbl)"
907 ", '/where/', sj(from_col||' = old.'||dq(to_col),' AND ')"
908 ")"
909 "WHEN 'CASCADE' THEN "
910 "multireplace('DELETE FROM /tbl/ WHERE /where/;' "
911 ", '/tbl/', dq(from_tbl)"
912 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
913 ")"
914 "ELSE "
915 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
916 "END "
917
918 ") FROM temp.fkey "
919 "GROUP BY from_tbl, fkid"
920 ;
921
922 int rc;
923 const int enc = SQLITE_UTF8;
924 sqlite3 *db = 0;
925
926 GenfkeyCb cb;
927 cb.xData = xData;
928 cb.pCtx = pCtx;
929
shanec0688ea2009-03-05 03:48:06 +0000930 UNUSED_PARAMETER(zDb);
931
danielk1977c8c70692009-02-25 15:22:02 +0000932 /* Open the working database handle. */
933 rc = sqlite3_open(":memory:", &db);
934 if( rc!=SQLITE_OK ) goto genfkey_exit;
935
936 /* Create the special scalar and aggregate functions used by this program. */
937 sqlite3_create_function(db, "dq", 1, enc, 0, doublequote, 0, 0);
938 sqlite3_create_function(db, "multireplace", -1, enc, db, multireplace, 0, 0);
939 sqlite3_create_function(db, "sj", 2, enc, 0, 0, joinStep, joinFinalize);
940
941 /* Install the "schema" virtual table module */
942 installSchemaModule(db, sdb);
943
944 /* Create and populate a temp table with the information required to
945 ** build the foreign key triggers. See function populateTempTable()
946 ** for details.
947 */
948 cb.eType = GENFKEY_ERROR;
949 rc = populateTempTable(db, &cb);
950 if( rc!=SQLITE_OK ) goto genfkey_exit;
951
952 /* Unless the --no-drop option was specified, generate DROP TRIGGER
953 ** statements to drop any triggers in the database generated by a
954 ** previous run of this program.
955 */
956 cb.eType = GENFKEY_DROPTRIGGER;
957 rc = sqlite3_exec(db,
958 "SELECT 'DROP TRIGGER main.' || dq(triggername) || ';' FROM triggers"
959 ,invokeCallback, (void *)&cb, 0
960 );
961 if( rc!=SQLITE_OK ) goto genfkey_exit;
962
963 /* Run the main query to create the trigger definitions. */
964 cb.eType = GENFKEY_CREATETRIGGER;
965 rc = sqlite3_exec(db, zSql, invokeCallback, (void *)&cb, 0);
966 if( rc!=SQLITE_OK ) goto genfkey_exit;
967
968genfkey_exit:
969 sqlite3_close(db);
970 return rc;
971}
972
973
974#endif
975/* End genfkey logic. */
976/*************************************************************************/
977/*************************************************************************/
978
drhe91d16b2008-12-08 18:27:31 +0000979/*
drhc49f44e2006-10-26 18:15:42 +0000980** If the following flag is set, then command execution stops
981** at an error if we are not interactive.
982*/
983static int bail_on_error = 0;
984
985/*
drhc28490c2006-10-26 14:25:58 +0000986** Threat stdin as an interactive input if the following variable
987** is true. Otherwise, assume stdin is connected to a file or pipe.
988*/
989static int stdin_is_interactive = 1;
990
991/*
drh4c504392000-10-16 22:06:40 +0000992** The following is the open SQLite database. We make a pointer
993** to this database a static variable so that it can be accessed
994** by the SIGINT handler to interrupt database processing.
995*/
danielk197792f9a1b2004-06-19 09:08:16 +0000996static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000997
998/*
drh67505e72002-04-19 12:34:06 +0000999** True if an interrupt (Control-C) has been received.
1000*/
drh43617e92006-03-06 20:55:46 +00001001static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +00001002
1003/*
persicom7e2dfdd2002-04-18 02:46:52 +00001004** This is the name of our program. It is set in main(), used
1005** in a number of other places, mostly for error messages.
1006*/
1007static char *Argv0;
1008
1009/*
1010** Prompt strings. Initialized in main. Settable with
1011** .prompt main continue
1012*/
1013static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
1014static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
1015
drhb0603412007-02-28 04:47:26 +00001016/*
1017** Write I/O traces to the following stream.
1018*/
rsebe0a9092007-07-30 18:24:38 +00001019#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001020static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +00001021#endif
drhb0603412007-02-28 04:47:26 +00001022
1023/*
1024** This routine works like printf in that its first argument is a
1025** format string and subsequent arguments are values to be substituted
1026** in place of % fields. The result of formatting this string
1027** is written to iotrace.
1028*/
rsebe0a9092007-07-30 18:24:38 +00001029#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001030static void iotracePrintf(const char *zFormat, ...){
1031 va_list ap;
drhf075cd02007-02-28 06:14:25 +00001032 char *z;
drhb0603412007-02-28 04:47:26 +00001033 if( iotrace==0 ) return;
1034 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +00001035 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +00001036 va_end(ap);
drhf075cd02007-02-28 06:14:25 +00001037 fprintf(iotrace, "%s", z);
1038 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +00001039}
rsebe0a9092007-07-30 18:24:38 +00001040#endif
drhb0603412007-02-28 04:47:26 +00001041
drh44c2eb12003-04-30 11:38:26 +00001042
persicom7e2dfdd2002-04-18 02:46:52 +00001043/*
drh83965662003-04-17 02:54:13 +00001044** Determines if a string is a number of not.
1045*/
danielk19772e588c72005-12-09 14:25:08 +00001046static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +00001047 if( *z=='-' || *z=='+' ) z++;
1048 if( !isdigit(*z) ){
1049 return 0;
1050 }
1051 z++;
1052 if( realnum ) *realnum = 0;
1053 while( isdigit(*z) ){ z++; }
1054 if( *z=='.' ){
1055 z++;
1056 if( !isdigit(*z) ) return 0;
1057 while( isdigit(*z) ){ z++; }
1058 if( realnum ) *realnum = 1;
1059 }
1060 if( *z=='e' || *z=='E' ){
1061 z++;
1062 if( *z=='+' || *z=='-' ) z++;
1063 if( !isdigit(*z) ) return 0;
1064 while( isdigit(*z) ){ z++; }
1065 if( realnum ) *realnum = 1;
1066 }
1067 return *z==0;
1068}
drh83965662003-04-17 02:54:13 +00001069
1070/*
danielk1977bc6ada42004-06-30 08:20:16 +00001071** A global char* and an SQL function to access its current value
1072** from within an SQL statement. This program used to use the
1073** sqlite_exec_printf() API to substitue a string into an SQL statement.
1074** The correct way to do this with sqlite3 is to use the bind API, but
1075** since the shell is built around the callback paradigm it would be a lot
1076** of work. Instead just use this hack, which is quite harmless.
1077*/
1078static const char *zShellStatic = 0;
1079static void shellstaticFunc(
1080 sqlite3_context *context,
1081 int argc,
1082 sqlite3_value **argv
1083){
1084 assert( 0==argc );
1085 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +00001086 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +00001087 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +00001088 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
1089}
1090
1091
1092/*
drhfeac5f82004-08-01 00:10:45 +00001093** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +00001094** the text in memory obtained from malloc() and returns a pointer
1095** to the text. NULL is returned at end of file, or if malloc()
1096** fails.
1097**
1098** The interface is like "readline" but no command-line editing
1099** is done.
1100*/
drh9347b202003-07-18 01:30:59 +00001101static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +00001102 char *zLine;
1103 int nLine;
drh8e7e7a22000-05-30 18:45:23 +00001104 int n;
1105 int eol;
1106
1107 if( zPrompt && *zPrompt ){
1108 printf("%s",zPrompt);
1109 fflush(stdout);
1110 }
1111 nLine = 100;
1112 zLine = malloc( nLine );
1113 if( zLine==0 ) return 0;
1114 n = 0;
1115 eol = 0;
1116 while( !eol ){
1117 if( n+100>nLine ){
1118 nLine = nLine*2 + 100;
1119 zLine = realloc(zLine, nLine);
1120 if( zLine==0 ) return 0;
1121 }
drhdaffd0e2001-04-11 14:28:42 +00001122 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +00001123 if( n==0 ){
1124 free(zLine);
1125 return 0;
1126 }
1127 zLine[n] = 0;
1128 eol = 1;
1129 break;
1130 }
1131 while( zLine[n] ){ n++; }
1132 if( n>0 && zLine[n-1]=='\n' ){
1133 n--;
1134 zLine[n] = 0;
1135 eol = 1;
1136 }
1137 }
1138 zLine = realloc( zLine, n+1 );
1139 return zLine;
1140}
1141
1142/*
drhc28490c2006-10-26 14:25:58 +00001143** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +00001144**
1145** zPrior is a string of prior text retrieved. If not the empty
1146** string, then issue a continuation prompt.
1147*/
drhdaffd0e2001-04-11 14:28:42 +00001148static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +00001149 char *zPrompt;
1150 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +00001151 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +00001152 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +00001153 }
1154 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +00001155 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +00001156 }else{
persicom7e2dfdd2002-04-18 02:46:52 +00001157 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +00001158 }
1159 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +00001160#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +00001161 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +00001162#endif
drh8e7e7a22000-05-30 18:45:23 +00001163 return zResult;
1164}
1165
persicom7e2dfdd2002-04-18 02:46:52 +00001166struct previous_mode_data {
1167 int valid; /* Is there legit data in here? */
1168 int mode;
1169 int showHeader;
1170 int colWidth[100];
1171};
drh45e29d82006-11-20 16:21:10 +00001172
drh8e7e7a22000-05-30 18:45:23 +00001173/*
drh75897232000-05-29 14:26:00 +00001174** An pointer to an instance of this structure is passed from
1175** the main program to the callback. This is used to communicate
1176** state and mode information.
1177*/
1178struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +00001179 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +00001180 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +00001181 int cnt; /* Number of records displayed so far */
1182 FILE *out; /* Write results here */
1183 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +00001184 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +00001185 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +00001186 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +00001187 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +00001188 int colWidth[100]; /* Requested width of each column when in column mode*/
1189 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +00001190 char nullvalue[20]; /* The text to print when a NULL comes back from
1191 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +00001192 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +00001193 /* Holds the mode information just before
1194 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +00001195 char outfile[FILENAME_MAX]; /* Filename for *out */
1196 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +00001197};
1198
1199/*
1200** These are the allowed modes.
1201*/
drh967e8b72000-06-21 13:59:10 +00001202#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +00001203#define MODE_Column 1 /* One record per line in neat columns */
1204#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +00001205#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
1206#define MODE_Html 4 /* Generate an XHTML table */
1207#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +00001208#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +00001209#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +00001210#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +00001211
drh66ce4d02008-02-15 17:38:06 +00001212static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +00001213 "line",
1214 "column",
1215 "list",
1216 "semi",
1217 "html",
drhfeac5f82004-08-01 00:10:45 +00001218 "insert",
1219 "tcl",
drh8e64d1c2004-10-07 00:32:39 +00001220 "csv",
drh66ce4d02008-02-15 17:38:06 +00001221 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +00001222};
drh75897232000-05-29 14:26:00 +00001223
1224/*
1225** Number of elements in an array
1226*/
drh902b9ee2008-12-05 17:17:07 +00001227#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +00001228
1229/*
drhea678832008-12-10 19:26:22 +00001230** Compute a string length that is limited to what can be stored in
1231** lower 30 bits of a 32-bit signed integer.
1232*/
drh4f21c4a2008-12-10 22:15:00 +00001233static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +00001234 const char *z2 = z;
1235 while( *z2 ){ z2++; }
1236 return 0x3fffffff & (int)(z2 - z);
1237}
1238
1239/*
drh28bd4bc2000-06-15 15:57:22 +00001240** Output the given string as a quoted string using SQL quoting conventions.
1241*/
1242static void output_quoted_string(FILE *out, const char *z){
1243 int i;
1244 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +00001245 for(i=0; z[i]; i++){
1246 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +00001247 }
1248 if( nSingle==0 ){
1249 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +00001250 }else{
1251 fprintf(out,"'");
1252 while( *z ){
1253 for(i=0; z[i] && z[i]!='\''; i++){}
1254 if( i==0 ){
1255 fprintf(out,"''");
1256 z++;
1257 }else if( z[i]=='\'' ){
1258 fprintf(out,"%.*s''",i,z);
1259 z += i+1;
1260 }else{
drhcd7d2732002-02-26 23:24:26 +00001261 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +00001262 break;
1263 }
1264 }
drhcd7d2732002-02-26 23:24:26 +00001265 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +00001266 }
1267}
1268
1269/*
drhfeac5f82004-08-01 00:10:45 +00001270** Output the given string as a quoted according to C or TCL quoting rules.
1271*/
1272static void output_c_string(FILE *out, const char *z){
1273 unsigned int c;
1274 fputc('"', out);
1275 while( (c = *(z++))!=0 ){
1276 if( c=='\\' ){
1277 fputc(c, out);
1278 fputc(c, out);
1279 }else if( c=='\t' ){
1280 fputc('\\', out);
1281 fputc('t', out);
1282 }else if( c=='\n' ){
1283 fputc('\\', out);
1284 fputc('n', out);
1285 }else if( c=='\r' ){
1286 fputc('\\', out);
1287 fputc('r', out);
1288 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +00001289 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +00001290 }else{
1291 fputc(c, out);
1292 }
1293 }
1294 fputc('"', out);
1295}
1296
1297/*
drhc08a4f12000-06-15 16:49:48 +00001298** Output the given string with characters that are special to
1299** HTML escaped.
1300*/
1301static void output_html_string(FILE *out, const char *z){
1302 int i;
1303 while( *z ){
1304 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
1305 if( i>0 ){
1306 fprintf(out,"%.*s",i,z);
1307 }
1308 if( z[i]=='<' ){
1309 fprintf(out,"&lt;");
1310 }else if( z[i]=='&' ){
1311 fprintf(out,"&amp;");
1312 }else{
1313 break;
1314 }
1315 z += i + 1;
1316 }
1317}
1318
1319/*
drhc49f44e2006-10-26 18:15:42 +00001320** If a field contains any character identified by a 1 in the following
1321** array, then the string must be quoted for CSV.
1322*/
1323static const char needCsvQuote[] = {
1324 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1325 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1326 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1328 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1329 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1332 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1333 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1334 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1335 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1336 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1337 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1338 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1339 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1340};
1341
1342/*
drh8e64d1c2004-10-07 00:32:39 +00001343** Output a single term of CSV. Actually, p->separator is used for
1344** the separator, which may or may not be a comma. p->nullvalue is
1345** the null value. Strings are quoted using ANSI-C rules. Numbers
1346** appear outside of quotes.
1347*/
1348static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +00001349 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +00001350 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +00001351 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +00001352 }else{
drhc49f44e2006-10-26 18:15:42 +00001353 int i;
drh4f21c4a2008-12-10 22:15:00 +00001354 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +00001355 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +00001356 if( needCsvQuote[((unsigned char*)z)[i]]
1357 || (z[i]==p->separator[0] &&
1358 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +00001359 i = 0;
1360 break;
1361 }
1362 }
1363 if( i==0 ){
1364 putc('"', out);
1365 for(i=0; z[i]; i++){
1366 if( z[i]=='"' ) putc('"', out);
1367 putc(z[i], out);
1368 }
1369 putc('"', out);
1370 }else{
1371 fprintf(out, "%s", z);
1372 }
drh8e64d1c2004-10-07 00:32:39 +00001373 }
1374 if( bSep ){
drhd0e77882008-01-14 15:20:08 +00001375 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +00001376 }
1377}
1378
danielk19774af00c62005-01-23 23:43:21 +00001379#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +00001380/*
drh4c504392000-10-16 22:06:40 +00001381** This routine runs when the user presses Ctrl-C
1382*/
1383static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +00001384 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +00001385 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +00001386 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +00001387}
danielk19774af00c62005-01-23 23:43:21 +00001388#endif
drh4c504392000-10-16 22:06:40 +00001389
1390/*
drh75897232000-05-29 14:26:00 +00001391** This is the callback routine that the SQLite library
1392** invokes for each row of a query result.
1393*/
1394static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1395 int i;
1396 struct callback_data *p = (struct callback_data*)pArg;
1397 switch( p->mode ){
1398 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +00001399 int w = 5;
drh6a535342001-10-19 16:44:56 +00001400 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +00001401 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +00001402 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +00001403 if( len>w ) w = len;
1404 }
drh75897232000-05-29 14:26:00 +00001405 if( p->cnt++>0 ) fprintf(p->out,"\n");
1406 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001407 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +00001408 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +00001409 }
1410 break;
1411 }
danielk19770d78bae2008-01-03 07:09:48 +00001412 case MODE_Explain:
drh75897232000-05-29 14:26:00 +00001413 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +00001414 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +00001415 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +00001416 int w, n;
1417 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +00001418 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +00001419 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001420 w = 0;
drh75897232000-05-29 14:26:00 +00001421 }
drha0c66f52000-07-29 13:20:21 +00001422 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001423 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001424 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +00001425 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +00001426 if( w<n ) w = n;
1427 }
1428 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001429 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001430 }
1431 if( p->showHeader ){
1432 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
1433 }
1434 }
1435 if( p->showHeader ){
1436 for(i=0; i<nArg; i++){
1437 int w;
1438 if( i<ArraySize(p->actualWidth) ){
1439 w = p->actualWidth[i];
1440 }else{
1441 w = 10;
1442 }
1443 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
1444 "----------------------------------------------------------",
1445 i==nArg-1 ? "\n": " ");
1446 }
drh75897232000-05-29 14:26:00 +00001447 }
1448 }
drh6a535342001-10-19 16:44:56 +00001449 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001450 for(i=0; i<nArg; i++){
1451 int w;
drha0c66f52000-07-29 13:20:21 +00001452 if( i<ArraySize(p->actualWidth) ){
1453 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001454 }else{
1455 w = 10;
1456 }
drhea678832008-12-10 19:26:22 +00001457 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +00001458 strlen30(azArg[i])>w ){
1459 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001460 }
drhc61053b2000-06-04 12:58:36 +00001461 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +00001462 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +00001463 }
1464 break;
1465 }
drhe3710332000-09-29 13:30:53 +00001466 case MODE_Semi:
drh75897232000-05-29 14:26:00 +00001467 case MODE_List: {
1468 if( p->cnt++==0 && p->showHeader ){
1469 for(i=0; i<nArg; i++){
1470 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
1471 }
1472 }
drh6a535342001-10-19 16:44:56 +00001473 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001474 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001475 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +00001476 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +00001477 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001478 if( i<nArg-1 ){
1479 fprintf(p->out, "%s", p->separator);
1480 }else if( p->mode==MODE_Semi ){
1481 fprintf(p->out, ";\n");
1482 }else{
1483 fprintf(p->out, "\n");
1484 }
drh75897232000-05-29 14:26:00 +00001485 }
1486 break;
1487 }
drh1e5d0e92000-05-31 23:33:17 +00001488 case MODE_Html: {
1489 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +00001490 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001491 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +00001492 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
drh1e5d0e92000-05-31 23:33:17 +00001493 }
mihailim57c591a2008-06-23 21:26:05 +00001494 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001495 }
drh6a535342001-10-19 16:44:56 +00001496 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +00001497 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001498 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +00001499 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +00001500 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +00001501 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001502 }
mihailim57c591a2008-06-23 21:26:05 +00001503 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001504 break;
1505 }
drhfeac5f82004-08-01 00:10:45 +00001506 case MODE_Tcl: {
1507 if( p->cnt++==0 && p->showHeader ){
1508 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001509 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +00001510 fprintf(p->out, "%s", p->separator);
1511 }
1512 fprintf(p->out,"\n");
1513 }
1514 if( azArg==0 ) break;
1515 for(i=0; i<nArg; i++){
1516 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
1517 fprintf(p->out, "%s", p->separator);
1518 }
1519 fprintf(p->out,"\n");
1520 break;
1521 }
drh8e64d1c2004-10-07 00:32:39 +00001522 case MODE_Csv: {
1523 if( p->cnt++==0 && p->showHeader ){
1524 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001525 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001526 }
1527 fprintf(p->out,"\n");
1528 }
1529 if( azArg==0 ) break;
1530 for(i=0; i<nArg; i++){
1531 output_csv(p, azArg[i], i<nArg-1);
1532 }
1533 fprintf(p->out,"\n");
1534 break;
1535 }
drh28bd4bc2000-06-15 15:57:22 +00001536 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +00001537 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +00001538 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +00001539 for(i=0; i<nArg; i++){
1540 char *zSep = i>0 ? ",": "";
1541 if( azArg[i]==0 ){
1542 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +00001543 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001544 fprintf(p->out,"%s%s",zSep, azArg[i]);
1545 }else{
1546 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1547 output_quoted_string(p->out, azArg[i]);
1548 }
1549 }
1550 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001551 break;
drh28bd4bc2000-06-15 15:57:22 +00001552 }
persicom1d0b8722002-04-18 02:53:04 +00001553 }
drh75897232000-05-29 14:26:00 +00001554 return 0;
1555}
1556
1557/*
drh33048c02001-10-01 14:29:22 +00001558** Set the destination table field of the callback_data structure to
1559** the name of the table given. Escape any quote characters in the
1560** table name.
1561*/
1562static void set_table_name(struct callback_data *p, const char *zName){
1563 int i, n;
1564 int needQuote;
1565 char *z;
1566
1567 if( p->zDestTable ){
1568 free(p->zDestTable);
1569 p->zDestTable = 0;
1570 }
1571 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001572 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001573 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001574 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001575 needQuote = 1;
1576 if( zName[i]=='\'' ) n++;
1577 }
1578 }
1579 if( needQuote ) n += 2;
1580 z = p->zDestTable = malloc( n+1 );
1581 if( z==0 ){
1582 fprintf(stderr,"Out of memory!\n");
1583 exit(1);
1584 }
1585 n = 0;
1586 if( needQuote ) z[n++] = '\'';
1587 for(i=0; zName[i]; i++){
1588 z[n++] = zName[i];
1589 if( zName[i]=='\'' ) z[n++] = '\'';
1590 }
1591 if( needQuote ) z[n++] = '\'';
1592 z[n] = 0;
1593}
1594
danielk19772a02e332004-06-05 08:04:36 +00001595/* zIn is either a pointer to a NULL-terminated string in memory obtained
1596** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1597** added to zIn, and the result returned in memory obtained from malloc().
1598** zIn, if it was not NULL, is freed.
1599**
1600** If the third argument, quote, is not '\0', then it is used as a
1601** quote character for zAppend.
1602*/
drhc28490c2006-10-26 14:25:58 +00001603static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001604 int len;
1605 int i;
drh4f21c4a2008-12-10 22:15:00 +00001606 int nAppend = strlen30(zAppend);
1607 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001608
1609 len = nAppend+nIn+1;
1610 if( quote ){
1611 len += 2;
1612 for(i=0; i<nAppend; i++){
1613 if( zAppend[i]==quote ) len++;
1614 }
1615 }
1616
1617 zIn = (char *)realloc(zIn, len);
1618 if( !zIn ){
1619 return 0;
1620 }
1621
1622 if( quote ){
1623 char *zCsr = &zIn[nIn];
1624 *zCsr++ = quote;
1625 for(i=0; i<nAppend; i++){
1626 *zCsr++ = zAppend[i];
1627 if( zAppend[i]==quote ) *zCsr++ = quote;
1628 }
1629 *zCsr++ = quote;
1630 *zCsr++ = '\0';
1631 assert( (zCsr-zIn)==len );
1632 }else{
1633 memcpy(&zIn[nIn], zAppend, nAppend);
1634 zIn[len-1] = '\0';
1635 }
1636
1637 return zIn;
1638}
1639
drhdd3d4592004-08-30 01:54:05 +00001640
1641/*
1642** Execute a query statement that has a single result column. Print
1643** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +00001644**
1645** This is used, for example, to show the schema of the database by
1646** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +00001647*/
1648static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
1649 sqlite3_stmt *pSelect;
1650 int rc;
1651 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
1652 if( rc!=SQLITE_OK || !pSelect ){
1653 return rc;
1654 }
1655 rc = sqlite3_step(pSelect);
1656 while( rc==SQLITE_ROW ){
1657 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
1658 rc = sqlite3_step(pSelect);
1659 }
1660 return sqlite3_finalize(pSelect);
1661}
1662
1663
drh33048c02001-10-01 14:29:22 +00001664/*
drh4c653a02000-06-07 01:27:47 +00001665** This is a different callback routine used for dumping the database.
1666** Each row received by this callback consists of a table name,
1667** the table type ("index" or "table") and SQL to create the table.
1668** This routine should print text sufficient to recreate the table.
1669*/
1670static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001671 int rc;
1672 const char *zTable;
1673 const char *zType;
1674 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +00001675 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001676
drh902b9ee2008-12-05 17:17:07 +00001677 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001678 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001679 zTable = azArg[0];
1680 zType = azArg[1];
1681 zSql = azArg[2];
1682
drh00b950d2005-09-11 02:03:03 +00001683 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +00001684 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +00001685 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1686 fprintf(p->out, "ANALYZE sqlite_master;\n");
1687 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1688 return 0;
drh45e29d82006-11-20 16:21:10 +00001689 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1690 char *zIns;
1691 if( !p->writableSchema ){
1692 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1693 p->writableSchema = 1;
1694 }
1695 zIns = sqlite3_mprintf(
1696 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1697 "VALUES('table','%q','%q',0,'%q');",
1698 zTable, zTable, zSql);
1699 fprintf(p->out, "%s\n", zIns);
1700 sqlite3_free(zIns);
1701 return 0;
drh00b950d2005-09-11 02:03:03 +00001702 }else{
1703 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001704 }
danielk19772a02e332004-06-05 08:04:36 +00001705
1706 if( strcmp(zType, "table")==0 ){
1707 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001708 char *zSelect = 0;
1709 char *zTableInfo = 0;
1710 char *zTmp = 0;
1711
1712 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1713 zTableInfo = appendText(zTableInfo, zTable, '"');
1714 zTableInfo = appendText(zTableInfo, ");", 0);
1715
1716 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
1717 if( zTableInfo ) free(zTableInfo);
1718 if( rc!=SQLITE_OK || !pTableInfo ){
1719 return 1;
1720 }
1721
1722 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1723 zTmp = appendText(zTmp, zTable, '"');
1724 if( zTmp ){
1725 zSelect = appendText(zSelect, zTmp, '\'');
1726 }
1727 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1728 rc = sqlite3_step(pTableInfo);
1729 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001730 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001731 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001732 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001733 rc = sqlite3_step(pTableInfo);
1734 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001735 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001736 }else{
1737 zSelect = appendText(zSelect, ") ", 0);
1738 }
1739 }
1740 rc = sqlite3_finalize(pTableInfo);
1741 if( rc!=SQLITE_OK ){
1742 if( zSelect ) free(zSelect);
1743 return 1;
1744 }
1745 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1746 zSelect = appendText(zSelect, zTable, '"');
1747
drhdd3d4592004-08-30 01:54:05 +00001748 rc = run_table_dump_query(p->out, p->db, zSelect);
1749 if( rc==SQLITE_CORRUPT ){
1750 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
1751 rc = run_table_dump_query(p->out, p->db, zSelect);
1752 }
danielk19772a02e332004-06-05 08:04:36 +00001753 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001754 }
drh4c653a02000-06-07 01:27:47 +00001755 return 0;
1756}
1757
1758/*
drh45e29d82006-11-20 16:21:10 +00001759** Run zQuery. Use dump_callback() as the callback routine so that
1760** the contents of the query are output as SQL statements.
1761**
drhdd3d4592004-08-30 01:54:05 +00001762** If we get a SQLITE_CORRUPT error, rerun the query after appending
1763** "ORDER BY rowid DESC" to the end.
1764*/
1765static int run_schema_dump_query(
1766 struct callback_data *p,
1767 const char *zQuery,
1768 char **pzErrMsg
1769){
1770 int rc;
1771 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1772 if( rc==SQLITE_CORRUPT ){
1773 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001774 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001775 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1776 zQ2 = malloc( len+100 );
1777 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001778 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001779 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1780 free(zQ2);
1781 }
1782 return rc;
1783}
1784
danielk1977c8c70692009-02-25 15:22:02 +00001785
1786#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
1787struct GenfkeyCmd {
1788 sqlite3 *db; /* Database handle */
1789 struct callback_data *pCb; /* Callback data */
1790 int isIgnoreErrors; /* True for --ignore-errors */
1791 int isExec; /* True for --exec */
1792 int isNoDrop; /* True for --no-drop */
1793 int nErr; /* Number of errors seen so far */
1794};
1795typedef struct GenfkeyCmd GenfkeyCmd;
1796
1797static int genfkeyParseArgs(GenfkeyCmd *p, char **azArg, int nArg){
1798 int ii;
1799 memset(p, 0, sizeof(GenfkeyCmd));
1800
1801 for(ii=0; ii<nArg; ii++){
shanec0688ea2009-03-05 03:48:06 +00001802 size_t n = strlen(azArg[ii]);
danielk1977c8c70692009-02-25 15:22:02 +00001803
1804 if( n>2 && n<10 && 0==strncmp(azArg[ii], "--no-drop", n) ){
1805 p->isNoDrop = 1;
1806 }else if( n>2 && n<16 && 0==strncmp(azArg[ii], "--ignore-errors", n) ){
1807 p->isIgnoreErrors = 1;
1808 }else if( n>2 && n<7 && 0==strncmp(azArg[ii], "--exec", n) ){
1809 p->isExec = 1;
1810 }else{
1811 fprintf(stderr, "unknown option: %s\n", azArg[ii]);
1812 return -1;
1813 }
1814 }
1815
1816 return SQLITE_OK;
1817}
1818
1819static int genfkeyCmdCb(void *pCtx, int eType, const char *z){
1820 GenfkeyCmd *p = (GenfkeyCmd *)pCtx;
1821 if( eType==GENFKEY_ERROR && !p->isIgnoreErrors ){
1822 p->nErr++;
1823 fprintf(stderr, "%s\n", z);
1824 }
1825
1826 if( p->nErr==0 && (
1827 (eType==GENFKEY_CREATETRIGGER)
1828 || (eType==GENFKEY_DROPTRIGGER && !p->isNoDrop)
1829 )){
1830 if( p->isExec ){
1831 sqlite3_exec(p->db, z, 0, 0, 0);
1832 }else{
1833 char *zCol = "sql";
1834 callback((void *)p->pCb, 1, (char **)&z, (char **)&zCol);
1835 }
1836 }
1837
1838 return SQLITE_OK;
1839}
1840#endif
1841
drhdd3d4592004-08-30 01:54:05 +00001842/*
drh75897232000-05-29 14:26:00 +00001843** Text of a help message
1844*/
persicom1d0b8722002-04-18 02:53:04 +00001845static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001846 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001847 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001848 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001849 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +00001850 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001851 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001852 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
danielk1977c8c70692009-02-25 15:22:02 +00001853#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
1854 ".genfkey ?OPTIONS? Options are:\n"
1855 " --no-drop: Do not drop old fkey triggers.\n"
1856 " --ignore-errors: Ignore tables with fkey errors\n"
1857 " --exec: Execute generated SQL immediately\n"
danielk1977e6320042009-02-25 15:43:57 +00001858 " See file tool/genfkey.README in the source \n"
1859 " distribution for further information.\n"
danielk1977c8c70692009-02-25 15:22:02 +00001860#endif
persicom7e2dfdd2002-04-18 02:46:52 +00001861 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001862 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001863 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +00001864 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +00001865#ifdef SQLITE_ENABLE_IOTRACE
1866 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1867#endif
drh70df4fe2006-06-13 15:12:21 +00001868#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001869 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001870#endif
danielk19776b77a362005-01-13 11:10:25 +00001871 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001872 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001873 " column Left-aligned columns. (See .width)\n"
1874 " html HTML <table> code\n"
1875 " insert SQL insert statements for TABLE\n"
1876 " line One value per line\n"
1877 " list Values delimited by .separator string\n"
1878 " tabs Tab-separated values\n"
1879 " tcl TCL list elements\n"
1880 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001881 ".output FILENAME Send output to FILENAME\n"
1882 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001883 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001884 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001885 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001886 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001887 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +00001888 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001889 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +00001890 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +00001891 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +00001892#if HAS_TIMER
1893 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1894#endif
drh75897232000-05-29 14:26:00 +00001895 ".width NUM NUM ... Set column widths for \"column\" mode\n"
1896;
1897
drhdaffd0e2001-04-11 14:28:42 +00001898/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001899static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001900
drh75897232000-05-29 14:26:00 +00001901/*
drh44c2eb12003-04-30 11:38:26 +00001902** Make sure the database is open. If it is not, then open it. If
1903** the database fails to open, print an error message and exit.
1904*/
1905static void open_db(struct callback_data *p){
1906 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001907 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001908 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001909 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1910 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1911 shellstaticFunc, 0, 0);
1912 }
1913 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +00001914 fprintf(stderr,"Unable to open database \"%s\": %s\n",
1915 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001916 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001917 }
drhc2e87a32006-06-27 15:16:14 +00001918#ifndef SQLITE_OMIT_LOAD_EXTENSION
1919 sqlite3_enable_load_extension(p->db, 1);
1920#endif
drh44c2eb12003-04-30 11:38:26 +00001921 }
1922}
1923
1924/*
drhfeac5f82004-08-01 00:10:45 +00001925** Do C-language style dequoting.
1926**
1927** \t -> tab
1928** \n -> newline
1929** \r -> carriage return
1930** \NNN -> ascii character NNN in octal
1931** \\ -> backslash
1932*/
1933static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001934 int i, j;
1935 char c;
drhfeac5f82004-08-01 00:10:45 +00001936 for(i=j=0; (c = z[i])!=0; i++, j++){
1937 if( c=='\\' ){
1938 c = z[++i];
1939 if( c=='n' ){
1940 c = '\n';
1941 }else if( c=='t' ){
1942 c = '\t';
1943 }else if( c=='r' ){
1944 c = '\r';
1945 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001946 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001947 if( z[i+1]>='0' && z[i+1]<='7' ){
1948 i++;
1949 c = (c<<3) + z[i] - '0';
1950 if( z[i+1]>='0' && z[i+1]<='7' ){
1951 i++;
1952 c = (c<<3) + z[i] - '0';
1953 }
1954 }
1955 }
1956 }
1957 z[j] = c;
1958 }
1959 z[j] = 0;
1960}
1961
1962/*
drhc28490c2006-10-26 14:25:58 +00001963** Interpret zArg as a boolean value. Return either 0 or 1.
1964*/
1965static int booleanValue(char *zArg){
1966 int val = atoi(zArg);
1967 int j;
1968 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001969 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001970 }
1971 if( strcmp(zArg,"on")==0 ){
1972 val = 1;
1973 }else if( strcmp(zArg,"yes")==0 ){
1974 val = 1;
1975 }
1976 return val;
1977}
1978
1979/*
drh75897232000-05-29 14:26:00 +00001980** If an input line begins with "." then invoke this routine to
1981** process that line.
drh67505e72002-04-19 12:34:06 +00001982**
drh47ad6842006-11-08 12:25:42 +00001983** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001984*/
drh44c2eb12003-04-30 11:38:26 +00001985static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001986 int i = 1;
1987 int nArg = 0;
1988 int n, c;
drh67505e72002-04-19 12:34:06 +00001989 int rc = 0;
drh75897232000-05-29 14:26:00 +00001990 char *azArg[50];
1991
1992 /* Parse the input line into tokens.
1993 */
1994 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001995 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001996 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001997 if( zLine[i]=='\'' || zLine[i]=='"' ){
1998 int delim = zLine[i++];
1999 azArg[nArg++] = &zLine[i];
2000 while( zLine[i] && zLine[i]!=delim ){ i++; }
2001 if( zLine[i]==delim ){
2002 zLine[i++] = 0;
2003 }
drhfeac5f82004-08-01 00:10:45 +00002004 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002005 }else{
2006 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00002007 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002008 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002009 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002010 }
2011 }
2012
2013 /* Process the input line.
2014 */
drh67505e72002-04-19 12:34:06 +00002015 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00002016 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002017 c = azArg[0][0];
drh9ff849f2009-02-04 20:55:57 +00002018 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){
2019 const char *zDestFile;
2020 const char *zDb;
2021 sqlite3 *pDest;
2022 sqlite3_backup *pBackup;
2023 int rc;
2024 if( nArg==2 ){
2025 zDestFile = azArg[1];
2026 zDb = "main";
2027 }else{
2028 zDestFile = azArg[2];
2029 zDb = azArg[1];
2030 }
2031 rc = sqlite3_open(zDestFile, &pDest);
2032 if( rc!=SQLITE_OK ){
2033 fprintf(stderr, "Error: cannot open %s\n", zDestFile);
2034 sqlite3_close(pDest);
2035 return 1;
2036 }
drhdc2c4912009-02-04 22:46:47 +00002037 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002038 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2039 if( pBackup==0 ){
2040 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2041 sqlite3_close(pDest);
2042 return 1;
2043 }
2044 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2045 sqlite3_backup_finish(pBackup);
2046 if( rc==SQLITE_DONE ){
2047 rc = SQLITE_OK;
2048 }else{
2049 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2050 }
2051 sqlite3_close(pDest);
2052 }else
2053
2054 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
drhc49f44e2006-10-26 18:15:42 +00002055 bail_on_error = booleanValue(azArg[1]);
2056 }else
2057
jplyon6a65bb32003-05-04 07:25:57 +00002058 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00002059 struct callback_data data;
2060 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00002061 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00002062 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002063 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002064 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002065 data.colWidth[0] = 3;
2066 data.colWidth[1] = 15;
2067 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002068 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002069 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002070 if( zErrMsg ){
2071 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002072 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00002073 }
2074 }else
2075
drh4c653a02000-06-07 01:27:47 +00002076 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
2077 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002078 open_db(p);
drh33048c02001-10-01 14:29:22 +00002079 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002080 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00002081 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002082 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002083 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002084 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002085 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00002086 );
2087 run_table_dump_query(p->out, p->db,
2088 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002089 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00002090 );
drh4c653a02000-06-07 01:27:47 +00002091 }else{
2092 int i;
drhdd3d4592004-08-30 01:54:05 +00002093 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002094 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002095 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002096 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002097 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00002098 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00002099 run_table_dump_query(p->out, p->db,
2100 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002101 "WHERE sql NOT NULL"
2102 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00002103 " AND tbl_name LIKE shellstatic()"
2104 );
danielk1977bc6ada42004-06-30 08:20:16 +00002105 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002106 }
2107 }
drh45e29d82006-11-20 16:21:10 +00002108 if( p->writableSchema ){
2109 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
2110 p->writableSchema = 0;
2111 }
drh93f41e52008-08-11 19:12:34 +00002112 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002113 if( zErrMsg ){
2114 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002115 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00002116 }else{
2117 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002118 }
2119 }else
drh75897232000-05-29 14:26:00 +00002120
drhdaffd0e2001-04-11 14:28:42 +00002121 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002122 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00002123 }else
2124
drh75897232000-05-29 14:26:00 +00002125 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002126 rc = 2;
drh75897232000-05-29 14:26:00 +00002127 }else
2128
drhdd45df82002-04-18 12:39:03 +00002129 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002130 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002131 if(val == 1) {
2132 if(!p->explainPrev.valid) {
2133 p->explainPrev.valid = 1;
2134 p->explainPrev.mode = p->mode;
2135 p->explainPrev.showHeader = p->showHeader;
2136 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
2137 }
2138 /* We could put this code under the !p->explainValid
2139 ** condition so that it does not execute if we are already in
2140 ** explain mode. However, always executing it allows us an easy
2141 ** was to reset to explain mode in case the user previously
2142 ** did an .explain followed by a .width, .mode or .header
2143 ** command.
2144 */
danielk19770d78bae2008-01-03 07:09:48 +00002145 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002146 p->showHeader = 1;
2147 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002148 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002149 p->colWidth[1] = 13; /* opcode */
2150 p->colWidth[2] = 4; /* P1 */
2151 p->colWidth[3] = 4; /* P2 */
2152 p->colWidth[4] = 4; /* P3 */
2153 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002154 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002155 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00002156 }else if (p->explainPrev.valid) {
2157 p->explainPrev.valid = 0;
2158 p->mode = p->explainPrev.mode;
2159 p->showHeader = p->explainPrev.showHeader;
2160 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2161 }
drh75897232000-05-29 14:26:00 +00002162 }else
2163
danielk1977c8c70692009-02-25 15:22:02 +00002164#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
2165 if( c=='g' && strncmp(azArg[0], "genfkey", n)==0 ){
2166 GenfkeyCmd cmd;
2167 if( 0==genfkeyParseArgs(&cmd, &azArg[1], nArg-1) ){
2168 cmd.db = p->db;
2169 cmd.pCb = p;
2170 genfkey_create_triggers(p->db, "main", (void *)&cmd, genfkeyCmdCb);
2171 }
2172 }else
2173#endif
2174
drhc28490c2006-10-26 14:25:58 +00002175 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00002176 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002177 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00002178 }else
2179
2180 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00002181 fprintf(stderr,"%s",zHelp);
drh75897232000-05-29 14:26:00 +00002182 }else
2183
drhfeac5f82004-08-01 00:10:45 +00002184 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
2185 char *zTable = azArg[2]; /* Insert data into this table */
2186 char *zFile = azArg[1]; /* The file from which to extract data */
2187 sqlite3_stmt *pStmt; /* A statement */
2188 int rc; /* Result code */
2189 int nCol; /* Number of columns in the table */
2190 int nByte; /* Number of bytes in an SQL string */
2191 int i, j; /* Loop counters */
2192 int nSep; /* Number of bytes in p->separator[] */
2193 char *zSql; /* An SQL statement */
2194 char *zLine; /* A single line of input from the file */
2195 char **azCol; /* zLine[] broken up into columns */
2196 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00002197 FILE *in; /* The input file */
2198 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00002199
drha543c822006-06-08 16:10:14 +00002200 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002201 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002202 if( nSep==0 ){
2203 fprintf(stderr, "non-null separator required for import\n");
2204 return 0;
2205 }
2206 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
2207 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00002208 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002209 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002210 sqlite3_free(zSql);
2211 if( rc ){
2212 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2213 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00002214 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002215 }else{
2216 nCol = sqlite3_column_count(pStmt);
2217 }
2218 sqlite3_finalize(pStmt);
2219 if( nCol==0 ) return 0;
2220 zSql = malloc( nByte + 20 + nCol*2 );
2221 if( zSql==0 ) return 0;
2222 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002223 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002224 for(i=1; i<nCol; i++){
2225 zSql[j++] = ',';
2226 zSql[j++] = '?';
2227 }
2228 zSql[j++] = ')';
2229 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002230 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002231 free(zSql);
2232 if( rc ){
2233 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
2234 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00002235 return 1;
drhfeac5f82004-08-01 00:10:45 +00002236 }
2237 in = fopen(zFile, "rb");
2238 if( in==0 ){
2239 fprintf(stderr, "cannot open file: %s\n", zFile);
2240 sqlite3_finalize(pStmt);
2241 return 0;
2242 }
2243 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00002244 if( azCol==0 ){
2245 fclose(in);
2246 return 0;
2247 }
drhfeac5f82004-08-01 00:10:45 +00002248 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
2249 zCommit = "COMMIT";
2250 while( (zLine = local_getline(0, in))!=0 ){
2251 char *z;
2252 i = 0;
drhb860bc92004-08-04 15:16:55 +00002253 lineno++;
drhfeac5f82004-08-01 00:10:45 +00002254 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00002255 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00002256 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
2257 *z = 0;
2258 i++;
drhb860bc92004-08-04 15:16:55 +00002259 if( i<nCol ){
2260 azCol[i] = &z[nSep];
2261 z += nSep-1;
2262 }
drhfeac5f82004-08-01 00:10:45 +00002263 }
2264 }
drh1cd7f832005-08-05 18:50:51 +00002265 *z = 0;
drhb860bc92004-08-04 15:16:55 +00002266 if( i+1!=nCol ){
2267 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
2268 zFile, lineno, nCol, i+1);
2269 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00002270 free(zLine);
drhb860bc92004-08-04 15:16:55 +00002271 break;
2272 }
drhfeac5f82004-08-01 00:10:45 +00002273 for(i=0; i<nCol; i++){
2274 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2275 }
2276 sqlite3_step(pStmt);
2277 rc = sqlite3_reset(pStmt);
2278 free(zLine);
2279 if( rc!=SQLITE_OK ){
2280 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2281 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00002282 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002283 break;
2284 }
2285 }
2286 free(azCol);
2287 fclose(in);
2288 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00002289 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002290 }else
2291
drh75897232000-05-29 14:26:00 +00002292 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
2293 struct callback_data data;
2294 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002295 open_db(p);
drh75897232000-05-29 14:26:00 +00002296 memcpy(&data, p, sizeof(data));
2297 data.showHeader = 0;
2298 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00002299 zShellStatic = azArg[1];
2300 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00002301 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002302 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002303 "UNION ALL "
2304 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002305 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002306 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002307 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002308 );
danielk1977bc6ada42004-06-30 08:20:16 +00002309 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00002310 if( zErrMsg ){
2311 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002312 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002313 }
2314 }else
2315
drhae5e4452007-05-03 17:18:36 +00002316#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002317 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002318 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002319 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2320 iotrace = 0;
2321 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002322 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002323 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002324 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002325 iotrace = stdout;
2326 }else{
2327 iotrace = fopen(azArg[1], "w");
2328 if( iotrace==0 ){
2329 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002330 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002331 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002332 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002333 }
2334 }
2335 }else
drhae5e4452007-05-03 17:18:36 +00002336#endif
drhb0603412007-02-28 04:47:26 +00002337
drh70df4fe2006-06-13 15:12:21 +00002338#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002339 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2340 const char *zFile, *zProc;
2341 char *zErrMsg = 0;
2342 int rc;
2343 zFile = azArg[1];
2344 zProc = nArg>=3 ? azArg[2] : 0;
2345 open_db(p);
2346 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2347 if( rc!=SQLITE_OK ){
2348 fprintf(stderr, "%s\n", zErrMsg);
2349 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002350 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002351 }
2352 }else
drh70df4fe2006-06-13 15:12:21 +00002353#endif
drh1e397f82006-06-08 15:28:43 +00002354
drh28bd4bc2000-06-15 15:57:22 +00002355 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00002356 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002357 if( strncmp(azArg[1],"line",n2)==0
2358 ||
2359 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002360 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00002361 }else if( strncmp(azArg[1],"column",n2)==0
2362 ||
2363 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002364 p->mode = MODE_Column;
2365 }else if( strncmp(azArg[1],"list",n2)==0 ){
2366 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00002367 }else if( strncmp(azArg[1],"html",n2)==0 ){
2368 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00002369 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
2370 p->mode = MODE_Tcl;
2371 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002372 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002373 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00002374 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
2375 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002376 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00002377 }else if( strncmp(azArg[1],"insert",n2)==0 ){
2378 p->mode = MODE_Insert;
2379 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00002380 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00002381 }else{
drh33048c02001-10-01 14:29:22 +00002382 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00002383 }
drhdaffd0e2001-04-11 14:28:42 +00002384 }else {
drhcf68ae92006-12-19 18:47:41 +00002385 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002386 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00002387 }
2388 }else
2389
persicom7e2dfdd2002-04-18 02:46:52 +00002390 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002391 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2392 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002393 }else
2394
drh75897232000-05-29 14:26:00 +00002395 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
2396 if( p->out!=stdout ){
2397 fclose(p->out);
2398 }
2399 if( strcmp(azArg[1],"stdout")==0 ){
2400 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00002401 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00002402 }else{
drha1f9b5e2004-02-14 16:31:02 +00002403 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00002404 if( p->out==0 ){
2405 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
2406 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00002407 } else {
drh5bb3eb92007-05-04 13:15:55 +00002408 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002409 }
2410 }
2411 }else
2412
drhdd45df82002-04-18 12:39:03 +00002413 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002414 if( nArg >= 2) {
2415 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2416 }
2417 if( nArg >= 3) {
2418 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2419 }
2420 }else
2421
2422 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002423 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002424 }else
2425
drh9ff849f2009-02-04 20:55:57 +00002426 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002427 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002428 if( alt==0 ){
2429 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
2430 }else{
2431 process_input(p, alt);
2432 fclose(alt);
2433 }
2434 }else
2435
drh9ff849f2009-02-04 20:55:57 +00002436 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){
2437 const char *zSrcFile;
2438 const char *zDb;
2439 sqlite3 *pSrc;
2440 sqlite3_backup *pBackup;
2441 int rc;
drhdc2c4912009-02-04 22:46:47 +00002442 int nTimeout = 0;
2443
drh9ff849f2009-02-04 20:55:57 +00002444 if( nArg==2 ){
2445 zSrcFile = azArg[1];
2446 zDb = "main";
2447 }else{
2448 zSrcFile = azArg[2];
2449 zDb = azArg[1];
2450 }
2451 rc = sqlite3_open(zSrcFile, &pSrc);
2452 if( rc!=SQLITE_OK ){
2453 fprintf(stderr, "Error: cannot open %s\n", zSrcFile);
2454 sqlite3_close(pSrc);
2455 return 1;
2456 }
drhdc2c4912009-02-04 22:46:47 +00002457 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002458 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2459 if( pBackup==0 ){
2460 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2461 sqlite3_close(pSrc);
2462 return 1;
2463 }
drhdc2c4912009-02-04 22:46:47 +00002464 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2465 || rc==SQLITE_BUSY ){
2466 if( rc==SQLITE_BUSY ){
2467 if( nTimeout++ >= 3 ) break;
2468 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002469 }
2470 }
2471 sqlite3_backup_finish(pBackup);
2472 if( rc==SQLITE_DONE ){
2473 rc = SQLITE_OK;
drhdc2c4912009-02-04 22:46:47 +00002474 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2475 fprintf(stderr, "source database is busy\n");
drh9ff849f2009-02-04 20:55:57 +00002476 }else{
2477 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2478 }
2479 sqlite3_close(pSrc);
2480 }else
2481
drh75897232000-05-29 14:26:00 +00002482 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
2483 struct callback_data data;
2484 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002485 open_db(p);
drh75897232000-05-29 14:26:00 +00002486 memcpy(&data, p, sizeof(data));
2487 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002488 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002489 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002490 int i;
shane7d3846a2008-12-11 02:58:26 +00002491 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002492 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002493 char *new_argv[2], *new_colv[2];
2494 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2495 " type text,\n"
2496 " name text,\n"
2497 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002498 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002499 " sql text\n"
2500 ")";
2501 new_argv[1] = 0;
2502 new_colv[0] = "sql";
2503 new_colv[1] = 0;
2504 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00002505 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002506 char *new_argv[2], *new_colv[2];
2507 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2508 " type text,\n"
2509 " name text,\n"
2510 " tbl_name text,\n"
2511 " rootpage integer,\n"
2512 " sql text\n"
2513 ")";
2514 new_argv[1] = 0;
2515 new_colv[0] = "sql";
2516 new_colv[1] = 0;
2517 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00002518 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002519 zShellStatic = azArg[1];
2520 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002521 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002522 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2523 " FROM sqlite_master UNION ALL"
2524 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002525 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002526 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002527 callback, &data, &zErrMsg);
2528 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002529 }
drh75897232000-05-29 14:26:00 +00002530 }else{
danielk19776f8a5032004-05-10 10:34:51 +00002531 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002532 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002533 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2534 " FROM sqlite_master UNION ALL"
2535 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002536 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002537 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002538 callback, &data, &zErrMsg
2539 );
drh75897232000-05-29 14:26:00 +00002540 }
drh75897232000-05-29 14:26:00 +00002541 if( zErrMsg ){
2542 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002543 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002544 }
2545 }else
2546
2547 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002548 sqlite3_snprintf(sizeof(p->separator), p->separator,
2549 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002550 }else
2551
persicom7e2dfdd2002-04-18 02:46:52 +00002552 if( c=='s' && strncmp(azArg[0], "show", n)==0){
2553 int i;
2554 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002555 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002556 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002557 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002558 fprintf(p->out,"%9.9s: ", "nullvalue");
2559 output_c_string(p->out, p->nullvalue);
2560 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002561 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002562 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002563 fprintf(p->out,"%9.9s: ", "separator");
2564 output_c_string(p->out, p->separator);
2565 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002566 fprintf(p->out,"%9.9s: ","width");
2567 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002568 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002569 }
drhfeac5f82004-08-01 00:10:45 +00002570 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002571 }else
2572
drh2dfbbca2000-07-28 14:32:48 +00002573 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00002574 char **azResult;
2575 int nRow, rc;
2576 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002577 open_db(p);
drha50da102000-08-08 20:19:09 +00002578 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002579 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002580 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00002581 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002582 "UNION ALL "
2583 "SELECT name FROM sqlite_temp_master "
2584 "WHERE type IN ('table','view') "
2585 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002586 &azResult, &nRow, 0, &zErrMsg
2587 );
drha50da102000-08-08 20:19:09 +00002588 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002589 zShellStatic = azArg[1];
2590 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002591 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002592 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002593 "UNION ALL "
2594 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002595 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002596 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002597 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002598 );
danielk1977bc6ada42004-06-30 08:20:16 +00002599 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002600 }
drh75897232000-05-29 14:26:00 +00002601 if( zErrMsg ){
2602 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002603 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002604 }
drhe3710332000-09-29 13:30:53 +00002605 if( rc==SQLITE_OK ){
2606 int len, maxlen = 0;
2607 int i, j;
2608 int nPrintCol, nPrintRow;
2609 for(i=1; i<=nRow; i++){
2610 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002611 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002612 if( len>maxlen ) maxlen = len;
2613 }
2614 nPrintCol = 80/(maxlen+2);
2615 if( nPrintCol<1 ) nPrintCol = 1;
2616 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2617 for(i=0; i<nPrintRow; i++){
2618 for(j=i+1; j<=nRow; j+=nPrintRow){
2619 char *zSp = j<=nPrintRow ? "" : " ";
2620 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2621 }
2622 printf("\n");
2623 }
drh47ad6842006-11-08 12:25:42 +00002624 }else{
2625 rc = 1;
drhe3710332000-09-29 13:30:53 +00002626 }
danielk19776f8a5032004-05-10 10:34:51 +00002627 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002628 }else
2629
drh3b1a9882007-11-02 12:53:03 +00002630 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00002631 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002632 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00002633 }else
drh3b1a9882007-11-02 12:53:03 +00002634
2635#if HAS_TIMER
2636 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
2637 enableTimer = booleanValue(azArg[1]);
2638 }else
2639#endif
drh2dfbbca2000-07-28 14:32:48 +00002640
drh75897232000-05-29 14:26:00 +00002641 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
2642 int j;
drh43617e92006-03-06 20:55:46 +00002643 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002644 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2645 p->colWidth[j-1] = atoi(azArg[j]);
2646 }
2647 }else
2648
drh3b1a9882007-11-02 12:53:03 +00002649
drh75897232000-05-29 14:26:00 +00002650 {
drh67505e72002-04-19 12:34:06 +00002651 fprintf(stderr, "unknown command or invalid arguments: "
2652 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00002653 }
drh67505e72002-04-19 12:34:06 +00002654
2655 return rc;
drh75897232000-05-29 14:26:00 +00002656}
2657
drh67505e72002-04-19 12:34:06 +00002658/*
drh91a66392007-09-07 01:12:32 +00002659** Return TRUE if a semicolon occurs anywhere in the first N characters
2660** of string z[].
drh324ccef2003-02-05 14:06:20 +00002661*/
drh91a66392007-09-07 01:12:32 +00002662static int _contains_semicolon(const char *z, int N){
2663 int i;
2664 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2665 return 0;
drh324ccef2003-02-05 14:06:20 +00002666}
2667
2668/*
drh70c7a4b2003-04-26 03:03:06 +00002669** Test to see if a line consists entirely of whitespace.
2670*/
2671static int _all_whitespace(const char *z){
2672 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002673 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002674 if( *z=='/' && z[1]=='*' ){
2675 z += 2;
2676 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2677 if( *z==0 ) return 0;
2678 z++;
2679 continue;
2680 }
2681 if( *z=='-' && z[1]=='-' ){
2682 z += 2;
2683 while( *z && *z!='\n' ){ z++; }
2684 if( *z==0 ) return 1;
2685 continue;
2686 }
2687 return 0;
2688 }
2689 return 1;
2690}
2691
2692/*
drha9b17162003-04-29 18:01:28 +00002693** Return TRUE if the line typed in is an SQL command terminator other
2694** than a semi-colon. The SQL Server style "go" command is understood
2695** as is the Oracle "/".
2696*/
2697static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002698 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002699 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2700 return 1; /* Oracle */
2701 }
drhc8d74412004-08-31 23:41:26 +00002702 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2703 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002704 return 1; /* SQL Server */
2705 }
2706 return 0;
2707}
2708
2709/*
drh233a5312008-12-18 22:25:13 +00002710** Return true if zSql is a complete SQL statement. Return false if it
2711** ends in the middle of a string literal or C-style comment.
2712*/
2713static int _is_complete(char *zSql, int nSql){
2714 int rc;
2715 if( zSql==0 ) return 1;
2716 zSql[nSql] = ';';
2717 zSql[nSql+1] = 0;
2718 rc = sqlite3_complete(zSql);
2719 zSql[nSql] = 0;
2720 return rc;
2721}
2722
2723/*
drh67505e72002-04-19 12:34:06 +00002724** Read input from *in and process it. If *in==0 then input
2725** is interactive - the user is typing it it. Otherwise, input
2726** is coming from a file or device. A prompt is issued and history
2727** is saved only if input is interactive. An interrupt signal will
2728** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002729**
2730** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002731*/
drhc28490c2006-10-26 14:25:58 +00002732static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002733 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002734 char *zSql = 0;
2735 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002736 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002737 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002738 int rc;
2739 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002740 int lineno = 0;
2741 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002742
2743 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2744 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002745 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002746 zLine = one_input_line(zSql, in);
2747 if( zLine==0 ){
2748 break; /* We have reached EOF */
2749 }
drh67505e72002-04-19 12:34:06 +00002750 if( seenInterrupt ){
2751 if( in!=0 ) break;
2752 seenInterrupt = 0;
2753 }
drhc28490c2006-10-26 14:25:58 +00002754 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00002755 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00002756 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002757 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00002758 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00002759 if( rc==2 ){
2760 break;
2761 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002762 errCnt++;
2763 }
drhdaffd0e2001-04-11 14:28:42 +00002764 continue;
2765 }
drh233a5312008-12-18 22:25:13 +00002766 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002767 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002768 }
drh91a66392007-09-07 01:12:32 +00002769 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002770 if( zSql==0 ){
2771 int i;
drh4c755c02004-08-08 20:22:17 +00002772 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002773 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002774 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002775 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002776 if( zSql==0 ){
2777 fprintf(stderr, "out of memory\n");
2778 exit(1);
2779 }
drh5bb3eb92007-05-04 13:15:55 +00002780 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002781 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002782 }
2783 }else{
drh4f21c4a2008-12-10 22:15:00 +00002784 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002785 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002786 if( zSql==0 ){
2787 fprintf(stderr,"%s: out of memory!\n", Argv0);
2788 exit(1);
2789 }
drh5bb3eb92007-05-04 13:15:55 +00002790 zSql[nSql++] = '\n';
2791 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002792 nSql += len;
2793 }
drh91a66392007-09-07 01:12:32 +00002794 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2795 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002796 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002797 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002798 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00002799 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002800 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002801 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002802 char zPrefix[100];
2803 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002804 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
2805 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002806 }else{
drh5bb3eb92007-05-04 13:15:55 +00002807 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00002808 }
drh7f953e22002-07-13 17:33:45 +00002809 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00002810 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002811 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002812 zErrMsg = 0;
2813 }else{
drhc28490c2006-10-26 14:25:58 +00002814 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002815 }
drhc49f44e2006-10-26 18:15:42 +00002816 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002817 }
2818 free(zSql);
2819 zSql = 0;
2820 nSql = 0;
2821 }
2822 }
2823 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00002824 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002825 free(zSql);
2826 }
danielk19772ac27622007-07-03 05:31:16 +00002827 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002828 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002829}
2830
drh67505e72002-04-19 12:34:06 +00002831/*
2832** Return a pathname which is the user's home directory. A
2833** 0 return indicates an error of some kind. Space to hold the
2834** resulting string is obtained from malloc(). The calling
2835** function should free the result.
2836*/
2837static char *find_home_dir(void){
2838 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002839
chw97185482008-11-17 08:05:31 +00002840#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002841 struct passwd *pwent;
2842 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002843 if( (pwent=getpwuid(uid)) != NULL) {
2844 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002845 }
2846#endif
2847
chw65d3c132007-11-12 21:09:10 +00002848#if defined(_WIN32_WCE)
2849 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2850 */
2851 home_dir = strdup("/");
2852#else
2853
drh164a1b62006-08-19 11:15:20 +00002854#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2855 if (!home_dir) {
2856 home_dir = getenv("USERPROFILE");
2857 }
2858#endif
2859
drh67505e72002-04-19 12:34:06 +00002860 if (!home_dir) {
2861 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002862 }
2863
drhcdb36b72006-06-12 12:57:45 +00002864#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002865 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002866 char *zDrive, *zPath;
2867 int n;
2868 zDrive = getenv("HOMEDRIVE");
2869 zPath = getenv("HOMEPATH");
2870 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002871 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002872 home_dir = malloc( n );
2873 if( home_dir==0 ) return 0;
2874 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2875 return home_dir;
2876 }
2877 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002878 }
2879#endif
2880
chw65d3c132007-11-12 21:09:10 +00002881#endif /* !_WIN32_WCE */
2882
drh67505e72002-04-19 12:34:06 +00002883 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002884 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002885 char *z = malloc( n );
2886 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002887 home_dir = z;
2888 }
drhe98d4fa2002-04-21 19:06:22 +00002889
drh67505e72002-04-19 12:34:06 +00002890 return home_dir;
2891}
2892
2893/*
2894** Read input from the file given by sqliterc_override. Or if that
2895** parameter is NULL, take input from ~/.sqliterc
2896*/
drh22fbcb82004-02-01 01:22:50 +00002897static void process_sqliterc(
2898 struct callback_data *p, /* Configuration data */
2899 const char *sqliterc_override /* Name of config file. NULL to use default */
2900){
persicom7e2dfdd2002-04-18 02:46:52 +00002901 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002902 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002903 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002904 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002905 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002906
2907 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002908 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002909 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002910#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00002911 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00002912#endif
drhe98d4fa2002-04-21 19:06:22 +00002913 return;
2914 }
drh4f21c4a2008-12-10 22:15:00 +00002915 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002916 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002917 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002918 fprintf(stderr,"%s: out of memory!\n", Argv0);
2919 exit(1);
2920 }
drha959ac42007-06-20 13:10:00 +00002921 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002922 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002923 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002924 }
drha1f9b5e2004-02-14 16:31:02 +00002925 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002926 if( in ){
drhc28490c2006-10-26 14:25:58 +00002927 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00002928 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002929 }
persicom7e2dfdd2002-04-18 02:46:52 +00002930 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002931 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002932 }
drh43617e92006-03-06 20:55:46 +00002933 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00002934 return;
2935}
2936
drh67505e72002-04-19 12:34:06 +00002937/*
drhe1e38c42003-05-04 18:30:59 +00002938** Show available command line options
2939*/
2940static const char zOptions[] =
2941 " -init filename read/process named file\n"
2942 " -echo print commands before execution\n"
2943 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002944 " -bail stop after hitting an error\n"
2945 " -interactive force interactive I/O\n"
2946 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002947 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002948 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002949 " -html set output mode to HTML\n"
2950 " -line set output mode to 'line'\n"
2951 " -list set output mode to 'list'\n"
2952 " -separator 'x' set output field separator (|)\n"
2953 " -nullvalue 'text' set text string for NULL values\n"
2954 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002955;
2956static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002957 fprintf(stderr,
2958 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2959 "FILENAME is the name of an SQLite database. A new database is created\n"
2960 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002961 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002962 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002963 }else{
2964 fprintf(stderr, "Use the -help option for additional information\n");
2965 }
2966 exit(1);
2967}
2968
2969/*
drh67505e72002-04-19 12:34:06 +00002970** Initialize the state information in data
2971*/
drh0850b532006-01-31 19:31:43 +00002972static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002973 memset(data, 0, sizeof(*data));
2974 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002975 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002976 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00002977 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2978 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00002979}
2980
drh75897232000-05-29 14:26:00 +00002981int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002982 char *zErrMsg = 0;
2983 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002984 const char *zInitFile = 0;
2985 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002986 int i;
drhc28490c2006-10-26 14:25:58 +00002987 int rc = 0;
drh75897232000-05-29 14:26:00 +00002988
drhdaffd0e2001-04-11 14:28:42 +00002989 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002990 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002991 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002992
drh44c2eb12003-04-30 11:38:26 +00002993 /* Make sure we have a valid signal handler early, before anything
2994 ** else is done.
2995 */
drh4c504392000-10-16 22:06:40 +00002996#ifdef SIGINT
2997 signal(SIGINT, interrupt_handler);
2998#endif
drh44c2eb12003-04-30 11:38:26 +00002999
drh22fbcb82004-02-01 01:22:50 +00003000 /* Do an initial pass through the command-line argument to locate
3001 ** the name of the database file, the name of the initialization file,
3002 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003003 */
drh22fbcb82004-02-01 01:22:50 +00003004 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00003005 char *z;
drh44c2eb12003-04-30 11:38:26 +00003006 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00003007 z = argv[i];
3008 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00003009 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
3010 i++;
drh22fbcb82004-02-01 01:22:50 +00003011 }else if( strcmp(argv[i],"-init")==0 ){
3012 i++;
3013 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00003014 }
3015 }
drh22fbcb82004-02-01 01:22:50 +00003016 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00003017#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00003018 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
3019#else
drh22fbcb82004-02-01 01:22:50 +00003020 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00003021#endif
drh22fbcb82004-02-01 01:22:50 +00003022 }else{
danielk197703aded42004-11-22 05:26:27 +00003023#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003024 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003025#else
3026 data.zDbFilename = 0;
3027#endif
drh22fbcb82004-02-01 01:22:50 +00003028 }
3029 if( i<argc ){
3030 zFirstCmd = argv[i++];
3031 }
drh44c2eb12003-04-30 11:38:26 +00003032 data.out = stdout;
3033
drh01b41712005-08-29 23:06:23 +00003034#ifdef SQLITE_OMIT_MEMORYDB
3035 if( data.zDbFilename==0 ){
3036 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
3037 exit(1);
3038 }
3039#endif
3040
drh44c2eb12003-04-30 11:38:26 +00003041 /* Go ahead and open the database file if it already exists. If the
3042 ** file does not exist, delay opening it. This prevents empty database
3043 ** files from being created if a user mistypes the database name argument
3044 ** to the sqlite command-line tool.
3045 */
drhc8d74412004-08-31 23:41:26 +00003046 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003047 open_db(&data);
3048 }
3049
drh22fbcb82004-02-01 01:22:50 +00003050 /* Process the initialization file if there is one. If no -init option
3051 ** is given on the command line, look for a file named ~/.sqliterc and
3052 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003053 */
drh22fbcb82004-02-01 01:22:50 +00003054 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00003055
drh22fbcb82004-02-01 01:22:50 +00003056 /* Make a second pass through the command-line argument and set
3057 ** options. This second pass is delayed until after the initialization
3058 ** file is processed so that the command-line arguments will override
3059 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003060 */
drh22fbcb82004-02-01 01:22:50 +00003061 for(i=1; i<argc && argv[i][0]=='-'; i++){
3062 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00003063 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003064 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003065 i++;
3066 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003067 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003068 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003069 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003070 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003071 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003072 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003073 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003074 }else if( strcmp(z,"-csv")==0 ){
3075 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003076 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003077 }else if( strcmp(z,"-separator")==0 ){
3078 i++;
drh5bb3eb92007-05-04 13:15:55 +00003079 sqlite3_snprintf(sizeof(data.separator), data.separator,
3080 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003081 }else if( strcmp(z,"-nullvalue")==0 ){
3082 i++;
drh5bb3eb92007-05-04 13:15:55 +00003083 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
3084 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003085 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003086 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003087 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003088 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003089 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003090 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003091 }else if( strcmp(z,"-bail")==0 ){
3092 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003093 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00003094 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00003095 return 0;
drhc28490c2006-10-26 14:25:58 +00003096 }else if( strcmp(z,"-interactive")==0 ){
3097 stdin_is_interactive = 1;
3098 }else if( strcmp(z,"-batch")==0 ){
3099 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00003100 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003101 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00003102 }else{
drh22fbcb82004-02-01 01:22:50 +00003103 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003104 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003105 return 1;
3106 }
3107 }
drh44c2eb12003-04-30 11:38:26 +00003108
drh22fbcb82004-02-01 01:22:50 +00003109 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003110 /* Run just the command that follows the database name
3111 */
drh22fbcb82004-02-01 01:22:50 +00003112 if( zFirstCmd[0]=='.' ){
3113 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003114 exit(0);
3115 }else{
3116 int rc;
drh44c2eb12003-04-30 11:38:26 +00003117 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00003118 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00003119 if( rc!=0 && zErrMsg!=0 ){
3120 fprintf(stderr,"SQL error: %s\n", zErrMsg);
3121 exit(1);
3122 }
drh75897232000-05-29 14:26:00 +00003123 }
3124 }else{
drh44c2eb12003-04-30 11:38:26 +00003125 /* Run commands received from standard input
3126 */
drhc28490c2006-10-26 14:25:58 +00003127 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003128 char *zHome;
3129 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003130 int nHistory;
drh75897232000-05-29 14:26:00 +00003131 printf(
drhb217a572000-08-22 13:40:18 +00003132 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00003133 "Enter \".help\" for instructions\n"
3134 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00003135 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00003136 );
drh67505e72002-04-19 12:34:06 +00003137 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003138 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003139 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003140 if( (zHistory = malloc(nHistory))!=0 ){
3141 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3142 }
drh67505e72002-04-19 12:34:06 +00003143 }
danielk19774af00c62005-01-23 23:43:21 +00003144#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003145 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003146#endif
drhc28490c2006-10-26 14:25:58 +00003147 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003148 if( zHistory ){
3149 stifle_history(100);
3150 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003151 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003152 }
adamd0a3daa32006-07-28 20:16:14 +00003153 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00003154 }else{
drhc28490c2006-10-26 14:25:58 +00003155 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003156 }
3157 }
drh33048c02001-10-01 14:29:22 +00003158 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00003159 if( db ){
3160 if( sqlite3_close(db)!=SQLITE_OK ){
3161 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
3162 }
3163 }
drhc28490c2006-10-26 14:25:58 +00003164 return rc;
drh75897232000-05-29 14:26:00 +00003165}