Merge the command-line shell enhancements from trunk.
FossilOrigin-Name: c3931db560ab4a2601c7f7318fb02c8d5e6862b1
This commit is contained in:
commit
00dbc89824
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Revise\sthe\sway\sthat\sthe\sindex\sstructure\sfor\sa\sWITHOUT\sROWID\stable\sis\ndiscovered.
|
||||
D 2015-02-06T00:31:45.481
|
||||
C Merge\sthe\scommand-line\sshell\senhancements\sfrom\strunk.
|
||||
D 2015-02-06T15:03:45.342
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -246,7 +246,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c f6c46d3434439ab2084618d603e6d6dbeb0d6ada
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 1f2087523007c42900ffcbdeaef06a23ad9329fc
|
||||
F src/shell.c 22b4406b0b59efd14b3b351a5809dda517df6d30
|
||||
F src/shell.c 82c25508dac802b32198af6f5256ca1597c6a1af
|
||||
F src/sqlite.h.in 4807b024e8d257af774cde0cf178f721ff2406ec
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
@ -874,7 +874,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test cdeb849acc2c37aada70d084564b0cc0a2c7df08
|
||||
F test/shell1.test ca88b14a8fc8b1f3543a24e519d019585ac9c903
|
||||
F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862
|
||||
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
|
||||
F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
|
||||
@ -1255,7 +1255,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P a5e86bea4ad51bbb988a2a2215961706894f4a02
|
||||
R cf9fe799f99a90eb0a6f043505cb4c1a
|
||||
P 7f10a0eaf1fedfa020cbd7019ec9342ffdc3b9b0 0f65a7e2e09f801b66897479d501607caeae4abf
|
||||
R 1ef390b8e8775fda79ba88277a4a2044
|
||||
U drh
|
||||
Z c0c25c22927eb0667b2fe51c91fe6714
|
||||
Z f716caa3559c7f56ae8a7035846f96fb
|
||||
|
@ -1 +1 @@
|
||||
7f10a0eaf1fedfa020cbd7019ec9342ffdc3b9b0
|
||||
c3931db560ab4a2601c7f7318fb02c8d5e6862b1
|
123
src/shell.c
123
src/shell.c
@ -1733,6 +1733,7 @@ static char zHelp[] =
|
||||
".bail on|off Stop after hitting an error. Default OFF\n"
|
||||
".clone NEWDB Clone data into NEWDB from the existing database\n"
|
||||
".databases List names and files of attached databases\n"
|
||||
".dbinfo ?DB? Show status information about the database\n"
|
||||
".dump ?TABLE? ... Dump the database in an SQL text format\n"
|
||||
" If TABLE specified, only dump tables matching\n"
|
||||
" LIKE pattern TABLE.\n"
|
||||
@ -1745,8 +1746,8 @@ static char zHelp[] =
|
||||
".headers on|off Turn display of headers on or off\n"
|
||||
".help Show this message\n"
|
||||
".import FILE TABLE Import data from FILE into TABLE\n"
|
||||
".indices ?TABLE? Show names of all indices\n"
|
||||
" If TABLE specified, only show indices for tables\n"
|
||||
".indexes ?TABLE? Show names of all indexes\n"
|
||||
" If TABLE specified, only show indexes for tables\n"
|
||||
" matching LIKE pattern TABLE.\n"
|
||||
#ifdef SQLITE_ENABLE_IOTRACE
|
||||
".iotrace FILE Enable I/O diagnostic logging to FILE\n"
|
||||
@ -2426,6 +2427,115 @@ static void output_reset(ShellState *p){
|
||||
p->out = stdout;
|
||||
}
|
||||
|
||||
/*
|
||||
** Run an SQL command and return the single integer result.
|
||||
*/
|
||||
static int db_int(ShellState *p, const char *zSql){
|
||||
sqlite3_stmt *pStmt;
|
||||
int res = 0;
|
||||
sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
res = sqlite3_column_int(pStmt,0);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert a 2-byte or 4-byte big-endian integer into a native integer
|
||||
*/
|
||||
unsigned int get2byteInt(unsigned char *a){
|
||||
return (a[0]<<8) + a[1];
|
||||
}
|
||||
unsigned int get4byteInt(unsigned char *a){
|
||||
return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the ".info" command.
|
||||
**
|
||||
** Return 1 on error, 2 to exit, and 0 otherwise.
|
||||
*/
|
||||
static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
|
||||
static const struct { const char *zName; int ofst; } aField[] = {
|
||||
{ "file change counter:", 24 },
|
||||
{ "database page count:", 28 },
|
||||
{ "freelist page count:", 36 },
|
||||
{ "schema cookie:", 40 },
|
||||
{ "schema format:", 44 },
|
||||
{ "default cache size:", 48 },
|
||||
{ "autovacuum top root:", 52 },
|
||||
{ "incremental vacuum:", 64 },
|
||||
{ "text encoding:", 56 },
|
||||
{ "user version:", 60 },
|
||||
{ "application id:", 68 },
|
||||
{ "software version:", 96 },
|
||||
};
|
||||
static const struct { const char *zName; const char *zSql; } aQuery[] = {
|
||||
{ "number of tables:",
|
||||
"SELECT count(*) FROM %s WHERE type='table'" },
|
||||
{ "number of indexes:",
|
||||
"SELECT count(*) FROM %s WHERE type='index'" },
|
||||
{ "number of triggers:",
|
||||
"SELECT count(*) FROM %s WHERE type='trigger'" },
|
||||
{ "number of views:",
|
||||
"SELECT count(*) FROM %s WHERE type='view'" },
|
||||
{ "schema size:",
|
||||
"SELECT total(length(sql)) FROM %s" },
|
||||
};
|
||||
sqlite3_file *pFile;
|
||||
int i;
|
||||
char *zSchemaTab;
|
||||
char *zDb = nArg>=2 ? azArg[1] : "main";
|
||||
unsigned char aHdr[100];
|
||||
open_db(p, 0);
|
||||
if( p->db==0 ) return 1;
|
||||
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
|
||||
if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
|
||||
return 1;
|
||||
}
|
||||
i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
|
||||
if( i!=SQLITE_OK ){
|
||||
fprintf(stderr, "unable to read database header\n");
|
||||
return 1;
|
||||
}
|
||||
i = get2byteInt(aHdr+16);
|
||||
if( i==1 ) i = 65536;
|
||||
fprintf(p->out, "%-20s %d\n", "database page size:", i);
|
||||
fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
|
||||
fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
|
||||
fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
|
||||
for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
|
||||
int ofst = aField[i].ofst;
|
||||
unsigned int val = get4byteInt(aHdr + ofst);
|
||||
fprintf(p->out, "%-20s %u", aField[i].zName, val);
|
||||
switch( ofst ){
|
||||
case 56: {
|
||||
if( val==1 ) fprintf(p->out, " (utf8)");
|
||||
if( val==2 ) fprintf(p->out, " (utf16le)");
|
||||
if( val==3 ) fprintf(p->out, " (utf16be)");
|
||||
}
|
||||
}
|
||||
fprintf(p->out, "\n");
|
||||
}
|
||||
if( zDb==0 ){
|
||||
zSchemaTab = sqlite3_mprintf("main.sqlite_master");
|
||||
}else if( strcmp(zDb,"temp")==0 ){
|
||||
zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
|
||||
}else{
|
||||
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
|
||||
}
|
||||
for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
|
||||
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
|
||||
int val = db_int(p, zSql);
|
||||
sqlite3_free(zSql);
|
||||
fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
|
||||
}
|
||||
sqlite3_free(zSchemaTab);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** If an input line begins with "." then invoke this routine to
|
||||
** process that line.
|
||||
@ -2568,6 +2678,10 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
|
||||
rc = shell_dbinfo_command(p, nArg, azArg);
|
||||
}else
|
||||
|
||||
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
|
||||
open_db(p, 0);
|
||||
/* When playing back a "dump", the content might appear in an order
|
||||
@ -2936,7 +3050,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
}else
|
||||
|
||||
if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
|
||||
if( c=='i' && (strncmp(azArg[0], "indices", n)==0
|
||||
|| strncmp(azArg[0], "indexes", n)==0) ){
|
||||
ShellState data;
|
||||
char *zErrMsg = 0;
|
||||
open_db(p, 0);
|
||||
@ -2966,7 +3081,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
);
|
||||
zShellStatic = 0;
|
||||
}else{
|
||||
fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
|
||||
fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
|
@ -406,19 +406,22 @@ do_test shell1-3.11.3 {
|
||||
catchcmd "test.db" ".import FOO BAR BAD"
|
||||
} {1 {Usage: .import FILE TABLE}}
|
||||
|
||||
# .indices ?TABLE? Show names of all indices
|
||||
# If TABLE specified, only show indices for tables
|
||||
# .indexes ?TABLE? Show names of all indexes
|
||||
# If TABLE specified, only show indexes for tables
|
||||
# matching LIKE pattern TABLE.
|
||||
do_test shell1-3.12.1 {
|
||||
catchcmd "test.db" ".indices"
|
||||
catchcmd "test.db" ".indexes"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.2 {
|
||||
catchcmd "test.db" ".indexes FOO"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.2-legacy {
|
||||
catchcmd "test.db" ".indices FOO"
|
||||
} {0 {}}
|
||||
do_test shell1-3.12.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".indices FOO BAD"
|
||||
} {1 {Usage: .indices ?LIKE-PATTERN?}}
|
||||
catchcmd "test.db" ".indexes FOO BAD"
|
||||
} {1 {Usage: .indexes ?LIKE-PATTERN?}}
|
||||
|
||||
# .mode MODE ?TABLE? Set output mode where MODE is one of:
|
||||
# ascii Columns/rows delimited by 0x1F and 0x1E
|
||||
|
Loading…
x
Reference in New Issue
Block a user