From: drh <> Date: Wed, 10 Dec 2025 15:24:46 +0000 (+0000) Subject: Add the nTitleLimit option to QRF. Also change "line" style so that it X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9bf37cc3ebc035175eccbb47f49b46212881d963;p=thirdparty%2Fsqlite.git Add the nTitleLimit option to QRF. Also change "line" style so that it uses zColumnSep as the divider between the title and the value. FossilOrigin-Name: d67a299c86ff80ed67857d2546b0edaf852cb23dbfbc15e24793d1c4860a2e50 --- diff --git a/ext/qrf/README.md b/ext/qrf/README.md index 111d2b2d96..02672d67dc 100644 --- a/ext/qrf/README.md +++ b/ext/qrf/README.md @@ -114,6 +114,7 @@ struct sqlite3_qrf_spec { short int nWrap; /* Wrap columns wider than this */ short int nScreenWidth; /* Maximum overall table width */ short int nLineLimit; /* Maximum number of lines for any row */ + short int nTitleLimit; /* Maximum number of characters in a title */ int nCharLimit; /* Maximum number of characters in a cell */ int nWidth; /* Number of entries in aWidth[] */ int nAlign; /* Number of entries in aAlignment[] */ @@ -343,7 +344,7 @@ A value of QRF_BLOB_Size does not show any BLOB content at all. Instead, it substitutes a text string that says how many bytes the BLOB contains. -### 2.8 Maximum size of displayed content (nLineLimit, nCharLimit) +### 2.8 Maximum size of displayed content (nLineLimit, nCharLimit, nTitleLimit) If the sqlite3_qrf_spec.nCharLimit setting is non-zero, then the formatter will display only the first nCharLimit characters of each value. @@ -366,6 +367,17 @@ The idea behind both of these settings is to prevent large renderings when doing a query that (unexpectedly) contains very large text or blob values: perhaps megabyes of text. +If the sqlite3_qrf_spec.nTitleLimit is non-zero, then the formatter +attempts to limits the size of column titles to at most nTitleLimit +display characters in width and a single line of text. The nTitleLimit +is useful for queries that have result columns that are scalar +subqueries or complex expressions. If those columns lack an AS +clause, then the name of the column will be a copy of the expression +that defines the column, which in some queries can be hundreds of +characters and multiple lines in length, which can reduce the readability +of tabular displays. An nTitleLimit somewhere in the range of 10 to +20 can improve readability. + ### 2.9 Word Wrapping In Columnar Styles (nWrap, bWordWrap) When using columnar formatting modes (QRF_STYLE_Box, QRF_STYLE_Column, diff --git a/ext/qrf/qrf.c b/ext/qrf/qrf.c index 4c542f8333..465054ad1e 100644 --- a/ext/qrf/qrf.c +++ b/ext/qrf/qrf.c @@ -56,7 +56,7 @@ struct Qrf { union { struct { /* Content for QRF_STYLE_Line */ int mxColWth; /* Maximum display width of any column */ - const char **azCol; /* Names of output columns (MODE_Line) */ + char **azCol; /* Names of output columns (MODE_Line) */ } sLine; qrfEQPGraph *pGraph; /* EQP graph (Eqp, Stats, and StatsEst) */ struct { /* Content for QRF_STYLE_Explain */ @@ -945,6 +945,50 @@ static const char *qrfJsonbToJson(Qrf *p, int iCol){ } } +/* +** Adjust the input string zIn[] such that it is no more than N display +** characters wide. If it is wider than that, then truncate and add +** ellipsis. Or if zIn[] contains a \r or \n, truncate at that point, +** adding ellipsis. Embedded tabs in zIn[] are converted into ordinary +** spaces. +** +** Return this display width of the modified title string. +*/ +static int qrfTitleLimit(char *zIn, int N){ + unsigned char *z = (unsigned char*)zIn; + int n = 0; + unsigned char *zEllipse = 0; + while( z[0] ){ + if( z[0]<' ' ){ + int k; + if( z[0]=='\033' && (k = qrfIsVt100(z))>0 ){ + z += k; + }else if( z[0]=='\t' ){ + z[0] = ' '; + }else if( z[0]=='\n' || z[0]=='\r' ){ + z[0] = ' '; + }else{ + z++; + } + }else if( (0x80&z[0])==0 ){ + if( n>=(N-3) && zEllipse==0 ) zEllipse = z; + if( n==N ){ z[0] = 0; break; } + n++; + z++; + }else{ + int u = 0; + int len = sqlite3_qrf_decode_utf8(z, &u); + if( n+len>(N-3) && zEllipse==0 ) zEllipse = z; + if( n+len>N ){ z[0] = 0; break; } + z += len; + n += sqlite3_qrf_wcwidth(u); + } + } + if( zEllipse ) memcpy(zEllipse,"...",4); + return n; +} + + /* ** Render value pVal into pOut */ @@ -1828,7 +1872,13 @@ static void qrfColumnar(Qrf *p){ qrfEncodeText(p, pStr, z ? z : ""); n = sqlite3_str_length(pStr); z = data.az[data.n] = sqlite3_str_finish(pStr); - data.aiWth[data.n] = w = qrfDisplayWidth(z, n, &nNL); + if( p->spec.nTitleLimit ){ + nNL = 0; + data.aiWth[data.n] = w = qrfTitleLimit(data.az[data.n], + p->spec.nTitleLimit ); + }else{ + data.aiWth[data.n] = w = qrfDisplayWidth(z, n, &nNL); + } data.n++; if( w>data.a[i].mxW ) data.a[i].mxW = w; if( nNL ) data.bMultiRow = 1; @@ -2454,6 +2504,7 @@ static void qrfOneSimpleRow(Qrf *p){ sqlite3_str *pVal; int mxW; int bWW; + int nSep; if( p->u.sLine.azCol==0 ){ p->u.sLine.azCol = sqlite3_malloc64( p->nCol*sizeof(char*) ); if( p->u.sLine.azCol==0 ){ @@ -2463,21 +2514,26 @@ static void qrfOneSimpleRow(Qrf *p){ p->u.sLine.mxColWth = 0; for(i=0; inCol; i++){ int sz; - p->u.sLine.azCol[i] = sqlite3_column_name(p->pStmt, i); - if( p->u.sLine.azCol[i]==0 ) p->u.sLine.azCol[i] = "unknown"; + const char *zCName = sqlite3_column_name(p->pStmt, i); + if( zCName==0 ) zCName = "unknown"; + p->u.sLine.azCol[i] = sqlite3_mprintf("%s", zCName); + if( p->spec.nTitleLimit>0 ){ + (void)qrfTitleLimit(p->u.sLine.azCol[i], p->spec.nTitleLimit); + } sz = (int)sqlite3_qrf_wcswidth(p->u.sLine.azCol[i]); if( sz > p->u.sLine.mxColWth ) p->u.sLine.mxColWth = sz; } } if( p->nRow ) sqlite3_str_append(p->pOut, "\n", 1); pVal = sqlite3_str_new(p->db); - mxW = p->mxWidth - (3 + p->u.sLine.mxColWth); + nSep = (int)strlen(p->spec.zColumnSep); + mxW = p->mxWidth - (nSep + p->u.sLine.mxColWth); bWW = p->spec.bWordWrap==QRF_Yes; for(i=0; inCol; i++){ const char *zVal; int cnt = 0; qrfWidthPrint(p, p->pOut, -p->u.sLine.mxColWth, p->u.sLine.azCol[i]); - sqlite3_str_append(p->pOut, " = ", 3); + sqlite3_str_append(p->pOut, p->spec.zColumnSep, nSep); qrfRenderValue(p, pVal, i); zVal = sqlite3_str_value(pVal); if( zVal==0 ) zVal = ""; @@ -2608,6 +2664,12 @@ qrf_reinit: } break; } + case QRF_STYLE_Line: { + if( p->spec.zColumnSep==0 ){ + p->spec.zColumnSep = ": "; + } + break; + } case QRF_STYLE_Csv: { p->spec.eStyle = QRF_STYLE_List; p->spec.eText = QRF_TEXT_Csv; @@ -2716,7 +2778,11 @@ static void qrfFinalize(Qrf *p){ break; } case QRF_STYLE_Line: { - if( p->u.sLine.azCol ) sqlite3_free(p->u.sLine.azCol); + if( p->u.sLine.azCol ){ + int i; + for(i=0; inCol; i++) sqlite3_free(p->u.sLine.azCol[i]); + sqlite3_free(p->u.sLine.azCol); + } break; } case QRF_STYLE_Stats: diff --git a/ext/qrf/qrf.h b/ext/qrf/qrf.h index 06ada9abee..c23ec772f0 100644 --- a/ext/qrf/qrf.h +++ b/ext/qrf/qrf.h @@ -41,6 +41,7 @@ struct sqlite3_qrf_spec { short int nWrap; /* Wrap columns wider than this */ short int nScreenWidth; /* Maximum overall table width */ short int nLineLimit; /* Maximum number of lines for any row */ + short int nTitleLimit; /* Maximum number of characters in a title */ int nCharLimit; /* Maximum number of characters in a cell */ int nWidth; /* Number of entries in aWidth[] */ int nAlign; /* Number of entries in aAlignment[] */ diff --git a/manifest b/manifest index 9ffb108ad0..d7936a1c35 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sfts5,\savoid\sholding\san\sopen\sblob\shandle\safter\san\sINSERT/UPDATE/DELETE\sstatement,\sas\sthis\scan\sinterfere\swith\ssqlite3_interrupt().\sForum\spost\s[forum:/forumpost/95413eb410\s|\s95413eb410]. -D 2025-12-09T13:41:01.298 +C Add\sthe\snTitleLimit\soption\sto\sQRF.\s\sAlso\schange\s"line"\sstyle\sso\sthat\sit\nuses\szColumnSep\sas\sthe\sdivider\sbetween\sthe\stitle\sand\sthe\svalue. +D 2025-12-10T15:24:46.290 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -416,10 +416,10 @@ F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f6 F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c F ext/misc/zipfile.c d792ed9b936ddfe9a210ecc893352afaee306c63b084187f6e44951f6f669e21 F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee -F ext/qrf/README.md e726cff56c5c8a3aa493d15b6c052834cb6b5f1ca612867bc1cc6a11be8f019b +F ext/qrf/README.md af1c7faf239625cf27a3a0e8c9d78af4e0da8e4d887223141182bc87bfbd22c8 F ext/qrf/dev-notes.md e68a6d91ce4c7eb296ef2daadc2bb79c95c317ad15b9fafe40850c67b29c2430 -F ext/qrf/qrf.c 7fb2c4b600fcba4439a3ce8f7aed95f726f15548ce375b78cd983388a0ecebf7 -F ext/qrf/qrf.h 0f0387eb4c56eaa46405cd640132624933377e46df3d2baa940392f9a7d35768 +F ext/qrf/qrf.c 03191b452a83aa970f43f0e3bac25082e1f5b71da5cab2f547789fa5fb0fbf28 +F ext/qrf/qrf.h 2ac14b0aaacf44636d8c81051bfeab4afae50a98fbb2e10ff5aed0c28a87b2b2 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255 F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363 @@ -737,7 +737,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 8d53771eb51a4ab5f970150c3a70969d8db79cd04a8774c2d296bbcf471a0dd0 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 344518c1bba9c4636bf651b7642304abd2e7075ba35feb4bae42a51e5efe991f -F src/shell.c.in 5eb15c585bd49b8cce88e762353a92b470b99a95e459bb434da41576a4f1b6eb +F src/shell.c.in fe95f5121a2a05ce3b5f9582a3d96d77f6d148cb784c5c4f2f78f26a4ed9ab19 F src/sqlite.h.in 706cacea5308b0244fb6cec92e08310fb427a125375c64137cc1f878ae4cf5c0 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 5d5330f5f8461f5ce74960436ddcfa53ecd09c2b8b23901e22ae38aec3243998 @@ -745,7 +745,7 @@ F src/sqliteInt.h af67bc95fa6b66cd3c7f3d18d2d040ad386e4cbb02965ee318cc721ee9d5fa F src/sqliteLimit.h 7e705474d59912388832cc5465edbc0dbb552872e23452812846e90d280987f3 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 1411438584e8e08c0959e6341acb0487039de662dab223ae0fef26d361211b6e +F src/tclsqlite.c 85b5a20df96016e5d1d8fdc68c8a4c279c5b93e2049b77cd806c2cc50b9d8c56 F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a F src/test1.c 0e71fbcb484a271564e98e0158192c28c24f5521594218c3ba48bcb4cf634f91 F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff @@ -1441,7 +1441,7 @@ F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93 F test/mmapcorrupt.test 470fb44fe92e99c1d23701d156f8c17865f5b027063c9119dcfdb842791f4465 F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3 F test/mmapwarm.test 2272005969cd17a910077bd5082f70bc1fefad9a875afec7fc9af483898ecaf3 -F test/modeA.clitest 96939c5fac8595213d84de82f3e09e4d126bafed19ec30167953627f4afa1723 +F test/modeA.clitest c06845925e37a4aeaadcc9f4878127cc8b5500e848c5bebdcd167a84ad8d55c9 F test/multiplex.test d74c034e52805f6de8cc5432cef8c9eb774bb64ec29b83a22effc8ca4dac1f08 F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex3.test fac575e0b1b852025575a6a8357701d80933e98b5d2fe6d35ddaa68f92f6a1f7 @@ -1511,7 +1511,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 7ad8bb08eaaf9dee2a76a807741dfe4d6752614baa3c03afc734580bccc59afa +F test/qrf01.test c464a5c72bcb11377d25ba955bfde47eae6332e1c00fcc97a6a1ca996d8fe11b F test/qrf02.test 39b4afdc000bedccdafc0aecf17638df67a67aaa2d2942865ae6abcc48ba0e92 F test/qrf03.test e7efe46d204671726b4707585126cd78d107368de4a7d0c7b8d5157cdd8624ed F test/qrf04.test 0894692c998d2401dcc33449c02051b503ecce0c94217be54fb007c82d2d1379 @@ -1614,12 +1614,12 @@ F test/shell1.test 4e1b57c43b6246fb3e617903992b704ce3798c437b01cbf1e7a5e75060fdb F test/shell2.test 9d55aa53ca36c6889dedf5a23d849793afbd2dbe62d512ce066cb293a8a66a88 F test/shell3.test 840192774cc4edf7653520c0434a311c7477b9bc324abbc7bd2887915792fa8c F test/shell4.test e25580a792b7b54560c3a76b6968bd8189261f38979fe28e6bc6312c5db280db -F test/shell5.test 7a249400bb2af59ac8524f357f8cf2844a62b6ac5ff8ecd69b045ceb688700ae +F test/shell5.test 145a9474bab6d80b6ee452b83135507b25275d53b0936aab76520f007ac4d9dc F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8 F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3 F test/shell8.test 641cf21a99c59404c24e3062923734951c4099a6b6b6520de00cf7a1249ee871 F test/shell9.test 8742a5b390cdcef6369f5aa223e415aa4255a4129ef249b177887dc635a87209 -F test/shellA.test 5fa0bdb7a19b0c1ba32649eab3eca0f7164bd9d33d391fff17586abcbc6c6e18 +F test/shellA.test 6319e4ede6658aa71b8d5265bf96071bcccdafe93853b56e670f64345a590029 F test/shellB.test de879b1ea7c25daf1a06b2c882b45a5d002e6580c81c57169ce47084cc6afb6b F test/shmlock.test 9f1f729a7fe2c46c88b156af819ac9b72c0714ac6f7246638a73c5752b5fd13c F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 @@ -2184,8 +2184,11 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 939275c6c574a3354e0626164aab1a005998f811c53a66b078249d6b2fcbd68e -R 286d8b5aad9d68a56a5f96ea87c4c7dc -U dan -Z 7641cdfba34b6b7502af4bf575815d5f +P f88e1d03573f394fc7caf60704c96152717b3fe8be4eef0caeb64737054f0fd2 +R ffbc5a3c90afd01d69ca06bdb0522a1b +T *branch * title-limit +T *sym-title-limit * +T -sym-trunk * +U drh +Z 42a92002f07a36f7c65671dbf43f2ad5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.tags b/manifest.tags index bec971799f..2992329bb1 100644 --- a/manifest.tags +++ b/manifest.tags @@ -1,2 +1,2 @@ -branch trunk -tag trunk +branch title-limit +tag title-limit diff --git a/manifest.uuid b/manifest.uuid index 939fec28a9..84481c3f43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f88e1d03573f394fc7caf60704c96152717b3fe8be4eef0caeb64737054f0fd2 +d67a299c86ff80ed67857d2546b0edaf852cb23dbfbc15e24793d1c4860a2e50 diff --git a/src/shell.c.in b/src/shell.c.in index 1af8a3b9c6..825c33e128 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1448,8 +1448,8 @@ struct ModeInfo { static const char *aModeStr[] = /* 0 1 2 3 4 5 6 7 8 */ { 0, "\n", "|", " ", ",", "\r\n", "\036", "\037", "\t", - "", "NULL", "null", "\"\"" }; - /* 9 10 11 12 */ + "", "NULL", "null", "\"\"", ": ", }; + /* 9 10 11 12 13 */ static const ModeInfo aModeInfo[] = { /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx mFlg */ @@ -1464,7 +1464,7 @@ static const ModeInfo aModeInfo[] = { { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0, 0 }, { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0, 0 }, { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0, 0 }, - { "line", 0, 1, 9, 1, 1, 0, 0, 11, 1, 0 }, + { "line", 13, 1, 9, 1, 1, 0, 0, 11, 1, 0 }, { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0, 0 }, { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2, 0 }, { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0, 0 }, @@ -1629,6 +1629,7 @@ static void modeChange(ShellState *p, unsigned char eMode){ p->mode.spec.nCharLimit = 300; p->mode.spec.nLineLimit = 5; p->mode.spec.bTextJsonb = QRF_Yes; + p->mode.spec.nTitleLimit = 20; p->mode.mFlags = mFlags; } } @@ -7707,6 +7708,7 @@ static int modeTitleDsply(ShellState *p, int bAll){ ** --title ARG Whether or not to show column headers, and if so ** how to encode them. ARG can be "off", "on", ** "sql", "csv", "html", "tcl", or "json". +** --titlelimit N Limit the length of column titles to N characters. ** -v|--verbose Verbose output ** --widths LIST Set the columns widths for columnar modes. The ** argument is a list of integers, one for each @@ -7801,17 +7803,17 @@ static int dotCmdMode(ShellState *p){ p->mode.spec.bBorder = k & 0x3; } chng = 1; - }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){ + }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","-titlelimit","")) ){ int w; /* 0 1 */ if( i+1>=nArg ){ dotCmdError(p, i, "missing argument", 0); return 1; } w = integerValue(azArg[++i]); - if( k==0 ){ - p->mode.spec.nCharLimit = w; - }else{ - p->mode.spec.nLineLimit = w; + switch( k ){ + case 0: p->mode.spec.nCharLimit = w; break; + case 1: p->mode.spec.nLineLimit = w; break; + default: p->mode.spec.nTitleLimit = w; break; } chng = 1; }else if( 0<=(k=pickStr(z,0,"-tablename","-rowsep","-colsep","-null","")) ){ @@ -8176,6 +8178,9 @@ static int dotCmdMode(ShellState *p){ sqlite3_str_appendf(pDesc," --textjsonb %s", p->mode.spec.bTextJsonb==QRF_Yes ? "on" : "off"); } + if( bAll || p->mode.spec.nTitleLimit>0 ){ + sqlite3_str_appendf(pDesc, " --titlelimit %d", p->mode.spec.nTitleLimit); + } k = modeTitleDsply(p, bAll); if( k==1 ){ sqlite3_str_appendall(pDesc, " --titles off"); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index d6bc3926fa..2c79189266 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2070,6 +2070,7 @@ static void DbHookCmd( ** -screenwidth NUMBER Width of the display TTY ** -linelimit NUMBER Max lines for any cell ** -charlimit NUMBER Content truncated to this size +** -titlelimit NUMBER Max width of column titles ** -align LIST-OF-ALIGNMENT Alignment of columns ** -widths LIST-OF-NUMBERS Widths for individual columns ** -columnsep TEXT Column separator text @@ -2097,6 +2098,7 @@ static void DbHookCmd( ** -screenwidth nScreenWidth ** -linelimit nLineLimit ** -charlimit nCharLimit +** -titlelimit nTitleLimit ** -align nAlign, aAlign ** -widths nWidth, aWidth ** -columnsep zColumnSep @@ -2272,6 +2274,7 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ }else if( strcmp(zArg,"-wrap")==0 || strcmp(zArg,"-screenwidth")==0 || strcmp(zArg,"-linelimit")==0 + || strcmp(zArg,"-titlelimit")==0 ){ int v = 0; rc = Tcl_GetIntFromObj(pDb->interp, objv[i+1], &v); @@ -2285,6 +2288,8 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ qrf.nWrap = v; }else if( zArg[1]=='s' ){ qrf.nScreenWidth = v; + }else if( zArg[1]=='t' ){ + qrf.nTitleLimit = v; }else{ qrf.nLineLimit = v; } diff --git a/test/modeA.clitest b/test/modeA.clitest index ec5fab6774..e4dbbe953c 100644 --- a/test/modeA.clitest +++ b/test/modeA.clitest @@ -79,12 +79,12 @@ END .output memory .mode .output --verify END -current output mode: qbox --limits 5,300 --quote relaxed --screenwidth auto --textjsonb on +current output mode: qbox --limits 5,300 --quote relaxed --screenwidth auto --textjsonb on --titlelimit 20 END .output memory .mode -v .output --verify END -current output mode: qbox --align "" --border on --blob-quote auto --colsep "" --escape auto --limits 5,300 --null "NULL" --quote relaxed --rowsep "" --screenwidth auto --tablename "" --textjsonb on --titles on --widths "" --wordwrap off --wrap 10 +current output mode: qbox --align "" --border on --blob-quote auto --colsep "" --escape auto --limits 5,300 --null "NULL" --quote relaxed --rowsep "" --screenwidth auto --tablename "" --textjsonb on --titlelimit 20 --titles on --widths "" --wordwrap off --wrap 10 END .output memory --error-prefix "Error:" diff --git a/test/qrf01.test b/test/qrf01.test index 89624002af..8cf080b645 100644 --- a/test/qrf01.test +++ b/test/qrf01.test @@ -289,27 +289,27 @@ do_test 1.92 { do_test 1.100 { set result "\n[db format -style line {SELECT * FROM t1}]" } { -a = 1 -b = 2.5 -c = three +a: 1 +b: 2.5 +c: three -a = BLOB -b = -c = Ἀμήν +a: BLOB +b: +c: Ἀμήν } do_test 1.101 { set result "\n[db format -style line -null (NULL) {SELECT * FROM t1}]" } { -a = 1 -b = 2.5 -c = three +a: 1 +b: 2.5 +c: three -a = BLOB -b = (NULL) -c = Ἀμήν +a: BLOB +b: (NULL) +c: Ἀμήν } do_test 1.102 { - set result "\n[db format -style line -null (NULL) \ + set result "\n[db format -style line -null (NULL) -columnsep { = } \ -text sql {SELECT * FROM t1}]" } { a = 1 @@ -624,7 +624,8 @@ do_test 5.1 { set sql {SELECT name, mtime, datetime(mtime,'unixepoch') AS time, value FROM t1 ORDER BY mtime} set result "\n[db format -style line -screenwidth 60 -blob sql \ - -text sql -wordwrap off -linelimit 77 $sql]" + -text sql -wordwrap off -linelimit 77 \ + -columnsep { = } $sql]" } { name = 'sample-jsonb' mtime = 1333101221 @@ -660,7 +661,7 @@ do_test 5.2 { set sql {SELECT name, mtime, datetime(mtime,'unixepoch') AS time, value FROM t1 ORDER BY mtime} set result "\n[db format -style line -screenwidth 60 -blob sql \ - -text plain -esc off -textjsonb yes \ + -text plain -esc off -textjsonb yes -columnsep { = }\ -wordwrap yes -linelimit 3 $sql]" } { name = sample-jsonb diff --git a/test/shell5.test b/test/shell5.test index 2c8181579b..bb8d36732c 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -521,7 +521,7 @@ do_test shell5-5.1 { close $out forcedelete test.db catchcmd test.db {.import -csv shell5.csv t1 -.mode line +.mode line --colsep ' = ' SELECT * FROM t1;} } {1 { ? = 0 x_02 = x2 @@ -537,7 +537,7 @@ Columns renamed during .import shell5.csv due to duplicates: "z" to "z_05", "z" to "z_08"}} -do_test shell5-5.1 { +do_test shell5-5.1b { set out [open shell5.csv w] fconfigure $out -translation lf puts $out {"COW","cow","CoW","cOw"} @@ -547,10 +547,10 @@ do_test shell5-5.1 { catchcmd test.db {.import -csv shell5.csv t1 .mode line SELECT * FROM t1;} -} {1 {COW_1 = uuu -cow_2 = lll -CoW_3 = ulu -cOw_4 = lul +} {1 {COW_1: uuu +cow_2: lll +CoW_3: ulu +cOw_4: lul Columns renamed during .import shell5.csv due to duplicates: "COW" to "COW_1", "cow" to "cow_2", @@ -569,7 +569,7 @@ do_test_with_ansi_output shell5-6.1 { close $out forcedelete test.db catchcmd test.db {.import -csv shell5.csv t1 -.mode line +.mode line --colsep " = " SELECT * FROM t1;} } {0 { あい = 1 うえお = 2}} @@ -584,8 +584,8 @@ do_test_with_ansi_output shell5-6.2 { catchcmd test.db {.import -csv shell5.csv t1 .mode line SELECT * FROM t1;} -} {0 {1 = あい -2 = うえお}} +} {0 {1: あい +2: うえお}} # 2024-03-11 https://sqlite.org/forum/forumpost/ca014d7358 # Import into a table that contains computed columns. diff --git a/test/shellA.test b/test/shellA.test index 6a0ea26fe2..e6b7bcd33f 100644 --- a/test/shellA.test +++ b/test/shellA.test @@ -139,41 +139,41 @@ do_test_with_ansi_output shellA-3.1 { exec {*}$CLI -noinit test.db --line --escape symbol \ {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { - a = 1 - x = line with ' single quote + a: 1 + x: line with ' single quote - a = 2 - x = ␛[31mVT-100 codes␛[0m + a: 2 + x: ␛[31mVT-100 codes␛[0m - a = 6 - x = new -line + a: 6 + x: new + line - a = 7 - x = carriage␍return + a: 7 + x: carriage␍return - a = 8 - x = last line + a: 8 + x: last line } do_test shellA-3.2 { exec {*}$CLI -noinit test.db --line --escape ascii \ {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)} } { - a = 1 - x = line with ' single quote + a: 1 + x: line with ' single quote - a = 2 - x = ^[[31mVT-100 codes^[[0m + a: 2 + x: ^[[31mVT-100 codes^[[0m - a = 6 - x = new -line + a: 6 + x: new + line - a = 7 - x = carriage^Mreturn + a: 7 + x: carriage^Mreturn - a = 8 - x = last line + a: 8 + x: last line } # ".mode box"