blob: 35be1b3cbc521828843d435c12cf1bb3fddcb4a4 [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**
drhda108222009-02-25 19:07:24 +000015** $Id: shell.c,v 1.204 2009/02/25 19:07:25 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
danielk1977c8c70692009-02-25 15:22:02 +0000118
119/**************************************************************************
120***************************************************************************
121** Begin genfkey logic.
122*/
123#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined SQLITE_OMIT_SUBQUERY
124
125#define GENFKEY_ERROR 1
126#define GENFKEY_DROPTRIGGER 2
127#define GENFKEY_CREATETRIGGER 3
128static int genfkey_create_triggers(sqlite3 *, const char *, void *,
129 int (*)(void *, int, const char *)
130);
131
132struct GenfkeyCb {
133 void *pCtx;
134 int eType;
135 int (*xData)(void *, int, const char *);
136};
137typedef struct GenfkeyCb GenfkeyCb;
138
139/* The code in this file defines a sqlite3 virtual-table module that
140** provides a read-only view of the current database schema. There is one
141** row in the schema table for each column in the database schema.
142*/
143#define SCHEMA \
144"CREATE TABLE x(" \
145 "database," /* Name of database (i.e. main, temp etc.) */ \
146 "tablename," /* Name of table */ \
147 "cid," /* Column number (from left-to-right, 0 upward) */ \
148 "name," /* Column name */ \
149 "type," /* Specified type (i.e. VARCHAR(32)) */ \
150 "not_null," /* Boolean. True if NOT NULL was specified */ \
151 "dflt_value," /* Default value for this column */ \
152 "pk" /* True if this column is part of the primary key */ \
153")"
154
155#define SCHEMA2 \
156"CREATE TABLE x(" \
157 "database," /* Name of database (i.e. main, temp etc.) */ \
158 "from_tbl," /* Name of table */ \
159 "fkid," \
160 "seq," \
161 "to_tbl," \
162 "from_col," \
163 "to_col," \
164 "on_update," \
165 "on_delete," \
166 "match" \
167")"
168
169#define SCHEMA3 \
170"CREATE TABLE x(" \
171 "database," /* Name of database (i.e. main, temp etc.) */ \
172 "tablename," /* Name of table */ \
173 "seq," \
174 "name," \
175 "isunique" \
176")"
177
178#define SCHEMA4 \
179"CREATE TABLE x(" \
180 "database," /* Name of database (i.e. main, temp etc.) */ \
181 "indexname," /* Name of table */ \
182 "seqno," \
183 "cid," \
184 "name" \
185")"
186
187#define SCHEMA5 \
188"CREATE TABLE x(" \
189 "database," /* Name of database (i.e. main, temp etc.) */ \
190 "triggername," /* Name of trigger */ \
191 "dummy" /* Unused */ \
192")"
193
194typedef struct SchemaTable SchemaTable;
195struct SchemaTable {
196 const char *zName;
197 const char *zObject;
198 const char *zPragma;
199 const char *zSchema;
200} aSchemaTable[] = {
201 { "table_info", "table", "PRAGMA %Q.table_info(%Q)", SCHEMA },
202 { "foreign_key_list", "table", "PRAGMA %Q.foreign_key_list(%Q)", SCHEMA2 },
203 { "index_list", "table", "PRAGMA %Q.index_list(%Q)", SCHEMA3 },
204 { "index_info", "index", "PRAGMA %Q.index_info(%Q)", SCHEMA4 },
205 { "trigger_list", "trigger", "SELECT 1", SCHEMA5 },
206 { 0, 0, 0, 0 }
207};
208
209typedef struct schema_vtab schema_vtab;
210typedef struct schema_cursor schema_cursor;
211
212/* A schema table object */
213struct schema_vtab {
214 sqlite3_vtab base;
215 sqlite3 *db;
216 SchemaTable *pType;
217};
218
219/* A schema table cursor object */
220struct schema_cursor {
221 sqlite3_vtab_cursor base;
222 sqlite3_stmt *pDbList;
223 sqlite3_stmt *pTableList;
224 sqlite3_stmt *pColumnList;
225 int rowid;
226};
227
228/*
229** Table destructor for the schema module.
230*/
231static int schemaDestroy(sqlite3_vtab *pVtab){
232 sqlite3_free(pVtab);
233 return 0;
234}
235
236/*
237** Table constructor for the schema module.
238*/
239static int schemaCreate(
240 sqlite3 *db,
241 void *pAux,
242 int argc, const char *const*argv,
243 sqlite3_vtab **ppVtab,
244 char **pzErr
245){
246 int rc = SQLITE_NOMEM;
247 schema_vtab *pVtab;
248 SchemaTable *pType = &aSchemaTable[0];
249
250 if( argc>3 ){
251 int i;
252 pType = 0;
253 for(i=0; aSchemaTable[i].zName; i++){
254 if( 0==strcmp(argv[3], aSchemaTable[i].zName) ){
255 pType = &aSchemaTable[i];
256 }
257 }
258 if( !pType ){
259 return SQLITE_ERROR;
260 }
261 }
262
263 pVtab = sqlite3_malloc(sizeof(schema_vtab));
264 if( pVtab ){
265 memset(pVtab, 0, sizeof(schema_vtab));
266 pVtab->db = (sqlite3 *)pAux;
267 pVtab->pType = pType;
268 rc = sqlite3_declare_vtab(db, pType->zSchema);
269 }
270 *ppVtab = (sqlite3_vtab *)pVtab;
271 return rc;
272}
273
274/*
275** Open a new cursor on the schema table.
276*/
277static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
278 int rc = SQLITE_NOMEM;
279 schema_cursor *pCur;
280 pCur = sqlite3_malloc(sizeof(schema_cursor));
281 if( pCur ){
282 memset(pCur, 0, sizeof(schema_cursor));
283 *ppCursor = (sqlite3_vtab_cursor *)pCur;
284 rc = SQLITE_OK;
285 }
286 return rc;
287}
288
289/*
290** Close a schema table cursor.
291*/
292static int schemaClose(sqlite3_vtab_cursor *cur){
293 schema_cursor *pCur = (schema_cursor *)cur;
294 sqlite3_finalize(pCur->pDbList);
295 sqlite3_finalize(pCur->pTableList);
296 sqlite3_finalize(pCur->pColumnList);
297 sqlite3_free(pCur);
298 return SQLITE_OK;
299}
300
301static void columnToResult(sqlite3_context *ctx, sqlite3_stmt *pStmt, int iCol){
302 switch( sqlite3_column_type(pStmt, iCol) ){
303 case SQLITE_NULL:
304 sqlite3_result_null(ctx);
305 break;
306 case SQLITE_INTEGER:
307 sqlite3_result_int64(ctx, sqlite3_column_int64(pStmt, iCol));
308 break;
309 case SQLITE_FLOAT:
310 sqlite3_result_double(ctx, sqlite3_column_double(pStmt, iCol));
311 break;
312 case SQLITE_TEXT: {
313 const char *z = (const char *)sqlite3_column_text(pStmt, iCol);
314 sqlite3_result_text(ctx, z, -1, SQLITE_TRANSIENT);
315 break;
316 }
317 }
318}
319
320/*
321** Retrieve a column of data.
322*/
323static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
324 schema_cursor *pCur = (schema_cursor *)cur;
325 switch( i ){
326 case 0:
327 columnToResult(ctx, pCur->pDbList, 1);
328 break;
329 case 1:
330 columnToResult(ctx, pCur->pTableList, 0);
331 break;
332 default:
333 columnToResult(ctx, pCur->pColumnList, i-2);
334 break;
335 }
336 return SQLITE_OK;
337}
338
339/*
340** Retrieve the current rowid.
341*/
342static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
343 schema_cursor *pCur = (schema_cursor *)cur;
344 *pRowid = pCur->rowid;
345 return SQLITE_OK;
346}
347
348static int finalize(sqlite3_stmt **ppStmt){
349 int rc = sqlite3_finalize(*ppStmt);
350 *ppStmt = 0;
351 return rc;
352}
353
354static int schemaEof(sqlite3_vtab_cursor *cur){
355 schema_cursor *pCur = (schema_cursor *)cur;
356 return (pCur->pDbList ? 0 : 1);
357}
358
359/*
360** Advance the cursor to the next row.
361*/
362static int schemaNext(sqlite3_vtab_cursor *cur){
363 int rc = SQLITE_OK;
364 schema_cursor *pCur = (schema_cursor *)cur;
365 schema_vtab *pVtab = (schema_vtab *)(cur->pVtab);
366 char *zSql = 0;
367
368 while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){
369 if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit;
370
371 while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){
372 if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit;
373
374 assert(pCur->pDbList);
375 while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){
376 rc = finalize(&pCur->pDbList);
377 goto next_exit;
378 }
379
380 /* Set zSql to the SQL to pull the list of tables from the
381 ** sqlite_master (or sqlite_temp_master) table of the database
382 ** identfied by the row pointed to by the SQL statement pCur->pDbList
383 ** (iterating through a "PRAGMA database_list;" statement).
384 */
385 if( sqlite3_column_int(pCur->pDbList, 0)==1 ){
386 zSql = sqlite3_mprintf(
387 "SELECT name FROM sqlite_temp_master WHERE type=%Q",
388 pVtab->pType->zObject
389 );
390 }else{
391 sqlite3_stmt *pDbList = pCur->pDbList;
392 zSql = sqlite3_mprintf(
393 "SELECT name FROM %Q.sqlite_master WHERE type=%Q",
394 sqlite3_column_text(pDbList, 1), pVtab->pType->zObject
395 );
396 }
397 if( !zSql ){
398 rc = SQLITE_NOMEM;
399 goto next_exit;
400 }
401
402 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0);
403 sqlite3_free(zSql);
404 if( rc!=SQLITE_OK ) goto next_exit;
405 }
406
407 /* Set zSql to the SQL to the table_info pragma for the table currently
408 ** identified by the rows pointed to by statements pCur->pDbList and
409 ** pCur->pTableList.
410 */
411 zSql = sqlite3_mprintf(pVtab->pType->zPragma,
412 sqlite3_column_text(pCur->pDbList, 1),
413 sqlite3_column_text(pCur->pTableList, 0)
414 );
415
416 if( !zSql ){
417 rc = SQLITE_NOMEM;
418 goto next_exit;
419 }
420 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0);
421 sqlite3_free(zSql);
422 if( rc!=SQLITE_OK ) goto next_exit;
423 }
424 pCur->rowid++;
425
426next_exit:
427 /* TODO: Handle rc */
428 return rc;
429}
430
431/*
432** Reset a schema table cursor.
433*/
434static int schemaFilter(
435 sqlite3_vtab_cursor *pVtabCursor,
436 int idxNum, const char *idxStr,
437 int argc, sqlite3_value **argv
438){
439 int rc;
440 schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab);
441 schema_cursor *pCur = (schema_cursor *)pVtabCursor;
442 pCur->rowid = 0;
443 finalize(&pCur->pTableList);
444 finalize(&pCur->pColumnList);
445 finalize(&pCur->pDbList);
446 rc = sqlite3_prepare(pVtab->db,"SELECT 0, 'main'", -1, &pCur->pDbList, 0);
447 return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc);
448}
449
450/*
451** Analyse the WHERE condition.
452*/
453static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
454 return SQLITE_OK;
455}
456
457/*
458** A virtual table module that merely echos method calls into TCL
459** variables.
460*/
461static sqlite3_module schemaModule = {
462 0, /* iVersion */
463 schemaCreate,
464 schemaCreate,
465 schemaBestIndex,
466 schemaDestroy,
467 schemaDestroy,
468 schemaOpen, /* xOpen - open a cursor */
469 schemaClose, /* xClose - close a cursor */
470 schemaFilter, /* xFilter - configure scan constraints */
471 schemaNext, /* xNext - advance a cursor */
472 schemaEof, /* xEof */
473 schemaColumn, /* xColumn - read data */
474 schemaRowid, /* xRowid - read data */
475 0, /* xUpdate */
476 0, /* xBegin */
477 0, /* xSync */
478 0, /* xCommit */
479 0, /* xRollback */
480 0, /* xFindMethod */
481 0, /* xRename */
482};
483
484/*
485** Extension load function.
486*/
487static int installSchemaModule(sqlite3 *db, sqlite3 *sdb){
488 sqlite3_create_module(db, "schema", &schemaModule, (void *)sdb);
489 return 0;
490}
491
492/*
493** sj(zValue, zJoin)
494**
495** The following block contains the implementation of an aggregate
496** function that returns a string. Each time the function is stepped,
497** it appends data to an internal buffer. When the aggregate is finalized,
498** the contents of the buffer are returned.
499**
500** The first time the aggregate is stepped the buffer is set to a copy
501** of the first argument. The second time and subsequent times it is
502** stepped a copy of the second argument is appended to the buffer, then
503** a copy of the first.
504**
505** Example:
506**
507** INSERT INTO t1(a) VALUES('1');
508** INSERT INTO t1(a) VALUES('2');
509** INSERT INTO t1(a) VALUES('3');
510** SELECT sj(a, ', ') FROM t1;
511**
512** => "1, 2, 3"
513**
514*/
515struct StrBuffer {
516 char *zBuf;
517};
518typedef struct StrBuffer StrBuffer;
519static void joinFinalize(sqlite3_context *context){
520 StrBuffer *p;
521 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
522 sqlite3_result_text(context, p->zBuf, -1, SQLITE_TRANSIENT);
523 sqlite3_free(p->zBuf);
524}
525static void joinStep(
526 sqlite3_context *context,
527 int argc,
528 sqlite3_value **argv
529){
530 StrBuffer *p;
531 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
532 if( p->zBuf==0 ){
533 p->zBuf = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
534 }else{
535 char *zTmp = p->zBuf;
536 p->zBuf = sqlite3_mprintf("%s%s%s",
537 zTmp, sqlite3_value_text(argv[1]), sqlite3_value_text(argv[0])
538 );
539 sqlite3_free(zTmp);
540 }
541}
542
543/*
544** dq(zString)
545**
546** This scalar function accepts a single argument and interprets it as
547** a text value. The return value is the argument enclosed in double
548** quotes. If any double quote characters are present in the argument,
549** these are escaped.
550**
551** dq('the raven "Nevermore."') == '"the raven ""Nevermore."""'
552*/
553static void doublequote(
554 sqlite3_context *context,
555 int argc,
556 sqlite3_value **argv
557){
558 int ii;
559 char *zOut;
560 char *zCsr;
561 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
562 int nIn = sqlite3_value_bytes(argv[0]);
563
564 zOut = sqlite3_malloc(nIn*2+3);
565 zCsr = zOut;
566 *zCsr++ = '"';
567 for(ii=0; ii<nIn; ii++){
568 *zCsr++ = zIn[ii];
569 if( zIn[ii]=='"' ){
570 *zCsr++ = '"';
571 }
572 }
573 *zCsr++ = '"';
574 *zCsr++ = '\0';
575
576 sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT);
577 sqlite3_free(zOut);
578}
579
580/*
581** multireplace(zString, zSearch1, zReplace1, ...)
582*/
583static void multireplace(
584 sqlite3_context *context,
585 int argc,
586 sqlite3_value **argv
587){
588 int i = 0;
589 char *zOut = 0;
590 int nOut = 0;
591 int nMalloc = 0;
592 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
593 int nIn = sqlite3_value_bytes(argv[0]);
594
595 while( i<nIn ){
596 const char *zCopy = &zIn[i];
597 int nCopy = 1;
598 int nReplace = 1;
599 int j;
600 for(j=1; j<(argc-1); j+=2){
601 const char *z = (const char *)sqlite3_value_text(argv[j]);
602 int n = sqlite3_value_bytes(argv[j]);
603 if( n<=(nIn-i) && 0==strncmp(z, zCopy, n) ){
604 zCopy = (const char *)sqlite3_value_text(argv[j+1]);
605 nCopy = sqlite3_value_bytes(argv[j+1]);
606 nReplace = n;
607 break;
608 }
609 }
610 if( (nOut+nCopy)>nMalloc ){
611 nMalloc += (nMalloc + 16);
612 zOut = (char *)sqlite3_realloc(zOut, nMalloc);
613 }
614 memcpy(&zOut[nOut], zCopy, nCopy);
615 i += nReplace;
616 nOut += nCopy;
617 }
618
619 sqlite3_result_text(context, zOut, nOut, SQLITE_TRANSIENT);
620 sqlite3_free(zOut);
621}
622
623/*
624** A callback for sqlite3_exec() invokes the callback specified by the
625** GenfkeyCb structure pointed to by the void* passed as the first argument.
626*/
627static int invokeCallback(void *p, int nArg, char **azArg, char **azCol){
628 GenfkeyCb *pCb = (GenfkeyCb *)p;
629 return pCb->xData(pCb->pCtx, pCb->eType, azArg[0]);
630}
631
632int detectSchemaProblem(
633 sqlite3 *db, /* Database connection */
634 const char *zMessage, /* English language error message */
635 const char *zSql, /* SQL statement to run */
636 GenfkeyCb *pCb
637){
638 sqlite3_stmt *pStmt;
639 int rc;
640 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
641 if( rc!=SQLITE_OK ){
642 return rc;
643 }
644 while( SQLITE_ROW==sqlite3_step(pStmt) ){
645 char *zDel;
646 int iFk = sqlite3_column_int(pStmt, 0);
647 const char *zTab = (const char *)sqlite3_column_text(pStmt, 1);
648 zDel = sqlite3_mprintf("Error in table %s: %s", zTab, zMessage);
649 rc = pCb->xData(pCb->pCtx, pCb->eType, zDel);
650 sqlite3_free(zDel);
651 if( rc!=SQLITE_OK ) return rc;
652 zDel = sqlite3_mprintf(
653 "DELETE FROM temp.fkey WHERE from_tbl = %Q AND fkid = %d"
654 , zTab, iFk
655 );
656 sqlite3_exec(db, zDel, 0, 0, 0);
657 sqlite3_free(zDel);
658 }
659 sqlite3_finalize(pStmt);
660 return SQLITE_OK;
661}
662
663/*
664** Create and populate temporary table "fkey".
665*/
666static int populateTempTable(sqlite3 *db, GenfkeyCb *pCallback){
667 int rc;
668
669 rc = sqlite3_exec(db,
670 "CREATE VIRTUAL TABLE temp.v_fkey USING schema(foreign_key_list);"
671 "CREATE VIRTUAL TABLE temp.v_col USING schema(table_info);"
672 "CREATE VIRTUAL TABLE temp.v_idxlist USING schema(index_list);"
673 "CREATE VIRTUAL TABLE temp.v_idxinfo USING schema(index_info);"
674 "CREATE VIRTUAL TABLE temp.v_triggers USING schema(trigger_list);"
675 "CREATE TABLE temp.fkey AS "
676 "SELECT from_tbl, to_tbl, fkid, from_col, to_col, on_update, on_delete "
677 "FROM temp.v_fkey WHERE database = 'main';"
678 , 0, 0, 0
679 );
680 if( rc!=SQLITE_OK ) return rc;
681
682 rc = detectSchemaProblem(db, "foreign key columns do not exist",
683 "SELECT fkid, from_tbl "
684 "FROM temp.fkey "
685 "WHERE to_col IS NOT NULL AND NOT EXISTS (SELECT 1 "
686 "FROM temp.v_col WHERE tablename=to_tbl AND name==to_col"
687 ")", pCallback
688 );
689 if( rc!=SQLITE_OK ) return rc;
690
691 /* At this point the temp.fkey table is mostly populated. If any foreign
692 ** keys were specified so that they implicitly refer to they primary
693 ** key of the parent table, the "to_col" values of the temp.fkey rows
694 ** are still set to NULL.
695 **
696 ** This is easily fixed for single column primary keys, but not for
697 ** composites. With a composite primary key, there is no way to reliably
698 ** query sqlite for the order in which the columns that make up the
699 ** composite key were declared i.e. there is no way to tell if the
700 ** schema actually contains "PRIMARY KEY(a, b)" or "PRIMARY KEY(b, a)".
701 ** Therefore, this case is not handled. The following function call
702 ** detects instances of this case.
703 */
704 rc = detectSchemaProblem(db, "implicit mapping to composite primary key",
705 "SELECT fkid, from_tbl "
706 "FROM temp.fkey "
707 "WHERE to_col IS NULL "
708 "GROUP BY fkid, from_tbl HAVING count(*) > 1", pCallback
709 );
710 if( rc!=SQLITE_OK ) return rc;
711
712 /* Detect attempts to implicitly map to the primary key of a table
713 ** that has no primary key column.
714 */
715 rc = detectSchemaProblem(db, "implicit mapping to non-existant primary key",
716 "SELECT fkid, from_tbl "
717 "FROM temp.fkey "
718 "WHERE to_col IS NULL AND NOT EXISTS "
719 "(SELECT 1 FROM temp.v_col WHERE pk AND tablename = temp.fkey.to_tbl)"
720 , pCallback
721 );
722 if( rc!=SQLITE_OK ) return rc;
723
724 /* Fix all the implicit primary key mappings in the temp.fkey table. */
725 rc = sqlite3_exec(db,
726 "UPDATE temp.fkey SET to_col = "
727 "(SELECT name FROM temp.v_col WHERE pk AND tablename=temp.fkey.to_tbl)"
728 " WHERE to_col IS NULL;"
729 , 0, 0, 0
730 );
731 if( rc!=SQLITE_OK ) return rc;
732
733 /* Now check that all all parent keys are either primary keys or
734 ** subject to a unique constraint.
735 */
736 rc = sqlite3_exec(db,
737 "CREATE TABLE temp.idx2 AS SELECT "
738 "il.tablename AS tablename,"
739 "ii.indexname AS indexname,"
740 "ii.name AS col "
741 "FROM temp.v_idxlist AS il, temp.v_idxinfo AS ii "
742 "WHERE il.isunique AND il.database='main' AND ii.indexname = il.name;"
743 "INSERT INTO temp.idx2 "
744 "SELECT tablename, 'pk', name FROM temp.v_col WHERE pk;"
745
746 "CREATE TABLE temp.idx AS SELECT "
747 "tablename, indexname, sj(dq(col),',') AS cols "
748 "FROM (SELECT * FROM temp.idx2 ORDER BY col) "
749 "GROUP BY tablename, indexname;"
750
751 "CREATE TABLE temp.fkey2 AS SELECT "
752 "fkid, from_tbl, to_tbl, sj(dq(to_col),',') AS cols "
753 "FROM (SELECT * FROM temp.fkey ORDER BY to_col) "
754 "GROUP BY fkid, from_tbl;"
755
756 "CREATE TABLE temp.triggers AS SELECT "
757 "triggername FROM temp.v_triggers WHERE database='main' AND "
758 "triggername LIKE 'genfkey%';"
759 , 0, 0, 0
760 );
761 if( rc!=SQLITE_OK ) return rc;
762 rc = detectSchemaProblem(db, "foreign key is not unique",
763 "SELECT fkid, from_tbl "
764 "FROM temp.fkey2 "
765 "WHERE NOT EXISTS (SELECT 1 "
766 "FROM temp.idx WHERE tablename=to_tbl AND fkey2.cols==idx.cols"
767 ")", pCallback
768 );
769 if( rc!=SQLITE_OK ) return rc;
770
771 return rc;
772}
773
774#define GENFKEY_ERROR 1
775#define GENFKEY_DROPTRIGGER 2
776#define GENFKEY_CREATETRIGGER 3
777static int genfkey_create_triggers(
778 sqlite3 *sdb, /* Connection to read schema from */
779 const char *zDb, /* Name of db to read ("main", "temp") */
780 void *pCtx, /* Context pointer to pass to xData */
781 int (*xData)(void *, int, const char *)
782){
783 const char *zSql =
784 "SELECT multireplace('"
785
786 "-- Triggers for foreign key mapping:\n"
787 "--\n"
788 "-- /from_readable/ REFERENCES /to_readable/\n"
789 "-- on delete /on_delete/\n"
790 "-- on update /on_update/\n"
791 "--\n"
792
793 /* The "BEFORE INSERT ON <referencing>" trigger. This trigger's job is to
794 ** throw an exception if the user tries to insert a row into the
795 ** referencing table for which there is no corresponding row in
796 ** the referenced table.
797 */
798 "CREATE TRIGGER /name/_insert_referencing BEFORE INSERT ON /tbl/ WHEN \n"
799 " /key_notnull/ AND NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
800 "BEGIN\n"
801 " SELECT RAISE(ABORT, ''constraint failed'');\n"
802 "END;\n"
803
804 /* The "BEFORE UPDATE ON <referencing>" trigger. This trigger's job
805 ** is to throw an exception if the user tries to update a row in the
806 ** referencing table causing it to correspond to no row in the
807 ** referenced table.
808 */
809 "CREATE TRIGGER /name/_update_referencing BEFORE\n"
810 " UPDATE OF /rkey_list/ ON /tbl/ WHEN \n"
811 " /key_notnull/ AND \n"
812 " NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
813 "BEGIN\n"
814 " SELECT RAISE(ABORT, ''constraint failed'');\n"
815 "END;\n"
816
817
818 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
819 ** is to detect when a row is deleted from the referenced table to
820 ** which rows in the referencing table correspond. The action taken
821 ** depends on the value of the 'ON DELETE' clause.
822 */
823 "CREATE TRIGGER /name/_delete_referenced BEFORE DELETE ON /ref/ WHEN\n"
824 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
825 "BEGIN\n"
826 " /delete_action/\n"
827 "END;\n"
828
829 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
830 ** is to detect when the key columns of a row in the referenced table
831 ** to which one or more rows in the referencing table correspond are
832 ** updated. The action taken depends on the value of the 'ON UPDATE'
833 ** clause.
834 */
835 "CREATE TRIGGER /name/_update_referenced AFTER\n"
836 " UPDATE OF /fkey_list/ ON /ref/ WHEN \n"
837 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
838 "BEGIN\n"
839 " /update_action/\n"
840 "END;\n"
841 "'"
842
843 /* These are used in the SQL comment written above each set of triggers */
844 ", '/from_readable/', from_tbl || '(' || sj(from_col, ', ') || ')'"
845 ", '/to_readable/', to_tbl || '(' || sj(to_col, ', ') || ')'"
846 ", '/on_delete/', on_delete"
847 ", '/on_update/', on_update"
848
849 ", '/name/', 'genfkey' || min(rowid)"
850 ", '/tbl/', dq(from_tbl)"
851 ", '/ref/', dq(to_tbl)"
852 ", '/key_notnull/', sj('new.' || dq(from_col) || ' IS NOT NULL', ' AND ')"
853
854 ", '/fkey_list/', sj(to_col, ', ')"
855 ", '/rkey_list/', sj(from_col, ', ')"
856
857 ", '/cond1/', sj(multireplace('new./from/ == /to/'"
858 ", '/from/', dq(from_col)"
859 ", '/to/', dq(to_col)"
860 "), ' AND ')"
861 ", '/cond2/', sj(multireplace('old./to/ == /from/'"
862 ", '/from/', dq(from_col)"
863 ", '/to/', dq(to_col)"
864 "), ' AND ')"
865
866 ", '/update_action/', CASE on_update "
867 "WHEN 'SET NULL' THEN "
868 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
869 ", '/setlist/', sj(from_col||' = NULL',', ')"
870 ", '/tbl/', dq(from_tbl)"
871 ", '/where/', sj(from_col||' = old.'||dq(to_col),' AND ')"
872 ")"
873 "WHEN 'CASCADE' THEN "
874 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
875 ", '/setlist/', sj(dq(from_col)||' = new.'||dq(to_col),', ')"
876 ", '/tbl/', dq(from_tbl)"
877 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
878 ")"
879 "ELSE "
880 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
881 "END "
882
883 ", '/delete_action/', CASE on_delete "
884 "WHEN 'SET NULL' THEN "
885 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
886 ", '/setlist/', sj(from_col||' = NULL',', ')"
887 ", '/tbl/', dq(from_tbl)"
888 ", '/where/', sj(from_col||' = old.'||dq(to_col),' AND ')"
889 ")"
890 "WHEN 'CASCADE' THEN "
891 "multireplace('DELETE FROM /tbl/ WHERE /where/;' "
892 ", '/tbl/', dq(from_tbl)"
893 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
894 ")"
895 "ELSE "
896 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
897 "END "
898
899 ") FROM temp.fkey "
900 "GROUP BY from_tbl, fkid"
901 ;
902
903 int rc;
904 const int enc = SQLITE_UTF8;
905 sqlite3 *db = 0;
906
907 GenfkeyCb cb;
908 cb.xData = xData;
909 cb.pCtx = pCtx;
910
911 /* Open the working database handle. */
912 rc = sqlite3_open(":memory:", &db);
913 if( rc!=SQLITE_OK ) goto genfkey_exit;
914
915 /* Create the special scalar and aggregate functions used by this program. */
916 sqlite3_create_function(db, "dq", 1, enc, 0, doublequote, 0, 0);
917 sqlite3_create_function(db, "multireplace", -1, enc, db, multireplace, 0, 0);
918 sqlite3_create_function(db, "sj", 2, enc, 0, 0, joinStep, joinFinalize);
919
920 /* Install the "schema" virtual table module */
921 installSchemaModule(db, sdb);
922
923 /* Create and populate a temp table with the information required to
924 ** build the foreign key triggers. See function populateTempTable()
925 ** for details.
926 */
927 cb.eType = GENFKEY_ERROR;
928 rc = populateTempTable(db, &cb);
929 if( rc!=SQLITE_OK ) goto genfkey_exit;
930
931 /* Unless the --no-drop option was specified, generate DROP TRIGGER
932 ** statements to drop any triggers in the database generated by a
933 ** previous run of this program.
934 */
935 cb.eType = GENFKEY_DROPTRIGGER;
936 rc = sqlite3_exec(db,
937 "SELECT 'DROP TRIGGER main.' || dq(triggername) || ';' FROM triggers"
938 ,invokeCallback, (void *)&cb, 0
939 );
940 if( rc!=SQLITE_OK ) goto genfkey_exit;
941
942 /* Run the main query to create the trigger definitions. */
943 cb.eType = GENFKEY_CREATETRIGGER;
944 rc = sqlite3_exec(db, zSql, invokeCallback, (void *)&cb, 0);
945 if( rc!=SQLITE_OK ) goto genfkey_exit;
946
947genfkey_exit:
948 sqlite3_close(db);
949 return rc;
950}
951
952
953#endif
954/* End genfkey logic. */
955/*************************************************************************/
956/*************************************************************************/
957
drhe91d16b2008-12-08 18:27:31 +0000958/*
959** Used to prevent warnings about unused parameters
960*/
961#define UNUSED_PARAMETER(x) (void)(x)
drh3b1a9882007-11-02 12:53:03 +0000962
drh75897232000-05-29 14:26:00 +0000963/*
drhc49f44e2006-10-26 18:15:42 +0000964** If the following flag is set, then command execution stops
965** at an error if we are not interactive.
966*/
967static int bail_on_error = 0;
968
969/*
drhc28490c2006-10-26 14:25:58 +0000970** Threat stdin as an interactive input if the following variable
971** is true. Otherwise, assume stdin is connected to a file or pipe.
972*/
973static int stdin_is_interactive = 1;
974
975/*
drh4c504392000-10-16 22:06:40 +0000976** The following is the open SQLite database. We make a pointer
977** to this database a static variable so that it can be accessed
978** by the SIGINT handler to interrupt database processing.
979*/
danielk197792f9a1b2004-06-19 09:08:16 +0000980static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000981
982/*
drh67505e72002-04-19 12:34:06 +0000983** True if an interrupt (Control-C) has been received.
984*/
drh43617e92006-03-06 20:55:46 +0000985static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000986
987/*
persicom7e2dfdd2002-04-18 02:46:52 +0000988** This is the name of our program. It is set in main(), used
989** in a number of other places, mostly for error messages.
990*/
991static char *Argv0;
992
993/*
994** Prompt strings. Initialized in main. Settable with
995** .prompt main continue
996*/
997static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
998static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
999
drhb0603412007-02-28 04:47:26 +00001000/*
1001** Write I/O traces to the following stream.
1002*/
rsebe0a9092007-07-30 18:24:38 +00001003#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001004static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +00001005#endif
drhb0603412007-02-28 04:47:26 +00001006
1007/*
1008** This routine works like printf in that its first argument is a
1009** format string and subsequent arguments are values to be substituted
1010** in place of % fields. The result of formatting this string
1011** is written to iotrace.
1012*/
rsebe0a9092007-07-30 18:24:38 +00001013#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001014static void iotracePrintf(const char *zFormat, ...){
1015 va_list ap;
drhf075cd02007-02-28 06:14:25 +00001016 char *z;
drhb0603412007-02-28 04:47:26 +00001017 if( iotrace==0 ) return;
1018 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +00001019 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +00001020 va_end(ap);
drhf075cd02007-02-28 06:14:25 +00001021 fprintf(iotrace, "%s", z);
1022 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +00001023}
rsebe0a9092007-07-30 18:24:38 +00001024#endif
drhb0603412007-02-28 04:47:26 +00001025
drh44c2eb12003-04-30 11:38:26 +00001026
persicom7e2dfdd2002-04-18 02:46:52 +00001027/*
drh83965662003-04-17 02:54:13 +00001028** Determines if a string is a number of not.
1029*/
danielk19772e588c72005-12-09 14:25:08 +00001030static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +00001031 if( *z=='-' || *z=='+' ) z++;
1032 if( !isdigit(*z) ){
1033 return 0;
1034 }
1035 z++;
1036 if( realnum ) *realnum = 0;
1037 while( isdigit(*z) ){ z++; }
1038 if( *z=='.' ){
1039 z++;
1040 if( !isdigit(*z) ) return 0;
1041 while( isdigit(*z) ){ z++; }
1042 if( realnum ) *realnum = 1;
1043 }
1044 if( *z=='e' || *z=='E' ){
1045 z++;
1046 if( *z=='+' || *z=='-' ) z++;
1047 if( !isdigit(*z) ) return 0;
1048 while( isdigit(*z) ){ z++; }
1049 if( realnum ) *realnum = 1;
1050 }
1051 return *z==0;
1052}
drh83965662003-04-17 02:54:13 +00001053
1054/*
danielk1977bc6ada42004-06-30 08:20:16 +00001055** A global char* and an SQL function to access its current value
1056** from within an SQL statement. This program used to use the
1057** sqlite_exec_printf() API to substitue a string into an SQL statement.
1058** The correct way to do this with sqlite3 is to use the bind API, but
1059** since the shell is built around the callback paradigm it would be a lot
1060** of work. Instead just use this hack, which is quite harmless.
1061*/
1062static const char *zShellStatic = 0;
1063static void shellstaticFunc(
1064 sqlite3_context *context,
1065 int argc,
1066 sqlite3_value **argv
1067){
1068 assert( 0==argc );
1069 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +00001070 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +00001071 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +00001072 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
1073}
1074
1075
1076/*
drhfeac5f82004-08-01 00:10:45 +00001077** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +00001078** the text in memory obtained from malloc() and returns a pointer
1079** to the text. NULL is returned at end of file, or if malloc()
1080** fails.
1081**
1082** The interface is like "readline" but no command-line editing
1083** is done.
1084*/
drh9347b202003-07-18 01:30:59 +00001085static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +00001086 char *zLine;
1087 int nLine;
drh8e7e7a22000-05-30 18:45:23 +00001088 int n;
1089 int eol;
1090
1091 if( zPrompt && *zPrompt ){
1092 printf("%s",zPrompt);
1093 fflush(stdout);
1094 }
1095 nLine = 100;
1096 zLine = malloc( nLine );
1097 if( zLine==0 ) return 0;
1098 n = 0;
1099 eol = 0;
1100 while( !eol ){
1101 if( n+100>nLine ){
1102 nLine = nLine*2 + 100;
1103 zLine = realloc(zLine, nLine);
1104 if( zLine==0 ) return 0;
1105 }
drhdaffd0e2001-04-11 14:28:42 +00001106 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +00001107 if( n==0 ){
1108 free(zLine);
1109 return 0;
1110 }
1111 zLine[n] = 0;
1112 eol = 1;
1113 break;
1114 }
1115 while( zLine[n] ){ n++; }
1116 if( n>0 && zLine[n-1]=='\n' ){
1117 n--;
1118 zLine[n] = 0;
1119 eol = 1;
1120 }
1121 }
1122 zLine = realloc( zLine, n+1 );
1123 return zLine;
1124}
1125
1126/*
drhc28490c2006-10-26 14:25:58 +00001127** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +00001128**
1129** zPrior is a string of prior text retrieved. If not the empty
1130** string, then issue a continuation prompt.
1131*/
drhdaffd0e2001-04-11 14:28:42 +00001132static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +00001133 char *zPrompt;
1134 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +00001135 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +00001136 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +00001137 }
1138 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +00001139 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +00001140 }else{
persicom7e2dfdd2002-04-18 02:46:52 +00001141 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +00001142 }
1143 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +00001144#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +00001145 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +00001146#endif
drh8e7e7a22000-05-30 18:45:23 +00001147 return zResult;
1148}
1149
persicom7e2dfdd2002-04-18 02:46:52 +00001150struct previous_mode_data {
1151 int valid; /* Is there legit data in here? */
1152 int mode;
1153 int showHeader;
1154 int colWidth[100];
1155};
drh45e29d82006-11-20 16:21:10 +00001156
drh8e7e7a22000-05-30 18:45:23 +00001157/*
drh75897232000-05-29 14:26:00 +00001158** An pointer to an instance of this structure is passed from
1159** the main program to the callback. This is used to communicate
1160** state and mode information.
1161*/
1162struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +00001163 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +00001164 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +00001165 int cnt; /* Number of records displayed so far */
1166 FILE *out; /* Write results here */
1167 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +00001168 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +00001169 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +00001170 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +00001171 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +00001172 int colWidth[100]; /* Requested width of each column when in column mode*/
1173 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +00001174 char nullvalue[20]; /* The text to print when a NULL comes back from
1175 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +00001176 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +00001177 /* Holds the mode information just before
1178 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +00001179 char outfile[FILENAME_MAX]; /* Filename for *out */
1180 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +00001181};
1182
1183/*
1184** These are the allowed modes.
1185*/
drh967e8b72000-06-21 13:59:10 +00001186#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +00001187#define MODE_Column 1 /* One record per line in neat columns */
1188#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +00001189#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
1190#define MODE_Html 4 /* Generate an XHTML table */
1191#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +00001192#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +00001193#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +00001194#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +00001195
drh66ce4d02008-02-15 17:38:06 +00001196static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +00001197 "line",
1198 "column",
1199 "list",
1200 "semi",
1201 "html",
drhfeac5f82004-08-01 00:10:45 +00001202 "insert",
1203 "tcl",
drh8e64d1c2004-10-07 00:32:39 +00001204 "csv",
drh66ce4d02008-02-15 17:38:06 +00001205 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +00001206};
drh75897232000-05-29 14:26:00 +00001207
1208/*
1209** Number of elements in an array
1210*/
drh902b9ee2008-12-05 17:17:07 +00001211#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +00001212
1213/*
drhea678832008-12-10 19:26:22 +00001214** Compute a string length that is limited to what can be stored in
1215** lower 30 bits of a 32-bit signed integer.
1216*/
drh4f21c4a2008-12-10 22:15:00 +00001217static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +00001218 const char *z2 = z;
1219 while( *z2 ){ z2++; }
1220 return 0x3fffffff & (int)(z2 - z);
1221}
1222
1223/*
drh28bd4bc2000-06-15 15:57:22 +00001224** Output the given string as a quoted string using SQL quoting conventions.
1225*/
1226static void output_quoted_string(FILE *out, const char *z){
1227 int i;
1228 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +00001229 for(i=0; z[i]; i++){
1230 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +00001231 }
1232 if( nSingle==0 ){
1233 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +00001234 }else{
1235 fprintf(out,"'");
1236 while( *z ){
1237 for(i=0; z[i] && z[i]!='\''; i++){}
1238 if( i==0 ){
1239 fprintf(out,"''");
1240 z++;
1241 }else if( z[i]=='\'' ){
1242 fprintf(out,"%.*s''",i,z);
1243 z += i+1;
1244 }else{
drhcd7d2732002-02-26 23:24:26 +00001245 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +00001246 break;
1247 }
1248 }
drhcd7d2732002-02-26 23:24:26 +00001249 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +00001250 }
1251}
1252
1253/*
drhfeac5f82004-08-01 00:10:45 +00001254** Output the given string as a quoted according to C or TCL quoting rules.
1255*/
1256static void output_c_string(FILE *out, const char *z){
1257 unsigned int c;
1258 fputc('"', out);
1259 while( (c = *(z++))!=0 ){
1260 if( c=='\\' ){
1261 fputc(c, out);
1262 fputc(c, out);
1263 }else if( c=='\t' ){
1264 fputc('\\', out);
1265 fputc('t', out);
1266 }else if( c=='\n' ){
1267 fputc('\\', out);
1268 fputc('n', out);
1269 }else if( c=='\r' ){
1270 fputc('\\', out);
1271 fputc('r', out);
1272 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +00001273 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +00001274 }else{
1275 fputc(c, out);
1276 }
1277 }
1278 fputc('"', out);
1279}
1280
1281/*
drhc08a4f12000-06-15 16:49:48 +00001282** Output the given string with characters that are special to
1283** HTML escaped.
1284*/
1285static void output_html_string(FILE *out, const char *z){
1286 int i;
1287 while( *z ){
1288 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
1289 if( i>0 ){
1290 fprintf(out,"%.*s",i,z);
1291 }
1292 if( z[i]=='<' ){
1293 fprintf(out,"&lt;");
1294 }else if( z[i]=='&' ){
1295 fprintf(out,"&amp;");
1296 }else{
1297 break;
1298 }
1299 z += i + 1;
1300 }
1301}
1302
1303/*
drhc49f44e2006-10-26 18:15:42 +00001304** If a field contains any character identified by a 1 in the following
1305** array, then the string must be quoted for CSV.
1306*/
1307static const char needCsvQuote[] = {
1308 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1309 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1310 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1315 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1316 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1317 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1318 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1319 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1320 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1321 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1322 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1323 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1324};
1325
1326/*
drh8e64d1c2004-10-07 00:32:39 +00001327** Output a single term of CSV. Actually, p->separator is used for
1328** the separator, which may or may not be a comma. p->nullvalue is
1329** the null value. Strings are quoted using ANSI-C rules. Numbers
1330** appear outside of quotes.
1331*/
1332static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +00001333 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +00001334 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +00001335 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +00001336 }else{
drhc49f44e2006-10-26 18:15:42 +00001337 int i;
drh4f21c4a2008-12-10 22:15:00 +00001338 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +00001339 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +00001340 if( needCsvQuote[((unsigned char*)z)[i]]
1341 || (z[i]==p->separator[0] &&
1342 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +00001343 i = 0;
1344 break;
1345 }
1346 }
1347 if( i==0 ){
1348 putc('"', out);
1349 for(i=0; z[i]; i++){
1350 if( z[i]=='"' ) putc('"', out);
1351 putc(z[i], out);
1352 }
1353 putc('"', out);
1354 }else{
1355 fprintf(out, "%s", z);
1356 }
drh8e64d1c2004-10-07 00:32:39 +00001357 }
1358 if( bSep ){
drhd0e77882008-01-14 15:20:08 +00001359 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +00001360 }
1361}
1362
danielk19774af00c62005-01-23 23:43:21 +00001363#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +00001364/*
drh4c504392000-10-16 22:06:40 +00001365** This routine runs when the user presses Ctrl-C
1366*/
1367static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +00001368 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +00001369 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +00001370 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +00001371}
danielk19774af00c62005-01-23 23:43:21 +00001372#endif
drh4c504392000-10-16 22:06:40 +00001373
1374/*
drh75897232000-05-29 14:26:00 +00001375** This is the callback routine that the SQLite library
1376** invokes for each row of a query result.
1377*/
1378static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1379 int i;
1380 struct callback_data *p = (struct callback_data*)pArg;
1381 switch( p->mode ){
1382 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +00001383 int w = 5;
drh6a535342001-10-19 16:44:56 +00001384 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +00001385 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +00001386 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +00001387 if( len>w ) w = len;
1388 }
drh75897232000-05-29 14:26:00 +00001389 if( p->cnt++>0 ) fprintf(p->out,"\n");
1390 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001391 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +00001392 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +00001393 }
1394 break;
1395 }
danielk19770d78bae2008-01-03 07:09:48 +00001396 case MODE_Explain:
drh75897232000-05-29 14:26:00 +00001397 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +00001398 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +00001399 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +00001400 int w, n;
1401 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +00001402 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +00001403 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001404 w = 0;
drh75897232000-05-29 14:26:00 +00001405 }
drha0c66f52000-07-29 13:20:21 +00001406 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001407 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001408 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +00001409 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +00001410 if( w<n ) w = n;
1411 }
1412 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001413 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001414 }
1415 if( p->showHeader ){
1416 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
1417 }
1418 }
1419 if( p->showHeader ){
1420 for(i=0; i<nArg; i++){
1421 int w;
1422 if( i<ArraySize(p->actualWidth) ){
1423 w = p->actualWidth[i];
1424 }else{
1425 w = 10;
1426 }
1427 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
1428 "----------------------------------------------------------",
1429 i==nArg-1 ? "\n": " ");
1430 }
drh75897232000-05-29 14:26:00 +00001431 }
1432 }
drh6a535342001-10-19 16:44:56 +00001433 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001434 for(i=0; i<nArg; i++){
1435 int w;
drha0c66f52000-07-29 13:20:21 +00001436 if( i<ArraySize(p->actualWidth) ){
1437 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001438 }else{
1439 w = 10;
1440 }
drhea678832008-12-10 19:26:22 +00001441 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +00001442 strlen30(azArg[i])>w ){
1443 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001444 }
drhc61053b2000-06-04 12:58:36 +00001445 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +00001446 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +00001447 }
1448 break;
1449 }
drhe3710332000-09-29 13:30:53 +00001450 case MODE_Semi:
drh75897232000-05-29 14:26:00 +00001451 case MODE_List: {
1452 if( p->cnt++==0 && p->showHeader ){
1453 for(i=0; i<nArg; i++){
1454 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
1455 }
1456 }
drh6a535342001-10-19 16:44:56 +00001457 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001458 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001459 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +00001460 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +00001461 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001462 if( i<nArg-1 ){
1463 fprintf(p->out, "%s", p->separator);
1464 }else if( p->mode==MODE_Semi ){
1465 fprintf(p->out, ";\n");
1466 }else{
1467 fprintf(p->out, "\n");
1468 }
drh75897232000-05-29 14:26:00 +00001469 }
1470 break;
1471 }
drh1e5d0e92000-05-31 23:33:17 +00001472 case MODE_Html: {
1473 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +00001474 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001475 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +00001476 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
drh1e5d0e92000-05-31 23:33:17 +00001477 }
mihailim57c591a2008-06-23 21:26:05 +00001478 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001479 }
drh6a535342001-10-19 16:44:56 +00001480 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +00001481 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001482 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +00001483 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +00001484 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +00001485 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001486 }
mihailim57c591a2008-06-23 21:26:05 +00001487 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001488 break;
1489 }
drhfeac5f82004-08-01 00:10:45 +00001490 case MODE_Tcl: {
1491 if( p->cnt++==0 && p->showHeader ){
1492 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001493 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +00001494 fprintf(p->out, "%s", p->separator);
1495 }
1496 fprintf(p->out,"\n");
1497 }
1498 if( azArg==0 ) break;
1499 for(i=0; i<nArg; i++){
1500 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
1501 fprintf(p->out, "%s", p->separator);
1502 }
1503 fprintf(p->out,"\n");
1504 break;
1505 }
drh8e64d1c2004-10-07 00:32:39 +00001506 case MODE_Csv: {
1507 if( p->cnt++==0 && p->showHeader ){
1508 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001509 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001510 }
1511 fprintf(p->out,"\n");
1512 }
1513 if( azArg==0 ) break;
1514 for(i=0; i<nArg; i++){
1515 output_csv(p, azArg[i], i<nArg-1);
1516 }
1517 fprintf(p->out,"\n");
1518 break;
1519 }
drh28bd4bc2000-06-15 15:57:22 +00001520 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +00001521 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +00001522 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +00001523 for(i=0; i<nArg; i++){
1524 char *zSep = i>0 ? ",": "";
1525 if( azArg[i]==0 ){
1526 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +00001527 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001528 fprintf(p->out,"%s%s",zSep, azArg[i]);
1529 }else{
1530 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1531 output_quoted_string(p->out, azArg[i]);
1532 }
1533 }
1534 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001535 break;
drh28bd4bc2000-06-15 15:57:22 +00001536 }
persicom1d0b8722002-04-18 02:53:04 +00001537 }
drh75897232000-05-29 14:26:00 +00001538 return 0;
1539}
1540
1541/*
drh33048c02001-10-01 14:29:22 +00001542** Set the destination table field of the callback_data structure to
1543** the name of the table given. Escape any quote characters in the
1544** table name.
1545*/
1546static void set_table_name(struct callback_data *p, const char *zName){
1547 int i, n;
1548 int needQuote;
1549 char *z;
1550
1551 if( p->zDestTable ){
1552 free(p->zDestTable);
1553 p->zDestTable = 0;
1554 }
1555 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001556 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001557 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001558 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001559 needQuote = 1;
1560 if( zName[i]=='\'' ) n++;
1561 }
1562 }
1563 if( needQuote ) n += 2;
1564 z = p->zDestTable = malloc( n+1 );
1565 if( z==0 ){
1566 fprintf(stderr,"Out of memory!\n");
1567 exit(1);
1568 }
1569 n = 0;
1570 if( needQuote ) z[n++] = '\'';
1571 for(i=0; zName[i]; i++){
1572 z[n++] = zName[i];
1573 if( zName[i]=='\'' ) z[n++] = '\'';
1574 }
1575 if( needQuote ) z[n++] = '\'';
1576 z[n] = 0;
1577}
1578
danielk19772a02e332004-06-05 08:04:36 +00001579/* zIn is either a pointer to a NULL-terminated string in memory obtained
1580** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1581** added to zIn, and the result returned in memory obtained from malloc().
1582** zIn, if it was not NULL, is freed.
1583**
1584** If the third argument, quote, is not '\0', then it is used as a
1585** quote character for zAppend.
1586*/
drhc28490c2006-10-26 14:25:58 +00001587static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001588 int len;
1589 int i;
drh4f21c4a2008-12-10 22:15:00 +00001590 int nAppend = strlen30(zAppend);
1591 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001592
1593 len = nAppend+nIn+1;
1594 if( quote ){
1595 len += 2;
1596 for(i=0; i<nAppend; i++){
1597 if( zAppend[i]==quote ) len++;
1598 }
1599 }
1600
1601 zIn = (char *)realloc(zIn, len);
1602 if( !zIn ){
1603 return 0;
1604 }
1605
1606 if( quote ){
1607 char *zCsr = &zIn[nIn];
1608 *zCsr++ = quote;
1609 for(i=0; i<nAppend; i++){
1610 *zCsr++ = zAppend[i];
1611 if( zAppend[i]==quote ) *zCsr++ = quote;
1612 }
1613 *zCsr++ = quote;
1614 *zCsr++ = '\0';
1615 assert( (zCsr-zIn)==len );
1616 }else{
1617 memcpy(&zIn[nIn], zAppend, nAppend);
1618 zIn[len-1] = '\0';
1619 }
1620
1621 return zIn;
1622}
1623
drhdd3d4592004-08-30 01:54:05 +00001624
1625/*
1626** Execute a query statement that has a single result column. Print
1627** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +00001628**
1629** This is used, for example, to show the schema of the database by
1630** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +00001631*/
1632static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
1633 sqlite3_stmt *pSelect;
1634 int rc;
1635 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
1636 if( rc!=SQLITE_OK || !pSelect ){
1637 return rc;
1638 }
1639 rc = sqlite3_step(pSelect);
1640 while( rc==SQLITE_ROW ){
1641 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
1642 rc = sqlite3_step(pSelect);
1643 }
1644 return sqlite3_finalize(pSelect);
1645}
1646
1647
drh33048c02001-10-01 14:29:22 +00001648/*
drh4c653a02000-06-07 01:27:47 +00001649** This is a different callback routine used for dumping the database.
1650** Each row received by this callback consists of a table name,
1651** the table type ("index" or "table") and SQL to create the table.
1652** This routine should print text sufficient to recreate the table.
1653*/
1654static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001655 int rc;
1656 const char *zTable;
1657 const char *zType;
1658 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +00001659 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001660
drh902b9ee2008-12-05 17:17:07 +00001661 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001662 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001663 zTable = azArg[0];
1664 zType = azArg[1];
1665 zSql = azArg[2];
1666
drh00b950d2005-09-11 02:03:03 +00001667 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +00001668 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +00001669 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1670 fprintf(p->out, "ANALYZE sqlite_master;\n");
1671 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1672 return 0;
drh45e29d82006-11-20 16:21:10 +00001673 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1674 char *zIns;
1675 if( !p->writableSchema ){
1676 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1677 p->writableSchema = 1;
1678 }
1679 zIns = sqlite3_mprintf(
1680 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1681 "VALUES('table','%q','%q',0,'%q');",
1682 zTable, zTable, zSql);
1683 fprintf(p->out, "%s\n", zIns);
1684 sqlite3_free(zIns);
1685 return 0;
drh00b950d2005-09-11 02:03:03 +00001686 }else{
1687 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001688 }
danielk19772a02e332004-06-05 08:04:36 +00001689
1690 if( strcmp(zType, "table")==0 ){
1691 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001692 char *zSelect = 0;
1693 char *zTableInfo = 0;
1694 char *zTmp = 0;
1695
1696 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1697 zTableInfo = appendText(zTableInfo, zTable, '"');
1698 zTableInfo = appendText(zTableInfo, ");", 0);
1699
1700 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
1701 if( zTableInfo ) free(zTableInfo);
1702 if( rc!=SQLITE_OK || !pTableInfo ){
1703 return 1;
1704 }
1705
1706 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1707 zTmp = appendText(zTmp, zTable, '"');
1708 if( zTmp ){
1709 zSelect = appendText(zSelect, zTmp, '\'');
1710 }
1711 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1712 rc = sqlite3_step(pTableInfo);
1713 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001714 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001715 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001716 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001717 rc = sqlite3_step(pTableInfo);
1718 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001719 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001720 }else{
1721 zSelect = appendText(zSelect, ") ", 0);
1722 }
1723 }
1724 rc = sqlite3_finalize(pTableInfo);
1725 if( rc!=SQLITE_OK ){
1726 if( zSelect ) free(zSelect);
1727 return 1;
1728 }
1729 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1730 zSelect = appendText(zSelect, zTable, '"');
1731
drhdd3d4592004-08-30 01:54:05 +00001732 rc = run_table_dump_query(p->out, p->db, zSelect);
1733 if( rc==SQLITE_CORRUPT ){
1734 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
1735 rc = run_table_dump_query(p->out, p->db, zSelect);
1736 }
danielk19772a02e332004-06-05 08:04:36 +00001737 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001738 }
drh4c653a02000-06-07 01:27:47 +00001739 return 0;
1740}
1741
1742/*
drh45e29d82006-11-20 16:21:10 +00001743** Run zQuery. Use dump_callback() as the callback routine so that
1744** the contents of the query are output as SQL statements.
1745**
drhdd3d4592004-08-30 01:54:05 +00001746** If we get a SQLITE_CORRUPT error, rerun the query after appending
1747** "ORDER BY rowid DESC" to the end.
1748*/
1749static int run_schema_dump_query(
1750 struct callback_data *p,
1751 const char *zQuery,
1752 char **pzErrMsg
1753){
1754 int rc;
1755 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1756 if( rc==SQLITE_CORRUPT ){
1757 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001758 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001759 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1760 zQ2 = malloc( len+100 );
1761 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001762 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001763 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1764 free(zQ2);
1765 }
1766 return rc;
1767}
1768
danielk1977c8c70692009-02-25 15:22:02 +00001769
1770#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
1771struct GenfkeyCmd {
1772 sqlite3 *db; /* Database handle */
1773 struct callback_data *pCb; /* Callback data */
1774 int isIgnoreErrors; /* True for --ignore-errors */
1775 int isExec; /* True for --exec */
1776 int isNoDrop; /* True for --no-drop */
1777 int nErr; /* Number of errors seen so far */
1778};
1779typedef struct GenfkeyCmd GenfkeyCmd;
1780
1781static int genfkeyParseArgs(GenfkeyCmd *p, char **azArg, int nArg){
1782 int ii;
1783 memset(p, 0, sizeof(GenfkeyCmd));
1784
1785 for(ii=0; ii<nArg; ii++){
1786 int n = strlen(azArg[ii]);
1787
1788 if( n>2 && n<10 && 0==strncmp(azArg[ii], "--no-drop", n) ){
1789 p->isNoDrop = 1;
1790 }else if( n>2 && n<16 && 0==strncmp(azArg[ii], "--ignore-errors", n) ){
1791 p->isIgnoreErrors = 1;
1792 }else if( n>2 && n<7 && 0==strncmp(azArg[ii], "--exec", n) ){
1793 p->isExec = 1;
1794 }else{
1795 fprintf(stderr, "unknown option: %s\n", azArg[ii]);
1796 return -1;
1797 }
1798 }
1799
1800 return SQLITE_OK;
1801}
1802
1803static int genfkeyCmdCb(void *pCtx, int eType, const char *z){
1804 GenfkeyCmd *p = (GenfkeyCmd *)pCtx;
1805 if( eType==GENFKEY_ERROR && !p->isIgnoreErrors ){
1806 p->nErr++;
1807 fprintf(stderr, "%s\n", z);
1808 }
1809
1810 if( p->nErr==0 && (
1811 (eType==GENFKEY_CREATETRIGGER)
1812 || (eType==GENFKEY_DROPTRIGGER && !p->isNoDrop)
1813 )){
1814 if( p->isExec ){
1815 sqlite3_exec(p->db, z, 0, 0, 0);
1816 }else{
1817 char *zCol = "sql";
1818 callback((void *)p->pCb, 1, (char **)&z, (char **)&zCol);
1819 }
1820 }
1821
1822 return SQLITE_OK;
1823}
1824#endif
1825
drhdd3d4592004-08-30 01:54:05 +00001826/*
drh75897232000-05-29 14:26:00 +00001827** Text of a help message
1828*/
persicom1d0b8722002-04-18 02:53:04 +00001829static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001830 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001831 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001832 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001833 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +00001834 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001835 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001836 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
danielk1977c8c70692009-02-25 15:22:02 +00001837#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
1838 ".genfkey ?OPTIONS? Options are:\n"
1839 " --no-drop: Do not drop old fkey triggers.\n"
1840 " --ignore-errors: Ignore tables with fkey errors\n"
1841 " --exec: Execute generated SQL immediately\n"
danielk1977e6320042009-02-25 15:43:57 +00001842 " See file tool/genfkey.README in the source \n"
1843 " distribution for further information.\n"
danielk1977c8c70692009-02-25 15:22:02 +00001844#endif
persicom7e2dfdd2002-04-18 02:46:52 +00001845 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001846 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001847 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +00001848 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +00001849#ifdef SQLITE_ENABLE_IOTRACE
1850 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1851#endif
drh70df4fe2006-06-13 15:12:21 +00001852#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001853 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001854#endif
danielk19776b77a362005-01-13 11:10:25 +00001855 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001856 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001857 " column Left-aligned columns. (See .width)\n"
1858 " html HTML <table> code\n"
1859 " insert SQL insert statements for TABLE\n"
1860 " line One value per line\n"
1861 " list Values delimited by .separator string\n"
1862 " tabs Tab-separated values\n"
1863 " tcl TCL list elements\n"
1864 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001865 ".output FILENAME Send output to FILENAME\n"
1866 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001867 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001868 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001869 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001870 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001871 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +00001872 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001873 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +00001874 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +00001875 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +00001876#if HAS_TIMER
1877 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1878#endif
drh75897232000-05-29 14:26:00 +00001879 ".width NUM NUM ... Set column widths for \"column\" mode\n"
1880;
1881
drhdaffd0e2001-04-11 14:28:42 +00001882/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001883static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001884
drh75897232000-05-29 14:26:00 +00001885/*
drh44c2eb12003-04-30 11:38:26 +00001886** Make sure the database is open. If it is not, then open it. If
1887** the database fails to open, print an error message and exit.
1888*/
1889static void open_db(struct callback_data *p){
1890 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001891 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001892 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001893 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1894 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1895 shellstaticFunc, 0, 0);
1896 }
1897 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +00001898 fprintf(stderr,"Unable to open database \"%s\": %s\n",
1899 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001900 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001901 }
drhc2e87a32006-06-27 15:16:14 +00001902#ifndef SQLITE_OMIT_LOAD_EXTENSION
1903 sqlite3_enable_load_extension(p->db, 1);
1904#endif
drh44c2eb12003-04-30 11:38:26 +00001905 }
1906}
1907
1908/*
drhfeac5f82004-08-01 00:10:45 +00001909** Do C-language style dequoting.
1910**
1911** \t -> tab
1912** \n -> newline
1913** \r -> carriage return
1914** \NNN -> ascii character NNN in octal
1915** \\ -> backslash
1916*/
1917static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001918 int i, j;
1919 char c;
drhfeac5f82004-08-01 00:10:45 +00001920 for(i=j=0; (c = z[i])!=0; i++, j++){
1921 if( c=='\\' ){
1922 c = z[++i];
1923 if( c=='n' ){
1924 c = '\n';
1925 }else if( c=='t' ){
1926 c = '\t';
1927 }else if( c=='r' ){
1928 c = '\r';
1929 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001930 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001931 if( z[i+1]>='0' && z[i+1]<='7' ){
1932 i++;
1933 c = (c<<3) + z[i] - '0';
1934 if( z[i+1]>='0' && z[i+1]<='7' ){
1935 i++;
1936 c = (c<<3) + z[i] - '0';
1937 }
1938 }
1939 }
1940 }
1941 z[j] = c;
1942 }
1943 z[j] = 0;
1944}
1945
1946/*
drhc28490c2006-10-26 14:25:58 +00001947** Interpret zArg as a boolean value. Return either 0 or 1.
1948*/
1949static int booleanValue(char *zArg){
1950 int val = atoi(zArg);
1951 int j;
1952 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001953 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001954 }
1955 if( strcmp(zArg,"on")==0 ){
1956 val = 1;
1957 }else if( strcmp(zArg,"yes")==0 ){
1958 val = 1;
1959 }
1960 return val;
1961}
1962
1963/*
drh75897232000-05-29 14:26:00 +00001964** If an input line begins with "." then invoke this routine to
1965** process that line.
drh67505e72002-04-19 12:34:06 +00001966**
drh47ad6842006-11-08 12:25:42 +00001967** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001968*/
drh44c2eb12003-04-30 11:38:26 +00001969static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001970 int i = 1;
1971 int nArg = 0;
1972 int n, c;
drh67505e72002-04-19 12:34:06 +00001973 int rc = 0;
drh75897232000-05-29 14:26:00 +00001974 char *azArg[50];
1975
1976 /* Parse the input line into tokens.
1977 */
1978 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001979 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001980 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001981 if( zLine[i]=='\'' || zLine[i]=='"' ){
1982 int delim = zLine[i++];
1983 azArg[nArg++] = &zLine[i];
1984 while( zLine[i] && zLine[i]!=delim ){ i++; }
1985 if( zLine[i]==delim ){
1986 zLine[i++] = 0;
1987 }
drhfeac5f82004-08-01 00:10:45 +00001988 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001989 }else{
1990 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001991 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001992 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001993 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001994 }
1995 }
1996
1997 /* Process the input line.
1998 */
drh67505e72002-04-19 12:34:06 +00001999 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00002000 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002001 c = azArg[0][0];
drh9ff849f2009-02-04 20:55:57 +00002002 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){
2003 const char *zDestFile;
2004 const char *zDb;
2005 sqlite3 *pDest;
2006 sqlite3_backup *pBackup;
2007 int rc;
2008 if( nArg==2 ){
2009 zDestFile = azArg[1];
2010 zDb = "main";
2011 }else{
2012 zDestFile = azArg[2];
2013 zDb = azArg[1];
2014 }
2015 rc = sqlite3_open(zDestFile, &pDest);
2016 if( rc!=SQLITE_OK ){
2017 fprintf(stderr, "Error: cannot open %s\n", zDestFile);
2018 sqlite3_close(pDest);
2019 return 1;
2020 }
drhdc2c4912009-02-04 22:46:47 +00002021 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002022 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2023 if( pBackup==0 ){
2024 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2025 sqlite3_close(pDest);
2026 return 1;
2027 }
2028 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2029 sqlite3_backup_finish(pBackup);
2030 if( rc==SQLITE_DONE ){
2031 rc = SQLITE_OK;
2032 }else{
2033 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2034 }
2035 sqlite3_close(pDest);
2036 }else
2037
2038 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
drhc49f44e2006-10-26 18:15:42 +00002039 bail_on_error = booleanValue(azArg[1]);
2040 }else
2041
jplyon6a65bb32003-05-04 07:25:57 +00002042 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00002043 struct callback_data data;
2044 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00002045 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00002046 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002047 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002048 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002049 data.colWidth[0] = 3;
2050 data.colWidth[1] = 15;
2051 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002052 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002053 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002054 if( zErrMsg ){
2055 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002056 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00002057 }
2058 }else
2059
drh4c653a02000-06-07 01:27:47 +00002060 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
2061 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002062 open_db(p);
drh33048c02001-10-01 14:29:22 +00002063 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002064 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00002065 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002066 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002067 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002068 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002069 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00002070 );
2071 run_table_dump_query(p->out, p->db,
2072 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002073 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00002074 );
drh4c653a02000-06-07 01:27:47 +00002075 }else{
2076 int i;
drhdd3d4592004-08-30 01:54:05 +00002077 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002078 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002079 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002080 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002081 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00002082 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00002083 run_table_dump_query(p->out, p->db,
2084 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002085 "WHERE sql NOT NULL"
2086 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00002087 " AND tbl_name LIKE shellstatic()"
2088 );
danielk1977bc6ada42004-06-30 08:20:16 +00002089 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002090 }
2091 }
drh45e29d82006-11-20 16:21:10 +00002092 if( p->writableSchema ){
2093 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
2094 p->writableSchema = 0;
2095 }
drh93f41e52008-08-11 19:12:34 +00002096 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002097 if( zErrMsg ){
2098 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002099 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00002100 }else{
2101 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002102 }
2103 }else
drh75897232000-05-29 14:26:00 +00002104
drhdaffd0e2001-04-11 14:28:42 +00002105 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002106 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00002107 }else
2108
drh75897232000-05-29 14:26:00 +00002109 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002110 rc = 2;
drh75897232000-05-29 14:26:00 +00002111 }else
2112
drhdd45df82002-04-18 12:39:03 +00002113 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002114 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002115 if(val == 1) {
2116 if(!p->explainPrev.valid) {
2117 p->explainPrev.valid = 1;
2118 p->explainPrev.mode = p->mode;
2119 p->explainPrev.showHeader = p->showHeader;
2120 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
2121 }
2122 /* We could put this code under the !p->explainValid
2123 ** condition so that it does not execute if we are already in
2124 ** explain mode. However, always executing it allows us an easy
2125 ** was to reset to explain mode in case the user previously
2126 ** did an .explain followed by a .width, .mode or .header
2127 ** command.
2128 */
danielk19770d78bae2008-01-03 07:09:48 +00002129 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002130 p->showHeader = 1;
2131 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002132 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002133 p->colWidth[1] = 13; /* opcode */
2134 p->colWidth[2] = 4; /* P1 */
2135 p->colWidth[3] = 4; /* P2 */
2136 p->colWidth[4] = 4; /* P3 */
2137 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002138 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002139 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00002140 }else if (p->explainPrev.valid) {
2141 p->explainPrev.valid = 0;
2142 p->mode = p->explainPrev.mode;
2143 p->showHeader = p->explainPrev.showHeader;
2144 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2145 }
drh75897232000-05-29 14:26:00 +00002146 }else
2147
danielk1977c8c70692009-02-25 15:22:02 +00002148#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
2149 if( c=='g' && strncmp(azArg[0], "genfkey", n)==0 ){
2150 GenfkeyCmd cmd;
2151 if( 0==genfkeyParseArgs(&cmd, &azArg[1], nArg-1) ){
2152 cmd.db = p->db;
2153 cmd.pCb = p;
2154 genfkey_create_triggers(p->db, "main", (void *)&cmd, genfkeyCmdCb);
2155 }
2156 }else
2157#endif
2158
drhc28490c2006-10-26 14:25:58 +00002159 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00002160 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002161 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00002162 }else
2163
2164 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00002165 fprintf(stderr,"%s",zHelp);
drh75897232000-05-29 14:26:00 +00002166 }else
2167
drhfeac5f82004-08-01 00:10:45 +00002168 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
2169 char *zTable = azArg[2]; /* Insert data into this table */
2170 char *zFile = azArg[1]; /* The file from which to extract data */
2171 sqlite3_stmt *pStmt; /* A statement */
2172 int rc; /* Result code */
2173 int nCol; /* Number of columns in the table */
2174 int nByte; /* Number of bytes in an SQL string */
2175 int i, j; /* Loop counters */
2176 int nSep; /* Number of bytes in p->separator[] */
2177 char *zSql; /* An SQL statement */
2178 char *zLine; /* A single line of input from the file */
2179 char **azCol; /* zLine[] broken up into columns */
2180 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00002181 FILE *in; /* The input file */
2182 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00002183
drha543c822006-06-08 16:10:14 +00002184 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002185 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002186 if( nSep==0 ){
2187 fprintf(stderr, "non-null separator required for import\n");
2188 return 0;
2189 }
2190 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
2191 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00002192 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002193 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002194 sqlite3_free(zSql);
2195 if( rc ){
2196 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2197 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00002198 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002199 }else{
2200 nCol = sqlite3_column_count(pStmt);
2201 }
2202 sqlite3_finalize(pStmt);
2203 if( nCol==0 ) return 0;
2204 zSql = malloc( nByte + 20 + nCol*2 );
2205 if( zSql==0 ) return 0;
2206 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002207 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002208 for(i=1; i<nCol; i++){
2209 zSql[j++] = ',';
2210 zSql[j++] = '?';
2211 }
2212 zSql[j++] = ')';
2213 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002214 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002215 free(zSql);
2216 if( rc ){
2217 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
2218 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00002219 return 1;
drhfeac5f82004-08-01 00:10:45 +00002220 }
2221 in = fopen(zFile, "rb");
2222 if( in==0 ){
2223 fprintf(stderr, "cannot open file: %s\n", zFile);
2224 sqlite3_finalize(pStmt);
2225 return 0;
2226 }
2227 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00002228 if( azCol==0 ){
2229 fclose(in);
2230 return 0;
2231 }
drhfeac5f82004-08-01 00:10:45 +00002232 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
2233 zCommit = "COMMIT";
2234 while( (zLine = local_getline(0, in))!=0 ){
2235 char *z;
2236 i = 0;
drhb860bc92004-08-04 15:16:55 +00002237 lineno++;
drhfeac5f82004-08-01 00:10:45 +00002238 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00002239 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00002240 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
2241 *z = 0;
2242 i++;
drhb860bc92004-08-04 15:16:55 +00002243 if( i<nCol ){
2244 azCol[i] = &z[nSep];
2245 z += nSep-1;
2246 }
drhfeac5f82004-08-01 00:10:45 +00002247 }
2248 }
drh1cd7f832005-08-05 18:50:51 +00002249 *z = 0;
drhb860bc92004-08-04 15:16:55 +00002250 if( i+1!=nCol ){
2251 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
2252 zFile, lineno, nCol, i+1);
2253 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00002254 free(zLine);
drhb860bc92004-08-04 15:16:55 +00002255 break;
2256 }
drhfeac5f82004-08-01 00:10:45 +00002257 for(i=0; i<nCol; i++){
2258 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2259 }
2260 sqlite3_step(pStmt);
2261 rc = sqlite3_reset(pStmt);
2262 free(zLine);
2263 if( rc!=SQLITE_OK ){
2264 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2265 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00002266 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002267 break;
2268 }
2269 }
2270 free(azCol);
2271 fclose(in);
2272 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00002273 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002274 }else
2275
drh75897232000-05-29 14:26:00 +00002276 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
2277 struct callback_data data;
2278 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002279 open_db(p);
drh75897232000-05-29 14:26:00 +00002280 memcpy(&data, p, sizeof(data));
2281 data.showHeader = 0;
2282 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00002283 zShellStatic = azArg[1];
2284 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00002285 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002286 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002287 "UNION ALL "
2288 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002289 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002290 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002291 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002292 );
danielk1977bc6ada42004-06-30 08:20:16 +00002293 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00002294 if( zErrMsg ){
2295 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002296 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002297 }
2298 }else
2299
drhae5e4452007-05-03 17:18:36 +00002300#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002301 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002302 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002303 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2304 iotrace = 0;
2305 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002306 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002307 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002308 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002309 iotrace = stdout;
2310 }else{
2311 iotrace = fopen(azArg[1], "w");
2312 if( iotrace==0 ){
2313 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002314 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002315 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002316 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002317 }
2318 }
2319 }else
drhae5e4452007-05-03 17:18:36 +00002320#endif
drhb0603412007-02-28 04:47:26 +00002321
drh70df4fe2006-06-13 15:12:21 +00002322#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002323 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2324 const char *zFile, *zProc;
2325 char *zErrMsg = 0;
2326 int rc;
2327 zFile = azArg[1];
2328 zProc = nArg>=3 ? azArg[2] : 0;
2329 open_db(p);
2330 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2331 if( rc!=SQLITE_OK ){
2332 fprintf(stderr, "%s\n", zErrMsg);
2333 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002334 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002335 }
2336 }else
drh70df4fe2006-06-13 15:12:21 +00002337#endif
drh1e397f82006-06-08 15:28:43 +00002338
drh28bd4bc2000-06-15 15:57:22 +00002339 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00002340 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002341 if( strncmp(azArg[1],"line",n2)==0
2342 ||
2343 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002344 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00002345 }else if( strncmp(azArg[1],"column",n2)==0
2346 ||
2347 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002348 p->mode = MODE_Column;
2349 }else if( strncmp(azArg[1],"list",n2)==0 ){
2350 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00002351 }else if( strncmp(azArg[1],"html",n2)==0 ){
2352 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00002353 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
2354 p->mode = MODE_Tcl;
2355 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002356 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002357 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00002358 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
2359 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002360 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00002361 }else if( strncmp(azArg[1],"insert",n2)==0 ){
2362 p->mode = MODE_Insert;
2363 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00002364 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00002365 }else{
drh33048c02001-10-01 14:29:22 +00002366 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00002367 }
drhdaffd0e2001-04-11 14:28:42 +00002368 }else {
drhcf68ae92006-12-19 18:47:41 +00002369 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002370 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00002371 }
2372 }else
2373
persicom7e2dfdd2002-04-18 02:46:52 +00002374 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002375 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2376 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002377 }else
2378
drh75897232000-05-29 14:26:00 +00002379 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
2380 if( p->out!=stdout ){
2381 fclose(p->out);
2382 }
2383 if( strcmp(azArg[1],"stdout")==0 ){
2384 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00002385 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00002386 }else{
drha1f9b5e2004-02-14 16:31:02 +00002387 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00002388 if( p->out==0 ){
2389 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
2390 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00002391 } else {
drh5bb3eb92007-05-04 13:15:55 +00002392 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002393 }
2394 }
2395 }else
2396
drhdd45df82002-04-18 12:39:03 +00002397 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002398 if( nArg >= 2) {
2399 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2400 }
2401 if( nArg >= 3) {
2402 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2403 }
2404 }else
2405
2406 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002407 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002408 }else
2409
drh9ff849f2009-02-04 20:55:57 +00002410 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002411 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002412 if( alt==0 ){
2413 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
2414 }else{
2415 process_input(p, alt);
2416 fclose(alt);
2417 }
2418 }else
2419
drh9ff849f2009-02-04 20:55:57 +00002420 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){
2421 const char *zSrcFile;
2422 const char *zDb;
2423 sqlite3 *pSrc;
2424 sqlite3_backup *pBackup;
2425 int rc;
drhdc2c4912009-02-04 22:46:47 +00002426 int nTimeout = 0;
2427
drh9ff849f2009-02-04 20:55:57 +00002428 if( nArg==2 ){
2429 zSrcFile = azArg[1];
2430 zDb = "main";
2431 }else{
2432 zSrcFile = azArg[2];
2433 zDb = azArg[1];
2434 }
2435 rc = sqlite3_open(zSrcFile, &pSrc);
2436 if( rc!=SQLITE_OK ){
2437 fprintf(stderr, "Error: cannot open %s\n", zSrcFile);
2438 sqlite3_close(pSrc);
2439 return 1;
2440 }
drhdc2c4912009-02-04 22:46:47 +00002441 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002442 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2443 if( pBackup==0 ){
2444 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2445 sqlite3_close(pSrc);
2446 return 1;
2447 }
drhdc2c4912009-02-04 22:46:47 +00002448 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2449 || rc==SQLITE_BUSY ){
2450 if( rc==SQLITE_BUSY ){
2451 if( nTimeout++ >= 3 ) break;
2452 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002453 }
2454 }
2455 sqlite3_backup_finish(pBackup);
2456 if( rc==SQLITE_DONE ){
2457 rc = SQLITE_OK;
drhdc2c4912009-02-04 22:46:47 +00002458 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2459 fprintf(stderr, "source database is busy\n");
drh9ff849f2009-02-04 20:55:57 +00002460 }else{
2461 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2462 }
2463 sqlite3_close(pSrc);
2464 }else
2465
drh75897232000-05-29 14:26:00 +00002466 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
2467 struct callback_data data;
2468 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002469 open_db(p);
drh75897232000-05-29 14:26:00 +00002470 memcpy(&data, p, sizeof(data));
2471 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002472 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002473 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002474 int i;
shane7d3846a2008-12-11 02:58:26 +00002475 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002476 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002477 char *new_argv[2], *new_colv[2];
2478 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2479 " type text,\n"
2480 " name text,\n"
2481 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002482 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002483 " sql text\n"
2484 ")";
2485 new_argv[1] = 0;
2486 new_colv[0] = "sql";
2487 new_colv[1] = 0;
2488 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00002489 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002490 char *new_argv[2], *new_colv[2];
2491 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2492 " type text,\n"
2493 " name text,\n"
2494 " tbl_name text,\n"
2495 " rootpage integer,\n"
2496 " sql text\n"
2497 ")";
2498 new_argv[1] = 0;
2499 new_colv[0] = "sql";
2500 new_colv[1] = 0;
2501 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00002502 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002503 zShellStatic = azArg[1];
2504 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002505 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002506 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2507 " FROM sqlite_master UNION ALL"
2508 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002509 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002510 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002511 callback, &data, &zErrMsg);
2512 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002513 }
drh75897232000-05-29 14:26:00 +00002514 }else{
danielk19776f8a5032004-05-10 10:34:51 +00002515 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002516 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002517 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2518 " FROM sqlite_master UNION ALL"
2519 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002520 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002521 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002522 callback, &data, &zErrMsg
2523 );
drh75897232000-05-29 14:26:00 +00002524 }
drh75897232000-05-29 14:26:00 +00002525 if( zErrMsg ){
2526 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002527 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002528 }
2529 }else
2530
2531 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002532 sqlite3_snprintf(sizeof(p->separator), p->separator,
2533 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002534 }else
2535
persicom7e2dfdd2002-04-18 02:46:52 +00002536 if( c=='s' && strncmp(azArg[0], "show", n)==0){
2537 int i;
2538 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002539 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002540 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002541 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002542 fprintf(p->out,"%9.9s: ", "nullvalue");
2543 output_c_string(p->out, p->nullvalue);
2544 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002545 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002546 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002547 fprintf(p->out,"%9.9s: ", "separator");
2548 output_c_string(p->out, p->separator);
2549 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002550 fprintf(p->out,"%9.9s: ","width");
2551 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002552 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002553 }
drhfeac5f82004-08-01 00:10:45 +00002554 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002555 }else
2556
drh2dfbbca2000-07-28 14:32:48 +00002557 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00002558 char **azResult;
2559 int nRow, rc;
2560 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002561 open_db(p);
drha50da102000-08-08 20:19:09 +00002562 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002563 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002564 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00002565 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002566 "UNION ALL "
2567 "SELECT name FROM sqlite_temp_master "
2568 "WHERE type IN ('table','view') "
2569 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002570 &azResult, &nRow, 0, &zErrMsg
2571 );
drha50da102000-08-08 20:19:09 +00002572 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002573 zShellStatic = azArg[1];
2574 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002575 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002576 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002577 "UNION ALL "
2578 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002579 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002580 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002581 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002582 );
danielk1977bc6ada42004-06-30 08:20:16 +00002583 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002584 }
drh75897232000-05-29 14:26:00 +00002585 if( zErrMsg ){
2586 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002587 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002588 }
drhe3710332000-09-29 13:30:53 +00002589 if( rc==SQLITE_OK ){
2590 int len, maxlen = 0;
2591 int i, j;
2592 int nPrintCol, nPrintRow;
2593 for(i=1; i<=nRow; i++){
2594 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002595 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002596 if( len>maxlen ) maxlen = len;
2597 }
2598 nPrintCol = 80/(maxlen+2);
2599 if( nPrintCol<1 ) nPrintCol = 1;
2600 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2601 for(i=0; i<nPrintRow; i++){
2602 for(j=i+1; j<=nRow; j+=nPrintRow){
2603 char *zSp = j<=nPrintRow ? "" : " ";
2604 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2605 }
2606 printf("\n");
2607 }
drh47ad6842006-11-08 12:25:42 +00002608 }else{
2609 rc = 1;
drhe3710332000-09-29 13:30:53 +00002610 }
danielk19776f8a5032004-05-10 10:34:51 +00002611 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002612 }else
2613
drh3b1a9882007-11-02 12:53:03 +00002614 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00002615 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002616 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00002617 }else
drh3b1a9882007-11-02 12:53:03 +00002618
2619#if HAS_TIMER
2620 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
2621 enableTimer = booleanValue(azArg[1]);
2622 }else
2623#endif
drh2dfbbca2000-07-28 14:32:48 +00002624
drh75897232000-05-29 14:26:00 +00002625 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
2626 int j;
drh43617e92006-03-06 20:55:46 +00002627 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002628 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2629 p->colWidth[j-1] = atoi(azArg[j]);
2630 }
2631 }else
2632
drh3b1a9882007-11-02 12:53:03 +00002633
drh75897232000-05-29 14:26:00 +00002634 {
drh67505e72002-04-19 12:34:06 +00002635 fprintf(stderr, "unknown command or invalid arguments: "
2636 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00002637 }
drh67505e72002-04-19 12:34:06 +00002638
2639 return rc;
drh75897232000-05-29 14:26:00 +00002640}
2641
drh67505e72002-04-19 12:34:06 +00002642/*
drh91a66392007-09-07 01:12:32 +00002643** Return TRUE if a semicolon occurs anywhere in the first N characters
2644** of string z[].
drh324ccef2003-02-05 14:06:20 +00002645*/
drh91a66392007-09-07 01:12:32 +00002646static int _contains_semicolon(const char *z, int N){
2647 int i;
2648 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2649 return 0;
drh324ccef2003-02-05 14:06:20 +00002650}
2651
2652/*
drh70c7a4b2003-04-26 03:03:06 +00002653** Test to see if a line consists entirely of whitespace.
2654*/
2655static int _all_whitespace(const char *z){
2656 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002657 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002658 if( *z=='/' && z[1]=='*' ){
2659 z += 2;
2660 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2661 if( *z==0 ) return 0;
2662 z++;
2663 continue;
2664 }
2665 if( *z=='-' && z[1]=='-' ){
2666 z += 2;
2667 while( *z && *z!='\n' ){ z++; }
2668 if( *z==0 ) return 1;
2669 continue;
2670 }
2671 return 0;
2672 }
2673 return 1;
2674}
2675
2676/*
drha9b17162003-04-29 18:01:28 +00002677** Return TRUE if the line typed in is an SQL command terminator other
2678** than a semi-colon. The SQL Server style "go" command is understood
2679** as is the Oracle "/".
2680*/
2681static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002682 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002683 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2684 return 1; /* Oracle */
2685 }
drhc8d74412004-08-31 23:41:26 +00002686 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2687 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002688 return 1; /* SQL Server */
2689 }
2690 return 0;
2691}
2692
2693/*
drh233a5312008-12-18 22:25:13 +00002694** Return true if zSql is a complete SQL statement. Return false if it
2695** ends in the middle of a string literal or C-style comment.
2696*/
2697static int _is_complete(char *zSql, int nSql){
2698 int rc;
2699 if( zSql==0 ) return 1;
2700 zSql[nSql] = ';';
2701 zSql[nSql+1] = 0;
2702 rc = sqlite3_complete(zSql);
2703 zSql[nSql] = 0;
2704 return rc;
2705}
2706
2707/*
drh67505e72002-04-19 12:34:06 +00002708** Read input from *in and process it. If *in==0 then input
2709** is interactive - the user is typing it it. Otherwise, input
2710** is coming from a file or device. A prompt is issued and history
2711** is saved only if input is interactive. An interrupt signal will
2712** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002713**
2714** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002715*/
drhc28490c2006-10-26 14:25:58 +00002716static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002717 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002718 char *zSql = 0;
2719 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002720 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002721 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002722 int rc;
2723 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002724 int lineno = 0;
2725 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002726
2727 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2728 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002729 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002730 zLine = one_input_line(zSql, in);
2731 if( zLine==0 ){
2732 break; /* We have reached EOF */
2733 }
drh67505e72002-04-19 12:34:06 +00002734 if( seenInterrupt ){
2735 if( in!=0 ) break;
2736 seenInterrupt = 0;
2737 }
drhc28490c2006-10-26 14:25:58 +00002738 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00002739 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00002740 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002741 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00002742 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00002743 if( rc==2 ){
2744 break;
2745 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002746 errCnt++;
2747 }
drhdaffd0e2001-04-11 14:28:42 +00002748 continue;
2749 }
drh233a5312008-12-18 22:25:13 +00002750 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002751 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002752 }
drh91a66392007-09-07 01:12:32 +00002753 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002754 if( zSql==0 ){
2755 int i;
drh4c755c02004-08-08 20:22:17 +00002756 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002757 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002758 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002759 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002760 if( zSql==0 ){
2761 fprintf(stderr, "out of memory\n");
2762 exit(1);
2763 }
drh5bb3eb92007-05-04 13:15:55 +00002764 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002765 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002766 }
2767 }else{
drh4f21c4a2008-12-10 22:15:00 +00002768 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002769 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002770 if( zSql==0 ){
2771 fprintf(stderr,"%s: out of memory!\n", Argv0);
2772 exit(1);
2773 }
drh5bb3eb92007-05-04 13:15:55 +00002774 zSql[nSql++] = '\n';
2775 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002776 nSql += len;
2777 }
drh91a66392007-09-07 01:12:32 +00002778 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2779 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002780 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002781 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002782 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00002783 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002784 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002785 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002786 char zPrefix[100];
2787 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002788 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
2789 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002790 }else{
drh5bb3eb92007-05-04 13:15:55 +00002791 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00002792 }
drh7f953e22002-07-13 17:33:45 +00002793 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00002794 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002795 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002796 zErrMsg = 0;
2797 }else{
drhc28490c2006-10-26 14:25:58 +00002798 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002799 }
drhc49f44e2006-10-26 18:15:42 +00002800 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002801 }
2802 free(zSql);
2803 zSql = 0;
2804 nSql = 0;
2805 }
2806 }
2807 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00002808 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002809 free(zSql);
2810 }
danielk19772ac27622007-07-03 05:31:16 +00002811 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002812 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002813}
2814
drh67505e72002-04-19 12:34:06 +00002815/*
2816** Return a pathname which is the user's home directory. A
2817** 0 return indicates an error of some kind. Space to hold the
2818** resulting string is obtained from malloc(). The calling
2819** function should free the result.
2820*/
2821static char *find_home_dir(void){
2822 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002823
chw97185482008-11-17 08:05:31 +00002824#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002825 struct passwd *pwent;
2826 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002827 if( (pwent=getpwuid(uid)) != NULL) {
2828 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002829 }
2830#endif
2831
chw65d3c132007-11-12 21:09:10 +00002832#if defined(_WIN32_WCE)
2833 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2834 */
2835 home_dir = strdup("/");
2836#else
2837
drh164a1b62006-08-19 11:15:20 +00002838#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2839 if (!home_dir) {
2840 home_dir = getenv("USERPROFILE");
2841 }
2842#endif
2843
drh67505e72002-04-19 12:34:06 +00002844 if (!home_dir) {
2845 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002846 }
2847
drhcdb36b72006-06-12 12:57:45 +00002848#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002849 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002850 char *zDrive, *zPath;
2851 int n;
2852 zDrive = getenv("HOMEDRIVE");
2853 zPath = getenv("HOMEPATH");
2854 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002855 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002856 home_dir = malloc( n );
2857 if( home_dir==0 ) return 0;
2858 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2859 return home_dir;
2860 }
2861 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002862 }
2863#endif
2864
chw65d3c132007-11-12 21:09:10 +00002865#endif /* !_WIN32_WCE */
2866
drh67505e72002-04-19 12:34:06 +00002867 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002868 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002869 char *z = malloc( n );
2870 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002871 home_dir = z;
2872 }
drhe98d4fa2002-04-21 19:06:22 +00002873
drh67505e72002-04-19 12:34:06 +00002874 return home_dir;
2875}
2876
2877/*
2878** Read input from the file given by sqliterc_override. Or if that
2879** parameter is NULL, take input from ~/.sqliterc
2880*/
drh22fbcb82004-02-01 01:22:50 +00002881static void process_sqliterc(
2882 struct callback_data *p, /* Configuration data */
2883 const char *sqliterc_override /* Name of config file. NULL to use default */
2884){
persicom7e2dfdd2002-04-18 02:46:52 +00002885 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002886 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002887 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002888 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002889 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002890
2891 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002892 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002893 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002894#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00002895 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00002896#endif
drhe98d4fa2002-04-21 19:06:22 +00002897 return;
2898 }
drh4f21c4a2008-12-10 22:15:00 +00002899 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002900 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002901 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002902 fprintf(stderr,"%s: out of memory!\n", Argv0);
2903 exit(1);
2904 }
drha959ac42007-06-20 13:10:00 +00002905 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002906 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002907 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002908 }
drha1f9b5e2004-02-14 16:31:02 +00002909 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002910 if( in ){
drhc28490c2006-10-26 14:25:58 +00002911 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00002912 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002913 }
persicom7e2dfdd2002-04-18 02:46:52 +00002914 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002915 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002916 }
drh43617e92006-03-06 20:55:46 +00002917 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00002918 return;
2919}
2920
drh67505e72002-04-19 12:34:06 +00002921/*
drhe1e38c42003-05-04 18:30:59 +00002922** Show available command line options
2923*/
2924static const char zOptions[] =
2925 " -init filename read/process named file\n"
2926 " -echo print commands before execution\n"
2927 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002928 " -bail stop after hitting an error\n"
2929 " -interactive force interactive I/O\n"
2930 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002931 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002932 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002933 " -html set output mode to HTML\n"
2934 " -line set output mode to 'line'\n"
2935 " -list set output mode to 'list'\n"
2936 " -separator 'x' set output field separator (|)\n"
2937 " -nullvalue 'text' set text string for NULL values\n"
2938 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002939;
2940static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002941 fprintf(stderr,
2942 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2943 "FILENAME is the name of an SQLite database. A new database is created\n"
2944 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002945 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002946 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002947 }else{
2948 fprintf(stderr, "Use the -help option for additional information\n");
2949 }
2950 exit(1);
2951}
2952
2953/*
drh67505e72002-04-19 12:34:06 +00002954** Initialize the state information in data
2955*/
drh0850b532006-01-31 19:31:43 +00002956static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002957 memset(data, 0, sizeof(*data));
2958 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002959 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002960 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00002961 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2962 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00002963}
2964
drh75897232000-05-29 14:26:00 +00002965int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002966 char *zErrMsg = 0;
2967 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002968 const char *zInitFile = 0;
2969 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002970 int i;
drhc28490c2006-10-26 14:25:58 +00002971 int rc = 0;
drh75897232000-05-29 14:26:00 +00002972
drhdaffd0e2001-04-11 14:28:42 +00002973 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002974 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002975 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002976
drh44c2eb12003-04-30 11:38:26 +00002977 /* Make sure we have a valid signal handler early, before anything
2978 ** else is done.
2979 */
drh4c504392000-10-16 22:06:40 +00002980#ifdef SIGINT
2981 signal(SIGINT, interrupt_handler);
2982#endif
drh44c2eb12003-04-30 11:38:26 +00002983
drh22fbcb82004-02-01 01:22:50 +00002984 /* Do an initial pass through the command-line argument to locate
2985 ** the name of the database file, the name of the initialization file,
2986 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002987 */
drh22fbcb82004-02-01 01:22:50 +00002988 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002989 char *z;
drh44c2eb12003-04-30 11:38:26 +00002990 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002991 z = argv[i];
2992 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002993 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2994 i++;
drh22fbcb82004-02-01 01:22:50 +00002995 }else if( strcmp(argv[i],"-init")==0 ){
2996 i++;
2997 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00002998 }
2999 }
drh22fbcb82004-02-01 01:22:50 +00003000 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00003001#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00003002 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
3003#else
drh22fbcb82004-02-01 01:22:50 +00003004 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00003005#endif
drh22fbcb82004-02-01 01:22:50 +00003006 }else{
danielk197703aded42004-11-22 05:26:27 +00003007#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003008 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003009#else
3010 data.zDbFilename = 0;
3011#endif
drh22fbcb82004-02-01 01:22:50 +00003012 }
3013 if( i<argc ){
3014 zFirstCmd = argv[i++];
3015 }
drh44c2eb12003-04-30 11:38:26 +00003016 data.out = stdout;
3017
drh01b41712005-08-29 23:06:23 +00003018#ifdef SQLITE_OMIT_MEMORYDB
3019 if( data.zDbFilename==0 ){
3020 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
3021 exit(1);
3022 }
3023#endif
3024
drh44c2eb12003-04-30 11:38:26 +00003025 /* Go ahead and open the database file if it already exists. If the
3026 ** file does not exist, delay opening it. This prevents empty database
3027 ** files from being created if a user mistypes the database name argument
3028 ** to the sqlite command-line tool.
3029 */
drhc8d74412004-08-31 23:41:26 +00003030 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003031 open_db(&data);
3032 }
3033
drh22fbcb82004-02-01 01:22:50 +00003034 /* Process the initialization file if there is one. If no -init option
3035 ** is given on the command line, look for a file named ~/.sqliterc and
3036 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003037 */
drh22fbcb82004-02-01 01:22:50 +00003038 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00003039
drh22fbcb82004-02-01 01:22:50 +00003040 /* Make a second pass through the command-line argument and set
3041 ** options. This second pass is delayed until after the initialization
3042 ** file is processed so that the command-line arguments will override
3043 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003044 */
drh22fbcb82004-02-01 01:22:50 +00003045 for(i=1; i<argc && argv[i][0]=='-'; i++){
3046 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00003047 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003048 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003049 i++;
3050 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003051 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003052 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003053 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003054 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003055 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003056 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003057 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003058 }else if( strcmp(z,"-csv")==0 ){
3059 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003060 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003061 }else if( strcmp(z,"-separator")==0 ){
3062 i++;
drh5bb3eb92007-05-04 13:15:55 +00003063 sqlite3_snprintf(sizeof(data.separator), data.separator,
3064 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003065 }else if( strcmp(z,"-nullvalue")==0 ){
3066 i++;
drh5bb3eb92007-05-04 13:15:55 +00003067 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
3068 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003069 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003070 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003071 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003072 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003073 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003074 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003075 }else if( strcmp(z,"-bail")==0 ){
3076 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003077 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00003078 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00003079 return 0;
drhc28490c2006-10-26 14:25:58 +00003080 }else if( strcmp(z,"-interactive")==0 ){
3081 stdin_is_interactive = 1;
3082 }else if( strcmp(z,"-batch")==0 ){
3083 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00003084 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003085 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00003086 }else{
drh22fbcb82004-02-01 01:22:50 +00003087 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003088 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003089 return 1;
3090 }
3091 }
drh44c2eb12003-04-30 11:38:26 +00003092
drh22fbcb82004-02-01 01:22:50 +00003093 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003094 /* Run just the command that follows the database name
3095 */
drh22fbcb82004-02-01 01:22:50 +00003096 if( zFirstCmd[0]=='.' ){
3097 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003098 exit(0);
3099 }else{
3100 int rc;
drh44c2eb12003-04-30 11:38:26 +00003101 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00003102 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00003103 if( rc!=0 && zErrMsg!=0 ){
3104 fprintf(stderr,"SQL error: %s\n", zErrMsg);
3105 exit(1);
3106 }
drh75897232000-05-29 14:26:00 +00003107 }
3108 }else{
drh44c2eb12003-04-30 11:38:26 +00003109 /* Run commands received from standard input
3110 */
drhc28490c2006-10-26 14:25:58 +00003111 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003112 char *zHome;
3113 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003114 int nHistory;
drh75897232000-05-29 14:26:00 +00003115 printf(
drhb217a572000-08-22 13:40:18 +00003116 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00003117 "Enter \".help\" for instructions\n"
3118 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00003119 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00003120 );
drh67505e72002-04-19 12:34:06 +00003121 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003122 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003123 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003124 if( (zHistory = malloc(nHistory))!=0 ){
3125 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3126 }
drh67505e72002-04-19 12:34:06 +00003127 }
danielk19774af00c62005-01-23 23:43:21 +00003128#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003129 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003130#endif
drhc28490c2006-10-26 14:25:58 +00003131 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003132 if( zHistory ){
3133 stifle_history(100);
3134 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003135 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003136 }
adamd0a3daa32006-07-28 20:16:14 +00003137 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00003138 }else{
drhc28490c2006-10-26 14:25:58 +00003139 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003140 }
3141 }
drh33048c02001-10-01 14:29:22 +00003142 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00003143 if( db ){
3144 if( sqlite3_close(db)!=SQLITE_OK ){
3145 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
3146 }
3147 }
drhc28490c2006-10-26 14:25:58 +00003148 return rc;
drh75897232000-05-29 14:26:00 +00003149}