Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Take over latest shell.c, but without SQLITE_TESTCTRL_IMPOSTER support (included SQLite doesn't have that yet). Reason: add '.dbinfo' command to "fossil sqlite" [http://www.sqlite.org/src/info/0f65a7e2e09f801b|0f65a7e2e0] and fix bug in '.import' [http://www.sqlite.org/src/info/9c5bcad1f7d04c16|9c5bcad1] |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
d96488860f5a855908a33edd2018f8f3 |
| User & Date: | jan.nijtmans 2015-02-13 09:00:51.713 |
Context
|
2015-02-13
| ||
| 09:03 | A few more places where displayed UUID length should be configurable. check-in: c62e94f8a3 user: jan.nijtmans tags: trunk | |
| 09:00 | Take over latest shell.c, but without SQLITE_TESTCTRL_IMPOSTER support (included SQLite doesn't have that yet). Reason: add '.dbinfo' command to "fossil sqlite" [http://www.sqlite.org/src/info/0f65a7e2e09f801b|0f65a7e2e0] and fix bug in '.import' [http://www.sqlite.org/src/info/9c5bcad1f7d04c16|9c5bcad1] check-in: d96488860f user: jan.nijtmans tags: trunk | |
| 02:36 | Add the "hash-digits" setting for controling the number of digits of the SHA1 hash to display in output intended for humans. The minimum is 6 and the default is 10. Compile-time option FOSSIL_HASH_DIGITS can set a different default. URLs use at least 6 more digits than human output. Compile-time option FOSSIL_HASH_DIGITS_URL sets a lower-bound on the number of hash digits in URLs. check-in: cc94bd078e user: drh tags: trunk | |
Changes
Changes to src/shell.c.
| ︙ | ︙ | |||
1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 | ** Text of a help message */ static char zHelp[] = ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".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" ".dump ?TABLE? ... Dump the database in an SQL text format\n" " If TABLE specified, only dump tables matching\n" " LIKE pattern TABLE.\n" ".echo on|off Turn command echo on or off\n" ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n" ".exit Exit this program\n" ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n" " With no args, it turns EXPLAIN on.\n" ".fullschema Show schema and the content of sqlite_stat tables\n" ".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" | > | | | 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 | ** Text of a help message */ static char zHelp[] = ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".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" ".echo on|off Turn command echo on or off\n" ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n" ".exit Exit this program\n" ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n" " With no args, it turns EXPLAIN on.\n" ".fullschema Show schema and the content of sqlite_stat tables\n" ".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" ".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" #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION ".load FILE ?ENTRY? Load an extension library\n" #endif |
| ︙ | ︙ | |||
2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 |
pclose(p->out);
}else{
output_file_close(p->out);
}
p->outfile[0] = 0;
p->out = stdout;
}
/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 |
pclose(p->out);
}else{
output_file_close(p->out);
}
p->outfile[0] = 0;
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.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
|
| ︙ | ︙ | |||
2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 |
sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
if( zErrMsg ){
fprintf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
}
}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
** which causes immediate foreign key constraints to be violated.
** So disable foreign-key constraint enforcement to prevent problems. */
if( nArg!=1 && nArg!=2 ){
| > > > > | 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 |
sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
if( zErrMsg ){
fprintf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
}
}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
** which causes immediate foreign key constraints to be violated.
** So disable foreign-key constraint enforcement to prevent problems. */
if( nArg!=1 && nArg!=2 ){
|
| ︙ | ︙ | |||
2914 2915 2916 2917 2918 2919 2920 |
*/
if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
fprintf(stderr, "%s:%d: expected %d columns but found %d - "
"filling the rest with NULL\n",
sCtx.zFile, startLine, nCol, i+1);
| | | 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 |
*/
if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
fprintf(stderr, "%s:%d: expected %d columns but found %d - "
"filling the rest with NULL\n",
sCtx.zFile, startLine, nCol, i+1);
i += 2;
while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
}
}
if( sCtx.cTerm==sCtx.cColSep ){
do{
xRead(&sCtx);
i++;
|
| ︙ | ︙ | |||
2943 2944 2945 2946 2947 2948 2949 |
xCloser(sCtx.in);
sqlite3_free(sCtx.z);
sqlite3_finalize(pStmt);
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
}else
| | > | 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 |
xCloser(sCtx.in);
sqlite3_free(sCtx.z);
sqlite3_finalize(pStmt);
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
}else
if( c=='i' && (strncmp(azArg[0], "indices", n)==0
|| strncmp(azArg[0], "indexes", n)==0) ){
ShellState data;
char *zErrMsg = 0;
open_db(p, 0);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.mode = MODE_List;
if( nArg==1 ){
|
| ︙ | ︙ | |||
2973 2974 2975 2976 2977 2978 2979 |
"SELECT name FROM sqlite_temp_master "
"WHERE type='index' AND tbl_name LIKE shellstatic() "
"ORDER BY 1",
callback, &data, &zErrMsg
);
zShellStatic = 0;
}else{
| | | 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 |
"SELECT name FROM sqlite_temp_master "
"WHERE type='index' AND tbl_name LIKE shellstatic() "
"ORDER BY 1",
callback, &data, &zErrMsg
);
zShellStatic = 0;
}else{
fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
rc = 1;
goto meta_command_exit;
}
if( zErrMsg ){
fprintf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
|
| ︙ | ︙ |