1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-06 15:49:35 +03:00

Modify CLI to optionally display "stats".

FossilOrigin-Name: 419ce0ed89d10252492b2926817259899ee74e71
This commit is contained in:
shaneh
2010-07-28 16:05:34 +00:00
parent 39539804c6
commit 642d8b87fe
5 changed files with 281 additions and 31 deletions

View File

@@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Lookaside\smemory\sis\snot\sused\sto\sstore\sschemas.\s\sChange\sthe\nSQLITE_DBSATUS_SCHEMA_USED\sdocumentation\sto\sreflect\sthis\sfact.
D 2010-07-28T15:52:09
C Modify\sCLI\sto\soptionally\sdisplay\s"stats".
D 2010-07-28T16:05:35
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -172,7 +169,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 74fef1334bec27e606ef0b19e5c41cd0a639e69c
F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
F src/shell.c 74c82a4ecfd833900a5bacc5f32abd18b93079d1
F src/sqlite.h.in 373dedd8489ecd9dfb33d6d4378ee9f34a3c2386
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
F src/sqliteInt.h a9be6badc6cd6a3c1ae54475a98661cf351ecad5
@@ -826,9 +823,10 @@ F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/shell1.test a738c71bc08ea9162baee9a14b3cf9994f181921
F tool/shell1.test 930444cadb71ce9ce78bc6cd14ec21e6b69776ea
F tool/shell2.test 5dc76b8005b465f420fed8241621da7513060ff3
F tool/shell3.test 4fad469e8003938426355afdf34155f08c587836
F tool/shell4.test 0c82af2b7ce4e8e84565078a8690d1c46ec4e8f6
F tool/showdb.c 01c20e8181941b714fe07f72c64a7560fee17ff9
F tool/showjournal.c ec3b171be148656827c4949fbfb8ab4370822f87
F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9
@@ -841,14 +839,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P dbfbdb60c00b5aeae29c85acec0ae910b82dbdba
R db99aad6ade6f84bf548bac1cfdabd10
U drh
Z 87e1fd645b598e91788e82cf253f48fb
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFMUFIsoxKgR168RlERAicpAKCHH5v5EXtY/BOEo/lp30OkqVQK0wCgisZZ
js0Ce6xvYCx8PUpn/o0QZSQ=
=7PD/
-----END PGP SIGNATURE-----
P 07abfd5268564c18afd1074c2069d65c64f4b8eb
R 685d62477503a0184c458ad36031979f
U shaneh
Z 72eb3f2af1f8ca9f1cfbf340110562c7

View File

@@ -1 +1 @@
07abfd5268564c18afd1074c2069d65c64f4b8eb
419ce0ed89d10252492b2926817259899ee74e71

View File

