From 45e29d8a1e656b602b83d9e82beeebb8ad2e1eae Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Nov 2006 16:21:10 +0000 Subject: [PATCH] Fix the ".dump" command in the shell. Ticket #2072. Also ticket #2065. (CVS 3515) FossilOrigin-Name: 9fdc249609a4745715a2bf49bbf1376ea243a20a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 49 +++++++++++++++++++++++++++++++++---------------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index abfb3a6c9e..5ad991f355 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sVACUUM\scleans\sup\safter\sitself.\s\sTicket\s#2071.\s(CVS\s3514) -D 2006-11-18T20:20:22 +C Fix\sthe\s".dump"\scommand\sin\sthe\sshell.\s\sTicket\s#2072.\s\sAlso\sticket\s#2065.\s(CVS\s3515) +D 2006-11-20T16:21:10 F Makefile.in 8e14898d41a53033ecb687d93c9cd5d109fb9ae3 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -94,7 +94,7 @@ F src/printf.c b179b6ed12f793e028dd169e2e2e2b2a37eedc63 F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261 F src/select.c 6ba6d8ead43d0575ce1f8b418cc039f8f301389a F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 -F src/shell.c 41513f31dce4252198944c712b79ea4c92df2592 +F src/shell.c 934cdcf67eccee6f5c1be87c98a477a2e263db3c F src/sqlite.h.in 2931f7ee2415e7a49fd12f386c23575046f0f540 F src/sqlite3ext.h 2c2156cc32a158e2b7bd9042d42accf94bff2e40 F src/sqliteInt.h f6bac44ee7b8ee2614b046974551c22999ec674f @@ -421,7 +421,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P f6e0b080dcfaf554b2c05df5e7d4db69d012fba3 -R ad774b2735ecc59c61fa373df002cbdb +P 2fdc147d0059dcdfff2da33bd9fedb0bee057aa1 +R 794dc2fbb3e0e83e5207db81c11bb327 U drh -Z bebd3b34dccaadcb360a71274b94137f +Z 79a147f5026204797ae394029f543a2e diff --git a/manifest.uuid b/manifest.uuid index 78faf40c94..2bc88a14bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2fdc147d0059dcdfff2da33bd9fedb0bee057aa1 \ No newline at end of file +9fdc249609a4745715a2bf49bbf1376ea243a20a \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 1b59788600..6f651350a6 100644 --- a/src/shell.c +++ b/src/shell.c @@ -12,7 +12,7 @@ ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** -** $Id: shell.c,v 1.155 2006/11/08 12:25:43 drh Exp $ +** $Id: shell.c,v 1.156 2006/11/20 16:21:10 drh Exp $ */ #include #include @@ -225,6 +225,7 @@ struct previous_mode_data { int showHeader; int colWidth[100]; }; + /* ** An pointer to an instance of this structure is passed from ** the main program to the callback. This is used to communicate @@ -236,6 +237,7 @@ struct callback_data { int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ int mode; /* An output mode setting */ + int writableSchema; /* True if PRAGMA writable_schema=ON */ int showHeader; /* True to show column names in List or Column mode */ char *zDestTable; /* Name of destination table when MODE_Insert */ char separator[20]; /* Separator character for MODE_List */ @@ -675,6 +677,9 @@ static char *appendText(char *zIn, char const *zAppend, char quote){ /* ** Execute a query statement that has a single result column. Print ** that result column on a line by itself with a semicolon terminator. +** +** This is used, for example, to show the schema of the database by +** querying the SQLITE_MASTER table. */ static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){ sqlite3_stmt *pSelect; @@ -716,6 +721,19 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ fprintf(p->out, "ANALYZE sqlite_master;\n"); }else if( strncmp(zTable, "sqlite_", 7)==0 ){ return 0; + }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ + char *zIns; + if( !p->writableSchema ){ + fprintf(p->out, "PRAGMA writable_schema=ON;\n"); + p->writableSchema = 1; + } + zIns = sqlite3_mprintf( + "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','%q','%q',0,'%q');", + zTable, zTable, zSql); + fprintf(p->out, "%s\n", zIns); + sqlite3_free(zIns); + return 0; }else{ fprintf(p->out, "%s;\n", zSql); } @@ -749,7 +767,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ zSelect = appendText(zSelect, zText, '"'); rc = sqlite3_step(pTableInfo); if( rc==SQLITE_ROW ){ - zSelect = appendText(zSelect, ") || ', ' || ", 0); + zSelect = appendText(zSelect, ") || ',' || ", 0); }else{ zSelect = appendText(zSelect, ") ", 0); } @@ -773,7 +791,9 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ } /* -** Run zQuery. Update dump_callback() as the callback routine. +** Run zQuery. Use dump_callback() as the callback routine so that +** the contents of the query are output as SQL statements. +** ** If we get a SQLITE_CORRUPT error, rerun the query after appending ** "ORDER BY rowid DESC" to the end. */ @@ -979,19 +999,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){ char *zErrMsg = 0; open_db(p); fprintf(p->out, "BEGIN TRANSACTION;\n"); + p->writableSchema = 0; if( nArg==1 ){ run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type=='table' AND rootpage!=0", 0 - ); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND " - " AND type!='table' AND type!='meta'", 0 + "WHERE sql NOT NULL AND type=='table'", 0 ); run_table_dump_query(p->out, p->db, "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL AND rootpage==0" + "WHERE sql NOT NULL AND type IN ('index','trigger','view')" ); }else{ int i; @@ -1000,19 +1016,20 @@ static int do_meta_command(char *zLine, struct callback_data *p){ run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE tbl_name LIKE shellstatic() AND type=='table'" - " AND rootpage!=0 AND sql NOT NULL", 0); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE tbl_name LIKE shellstatic() AND type!='table'" - " AND type!='meta' AND sql NOT NULL", 0); + " AND sql NOT NULL", 0); run_table_dump_query(p->out, p->db, "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL AND rootpage==0" + "WHERE sql NOT NULL" + " AND type IN ('index','trigger','view')" " AND tbl_name LIKE shellstatic()" ); zShellStatic = 0; } } + if( p->writableSchema ){ + fprintf(p->out, "PRAGMA writable_schema=OFF;\n"); + p->writableSchema = 0; + } if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg);