Fossil SCM
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]
Commit
d96488860f5a855908a33edd2018f8f3d3c0dde0
Parent
cc94bd078e322b6…
1 file changed
+120
-5
+120
-5
| --- src/shell.c | ||
| +++ src/shell.c | ||
| @@ -1742,10 +1742,11 @@ | ||
| 1742 | 1742 | static char zHelp[] = |
| 1743 | 1743 | ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" |
| 1744 | 1744 | ".bail on|off Stop after hitting an error. Default OFF\n" |
| 1745 | 1745 | ".clone NEWDB Clone data into NEWDB from the existing database\n" |
| 1746 | 1746 | ".databases List names and files of attached databases\n" |
| 1747 | + ".dbinfo ?DB? Show status information about the database\n" | |
| 1747 | 1748 | ".dump ?TABLE? ... Dump the database in an SQL text format\n" |
| 1748 | 1749 | " If TABLE specified, only dump tables matching\n" |
| 1749 | 1750 | " LIKE pattern TABLE.\n" |
| 1750 | 1751 | ".echo on|off Turn command echo on or off\n" |
| 1751 | 1752 | ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n" |
| @@ -1754,12 +1755,12 @@ | ||
| 1754 | 1755 | " With no args, it turns EXPLAIN on.\n" |
| 1755 | 1756 | ".fullschema Show schema and the content of sqlite_stat tables\n" |
| 1756 | 1757 | ".headers on|off Turn display of headers on or off\n" |
| 1757 | 1758 | ".help Show this message\n" |
| 1758 | 1759 | ".import FILE TABLE Import data from FILE into TABLE\n" |
| 1759 | - ".indices ?TABLE? Show names of all indices\n" | |
| 1760 | - " If TABLE specified, only show indices for tables\n" | |
| 1760 | + ".indexes ?TABLE? Show names of all indexes\n" | |
| 1761 | + " If TABLE specified, only show indexes for tables\n" | |
| 1761 | 1762 | " matching LIKE pattern TABLE.\n" |
| 1762 | 1763 | #ifdef SQLITE_ENABLE_IOTRACE |
| 1763 | 1764 | ".iotrace FILE Enable I/O diagnostic logging to FILE\n" |
| 1764 | 1765 | #endif |
| 1765 | 1766 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| @@ -2434,10 +2435,119 @@ | ||
| 2434 | 2435 | output_file_close(p->out); |
| 2435 | 2436 | } |
| 2436 | 2437 | p->outfile[0] = 0; |
| 2437 | 2438 | p->out = stdout; |
| 2438 | 2439 | } |
| 2440 | + | |
| 2441 | +/* | |
| 2442 | +** Run an SQL command and return the single integer result. | |
| 2443 | +*/ | |
| 2444 | +static int db_int(ShellState *p, const char *zSql){ | |
| 2445 | + sqlite3_stmt *pStmt; | |
| 2446 | + int res = 0; | |
| 2447 | + sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 2448 | + if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 2449 | + res = sqlite3_column_int(pStmt,0); | |
| 2450 | + } | |
| 2451 | + sqlite3_finalize(pStmt); | |
| 2452 | + return res; | |
| 2453 | +} | |
| 2454 | + | |
| 2455 | +/* | |
| 2456 | +** Convert a 2-byte or 4-byte big-endian integer into a native integer | |
| 2457 | +*/ | |
| 2458 | +unsigned int get2byteInt(unsigned char *a){ | |
| 2459 | + return (a[0]<<8) + a[1]; | |
| 2460 | +} | |
| 2461 | +unsigned int get4byteInt(unsigned char *a){ | |
| 2462 | + return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; | |
| 2463 | +} | |
| 2464 | + | |
| 2465 | +/* | |
| 2466 | +** Implementation of the ".info" command. | |
| 2467 | +** | |
| 2468 | +** Return 1 on error, 2 to exit, and 0 otherwise. | |
| 2469 | +*/ | |
| 2470 | +static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ | |
| 2471 | + static const struct { const char *zName; int ofst; } aField[] = { | |
| 2472 | + { "file change counter:", 24 }, | |
| 2473 | + { "database page count:", 28 }, | |
| 2474 | + { "freelist page count:", 36 }, | |
| 2475 | + { "schema cookie:", 40 }, | |
| 2476 | + { "schema format:", 44 }, | |
| 2477 | + { "default cache size:", 48 }, | |
| 2478 | + { "autovacuum top root:", 52 }, | |
| 2479 | + { "incremental vacuum:", 64 }, | |
| 2480 | + { "text encoding:", 56 }, | |
| 2481 | + { "user version:", 60 }, | |
| 2482 | + { "application id:", 68 }, | |
| 2483 | + { "software version:", 96 }, | |
| 2484 | + }; | |
| 2485 | + static const struct { const char *zName; const char *zSql; } aQuery[] = { | |
| 2486 | + { "number of tables:", | |
| 2487 | + "SELECT count(*) FROM %s WHERE type='table'" }, | |
| 2488 | + { "number of indexes:", | |
| 2489 | + "SELECT count(*) FROM %s WHERE type='index'" }, | |
| 2490 | + { "number of triggers:", | |
| 2491 | + "SELECT count(*) FROM %s WHERE type='trigger'" }, | |
| 2492 | + { "number of views:", | |
| 2493 | + "SELECT count(*) FROM %s WHERE type='view'" }, | |
| 2494 | + { "schema size:", | |
| 2495 | + "SELECT total(length(sql)) FROM %s" }, | |
| 2496 | + }; | |
| 2497 | + sqlite3_file *pFile; | |
| 2498 | + int i; | |
| 2499 | + char *zSchemaTab; | |
| 2500 | + char *zDb = nArg>=2 ? azArg[1] : "main"; | |
| 2501 | + unsigned char aHdr[100]; | |
| 2502 | + open_db(p, 0); | |
| 2503 | + if( p->db==0 ) return 1; | |
| 2504 | + sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); | |
| 2505 | + if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ | |
| 2506 | + return 1; | |
| 2507 | + } | |
| 2508 | + i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); | |
| 2509 | + if( i!=SQLITE_OK ){ | |
| 2510 | + fprintf(stderr, "unable to read database header\n"); | |
| 2511 | + return 1; | |
| 2512 | + } | |
| 2513 | + i = get2byteInt(aHdr+16); | |
| 2514 | + if( i==1 ) i = 65536; | |
| 2515 | + fprintf(p->out, "%-20s %d\n", "database page size:", i); | |
| 2516 | + fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); | |
| 2517 | + fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); | |
| 2518 | + fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); | |
| 2519 | + for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){ | |
| 2520 | + int ofst = aField[i].ofst; | |
| 2521 | + unsigned int val = get4byteInt(aHdr + ofst); | |
| 2522 | + fprintf(p->out, "%-20s %u", aField[i].zName, val); | |
| 2523 | + switch( ofst ){ | |
| 2524 | + case 56: { | |
| 2525 | + if( val==1 ) fprintf(p->out, " (utf8)"); | |
| 2526 | + if( val==2 ) fprintf(p->out, " (utf16le)"); | |
| 2527 | + if( val==3 ) fprintf(p->out, " (utf16be)"); | |
| 2528 | + } | |
| 2529 | + } | |
| 2530 | + fprintf(p->out, "\n"); | |
| 2531 | + } | |
| 2532 | + if( zDb==0 ){ | |
| 2533 | + zSchemaTab = sqlite3_mprintf("main.sqlite_master"); | |
| 2534 | + }else if( strcmp(zDb,"temp")==0 ){ | |
| 2535 | + zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master"); | |
| 2536 | + }else{ | |
| 2537 | + zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); | |
| 2538 | + } | |
| 2539 | + for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){ | |
| 2540 | + char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); | |
| 2541 | + int val = db_int(p, zSql); | |
| 2542 | + sqlite3_free(zSql); | |
| 2543 | + fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); | |
| 2544 | + } | |
| 2545 | + sqlite3_free(zSchemaTab); | |
| 2546 | + return 0; | |
| 2547 | +} | |
| 2548 | + | |
| 2439 | 2549 | |
| 2440 | 2550 | /* |
| 2441 | 2551 | ** If an input line begins with "." then invoke this routine to |
| 2442 | 2552 | ** process that line. |
| 2443 | 2553 | ** |
| @@ -2576,10 +2686,14 @@ | ||
| 2576 | 2686 | fprintf(stderr,"Error: %s\n", zErrMsg); |
| 2577 | 2687 | sqlite3_free(zErrMsg); |
| 2578 | 2688 | rc = 1; |
| 2579 | 2689 | } |
| 2580 | 2690 | }else |
| 2691 | + | |
| 2692 | + if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ | |
| 2693 | + rc = shell_dbinfo_command(p, nArg, azArg); | |
| 2694 | + }else | |
| 2581 | 2695 | |
| 2582 | 2696 | if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ |
| 2583 | 2697 | open_db(p, 0); |
| 2584 | 2698 | /* When playing back a "dump", the content might appear in an order |
| 2585 | 2699 | ** which causes immediate foreign key constraints to be violated. |
| @@ -2916,11 +3030,11 @@ | ||
| 2916 | 3030 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 2917 | 3031 | if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ |
| 2918 | 3032 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2919 | 3033 | "filling the rest with NULL\n", |
| 2920 | 3034 | sCtx.zFile, startLine, nCol, i+1); |
| 2921 | - i++; | |
| 3035 | + i += 2; | |
| 2922 | 3036 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 2923 | 3037 | } |
| 2924 | 3038 | } |
| 2925 | 3039 | if( sCtx.cTerm==sCtx.cColSep ){ |
| 2926 | 3040 | do{ |
| @@ -2945,11 +3059,12 @@ | ||
| 2945 | 3059 | sqlite3_free(sCtx.z); |
| 2946 | 3060 | sqlite3_finalize(pStmt); |
| 2947 | 3061 | if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 2948 | 3062 | }else |
| 2949 | 3063 | |
| 2950 | - if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ | |
| 3064 | + if( c=='i' && (strncmp(azArg[0], "indices", n)==0 | |
| 3065 | + || strncmp(azArg[0], "indexes", n)==0) ){ | |
| 2951 | 3066 | ShellState data; |
| 2952 | 3067 | char *zErrMsg = 0; |
| 2953 | 3068 | open_db(p, 0); |
| 2954 | 3069 | memcpy(&data, p, sizeof(data)); |
| 2955 | 3070 | data.showHeader = 0; |
| @@ -2975,11 +3090,11 @@ | ||
| 2975 | 3090 | "ORDER BY 1", |
| 2976 | 3091 | callback, &data, &zErrMsg |
| 2977 | 3092 | ); |
| 2978 | 3093 | zShellStatic = 0; |
| 2979 | 3094 | }else{ |
| 2980 | - fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n"); | |
| 3095 | + fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); | |
| 2981 | 3096 | rc = 1; |
| 2982 | 3097 | goto meta_command_exit; |
| 2983 | 3098 | } |
| 2984 | 3099 | if( zErrMsg ){ |
| 2985 | 3100 | fprintf(stderr,"Error: %s\n", zErrMsg); |
| 2986 | 3101 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -1742,10 +1742,11 @@ | |
| 1742 | static char zHelp[] = |
| 1743 | ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" |
| 1744 | ".bail on|off Stop after hitting an error. Default OFF\n" |
| 1745 | ".clone NEWDB Clone data into NEWDB from the existing database\n" |
| 1746 | ".databases List names and files of attached databases\n" |
| 1747 | ".dump ?TABLE? ... Dump the database in an SQL text format\n" |
| 1748 | " If TABLE specified, only dump tables matching\n" |
| 1749 | " LIKE pattern TABLE.\n" |
| 1750 | ".echo on|off Turn command echo on or off\n" |
| 1751 | ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n" |
| @@ -1754,12 +1755,12 @@ | |
| 1754 | " With no args, it turns EXPLAIN on.\n" |
| 1755 | ".fullschema Show schema and the content of sqlite_stat tables\n" |
| 1756 | ".headers on|off Turn display of headers on or off\n" |
| 1757 | ".help Show this message\n" |
| 1758 | ".import FILE TABLE Import data from FILE into TABLE\n" |
| 1759 | ".indices ?TABLE? Show names of all indices\n" |
| 1760 | " If TABLE specified, only show indices for tables\n" |
| 1761 | " matching LIKE pattern TABLE.\n" |
| 1762 | #ifdef SQLITE_ENABLE_IOTRACE |
| 1763 | ".iotrace FILE Enable I/O diagnostic logging to FILE\n" |
| 1764 | #endif |
| 1765 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| @@ -2434,10 +2435,119 @@ | |
| 2434 | output_file_close(p->out); |
| 2435 | } |
| 2436 | p->outfile[0] = 0; |
| 2437 | p->out = stdout; |
| 2438 | } |
| 2439 | |
| 2440 | /* |
| 2441 | ** If an input line begins with "." then invoke this routine to |
| 2442 | ** process that line. |
| 2443 | ** |
| @@ -2576,10 +2686,14 @@ | |
| 2576 | fprintf(stderr,"Error: %s\n", zErrMsg); |
| 2577 | sqlite3_free(zErrMsg); |
| 2578 | rc = 1; |
| 2579 | } |
| 2580 | }else |
| 2581 | |
| 2582 | if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ |
| 2583 | open_db(p, 0); |
| 2584 | /* When playing back a "dump", the content might appear in an order |
| 2585 | ** which causes immediate foreign key constraints to be violated. |
| @@ -2916,11 +3030,11 @@ | |
| 2916 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 2917 | if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ |
| 2918 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2919 | "filling the rest with NULL\n", |
| 2920 | sCtx.zFile, startLine, nCol, i+1); |
| 2921 | i++; |
| 2922 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 2923 | } |
| 2924 | } |
| 2925 | if( sCtx.cTerm==sCtx.cColSep ){ |
| 2926 | do{ |
| @@ -2945,11 +3059,12 @@ | |
| 2945 | sqlite3_free(sCtx.z); |
| 2946 | sqlite3_finalize(pStmt); |
| 2947 | if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 2948 | }else |
| 2949 | |
| 2950 | if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ |
| 2951 | ShellState data; |
| 2952 | char *zErrMsg = 0; |
| 2953 | open_db(p, 0); |
| 2954 | memcpy(&data, p, sizeof(data)); |
| 2955 | data.showHeader = 0; |
| @@ -2975,11 +3090,11 @@ | |
| 2975 | "ORDER BY 1", |
| 2976 | callback, &data, &zErrMsg |
| 2977 | ); |
| 2978 | zShellStatic = 0; |
| 2979 | }else{ |
| 2980 | fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n"); |
| 2981 | rc = 1; |
| 2982 | goto meta_command_exit; |
| 2983 | } |
| 2984 | if( zErrMsg ){ |
| 2985 | fprintf(stderr,"Error: %s\n", zErrMsg); |
| 2986 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -1742,10 +1742,11 @@ | |
| 1742 | static char zHelp[] = |
| 1743 | ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" |
| 1744 | ".bail on|off Stop after hitting an error. Default OFF\n" |
| 1745 | ".clone NEWDB Clone data into NEWDB from the existing database\n" |
| 1746 | ".databases List names and files of attached databases\n" |
| 1747 | ".dbinfo ?DB? Show status information about the database\n" |
| 1748 | ".dump ?TABLE? ... Dump the database in an SQL text format\n" |
| 1749 | " If TABLE specified, only dump tables matching\n" |
| 1750 | " LIKE pattern TABLE.\n" |
| 1751 | ".echo on|off Turn command echo on or off\n" |
| 1752 | ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n" |
| @@ -1754,12 +1755,12 @@ | |
| 1755 | " With no args, it turns EXPLAIN on.\n" |
| 1756 | ".fullschema Show schema and the content of sqlite_stat tables\n" |
| 1757 | ".headers on|off Turn display of headers on or off\n" |
| 1758 | ".help Show this message\n" |
| 1759 | ".import FILE TABLE Import data from FILE into TABLE\n" |
| 1760 | ".indexes ?TABLE? Show names of all indexes\n" |
| 1761 | " If TABLE specified, only show indexes for tables\n" |
| 1762 | " matching LIKE pattern TABLE.\n" |
| 1763 | #ifdef SQLITE_ENABLE_IOTRACE |
| 1764 | ".iotrace FILE Enable I/O diagnostic logging to FILE\n" |
| 1765 | #endif |
| 1766 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| @@ -2434,10 +2435,119 @@ | |
| 2435 | output_file_close(p->out); |
| 2436 | } |
| 2437 | p->outfile[0] = 0; |
| 2438 | p->out = stdout; |
| 2439 | } |
| 2440 | |
| 2441 | /* |
| 2442 | ** Run an SQL command and return the single integer result. |
| 2443 | */ |
| 2444 | static int db_int(ShellState *p, const char *zSql){ |
| 2445 | sqlite3_stmt *pStmt; |
| 2446 | int res = 0; |
| 2447 | sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2448 | if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 2449 | res = sqlite3_column_int(pStmt,0); |
| 2450 | } |
| 2451 | sqlite3_finalize(pStmt); |
| 2452 | return res; |
| 2453 | } |
| 2454 | |
| 2455 | /* |
| 2456 | ** Convert a 2-byte or 4-byte big-endian integer into a native integer |
| 2457 | */ |
| 2458 | unsigned int get2byteInt(unsigned char *a){ |
| 2459 | return (a[0]<<8) + a[1]; |
| 2460 | } |
| 2461 | unsigned int get4byteInt(unsigned char *a){ |
| 2462 | return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; |
| 2463 | } |
| 2464 | |
| 2465 | /* |
| 2466 | ** Implementation of the ".info" command. |
| 2467 | ** |
| 2468 | ** Return 1 on error, 2 to exit, and 0 otherwise. |
| 2469 | */ |
| 2470 | static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ |
| 2471 | static const struct { const char *zName; int ofst; } aField[] = { |
| 2472 | { "file change counter:", 24 }, |
| 2473 | { "database page count:", 28 }, |
| 2474 | { "freelist page count:", 36 }, |
| 2475 | { "schema cookie:", 40 }, |
| 2476 | { "schema format:", 44 }, |
| 2477 | { "default cache size:", 48 }, |
| 2478 | { "autovacuum top root:", 52 }, |
| 2479 | { "incremental vacuum:", 64 }, |
| 2480 | { "text encoding:", 56 }, |
| 2481 | { "user version:", 60 }, |
| 2482 | { "application id:", 68 }, |
| 2483 | { "software version:", 96 }, |
| 2484 | }; |
| 2485 | static const struct { const char *zName; const char *zSql; } aQuery[] = { |
| 2486 | { "number of tables:", |
| 2487 | "SELECT count(*) FROM %s WHERE type='table'" }, |
| 2488 | { "number of indexes:", |
| 2489 | "SELECT count(*) FROM %s WHERE type='index'" }, |
| 2490 | { "number of triggers:", |
| 2491 | "SELECT count(*) FROM %s WHERE type='trigger'" }, |
| 2492 | { "number of views:", |
| 2493 | "SELECT count(*) FROM %s WHERE type='view'" }, |
| 2494 | { "schema size:", |
| 2495 | "SELECT total(length(sql)) FROM %s" }, |
| 2496 | }; |
| 2497 | sqlite3_file *pFile; |
| 2498 | int i; |
| 2499 | char *zSchemaTab; |
| 2500 | char *zDb = nArg>=2 ? azArg[1] : "main"; |
| 2501 | unsigned char aHdr[100]; |
| 2502 | open_db(p, 0); |
| 2503 | if( p->db==0 ) return 1; |
| 2504 | sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); |
| 2505 | if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ |
| 2506 | return 1; |
| 2507 | } |
| 2508 | i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); |
| 2509 | if( i!=SQLITE_OK ){ |
| 2510 | fprintf(stderr, "unable to read database header\n"); |
| 2511 | return 1; |
| 2512 | } |
| 2513 | i = get2byteInt(aHdr+16); |
| 2514 | if( i==1 ) i = 65536; |
| 2515 | fprintf(p->out, "%-20s %d\n", "database page size:", i); |
| 2516 | fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); |
| 2517 | fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); |
| 2518 | fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); |
| 2519 | for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){ |
| 2520 | int ofst = aField[i].ofst; |
| 2521 | unsigned int val = get4byteInt(aHdr + ofst); |
| 2522 | fprintf(p->out, "%-20s %u", aField[i].zName, val); |
| 2523 | switch( ofst ){ |
| 2524 | case 56: { |
| 2525 | if( val==1 ) fprintf(p->out, " (utf8)"); |
| 2526 | if( val==2 ) fprintf(p->out, " (utf16le)"); |
| 2527 | if( val==3 ) fprintf(p->out, " (utf16be)"); |
| 2528 | } |
| 2529 | } |
| 2530 | fprintf(p->out, "\n"); |
| 2531 | } |
| 2532 | if( zDb==0 ){ |
| 2533 | zSchemaTab = sqlite3_mprintf("main.sqlite_master"); |
| 2534 | }else if( strcmp(zDb,"temp")==0 ){ |
| 2535 | zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master"); |
| 2536 | }else{ |
| 2537 | zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); |
| 2538 | } |
| 2539 | for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){ |
| 2540 | char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); |
| 2541 | int val = db_int(p, zSql); |
| 2542 | sqlite3_free(zSql); |
| 2543 | fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); |
| 2544 | } |
| 2545 | sqlite3_free(zSchemaTab); |
| 2546 | return 0; |
| 2547 | } |
| 2548 | |
| 2549 | |
| 2550 | /* |
| 2551 | ** If an input line begins with "." then invoke this routine to |
| 2552 | ** process that line. |
| 2553 | ** |
| @@ -2576,10 +2686,14 @@ | |
| 2686 | fprintf(stderr,"Error: %s\n", zErrMsg); |
| 2687 | sqlite3_free(zErrMsg); |
| 2688 | rc = 1; |
| 2689 | } |
| 2690 | }else |
| 2691 | |
| 2692 | if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ |
| 2693 | rc = shell_dbinfo_command(p, nArg, azArg); |
| 2694 | }else |
| 2695 | |
| 2696 | if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ |
| 2697 | open_db(p, 0); |
| 2698 | /* When playing back a "dump", the content might appear in an order |
| 2699 | ** which causes immediate foreign key constraints to be violated. |
| @@ -2916,11 +3030,11 @@ | |
| 3030 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 3031 | if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ |
| 3032 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 3033 | "filling the rest with NULL\n", |
| 3034 | sCtx.zFile, startLine, nCol, i+1); |
| 3035 | i += 2; |
| 3036 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 3037 | } |
| 3038 | } |
| 3039 | if( sCtx.cTerm==sCtx.cColSep ){ |
| 3040 | do{ |
| @@ -2945,11 +3059,12 @@ | |
| 3059 | sqlite3_free(sCtx.z); |
| 3060 | sqlite3_finalize(pStmt); |
| 3061 | if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 3062 | }else |
| 3063 | |
| 3064 | if( c=='i' && (strncmp(azArg[0], "indices", n)==0 |
| 3065 | || strncmp(azArg[0], "indexes", n)==0) ){ |
| 3066 | ShellState data; |
| 3067 | char *zErrMsg = 0; |
| 3068 | open_db(p, 0); |
| 3069 | memcpy(&data, p, sizeof(data)); |
| 3070 | data.showHeader = 0; |
| @@ -2975,11 +3090,11 @@ | |
| 3090 | "ORDER BY 1", |
| 3091 | callback, &data, &zErrMsg |
| 3092 | ); |
| 3093 | zShellStatic = 0; |
| 3094 | }else{ |
| 3095 | fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); |
| 3096 | rc = 1; |
| 3097 | goto meta_command_exit; |
| 3098 | } |
| 3099 | if( zErrMsg ){ |
| 3100 | fprintf(stderr,"Error: %s\n", zErrMsg); |
| 3101 |