blob: 73742fc9b2f532cd94019be26570b3f9baed8fae [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**
danielk1977e6320042009-02-25 15:43:57 +000015** $Id: shell.c,v 1.203 2009/02/25 15:43:57 danielk1977 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
danielk1977c8c70692009-02-25 15:22:02 +000076
77/**************************************************************************
78***************************************************************************
79** Begin genfkey logic.
80*/
81#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined SQLITE_OMIT_SUBQUERY
82
83#define GENFKEY_ERROR 1
84#define GENFKEY_DROPTRIGGER 2
85#define GENFKEY_CREATETRIGGER 3
86static int genfkey_create_triggers(sqlite3 *, const char *, void *,
87 int (*)(void *, int, const char *)
88);
89
90struct GenfkeyCb {
91 void *pCtx;
92 int eType;
93 int (*xData)(void *, int, const char *);
94};
95typedef struct GenfkeyCb GenfkeyCb;
96
97/* The code in this file defines a sqlite3 virtual-table module that
98** provides a read-only view of the current database schema. There is one
99** row in the schema table for each column in the database schema.
100*/
101#define SCHEMA \
102"CREATE TABLE x(" \
103 "database," /* Name of database (i.e. main, temp etc.) */ \
104 "tablename," /* Name of table */ \
105 "cid," /* Column number (from left-to-right, 0 upward) */ \
106 "name," /* Column name */ \
107 "type," /* Specified type (i.e. VARCHAR(32)) */ \
108 "not_null," /* Boolean. True if NOT NULL was specified */ \
109 "dflt_value," /* Default value for this column */ \
110 "pk" /* True if this column is part of the primary key */ \
111")"
112
113#define SCHEMA2 \
114"CREATE TABLE x(" \
115 "database," /* Name of database (i.e. main, temp etc.) */ \
116 "from_tbl," /* Name of table */ \
117 "fkid," \
118 "seq," \
119 "to_tbl," \
120 "from_col," \
121 "to_col," \
122 "on_update," \
123 "on_delete," \
124 "match" \
125")"
126
127#define SCHEMA3 \
128"CREATE TABLE x(" \
129 "database," /* Name of database (i.e. main, temp etc.) */ \
130 "tablename," /* Name of table */ \
131 "seq," \
132 "name," \
133 "isunique" \
134")"
135
136#define SCHEMA4 \
137"CREATE TABLE x(" \
138 "database," /* Name of database (i.e. main, temp etc.) */ \
139 "indexname," /* Name of table */ \
140 "seqno," \
141 "cid," \
142 "name" \
143")"
144
145#define SCHEMA5 \
146"CREATE TABLE x(" \
147 "database," /* Name of database (i.e. main, temp etc.) */ \
148 "triggername," /* Name of trigger */ \
149 "dummy" /* Unused */ \
150")"
151
152typedef struct SchemaTable SchemaTable;
153struct SchemaTable {
154 const char *zName;
155 const char *zObject;
156 const char *zPragma;
157 const char *zSchema;
158} aSchemaTable[] = {
159 { "table_info", "table", "PRAGMA %Q.table_info(%Q)", SCHEMA },
160 { "foreign_key_list", "table", "PRAGMA %Q.foreign_key_list(%Q)", SCHEMA2 },
161 { "index_list", "table", "PRAGMA %Q.index_list(%Q)", SCHEMA3 },
162 { "index_info", "index", "PRAGMA %Q.index_info(%Q)", SCHEMA4 },
163 { "trigger_list", "trigger", "SELECT 1", SCHEMA5 },
164 { 0, 0, 0, 0 }
165};
166
167typedef struct schema_vtab schema_vtab;
168typedef struct schema_cursor schema_cursor;
169
170/* A schema table object */
171struct schema_vtab {
172 sqlite3_vtab base;
173 sqlite3 *db;
174 SchemaTable *pType;
175};
176
177/* A schema table cursor object */
178struct schema_cursor {
179 sqlite3_vtab_cursor base;
180 sqlite3_stmt *pDbList;
181 sqlite3_stmt *pTableList;
182 sqlite3_stmt *pColumnList;
183 int rowid;
184};
185
186/*
187** Table destructor for the schema module.
188*/
189static int schemaDestroy(sqlite3_vtab *pVtab){
190 sqlite3_free(pVtab);
191 return 0;
192}
193
194/*
195** Table constructor for the schema module.
196*/
197static int schemaCreate(
198 sqlite3 *db,
199 void *pAux,
200 int argc, const char *const*argv,
201 sqlite3_vtab **ppVtab,
202 char **pzErr
203){
204 int rc = SQLITE_NOMEM;
205 schema_vtab *pVtab;
206 SchemaTable *pType = &aSchemaTable[0];
207
208 if( argc>3 ){
209 int i;
210 pType = 0;
211 for(i=0; aSchemaTable[i].zName; i++){
212 if( 0==strcmp(argv[3], aSchemaTable[i].zName) ){
213 pType = &aSchemaTable[i];
214 }
215 }
216 if( !pType ){
217 return SQLITE_ERROR;
218 }
219 }
220
221 pVtab = sqlite3_malloc(sizeof(schema_vtab));
222 if( pVtab ){
223 memset(pVtab, 0, sizeof(schema_vtab));
224 pVtab->db = (sqlite3 *)pAux;
225 pVtab->pType = pType;
226 rc = sqlite3_declare_vtab(db, pType->zSchema);
227 }
228 *ppVtab = (sqlite3_vtab *)pVtab;
229 return rc;
230}
231
232/*
233** Open a new cursor on the schema table.
234*/
235static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
236 int rc = SQLITE_NOMEM;
237 schema_cursor *pCur;
238 pCur = sqlite3_malloc(sizeof(schema_cursor));
239 if( pCur ){
240 memset(pCur, 0, sizeof(schema_cursor));
241 *ppCursor = (sqlite3_vtab_cursor *)pCur;
242 rc = SQLITE_OK;
243 }
244 return rc;
245}
246
247/*
248** Close a schema table cursor.
249*/
250static int schemaClose(sqlite3_vtab_cursor *cur){
251 schema_cursor *pCur = (schema_cursor *)cur;
252 sqlite3_finalize(pCur->pDbList);
253 sqlite3_finalize(pCur->pTableList);
254 sqlite3_finalize(pCur->pColumnList);
255 sqlite3_free(pCur);
256 return SQLITE_OK;
257}
258
259static void columnToResult(sqlite3_context *ctx, sqlite3_stmt *pStmt, int iCol){
260 switch( sqlite3_column_type(pStmt, iCol) ){
261 case SQLITE_NULL:
262 sqlite3_result_null(ctx);
263 break;
264 case SQLITE_INTEGER:
265 sqlite3_result_int64(ctx, sqlite3_column_int64(pStmt, iCol));
266 break;
267 case SQLITE_FLOAT:
268 sqlite3_result_double(ctx, sqlite3_column_double(pStmt, iCol));
269 break;
270 case SQLITE_TEXT: {
271 const char *z = (const char *)sqlite3_column_text(pStmt, iCol);
272 sqlite3_result_text(ctx, z, -1, SQLITE_TRANSIENT);
273 break;
274 }
275 }
276}
277
278/*
279** Retrieve a column of data.
280*/
281static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
282 schema_cursor *pCur = (schema_cursor *)cur;
283 switch( i ){
284 case 0:
285 columnToResult(ctx, pCur->pDbList, 1);
286 break;
287 case 1:
288 columnToResult(ctx, pCur->pTableList, 0);
289 break;
290 default:
291 columnToResult(ctx, pCur->pColumnList, i-2);
292 break;
293 }
294 return SQLITE_OK;
295}
296
297/*
298** Retrieve the current rowid.
299*/
300static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
301 schema_cursor *pCur = (schema_cursor *)cur;
302 *pRowid = pCur->rowid;
303 return SQLITE_OK;
304}
305
306static int finalize(sqlite3_stmt **ppStmt){
307 int rc = sqlite3_finalize(*ppStmt);
308 *ppStmt = 0;
309 return rc;
310}
311
312static int schemaEof(sqlite3_vtab_cursor *cur){
313 schema_cursor *pCur = (schema_cursor *)cur;
314 return (pCur->pDbList ? 0 : 1);
315}
316
317/*
318** Advance the cursor to the next row.
319*/
320static int schemaNext(sqlite3_vtab_cursor *cur){
321 int rc = SQLITE_OK;
322 schema_cursor *pCur = (schema_cursor *)cur;
323 schema_vtab *pVtab = (schema_vtab *)(cur->pVtab);
324 char *zSql = 0;
325
326 while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){
327 if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit;
328
329 while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){
330 if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit;
331
332 assert(pCur->pDbList);
333 while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){
334 rc = finalize(&pCur->pDbList);
335 goto next_exit;
336 }
337
338 /* Set zSql to the SQL to pull the list of tables from the
339 ** sqlite_master (or sqlite_temp_master) table of the database
340 ** identfied by the row pointed to by the SQL statement pCur->pDbList
341 ** (iterating through a "PRAGMA database_list;" statement).
342 */
343 if( sqlite3_column_int(pCur->pDbList, 0)==1 ){
344 zSql = sqlite3_mprintf(
345 "SELECT name FROM sqlite_temp_master WHERE type=%Q",
346 pVtab->pType->zObject
347 );
348 }else{
349 sqlite3_stmt *pDbList = pCur->pDbList;
350 zSql = sqlite3_mprintf(
351 "SELECT name FROM %Q.sqlite_master WHERE type=%Q",
352 sqlite3_column_text(pDbList, 1), pVtab->pType->zObject
353 );
354 }
355 if( !zSql ){
356 rc = SQLITE_NOMEM;
357 goto next_exit;
358 }
359
360 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0);
361 sqlite3_free(zSql);
362 if( rc!=SQLITE_OK ) goto next_exit;
363 }
364
365 /* Set zSql to the SQL to the table_info pragma for the table currently
366 ** identified by the rows pointed to by statements pCur->pDbList and
367 ** pCur->pTableList.
368 */
369 zSql = sqlite3_mprintf(pVtab->pType->zPragma,
370 sqlite3_column_text(pCur->pDbList, 1),
371 sqlite3_column_text(pCur->pTableList, 0)
372 );
373
374 if( !zSql ){
375 rc = SQLITE_NOMEM;
376 goto next_exit;
377 }
378 rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0);
379 sqlite3_free(zSql);
380 if( rc!=SQLITE_OK ) goto next_exit;
381 }
382 pCur->rowid++;
383
384next_exit:
385 /* TODO: Handle rc */
386 return rc;
387}
388
389/*
390** Reset a schema table cursor.
391*/
392static int schemaFilter(
393 sqlite3_vtab_cursor *pVtabCursor,
394 int idxNum, const char *idxStr,
395 int argc, sqlite3_value **argv
396){
397 int rc;
398 schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab);
399 schema_cursor *pCur = (schema_cursor *)pVtabCursor;
400 pCur->rowid = 0;
401 finalize(&pCur->pTableList);
402 finalize(&pCur->pColumnList);
403 finalize(&pCur->pDbList);
404 rc = sqlite3_prepare(pVtab->db,"SELECT 0, 'main'", -1, &pCur->pDbList, 0);
405 return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc);
406}
407
408/*
409** Analyse the WHERE condition.
410*/
411static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
412 return SQLITE_OK;
413}
414
415/*
416** A virtual table module that merely echos method calls into TCL
417** variables.
418*/
419static sqlite3_module schemaModule = {
420 0, /* iVersion */
421 schemaCreate,
422 schemaCreate,
423 schemaBestIndex,
424 schemaDestroy,
425 schemaDestroy,
426 schemaOpen, /* xOpen - open a cursor */
427 schemaClose, /* xClose - close a cursor */
428 schemaFilter, /* xFilter - configure scan constraints */
429 schemaNext, /* xNext - advance a cursor */
430 schemaEof, /* xEof */
431 schemaColumn, /* xColumn - read data */
432 schemaRowid, /* xRowid - read data */
433 0, /* xUpdate */
434 0, /* xBegin */
435 0, /* xSync */
436 0, /* xCommit */
437 0, /* xRollback */
438 0, /* xFindMethod */
439 0, /* xRename */
440};
441
442/*
443** Extension load function.
444*/
445static int installSchemaModule(sqlite3 *db, sqlite3 *sdb){
446 sqlite3_create_module(db, "schema", &schemaModule, (void *)sdb);
447 return 0;
448}
449
450/*
451** sj(zValue, zJoin)
452**
453** The following block contains the implementation of an aggregate
454** function that returns a string. Each time the function is stepped,
455** it appends data to an internal buffer. When the aggregate is finalized,
456** the contents of the buffer are returned.
457**
458** The first time the aggregate is stepped the buffer is set to a copy
459** of the first argument. The second time and subsequent times it is
460** stepped a copy of the second argument is appended to the buffer, then
461** a copy of the first.
462**
463** Example:
464**
465** INSERT INTO t1(a) VALUES('1');
466** INSERT INTO t1(a) VALUES('2');
467** INSERT INTO t1(a) VALUES('3');
468** SELECT sj(a, ', ') FROM t1;
469**
470** => "1, 2, 3"
471**
472*/
473struct StrBuffer {
474 char *zBuf;
475};
476typedef struct StrBuffer StrBuffer;
477static void joinFinalize(sqlite3_context *context){
478 StrBuffer *p;
479 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
480 sqlite3_result_text(context, p->zBuf, -1, SQLITE_TRANSIENT);
481 sqlite3_free(p->zBuf);
482}
483static void joinStep(
484 sqlite3_context *context,
485 int argc,
486 sqlite3_value **argv
487){
488 StrBuffer *p;
489 p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer));
490 if( p->zBuf==0 ){
491 p->zBuf = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
492 }else{
493 char *zTmp = p->zBuf;
494 p->zBuf = sqlite3_mprintf("%s%s%s",
495 zTmp, sqlite3_value_text(argv[1]), sqlite3_value_text(argv[0])
496 );
497 sqlite3_free(zTmp);
498 }
499}
500
501/*
502** dq(zString)
503**
504** This scalar function accepts a single argument and interprets it as
505** a text value. The return value is the argument enclosed in double
506** quotes. If any double quote characters are present in the argument,
507** these are escaped.
508**
509** dq('the raven "Nevermore."') == '"the raven ""Nevermore."""'
510*/
511static void doublequote(
512 sqlite3_context *context,
513 int argc,
514 sqlite3_value **argv
515){
516 int ii;
517 char *zOut;
518 char *zCsr;
519 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
520 int nIn = sqlite3_value_bytes(argv[0]);
521
522 zOut = sqlite3_malloc(nIn*2+3);
523 zCsr = zOut;
524 *zCsr++ = '"';
525 for(ii=0; ii<nIn; ii++){
526 *zCsr++ = zIn[ii];
527 if( zIn[ii]=='"' ){
528 *zCsr++ = '"';
529 }
530 }
531 *zCsr++ = '"';
532 *zCsr++ = '\0';
533
534 sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT);
535 sqlite3_free(zOut);
536}
537
538/*
539** multireplace(zString, zSearch1, zReplace1, ...)
540*/
541static void multireplace(
542 sqlite3_context *context,
543 int argc,
544 sqlite3_value **argv
545){
546 int i = 0;
547 char *zOut = 0;
548 int nOut = 0;
549 int nMalloc = 0;
550 const char *zIn = (const char *)sqlite3_value_text(argv[0]);
551 int nIn = sqlite3_value_bytes(argv[0]);
552
553 while( i<nIn ){
554 const char *zCopy = &zIn[i];
555 int nCopy = 1;
556 int nReplace = 1;
557 int j;
558 for(j=1; j<(argc-1); j+=2){
559 const char *z = (const char *)sqlite3_value_text(argv[j]);
560 int n = sqlite3_value_bytes(argv[j]);
561 if( n<=(nIn-i) && 0==strncmp(z, zCopy, n) ){
562 zCopy = (const char *)sqlite3_value_text(argv[j+1]);
563 nCopy = sqlite3_value_bytes(argv[j+1]);
564 nReplace = n;
565 break;
566 }
567 }
568 if( (nOut+nCopy)>nMalloc ){
569 nMalloc += (nMalloc + 16);
570 zOut = (char *)sqlite3_realloc(zOut, nMalloc);
571 }
572 memcpy(&zOut[nOut], zCopy, nCopy);
573 i += nReplace;
574 nOut += nCopy;
575 }
576
577 sqlite3_result_text(context, zOut, nOut, SQLITE_TRANSIENT);
578 sqlite3_free(zOut);
579}
580
581/*
582** A callback for sqlite3_exec() invokes the callback specified by the
583** GenfkeyCb structure pointed to by the void* passed as the first argument.
584*/
585static int invokeCallback(void *p, int nArg, char **azArg, char **azCol){
586 GenfkeyCb *pCb = (GenfkeyCb *)p;
587 return pCb->xData(pCb->pCtx, pCb->eType, azArg[0]);
588}
589
590int detectSchemaProblem(
591 sqlite3 *db, /* Database connection */
592 const char *zMessage, /* English language error message */
593 const char *zSql, /* SQL statement to run */
594 GenfkeyCb *pCb
595){
596 sqlite3_stmt *pStmt;
597 int rc;
598 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
599 if( rc!=SQLITE_OK ){
600 return rc;
601 }
602 while( SQLITE_ROW==sqlite3_step(pStmt) ){
603 char *zDel;
604 int iFk = sqlite3_column_int(pStmt, 0);
605 const char *zTab = (const char *)sqlite3_column_text(pStmt, 1);
606 zDel = sqlite3_mprintf("Error in table %s: %s", zTab, zMessage);
607 rc = pCb->xData(pCb->pCtx, pCb->eType, zDel);
608 sqlite3_free(zDel);
609 if( rc!=SQLITE_OK ) return rc;
610 zDel = sqlite3_mprintf(
611 "DELETE FROM temp.fkey WHERE from_tbl = %Q AND fkid = %d"
612 , zTab, iFk
613 );
614 sqlite3_exec(db, zDel, 0, 0, 0);
615 sqlite3_free(zDel);
616 }
617 sqlite3_finalize(pStmt);
618 return SQLITE_OK;
619}
620
621/*
622** Create and populate temporary table "fkey".
623*/
624static int populateTempTable(sqlite3 *db, GenfkeyCb *pCallback){
625 int rc;
626
627 rc = sqlite3_exec(db,
628 "CREATE VIRTUAL TABLE temp.v_fkey USING schema(foreign_key_list);"
629 "CREATE VIRTUAL TABLE temp.v_col USING schema(table_info);"
630 "CREATE VIRTUAL TABLE temp.v_idxlist USING schema(index_list);"
631 "CREATE VIRTUAL TABLE temp.v_idxinfo USING schema(index_info);"
632 "CREATE VIRTUAL TABLE temp.v_triggers USING schema(trigger_list);"
633 "CREATE TABLE temp.fkey AS "
634 "SELECT from_tbl, to_tbl, fkid, from_col, to_col, on_update, on_delete "
635 "FROM temp.v_fkey WHERE database = 'main';"
636 , 0, 0, 0
637 );
638 if( rc!=SQLITE_OK ) return rc;
639
640 rc = detectSchemaProblem(db, "foreign key columns do not exist",
641 "SELECT fkid, from_tbl "
642 "FROM temp.fkey "
643 "WHERE to_col IS NOT NULL AND NOT EXISTS (SELECT 1 "
644 "FROM temp.v_col WHERE tablename=to_tbl AND name==to_col"
645 ")", pCallback
646 );
647 if( rc!=SQLITE_OK ) return rc;
648
649 /* At this point the temp.fkey table is mostly populated. If any foreign
650 ** keys were specified so that they implicitly refer to they primary
651 ** key of the parent table, the "to_col" values of the temp.fkey rows
652 ** are still set to NULL.
653 **
654 ** This is easily fixed for single column primary keys, but not for
655 ** composites. With a composite primary key, there is no way to reliably
656 ** query sqlite for the order in which the columns that make up the
657 ** composite key were declared i.e. there is no way to tell if the
658 ** schema actually contains "PRIMARY KEY(a, b)" or "PRIMARY KEY(b, a)".
659 ** Therefore, this case is not handled. The following function call
660 ** detects instances of this case.
661 */
662 rc = detectSchemaProblem(db, "implicit mapping to composite primary key",
663 "SELECT fkid, from_tbl "
664 "FROM temp.fkey "
665 "WHERE to_col IS NULL "
666 "GROUP BY fkid, from_tbl HAVING count(*) > 1", pCallback
667 );
668 if( rc!=SQLITE_OK ) return rc;
669
670 /* Detect attempts to implicitly map to the primary key of a table
671 ** that has no primary key column.
672 */
673 rc = detectSchemaProblem(db, "implicit mapping to non-existant primary key",
674 "SELECT fkid, from_tbl "
675 "FROM temp.fkey "
676 "WHERE to_col IS NULL AND NOT EXISTS "
677 "(SELECT 1 FROM temp.v_col WHERE pk AND tablename = temp.fkey.to_tbl)"
678 , pCallback
679 );
680 if( rc!=SQLITE_OK ) return rc;
681
682 /* Fix all the implicit primary key mappings in the temp.fkey table. */
683 rc = sqlite3_exec(db,
684 "UPDATE temp.fkey SET to_col = "
685 "(SELECT name FROM temp.v_col WHERE pk AND tablename=temp.fkey.to_tbl)"
686 " WHERE to_col IS NULL;"
687 , 0, 0, 0
688 );
689 if( rc!=SQLITE_OK ) return rc;
690
691 /* Now check that all all parent keys are either primary keys or
692 ** subject to a unique constraint.
693 */
694 rc = sqlite3_exec(db,
695 "CREATE TABLE temp.idx2 AS SELECT "
696 "il.tablename AS tablename,"
697 "ii.indexname AS indexname,"
698 "ii.name AS col "
699 "FROM temp.v_idxlist AS il, temp.v_idxinfo AS ii "
700 "WHERE il.isunique AND il.database='main' AND ii.indexname = il.name;"
701 "INSERT INTO temp.idx2 "
702 "SELECT tablename, 'pk', name FROM temp.v_col WHERE pk;"
703
704 "CREATE TABLE temp.idx AS SELECT "
705 "tablename, indexname, sj(dq(col),',') AS cols "
706 "FROM (SELECT * FROM temp.idx2 ORDER BY col) "
707 "GROUP BY tablename, indexname;"
708
709 "CREATE TABLE temp.fkey2 AS SELECT "
710 "fkid, from_tbl, to_tbl, sj(dq(to_col),',') AS cols "
711 "FROM (SELECT * FROM temp.fkey ORDER BY to_col) "
712 "GROUP BY fkid, from_tbl;"
713
714 "CREATE TABLE temp.triggers AS SELECT "
715 "triggername FROM temp.v_triggers WHERE database='main' AND "
716 "triggername LIKE 'genfkey%';"
717 , 0, 0, 0
718 );
719 if( rc!=SQLITE_OK ) return rc;
720 rc = detectSchemaProblem(db, "foreign key is not unique",
721 "SELECT fkid, from_tbl "
722 "FROM temp.fkey2 "
723 "WHERE NOT EXISTS (SELECT 1 "
724 "FROM temp.idx WHERE tablename=to_tbl AND fkey2.cols==idx.cols"
725 ")", pCallback
726 );
727 if( rc!=SQLITE_OK ) return rc;
728
729 return rc;
730}
731
732#define GENFKEY_ERROR 1
733#define GENFKEY_DROPTRIGGER 2
734#define GENFKEY_CREATETRIGGER 3
735static int genfkey_create_triggers(
736 sqlite3 *sdb, /* Connection to read schema from */
737 const char *zDb, /* Name of db to read ("main", "temp") */
738 void *pCtx, /* Context pointer to pass to xData */
739 int (*xData)(void *, int, const char *)
740){
741 const char *zSql =
742 "SELECT multireplace('"
743
744 "-- Triggers for foreign key mapping:\n"
745 "--\n"
746 "-- /from_readable/ REFERENCES /to_readable/\n"
747 "-- on delete /on_delete/\n"
748 "-- on update /on_update/\n"
749 "--\n"
750
751 /* The "BEFORE INSERT ON <referencing>" trigger. This trigger's job is to
752 ** throw an exception if the user tries to insert a row into the
753 ** referencing table for which there is no corresponding row in
754 ** the referenced table.
755 */
756 "CREATE TRIGGER /name/_insert_referencing BEFORE INSERT ON /tbl/ WHEN \n"
757 " /key_notnull/ AND NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
758 "BEGIN\n"
759 " SELECT RAISE(ABORT, ''constraint failed'');\n"
760 "END;\n"
761
762 /* The "BEFORE UPDATE ON <referencing>" trigger. This trigger's job
763 ** is to throw an exception if the user tries to update a row in the
764 ** referencing table causing it to correspond to no row in the
765 ** referenced table.
766 */
767 "CREATE TRIGGER /name/_update_referencing BEFORE\n"
768 " UPDATE OF /rkey_list/ ON /tbl/ WHEN \n"
769 " /key_notnull/ AND \n"
770 " NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"
771 "BEGIN\n"
772 " SELECT RAISE(ABORT, ''constraint failed'');\n"
773 "END;\n"
774
775
776 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
777 ** is to detect when a row is deleted from the referenced table to
778 ** which rows in the referencing table correspond. The action taken
779 ** depends on the value of the 'ON DELETE' clause.
780 */
781 "CREATE TRIGGER /name/_delete_referenced BEFORE DELETE ON /ref/ WHEN\n"
782 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
783 "BEGIN\n"
784 " /delete_action/\n"
785 "END;\n"
786
787 /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job
788 ** is to detect when the key columns of a row in the referenced table
789 ** to which one or more rows in the referencing table correspond are
790 ** updated. The action taken depends on the value of the 'ON UPDATE'
791 ** clause.
792 */
793 "CREATE TRIGGER /name/_update_referenced AFTER\n"
794 " UPDATE OF /fkey_list/ ON /ref/ WHEN \n"
795 " EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
796 "BEGIN\n"
797 " /update_action/\n"
798 "END;\n"
799 "'"
800
801 /* These are used in the SQL comment written above each set of triggers */
802 ", '/from_readable/', from_tbl || '(' || sj(from_col, ', ') || ')'"
803 ", '/to_readable/', to_tbl || '(' || sj(to_col, ', ') || ')'"
804 ", '/on_delete/', on_delete"
805 ", '/on_update/', on_update"
806
807 ", '/name/', 'genfkey' || min(rowid)"
808 ", '/tbl/', dq(from_tbl)"
809 ", '/ref/', dq(to_tbl)"
810 ", '/key_notnull/', sj('new.' || dq(from_col) || ' IS NOT NULL', ' AND ')"
811
812 ", '/fkey_list/', sj(to_col, ', ')"
813 ", '/rkey_list/', sj(from_col, ', ')"
814
815 ", '/cond1/', sj(multireplace('new./from/ == /to/'"
816 ", '/from/', dq(from_col)"
817 ", '/to/', dq(to_col)"
818 "), ' AND ')"
819 ", '/cond2/', sj(multireplace('old./to/ == /from/'"
820 ", '/from/', dq(from_col)"
821 ", '/to/', dq(to_col)"
822 "), ' AND ')"
823
824 ", '/update_action/', CASE on_update "
825 "WHEN 'SET NULL' THEN "
826 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
827 ", '/setlist/', sj(from_col||' = NULL',', ')"
828 ", '/tbl/', dq(from_tbl)"
829 ", '/where/', sj(from_col||' = old.'||dq(to_col),' AND ')"
830 ")"
831 "WHEN 'CASCADE' THEN "
832 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
833 ", '/setlist/', sj(dq(from_col)||' = new.'||dq(to_col),', ')"
834 ", '/tbl/', dq(from_tbl)"
835 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
836 ")"
837 "ELSE "
838 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
839 "END "
840
841 ", '/delete_action/', CASE on_delete "
842 "WHEN 'SET NULL' THEN "
843 "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
844 ", '/setlist/', sj(from_col||' = NULL',', ')"
845 ", '/tbl/', dq(from_tbl)"
846 ", '/where/', sj(from_col||' = old.'||dq(to_col),' AND ')"
847 ")"
848 "WHEN 'CASCADE' THEN "
849 "multireplace('DELETE FROM /tbl/ WHERE /where/;' "
850 ", '/tbl/', dq(from_tbl)"
851 ", '/where/', sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
852 ")"
853 "ELSE "
854 " 'SELECT RAISE(ABORT, ''constraint failed'');'"
855 "END "
856
857 ") FROM temp.fkey "
858 "GROUP BY from_tbl, fkid"
859 ;
860
861 int rc;
862 const int enc = SQLITE_UTF8;
863 sqlite3 *db = 0;
864
865 GenfkeyCb cb;
866 cb.xData = xData;
867 cb.pCtx = pCtx;
868
869 /* Open the working database handle. */
870 rc = sqlite3_open(":memory:", &db);
871 if( rc!=SQLITE_OK ) goto genfkey_exit;
872
873 /* Create the special scalar and aggregate functions used by this program. */
874 sqlite3_create_function(db, "dq", 1, enc, 0, doublequote, 0, 0);
875 sqlite3_create_function(db, "multireplace", -1, enc, db, multireplace, 0, 0);
876 sqlite3_create_function(db, "sj", 2, enc, 0, 0, joinStep, joinFinalize);
877
878 /* Install the "schema" virtual table module */
879 installSchemaModule(db, sdb);
880
881 /* Create and populate a temp table with the information required to
882 ** build the foreign key triggers. See function populateTempTable()
883 ** for details.
884 */
885 cb.eType = GENFKEY_ERROR;
886 rc = populateTempTable(db, &cb);
887 if( rc!=SQLITE_OK ) goto genfkey_exit;
888
889 /* Unless the --no-drop option was specified, generate DROP TRIGGER
890 ** statements to drop any triggers in the database generated by a
891 ** previous run of this program.
892 */
893 cb.eType = GENFKEY_DROPTRIGGER;
894 rc = sqlite3_exec(db,
895 "SELECT 'DROP TRIGGER main.' || dq(triggername) || ';' FROM triggers"
896 ,invokeCallback, (void *)&cb, 0
897 );
898 if( rc!=SQLITE_OK ) goto genfkey_exit;
899
900 /* Run the main query to create the trigger definitions. */
901 cb.eType = GENFKEY_CREATETRIGGER;
902 rc = sqlite3_exec(db, zSql, invokeCallback, (void *)&cb, 0);
903 if( rc!=SQLITE_OK ) goto genfkey_exit;
904
905genfkey_exit:
906 sqlite3_close(db);
907 return rc;
908}
909
910
911#endif
912/* End genfkey logic. */
913/*************************************************************************/
914/*************************************************************************/
915
drh3b1a9882007-11-02 12:53:03 +0000916/* Saved resource information for the beginning of an operation */
917static struct rusage sBegin;
918
919/* True if the timer is enabled */
920static int enableTimer = 0;
921
922/*
923** Begin timing an operation
924*/
925static void beginTimer(void){
926 if( enableTimer ){
927 getrusage(RUSAGE_SELF, &sBegin);
928 }
929}
930
drhf4608092008-07-11 17:23:24 +0000931/* Return the difference of two time_structs in seconds */
932static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
933 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
934 (double)(pEnd->tv_sec - pStart->tv_sec);
drh3b1a9882007-11-02 12:53:03 +0000935}
936
937/*
938** Print the timing results.
939*/
940static void endTimer(void){
941 if( enableTimer ){
942 struct rusage sEnd;
943 getrusage(RUSAGE_SELF, &sEnd);
944 printf("CPU Time: user %f sys %f\n",
drhf4608092008-07-11 17:23:24 +0000945 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
946 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
drh3b1a9882007-11-02 12:53:03 +0000947 }
948}
949#define BEGIN_TIMER beginTimer()
950#define END_TIMER endTimer()
951#define HAS_TIMER 1
952#else
953#define BEGIN_TIMER
954#define END_TIMER
955#define HAS_TIMER 0
956#endif
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}