blob: 9f297c4df4f6e48252cc2e6989852259952358d1 [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**
drh157e29a2009-05-21 15:15:00 +000015** $Id: shell.c,v 1.209 2009/05/21 15:15:01 drh Exp $
drh75897232000-05-29 14:26:00 +000016*/
shane18e526c2008-12-10 22:30:24 +000017#if defined(_WIN32) || defined(WIN32)
18/* This needs to come before any includes for MSVC compiler */
19#define _CRT_SECURE_NO_WARNINGS
20#endif
21
drh75897232000-05-29 14:26:00 +000022#include <stdlib.h>
23#include <string.h>
24#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000025#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000026#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000027#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000028#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000029
drh454ad582007-11-26 22:54:27 +000030#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000031# include <signal.h>
chw97185482008-11-17 08:05:31 +000032# if !defined(__RTP__) && !defined(_WRS_KERNEL)
33# include <pwd.h>
34# endif
drhdd45df82002-04-18 12:39:03 +000035# include <unistd.h>
36# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000037#endif
drh75897232000-05-29 14:26:00 +000038
drhcdb36b72006-06-12 12:57:45 +000039#ifdef __OS2__
40# include <unistd.h>
41#endif
42
drh16e59552000-07-31 11:57:37 +000043#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000044# include <readline/readline.h>
45# include <readline/history.h>
46#else
drh9347b202003-07-18 01:30:59 +000047# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000048# define add_history(X)
drh67505e72002-04-19 12:34:06 +000049# define read_history(X)
50# define write_history(X)
51# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000052#endif
53
adamd2e8464a2006-09-06 21:39:40 +000054#if defined(_WIN32) || defined(WIN32)
55# include <io.h>
shane18e526c2008-12-10 22:30:24 +000056#define isatty(h) _isatty(h)
57#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000058#else
drh4328c8b2003-04-26 02:50:11 +000059/* Make sure isatty() has a prototype.
60*/
61extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000062#endif
drh4328c8b2003-04-26 02:50:11 +000063
chw65d3c132007-11-12 21:09:10 +000064#if defined(_WIN32_WCE)
65/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
66 * thus we always assume that we have a console. That can be
67 * overridden with the -batch command line option.
68 */
69#define isatty(x) 1
70#endif
71
chw97185482008-11-17 08:05:31 +000072#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000073#include <sys/time.h>
74#include <sys/resource.h>
75
drhda108222009-02-25 19:07:24 +000076/* Saved resource information for the beginning of an operation */
77static struct rusage sBegin;
78
79/* True if the timer is enabled */
80static int enableTimer = 0;
81
82/*
83** Begin timing an operation
84*/
85static void beginTimer(void){
86 if( enableTimer ){
87 getrusage(RUSAGE_SELF, &sBegin);
88 }
89}
90
91/* Return the difference of two time_structs in seconds */
92static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
93 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
94 (double)(pEnd->tv_sec - pStart->tv_sec);
95}
96
97/*
98** Print the timing results.
99*/
100static void endTimer(void){
101 if( enableTimer ){
102 struct rusage sEnd;
103 getrusage(RUSAGE_SELF, &sEnd);
104 printf("CPU Time: user %f sys %f\n",
105 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
106 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
107 }
108}
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);
danielk1977c8c70692009-02-25 15:22:02 +0000256 if( argc>3 ){
257 int i;
258 pType = 0;
259 for(i=0; aSchemaTable[i].zName; i++){
260 if( 0==strcmp(argv[3], aSchemaTable[i].zName) ){
261 pType = &aSchemaTable[i];
262 }
263 }
264 if( !pType ){
265 return SQLITE_ERROR;
266 }
267 }
268
269 pVtab = sqlite3_malloc(sizeof(schema_vtab));
270 if( pVtab ){
271 memset(pVtab, 0, sizeof(schema_vtab));
272 pVtab->db = (sqlite3 *)pAux;
273 pVtab->pType = pType;
274 rc = sqlite3_declare_vtab(db, pType->zSchema);
275 }
276 *ppVtab = (sqlite3_vtab *)pVtab;
277 return rc;
278}
279
280/*
281** Open a new cursor on the schema table.
282*/
283static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
284 int rc = SQLITE_NOMEM;
285 schema_cursor *pCur;
shanec0688ea2009-03-05 03:48:06 +0000286 UNUSED_PARAMETER(pVTab);
danielk1977c8c70692009-02-25 15:22:02 +0000287 pCur = sqlite3_malloc(sizeof(schema_cursor));
288 if( pCur ){
289 memset(pCur, 0, sizeof(schema_cursor));
290 *ppCursor = (sqlite3_vtab_cursor *)pCur;
291 rc = SQLITE_OK;
292 }
293 return rc;
294}
295
296/*
297** Close a schema table cursor.
298*/
299static int schemaClose(sqlite3_vtab_cursor *cur){
300 schema_cursor *pCur = (schema_cursor *)cur;
301 sqlite3_finalize(pCur->pDbList);
302 sqlite3_finalize(pCur->pTableList);
303 sqlite3_finalize(pCur->pColumnList);
304 sqlite3_free(pCur);
305 return SQLITE_OK;
306}
307
308static void columnToResult(sqlite3_context *ctx, sqlite3_stmt *pStmt, int iCol){
309 switch( sqlite3_column_type(pStmt, iCol) ){
310 case SQLITE_NULL:
311 sqlite3_result_null(ctx);
312 break;
313 case SQLITE_INTEGER:
314 sqlite3_result_int64(ctx, sqlite3_column_int64(pStmt, iCol));
315 break;
316 case SQLITE_FLOAT:
317 sqlite3_result_double(ctx, sqlite3_column_double(pStmt, iCol));
318 break;
319 case SQLITE_TEXT: {
320 const char *z = (const char *)sqlite3_column_text(pStmt, iCol);
321 sqlite3_result_text(ctx, z, -1, SQLITE_TRANSIENT);
322 break;
323 }
324 }
325}
326
327/*
328** Retrieve a column of data.
329*/
330static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
331 schema_cursor *pCur = (schema_cursor *)cur;
332 switch( i ){
333 case 0:
334 columnToResult(ctx, pCur->pDbList, 1);
335 break;
336 case 1:
337 columnToResult(ctx, pCur->pTableList, 0);
338 break;
339 default:
340 columnToResult(ctx, pCur->pColumnList, i-2);
341 break;
342 }
343 return SQLITE_OK;
344}
345
346/*
347** Retrieve the current rowid.
348*/
349static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
350 schema_cursor *pCur = (schema_cursor *)cur;
351 *pRowid = pCur->rowid;
352 return SQLITE_OK;
353}
354
355static int finalize(sqlite3_stmt **ppStmt){
356 int rc = sqlite3_finalize(*ppStmt);
357 *ppStmt = 0;
358 return rc;
359}
360
361static int schemaEof(sqlite3_vtab_cursor *cur){
362 schema_cursor *pCur = (schema_cursor *)cur;
363 return (pCur->pDbList ? 0 : 1);
364}
365
366/*
367** Advance the cursor to the next row.
368*/
369static int schemaNext(sqlite3_vtab_cursor *cur){
370 int rc = SQLITE_OK;
371 schema_cursor *pCur = (schema_cursor *)cur;
372 schema_vtab *pVtab = (schema_vtab *)(cur->pVtab);
373 char *zSql = 0;
374
375 while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){
376 if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit;
377
378 while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){
379 if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit;
380
381 assert(pCur->pDbList);
382 while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){
383 rc = finalize(&pCur->pDbList);
384 goto next_exit;
385 }
386
387 /* Set zSql to the SQL to pull the list of tables from the
388 ** sqlite_master (or sqlite_temp_master) table of the database
389 ** identfied by the row pointed to by the SQL statement pCur->pDbList
390 ** (iterating through a "PRAGMA database_list;" statement).
391 */
392 if( sqlite3_column_int(pCur->pDbList, 0)==1 ){
393 zSql = sqlite3_mprintf(
394 "SELECT name FROM sqlite_temp_master WHERE type=%Q",
395 pVtab->pType->zObject
396 );
397 }else{
398 sqlite3_stmt *pDbList = pCur->pDbList;
399 zSql = sqlite3_mprintf(
400 "SELECT name FROM %Q.sqlite_master WHERE type=%Q",
401 sqlite3_column_text(pDbList, 1), pVtab->pType->zObject
402 );
403 }
404 if( !zSql ){
405 rc = SQLITE_NOMEM;
406 goto next_exit;
407 }
408
409 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0);
410 sqlite3_free(zSql);
411 if( rc!=SQLITE_OK ) goto next_exit;
412 }
413
414 /* Set zSql to the SQL to the table_info pragma for the table currently
415 ** identified by the rows pointed to by statements pCur->pDbList and
416 ** pCur->pTableList.
417 */
418 zSql = sqlite3_mprintf(pVtab->pType->zPragma,
419 sqlite3_column_text(pCur->pDbList, 1),
420 sqlite3_column_text(pCur->pTableList, 0)
421 );
422
423 if( !zSql ){
424 rc = SQLITE_NOMEM;
425 goto next_exit;
426 }
427 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0);
428 sqlite3_free(zSql);
429 if( rc!=SQLITE_OK ) goto next_exit;
430 }
431 pCur->rowid++;
432
433next_exit:
434 /* TODO: Handle rc */
435 return rc;
436}
437
438/*
439** Reset a schema table cursor.
440*/
441static int schemaFilter(
442 sqlite3_vtab_cursor *pVtabCursor,
443 int idxNum, const char *idxStr,
444 int argc, sqlite3_value **argv
445){
446 int rc;
447 schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab);
448 schema_cursor *pCur = (schema_cursor *)pVtabCursor;
shanec0688ea2009-03-05 03:48:06 +0000449 UNUSED_PARAMETER(idxNum);
450 UNUSED_PARAMETER(idxStr);
451 UNUSED_PARAMETER(argc);
452 UNUSED_PARAMETER(argv);
danielk1977c8c70692009-02-25 15:22:02 +0000453 pCur->rowid = 0;
454 finalize(&pCur->pTableList);
455 finalize(&pCur->pColumnList);
456 finalize(&pCur->pDbList);
457 rc = sqlite3_prepare(pVtab->db,"SELECT 0, 'main'", -1, &pCur->pDbList, 0);
458 return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc);
459}
460
461/*
462** Analyse the WHERE condition.
463*/
464static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
shanec0688ea2009-03-05 03:48:06 +0000465 UNUSED_PARAMETER(tab);
466 UNUSED_PARAMETER(pIdxInfo);
danielk1977c8c70692009-02-25 15:22:02 +0000467 return SQLITE_OK;
468}
469
470/*
471** A virtual table module that merely echos method calls into TCL
472** variables.
473*/
474static sqlite3_module schemaModule = {
475 0, /* iVersion */
476 schemaCreate,
477 schemaCreate,
478 schemaBestIndex,
479 schemaDestroy,
480 schemaDestroy,
481 schemaOpen, /* xOpen - open a cursor */
482 schemaClose, /* xClose - close a cursor */
483 schemaFilter, /* xFilter - configure scan constraints */
484 schemaNext, /* xNext - advance a cursor */
485 schemaEof, /* xEof */
486 schemaColumn, /* xColumn - read data */
487 schemaRowid, /* xRowid - read data */
488 0, /* xUpdate */
489 0, /* xBegin */
490 0, /* xSync */
491 0, /* xCommit */
492 0, /* xRollback */
493 0, /* xFindMethod */
494 0, /* xRename */
495};
496
497/*
498** Extension load function.
499*/
500static int installSchemaModule(sqlite3 *db, sqlite3 *sdb){
501 sqlite3_create_module(db, "schema", &schemaModule, (void *)sdb);
502 return 0;
503}
504
505/*
506** sj(zValue, zJoin)
507**
508** The following block contains the implementation of an aggregate
509** function that returns a string. Each time the function is stepped,
510** it appends data to an internal buffer. When the aggregate is finalized,
511** the contents of the buffer are returned.
512**
513** The first time the aggregate is stepped the buffer is set to a copy
514** of the first argument. The second time and subsequent times it is
515** stepped a copy of the second argument is appended to the buffer, then
516** a copy of the first.
517**
518** Example:
519**
520** INSERT INTO t1(a) VALUES('1');
521** INSERT INTO t1(a) VALUES('2');
522** INSERT INTO t1(a) VALUES('3');
523** SELECT sj(a, ', ') FROM t1;
524**
525** => "1, 2, 3"
526**
527*/
528struct StrBuffer {
529 char *zBuf;
530};
531typedef struct StrBuffer StrBuffer;
532static void joinFinalize(sqlite3_context *context){
533 StrBuffer *p;
534 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
535 sqlite3_result_text(context, p->zBuf, -1, SQLITE_TRANSIENT);
536 sqlite3_free(p->zBuf);
537}
538static void joinStep(
539 sqlite3_context *context,
540 int argc,
541 sqlite3_value **argv
542){
543 StrBuffer *p;
shanec0688ea2009-03-05 03:48:06 +0000544 UNUSED_PARAMETER(argc);
danielk1977c8c70692009-02-25 15:22:02 +0000545 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
546 if( p->zBuf==0 ){
547 p->zBuf = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
548 }else{
549 char *zTmp = p->zBuf;
550 p->zBuf = sqlite3_mprintf("%s%s%s",
551 zTmp, sqlite3_value_text(argv[1]), sqlite3_value_text(argv[0])
552 );
553 sqlite3_free(zTmp);
554 }
555}
556
557/*
558** dq(zString)
559**
560** This scalar function accepts a single argument and interprets it as
561** a text value. The return value is the argument enclosed in double
562** quotes. If any double quote characters are present in the argument,
563** these are escaped.
564**
565** dq('the raven "Nevermore."') == '"the raven ""Nevermore."""'
566*/
567static void doublequote(
568 sqlite3_context *context,
569 int argc,
570 sqlite3_value **argv
571){
572 int ii;
573 char *zOut;
574 char *zCsr;
575 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
576 int nIn = sqlite3_value_bytes(argv[0]);
577
shanec0688ea2009-03-05 03:48:06 +0000578 UNUSED_PARAMETER(argc);
danielk1977c8c70692009-02-25 15:22:02 +0000579 zOut = sqlite3_malloc(nIn*2+3);
580 zCsr = zOut;
581 *zCsr++ = '"';
582 for(ii=0; ii<nIn; ii++){
583 *zCsr++ = zIn[ii];
584 if( zIn[ii]=='"' ){
585 *zCsr++ = '"';
586 }
587 }
588 *zCsr++ = '"';
589 *zCsr++ = '\0';
590
591 sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT);
592 sqlite3_free(zOut);
593}
594
595/*
596** multireplace(zString, zSearch1, zReplace1, ...)
597*/
598static void multireplace(
599 sqlite3_context *context,
600 int argc,
601 sqlite3_value **argv
602){
603 int i = 0;
604 char *zOut = 0;
605 int nOut = 0;
606 int nMalloc = 0;
607 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
608 int nIn = sqlite3_value_bytes(argv[0]);
609
610 while( i<nIn ){
611 const char *zCopy = &zIn[i];
612 int nCopy = 1;
613 int nReplace = 1;
614 int j;
615 for(j=1; j<(argc-1); j+=2){
616 const char *z = (const char *)sqlite3_value_text(argv[j]);
617 int n = sqlite3_value_bytes(argv[j]);
618 if( n<=(nIn-i) && 0==strncmp(z, zCopy, n) ){
619 zCopy = (const char *)sqlite3_value_text(argv[j+1]);
620 nCopy = sqlite3_value_bytes(argv[j+1]);
621 nReplace = n;
622 break;
623 }
624 }
625 if( (nOut+nCopy)>nMalloc ){
danielk19779365c672009-03-13 15:32:53 +0000626 nMalloc = 16 + (nOut+nCopy)*2;
danielk1977c8c70692009-02-25 15:22:02 +0000627 zOut = (char *)sqlite3_realloc(zOut, nMalloc);
628 }
danielk19779365c672009-03-13 15:32:53 +0000629 assert( nMalloc>=(nOut+nCopy) );
danielk1977c8c70692009-02-25 15:22:02 +0000630 memcpy(&zOut[nOut], zCopy, nCopy);
631 i += nReplace;
632 nOut += nCopy;
633 }
634
635 sqlite3_result_text(context, zOut, nOut, SQLITE_TRANSIENT);
636 sqlite3_free(zOut);
637}
638
639/*
640** A callback for sqlite3_exec() invokes the callback specified by the
641** GenfkeyCb structure pointed to by the void* passed as the first argument.
642*/
643static int invokeCallback(void *p, int nArg, char **azArg, char **azCol){
644 GenfkeyCb *pCb = (GenfkeyCb *)p;
shanec0688ea2009-03-05 03:48:06 +0000645 UNUSED_PARAMETER(nArg);
646 UNUSED_PARAMETER(azCol);
danielk1977c8c70692009-02-25 15:22:02 +0000647 return pCb->xData(pCb->pCtx, pCb->eType, azArg[0]);
648}
649
650int detectSchemaProblem(
651 sqlite3 *db, /* Database connection */
652 const char *zMessage, /* English language error message */
653 const char *zSql, /* SQL statement to run */
654 GenfkeyCb *pCb
655){
656 sqlite3_stmt *pStmt;
657 int rc;
658 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
659 if( rc!=SQLITE_OK ){
660 return rc;
661 }
662 while( SQLITE_ROW==sqlite3_step(pStmt) ){
663 char *zDel;
664 int iFk = sqlite3_column_int(pStmt, 0);
665 const char *zTab = (const char *)sqlite3_column_text(pStmt, 1);
666 zDel = sqlite3_mprintf("Error in table %s: %s", zTab, zMessage);
667 rc = pCb->xData(pCb->pCtx, pCb->eType, zDel);
668 sqlite3_free(zDel);
669 if( rc!=SQLITE_OK ) return rc;
670 zDel = sqlite3_mprintf(
671 "DELETE FROM temp.fkey WHERE from_tbl = %Q AND fkid = %d"
672 , zTab, iFk
673 );
674 sqlite3_exec(db, zDel, 0, 0, 0);
675 sqlite3_free(zDel);
676 }
677 sqlite3_finalize(pStmt);
678 return SQLITE_OK;
679}
680
681/*
682** Create and populate temporary table "fkey".
683*/
684static int populateTempTable(sqlite3 *db, GenfkeyCb *pCallback){
685 int rc;
686
687 rc = sqlite3_exec(db,
688 "CREATE VIRTUAL TABLE temp.v_fkey USING schema(foreign_key_list);"
689 "CREATE VIRTUAL TABLE temp.v_col USING schema(table_info);"
690 "CREATE VIRTUAL TABLE temp.v_idxlist USING schema(index_list);"
691 "CREATE VIRTUAL TABLE temp.v_idxinfo USING schema(index_info);"
692 "CREATE VIRTUAL TABLE temp.v_triggers USING schema(trigger_list);"
693 "CREATE TABLE temp.fkey AS "
694 "SELECT from_tbl, to_tbl, fkid, from_col, to_col, on_update, on_delete "
695 "FROM temp.v_fkey WHERE database = 'main';"
696 , 0, 0, 0
697 );
698 if( rc!=SQLITE_OK ) return rc;
699
700 rc = detectSchemaProblem(db, "foreign key columns do not exist",
701 "SELECT fkid, from_tbl "
702 "FROM temp.fkey "
703 "WHERE to_col IS NOT NULL AND NOT EXISTS (SELECT 1 "
704 "FROM temp.v_col WHERE tablename=to_tbl AND name==to_col"
705 ")", pCallback
706 );
707 if( rc!=SQLITE_OK ) return rc;
708
709 /* At this point the temp.fkey table is mostly populated. If any foreign
710 ** keys were specified so that they implicitly refer to they primary
711 ** key of the parent table, the "to_col" values of the temp.fkey rows
712 ** are still set to NULL.
713 **
714 ** This is easily fixed for single column primary keys, but not for
715 ** composites. With a composite primary key, there is no way to reliably
716 ** query sqlite for the order in which the columns that make up the
717 ** composite key were declared i.e. there is no way to tell if the
718 ** schema actually contains "PRIMARY KEY(a, b)" or "PRIMARY KEY(b, a)".
719 ** Therefore, this case is not handled. The following function call
720 ** detects instances of this case.
721 */
722 rc = detectSchemaProblem(db, "implicit mapping to composite primary key",
723 "SELECT fkid, from_tbl "
724 "FROM temp.fkey "
725 "WHERE to_col IS NULL "
726 "GROUP BY fkid, from_tbl HAVING count(*) > 1", pCallback
727 );
728 if( rc!=SQLITE_OK ) return rc;
729
730 /* Detect attempts to implicitly map to the primary key of a table
731 ** that has no primary key column.
732 */
733 rc = detectSchemaProblem(db, "implicit mapping to non-existant primary key",
734 "SELECT fkid, from_tbl "
735 "FROM temp.fkey "
736 "WHERE to_col IS NULL AND NOT EXISTS "
737 "(SELECT 1 FROM temp.v_col WHERE pk AND tablename = temp.fkey.to_tbl)"
738 , pCallback
739 );
740 if( rc!=SQLITE_OK ) return rc;
741
742 /* Fix all the implicit primary key mappings in the temp.fkey table. */
743 rc = sqlite3_exec(db,
744 "UPDATE temp.fkey SET to_col = "
745 "(SELECT name FROM temp.v_col WHERE pk AND tablename=temp.fkey.to_tbl)"
746 " WHERE to_col IS NULL;"
747 , 0, 0, 0
748 );
749 if( rc!=SQLITE_OK ) return rc;
750
751 /* Now check that all all parent keys are either primary keys or
752 ** subject to a unique constraint.
753 */
754 rc = sqlite3_exec(db,
755 "CREATE TABLE temp.idx2 AS SELECT "
756 "il.tablename AS tablename,"
757 "ii.indexname AS indexname,"
758 "ii.name AS col "
759 "FROM temp.v_idxlist AS il, temp.v_idxinfo AS ii "
760 "WHERE il.isunique AND il.database='main' AND ii.indexname = il.name;"
761 "INSERT INTO temp.idx2 "
762 "SELECT tablename, 'pk', name FROM temp.v_col WHERE pk;"
763
764 "CREATE TABLE temp.idx AS SELECT "
765 "tablename, indexname, sj(dq(col),',') AS cols "
766 "FROM (SELECT * FROM temp.idx2 ORDER BY col) "
767 "GROUP BY tablename, indexname;"
768
769 "CREATE TABLE temp.fkey2 AS SELECT "
770 "fkid, from_tbl, to_tbl, sj(dq(to_col),',') AS cols "
771 "FROM (SELECT * FROM temp.fkey ORDER BY to_col) "
772 "GROUP BY fkid, from_tbl;"
773
774 "CREATE TABLE temp.triggers AS SELECT "
775 "triggername FROM temp.v_triggers WHERE database='main' AND "
776 "triggername LIKE 'genfkey%';"
777 , 0, 0, 0
778 );
779 if( rc!=SQLITE_OK ) return rc;
780 rc = detectSchemaProblem(db, "foreign key is not unique",
781 "SELECT fkid, from_tbl "
782 "FROM temp.fkey2 "
783 "WHERE NOT EXISTS (SELECT 1 "
784 "FROM temp.idx WHERE tablename=to_tbl AND fkey2.cols==idx.cols"
785 ")", pCallback
786 );
787 if( rc!=SQLITE_OK ) return rc;
788
789 return rc;
790}
791
792#define GENFKEY_ERROR 1
793#define GENFKEY_DROPTRIGGER 2
794#define GENFKEY_CREATETRIGGER 3
795static int genfkey_create_triggers(
796 sqlite3 *sdb, /* Connection to read schema from */
797 const char *zDb, /* Name of db to read ("main", "temp") */
798 void *pCtx, /* Context pointer to pass to xData */
799 int (*xData)(void *, int, const char *)
800){
801 const char *zSql =
802 "SELECT multireplace('"
803
804 "-- Triggers for foreign key mapping:\n"
805 "--\n"
806 "-- /from_readable/ REFERENCES /to_readable/\n"
807 "-- on delete /on_delete/\n"
808 "-- on update /on_update/\n"
809 "--\n"
810
811 /* The "BEFORE INSERT ON <referencing>" trigger. This trigger's job is to
812 ** throw an exception if the user tries to insert a row into the
813 ** referencing table for which there is no corresponding row in
814 ** the referenced table.
815 */
816 "CREATE TRIGGER /name/_insert_referencing BEFORE INSERT ON /tbl/ WHEN \n"
817 " /key_notnull/ AND NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
818 "BEGIN\n"
819 " SELECT RAISE(ABORT, ''constraint failed'');\n"
820 "END;\n"
821
822 /* The "BEFORE UPDATE ON <referencing>" trigger. This trigger's job
823 ** is to throw an exception if the user tries to update a row in the
824 ** referencing table causing it to correspond to no row in the
825 ** referenced table.
826 */
827 "CREATE TRIGGER /name/_update_referencing BEFORE\n"
828 " UPDATE OF /rkey_list/ ON /tbl/ WHEN \n"
829 " /key_notnull/ AND \n"
830 " NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
831 "BEGIN\n"
832 " SELECT RAISE(ABORT, ''constraint failed'');\n"
833 "END;\n"
834
835
836 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
837 ** is to detect when a row is deleted from the referenced table to
838 ** which rows in the referencing table correspond. The action taken
839 ** depends on the value of the 'ON DELETE' clause.
840 */
841 "CREATE TRIGGER /name/_delete_referenced BEFORE DELETE ON /ref/ WHEN\n"
842 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
843 "BEGIN\n"
844 " /delete_action/\n"
845 "END;\n"
846
847 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
848 ** is to detect when the key columns of a row in the referenced table
849 ** to which one or more rows in the referencing table correspond are
850 ** updated. The action taken depends on the value of the 'ON UPDATE'
851 ** clause.
852 */
853 "CREATE TRIGGER /name/_update_referenced AFTER\n"
854 " UPDATE OF /fkey_list/ ON /ref/ WHEN \n"
855 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
856 "BEGIN\n"
857 " /update_action/\n"
858 "END;\n"
859 "'"
860
861 /* These are used in the SQL comment written above each set of triggers */
862 ", '/from_readable/', from_tbl || '(' || sj(from_col, ', ') || ')'"
863 ", '/to_readable/', to_tbl || '(' || sj(to_col, ', ') || ')'"
864 ", '/on_delete/', on_delete"
865 ", '/on_update/', on_update"
866
867 ", '/name/', 'genfkey' || min(rowid)"
868 ", '/tbl/', dq(from_tbl)"
869 ", '/ref/', dq(to_tbl)"
870 ", '/key_notnull/', sj('new.' || dq(from_col) || ' IS NOT NULL', ' AND ')"
871
872 ", '/fkey_list/', sj(to_col, ', ')"
873 ", '/rkey_list/', sj(from_col, ', ')"
874
875 ", '/cond1/', sj(multireplace('new./from/ == /to/'"
876 ", '/from/', dq(from_col)"
877 ", '/to/', dq(to_col)"
878 "), ' AND ')"
879 ", '/cond2/', sj(multireplace('old./to/ == /from/'"
880 ", '/from/', dq(from_col)"
881 ", '/to/', dq(to_col)"
882 "), ' AND ')"
883
884 ", '/update_action/', CASE on_update "
885 "WHEN 'SET NULL' THEN "
886 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
887 ", '/setlist/', sj(from_col||' = NULL',', ')"
888 ", '/tbl/', dq(from_tbl)"
889 ", '/where/', sj(from_col||' = old.'||dq(to_col),' AND ')"
890 ")"
891 "WHEN 'CASCADE' THEN "
892 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
893 ", '/setlist/', sj(dq(from_col)||' = new.'||dq(to_col),', ')"
894 ", '/tbl/', dq(from_tbl)"
895 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
896 ")"
897 "ELSE "
898 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
899 "END "
900
901 ", '/delete_action/', CASE on_delete "
902 "WHEN 'SET NULL' THEN "
903 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
904 ", '/setlist/', sj(from_col||' = NULL',', ')"
905 ", '/tbl/', dq(from_tbl)"
906 ", '/where/', sj(from_col||' = old.'||dq(to_col),' AND ')"
907 ")"
908 "WHEN 'CASCADE' THEN "
909 "multireplace('DELETE FROM /tbl/ WHERE /where/;' "
910 ", '/tbl/', dq(from_tbl)"
911 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
912 ")"
913 "ELSE "
914 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
915 "END "
916
917 ") FROM temp.fkey "
918 "GROUP BY from_tbl, fkid"
919 ;
920
921 int rc;
922 const int enc = SQLITE_UTF8;
923 sqlite3 *db = 0;
924
925 GenfkeyCb cb;
926 cb.xData = xData;
927 cb.pCtx = pCtx;
928
shanec0688ea2009-03-05 03:48:06 +0000929 UNUSED_PARAMETER(zDb);
930
danielk1977c8c70692009-02-25 15:22:02 +0000931 /* Open the working database handle. */
932 rc = sqlite3_open(":memory:", &db);
933 if( rc!=SQLITE_OK ) goto genfkey_exit;
934
935 /* Create the special scalar and aggregate functions used by this program. */
936 sqlite3_create_function(db, "dq", 1, enc, 0, doublequote, 0, 0);
937 sqlite3_create_function(db, "multireplace", -1, enc, db, multireplace, 0, 0);
938 sqlite3_create_function(db, "sj", 2, enc, 0, 0, joinStep, joinFinalize);
939
940 /* Install the "schema" virtual table module */
941 installSchemaModule(db, sdb);
942
943 /* Create and populate a temp table with the information required to
944 ** build the foreign key triggers. See function populateTempTable()
945 ** for details.
946 */
947 cb.eType = GENFKEY_ERROR;
948 rc = populateTempTable(db, &cb);
949 if( rc!=SQLITE_OK ) goto genfkey_exit;
950
951 /* Unless the --no-drop option was specified, generate DROP TRIGGER
952 ** statements to drop any triggers in the database generated by a
953 ** previous run of this program.
954 */
955 cb.eType = GENFKEY_DROPTRIGGER;
956 rc = sqlite3_exec(db,
957 "SELECT 'DROP TRIGGER main.' || dq(triggername) || ';' FROM triggers"
958 ,invokeCallback, (void *)&cb, 0
959 );
960 if( rc!=SQLITE_OK ) goto genfkey_exit;
961
962 /* Run the main query to create the trigger definitions. */
963 cb.eType = GENFKEY_CREATETRIGGER;
964 rc = sqlite3_exec(db, zSql, invokeCallback, (void *)&cb, 0);
965 if( rc!=SQLITE_OK ) goto genfkey_exit;
966
967genfkey_exit:
968 sqlite3_close(db);
969 return rc;
970}
971
972
973#endif
974/* End genfkey logic. */
975/*************************************************************************/
976/*************************************************************************/
977
drhe91d16b2008-12-08 18:27:31 +0000978/*
drhc49f44e2006-10-26 18:15:42 +0000979** If the following flag is set, then command execution stops
980** at an error if we are not interactive.
981*/
982static int bail_on_error = 0;
983
984/*
drhc28490c2006-10-26 14:25:58 +0000985** Threat stdin as an interactive input if the following variable
986** is true. Otherwise, assume stdin is connected to a file or pipe.
987*/
988static int stdin_is_interactive = 1;
989
990/*
drh4c504392000-10-16 22:06:40 +0000991** The following is the open SQLite database. We make a pointer
992** to this database a static variable so that it can be accessed
993** by the SIGINT handler to interrupt database processing.
994*/
danielk197792f9a1b2004-06-19 09:08:16 +0000995static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000996
997/*
drh67505e72002-04-19 12:34:06 +0000998** True if an interrupt (Control-C) has been received.
999*/
drh43617e92006-03-06 20:55:46 +00001000static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +00001001
1002/*
persicom7e2dfdd2002-04-18 02:46:52 +00001003** This is the name of our program. It is set in main(), used
1004** in a number of other places, mostly for error messages.
1005*/
1006static char *Argv0;
1007
1008/*
1009** Prompt strings. Initialized in main. Settable with
1010** .prompt main continue
1011*/
1012static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
1013static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
1014
drhb0603412007-02-28 04:47:26 +00001015/*
1016** Write I/O traces to the following stream.
1017*/
rsebe0a9092007-07-30 18:24:38 +00001018#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001019static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +00001020#endif
drhb0603412007-02-28 04:47:26 +00001021
1022/*
1023** This routine works like printf in that its first argument is a
1024** format string and subsequent arguments are values to be substituted
1025** in place of % fields. The result of formatting this string
1026** is written to iotrace.
1027*/
rsebe0a9092007-07-30 18:24:38 +00001028#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001029static void iotracePrintf(const char *zFormat, ...){
1030 va_list ap;
drhf075cd02007-02-28 06:14:25 +00001031 char *z;
drhb0603412007-02-28 04:47:26 +00001032 if( iotrace==0 ) return;
1033 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +00001034 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +00001035 va_end(ap);
drhf075cd02007-02-28 06:14:25 +00001036 fprintf(iotrace, "%s", z);
1037 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +00001038}
rsebe0a9092007-07-30 18:24:38 +00001039#endif
drhb0603412007-02-28 04:47:26 +00001040
drh44c2eb12003-04-30 11:38:26 +00001041
persicom7e2dfdd2002-04-18 02:46:52 +00001042/*
drh83965662003-04-17 02:54:13 +00001043** Determines if a string is a number of not.
1044*/
danielk19772e588c72005-12-09 14:25:08 +00001045static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +00001046 if( *z=='-' || *z=='+' ) z++;
1047 if( !isdigit(*z) ){
1048 return 0;
1049 }
1050 z++;
1051 if( realnum ) *realnum = 0;
1052 while( isdigit(*z) ){ z++; }
1053 if( *z=='.' ){
1054 z++;
1055 if( !isdigit(*z) ) return 0;
1056 while( isdigit(*z) ){ z++; }
1057 if( realnum ) *realnum = 1;
1058 }
1059 if( *z=='e' || *z=='E' ){
1060 z++;
1061 if( *z=='+' || *z=='-' ) z++;
1062 if( !isdigit(*z) ) return 0;
1063 while( isdigit(*z) ){ z++; }
1064 if( realnum ) *realnum = 1;
1065 }
1066 return *z==0;
1067}
drh83965662003-04-17 02:54:13 +00001068
1069/*
danielk1977bc6ada42004-06-30 08:20:16 +00001070** A global char* and an SQL function to access its current value
1071** from within an SQL statement. This program used to use the
1072** sqlite_exec_printf() API to substitue a string into an SQL statement.
1073** The correct way to do this with sqlite3 is to use the bind API, but
1074** since the shell is built around the callback paradigm it would be a lot
1075** of work. Instead just use this hack, which is quite harmless.
1076*/
1077static const char *zShellStatic = 0;
1078static void shellstaticFunc(
1079 sqlite3_context *context,
1080 int argc,
1081 sqlite3_value **argv
1082){
1083 assert( 0==argc );
1084 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +00001085 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +00001086 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +00001087 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
1088}
1089
1090
1091/*
drhfeac5f82004-08-01 00:10:45 +00001092** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +00001093** the text in memory obtained from malloc() and returns a pointer
1094** to the text. NULL is returned at end of file, or if malloc()
1095** fails.
1096**
1097** The interface is like "readline" but no command-line editing
1098** is done.
1099*/
drh9347b202003-07-18 01:30:59 +00001100static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +00001101 char *zLine;
1102 int nLine;
drh8e7e7a22000-05-30 18:45:23 +00001103 int n;
1104 int eol;
1105
1106 if( zPrompt && *zPrompt ){
1107 printf("%s",zPrompt);
1108 fflush(stdout);
1109 }
1110 nLine = 100;
1111 zLine = malloc( nLine );
1112 if( zLine==0 ) return 0;
1113 n = 0;
1114 eol = 0;
1115 while( !eol ){
1116 if( n+100>nLine ){
1117 nLine = nLine*2 + 100;
1118 zLine = realloc(zLine, nLine);
1119 if( zLine==0 ) return 0;
1120 }
drhdaffd0e2001-04-11 14:28:42 +00001121 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +00001122 if( n==0 ){
1123 free(zLine);
1124 return 0;
1125 }
1126 zLine[n] = 0;
1127 eol = 1;
1128 break;
1129 }
1130 while( zLine[n] ){ n++; }
1131 if( n>0 && zLine[n-1]=='\n' ){
1132 n--;
1133 zLine[n] = 0;
1134 eol = 1;
1135 }
1136 }
1137 zLine = realloc( zLine, n+1 );
1138 return zLine;
1139}
1140
1141/*
drhc28490c2006-10-26 14:25:58 +00001142** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +00001143**
1144** zPrior is a string of prior text retrieved. If not the empty
1145** string, then issue a continuation prompt.
1146*/
drhdaffd0e2001-04-11 14:28:42 +00001147static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +00001148 char *zPrompt;
1149 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +00001150 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +00001151 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +00001152 }
1153 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +00001154 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +00001155 }else{
persicom7e2dfdd2002-04-18 02:46:52 +00001156 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +00001157 }
1158 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +00001159#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +00001160 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +00001161#endif
drh8e7e7a22000-05-30 18:45:23 +00001162 return zResult;
1163}
1164
persicom7e2dfdd2002-04-18 02:46:52 +00001165struct previous_mode_data {
1166 int valid; /* Is there legit data in here? */
1167 int mode;
1168 int showHeader;
1169 int colWidth[100];
1170};
drh45e29d82006-11-20 16:21:10 +00001171
drh8e7e7a22000-05-30 18:45:23 +00001172/*
drh75897232000-05-29 14:26:00 +00001173** An pointer to an instance of this structure is passed from
1174** the main program to the callback. This is used to communicate
1175** state and mode information.
1176*/
1177struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +00001178 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +00001179 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +00001180 int cnt; /* Number of records displayed so far */
1181 FILE *out; /* Write results here */
1182 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +00001183 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +00001184 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +00001185 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +00001186 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +00001187 int colWidth[100]; /* Requested width of each column when in column mode*/
1188 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +00001189 char nullvalue[20]; /* The text to print when a NULL comes back from
1190 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +00001191 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +00001192 /* Holds the mode information just before
1193 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +00001194 char outfile[FILENAME_MAX]; /* Filename for *out */
1195 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +00001196};
1197
1198/*
1199** These are the allowed modes.
1200*/
drh967e8b72000-06-21 13:59:10 +00001201#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +00001202#define MODE_Column 1 /* One record per line in neat columns */
1203#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +00001204#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
1205#define MODE_Html 4 /* Generate an XHTML table */
1206#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +00001207#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +00001208#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +00001209#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +00001210
drh66ce4d02008-02-15 17:38:06 +00001211static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +00001212 "line",
1213 "column",
1214 "list",
1215 "semi",
1216 "html",
drhfeac5f82004-08-01 00:10:45 +00001217 "insert",
1218 "tcl",
drh8e64d1c2004-10-07 00:32:39 +00001219 "csv",
drh66ce4d02008-02-15 17:38:06 +00001220 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +00001221};
drh75897232000-05-29 14:26:00 +00001222
1223/*
1224** Number of elements in an array
1225*/
drh902b9ee2008-12-05 17:17:07 +00001226#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +00001227
1228/*
drhea678832008-12-10 19:26:22 +00001229** Compute a string length that is limited to what can be stored in
1230** lower 30 bits of a 32-bit signed integer.
1231*/
drh4f21c4a2008-12-10 22:15:00 +00001232static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +00001233 const char *z2 = z;
1234 while( *z2 ){ z2++; }
1235 return 0x3fffffff & (int)(z2 - z);
1236}
1237
1238/*
drh28bd4bc2000-06-15 15:57:22 +00001239** Output the given string as a quoted string using SQL quoting conventions.
1240*/
1241static void output_quoted_string(FILE *out, const char *z){
1242 int i;
1243 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +00001244 for(i=0; z[i]; i++){
1245 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +00001246 }
1247 if( nSingle==0 ){
1248 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +00001249 }else{
1250 fprintf(out,"'");
1251 while( *z ){
1252 for(i=0; z[i] && z[i]!='\''; i++){}
1253 if( i==0 ){
1254 fprintf(out,"''");
1255 z++;
1256 }else if( z[i]=='\'' ){
1257 fprintf(out,"%.*s''",i,z);
1258 z += i+1;
1259 }else{
drhcd7d2732002-02-26 23:24:26 +00001260 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +00001261 break;
1262 }
1263 }
drhcd7d2732002-02-26 23:24:26 +00001264 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +00001265 }
1266}
1267
1268/*
drhfeac5f82004-08-01 00:10:45 +00001269** Output the given string as a quoted according to C or TCL quoting rules.
1270*/
1271static void output_c_string(FILE *out, const char *z){
1272 unsigned int c;
1273 fputc('"', out);
1274 while( (c = *(z++))!=0 ){
1275 if( c=='\\' ){
1276 fputc(c, out);
1277 fputc(c, out);
1278 }else if( c=='\t' ){
1279 fputc('\\', out);
1280 fputc('t', out);
1281 }else if( c=='\n' ){
1282 fputc('\\', out);
1283 fputc('n', out);
1284 }else if( c=='\r' ){
1285 fputc('\\', out);
1286 fputc('r', out);
1287 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +00001288 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +00001289 }else{
1290 fputc(c, out);
1291 }
1292 }
1293 fputc('"', out);
1294}
1295
1296/*
drhc08a4f12000-06-15 16:49:48 +00001297** Output the given string with characters that are special to
1298** HTML escaped.
1299*/
1300static void output_html_string(FILE *out, const char *z){
1301 int i;
1302 while( *z ){
1303 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
1304 if( i>0 ){
1305 fprintf(out,"%.*s",i,z);
1306 }
1307 if( z[i]=='<' ){
1308 fprintf(out,"&lt;");
1309 }else if( z[i]=='&' ){
1310 fprintf(out,"&amp;");
1311 }else{
1312 break;
1313 }
1314 z += i + 1;
1315 }
1316}
1317
1318/*
drhc49f44e2006-10-26 18:15:42 +00001319** If a field contains any character identified by a 1 in the following
1320** array, then the string must be quoted for CSV.
1321*/
1322static const char needCsvQuote[] = {
1323 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1324 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1325 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1326 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,
1331 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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};
1340
1341/*
drh8e64d1c2004-10-07 00:32:39 +00001342** Output a single term of CSV. Actually, p->separator is used for
1343** the separator, which may or may not be a comma. p->nullvalue is
1344** the null value. Strings are quoted using ANSI-C rules. Numbers
1345** appear outside of quotes.
1346*/
1347static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +00001348 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +00001349 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +00001350 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +00001351 }else{
drhc49f44e2006-10-26 18:15:42 +00001352 int i;
drh4f21c4a2008-12-10 22:15:00 +00001353 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +00001354 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +00001355 if( needCsvQuote[((unsigned char*)z)[i]]
1356 || (z[i]==p->separator[0] &&
1357 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +00001358 i = 0;
1359 break;
1360 }
1361 }
1362 if( i==0 ){
1363 putc('"', out);
1364 for(i=0; z[i]; i++){
1365 if( z[i]=='"' ) putc('"', out);
1366 putc(z[i], out);
1367 }
1368 putc('"', out);
1369 }else{
1370 fprintf(out, "%s", z);
1371 }
drh8e64d1c2004-10-07 00:32:39 +00001372 }
1373 if( bSep ){
drhd0e77882008-01-14 15:20:08 +00001374 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +00001375 }
1376}
1377
danielk19774af00c62005-01-23 23:43:21 +00001378#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +00001379/*
drh4c504392000-10-16 22:06:40 +00001380** This routine runs when the user presses Ctrl-C
1381*/
1382static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +00001383 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +00001384 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +00001385 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +00001386}
danielk19774af00c62005-01-23 23:43:21 +00001387#endif
drh4c504392000-10-16 22:06:40 +00001388
1389/*
drh75897232000-05-29 14:26:00 +00001390** This is the callback routine that the SQLite library
1391** invokes for each row of a query result.
1392*/
1393static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1394 int i;
1395 struct callback_data *p = (struct callback_data*)pArg;
1396 switch( p->mode ){
1397 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +00001398 int w = 5;
drh6a535342001-10-19 16:44:56 +00001399 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +00001400 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +00001401 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +00001402 if( len>w ) w = len;
1403 }
drh75897232000-05-29 14:26:00 +00001404 if( p->cnt++>0 ) fprintf(p->out,"\n");
1405 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001406 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +00001407 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +00001408 }
1409 break;
1410 }
danielk19770d78bae2008-01-03 07:09:48 +00001411 case MODE_Explain:
drh75897232000-05-29 14:26:00 +00001412 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +00001413 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +00001414 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +00001415 int w, n;
1416 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +00001417 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +00001418 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001419 w = 0;
drh75897232000-05-29 14:26:00 +00001420 }
drha0c66f52000-07-29 13:20:21 +00001421 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001422 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001423 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +00001424 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +00001425 if( w<n ) w = n;
1426 }
1427 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001428 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001429 }
1430 if( p->showHeader ){
1431 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
1432 }
1433 }
1434 if( p->showHeader ){
1435 for(i=0; i<nArg; i++){
1436 int w;
1437 if( i<ArraySize(p->actualWidth) ){
1438 w = p->actualWidth[i];
1439 }else{
1440 w = 10;
1441 }
1442 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
1443 "----------------------------------------------------------",
1444 i==nArg-1 ? "\n": " ");
1445 }
drh75897232000-05-29 14:26:00 +00001446 }
1447 }
drh6a535342001-10-19 16:44:56 +00001448 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001449 for(i=0; i<nArg; i++){
1450 int w;
drha0c66f52000-07-29 13:20:21 +00001451 if( i<ArraySize(p->actualWidth) ){
1452 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001453 }else{
1454 w = 10;
1455 }
drhea678832008-12-10 19:26:22 +00001456 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +00001457 strlen30(azArg[i])>w ){
1458 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001459 }
drhc61053b2000-06-04 12:58:36 +00001460 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +00001461 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +00001462 }
1463 break;
1464 }
drhe3710332000-09-29 13:30:53 +00001465 case MODE_Semi:
drh75897232000-05-29 14:26:00 +00001466 case MODE_List: {
1467 if( p->cnt++==0 && p->showHeader ){
1468 for(i=0; i<nArg; i++){
1469 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
1470 }
1471 }
drh6a535342001-10-19 16:44:56 +00001472 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001473 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001474 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +00001475 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +00001476 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001477 if( i<nArg-1 ){
1478 fprintf(p->out, "%s", p->separator);
1479 }else if( p->mode==MODE_Semi ){
1480 fprintf(p->out, ";\n");
1481 }else{
1482 fprintf(p->out, "\n");
1483 }
drh75897232000-05-29 14:26:00 +00001484 }
1485 break;
1486 }
drh1e5d0e92000-05-31 23:33:17 +00001487 case MODE_Html: {
1488 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +00001489 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001490 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +00001491 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
drh1e5d0e92000-05-31 23:33:17 +00001492 }
mihailim57c591a2008-06-23 21:26:05 +00001493 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001494 }
drh6a535342001-10-19 16:44:56 +00001495 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +00001496 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001497 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +00001498 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +00001499 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +00001500 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001501 }
mihailim57c591a2008-06-23 21:26:05 +00001502 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001503 break;
1504 }
drhfeac5f82004-08-01 00:10:45 +00001505 case MODE_Tcl: {
1506 if( p->cnt++==0 && p->showHeader ){
1507 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001508 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +00001509 fprintf(p->out, "%s", p->separator);
1510 }
1511 fprintf(p->out,"\n");
1512 }
1513 if( azArg==0 ) break;
1514 for(i=0; i<nArg; i++){
1515 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
1516 fprintf(p->out, "%s", p->separator);
1517 }
1518 fprintf(p->out,"\n");
1519 break;
1520 }
drh8e64d1c2004-10-07 00:32:39 +00001521 case MODE_Csv: {
1522 if( p->cnt++==0 && p->showHeader ){
1523 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001524 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001525 }
1526 fprintf(p->out,"\n");
1527 }
1528 if( azArg==0 ) break;
1529 for(i=0; i<nArg; i++){
1530 output_csv(p, azArg[i], i<nArg-1);
1531 }
1532 fprintf(p->out,"\n");
1533 break;
1534 }
drh28bd4bc2000-06-15 15:57:22 +00001535 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +00001536 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +00001537 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +00001538 for(i=0; i<nArg; i++){
1539 char *zSep = i>0 ? ",": "";
1540 if( azArg[i]==0 ){
1541 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +00001542 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001543 fprintf(p->out,"%s%s",zSep, azArg[i]);
1544 }else{
1545 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1546 output_quoted_string(p->out, azArg[i]);
1547 }
1548 }
1549 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001550 break;
drh28bd4bc2000-06-15 15:57:22 +00001551 }
persicom1d0b8722002-04-18 02:53:04 +00001552 }
drh75897232000-05-29 14:26:00 +00001553 return 0;
1554}
1555
1556/*
drh33048c02001-10-01 14:29:22 +00001557** Set the destination table field of the callback_data structure to
1558** the name of the table given. Escape any quote characters in the
1559** table name.
1560*/
1561static void set_table_name(struct callback_data *p, const char *zName){
1562 int i, n;
1563 int needQuote;
1564 char *z;
1565
1566 if( p->zDestTable ){
1567 free(p->zDestTable);
1568 p->zDestTable = 0;
1569 }
1570 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001571 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001572 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001573 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001574 needQuote = 1;
1575 if( zName[i]=='\'' ) n++;
1576 }
1577 }
1578 if( needQuote ) n += 2;
1579 z = p->zDestTable = malloc( n+1 );
1580 if( z==0 ){
1581 fprintf(stderr,"Out of memory!\n");
1582 exit(1);
1583 }
1584 n = 0;
1585 if( needQuote ) z[n++] = '\'';
1586 for(i=0; zName[i]; i++){
1587 z[n++] = zName[i];
1588 if( zName[i]=='\'' ) z[n++] = '\'';
1589 }
1590 if( needQuote ) z[n++] = '\'';
1591 z[n] = 0;
1592}
1593
danielk19772a02e332004-06-05 08:04:36 +00001594/* zIn is either a pointer to a NULL-terminated string in memory obtained
1595** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1596** added to zIn, and the result returned in memory obtained from malloc().
1597** zIn, if it was not NULL, is freed.
1598**
1599** If the third argument, quote, is not '\0', then it is used as a
1600** quote character for zAppend.
1601*/
drhc28490c2006-10-26 14:25:58 +00001602static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001603 int len;
1604 int i;
drh4f21c4a2008-12-10 22:15:00 +00001605 int nAppend = strlen30(zAppend);
1606 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001607
1608 len = nAppend+nIn+1;
1609 if( quote ){
1610 len += 2;
1611 for(i=0; i<nAppend; i++){
1612 if( zAppend[i]==quote ) len++;
1613 }
1614 }
1615
1616 zIn = (char *)realloc(zIn, len);
1617 if( !zIn ){
1618 return 0;
1619 }
1620
1621 if( quote ){
1622 char *zCsr = &zIn[nIn];
1623 *zCsr++ = quote;
1624 for(i=0; i<nAppend; i++){
1625 *zCsr++ = zAppend[i];
1626 if( zAppend[i]==quote ) *zCsr++ = quote;
1627 }
1628 *zCsr++ = quote;
1629 *zCsr++ = '\0';
1630 assert( (zCsr-zIn)==len );
1631 }else{
1632 memcpy(&zIn[nIn], zAppend, nAppend);
1633 zIn[len-1] = '\0';
1634 }
1635
1636 return zIn;
1637}
1638
drhdd3d4592004-08-30 01:54:05 +00001639
1640/*
1641** Execute a query statement that has a single result column. Print
1642** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +00001643**
1644** This is used, for example, to show the schema of the database by
1645** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +00001646*/
drh157e29a2009-05-21 15:15:00 +00001647static int run_table_dump_query(
1648 FILE *out, /* Send output here */
1649 sqlite3 *db, /* Database to query */
1650 const char *zSelect, /* SELECT statement to extract content */
1651 const char *zFirstRow /* Print before first row, if not NULL */
1652){
drhdd3d4592004-08-30 01:54:05 +00001653 sqlite3_stmt *pSelect;
1654 int rc;
1655 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
1656 if( rc!=SQLITE_OK || !pSelect ){
1657 return rc;
1658 }
1659 rc = sqlite3_step(pSelect);
1660 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001661 if( zFirstRow ){
1662 fprintf(out, "%s", zFirstRow);
1663 zFirstRow = 0;
1664 }
drhdd3d4592004-08-30 01:54:05 +00001665 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
1666 rc = sqlite3_step(pSelect);
1667 }
1668 return sqlite3_finalize(pSelect);
1669}
1670
1671
drh33048c02001-10-01 14:29:22 +00001672/*
drh4c653a02000-06-07 01:27:47 +00001673** This is a different callback routine used for dumping the database.
1674** Each row received by this callback consists of a table name,
1675** the table type ("index" or "table") and SQL to create the table.
1676** This routine should print text sufficient to recreate the table.
1677*/
1678static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001679 int rc;
1680 const char *zTable;
1681 const char *zType;
1682 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001683 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001684 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001685
drh902b9ee2008-12-05 17:17:07 +00001686 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001687 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001688 zTable = azArg[0];
1689 zType = azArg[1];
1690 zSql = azArg[2];
1691
drh00b950d2005-09-11 02:03:03 +00001692 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001693 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001694 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1695 fprintf(p->out, "ANALYZE sqlite_master;\n");
1696 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1697 return 0;
drh45e29d82006-11-20 16:21:10 +00001698 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1699 char *zIns;
1700 if( !p->writableSchema ){
1701 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1702 p->writableSchema = 1;
1703 }
1704 zIns = sqlite3_mprintf(
1705 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1706 "VALUES('table','%q','%q',0,'%q');",
1707 zTable, zTable, zSql);
1708 fprintf(p->out, "%s\n", zIns);
1709 sqlite3_free(zIns);
1710 return 0;
drh00b950d2005-09-11 02:03:03 +00001711 }else{
1712 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001713 }
danielk19772a02e332004-06-05 08:04:36 +00001714
1715 if( strcmp(zType, "table")==0 ){
1716 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001717 char *zSelect = 0;
1718 char *zTableInfo = 0;
1719 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001720 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001721
1722 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1723 zTableInfo = appendText(zTableInfo, zTable, '"');
1724 zTableInfo = appendText(zTableInfo, ");", 0);
1725
1726 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001727 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001728 if( rc!=SQLITE_OK || !pTableInfo ){
1729 return 1;
1730 }
1731
1732 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1733 zTmp = appendText(zTmp, zTable, '"');
1734 if( zTmp ){
1735 zSelect = appendText(zSelect, zTmp, '\'');
1736 }
1737 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1738 rc = sqlite3_step(pTableInfo);
1739 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001740 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001741 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001742 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001743 rc = sqlite3_step(pTableInfo);
1744 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001745 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001746 }else{
1747 zSelect = appendText(zSelect, ") ", 0);
1748 }
drh157e29a2009-05-21 15:15:00 +00001749 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001750 }
1751 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001752 if( rc!=SQLITE_OK || nRow==0 ){
1753 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001754 return 1;
1755 }
1756 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1757 zSelect = appendText(zSelect, zTable, '"');
1758
drh157e29a2009-05-21 15:15:00 +00001759 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001760 if( rc==SQLITE_CORRUPT ){
1761 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001762 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001763 }
danielk19772a02e332004-06-05 08:04:36 +00001764 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001765 }
drh4c653a02000-06-07 01:27:47 +00001766 return 0;
1767}
1768
1769/*
drh45e29d82006-11-20 16:21:10 +00001770** Run zQuery. Use dump_callback() as the callback routine so that
1771** the contents of the query are output as SQL statements.
1772**
drhdd3d4592004-08-30 01:54:05 +00001773** If we get a SQLITE_CORRUPT error, rerun the query after appending
1774** "ORDER BY rowid DESC" to the end.
1775*/
1776static int run_schema_dump_query(
1777 struct callback_data *p,
1778 const char *zQuery,
1779 char **pzErrMsg
1780){
1781 int rc;
1782 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1783 if( rc==SQLITE_CORRUPT ){
1784 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001785 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001786 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1787 zQ2 = malloc( len+100 );
1788 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001789 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001790 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1791 free(zQ2);
1792 }
1793 return rc;
1794}
1795
danielk1977c8c70692009-02-25 15:22:02 +00001796#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
1797struct GenfkeyCmd {
1798 sqlite3 *db; /* Database handle */
1799 struct callback_data *pCb; /* Callback data */
1800 int isIgnoreErrors; /* True for --ignore-errors */
1801 int isExec; /* True for --exec */
1802 int isNoDrop; /* True for --no-drop */
1803 int nErr; /* Number of errors seen so far */
1804};
1805typedef struct GenfkeyCmd GenfkeyCmd;
1806
1807static int genfkeyParseArgs(GenfkeyCmd *p, char **azArg, int nArg){
1808 int ii;
1809 memset(p, 0, sizeof(GenfkeyCmd));
1810
1811 for(ii=0; ii<nArg; ii++){
drh93a989c2009-03-16 10:59:44 +00001812 int n = strlen30(azArg[ii]);
danielk1977c8c70692009-02-25 15:22:02 +00001813
1814 if( n>2 && n<10 && 0==strncmp(azArg[ii], "--no-drop", n) ){
1815 p->isNoDrop = 1;
1816 }else if( n>2 && n<16 && 0==strncmp(azArg[ii], "--ignore-errors", n) ){
1817 p->isIgnoreErrors = 1;
1818 }else if( n>2 && n<7 && 0==strncmp(azArg[ii], "--exec", n) ){
1819 p->isExec = 1;
1820 }else{
1821 fprintf(stderr, "unknown option: %s\n", azArg[ii]);
1822 return -1;
1823 }
1824 }
1825
1826 return SQLITE_OK;
1827}
1828
1829static int genfkeyCmdCb(void *pCtx, int eType, const char *z){
1830 GenfkeyCmd *p = (GenfkeyCmd *)pCtx;
1831 if( eType==GENFKEY_ERROR && !p->isIgnoreErrors ){
1832 p->nErr++;
1833 fprintf(stderr, "%s\n", z);
1834 }
1835
1836 if( p->nErr==0 && (
1837 (eType==GENFKEY_CREATETRIGGER)
1838 || (eType==GENFKEY_DROPTRIGGER && !p->isNoDrop)
1839 )){
1840 if( p->isExec ){
1841 sqlite3_exec(p->db, z, 0, 0, 0);
1842 }else{
1843 char *zCol = "sql";
1844 callback((void *)p->pCb, 1, (char **)&z, (char **)&zCol);
1845 }
1846 }
1847
1848 return SQLITE_OK;
1849}
1850#endif
1851
drhdd3d4592004-08-30 01:54:05 +00001852/*
drh75897232000-05-29 14:26:00 +00001853** Text of a help message
1854*/
persicom1d0b8722002-04-18 02:53:04 +00001855static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001856 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001857 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001858 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001859 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +00001860 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001861 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001862 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
danielk1977c8c70692009-02-25 15:22:02 +00001863#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
1864 ".genfkey ?OPTIONS? Options are:\n"
1865 " --no-drop: Do not drop old fkey triggers.\n"
1866 " --ignore-errors: Ignore tables with fkey errors\n"
1867 " --exec: Execute generated SQL immediately\n"
danielk1977e6320042009-02-25 15:43:57 +00001868 " See file tool/genfkey.README in the source \n"
1869 " distribution for further information.\n"
danielk1977c8c70692009-02-25 15:22:02 +00001870#endif
persicom7e2dfdd2002-04-18 02:46:52 +00001871 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001872 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001873 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +00001874 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +00001875#ifdef SQLITE_ENABLE_IOTRACE
1876 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1877#endif
drh70df4fe2006-06-13 15:12:21 +00001878#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001879 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001880#endif
danielk19776b77a362005-01-13 11:10:25 +00001881 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001882 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001883 " column Left-aligned columns. (See .width)\n"
1884 " html HTML <table> code\n"
1885 " insert SQL insert statements for TABLE\n"
1886 " line One value per line\n"
1887 " list Values delimited by .separator string\n"
1888 " tabs Tab-separated values\n"
1889 " tcl TCL list elements\n"
1890 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001891 ".output FILENAME Send output to FILENAME\n"
1892 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001893 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001894 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001895 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001896 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001897 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +00001898 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001899 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +00001900 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +00001901 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +00001902#if HAS_TIMER
1903 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1904#endif
drh75897232000-05-29 14:26:00 +00001905 ".width NUM NUM ... Set column widths for \"column\" mode\n"
1906;
1907
drhdaffd0e2001-04-11 14:28:42 +00001908/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001909static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001910
drh75897232000-05-29 14:26:00 +00001911/*
drh44c2eb12003-04-30 11:38:26 +00001912** Make sure the database is open. If it is not, then open it. If
1913** the database fails to open, print an error message and exit.
1914*/
1915static void open_db(struct callback_data *p){
1916 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001917 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001918 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001919 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1920 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1921 shellstaticFunc, 0, 0);
1922 }
1923 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +00001924 fprintf(stderr,"Unable to open database \"%s\": %s\n",
1925 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001926 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001927 }
drhc2e87a32006-06-27 15:16:14 +00001928#ifndef SQLITE_OMIT_LOAD_EXTENSION
1929 sqlite3_enable_load_extension(p->db, 1);
1930#endif
drh44c2eb12003-04-30 11:38:26 +00001931 }
1932}
1933
1934/*
drhfeac5f82004-08-01 00:10:45 +00001935** Do C-language style dequoting.
1936**
1937** \t -> tab
1938** \n -> newline
1939** \r -> carriage return
1940** \NNN -> ascii character NNN in octal
1941** \\ -> backslash
1942*/
1943static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001944 int i, j;
1945 char c;
drhfeac5f82004-08-01 00:10:45 +00001946 for(i=j=0; (c = z[i])!=0; i++, j++){
1947 if( c=='\\' ){
1948 c = z[++i];
1949 if( c=='n' ){
1950 c = '\n';
1951 }else if( c=='t' ){
1952 c = '\t';
1953 }else if( c=='r' ){
1954 c = '\r';
1955 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001956 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001957 if( z[i+1]>='0' && z[i+1]<='7' ){
1958 i++;
1959 c = (c<<3) + z[i] - '0';
1960 if( z[i+1]>='0' && z[i+1]<='7' ){
1961 i++;
1962 c = (c<<3) + z[i] - '0';
1963 }
1964 }
1965 }
1966 }
1967 z[j] = c;
1968 }
1969 z[j] = 0;
1970}
1971
1972/*
drhc28490c2006-10-26 14:25:58 +00001973** Interpret zArg as a boolean value. Return either 0 or 1.
1974*/
1975static int booleanValue(char *zArg){
1976 int val = atoi(zArg);
1977 int j;
1978 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001979 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001980 }
1981 if( strcmp(zArg,"on")==0 ){
1982 val = 1;
1983 }else if( strcmp(zArg,"yes")==0 ){
1984 val = 1;
1985 }
1986 return val;
1987}
1988
1989/*
drh75897232000-05-29 14:26:00 +00001990** If an input line begins with "." then invoke this routine to
1991** process that line.
drh67505e72002-04-19 12:34:06 +00001992**
drh47ad6842006-11-08 12:25:42 +00001993** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001994*/
drh44c2eb12003-04-30 11:38:26 +00001995static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001996 int i = 1;
1997 int nArg = 0;
1998 int n, c;
drh67505e72002-04-19 12:34:06 +00001999 int rc = 0;
drh75897232000-05-29 14:26:00 +00002000 char *azArg[50];
2001
2002 /* Parse the input line into tokens.
2003 */
2004 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00002005 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002006 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002007 if( zLine[i]=='\'' || zLine[i]=='"' ){
2008 int delim = zLine[i++];
2009 azArg[nArg++] = &zLine[i];
2010 while( zLine[i] && zLine[i]!=delim ){ i++; }
2011 if( zLine[i]==delim ){
2012 zLine[i++] = 0;
2013 }
drhfeac5f82004-08-01 00:10:45 +00002014 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002015 }else{
2016 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00002017 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002018 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002019 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002020 }
2021 }
2022
2023 /* Process the input line.
2024 */
drh67505e72002-04-19 12:34:06 +00002025 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00002026 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002027 c = azArg[0][0];
drh9ff849f2009-02-04 20:55:57 +00002028 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){
2029 const char *zDestFile;
2030 const char *zDb;
2031 sqlite3 *pDest;
2032 sqlite3_backup *pBackup;
2033 int rc;
2034 if( nArg==2 ){
2035 zDestFile = azArg[1];
2036 zDb = "main";
2037 }else{
2038 zDestFile = azArg[2];
2039 zDb = azArg[1];
2040 }
2041 rc = sqlite3_open(zDestFile, &pDest);
2042 if( rc!=SQLITE_OK ){
2043 fprintf(stderr, "Error: cannot open %s\n", zDestFile);
2044 sqlite3_close(pDest);
2045 return 1;
2046 }
drhdc2c4912009-02-04 22:46:47 +00002047 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002048 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2049 if( pBackup==0 ){
2050 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2051 sqlite3_close(pDest);
2052 return 1;
2053 }
2054 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2055 sqlite3_backup_finish(pBackup);
2056 if( rc==SQLITE_DONE ){
2057 rc = SQLITE_OK;
2058 }else{
2059 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2060 }
2061 sqlite3_close(pDest);
2062 }else
2063
2064 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
drhc49f44e2006-10-26 18:15:42 +00002065 bail_on_error = booleanValue(azArg[1]);
2066 }else
2067
jplyon6a65bb32003-05-04 07:25:57 +00002068 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00002069 struct callback_data data;
2070 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00002071 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00002072 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002073 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002074 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002075 data.colWidth[0] = 3;
2076 data.colWidth[1] = 15;
2077 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002078 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002079 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002080 if( zErrMsg ){
2081 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002082 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00002083 }
2084 }else
2085
drh4c653a02000-06-07 01:27:47 +00002086 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
2087 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002088 open_db(p);
drh33048c02001-10-01 14:29:22 +00002089 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002090 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00002091 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002092 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002093 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002094 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00002095 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
2096 );
2097 run_schema_dump_query(p,
2098 "SELECT name, type, sql FROM sqlite_master "
2099 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00002100 );
2101 run_table_dump_query(p->out, p->db,
2102 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002103 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002104 );
drh4c653a02000-06-07 01:27:47 +00002105 }else{
2106 int i;
drhdd3d4592004-08-30 01:54:05 +00002107 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002108 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002109 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002110 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002111 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00002112 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00002113 run_table_dump_query(p->out, p->db,
2114 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002115 "WHERE sql NOT NULL"
2116 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002117 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002118 );
danielk1977bc6ada42004-06-30 08:20:16 +00002119 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002120 }
2121 }
drh45e29d82006-11-20 16:21:10 +00002122 if( p->writableSchema ){
2123 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
2124 p->writableSchema = 0;
2125 }
drh93f41e52008-08-11 19:12:34 +00002126 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002127 if( zErrMsg ){
2128 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002129 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00002130 }else{
2131 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002132 }
2133 }else
drh75897232000-05-29 14:26:00 +00002134
drhdaffd0e2001-04-11 14:28:42 +00002135 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002136 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00002137 }else
2138
drh75897232000-05-29 14:26:00 +00002139 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002140 rc = 2;
drh75897232000-05-29 14:26:00 +00002141 }else
2142
drhdd45df82002-04-18 12:39:03 +00002143 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002144 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002145 if(val == 1) {
2146 if(!p->explainPrev.valid) {
2147 p->explainPrev.valid = 1;
2148 p->explainPrev.mode = p->mode;
2149 p->explainPrev.showHeader = p->showHeader;
2150 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
2151 }
2152 /* We could put this code under the !p->explainValid
2153 ** condition so that it does not execute if we are already in
2154 ** explain mode. However, always executing it allows us an easy
2155 ** was to reset to explain mode in case the user previously
2156 ** did an .explain followed by a .width, .mode or .header
2157 ** command.
2158 */
danielk19770d78bae2008-01-03 07:09:48 +00002159 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002160 p->showHeader = 1;
2161 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002162 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002163 p->colWidth[1] = 13; /* opcode */
2164 p->colWidth[2] = 4; /* P1 */
2165 p->colWidth[3] = 4; /* P2 */
2166 p->colWidth[4] = 4; /* P3 */
2167 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002168 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002169 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00002170 }else if (p->explainPrev.valid) {
2171 p->explainPrev.valid = 0;
2172 p->mode = p->explainPrev.mode;
2173 p->showHeader = p->explainPrev.showHeader;
2174 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2175 }
drh75897232000-05-29 14:26:00 +00002176 }else
2177
danielk1977c8c70692009-02-25 15:22:02 +00002178#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
2179 if( c=='g' && strncmp(azArg[0], "genfkey", n)==0 ){
2180 GenfkeyCmd cmd;
2181 if( 0==genfkeyParseArgs(&cmd, &azArg[1], nArg-1) ){
2182 cmd.db = p->db;
2183 cmd.pCb = p;
2184 genfkey_create_triggers(p->db, "main", (void *)&cmd, genfkeyCmdCb);
2185 }
2186 }else
2187#endif
2188
drhc28490c2006-10-26 14:25:58 +00002189 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00002190 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002191 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00002192 }else
2193
2194 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00002195 fprintf(stderr,"%s",zHelp);
drh75897232000-05-29 14:26:00 +00002196 }else
2197
drhfeac5f82004-08-01 00:10:45 +00002198 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
2199 char *zTable = azArg[2]; /* Insert data into this table */
2200 char *zFile = azArg[1]; /* The file from which to extract data */
2201 sqlite3_stmt *pStmt; /* A statement */
2202 int rc; /* Result code */
2203 int nCol; /* Number of columns in the table */
2204 int nByte; /* Number of bytes in an SQL string */
2205 int i, j; /* Loop counters */
2206 int nSep; /* Number of bytes in p->separator[] */
2207 char *zSql; /* An SQL statement */
2208 char *zLine; /* A single line of input from the file */
2209 char **azCol; /* zLine[] broken up into columns */
2210 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00002211 FILE *in; /* The input file */
2212 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00002213
drha543c822006-06-08 16:10:14 +00002214 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002215 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002216 if( nSep==0 ){
2217 fprintf(stderr, "non-null separator required for import\n");
2218 return 0;
2219 }
2220 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
2221 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00002222 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002223 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002224 sqlite3_free(zSql);
2225 if( rc ){
2226 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2227 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00002228 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002229 }else{
2230 nCol = sqlite3_column_count(pStmt);
2231 }
2232 sqlite3_finalize(pStmt);
2233 if( nCol==0 ) return 0;
2234 zSql = malloc( nByte + 20 + nCol*2 );
2235 if( zSql==0 ) return 0;
2236 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002237 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002238 for(i=1; i<nCol; i++){
2239 zSql[j++] = ',';
2240 zSql[j++] = '?';
2241 }
2242 zSql[j++] = ')';
2243 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002244 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002245 free(zSql);
2246 if( rc ){
2247 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
2248 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00002249 return 1;
drhfeac5f82004-08-01 00:10:45 +00002250 }
2251 in = fopen(zFile, "rb");
2252 if( in==0 ){
2253 fprintf(stderr, "cannot open file: %s\n", zFile);
2254 sqlite3_finalize(pStmt);
2255 return 0;
2256 }
2257 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00002258 if( azCol==0 ){
2259 fclose(in);
2260 return 0;
2261 }
drhfeac5f82004-08-01 00:10:45 +00002262 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
2263 zCommit = "COMMIT";
2264 while( (zLine = local_getline(0, in))!=0 ){
2265 char *z;
2266 i = 0;
drhb860bc92004-08-04 15:16:55 +00002267 lineno++;
drhfeac5f82004-08-01 00:10:45 +00002268 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00002269 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00002270 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
2271 *z = 0;
2272 i++;
drhb860bc92004-08-04 15:16:55 +00002273 if( i<nCol ){
2274 azCol[i] = &z[nSep];
2275 z += nSep-1;
2276 }
drhfeac5f82004-08-01 00:10:45 +00002277 }
2278 }
drh1cd7f832005-08-05 18:50:51 +00002279 *z = 0;
drhb860bc92004-08-04 15:16:55 +00002280 if( i+1!=nCol ){
2281 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
2282 zFile, lineno, nCol, i+1);
2283 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00002284 free(zLine);
drhb860bc92004-08-04 15:16:55 +00002285 break;
2286 }
drhfeac5f82004-08-01 00:10:45 +00002287 for(i=0; i<nCol; i++){
2288 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2289 }
2290 sqlite3_step(pStmt);
2291 rc = sqlite3_reset(pStmt);
2292 free(zLine);
2293 if( rc!=SQLITE_OK ){
2294 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2295 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00002296 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002297 break;
2298 }
2299 }
2300 free(azCol);
2301 fclose(in);
2302 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00002303 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002304 }else
2305
drh75897232000-05-29 14:26:00 +00002306 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
2307 struct callback_data data;
2308 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002309 open_db(p);
drh75897232000-05-29 14:26:00 +00002310 memcpy(&data, p, sizeof(data));
2311 data.showHeader = 0;
2312 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00002313 zShellStatic = azArg[1];
2314 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00002315 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002316 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002317 "UNION ALL "
2318 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002319 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002320 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002321 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002322 );
danielk1977bc6ada42004-06-30 08:20:16 +00002323 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00002324 if( zErrMsg ){
2325 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002326 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002327 }
2328 }else
2329
drhae5e4452007-05-03 17:18:36 +00002330#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002331 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002332 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002333 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2334 iotrace = 0;
2335 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002336 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002337 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002338 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002339 iotrace = stdout;
2340 }else{
2341 iotrace = fopen(azArg[1], "w");
2342 if( iotrace==0 ){
2343 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002344 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002345 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002346 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002347 }
2348 }
2349 }else
drhae5e4452007-05-03 17:18:36 +00002350#endif
drhb0603412007-02-28 04:47:26 +00002351
drh70df4fe2006-06-13 15:12:21 +00002352#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002353 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2354 const char *zFile, *zProc;
2355 char *zErrMsg = 0;
2356 int rc;
2357 zFile = azArg[1];
2358 zProc = nArg>=3 ? azArg[2] : 0;
2359 open_db(p);
2360 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2361 if( rc!=SQLITE_OK ){
2362 fprintf(stderr, "%s\n", zErrMsg);
2363 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002364 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002365 }
2366 }else
drh70df4fe2006-06-13 15:12:21 +00002367#endif
drh1e397f82006-06-08 15:28:43 +00002368
drh28bd4bc2000-06-15 15:57:22 +00002369 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00002370 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002371 if( strncmp(azArg[1],"line",n2)==0
2372 ||
2373 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002374 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00002375 }else if( strncmp(azArg[1],"column",n2)==0
2376 ||
2377 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002378 p->mode = MODE_Column;
2379 }else if( strncmp(azArg[1],"list",n2)==0 ){
2380 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00002381 }else if( strncmp(azArg[1],"html",n2)==0 ){
2382 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00002383 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
2384 p->mode = MODE_Tcl;
2385 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002386 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002387 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00002388 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
2389 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002390 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00002391 }else if( strncmp(azArg[1],"insert",n2)==0 ){
2392 p->mode = MODE_Insert;
2393 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00002394 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00002395 }else{
drh33048c02001-10-01 14:29:22 +00002396 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00002397 }
drhdaffd0e2001-04-11 14:28:42 +00002398 }else {
drhcf68ae92006-12-19 18:47:41 +00002399 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002400 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00002401 }
2402 }else
2403
persicom7e2dfdd2002-04-18 02:46:52 +00002404 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002405 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2406 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002407 }else
2408
drh75897232000-05-29 14:26:00 +00002409 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
2410 if( p->out!=stdout ){
2411 fclose(p->out);
2412 }
2413 if( strcmp(azArg[1],"stdout")==0 ){
2414 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00002415 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00002416 }else{
drha1f9b5e2004-02-14 16:31:02 +00002417 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00002418 if( p->out==0 ){
2419 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
2420 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00002421 } else {
drh5bb3eb92007-05-04 13:15:55 +00002422 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002423 }
2424 }
2425 }else
2426
drhdd45df82002-04-18 12:39:03 +00002427 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002428 if( nArg >= 2) {
2429 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2430 }
2431 if( nArg >= 3) {
2432 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2433 }
2434 }else
2435
2436 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002437 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002438 }else
2439
drh9ff849f2009-02-04 20:55:57 +00002440 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002441 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002442 if( alt==0 ){
2443 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
2444 }else{
2445 process_input(p, alt);
2446 fclose(alt);
2447 }
2448 }else
2449
drh9ff849f2009-02-04 20:55:57 +00002450 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){
2451 const char *zSrcFile;
2452 const char *zDb;
2453 sqlite3 *pSrc;
2454 sqlite3_backup *pBackup;
2455 int rc;
drhdc2c4912009-02-04 22:46:47 +00002456 int nTimeout = 0;
2457
drh9ff849f2009-02-04 20:55:57 +00002458 if( nArg==2 ){
2459 zSrcFile = azArg[1];
2460 zDb = "main";
2461 }else{
2462 zSrcFile = azArg[2];
2463 zDb = azArg[1];
2464 }
2465 rc = sqlite3_open(zSrcFile, &pSrc);
2466 if( rc!=SQLITE_OK ){
2467 fprintf(stderr, "Error: cannot open %s\n", zSrcFile);
2468 sqlite3_close(pSrc);
2469 return 1;
2470 }
drhdc2c4912009-02-04 22:46:47 +00002471 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002472 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2473 if( pBackup==0 ){
2474 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2475 sqlite3_close(pSrc);
2476 return 1;
2477 }
drhdc2c4912009-02-04 22:46:47 +00002478 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2479 || rc==SQLITE_BUSY ){
2480 if( rc==SQLITE_BUSY ){
2481 if( nTimeout++ >= 3 ) break;
2482 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002483 }
2484 }
2485 sqlite3_backup_finish(pBackup);
2486 if( rc==SQLITE_DONE ){
2487 rc = SQLITE_OK;
drhdc2c4912009-02-04 22:46:47 +00002488 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2489 fprintf(stderr, "source database is busy\n");
drh9ff849f2009-02-04 20:55:57 +00002490 }else{
2491 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2492 }
2493 sqlite3_close(pSrc);
2494 }else
2495
drh75897232000-05-29 14:26:00 +00002496 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
2497 struct callback_data data;
2498 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002499 open_db(p);
drh75897232000-05-29 14:26:00 +00002500 memcpy(&data, p, sizeof(data));
2501 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002502 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002503 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002504 int i;
shane7d3846a2008-12-11 02:58:26 +00002505 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002506 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002507 char *new_argv[2], *new_colv[2];
2508 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2509 " type text,\n"
2510 " name text,\n"
2511 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002512 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002513 " sql text\n"
2514 ")";
2515 new_argv[1] = 0;
2516 new_colv[0] = "sql";
2517 new_colv[1] = 0;
2518 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00002519 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002520 char *new_argv[2], *new_colv[2];
2521 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2522 " type text,\n"
2523 " name text,\n"
2524 " tbl_name text,\n"
2525 " rootpage integer,\n"
2526 " sql text\n"
2527 ")";
2528 new_argv[1] = 0;
2529 new_colv[0] = "sql";
2530 new_colv[1] = 0;
2531 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00002532 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002533 zShellStatic = azArg[1];
2534 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002535 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002536 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2537 " FROM sqlite_master UNION ALL"
2538 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002539 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002540 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002541 callback, &data, &zErrMsg);
2542 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002543 }
drh75897232000-05-29 14:26:00 +00002544 }else{
danielk19776f8a5032004-05-10 10:34:51 +00002545 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002546 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002547 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2548 " FROM sqlite_master UNION ALL"
2549 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002550 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002551 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002552 callback, &data, &zErrMsg
2553 );
drh75897232000-05-29 14:26:00 +00002554 }
drh75897232000-05-29 14:26:00 +00002555 if( zErrMsg ){
2556 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002557 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002558 }
2559 }else
2560
2561 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002562 sqlite3_snprintf(sizeof(p->separator), p->separator,
2563 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002564 }else
2565
persicom7e2dfdd2002-04-18 02:46:52 +00002566 if( c=='s' && strncmp(azArg[0], "show", n)==0){
2567 int i;
2568 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002569 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002570 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002571 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002572 fprintf(p->out,"%9.9s: ", "nullvalue");
2573 output_c_string(p->out, p->nullvalue);
2574 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002575 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002576 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002577 fprintf(p->out,"%9.9s: ", "separator");
2578 output_c_string(p->out, p->separator);
2579 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002580 fprintf(p->out,"%9.9s: ","width");
2581 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002582 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002583 }
drhfeac5f82004-08-01 00:10:45 +00002584 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002585 }else
2586
drh2dfbbca2000-07-28 14:32:48 +00002587 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00002588 char **azResult;
2589 int nRow, rc;
2590 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002591 open_db(p);
drha50da102000-08-08 20:19:09 +00002592 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002593 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002594 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00002595 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002596 "UNION ALL "
2597 "SELECT name FROM sqlite_temp_master "
2598 "WHERE type IN ('table','view') "
2599 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002600 &azResult, &nRow, 0, &zErrMsg
2601 );
drha50da102000-08-08 20:19:09 +00002602 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002603 zShellStatic = azArg[1];
2604 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002605 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002606 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002607 "UNION ALL "
2608 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002609 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002610 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002611 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002612 );
danielk1977bc6ada42004-06-30 08:20:16 +00002613 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002614 }
drh75897232000-05-29 14:26:00 +00002615 if( zErrMsg ){
2616 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002617 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002618 }
drhe3710332000-09-29 13:30:53 +00002619 if( rc==SQLITE_OK ){
2620 int len, maxlen = 0;
2621 int i, j;
2622 int nPrintCol, nPrintRow;
2623 for(i=1; i<=nRow; i++){
2624 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002625 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002626 if( len>maxlen ) maxlen = len;
2627 }
2628 nPrintCol = 80/(maxlen+2);
2629 if( nPrintCol<1 ) nPrintCol = 1;
2630 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2631 for(i=0; i<nPrintRow; i++){
2632 for(j=i+1; j<=nRow; j+=nPrintRow){
2633 char *zSp = j<=nPrintRow ? "" : " ";
2634 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2635 }
2636 printf("\n");
2637 }
drh47ad6842006-11-08 12:25:42 +00002638 }else{
2639 rc = 1;
drhe3710332000-09-29 13:30:53 +00002640 }
danielk19776f8a5032004-05-10 10:34:51 +00002641 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002642 }else
2643
drh3b1a9882007-11-02 12:53:03 +00002644 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00002645 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002646 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00002647 }else
drh3b1a9882007-11-02 12:53:03 +00002648
2649#if HAS_TIMER
2650 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
2651 enableTimer = booleanValue(azArg[1]);
2652 }else
2653#endif
drh2dfbbca2000-07-28 14:32:48 +00002654
drh75897232000-05-29 14:26:00 +00002655 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
2656 int j;
drh43617e92006-03-06 20:55:46 +00002657 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002658 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2659 p->colWidth[j-1] = atoi(azArg[j]);
2660 }
2661 }else
2662
drh3b1a9882007-11-02 12:53:03 +00002663
drh75897232000-05-29 14:26:00 +00002664 {
drh67505e72002-04-19 12:34:06 +00002665 fprintf(stderr, "unknown command or invalid arguments: "
2666 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00002667 }
drh67505e72002-04-19 12:34:06 +00002668
2669 return rc;
drh75897232000-05-29 14:26:00 +00002670}
2671
drh67505e72002-04-19 12:34:06 +00002672/*
drh91a66392007-09-07 01:12:32 +00002673** Return TRUE if a semicolon occurs anywhere in the first N characters
2674** of string z[].
drh324ccef2003-02-05 14:06:20 +00002675*/
drh91a66392007-09-07 01:12:32 +00002676static int _contains_semicolon(const char *z, int N){
2677 int i;
2678 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2679 return 0;
drh324ccef2003-02-05 14:06:20 +00002680}
2681
2682/*
drh70c7a4b2003-04-26 03:03:06 +00002683** Test to see if a line consists entirely of whitespace.
2684*/
2685static int _all_whitespace(const char *z){
2686 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002687 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002688 if( *z=='/' && z[1]=='*' ){
2689 z += 2;
2690 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2691 if( *z==0 ) return 0;
2692 z++;
2693 continue;
2694 }
2695 if( *z=='-' && z[1]=='-' ){
2696 z += 2;
2697 while( *z && *z!='\n' ){ z++; }
2698 if( *z==0 ) return 1;
2699 continue;
2700 }
2701 return 0;
2702 }
2703 return 1;
2704}
2705
2706/*
drha9b17162003-04-29 18:01:28 +00002707** Return TRUE if the line typed in is an SQL command terminator other
2708** than a semi-colon. The SQL Server style "go" command is understood
2709** as is the Oracle "/".
2710*/
2711static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002712 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002713 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2714 return 1; /* Oracle */
2715 }
drhc8d74412004-08-31 23:41:26 +00002716 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2717 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002718 return 1; /* SQL Server */
2719 }
2720 return 0;
2721}
2722
2723/*
drh233a5312008-12-18 22:25:13 +00002724** Return true if zSql is a complete SQL statement. Return false if it
2725** ends in the middle of a string literal or C-style comment.
2726*/
2727static int _is_complete(char *zSql, int nSql){
2728 int rc;
2729 if( zSql==0 ) return 1;
2730 zSql[nSql] = ';';
2731 zSql[nSql+1] = 0;
2732 rc = sqlite3_complete(zSql);
2733 zSql[nSql] = 0;
2734 return rc;
2735}
2736
2737/*
drh67505e72002-04-19 12:34:06 +00002738** Read input from *in and process it. If *in==0 then input
2739** is interactive - the user is typing it it. Otherwise, input
2740** is coming from a file or device. A prompt is issued and history
2741** is saved only if input is interactive. An interrupt signal will
2742** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002743**
2744** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002745*/
drhc28490c2006-10-26 14:25:58 +00002746static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002747 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002748 char *zSql = 0;
2749 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002750 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002751 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002752 int rc;
2753 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002754 int lineno = 0;
2755 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002756
2757 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2758 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002759 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002760 zLine = one_input_line(zSql, in);
2761 if( zLine==0 ){
2762 break; /* We have reached EOF */
2763 }
drh67505e72002-04-19 12:34:06 +00002764 if( seenInterrupt ){
2765 if( in!=0 ) break;
2766 seenInterrupt = 0;
2767 }
drhc28490c2006-10-26 14:25:58 +00002768 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00002769 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00002770 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002771 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00002772 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00002773 if( rc==2 ){
2774 break;
2775 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002776 errCnt++;
2777 }
drhdaffd0e2001-04-11 14:28:42 +00002778 continue;
2779 }
drh233a5312008-12-18 22:25:13 +00002780 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002781 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002782 }
drh91a66392007-09-07 01:12:32 +00002783 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002784 if( zSql==0 ){
2785 int i;
drh4c755c02004-08-08 20:22:17 +00002786 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002787 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002788 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002789 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002790 if( zSql==0 ){
2791 fprintf(stderr, "out of memory\n");
2792 exit(1);
2793 }
drh5bb3eb92007-05-04 13:15:55 +00002794 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002795 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002796 }
2797 }else{
drh4f21c4a2008-12-10 22:15:00 +00002798 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002799 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002800 if( zSql==0 ){
2801 fprintf(stderr,"%s: out of memory!\n", Argv0);
2802 exit(1);
2803 }
drh5bb3eb92007-05-04 13:15:55 +00002804 zSql[nSql++] = '\n';
2805 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002806 nSql += len;
2807 }
drh91a66392007-09-07 01:12:32 +00002808 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2809 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002810 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002811 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002812 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00002813 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002814 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002815 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002816 char zPrefix[100];
2817 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002818 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
2819 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002820 }else{
drh5bb3eb92007-05-04 13:15:55 +00002821 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00002822 }
drh7f953e22002-07-13 17:33:45 +00002823 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00002824 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002825 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002826 zErrMsg = 0;
2827 }else{
drhc28490c2006-10-26 14:25:58 +00002828 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002829 }
drhc49f44e2006-10-26 18:15:42 +00002830 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002831 }
2832 free(zSql);
2833 zSql = 0;
2834 nSql = 0;
2835 }
2836 }
2837 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00002838 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002839 free(zSql);
2840 }
danielk19772ac27622007-07-03 05:31:16 +00002841 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002842 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002843}
2844
drh67505e72002-04-19 12:34:06 +00002845/*
2846** Return a pathname which is the user's home directory. A
2847** 0 return indicates an error of some kind. Space to hold the
2848** resulting string is obtained from malloc(). The calling
2849** function should free the result.
2850*/
2851static char *find_home_dir(void){
2852 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002853
chw97185482008-11-17 08:05:31 +00002854#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002855 struct passwd *pwent;
2856 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002857 if( (pwent=getpwuid(uid)) != NULL) {
2858 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002859 }
2860#endif
2861
chw65d3c132007-11-12 21:09:10 +00002862#if defined(_WIN32_WCE)
2863 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2864 */
2865 home_dir = strdup("/");
2866#else
2867
drh164a1b62006-08-19 11:15:20 +00002868#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2869 if (!home_dir) {
2870 home_dir = getenv("USERPROFILE");
2871 }
2872#endif
2873
drh67505e72002-04-19 12:34:06 +00002874 if (!home_dir) {
2875 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002876 }
2877
drhcdb36b72006-06-12 12:57:45 +00002878#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002879 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002880 char *zDrive, *zPath;
2881 int n;
2882 zDrive = getenv("HOMEDRIVE");
2883 zPath = getenv("HOMEPATH");
2884 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002885 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002886 home_dir = malloc( n );
2887 if( home_dir==0 ) return 0;
2888 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2889 return home_dir;
2890 }
2891 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002892 }
2893#endif
2894
chw65d3c132007-11-12 21:09:10 +00002895#endif /* !_WIN32_WCE */
2896
drh67505e72002-04-19 12:34:06 +00002897 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002898 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002899 char *z = malloc( n );
2900 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002901 home_dir = z;
2902 }
drhe98d4fa2002-04-21 19:06:22 +00002903
drh67505e72002-04-19 12:34:06 +00002904 return home_dir;
2905}
2906
2907/*
2908** Read input from the file given by sqliterc_override. Or if that
2909** parameter is NULL, take input from ~/.sqliterc
2910*/
drh22fbcb82004-02-01 01:22:50 +00002911static void process_sqliterc(
2912 struct callback_data *p, /* Configuration data */
2913 const char *sqliterc_override /* Name of config file. NULL to use default */
2914){
persicom7e2dfdd2002-04-18 02:46:52 +00002915 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002916 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002917 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002918 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002919 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002920
2921 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002922 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002923 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002924#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00002925 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00002926#endif
drhe98d4fa2002-04-21 19:06:22 +00002927 return;
2928 }
drh4f21c4a2008-12-10 22:15:00 +00002929 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002930 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002931 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002932 fprintf(stderr,"%s: out of memory!\n", Argv0);
2933 exit(1);
2934 }
drha959ac42007-06-20 13:10:00 +00002935 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002936 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002937 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002938 }
drha1f9b5e2004-02-14 16:31:02 +00002939 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002940 if( in ){
drhc28490c2006-10-26 14:25:58 +00002941 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00002942 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002943 }
persicom7e2dfdd2002-04-18 02:46:52 +00002944 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002945 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002946 }
drh43617e92006-03-06 20:55:46 +00002947 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00002948 return;
2949}
2950
drh67505e72002-04-19 12:34:06 +00002951/*
drhe1e38c42003-05-04 18:30:59 +00002952** Show available command line options
2953*/
2954static const char zOptions[] =
2955 " -init filename read/process named file\n"
2956 " -echo print commands before execution\n"
2957 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002958 " -bail stop after hitting an error\n"
2959 " -interactive force interactive I/O\n"
2960 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002961 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002962 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002963 " -html set output mode to HTML\n"
2964 " -line set output mode to 'line'\n"
2965 " -list set output mode to 'list'\n"
2966 " -separator 'x' set output field separator (|)\n"
2967 " -nullvalue 'text' set text string for NULL values\n"
2968 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002969;
2970static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002971 fprintf(stderr,
2972 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2973 "FILENAME is the name of an SQLite database. A new database is created\n"
2974 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002975 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002976 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002977 }else{
2978 fprintf(stderr, "Use the -help option for additional information\n");
2979 }
2980 exit(1);
2981}
2982
2983/*
drh67505e72002-04-19 12:34:06 +00002984** Initialize the state information in data
2985*/
drh0850b532006-01-31 19:31:43 +00002986static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002987 memset(data, 0, sizeof(*data));
2988 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002989 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002990 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00002991 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2992 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00002993}
2994
drh75897232000-05-29 14:26:00 +00002995int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002996 char *zErrMsg = 0;
2997 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002998 const char *zInitFile = 0;
2999 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003000 int i;
drhc28490c2006-10-26 14:25:58 +00003001 int rc = 0;
drh75897232000-05-29 14:26:00 +00003002
drhdaffd0e2001-04-11 14:28:42 +00003003 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003004 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003005 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003006
drh44c2eb12003-04-30 11:38:26 +00003007 /* Make sure we have a valid signal handler early, before anything
3008 ** else is done.
3009 */
drh4c504392000-10-16 22:06:40 +00003010#ifdef SIGINT
3011 signal(SIGINT, interrupt_handler);
3012#endif
drh44c2eb12003-04-30 11:38:26 +00003013
drh22fbcb82004-02-01 01:22:50 +00003014 /* Do an initial pass through the command-line argument to locate
3015 ** the name of the database file, the name of the initialization file,
3016 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003017 */
drh22fbcb82004-02-01 01:22:50 +00003018 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00003019 char *z;
drh44c2eb12003-04-30 11:38:26 +00003020 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00003021 z = argv[i];
3022 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00003023 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
3024 i++;
drh22fbcb82004-02-01 01:22:50 +00003025 }else if( strcmp(argv[i],"-init")==0 ){
3026 i++;
3027 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00003028 }
3029 }
drh22fbcb82004-02-01 01:22:50 +00003030 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00003031#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00003032 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
3033#else
drh22fbcb82004-02-01 01:22:50 +00003034 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00003035#endif
drh22fbcb82004-02-01 01:22:50 +00003036 }else{
danielk197703aded42004-11-22 05:26:27 +00003037#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003038 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003039#else
3040 data.zDbFilename = 0;
3041#endif
drh22fbcb82004-02-01 01:22:50 +00003042 }
3043 if( i<argc ){
3044 zFirstCmd = argv[i++];
3045 }
drh44c2eb12003-04-30 11:38:26 +00003046 data.out = stdout;
3047
drh01b41712005-08-29 23:06:23 +00003048#ifdef SQLITE_OMIT_MEMORYDB
3049 if( data.zDbFilename==0 ){
3050 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
3051 exit(1);
3052 }
3053#endif
3054
drh44c2eb12003-04-30 11:38:26 +00003055 /* Go ahead and open the database file if it already exists. If the
3056 ** file does not exist, delay opening it. This prevents empty database
3057 ** files from being created if a user mistypes the database name argument
3058 ** to the sqlite command-line tool.
3059 */
drhc8d74412004-08-31 23:41:26 +00003060 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003061 open_db(&data);
3062 }
3063
drh22fbcb82004-02-01 01:22:50 +00003064 /* Process the initialization file if there is one. If no -init option
3065 ** is given on the command line, look for a file named ~/.sqliterc and
3066 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003067 */
drh22fbcb82004-02-01 01:22:50 +00003068 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00003069
drh22fbcb82004-02-01 01:22:50 +00003070 /* Make a second pass through the command-line argument and set
3071 ** options. This second pass is delayed until after the initialization
3072 ** file is processed so that the command-line arguments will override
3073 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003074 */
drh22fbcb82004-02-01 01:22:50 +00003075 for(i=1; i<argc && argv[i][0]=='-'; i++){
3076 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00003077 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003078 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003079 i++;
3080 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003081 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003082 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003083 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003084 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003085 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003086 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003087 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003088 }else if( strcmp(z,"-csv")==0 ){
3089 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003090 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003091 }else if( strcmp(z,"-separator")==0 ){
3092 i++;
drh5bb3eb92007-05-04 13:15:55 +00003093 sqlite3_snprintf(sizeof(data.separator), data.separator,
3094 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003095 }else if( strcmp(z,"-nullvalue")==0 ){
3096 i++;
drh5bb3eb92007-05-04 13:15:55 +00003097 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
3098 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003099 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003100 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003101 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003102 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003103 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003104 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003105 }else if( strcmp(z,"-bail")==0 ){
3106 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003107 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00003108 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00003109 return 0;
drhc28490c2006-10-26 14:25:58 +00003110 }else if( strcmp(z,"-interactive")==0 ){
3111 stdin_is_interactive = 1;
3112 }else if( strcmp(z,"-batch")==0 ){
3113 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00003114 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003115 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00003116 }else{
drh22fbcb82004-02-01 01:22:50 +00003117 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003118 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003119 return 1;
3120 }
3121 }
drh44c2eb12003-04-30 11:38:26 +00003122
drh22fbcb82004-02-01 01:22:50 +00003123 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003124 /* Run just the command that follows the database name
3125 */
drh22fbcb82004-02-01 01:22:50 +00003126 if( zFirstCmd[0]=='.' ){
3127 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003128 exit(0);
3129 }else{
3130 int rc;
drh44c2eb12003-04-30 11:38:26 +00003131 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00003132 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00003133 if( rc!=0 && zErrMsg!=0 ){
3134 fprintf(stderr,"SQL error: %s\n", zErrMsg);
3135 exit(1);
3136 }
drh75897232000-05-29 14:26:00 +00003137 }
3138 }else{
drh44c2eb12003-04-30 11:38:26 +00003139 /* Run commands received from standard input
3140 */
drhc28490c2006-10-26 14:25:58 +00003141 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003142 char *zHome;
3143 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003144 int nHistory;
drh75897232000-05-29 14:26:00 +00003145 printf(
drhb217a572000-08-22 13:40:18 +00003146 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00003147 "Enter \".help\" for instructions\n"
3148 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00003149 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00003150 );
drh67505e72002-04-19 12:34:06 +00003151 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003152 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003153 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003154 if( (zHistory = malloc(nHistory))!=0 ){
3155 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3156 }
drh67505e72002-04-19 12:34:06 +00003157 }
danielk19774af00c62005-01-23 23:43:21 +00003158#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003159 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003160#endif
drhc28490c2006-10-26 14:25:58 +00003161 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003162 if( zHistory ){
3163 stifle_history(100);
3164 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003165 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003166 }
adamd0a3daa32006-07-28 20:16:14 +00003167 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00003168 }else{
drhc28490c2006-10-26 14:25:58 +00003169 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003170 }
3171 }
drh33048c02001-10-01 14:29:22 +00003172 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00003173 if( db ){
3174 if( sqlite3_close(db)!=SQLITE_OK ){
3175 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
3176 }
3177 }
drhc28490c2006-10-26 14:25:58 +00003178 return rc;
drh75897232000-05-29 14:26:00 +00003179}