From: drh <> Date: Tue, 11 Nov 2025 18:07:42 +0000 (+0000) Subject: Minor refactoring of some field names in the sqlite3_qrf_spec object, to try X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b43e8920d8be017b403a2fbdb0ca0fbf5a9f19dc;p=thirdparty%2Fsqlite.git Minor refactoring of some field names in the sqlite3_qrf_spec object, to try to make the names more intuitive, memorable, and succinct. FossilOrigin-Name: 3450bc7eecb717abedbaeb56dc824e14eb35ed30322fe3dd3b4b1cbd5fd14c60 --- diff --git a/ext/qrf/README.md b/ext/qrf/README.md index 3d5770bb45..48bd223177 100644 --- a/ext/qrf/README.md +++ b/ext/qrf/README.md @@ -71,16 +71,16 @@ struct sqlite3_qrf_spec { unsigned char eText; /* Quoting style for text */ unsigned char eTitle; /* Quating style for the text of column names */ unsigned char eBlob; /* Quoting style for BLOBs */ - unsigned char bColumnNames; /* True to show column names */ + unsigned char bTitles; /* True to show column names */ unsigned char bWordWrap; /* Try to wrap on word boundaries */ unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */ unsigned char bTextNull; /* Apply eText encoding to zNull[] */ unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */ unsigned char eTitleAlign; /* Alignment for column headers */ - short int mxColWidth; /* Maximum width of any individual column */ + short int nWrap; /* Wrap columns wider than this */ short int nScreenWidth; /* Maximum overall table width */ - short int mxRowHeight; /* Maximum number of lines for any row */ - int mxLength; /* Maximum content to display per element */ + short int nLineLimit; /* Maximum number of lines for any row */ + int nCharLimit; /* Maximum number of characters in a cell */ int nWidth; /* Number of entries in aWidth[] */ int nAlign; /* Number of entries in aAlignment[] */ short int *aWidth; /* Column widths */ @@ -146,9 +146,9 @@ for details on the meaning of the various style options. Other fields in sqlite3_qrf_spec might be used or might be ignored, depending on the value of eStyle. -### 2.4 Show Column Names (bColumnNames) +### 2.4 Show Column Names (bTitles) -The sqlite3_qrf_spec.bColumnNames field can be either QRF_SW_Auto, +The sqlite3_qrf_spec.bTitles field can be either QRF_SW_Auto, QRF_SW_On, or QRF_SW_Off. Those three constants also have shorter alternative spellings: QRF_Auto, QRF_No, and QRF_Yes. @@ -292,28 +292,40 @@ the C/Tcl/Perl octal backslash escapes. So the string from the previous paragraph would be shown as `"\u0005\u0028\u0081\u00f3"`. -### 2.8 Maximum displayed content length (mxLength) +### 2.8 Maximum size of displayed content (nLineLimit, nCharLimit) -If the sqlite3_qrf_spec.mxLength setting is non-zero, then the formatter -*attempts* to show only the first mxLength characters of each value. -This limit is approximate. The content length might exceed the limit -by a few characters, especially if the limit is very small. +If the sqlite3_qrf_spec.nCharLimit setting is non-zero, then the formatter +will display only the first nCharLimit characters of each value. +Only characters that take up space are counted when enforcing this +limit. Zero-width characters and VT100 escape sequences do not count +toward this limit. The count is in characters, not bytes. Content length limits only apply to TEXT and BLOB values. Numeric values and NULLs always display their full text regardless of the -mxLength setting. +nCharLimit setting. *This setting is a place-holder. -As for 2025-11-07, the mxLength constraint is not yet implemented. -The current behavior is always as if mxLength where zero.* +As for 2025-11-07, the nCharLimit constraint is not yet implemented. +The current behavior is always as if nCharLimit where zero.* -### 2.9 Word Wrapping In Columnar Styles (mxColWidth, bWordWrap) +If the sqlite3_qrf_spec.nLineLimit setting is non-zero, then the +formatter will only display the first nLineLimit lines of each value. +It does not matter if the value is split because it contains a newline +character, or if it split by wrapping. This setting merely limits +the number of displayed lines. This setting only works for +**Box**, **Column**, **Line**, **Markdown**, and **Table** styles. + +The idea behind these settings is to prevent excessively large renderings +when doing a query that (unexpectedly) contains very large text or +blob values: perhaps megabyes of text. + +### 2.9 Word Wrapping In Columnar Styles (nWrap, bWordWrap) When using columnar formatting modes (QRF_STYLE_Box, QRF_STYLE_Column, QRF_STYLE_Markdown, or QRF_STYLE_Table), the formatter attempts to limit -the width of any individual column to sqlite3_qrf_spec.mxColWidth characters -if mxColWidth is non-zero. A zero value for mxColWidth means "unlimited". -The mxColWidth limit might be exceeded if the limit is very small. +the width of any individual column to sqlite3_qrf_spec.nWrap characters +if nWrap is non-zero. A zero value for nWrap means "unlimited". +The nWrap limit might be exceeded if the limit is very small. In order to keep individual columns within requested width limits, it is sometimes necessary to wrap the content for a single row of @@ -567,7 +579,7 @@ into memory first in order to determine how wide to make each column. The nWidth, aWidth, and mxWidth fields of the `sqlite3_qrf_spec` object are used by these styles only, and are ignored by all other styles. The zRowSep and zColumnSep settings are ignored by these styles. The -bColumnNames setting is honored by these styles; it defaults to QRF_SW_On. +bTitles setting is honored by these styles; it defaults to QRF_SW_On. The **Box** style uses Unicode box-drawing character to draw a grid of columns and rows to show the result. The **Table** is the same, diff --git a/ext/qrf/qrf.c b/ext/qrf/qrf.c index f839ff57c8..c8382e8ef1 100644 --- a/ext/qrf/qrf.c +++ b/ext/qrf/qrf.c @@ -53,7 +53,7 @@ struct Qrf { int nCol; /* Number of output columns */ int expMode; /* Original sqlite3_stmt_isexplain() plus 1 */ int mxWidth; /* Screen width */ - int mxHeight; /* mxRowHeight */ + int mxHeight; /* nLineLimit */ union { struct { /* Content for QRF_STYLE_Line */ int mxColWth; /* Maximum display width of any column */ @@ -1316,7 +1316,7 @@ static void qrfColumnar(Qrf *p){ assert( data.aAlign!=0 ); /* Load the column header names and all cell content into data */ - if( p->spec.bColumnNames==QRF_Yes ){ + if( p->spec.bTitles==QRF_Yes ){ unsigned char saved_eText = p->spec.eText; p->spec.eText = p->spec.eTitle; for(i=0; ispec.bColumnNames==QRF_No ){ + if( p->spec.bTitles==QRF_No ){ qrfLoadAlignment(&data, p); }else if( p->spec.eTitleAlign==QRF_Auto ){ memset(data.aAlign, QRF_ALIGN_Center, nColumn); @@ -1386,8 +1386,8 @@ static void qrfColumnar(Qrf *p){ for(j=i; j w ){ w = data.aiWth[j]; - if( p->spec.mxColWidth>0 && w>p->spec.mxColWidth ){ - w = p->spec.mxColWidth; + if( p->spec.nWrap>0 && w>p->spec.nWrap ){ + w = p->spec.nWrap; data.bMultiRow = 1; break; } @@ -1472,7 +1472,7 @@ static void qrfColumnar(Qrf *p){ } }while( bMore && ++nRow < p->mxHeight ); if( bMore ){ - /* This row was terminated by mxRowHeight. Show ellipsis. */ + /* This row was terminated by nLineLimit. Show ellipsis. */ sqlite3_str_append(p->pOut, rowStart, szRowStart); for(j=0; jspec.bColumnNames==QRF_Yes); + int isTitleDataSeparator = (i==0 && p->spec.bTitles==QRF_Yes); if( isTitleDataSeparator ){ qrfLoadAlignment(&data, p); } @@ -1829,7 +1829,7 @@ static void qrfOneSimpleRow(Qrf *p){ break; } case QRF_STYLE_Html: { - if( p->nRow==0 && p->spec.bColumnNames==QRF_Yes ){ + if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){ sqlite3_str_append(p->pOut, "", 4); for(i=0; inCol; i++){ const char *zCName = sqlite3_column_name(p->pStmt, i); @@ -1853,7 +1853,7 @@ static void qrfOneSimpleRow(Qrf *p){ }else{ sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName); } - if( p->spec.bColumnNames==QRF_Yes ){ + if( p->spec.bTitles==QRF_Yes ){ for(i=0; inCol; i++){ const char *zCName = sqlite3_column_name(p->pStmt, i); if( qrf_need_quote(zCName) ){ @@ -1935,7 +1935,7 @@ static void qrfOneSimpleRow(Qrf *p){ break; } default: { /* QRF_STYLE_List */ - if( p->nRow==0 && p->spec.bColumnNames==QRF_Yes ){ + if( p->nRow==0 && p->spec.bTitles==QRF_Yes ){ int saved_eText = p->spec.eText; p->spec.eText = p->spec.eTitle; for(i=0; inCol; i++){ @@ -1992,7 +1992,7 @@ static void qrfInitialize( if( p->spec.zNull==0 ) p->spec.zNull = ""; p->mxWidth = p->spec.nScreenWidth; if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH; - p->mxHeight = p->spec.mxRowHeight; + p->mxHeight = p->spec.nLineLimit; if( p->mxHeight<=0 ) p->mxHeight = 2147483647; qrf_reinit: switch( p->spec.eStyle ){ @@ -2090,17 +2090,17 @@ qrf_reinit: default: p->spec.eBlob = QRF_BLOB_Text; break; } } - if( p->spec.bColumnNames==QRF_Auto ){ + if( p->spec.bTitles==QRF_Auto ){ switch( p->spec.eStyle ){ case QRF_STYLE_Box: case QRF_STYLE_Csv: case QRF_STYLE_Column: case QRF_STYLE_Table: case QRF_STYLE_Markdown: - p->spec.bColumnNames = QRF_Yes; + p->spec.bTitles = QRF_Yes; break; default: - p->spec.bColumnNames = QRF_No; + p->spec.bTitles = QRF_No; break; } } diff --git a/ext/qrf/qrf.h b/ext/qrf/qrf.h index 28e940e63e..a353ea055f 100644 --- a/ext/qrf/qrf.h +++ b/ext/qrf/qrf.h @@ -28,16 +28,16 @@ struct sqlite3_qrf_spec { unsigned char eText; /* Quoting style for text */ unsigned char eTitle; /* Quating style for the text of column names */ unsigned char eBlob; /* Quoting style for BLOBs */ - unsigned char bColumnNames; /* True to show column names */ + unsigned char bTitles; /* True to show column names */ unsigned char bWordWrap; /* Try to wrap on word boundaries */ unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */ unsigned char bTextNull; /* Apply eText encoding to zNull[] */ unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */ unsigned char eTitleAlign; /* Alignment for column headers */ - short int mxColWidth; /* Maximum width of any individual column */ + short int nWrap; /* Wrap columns wider than this */ short int nScreenWidth; /* Maximum overall table width */ - short int mxRowHeight; /* Maximum number of lines for any row */ - int mxLength; /* Maximum content to display per element */ + short int nLineLimit; /* Maximum number of lines for any row */ + int nCharLimit; /* Maximum number of characters in a cell */ int nWidth; /* Number of entries in aWidth[] */ int nAlign; /* Number of entries in aAlignment[] */ short int *aWidth; /* Column widths */ diff --git a/manifest b/manifest index 86c1ffaa95..aff6dfd237 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sthe\s".output"\scommand\sinto\sa\sseparate\ssubroutine.\s\sEnhance\s.output\sso\nthat\sit\sis\sable\sto\scapture\soutput\sin\sa\ssqlite3_str\sobject,\sthen\scompare\sthat\ncaptured\soutput\swe\spatterns\sto\saccomplish\stests. -D 2025-11-11T14:08:50.512 +C Minor\srefactoring\sof\ssome\sfield\snames\sin\sthe\ssqlite3_qrf_spec\sobject,\sto\stry\nto\smake\sthe\snames\smore\sintuitive,\smemorable,\sand\ssuccinct. +D 2025-11-11T18:07:42.284 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -416,9 +416,9 @@ F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f6 F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee -F ext/qrf/README.md e0d3f9b0270e4402ab9de7a29264f248298eb962f408bd30c87b92067486029c -F ext/qrf/qrf.c ad3ab57819b100619ed99d2d277fb252be43517b99bab07268a800e8e69936ea -F ext/qrf/qrf.h 5798e185000dddb7979fb90371abc7671fe3eeb65f1206ccb1d00ea5ee323419 +F ext/qrf/README.md fee287e4ee6be54bc6d43af7df2328bf18395178c40385c7d9914c0f2781333b +F ext/qrf/qrf.c 2ab94743a9caf24cacc9d8614dd074195f7675aeac7b30acbb6dd046bbc9c75e +F ext/qrf/qrf.h 02d9f6293c5974492b531a8e8afb2b332a3b1ac1644a3591328bfe135c2011e1 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255 F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363 @@ -735,7 +735,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a -F src/shell.c.in 6b289585d97c8d9e57efc8f589588566d88212c73e879806a09fdd03ce19acc0 +F src/shell.c.in 0bf3c5b49f639e5f68e19ee8504ac466fa49009aabe4a17cc22bd21125d641ab F src/sqlite.h.in 7403a952a8f1239de7525b73c4e3a0f9540ec0607ed24fec887f5832642d44b8 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52 @@ -743,7 +743,7 @@ F src/sqliteInt.h 88f7fc9ce1630d9a5f7e0a8e1f3287cdc63882fba985c18e7eee1b9f457f59 F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 79cf2fe03fbba118d594bb8317096ac5a7ee434a2c5e8a1f1926ce2b1f91d1c0 +F src/tclsqlite.c 7f65beb073a25c2db9a56c0bb4be5c66718763fe4d97b807ec265dc294e591a4 F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a F src/test1.c d27c91455865fb191eb1b2c892e7586c5e3d9d3977f54913c8e70e2e8e5148b3 F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff @@ -1506,7 +1506,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 8ab2ae7e87265e9faf0479e92fab21602d1e27157f1f35a4f8fc4e0fdf5ff7e6 +F test/qrf01.test ad05382a6693bcd99147857babce976f52e51cffb8508a3aca1d16c08c5d3797 F test/qrf02.test 39b4afdc000bedccdafc0aecf17638df67a67aaa2d2942865ae6abcc48ba0e92 F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 @@ -2173,8 +2173,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 b48aa054df488747a7db56faf1cd0da42e322edff60650b9187448e58eb12def -R 5c9f64670d89ec287264fbae90780bfe +P ddd167044753f5215624fc9ee0e3657836c528f23a6a3e262401fd1b64cdbb21 +R 55e92c2a04b40f143479b945540fb2e9 U drh -Z 419508d00d340c19a4153a9b54d8de2d +Z 069f6c588dd2080df4a98b06586c707c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5477ea85ab..b2260f4f2f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ddd167044753f5215624fc9ee0e3657836c528f23a6a3e262401fd1b64cdbb21 +3450bc7eecb717abedbaeb56dc824e14eb35ed30322fe3dd3b4b1cbd5fd14c60 diff --git a/src/shell.c.in b/src/shell.c.in index 5fbd62014b..c8ae7c2438 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2977,7 +2977,7 @@ static int shell_exec( switch( pArg->mode.eMode ){ case MODE_Insert: { if( ShellHasFlag(pArg, SHFLG_PreserveRowid) ){ - spec.bColumnNames = QRF_SW_On; + spec.bTitles = QRF_SW_On; } break; } @@ -2990,7 +2990,7 @@ static int shell_exec( case MODE_Box: case MODE_Table: case MODE_Markdown: { - spec.bColumnNames = QRF_Yes; + spec.bTitles = QRF_Yes; break; } } @@ -3364,7 +3364,7 @@ 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.bColumnNames = QRF_No; + p->mode.spec.bTitles = QRF_No; rc = shell_exec(p, sSelect.zTxt, 0); if( (rc&0xff)==SQLITE_CORRUPT ){ cli_puts("/****** CORRUPTION ERROR *******/\n", p->out); @@ -7070,7 +7070,7 @@ static int dotCmdMode(ShellState *p){ int w = integerValue(azArg[++i]); if( w<(-QRF_MAX_WIDTH) ) w = -QRF_MAX_WIDTH; if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH; - p->mode.spec.mxColWidth = w; + p->mode.spec.nWrap = w; chng |= 1; }else if( optionMatch(z,"ww") ){ p->mode.spec.bWordWrap = QRF_Yes; @@ -7157,9 +7157,9 @@ static int dotCmdMode(ShellState *p){ ){ cli_printf(p->out, "current output mode: %s", modeDescr[p->mode.eMode]); - if( p->mode.spec.mxColWidth ){ + if( p->mode.spec.nWrap ){ cli_printf(p->out, " --wrap %d", - p->mode.spec.mxColWidth); + p->mode.spec.nWrap); }else{ cli_printf(p->out, " --wrap off"); } @@ -8034,7 +8034,7 @@ static int do_meta_command(const char *zLine, ShellState *p){ cli_puts("BEGIN TRANSACTION;\n", p->out); } p->writableSchema = 0; - p->mode.spec.bColumnNames = QRF_No; + p->mode.spec.bTitles = QRF_No; /* Set writable_schema=ON since doing so forces SQLite to initialize ** as much of the schema as it can even if the sqlite_schema table is ** corrupt. */ @@ -8323,7 +8323,7 @@ static int do_meta_command(const char *zLine, ShellState *p){ " AND name NOT LIKE 'sqlite__%%' ESCAPE '_' " "ORDER BY x", flgs); memcpy(&data, p, sizeof(data)); - data.mode.spec.bColumnNames = QRF_No; + data.mode.spec.bTitles = QRF_No; data.mode.spec.eStyle= QRF_STYLE_List; data.mode.spec.zRowSep = "\n"; rc = shell_exec(&data,zSql,0); @@ -8364,7 +8364,7 @@ static int do_meta_command(const char *zLine, ShellState *p){ if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){ if( nArg==2 ){ - p->mode.spec.bColumnNames = booleanValue(azArg[1]) ? QRF_Yes : QRF_No; + p->mode.spec.bTitles = booleanValue(azArg[1]) ? QRF_Yes : QRF_No; }else{ eputz("Usage: .headers on|off\n"); rc = 1; @@ -9419,7 +9419,7 @@ static int do_meta_command(const char *zLine, ShellState *p){ open_db(p, 0); memcpy(&data, p, sizeof(data)); - data.mode.spec.bColumnNames = QRF_No; + data.mode.spec.bTitles = QRF_No; data.mode.eMode = MODE_List; modeSetStr(&data.mode.spec.zRowSep, "\n"); for(ii=1; iiout, "%12.12s: %s\n","explain", p->mode.autoExplain ? "auto" : "off"); cli_printf(p->out, "%12.12s: %s\n","headers", - azBool[p->mode.spec.bColumnNames==QRF_Yes]); + azBool[p->mode.spec.bTitles==QRF_Yes]); if( p->mode.spec.eStyle==QRF_STYLE_Column || p->mode.spec.eStyle==QRF_STYLE_Box || p->mode.spec.eStyle==QRF_STYLE_Table @@ -10115,7 +10115,7 @@ static int do_meta_command(const char *zLine, ShellState *p){ ){ cli_printf(p->out, "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", - modeDescr[p->mode.eMode], p->mode.spec.mxColWidth, + modeDescr[p->mode.eMode], p->mode.spec.nWrap, p->mode.spec.bWordWrap==QRF_Yes ? "on" : "off", p->mode.spec.eText==QRF_TEXT_Sql ? "" : "no"); }else{ @@ -12211,9 +12211,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ modeSetStr(&data.mode.spec.zNull, cmdline_option_value(argc,argv,++i)); }else if( cli_strcmp(z,"-header")==0 ){ - data.mode.spec.bColumnNames = QRF_Yes; + data.mode.spec.bTitles = QRF_Yes; }else if( cli_strcmp(z,"-noheader")==0 ){ - data.mode.spec.bColumnNames = QRF_No; + data.mode.spec.bTitles = QRF_No; }else if( cli_strcmp(z,"-echo")==0 ){ data.mode.bEcho = 1; }else if( cli_strcmp(z,"-eqp")==0 ){ diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 4909fd2819..ce9d0d127a 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2058,18 +2058,17 @@ static void DbHookCmd( ** -style ("auto"|"box"|"column"|...) Output style ** -esc ("auto"|"off"|"ascii"|"symbol") How to deal with ctrl chars ** -text ("auto"|"off"|"sql"|"csv"|...) How to escape TEXT values -** -title ("auto"|"off"|"sql"|...) How to escape column names +** -title ("auto"|"off"|"sql"|...|"off") How to escape column names ** -blob ("auto"|"text"|"sql"|...) How to escape BLOB values -** -columnnames ("auto"|"off"|"on") Show column names? ** -wordwrap ("auto"|"off"|"on") Try to wrap at word boundry? ** -textjsonb ("auto"|"off"|"on") Auto-convert JSONB to text? ** -textnull ("auto"|"off"|"on") Use text encoding for -null. ** -defaultalign ("auto"|"left"|...) Default alignment ** -titalalign ("auto"|"left"|"right"|...) Default column name alignment -** -maxcolwidth NUMBER Max width of any single column +** -wrap NUMBER Max width of any single column ** -screenwidth NUMBER Width of the display TTY -** -maxrowheight NUMBER Max height of a row in a table -** -maxlength NUMBER Content truncated to this size +** -linelimit NUMBER Max lines for any cell +** -charlimit NUMBER Content truncated to this size ** -align LIST-OF-ALIGNMENT Alignment of columns ** -widths LIST-OF-NUMBERS Widths for individual columns ** -columnsep TEXT Column separator text @@ -2085,18 +2084,17 @@ static void DbHookCmd( ** -style eStyle ** -esc eEsc ** -text eText -** -title eTitle +** -title eTitle, bTitle ** -blob eBlob -** -columnnames bColumnNames ** -wordwrap bWordWrap ** -textjsonb bTextJsonb ** -textnull bTestNull ** -defaultalign eDfltAlign ** -titlealign eTitleAlign -** -maxcolwidth mxColWidth +** -wrap nWrap ** -screenwidth nScreenWidth -** -maxrowheight mxRowHeight -** -maxlength mxLength +** -linelimit nLineLimit +** -charlimit nCharLimit ** -align nAlign, aAlign ** -widths nWidth, aWidth ** -columnsep zColumnSep @@ -2188,7 +2186,10 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ qrf.eEsc = aEscMap[esc]; i++; }else if( strcmp(zArg,"-text")==0 || strcmp(zArg, "-title")==0 ){ - static const char *azText[] = { + /* NB: --title can be "off" or "on but --text may not be. Thus we put + ** the "off" and "on" choices first and start the search on the + ** thrid element of the array when processing --text */ + static const char *azText[] = { "off", "on", "auto", "csv", "html", "json", "plain", "sql", "tcl", 0 @@ -2199,14 +2200,18 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ QRF_TEXT_Tcl }; int txt; - rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], azText, - zArg[2]=='e' ? "text encoding (-text)" : - "column-name encoding (-title)", 0, &txt); + int k = zArg[2]=='e'; + rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], &azText[k*2], zArg, + 0, &txt); if( rc ) goto format_failed; - if( zArg[2]=='e' ){ + if( k ){ qrf.eText = aTextMap[txt]; + }else if( txt<=1 ){ + qrf.bTitles = txt ? QRF_Yes : QRF_No; + qrf.eTitle = QRF_TEXT_Auto; }else{ - qrf.eTitle = aTextMap[txt]; + qrf.bTitles = QRF_Yes; + qrf.eTitle = aTextMap[txt-2]; } i++; }else if( strcmp(zArg,"-blob")==0 ){ @@ -2224,13 +2229,6 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ if( rc ) goto format_failed; qrf.eBlob = aBlobMap[blob]; i++; - }else if( strcmp(zArg,"-columnnames")==0 ){ - int v = 0; - rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], azBool, - "-columnnames", 0, &v); - if( rc ) goto format_failed; - qrf.bColumnNames = aBoolMap[v]; - i++; }else if( strcmp(zArg,"-wordwrap")==0 ){ int v = 0; rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], azBool, @@ -2262,9 +2260,9 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ qrf.eTitleAlign = aAlignMap[ax]; } i++; - }else if( strcmp(zArg,"-maxcolwidth")==0 + }else if( strcmp(zArg,"-wrap")==0 || strcmp(zArg,"-screenwidth")==0 - || strcmp(zArg,"-maxrowheight")==0 + || strcmp(zArg,"-linelimit")==0 ){ int v = 0; rc = Tcl_GetIntFromObj(pDb->interp, objv[i+1], &v); @@ -2274,20 +2272,20 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){ }else if( v>QRF_MAX_WIDTH ){ v = QRF_MAX_WIDTH; } - if( zArg[4]=='c' ){ - qrf.mxColWidth = v; - }else if( zArg[4]=='r' ){ - qrf.mxRowHeight = v; - }else{ + if( zArg[1]=='w' ){ + qrf.nWrap = v; + }else if( zArg[1]=='s' ){ qrf.nScreenWidth = v; + }else{ + qrf.nLineLimit = v; } i++; - }else if( strcmp(zArg,"-maxlength")==0 ){ + }else if( strcmp(zArg,"-charlimit")==0 ){ int v = 0; rc = Tcl_GetIntFromObj(pDb->interp, objv[i+1], &v); if( rc ) goto format_failed; if( v<0 ) v = 0; - qrf.mxLength = v; + qrf.nCharLimit = v; i++; }else if( strcmp(zArg,"-align")==0 ){ Tcl_Size n = 0; diff --git a/test/qrf01.test b/test/qrf01.test index a38b9905d8..0e6e3d932b 100644 --- a/test/qrf01.test +++ b/test/qrf01.test @@ -32,7 +32,7 @@ do_test 1.10 { └──────┴─────┴───────┘ } do_test 1.11a { - set result "\n[db format -columnnames off {SELECT * FROM t1}]" + set result "\n[db format -title off {SELECT * FROM t1}]" } { ┌──────┬─────┬───────┐ │ 1 │ 2.5 │ three │ @@ -72,7 +72,7 @@ do_test 1.13 { do_test 1.14 { catch {db format -text unk -blob hex {SELECT * FROM t1}} res set res -} {bad text encoding (-text) "unk": must be auto, csv, html, json, plain, sql, or tcl} +} {bad -text "unk": must be auto, csv, html, json, plain, sql, or tcl} do_test 1.15 { catch {db format -text sql -blob unk {SELECT * FROM t1}} res set res @@ -105,7 +105,7 @@ do_test 1.30 { +------+-----+-------+ } do_test 1.31 { - set result "\n[db format -style table -columnnames off {SELECT * FROM t1}]" + set result "\n[db format -style table -title off {SELECT * FROM t1}]" } { +------+-----+-------+ | 1 | 2.5 | three | @@ -122,7 +122,7 @@ a b c BLOB Ἀμήν } do_test 1.41 { - set result "\n[db format -style column -columnnames off {SELECT * FROM t1}]" + set result "\n[db format -style column -title off {SELECT * FROM t1}]" } { 1 2.5 three BLOB Ἀμήν @@ -136,10 +136,10 @@ do_test 1.60 { db format -style csv {SELECT * FROM t1} } "1,2.5,three\r\n\"\\102\\114\\117\\102\",,\"Ἀμήν\"\r\n" do_test 1.61 { - db format -style csv -columnnames on {SELECT * FROM t1} + db format -style csv -title auto {SELECT * FROM t1} } "a,b,c\r\n1,2.5,three\r\n\"\\102\\114\\117\\102\",,\"Ἀμήν\"\r\n" do_test 1.62 { - db format -style csv -columnnames on {SELECT a AS 'a x y', b, c FROM t1} + db format -style csv -title csv {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.70 { @@ -157,7 +157,7 @@ do_test 1.70 { } do_test 1.71 { - set result "\n[db format -style html -columnnames on {SELECT * FROM t1}]" + set result "\n[db format -style html -title auto {SELECT * FROM t1}]" } { a @@ -189,14 +189,14 @@ INSERT INTO t1 VALUES(1,2.5,'three'); INSERT INTO t1 VALUES(x'424c4f42',NULL,'Ἀμήν'); } do_test 1.82 { - set result "\n[db format -style insert -tablename t1 -columnnames on \ + set result "\n[db format -style insert -tablename t1 -title auto \ {SELECT * FROM t1}]" } { INSERT INTO t1(a,b,c) VALUES(1,2.5,'three'); INSERT INTO t1(a,b,c) VALUES(x'424c4f42',NULL,'Ἀμήν'); } do_test 1.83 { - set result "\n[db format -style insert -tablename drop -columnnames on \ + set result "\n[db format -style insert -tablename drop -title on \ {SELECT a AS "a-b", b, c AS "123" FROM t1}]" } { INSERT INTO "drop"("a-b",b,"123") VALUES(1,2.5,'three'); @@ -264,14 +264,14 @@ do_test 1.110 { BLOB||Ἀμήν } do_test 1.111 { - set result "\n[db format -style list -columnnames on {SELECT * FROM t1}]" + set result "\n[db format -style list -title on {SELECT * FROM t1}]" } { a|b|c 1|2.5|three BLOB||Ἀμήν } do_test 1.112 { - set result "\n[db format -style list -columnnames on -text sql -null NULL \ + set result "\n[db format -style list -title on -text sql -null NULL \ -title plain {SELECT * FROM t1}]" } { a|b|c @@ -279,9 +279,9 @@ a|b|c x'424c4f42'|NULL|'Ἀμήν' } do_test 1.118 { - set rc [catch {db format -style list -columnnames unk {SELECT * FROM t1}} res] + set rc [catch {db format -style list -title unk {SELECT * FROM t1}} res] lappend rc $res -} {1 {bad -columnnames "unk": must be auto, yes, no, on, or off}} +} {1 {bad -title "unk": must be off, on, auto, csv, html, json, plain, sql, or tcl}} do_test 1.120 { @@ -293,7 +293,7 @@ do_test 1.120 { | BLOB | | Ἀμήν | } do_test 1.121 { - set result "\n[db format -style markdown -columnnames off {SELECT * FROM t1}]" + set result "\n[db format -style markdown -title off {SELECT * FROM t1}]" } { | 1 | 2.5 | three | | BLOB | | Ἀμήν | @@ -306,7 +306,7 @@ do_test 1.130 { x'424c4f42',NULL,'Ἀμήν' } do_test 1.131 { - set result "\n[db format -style quote -columnnames on {SELECT * FROM t1}]" + set result "\n[db format -style quote -title on {SELECT * FROM t1}]" } { 'a','b','c' 1,2.5,'three' @@ -533,7 +533,7 @@ do_test 4.2 { └─────────────────┴─────────────────┴────┘ } do_test 4.3 { - set result "\n[db format -text plain -textjsonb on -maxcolwidth 11 \ + set result "\n[db format -text plain -textjsonb on -wrap 11 \ {SELECT a AS json, b AS jsonb, c AS num FROM t1}]" } { ┌─────────────┬─────────────┬─────┐ @@ -559,7 +559,7 @@ 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 -maxrowheight 77 $sql]" + -text sql -wordwrap off -linelimit 77 $sql]" } { name = 'sample-jsonb' mtime = 1333101221 @@ -596,7 +596,7 @@ do_test 5.2 { value FROM t1 ORDER BY mtime} set result "\n[db format -style line -screenwidth 60 -blob sql \ -text plain -esc off -textjsonb yes \ - -wordwrap yes -maxrowheight 3 $sql]" + -wordwrap yes -linelimit 3 $sql]" } { name = sample-jsonb mtime = 1333101221 @@ -625,7 +625,7 @@ do_test 5.3a { -align {left right right center} \ -blob sql \ -text plain -esc off -textjsonb no \ - -wordwrap yes -maxrowheight 2 $sql]" + -wordwrap yes -linelimit 2 $sql]" } { ┌──────────────┬────────────┬────────────┬────────────────┐ │ name │ mtime │ time │ value │ @@ -648,7 +648,7 @@ do_test 5.3b { -align {center right right right} \ -blob sql \ -text plain -esc off -textjsonb no \ - -wordwrap yes -maxrowheight 2 $sql]" + -wordwrap yes -linelimit 2 $sql]" } { +--------------+------------+------------+----------------+ | name | mtime | time | value | @@ -671,7 +671,7 @@ do_test 5.3c { -align {center right right right} \ -blob sql \ -text plain -esc off -textjsonb no \ - -wordwrap yes -maxrowheight 2 $sql]" + -wordwrap yes -linelimit 2 $sql]" } { name mtime time value ------------ ---------- ---------- -------------- @@ -696,7 +696,7 @@ do_test 5.4 { set sql {SELECT char(0x61,0xa,0x62,0xa,0x63,0xa,0x64) a, mtime b, mtime c, mtime d, mtime e FROM t1} set result "\n[db format -style box -widths {1 2 3 4 5}\ - -maxrowheight 3 -wordwrap off {SELECT *, 'x' AS x FROM t2}]" + -linelimit 3 -wordwrap off {SELECT *, 'x' AS x FROM t2}]" } { ┌────┬────┬─────┬──────┬───────┬───┐ │ a │ b │ c │ d │ e │ x │