@@ -398,6 +398,7 @@ struct previous_mode_data {
struct callback_data {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
int statsOn; /* True to display memory stats before each finalize */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
int mode; /* An output mode setting */
@@ -961,6 +962,86 @@ static char *save_err_msg(
return zErrMsg;
}
/*
** Display memory stats.
*/
static int display_stats(
sqlite3 *db, /* Database to query */
struct callback_data *pArg, /* Pointer to struct callback_data */
int bReset /* True to reset the stats */
){
int iCur;
int iHiwtr;
if( pArg && pArg->out ){
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Mem Used (Excludes Scratch/Pcache): %d (max %d) bytes\n", iCur, iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Number of Allocations: %d (max %d)\n", iCur, iHiwtr);
/*
** Not currently used by the CLI.
** iHiwtr = iCur = -1;
** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
*/
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
/*
** Not currently used by the CLI.
** iHiwtr = iCur = -1;
** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
*/
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
#ifdef YYTRACKMAXSTACKDEPTH
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
#endif
}
if( pArg && pArg->out && db ){
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Pcache Heap Usage: %d bytes\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
}
if( pArg && pArg->out && db && pArg->pStmt ){
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
fprintf(pArg->out, "Sort Operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
}
return 0;
}
/*
** Execute a statement or set of statements. Print
** any result rows/columns depending on the current mode
@@ -1000,10 +1081,16 @@ static int shell_exec(
continue;
}
/* save off the prepared statment handle and reset row count */
if( pArg ){
pArg->pStmt = pStmt;
pArg->cnt = 0;
}
/* echo the sql statement if echo on */
if( pArg->echoOn ){
if( pArg && pArg->echoOn ){
const char *zStmtSql = sqlite3_sql(pStmt);
fprintf(pArg->out,"%s\n", zStmtSql ? zStmtSql : zSql);
fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
}
/* perform the first step. this will tell us if we
@@ -1029,11 +1116,6 @@ static int shell_exec(
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
/* save off the prepared statment handle and reset row count */
if( pArg ){
pArg->pStmt = pStmt;
pArg->cnt = 0;
}
do{
/* extract the data and data types */
for(i=0; i<nCol; i++){
@@ -1056,9 +1138,6 @@ static int shell_exec(
}
} while( SQLITE_ROW == rc );
sqlite3_free(pData);
if( pArg ){
pArg->pStmt = NULL;
}
}
}else{
do{
@@ -1067,6 +1146,11 @@ static int shell_exec(
}
}
/* print usage stats if stats on */
if( pArg && pArg->statsOn ){
display_stats(db, pArg, 0);
}
/* Finalize the statement just executed. If this fails, save a
** copy of the error message. Otherwise, set zSql to point to the
** next statement to execute. */
@@ -1077,6 +1161,11 @@ static int shell_exec(
}else if( pzErrMsg ){
*pzErrMsg = save_err_msg(db);
}
/* clear saved stmt handle */
if( pArg ){
pArg->pStmt = NULL;
}
}
} /* end while */
@@ -1256,6 +1345,7 @@ static char zHelp[] =
" LIKE pattern TABLE.\n"
".separator STRING Change separator used by output mode and .import\n"
".show Show the current values for various settings\n"
".stats ON|OFF Turn stats on or off\n"
".tables ?TABLE? List names of tables\n"
" If TABLE specified, only list tables matching\n"
" LIKE pattern TABLE.\n"
@@ -2001,6 +2091,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
fprintf(p->out,"%9.9s: ", "separator");
output_c_string(p->out, p->separator);
fprintf(p->out, "\n");
fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
fprintf(p->out,"%9.9s: ","width");
for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
fprintf(p->out,"%d ",p->colWidth[i]);
@@ -2008,6 +2099,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
fprintf(p->out,"\n");
}else
if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
p->statsOn = booleanValue(azArg[1]);
}else
if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
char **azResult;
int nRow;
@@ -2391,6 +2486,7 @@ static const char zOptions[] =
" -line set output mode to 'line'\n"
" -list set output mode to 'list'\n"
" -separator 'x' set output field separator (|)\n"
" -stats print memory stats before each finalize\n"
" -nullvalue 'text' set text string for NULL values\n"
" -version show SQLite version\n"
;
@@ -2555,6 +2651,8 @@ int main(int argc, char **argv){
data.showHeader = 0;
}else if( strcmp(z,"-echo")==0 ){
data.echoOn = 1;
}else if( strcmp(z,"-stats")==0 ){
data.statsOn = 1;
}else if( strcmp(z,"-bail")==0 ){
bail_on_error = 1;
}else if( strcmp(z,"-version")==0 ){

View File

@@ -178,6 +178,11 @@ do_test shell1-1.14.3 {
[regexp {Error: missing argument for option: -separator} $res]
} {1 1}
# -stats print memory stats before each finalize
do_test shell1-1.14b.1 {
catchcmd "-stats test.db" ""
} {0 {}}
# -nullvalue 'text' set text string for NULL values
do_test shell1-1.15.1 {
catchcmd "-nullvalue 'x' test.db" ""
@@ -195,7 +200,7 @@ do_test shell1-1.15.3 {
# -version show SQLite version
do_test shell1-1.16.1 {
catchcmd "-version test.db" ""
} {0 3.7.0}
} {0 3.7.1}
#----------------------------------------------------------------------------
# Test cases shell1-2.*: Basic "dot" command token parsing.
@@ -621,13 +626,29 @@ do_test shell1-3.23.1 {
[regexp {nullvalue:} $res] \
[regexp {output:} $res] \
[regexp {separator:} $res] \
[regexp {stats:} $res] \
[regexp {width:} $res]
} {1 1 1 1 1 1 1 1}
} {1 1 1 1 1 1 1 1 1}
do_test shell1-3.23.2 {
# too many arguments
catchcmd "test.db" ".show BAD"
} {1 {Error: unknown command or invalid arguments: "show". Enter ".help" for help}}
# .stats ON|OFF Turn stats on or off
do_test shell1-3.23b.1 {
catchcmd "test.db" ".stats"
} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}}
do_test shell1-3.23b.2 {
catchcmd "test.db" ".stats ON"
} {0 {}}
do_test shell1-3.23b.3 {
catchcmd "test.db" ".stats OFF"
} {0 {}}
do_test shell1-3.23b.4 {
# too many arguments
catchcmd "test.db" ".stats OFF BAD"
} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}}
# .tables ?TABLE? List names of tables
# If TABLE specified, only list tables matching
# LIKE pattern TABLE.

