From: drh <> Date: Mon, 11 Nov 2024 19:07:58 +0000 (+0000) Subject: Add the ".dbtotxt" command to the CLI. X-Git-Tag: major-relase~173 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=be46f935dc3d2e5a033d5427f636fa3c521e06d2;p=thirdparty%2Fsqlite.git Add the ".dbtotxt" command to the CLI. FossilOrigin-Name: b43acf5a8cd4a5efbb90b71af7710084f49bb90ffe4f56de168e8c3a6b679124 --- diff --git a/manifest b/manifest index 7dd4be8871..7154ba0838 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Wrap\ssome\sexceptionally\slong\slines\sin\smain.mk.\sAdd\soption\sto\soverride\sLDFLAGS\son\sthe\ssqlite3.dll\starget.\sAudit:\sall\stargets\sfor\swhich\sit\sis\shypothetically\srelevant\scan\snow\sinherit\suser-supplied\sLDFLAGS,\sbut\sonly\sthose\sprovided\sto\sthe\sconfigure\sscript,\snot\sat\smake-time,\sin\sorder\sto\smimic\sthe\shistorical\sbuild's\srestriction\sin\sthat\sregard. -D 2024-11-11T18:15:50.014 +C Add\sthe\s".dbtotxt"\scommand\sto\sthe\sCLI. +D 2024-11-11T19:07:58.682 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -776,7 +776,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in bb97e0afcc4a73b73f38cc868330854a2df109095a7a10182ddfdd261fbec312 +F src/shell.c.in 2b684d9cdad2351e6cabe25ea3a64ac743eb4cda9837bdbc6096d240c4533ab6 F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P abfe488ed67e2e3510c230e656ecf203afa549ebd1d1872442f1fadc97d0817e -R 24df96c9d99772830356798614acfd48 -U stephan -Z 28b6529814c584cc2748223194d7bea5 +P 073080cae3ea0d12b133d9c9ae98413bb32870a9738c98b89bc345181be81f23 +R 6bdbd63031b22370793e2437aff7acb5 +U drh +Z d185df0f51d41a6d3859bb43f39c0c62 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 24c1159da9..b4972f3476 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -073080cae3ea0d12b133d9c9ae98413bb32870a9738c98b89bc345181be81f23 +b43acf5a8cd4a5efbb90b71af7710084f49bb90ffe4f56de168e8c3a6b679124 diff --git a/src/shell.c.in b/src/shell.c.in index 874f448f67..3fb608ff7f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -4951,6 +4951,7 @@ static const char *(azHelp[]) = { #if SQLITE_SHELL_HAVE_RECOVER ".dbinfo ?DB? Show status information about the database", #endif + ".dbtotxt Hex dump of the database file", ".dump ?OBJECTS? Render database content as SQL", " Options:", " --data-only Output only INSERT statements", @@ -6622,6 +6623,101 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ } #endif /* SQLITE_SHELL_HAVE_RECOVER */ +/* +** Implementation of the ".dbtotxt" command. +** +** Return 1 on error, 2 to exit, and 0 otherwise. +*/ +static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){ + sqlite3_stmt *pStmt = 0; + sqlite3_int64 nPage = 0; + int pgSz = 0; + const char *zFilename; + const char *zTail; + char *zName = 0; + int rc, i, j; + unsigned char bShow[256]; /* Characters ok to display */ + + memset(bShow, '.', sizeof(bShow)); + for(i=' '; i<='~'; i++){ + if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i; + } + rc = sqlite3_prepare_v2(p->db, "PRAGMA page_size", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; + pgSz = sqlite3_column_int(pStmt, 0); + sqlite3_finalize(pStmt); + pStmt = 0; + if( pgSz<512 || pgSz>65536 || (pgSz&(pgSz-1))!=0 ) goto dbtotxt_error; + rc = sqlite3_prepare_v2(p->db, "PRAGMA page_count", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; + nPage = sqlite3_column_int64(pStmt, 0); + sqlite3_finalize(pStmt); + pStmt = 0; + if( nPage<1 ) goto dbtotxt_error; + rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + if( sqlite3_step(pStmt)!=SQLITE_ROW ){ + zTail = zFilename = "unk.db"; + }else{ + zFilename = (const char*)sqlite3_column_text(pStmt, 2); + if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; + zTail = strrchr(zFilename, '/'); +#if defined(_WIN32) + if( zTail==0 ) zTail = strrchr(zFilename, '\\'); +#endif + if( zTail ) zFilename = zTail; + } + zName = strdup(zTail); + shell_check_oom(zName); + sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n", + nPage*pgSz, pgSz, zName); + sqlite3_finalize(pStmt); + pStmt = 0; + rc = sqlite3_prepare_v2(p->db, + "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0); + const u8 *aData = sqlite3_column_blob(pStmt, 1); + int seenPageLabel = 0; + for(i=0; iout, "| page %lld offset %lld\n", pgno, pgno*pgSz); + seenPageLabel = 1; + } + sqlite3_fprintf(p->out, "| %5d:", i); + for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]); + sqlite3_fprintf(p->out, " "); + for(j=0; j<16; j++){ + unsigned char c = (unsigned char)aLine[j]; + sqlite3_fprintf(p->out, "%c", bShow[c]); + } + sqlite3_fprintf(p->out, "\n"); + } + } + sqlite3_finalize(pStmt); + sqlite3_fprintf(p->out, "| end %s\n", zName); + free(zName); + return 0; + +dbtotxt_error: + if( rc ){ + sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db)); + } + sqlite3_finalize(pStmt); + free(zName); + return 1; +} + /* ** Print the given string as an error message. */ @@ -8799,6 +8895,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){ + rc = shell_dbtotxt_command(p, nArg, azArg); + }else + if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){ if( nArg==2 ){ p->autoEQPtest = 0;