blob: ce3c4eaaca0d17a4f8c782752105c16ea5cf583a [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**
danielk1977c8c70692009-02-25 15:22:02 +000015** $Id: shell.c,v 1.202 2009/02/25 15:22:03 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"
1842 " --help: Print help message for .genfkey\n"
1843#endif
persicom7e2dfdd2002-04-18 02:46:52 +00001844 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001845 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001846 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +00001847 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +00001848#ifdef SQLITE_ENABLE_IOTRACE
1849 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1850#endif
drh70df4fe2006-06-13 15:12:21 +00001851#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001852 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001853#endif
danielk19776b77a362005-01-13 11:10:25 +00001854 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001855 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001856 " column Left-aligned columns. (See .width)\n"
1857 " html HTML <table> code\n"
1858 " insert SQL insert statements for TABLE\n"
1859 " line One value per line\n"
1860 " list Values delimited by .separator string\n"
1861 " tabs Tab-separated values\n"
1862 " tcl TCL list elements\n"
1863 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001864 ".output FILENAME Send output to FILENAME\n"
1865 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001866 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001867 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001868 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001869 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001870 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +00001871 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001872 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +00001873 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +00001874 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +00001875#if HAS_TIMER
1876 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1877#endif
drh75897232000-05-29 14:26:00 +00001878 ".width NUM NUM ... Set column widths for \"column\" mode\n"
1879;
1880
drhdaffd0e2001-04-11 14:28:42 +00001881/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001882static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001883
drh75897232000-05-29 14:26:00 +00001884/*
drh44c2eb12003-04-30 11:38:26 +00001885** Make sure the database is open. If it is not, then open it. If
1886** the database fails to open, print an error message and exit.
1887*/
1888static void open_db(struct callback_data *p){
1889 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001890 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001891 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001892 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1893 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1894 shellstaticFunc, 0, 0);
1895 }
1896 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +00001897 fprintf(stderr,"Unable to open database \"%s\": %s\n",
1898 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001899 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001900 }
drhc2e87a32006-06-27 15:16:14 +00001901#ifndef SQLITE_OMIT_LOAD_EXTENSION
1902 sqlite3_enable_load_extension(p->db, 1);
1903#endif
drh44c2eb12003-04-30 11:38:26 +00001904 }
1905}
1906
1907/*
drhfeac5f82004-08-01 00:10:45 +00001908** Do C-language style dequoting.
1909**
1910** \t -> tab
1911** \n -> newline
1912** \r -> carriage return
1913** \NNN -> ascii character NNN in octal
1914** \\ -> backslash
1915*/
1916static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001917 int i, j;
1918 char c;
drhfeac5f82004-08-01 00:10:45 +00001919 for(i=j=0; (c = z[i])!=0; i++, j++){
1920 if( c=='\\' ){
1921 c = z[++i];
1922 if( c=='n' ){
1923 c = '\n';
1924 }else if( c=='t' ){
1925 c = '\t';
1926 }else if( c=='r' ){
1927 c = '\r';
1928 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001929 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001930 if( z[i+1]>='0' && z[i+1]<='7' ){
1931 i++;
1932 c = (c<<3) + z[i] - '0';
1933 if( z[i+1]>='0' && z[i+1]<='7' ){
1934 i++;
1935 c = (c<<3) + z[i] - '0';
1936 }
1937 }
1938 }
1939 }
1940 z[j] = c;
1941 }
1942 z[j] = 0;
1943}
1944
1945/*
drhc28490c2006-10-26 14:25:58 +00001946** Interpret zArg as a boolean value. Return either 0 or 1.
1947*/
1948static int booleanValue(char *zArg){
1949 int val = atoi(zArg);
1950 int j;
1951 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001952 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001953 }
1954 if( strcmp(zArg,"on")==0 ){
1955 val = 1;
1956 }else if( strcmp(zArg,"yes")==0 ){
1957 val = 1;
1958 }
1959 return val;
1960}
1961
1962/*
drh75897232000-05-29 14:26:00 +00001963** If an input line begins with "." then invoke this routine to
1964** process that line.
drh67505e72002-04-19 12:34:06 +00001965**
drh47ad6842006-11-08 12:25:42 +00001966** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001967*/
drh44c2eb12003-04-30 11:38:26 +00001968static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001969 int i = 1;
1970 int nArg = 0;
1971 int n, c;
drh67505e72002-04-19 12:34:06 +00001972 int rc = 0;
drh75897232000-05-29 14:26:00 +00001973 char *azArg[50];
1974
1975 /* Parse the input line into tokens.
1976 */
1977 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001978 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001979 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001980 if( zLine[i]=='\'' || zLine[i]=='"' ){
1981 int delim = zLine[i++];
1982 azArg[nArg++] = &zLine[i];
1983 while( zLine[i] && zLine[i]!=delim ){ i++; }
1984 if( zLine[i]==delim ){
1985 zLine[i++] = 0;
1986 }
drhfeac5f82004-08-01 00:10:45 +00001987 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001988 }else{
1989 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001990 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001991 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001992 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001993 }
1994 }
1995
1996 /* Process the input line.
1997 */
drh67505e72002-04-19 12:34:06 +00001998 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00001999 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002000 c = azArg[0][0];
drh9ff849f2009-02-04 20:55:57 +00002001 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){
2002 const char *zDestFile;
2003 const char *zDb;
2004 sqlite3 *pDest;
2005 sqlite3_backup *pBackup;
2006 int rc;
2007 if( nArg==2 ){
2008 zDestFile = azArg[1];
2009 zDb = "main";
2010 }else{
2011 zDestFile = azArg[2];
2012 zDb = azArg[1];
2013 }
2014 rc = sqlite3_open(zDestFile, &pDest);
2015 if( rc!=SQLITE_OK ){
2016 fprintf(stderr, "Error: cannot open %s\n", zDestFile);
2017 sqlite3_close(pDest);
2018 return 1;
2019 }
drhdc2c4912009-02-04 22:46:47 +00002020 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002021 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2022 if( pBackup==0 ){
2023 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2024 sqlite3_close(pDest);
2025 return 1;
2026 }
2027 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2028 sqlite3_backup_finish(pBackup);
2029 if( rc==SQLITE_DONE ){
2030 rc = SQLITE_OK;
2031 }else{
2032 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2033 }
2034 sqlite3_close(pDest);
2035 }else
2036
2037 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
drhc49f44e2006-10-26 18:15:42 +00002038 bail_on_error = booleanValue(azArg[1]);
2039 }else
2040
jplyon6a65bb32003-05-04 07:25:57 +00002041 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00002042 struct callback_data data;
2043 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00002044 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00002045 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002046 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002047 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002048 data.colWidth[0] = 3;
2049 data.colWidth[1] = 15;
2050 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002051 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002052 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002053 if( zErrMsg ){
2054 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002055 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00002056 }
2057 }else
2058
drh4c653a02000-06-07 01:27:47 +00002059 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
2060 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002061 open_db(p);
drh33048c02001-10-01 14:29:22 +00002062 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002063 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00002064 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002065 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002066 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002067 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002068 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00002069 );
2070 run_table_dump_query(p->out, p->db,
2071 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002072 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00002073 );
drh4c653a02000-06-07 01:27:47 +00002074 }else{
2075 int i;
drhdd3d4592004-08-30 01:54:05 +00002076 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002077 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002078 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002079 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002080 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00002081 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00002082 run_table_dump_query(p->out, p->db,
2083 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002084 "WHERE sql NOT NULL"
2085 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00002086 " AND tbl_name LIKE shellstatic()"
2087 );
danielk1977bc6ada42004-06-30 08:20:16 +00002088 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002089 }
2090 }
drh45e29d82006-11-20 16:21:10 +00002091 if( p->writableSchema ){
2092 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
2093 p->writableSchema = 0;
2094 }
drh93f41e52008-08-11 19:12:34 +00002095 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00002096 if( zErrMsg ){
2097 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002098 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00002099 }else{
2100 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002101 }
2102 }else
drh75897232000-05-29 14:26:00 +00002103
drhdaffd0e2001-04-11 14:28:42 +00002104 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002105 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00002106 }else
2107
drh75897232000-05-29 14:26:00 +00002108 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002109 rc = 2;
drh75897232000-05-29 14:26:00 +00002110 }else
2111
drhdd45df82002-04-18 12:39:03 +00002112 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002113 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002114 if(val == 1) {
2115 if(!p->explainPrev.valid) {
2116 p->explainPrev.valid = 1;
2117 p->explainPrev.mode = p->mode;
2118 p->explainPrev.showHeader = p->showHeader;
2119 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
2120 }
2121 /* We could put this code under the !p->explainValid
2122 ** condition so that it does not execute if we are already in
2123 ** explain mode. However, always executing it allows us an easy
2124 ** was to reset to explain mode in case the user previously
2125 ** did an .explain followed by a .width, .mode or .header
2126 ** command.
2127 */
danielk19770d78bae2008-01-03 07:09:48 +00002128 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002129 p->showHeader = 1;
2130 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002131 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002132 p->colWidth[1] = 13; /* opcode */
2133 p->colWidth[2] = 4; /* P1 */
2134 p->colWidth[3] = 4; /* P2 */
2135 p->colWidth[4] = 4; /* P3 */
2136 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002137 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002138 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00002139 }else if (p->explainPrev.valid) {
2140 p->explainPrev.valid = 0;
2141 p->mode = p->explainPrev.mode;
2142 p->showHeader = p->explainPrev.showHeader;
2143 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2144 }
drh75897232000-05-29 14:26:00 +00002145 }else
2146
danielk1977c8c70692009-02-25 15:22:02 +00002147#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
2148 if( c=='g' && strncmp(azArg[0], "genfkey", n)==0 ){
2149 GenfkeyCmd cmd;
2150 if( 0==genfkeyParseArgs(&cmd, &azArg[1], nArg-1) ){
2151 cmd.db = p->db;
2152 cmd.pCb = p;
2153 genfkey_create_triggers(p->db, "main", (void *)&cmd, genfkeyCmdCb);
2154 }
2155 }else
2156#endif
2157
drhc28490c2006-10-26 14:25:58 +00002158 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00002159 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00002160 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00002161 }else
2162
2163 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00002164 fprintf(stderr,"%s",zHelp);
drh75897232000-05-29 14:26:00 +00002165 }else
2166
drhfeac5f82004-08-01 00:10:45 +00002167 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
2168 char *zTable = azArg[2]; /* Insert data into this table */
2169 char *zFile = azArg[1]; /* The file from which to extract data */
2170 sqlite3_stmt *pStmt; /* A statement */
2171 int rc; /* Result code */
2172 int nCol; /* Number of columns in the table */
2173 int nByte; /* Number of bytes in an SQL string */
2174 int i, j; /* Loop counters */
2175 int nSep; /* Number of bytes in p->separator[] */
2176 char *zSql; /* An SQL statement */
2177 char *zLine; /* A single line of input from the file */
2178 char **azCol; /* zLine[] broken up into columns */
2179 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00002180 FILE *in; /* The input file */
2181 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00002182
drha543c822006-06-08 16:10:14 +00002183 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002184 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002185 if( nSep==0 ){
2186 fprintf(stderr, "non-null separator required for import\n");
2187 return 0;
2188 }
2189 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
2190 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00002191 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002192 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002193 sqlite3_free(zSql);
2194 if( rc ){
2195 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2196 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00002197 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002198 }else{
2199 nCol = sqlite3_column_count(pStmt);
2200 }
2201 sqlite3_finalize(pStmt);
2202 if( nCol==0 ) return 0;
2203 zSql = malloc( nByte + 20 + nCol*2 );
2204 if( zSql==0 ) return 0;
2205 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002206 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002207 for(i=1; i<nCol; i++){
2208 zSql[j++] = ',';
2209 zSql[j++] = '?';
2210 }
2211 zSql[j++] = ')';
2212 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002213 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00002214 free(zSql);
2215 if( rc ){
2216 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
2217 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00002218 return 1;
drhfeac5f82004-08-01 00:10:45 +00002219 }
2220 in = fopen(zFile, "rb");
2221 if( in==0 ){
2222 fprintf(stderr, "cannot open file: %s\n", zFile);
2223 sqlite3_finalize(pStmt);
2224 return 0;
2225 }
2226 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00002227 if( azCol==0 ){
2228 fclose(in);
2229 return 0;
2230 }
drhfeac5f82004-08-01 00:10:45 +00002231 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
2232 zCommit = "COMMIT";
2233 while( (zLine = local_getline(0, in))!=0 ){
2234 char *z;
2235 i = 0;
drhb860bc92004-08-04 15:16:55 +00002236 lineno++;
drhfeac5f82004-08-01 00:10:45 +00002237 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00002238 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00002239 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
2240 *z = 0;
2241 i++;
drhb860bc92004-08-04 15:16:55 +00002242 if( i<nCol ){
2243 azCol[i] = &z[nSep];
2244 z += nSep-1;
2245 }
drhfeac5f82004-08-01 00:10:45 +00002246 }
2247 }
drh1cd7f832005-08-05 18:50:51 +00002248 *z = 0;
drhb860bc92004-08-04 15:16:55 +00002249 if( i+1!=nCol ){
2250 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
2251 zFile, lineno, nCol, i+1);
2252 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00002253 free(zLine);
drhb860bc92004-08-04 15:16:55 +00002254 break;
2255 }
drhfeac5f82004-08-01 00:10:45 +00002256 for(i=0; i<nCol; i++){
2257 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2258 }
2259 sqlite3_step(pStmt);
2260 rc = sqlite3_reset(pStmt);
2261 free(zLine);
2262 if( rc!=SQLITE_OK ){
2263 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2264 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00002265 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00002266 break;
2267 }
2268 }
2269 free(azCol);
2270 fclose(in);
2271 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00002272 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002273 }else
2274
drh75897232000-05-29 14:26:00 +00002275 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
2276 struct callback_data data;
2277 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002278 open_db(p);
drh75897232000-05-29 14:26:00 +00002279 memcpy(&data, p, sizeof(data));
2280 data.showHeader = 0;
2281 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00002282 zShellStatic = azArg[1];
2283 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00002284 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002285 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002286 "UNION ALL "
2287 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002288 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002289 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002290 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002291 );
danielk1977bc6ada42004-06-30 08:20:16 +00002292 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00002293 if( zErrMsg ){
2294 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002295 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002296 }
2297 }else
2298
drhae5e4452007-05-03 17:18:36 +00002299#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002300 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002301 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002302 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2303 iotrace = 0;
2304 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002305 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002306 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002307 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002308 iotrace = stdout;
2309 }else{
2310 iotrace = fopen(azArg[1], "w");
2311 if( iotrace==0 ){
2312 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002313 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002314 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002315 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002316 }
2317 }
2318 }else
drhae5e4452007-05-03 17:18:36 +00002319#endif
drhb0603412007-02-28 04:47:26 +00002320
drh70df4fe2006-06-13 15:12:21 +00002321#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002322 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2323 const char *zFile, *zProc;
2324 char *zErrMsg = 0;
2325 int rc;
2326 zFile = azArg[1];
2327 zProc = nArg>=3 ? azArg[2] : 0;
2328 open_db(p);
2329 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2330 if( rc!=SQLITE_OK ){
2331 fprintf(stderr, "%s\n", zErrMsg);
2332 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002333 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002334 }
2335 }else
drh70df4fe2006-06-13 15:12:21 +00002336#endif
drh1e397f82006-06-08 15:28:43 +00002337
drh28bd4bc2000-06-15 15:57:22 +00002338 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00002339 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002340 if( strncmp(azArg[1],"line",n2)==0
2341 ||
2342 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002343 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00002344 }else if( strncmp(azArg[1],"column",n2)==0
2345 ||
2346 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002347 p->mode = MODE_Column;
2348 }else if( strncmp(azArg[1],"list",n2)==0 ){
2349 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00002350 }else if( strncmp(azArg[1],"html",n2)==0 ){
2351 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00002352 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
2353 p->mode = MODE_Tcl;
2354 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002355 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002356 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00002357 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
2358 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002359 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00002360 }else if( strncmp(azArg[1],"insert",n2)==0 ){
2361 p->mode = MODE_Insert;
2362 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00002363 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00002364 }else{
drh33048c02001-10-01 14:29:22 +00002365 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00002366 }
drhdaffd0e2001-04-11 14:28:42 +00002367 }else {
drhcf68ae92006-12-19 18:47:41 +00002368 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002369 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00002370 }
2371 }else
2372
persicom7e2dfdd2002-04-18 02:46:52 +00002373 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002374 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2375 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002376 }else
2377
drh75897232000-05-29 14:26:00 +00002378 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
2379 if( p->out!=stdout ){
2380 fclose(p->out);
2381 }
2382 if( strcmp(azArg[1],"stdout")==0 ){
2383 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00002384 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00002385 }else{
drha1f9b5e2004-02-14 16:31:02 +00002386 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00002387 if( p->out==0 ){
2388 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
2389 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00002390 } else {
drh5bb3eb92007-05-04 13:15:55 +00002391 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002392 }
2393 }
2394 }else
2395
drhdd45df82002-04-18 12:39:03 +00002396 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002397 if( nArg >= 2) {
2398 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2399 }
2400 if( nArg >= 3) {
2401 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2402 }
2403 }else
2404
2405 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002406 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002407 }else
2408
drh9ff849f2009-02-04 20:55:57 +00002409 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002410 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002411 if( alt==0 ){
2412 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
2413 }else{
2414 process_input(p, alt);
2415 fclose(alt);
2416 }
2417 }else
2418
drh9ff849f2009-02-04 20:55:57 +00002419 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){
2420 const char *zSrcFile;
2421 const char *zDb;
2422 sqlite3 *pSrc;
2423 sqlite3_backup *pBackup;
2424 int rc;
drhdc2c4912009-02-04 22:46:47 +00002425 int nTimeout = 0;
2426
drh9ff849f2009-02-04 20:55:57 +00002427 if( nArg==2 ){
2428 zSrcFile = azArg[1];
2429 zDb = "main";
2430 }else{
2431 zSrcFile = azArg[2];
2432 zDb = azArg[1];
2433 }
2434 rc = sqlite3_open(zSrcFile, &pSrc);
2435 if( rc!=SQLITE_OK ){
2436 fprintf(stderr, "Error: cannot open %s\n", zSrcFile);
2437 sqlite3_close(pSrc);
2438 return 1;
2439 }
drhdc2c4912009-02-04 22:46:47 +00002440 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002441 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2442 if( pBackup==0 ){
2443 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2444 sqlite3_close(pSrc);
2445 return 1;
2446 }
drhdc2c4912009-02-04 22:46:47 +00002447 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2448 || rc==SQLITE_BUSY ){
2449 if( rc==SQLITE_BUSY ){
2450 if( nTimeout++ >= 3 ) break;
2451 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002452 }
2453 }
2454 sqlite3_backup_finish(pBackup);
2455 if( rc==SQLITE_DONE ){
2456 rc = SQLITE_OK;
drhdc2c4912009-02-04 22:46:47 +00002457 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2458 fprintf(stderr, "source database is busy\n");
drh9ff849f2009-02-04 20:55:57 +00002459 }else{
2460 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2461 }
2462 sqlite3_close(pSrc);
2463 }else
2464
drh75897232000-05-29 14:26:00 +00002465 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
2466 struct callback_data data;
2467 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002468 open_db(p);
drh75897232000-05-29 14:26:00 +00002469 memcpy(&data, p, sizeof(data));
2470 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002471 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002472 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002473 int i;
shane7d3846a2008-12-11 02:58:26 +00002474 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002475 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002476 char *new_argv[2], *new_colv[2];
2477 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2478 " type text,\n"
2479 " name text,\n"
2480 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002481 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002482 " sql text\n"
2483 ")";
2484 new_argv[1] = 0;
2485 new_colv[0] = "sql";
2486 new_colv[1] = 0;
2487 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00002488 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002489 char *new_argv[2], *new_colv[2];
2490 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2491 " type text,\n"
2492 " name text,\n"
2493 " tbl_name text,\n"
2494 " rootpage integer,\n"
2495 " sql text\n"
2496 ")";
2497 new_argv[1] = 0;
2498 new_colv[0] = "sql";
2499 new_colv[1] = 0;
2500 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00002501 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002502 zShellStatic = azArg[1];
2503 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002504 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002505 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2506 " FROM sqlite_master UNION ALL"
2507 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002508 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002509 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002510 callback, &data, &zErrMsg);
2511 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002512 }
drh75897232000-05-29 14:26:00 +00002513 }else{
danielk19776f8a5032004-05-10 10:34:51 +00002514 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002515 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002516 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2517 " FROM sqlite_master UNION ALL"
2518 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002519 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002520 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002521 callback, &data, &zErrMsg
2522 );
drh75897232000-05-29 14:26:00 +00002523 }
drh75897232000-05-29 14:26:00 +00002524 if( zErrMsg ){
2525 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002526 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002527 }
2528 }else
2529
2530 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002531 sqlite3_snprintf(sizeof(p->separator), p->separator,
2532 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002533 }else
2534
persicom7e2dfdd2002-04-18 02:46:52 +00002535 if( c=='s' && strncmp(azArg[0], "show", n)==0){
2536 int i;
2537 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002538 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002539 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002540 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002541 fprintf(p->out,"%9.9s: ", "nullvalue");
2542 output_c_string(p->out, p->nullvalue);
2543 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002544 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002545 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002546 fprintf(p->out,"%9.9s: ", "separator");
2547 output_c_string(p->out, p->separator);
2548 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002549 fprintf(p->out,"%9.9s: ","width");
2550 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002551 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002552 }
drhfeac5f82004-08-01 00:10:45 +00002553 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002554 }else
2555
drh2dfbbca2000-07-28 14:32:48 +00002556 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00002557 char **azResult;
2558 int nRow, rc;
2559 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002560 open_db(p);
drha50da102000-08-08 20:19:09 +00002561 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002562 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002563 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00002564 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002565 "UNION ALL "
2566 "SELECT name FROM sqlite_temp_master "
2567 "WHERE type IN ('table','view') "
2568 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002569 &azResult, &nRow, 0, &zErrMsg
2570 );
drha50da102000-08-08 20:19:09 +00002571 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002572 zShellStatic = azArg[1];
2573 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002574 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002575 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002576 "UNION ALL "
2577 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00002578 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00002579 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002580 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002581 );
danielk1977bc6ada42004-06-30 08:20:16 +00002582 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002583 }
drh75897232000-05-29 14:26:00 +00002584 if( zErrMsg ){
2585 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002586 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00002587 }
drhe3710332000-09-29 13:30:53 +00002588 if( rc==SQLITE_OK ){
2589 int len, maxlen = 0;
2590 int i, j;
2591 int nPrintCol, nPrintRow;
2592 for(i=1; i<=nRow; i++){
2593 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002594 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002595 if( len>maxlen ) maxlen = len;
2596 }
2597 nPrintCol = 80/(maxlen+2);
2598 if( nPrintCol<1 ) nPrintCol = 1;
2599 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2600 for(i=0; i<nPrintRow; i++){
2601 for(j=i+1; j<=nRow; j+=nPrintRow){
2602 char *zSp = j<=nPrintRow ? "" : " ";
2603 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2604 }
2605 printf("\n");
2606 }
drh47ad6842006-11-08 12:25:42 +00002607 }else{
2608 rc = 1;
drhe3710332000-09-29 13:30:53 +00002609 }
danielk19776f8a5032004-05-10 10:34:51 +00002610 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002611 }else
2612
drh3b1a9882007-11-02 12:53:03 +00002613 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00002614 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002615 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00002616 }else
drh3b1a9882007-11-02 12:53:03 +00002617
2618#if HAS_TIMER
2619 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
2620 enableTimer = booleanValue(azArg[1]);
2621 }else
2622#endif
drh2dfbbca2000-07-28 14:32:48 +00002623
drh75897232000-05-29 14:26:00 +00002624 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
2625 int j;
drh43617e92006-03-06 20:55:46 +00002626 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002627 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2628 p->colWidth[j-1] = atoi(azArg[j]);
2629 }
2630 }else
2631
drh3b1a9882007-11-02 12:53:03 +00002632
drh75897232000-05-29 14:26:00 +00002633 {
drh67505e72002-04-19 12:34:06 +00002634 fprintf(stderr, "unknown command or invalid arguments: "
2635 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00002636 }
drh67505e72002-04-19 12:34:06 +00002637
2638 return rc;
drh75897232000-05-29 14:26:00 +00002639}
2640
drh67505e72002-04-19 12:34:06 +00002641/*
drh91a66392007-09-07 01:12:32 +00002642** Return TRUE if a semicolon occurs anywhere in the first N characters
2643** of string z[].
drh324ccef2003-02-05 14:06:20 +00002644*/
drh91a66392007-09-07 01:12:32 +00002645static int _contains_semicolon(const char *z, int N){
2646 int i;
2647 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2648 return 0;
drh324ccef2003-02-05 14:06:20 +00002649}
2650
2651/*
drh70c7a4b2003-04-26 03:03:06 +00002652** Test to see if a line consists entirely of whitespace.
2653*/
2654static int _all_whitespace(const char *z){
2655 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002656 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002657 if( *z=='/' && z[1]=='*' ){
2658 z += 2;
2659 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2660 if( *z==0 ) return 0;
2661 z++;
2662 continue;
2663 }
2664 if( *z=='-' && z[1]=='-' ){
2665 z += 2;
2666 while( *z && *z!='\n' ){ z++; }
2667 if( *z==0 ) return 1;
2668 continue;
2669 }
2670 return 0;
2671 }
2672 return 1;
2673}
2674
2675/*
drha9b17162003-04-29 18:01:28 +00002676** Return TRUE if the line typed in is an SQL command terminator other
2677** than a semi-colon. The SQL Server style "go" command is understood
2678** as is the Oracle "/".
2679*/
2680static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002681 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002682 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2683 return 1; /* Oracle */
2684 }
drhc8d74412004-08-31 23:41:26 +00002685 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2686 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002687 return 1; /* SQL Server */
2688 }
2689 return 0;
2690}
2691
2692/*
drh233a5312008-12-18 22:25:13 +00002693** Return true if zSql is a complete SQL statement. Return false if it
2694** ends in the middle of a string literal or C-style comment.
2695*/
2696static int _is_complete(char *zSql, int nSql){
2697 int rc;
2698 if( zSql==0 ) return 1;
2699 zSql[nSql] = ';';
2700 zSql[nSql+1] = 0;
2701 rc = sqlite3_complete(zSql);
2702 zSql[nSql] = 0;
2703 return rc;
2704}
2705
2706/*
drh67505e72002-04-19 12:34:06 +00002707** Read input from *in and process it. If *in==0 then input
2708** is interactive - the user is typing it it. Otherwise, input
2709** is coming from a file or device. A prompt is issued and history
2710** is saved only if input is interactive. An interrupt signal will
2711** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002712**
2713** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002714*/
drhc28490c2006-10-26 14:25:58 +00002715static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002716 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002717 char *zSql = 0;
2718 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002719 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002720 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002721 int rc;
2722 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002723 int lineno = 0;
2724 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002725
2726 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2727 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002728 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002729 zLine = one_input_line(zSql, in);
2730 if( zLine==0 ){
2731 break; /* We have reached EOF */
2732 }
drh67505e72002-04-19 12:34:06 +00002733 if( seenInterrupt ){
2734 if( in!=0 ) break;
2735 seenInterrupt = 0;
2736 }
drhc28490c2006-10-26 14:25:58 +00002737 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00002738 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00002739 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002740 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00002741 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00002742 if( rc==2 ){
2743 break;
2744 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002745 errCnt++;
2746 }
drhdaffd0e2001-04-11 14:28:42 +00002747 continue;
2748 }
drh233a5312008-12-18 22:25:13 +00002749 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002750 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002751 }
drh91a66392007-09-07 01:12:32 +00002752 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002753 if( zSql==0 ){
2754 int i;
drh4c755c02004-08-08 20:22:17 +00002755 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002756 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002757 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002758 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002759 if( zSql==0 ){
2760 fprintf(stderr, "out of memory\n");
2761 exit(1);
2762 }
drh5bb3eb92007-05-04 13:15:55 +00002763 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002764 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002765 }
2766 }else{
drh4f21c4a2008-12-10 22:15:00 +00002767 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002768 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002769 if( zSql==0 ){
2770 fprintf(stderr,"%s: out of memory!\n", Argv0);
2771 exit(1);
2772 }
drh5bb3eb92007-05-04 13:15:55 +00002773 zSql[nSql++] = '\n';
2774 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002775 nSql += len;
2776 }
drh91a66392007-09-07 01:12:32 +00002777 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2778 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002779 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002780 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002781 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00002782 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002783 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002784 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002785 char zPrefix[100];
2786 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002787 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
2788 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002789 }else{
drh5bb3eb92007-05-04 13:15:55 +00002790 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00002791 }
drh7f953e22002-07-13 17:33:45 +00002792 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00002793 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002794 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002795 zErrMsg = 0;
2796 }else{
drhc28490c2006-10-26 14:25:58 +00002797 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002798 }
drhc49f44e2006-10-26 18:15:42 +00002799 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002800 }
2801 free(zSql);
2802 zSql = 0;
2803 nSql = 0;
2804 }
2805 }
2806 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00002807 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002808 free(zSql);
2809 }
danielk19772ac27622007-07-03 05:31:16 +00002810 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002811 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002812}
2813
drh67505e72002-04-19 12:34:06 +00002814/*
2815** Return a pathname which is the user's home directory. A
2816** 0 return indicates an error of some kind. Space to hold the
2817** resulting string is obtained from malloc(). The calling
2818** function should free the result.
2819*/
2820static char *find_home_dir(void){
2821 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002822
chw97185482008-11-17 08:05:31 +00002823#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002824 struct passwd *pwent;
2825 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002826 if( (pwent=getpwuid(uid)) != NULL) {
2827 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002828 }
2829#endif
2830
chw65d3c132007-11-12 21:09:10 +00002831#if defined(_WIN32_WCE)
2832 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2833 */
2834 home_dir = strdup("/");
2835#else
2836
drh164a1b62006-08-19 11:15:20 +00002837#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2838 if (!home_dir) {
2839 home_dir = getenv("USERPROFILE");
2840 }
2841#endif
2842
drh67505e72002-04-19 12:34:06 +00002843 if (!home_dir) {
2844 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002845 }
2846
drhcdb36b72006-06-12 12:57:45 +00002847#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002848 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002849 char *zDrive, *zPath;
2850 int n;
2851 zDrive = getenv("HOMEDRIVE");
2852 zPath = getenv("HOMEPATH");
2853 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002854 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002855 home_dir = malloc( n );
2856 if( home_dir==0 ) return 0;
2857 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2858 return home_dir;
2859 }
2860 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002861 }
2862#endif
2863
chw65d3c132007-11-12 21:09:10 +00002864#endif /* !_WIN32_WCE */
2865
drh67505e72002-04-19 12:34:06 +00002866 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002867 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002868 char *z = malloc( n );
2869 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002870 home_dir = z;
2871 }
drhe98d4fa2002-04-21 19:06:22 +00002872
drh67505e72002-04-19 12:34:06 +00002873 return home_dir;
2874}
2875
2876/*
2877** Read input from the file given by sqliterc_override. Or if that
2878** parameter is NULL, take input from ~/.sqliterc
2879*/
drh22fbcb82004-02-01 01:22:50 +00002880static void process_sqliterc(
2881 struct callback_data *p, /* Configuration data */
2882 const char *sqliterc_override /* Name of config file. NULL to use default */
2883){
persicom7e2dfdd2002-04-18 02:46:52 +00002884 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002885 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002886 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002887 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002888 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002889
2890 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002891 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002892 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002893#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00002894 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00002895#endif
drhe98d4fa2002-04-21 19:06:22 +00002896 return;
2897 }
drh4f21c4a2008-12-10 22:15:00 +00002898 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002899 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002900 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002901 fprintf(stderr,"%s: out of memory!\n", Argv0);
2902 exit(1);
2903 }
drha959ac42007-06-20 13:10:00 +00002904 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002905 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002906 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002907 }
drha1f9b5e2004-02-14 16:31:02 +00002908 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002909 if( in ){
drhc28490c2006-10-26 14:25:58 +00002910 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00002911 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002912 }
persicom7e2dfdd2002-04-18 02:46:52 +00002913 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002914 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002915 }
drh43617e92006-03-06 20:55:46 +00002916 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00002917 return;
2918}
2919
drh67505e72002-04-19 12:34:06 +00002920/*
drhe1e38c42003-05-04 18:30:59 +00002921** Show available command line options
2922*/
2923static const char zOptions[] =
2924 " -init filename read/process named file\n"
2925 " -echo print commands before execution\n"
2926 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002927 " -bail stop after hitting an error\n"
2928 " -interactive force interactive I/O\n"
2929 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002930 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002931 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002932 " -html set output mode to HTML\n"
2933 " -line set output mode to 'line'\n"
2934 " -list set output mode to 'list'\n"
2935 " -separator 'x' set output field separator (|)\n"
2936 " -nullvalue 'text' set text string for NULL values\n"
2937 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002938;
2939static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002940 fprintf(stderr,
2941 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2942 "FILENAME is the name of an SQLite database. A new database is created\n"
2943 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002944 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002945 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002946 }else{
2947 fprintf(stderr, "Use the -help option for additional information\n");
2948 }
2949 exit(1);
2950}
2951
2952/*
drh67505e72002-04-19 12:34:06 +00002953** Initialize the state information in data
2954*/
drh0850b532006-01-31 19:31:43 +00002955static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002956 memset(data, 0, sizeof(*data));
2957 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002958 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002959 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00002960 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2961 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00002962}
2963
drh75897232000-05-29 14:26:00 +00002964int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002965 char *zErrMsg = 0;
2966 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002967 const char *zInitFile = 0;
2968 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002969 int i;
drhc28490c2006-10-26 14:25:58 +00002970 int rc = 0;
drh75897232000-05-29 14:26:00 +00002971
drhdaffd0e2001-04-11 14:28:42 +00002972 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002973 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002974 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002975
drh44c2eb12003-04-30 11:38:26 +00002976 /* Make sure we have a valid signal handler early, before anything
2977 ** else is done.
2978 */
drh4c504392000-10-16 22:06:40 +00002979#ifdef SIGINT
2980 signal(SIGINT, interrupt_handler);
2981#endif
drh44c2eb12003-04-30 11:38:26 +00002982
drh22fbcb82004-02-01 01:22:50 +00002983 /* Do an initial pass through the command-line argument to locate
2984 ** the name of the database file, the name of the initialization file,
2985 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002986 */
drh22fbcb82004-02-01 01:22:50 +00002987 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002988 char *z;
drh44c2eb12003-04-30 11:38:26 +00002989 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002990 z = argv[i];
2991 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002992 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2993 i++;
drh22fbcb82004-02-01 01:22:50 +00002994 }else if( strcmp(argv[i],"-init")==0 ){
2995 i++;
2996 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00002997 }
2998 }
drh22fbcb82004-02-01 01:22:50 +00002999 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00003000#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00003001 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
3002#else
drh22fbcb82004-02-01 01:22:50 +00003003 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00003004#endif
drh22fbcb82004-02-01 01:22:50 +00003005 }else{
danielk197703aded42004-11-22 05:26:27 +00003006#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003007 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003008#else
3009 data.zDbFilename = 0;
3010#endif
drh22fbcb82004-02-01 01:22:50 +00003011 }
3012 if( i<argc ){
3013 zFirstCmd = argv[i++];
3014 }
drh44c2eb12003-04-30 11:38:26 +00003015 data.out = stdout;
3016
drh01b41712005-08-29 23:06:23 +00003017#ifdef SQLITE_OMIT_MEMORYDB
3018 if( data.zDbFilename==0 ){
3019 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
3020 exit(1);
3021 }
3022#endif
3023
drh44c2eb12003-04-30 11:38:26 +00003024 /* Go ahead and open the database file if it already exists. If the
3025 ** file does not exist, delay opening it. This prevents empty database
3026 ** files from being created if a user mistypes the database name argument
3027 ** to the sqlite command-line tool.
3028 */
drhc8d74412004-08-31 23:41:26 +00003029 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003030 open_db(&data);
3031 }
3032
drh22fbcb82004-02-01 01:22:50 +00003033 /* Process the initialization file if there is one. If no -init option
3034 ** is given on the command line, look for a file named ~/.sqliterc and
3035 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003036 */
drh22fbcb82004-02-01 01:22:50 +00003037 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00003038
drh22fbcb82004-02-01 01:22:50 +00003039 /* Make a second pass through the command-line argument and set
3040 ** options. This second pass is delayed until after the initialization
3041 ** file is processed so that the command-line arguments will override
3042 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003043 */
drh22fbcb82004-02-01 01:22:50 +00003044 for(i=1; i<argc && argv[i][0]=='-'; i++){
3045 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00003046 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003047 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003048 i++;
3049 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003050 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003051 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003052 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003053 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003054 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003055 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003056 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003057 }else if( strcmp(z,"-csv")==0 ){
3058 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003059 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003060 }else if( strcmp(z,"-separator")==0 ){
3061 i++;
drh5bb3eb92007-05-04 13:15:55 +00003062 sqlite3_snprintf(sizeof(data.separator), data.separator,
3063 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003064 }else if( strcmp(z,"-nullvalue")==0 ){
3065 i++;
drh5bb3eb92007-05-04 13:15:55 +00003066 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
3067 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003068 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003069 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003070 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003071 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003072 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003073 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003074 }else if( strcmp(z,"-bail")==0 ){
3075 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003076 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00003077 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00003078 return 0;
drhc28490c2006-10-26 14:25:58 +00003079 }else if( strcmp(z,"-interactive")==0 ){
3080 stdin_is_interactive = 1;
3081 }else if( strcmp(z,"-batch")==0 ){
3082 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00003083 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003084 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00003085 }else{
drh22fbcb82004-02-01 01:22:50 +00003086 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003087 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003088 return 1;
3089 }
3090 }
drh44c2eb12003-04-30 11:38:26 +00003091
drh22fbcb82004-02-01 01:22:50 +00003092 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003093 /* Run just the command that follows the database name
3094 */
drh22fbcb82004-02-01 01:22:50 +00003095 if( zFirstCmd[0]=='.' ){
3096 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003097 exit(0);
3098 }else{
3099 int rc;
drh44c2eb12003-04-30 11:38:26 +00003100 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00003101 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00003102 if( rc!=0 && zErrMsg!=0 ){
3103 fprintf(stderr,"SQL error: %s\n", zErrMsg);
3104 exit(1);
3105 }
drh75897232000-05-29 14:26:00 +00003106 }
3107 }else{
drh44c2eb12003-04-30 11:38:26 +00003108 /* Run commands received from standard input
3109 */
drhc28490c2006-10-26 14:25:58 +00003110 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003111 char *zHome;
3112 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003113 int nHistory;
drh75897232000-05-29 14:26:00 +00003114 printf(
drhb217a572000-08-22 13:40:18 +00003115 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00003116 "Enter \".help\" for instructions\n"
3117 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00003118 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00003119 );
drh67505e72002-04-19 12:34:06 +00003120 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003121 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003122 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003123 if( (zHistory = malloc(nHistory))!=0 ){
3124 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3125 }
drh67505e72002-04-19 12:34:06 +00003126 }
danielk19774af00c62005-01-23 23:43:21 +00003127#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003128 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003129#endif
drhc28490c2006-10-26 14:25:58 +00003130 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003131 if( zHistory ){
3132 stifle_history(100);
3133 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003134 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003135 }
adamd0a3daa32006-07-28 20:16:14 +00003136 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00003137 }else{
drhc28490c2006-10-26 14:25:58 +00003138 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003139 }
3140 }
drh33048c02001-10-01 14:29:22 +00003141 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00003142 if( db ){
3143 if( sqlite3_close(db)!=SQLITE_OK ){
3144 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
3145 }
3146 }
drhc28490c2006-10-26 14:25:58 +00003147 return rc;
drh75897232000-05-29 14:26:00 +00003148}