140
tool/shell4.test Normal file
View File

@@ -0,0 +1,140 @@
# 2010 July 28
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of this file is testing the CLI shell tool.
#
# $Id: shell4.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $
#
# Test plan:
#
# shell4-1.*: Basic tests specific to the "stats" command.
#
package require sqlite3
set CLI "./sqlite3"
proc do_test {name cmd expected} {
puts -nonewline "$name ..."
set res [uplevel $cmd]
if {$res eq $expected} {
puts Ok
} else {
puts Error
puts " Got: $res"
puts " Expected: $expected"
exit
}
}
proc execsql {sql} {
uplevel [list db eval $sql]
}
proc catchsql {sql} {
set rc [catch {uplevel [list db eval $sql]} msg]
list $rc $msg
}
proc catchcmd {db {cmd ""}} {
global CLI
set out [open cmds.txt w]
puts $out $cmd
close $out
set line "exec $CLI $db < cmds.txt"
set rc [catch { eval $line } msg]
list $rc $msg
}
file delete -force test.db test.db.journal
sqlite3 db test.db
#----------------------------------------------------------------------------
# Test cases shell4-1.*: Tests specific to the "stats" command.
#
# should default to off
do_test shell4-1.1.1 {
set res [catchcmd "test.db" ".show"]
list [regexp {stats: off} $res]
} {1}
do_test shell4-1.1.2 {
set res [catchcmd "test.db" ".show"]
list [regexp {stats: on} $res]
} {0}
# -stats should turn it on
do_test shell4-1.2.1 {
set res [catchcmd "-stats test.db" ".show"]
list [regexp {stats: on} $res]
} {1}
do_test shell4-1.2.2 {
set res [catchcmd "-stats test.db" ".show"]
list [regexp {stats: off} $res]
} {0}
# .stats ON|OFF Turn stats on or off
do_test shell4-1.3.1 {
catchcmd "test.db" ".stats"
} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}}
do_test shell4-1.3.2 {
catchcmd "test.db" ".stats ON"
} {0 {}}
do_test shell4-1.3.3 {
catchcmd "test.db" ".stats OFF"
} {0 {}}
do_test shell4-1.3.4 {
# too many arguments
catchcmd "test.db" ".stats OFF BAD"
} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}}
# NB. whitespace is important
do_test shell4-1.4.1 {
set res [catchcmd "test.db" {.show}]
list [regexp {stats: off} $res]
} {1}
do_test shell4-1.4.2 {
set res [catchcmd "test.db" {.stats ON
.show
}]
list [regexp {stats: on} $res]
} {1}
do_test shell4-1.4.3 {
set res [catchcmd "test.db" {.stats OFF
.show
}]
list [regexp {stats: off} $res]
} {1}
# make sure stats not present when off
do_test shell4-1.5.1 {
set res [catchcmd "test.db" {SELECT 1;}]
list [regexp {Mem Used} $res] \
[regexp {Heap Usage} $res] \
[regexp {Autoindex Inserts} $res]
} {0 0 0}
# make sure stats are present when on
do_test shell4-1.5.2 {
set res [catchcmd "test.db" {.stats ON
SELECT 1;
}]
list [regexp {Mem Used} $res] \
[regexp {Heap Usage} $res] \
[regexp {Autoindex Inserts} $res]
} {1 1 1}
puts "CLI tests completed successfully"