From: drh <> Date: Mon, 24 Nov 2025 18:31:13 +0000 (+0000) Subject: Add the --blob-quote option to the ".mode" command in the CLI. X-Git-Tag: artiphishell~185 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=94b621a15a0a5c74af6f10eb8268f9e17d4286a8;p=thirdparty%2Fsqlite.git Add the --blob-quote option to the ".mode" command in the CLI. FossilOrigin-Name: 76a986b10d284b25915a07b7150ef1b85f4ef7d48d4e5315b13e7d1532cb97f1 --- diff --git a/ext/qrf/qrf.c b/ext/qrf/qrf.c index 7b314f1f2a..278420829a 100644 --- a/ext/qrf/qrf.c +++ b/ext/qrf/qrf.c @@ -2441,7 +2441,6 @@ qrf_reinit: case QRF_STYLE_JObject: case QRF_STYLE_Json: { p->spec.eText = QRF_TEXT_Json; - p->spec.eBlob = QRF_BLOB_Json; p->spec.zNull = "null"; break; } @@ -2452,7 +2451,6 @@ qrf_reinit: } case QRF_STYLE_Insert: { p->spec.eText = QRF_TEXT_Sql; - p->spec.eBlob = QRF_BLOB_Sql; p->spec.zNull = "NULL"; if( p->spec.zTableName==0 || p->spec.zTableName[0]==0 ){ p->spec.zTableName = "tab"; @@ -2462,7 +2460,6 @@ qrf_reinit: case QRF_STYLE_Csv: { p->spec.eStyle = QRF_STYLE_List; p->spec.eText = QRF_TEXT_Csv; - p->spec.eBlob = QRF_BLOB_Text; p->spec.zColumnSep = ","; p->spec.zRowSep = "\r\n"; p->spec.zNull = ""; @@ -2470,7 +2467,6 @@ qrf_reinit: } case QRF_STYLE_Quote: { p->spec.eText = QRF_TEXT_Sql; - p->spec.eBlob = QRF_BLOB_Sql; p->spec.zNull = "NULL"; p->spec.zColumnSep = ","; p->spec.zRowSep = "\n"; diff --git a/manifest b/manifest index 4970651664..3ab974ff38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\ssome\s32-bit\sintegers\sin\sfts3_write.c\sto\s64-bit\sto\sreduce\sthe\schances\sof\sinteger\soverflow. -D 2025-11-24T17:44:17.066 +C Add\sthe\s--blob-quote\soption\sto\sthe\s".mode"\scommand\sin\sthe\sCLI. +D 2025-11-24T18:31:13.324 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -417,7 +417,7 @@ F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6 F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee F ext/qrf/README.md dd565fd1ca0c46ea37dbf4d496e368b9ecade768c92669640bc106e039629016 -F ext/qrf/qrf.c 9e3eaf868d4cfbabfb1b26b54537ee46f8345a5cef4bbc7b2920563bba5907df +F ext/qrf/qrf.c af7c0f07ec880077f2cb8cbb32012523080be10c22a9a03fbd434b21bf46f650 F ext/qrf/qrf.h a758fd35e488ef93c7fe145aa96c228c985d3c4691eb89da6328ef3ebe1fedce F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255 @@ -735,7 +735,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 6a509cddd815d64f6141e539fff633a518a393772a44dffb4490f7fc3f0d83a9 -F src/shell.c.in 6de2bcea19da8782879da7f763d94564f30424786628e094b903b0bb534e9e0a +F src/shell.c.in 575c08b667378e442e8e63579bcaa1c9ae19e37c080b8096ee04e996e93cb9d6 F src/sqlite.h.in f1363321ca55cc2feaa289e9fe6dfb08102a28c54edf005564711a2348b06eef F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 5d5330f5f8461f5ce74960436ddcfa53ecd09c2b8b23901e22ae38aec3243998 @@ -1509,7 +1509,7 @@ F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224c F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/pushdown.test 46a626ef1c0ca79b85296ff2e078b9da20a50e9b804b38f441590c3987580ddd -F test/qrf01.test e92c24195b129606210f5ff3b21e6a1468999c885d3b7f4f62bdf284221969e4 +F test/qrf01.test 6aae6741fc307bae4dd647eaccf2186eb32704a2e5db36eb8e9042e9a1b2a7b8 F test/qrf02.test 39b4afdc000bedccdafc0aecf17638df67a67aaa2d2942865ae6abcc48ba0e92 F test/qrf03.test 9de53aea459f5a127283db03cbb6011500757685646d21aa3c29c44c6ef23e86 F test/qrf04.test 0894692c998d2401dcc33449c02051b503ecce0c94217be54fb007c82d2d1379 @@ -2179,8 +2179,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bafff695d34202377b937cb4ca9f8a7611ae286d9ab927e6c71faa3cd99496e5 -R cfc1251bc868a6200eefed64db533f1c -U dan -Z 6252b8ce71cf1f222eab37a79e8ca011 +P 8f8a7224c1e0173764757d5022de60abec3babdc3d4131632805e0b04d1a65bf +R 41c492e567cc3e3b2bc92a56b0c8251a +U drh +Z 879f2fe1a0da2d52e74ae988e2731bed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 06358b8042..af348c50a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f8a7224c1e0173764757d5022de60abec3babdc3d4131632805e0b04d1a65bf +76a986b10d284b25915a07b7150ef1b85f4ef7d48d4e5315b13e7d1532cb97f1 diff --git a/src/shell.c.in b/src/shell.c.in index 07357df95c..b657531c35 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1468,28 +1468,28 @@ static const char *aModeStr[] = static const ModeInfo aModeInfo[] = { /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx */ - { "ascii", 7, 6, 9, 1, 1, 1, 1, 12, 0 }, - { "box", 0, 0, 9, 1, 1, 1, 2, 1, 2 }, + { "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0 }, + { "box", 0, 0, 9, 1, 1, 0, 2, 1, 2 }, { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0 }, - { "column", 0, 0, 9, 1, 1, 1, 2, 2, 2 }, + { "column", 0, 0, 9, 1, 1, 0, 2, 2, 2 }, { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0 }, - { "csv", 4, 5, 9, 3, 3, 3, 1, 12, 0 }, - { "html", 0, 0, 9, 4, 4, 1, 2, 7, 0 }, - { "insert", 0, 0, 10, 2, 2, 2, 1, 8, 0 }, - { "jatom", 4, 1, 11, 6, 6, 5, 1, 12, 0 }, - { "jobject", 0, 1, 11, 6, 6, 5, 0, 10, 0 }, + { "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0 }, + { "html", 0, 0, 9, 4, 4, 0, 2, 7, 0 }, + { "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0 }, + { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0 }, + { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0 }, { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0 }, { "line", 0, 1, 9, 1, 1, 0, 0, 11, 1 }, - { "list", 2, 1, 9, 1, 1, 1, 1, 12, 0 }, - { "markdown", 0, 0, 9, 1, 1, 1, 2, 13, 2 }, + { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0 }, + { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2 }, { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0 }, - { "qbox", 0, 0, 9, 2, 1, 2, 2, 1, 2 }, - { "quote", 4, 1, 10, 2, 2, 2, 1, 12, 0 }, - { "split", 0, 0, 9, 1, 1, 1, 1, 2, 2 }, - { "table", 0, 0, 9, 1, 1, 1, 2, 19, 2 }, - { "tabs", 8, 1, 9, 3, 3, 1, 1, 12, 0 }, + { "qbox", 0, 0, 9, 2, 1, 0, 2, 1, 2 }, + { "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0 }, + { "split", 0, 0, 9, 1, 1, 0, 1, 2, 2 }, + { "table", 0, 0, 9, 1, 1, 0, 2, 19, 2 }, + { "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0 }, { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0 }, - { "www", 0, 0, 9, 4, 4, 1, 2, 7, 0 } + { "www", 0, 0, 9, 4, 4, 0, 2, 7, 0 } }; /* | / / | / / | | \ ** | / / | / / | | \_ 2: columnar ** Index into aModeStr[] | / / | | 1: line @@ -1499,12 +1499,13 @@ static const ModeInfo aModeInfo[] = { ** v-------------------' | hdrs? | The QRF style ** 0: n/a blob | v-----' ** 1: plain v_---------' 0: n/a - ** 2: sql 0: n/a 1: no + ** 2: sql 0: auto 1: no ** 3: csv 1: as-text 2: yes ** 4: html 2: sql ** 5: c 3: hex ** 6: json 4: c ** 5: json + ** 6: size ******************************************************************/ /* ** These are the column/row/line separators used by the various @@ -3194,6 +3195,13 @@ static int shell_exec( if( pArg->mode.bAutoScreenWidth ){ spec.nScreenWidth = shellScreenWidth(); } + if( spec.eBlob==QRF_BLOB_Auto ){ + switch( spec.eText ){ + case QRF_TEXT_Sql: spec.eBlob = QRF_BLOB_Sql; break; + case QRF_TEXT_Json: spec.eBlob = QRF_BLOB_Json; break; + default: spec.eBlob = QRF_BLOB_Text; break; + } + } #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) if( pArg->expert.pExpert ){ @@ -3561,6 +3569,8 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ savedMode = p->mode; p->mode.spec.zTableName = (char*)zTable; p->mode.eMode = MODE_Insert; + p->mode.spec.eText = QRF_TEXT_Sql; + p->mode.spec.eBlob = QRF_BLOB_Sql; p->mode.spec.bTitles = QRF_No; rc = shell_exec(p, sSelect.zTxt, 0); if( (rc&0xff)==SQLITE_CORRUPT ){ @@ -7663,6 +7673,8 @@ static int modeTitleDsply(ShellState *p, int bAll){ ** meaning "left", "centered", and "right", with ** one letter per column starting from the left. ** Unspecified alignment defaults to 'L'. +** --blob-quote ARG ARG can be "auto", "text", "sql", "hex", "tcl", +** "tcl", "json", or "size". Default is "auto". ** --charlimit N Set the maximum number of output characters to ** show for any single SQL value to N. Longer values ** truncated. Zero means "no limit". @@ -7768,6 +7780,19 @@ static int dotCmdMode(ShellState *p){ "Should contain only characters L, C, and R."); return 1; } + }else if( pickStr(z,0,"-blob","-blob-quote","")>=0 ){ + if( (++i)>=nArg ){ + dotCmdError(p, i-1, "missing argument", 0); + return 1; + } + k = pickStr(azArg[i], 0, + "auto", "text", "sql", "hex", "tcl", "json", "size", ""); + /* 0 1 2 3 4 5 6 + ** Must match QRF_BLOB_xxxx values. See also tag-20251124a */ + if( k>=0 ){ + p->mode.spec.eBlob = k & 0xff; + } + chng = 1; }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){ int w; /* 0 1 */ if( i+1>=nArg ){ @@ -7854,7 +7879,7 @@ static int dotCmdMode(ShellState *p){ }else if( optionMatch(z,"noquote") ){ /* (undocumented legacy) --noquote always turns quoting off */ p->mode.spec.eText = QRF_TEXT_Plain; - p->mode.spec.eBlob = QRF_BLOB_Text; + p->mode.spec.eBlob = QRF_BLOB_Auto; chng = 1; }else if( optionMatch(z,"quote") ){ if( i+1mode.spec.eText = QRF_TEXT_Sql; - p->mode.spec.eBlob = QRF_BLOB_Sql; break; case 3: /* csv */ p->mode.spec.eText = QRF_TEXT_Csv; - p->mode.spec.eBlob = QRF_BLOB_Text; break; case 4: /* html */ p->mode.spec.eText = QRF_TEXT_Html; - p->mode.spec.eBlob = QRF_BLOB_Text; break; case 5: /* tcl */ p->mode.spec.eText = QRF_TEXT_Tcl; - p->mode.spec.eBlob = QRF_BLOB_Text; break; case 6: /* json */ p->mode.spec.eText = QRF_TEXT_Json; - p->mode.spec.eBlob = QRF_BLOB_Json; break; default: /* off */ p->mode.spec.eText = QRF_TEXT_Plain; - p->mode.spec.eBlob = QRF_BLOB_Text; break; } chng = 1; @@ -8074,6 +8093,14 @@ static int dotCmdMode(ShellState *p){ } sqlite3_str_append(pDesc, "\"", 1); } + if( bAll || p->mode.spec.eBlob!=QRF_BLOB_Auto ){ + const char *azBQuote[] = + { "auto", "text", "sql", "hex", "tcl", "json", "size" }; + /* 0 1 2 3 4 5 6 + ** Must match QRF_BLOB_xxxx values. See all instances of tag-20251124a */ + u8 e = p->mode.spec.eBlob; + sqlite3_str_appendf(pDesc, " --blob-quote %s", azBQuote[e]); + } if( bAll || p->mode.spec.nCharLimit>0 ){ sqlite3_str_appendf(pDesc, " --charlimit %d",p->mode.spec.nCharLimit); } diff --git a/test/qrf01.test b/test/qrf01.test index a3fe83cb22..dd81f49612 100644 --- a/test/qrf01.test +++ b/test/qrf01.test @@ -137,19 +137,19 @@ do_test 1.60a { } "1,2.5,three\r\n\"\\102\\114\\117\\102\",,\"Ἀμήν\"\r\n" do_test 1.60b { db format -style csv -columnsep xyz -rowsep pqr -text sql -blob sql {SELECT * FROM t1} -} "1,2.5,three\r\nBLOB,,\"Ἀμήν\"\r\n" +} "1,2.5,three\r\nx'424c4f42',,\"Ἀμήν\"\r\n" do_test 1.61a { db format -style list -columnsep , -rowsep \r\n -text csv -title auto -blob tcl {SELECT * FROM t1} } "a,b,c\r\n1,2.5,three\r\n\"\\102\\114\\117\\102\",,\"Ἀμήν\"\r\n" do_test 1.61b { db format -style csv -title auto -blob tcl {SELECT * FROM t1} -} "a,b,c\r\n1,2.5,three\r\nBLOB,,\"Ἀμήν\"\r\n" +} "a,b,c\r\n1,2.5,three\r\n\"\\102\\114\\117\\102\",,\"Ἀμήν\"\r\n" do_test 1.62a { db format -style list -columnsep , -rowsep \r\n -text csv -title csv -blob tcl {SELECT a AS 'a x y', b, c FROM t1} } "\"a x y\",b,c\r\n1,2.5,three\r\n\"\\102\\114\\117\\102\",,\"Ἀμήν\"\r\n" do_test 1.62b { db format -style csv -title csv -blob tcl {SELECT a AS 'a x y', b, c FROM t1} -} "\"a x y\",b,c\r\n1,2.5,three\r\nBLOB,,\"Ἀμήν\"\r\n" +} "\"a x y\",b,c\r\n1,2.5,three\r\n\"\\102\\114\\117\\102\",,\"Ἀμήν\"\r\n" do_test 1.70 { set result "\n[db format -style html {SELECT * FROM t1}]"