]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the bBorder option to the QRF spec. Reflect this in the -border
authordrh <>
Wed, 26 Nov 2025 16:21:56 +0000 (16:21 +0000)
committerdrh <>
Wed, 26 Nov 2025 16:21:56 +0000 (16:21 +0000)
option on the TCL format method, and the --border option to ".mode"
in the CLI.  Also add the "psql" mode to the CLI.

FossilOrigin-Name: 02cbeb69884cd884d9b1b5f59c4168a3dc24b1a5aecc6967586c0be350b10574

ext/qrf/README.md
ext/qrf/qrf.c
ext/qrf/qrf.h
manifest
manifest.uuid
src/shell.c.in
src/tclsqlite.c
test/qrf01.test
test/shell1.test
test/shellA.test

index fce24c4e301254493fc004cb0548f660ba5c1aeb..d7fd0e47428770cdf6c75978e8e4cdd6bdb275ff 100644 (file)
@@ -75,6 +75,7 @@ struct sqlite3_qrf_spec {
   unsigned char eDfltAlign;   /* Default alignment, no covered by aAlignment */
   unsigned char eTitleAlign;  /* Alignment for column headers */
   unsigned char bSplitColumn; /* Wrap single-column output into many columns */
+  unsigned char bBorder;      /* Show outer border in Box and Table styles */
   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 */
@@ -587,8 +588,12 @@ to draw the grid. The **Column** arranges the results in neat columns
 but does not draw in column or row separator, except that it does draw
 lines horizontal lines using "`-`" characters to separate the column names
 from the data below.  This is very similar to default output styling in
-psql.  The **Markdown** renders its result in the
-Markdown table format.
+psql.  The **Markdown** renders its result in the Markdown table format.
+
+The **Box** and **Table** styles normally have a border that surrounds
+the entire result.  However, if sqlite3_qrf_spec.bBorder is QRF_No, then
+that border is omitted, saving a little space both horizontally and
+vertically.
 
 #### 4.2.1 Split Column Mode
 
index 24a19f663378f80fee92083bd8ff015f44cca45a..cc73a5f039715b3f6dc76de676e18eb3762670ae 100644 (file)
@@ -1370,13 +1370,24 @@ static int qrfColDataEnlarge(qrfColData *p){
 static void qrfRowSeparator(sqlite3_str *pOut, qrfColData *p, char cSep){
   int i;
   if( p->nCol>0 ){
-    sqlite3_str_append(pOut, &cSep, 1);
-    sqlite3_str_appendchar(pOut, p->a[0].w+p->nMargin, '-');
+    int endMargin;
+    int useBorder = p->p->spec.bBorder!=QRF_No;
+    if( useBorder ){
+      sqlite3_str_append(pOut, &cSep, 1);
+      endMargin = p->nMargin;
+    }else{
+      endMargin = p->nCol>1 ? p->nMargin/2 : 0;
+    }
+    sqlite3_str_appendchar(pOut, p->a[0].w+endMargin, '-');
     for(i=1; i<p->nCol; i++){
+      int w = p->a[i].w;
+      w += (i+1)==p->nCol ? endMargin : p->nMargin;
+      sqlite3_str_append(pOut, &cSep, 1);
+      sqlite3_str_appendchar(pOut, w, '-');
+    }
+    if( useBorder ){
       sqlite3_str_append(pOut, &cSep, 1);
-      sqlite3_str_appendchar(pOut, p->a[i].w+p->nMargin, '-');
     }
-    sqlite3_str_append(pOut, &cSep, 1);
   }
   sqlite3_str_append(pOut, "\n", 1);
 }
@@ -1434,13 +1445,24 @@ static void qrfBoxSeparator(
 ){
   int i;
   if( p->nCol>0 ){
-    sqlite3_str_appendall(pOut, zSep1);
-    qrfBoxLine(pOut, p->a[0].w+p->nMargin);
+    int endMargin;
+    int useBorder = p->p->spec.bBorder!=QRF_No;
+    if( useBorder ){
+      sqlite3_str_appendall(pOut, zSep1);
+      endMargin = p->nMargin;
+    }else{
+      endMargin = p->nCol>1 ? p->nMargin/2 : 0;
+    }
+    qrfBoxLine(pOut, p->a[0].w+endMargin);
     for(i=1; i<p->nCol; i++){
+      int w = p->a[i].w;
+      w += i==p->nCol-1 ? endMargin : p->nMargin;     
       sqlite3_str_appendall(pOut, zSep2);
-      qrfBoxLine(pOut, p->a[i].w+p->nMargin);
+      qrfBoxLine(pOut, w);
+    }
+    if( useBorder ){
+      sqlite3_str_appendall(pOut, zSep3);
     }
-    sqlite3_str_appendall(pOut, zSep3);
   }
   sqlite3_str_append(pOut, "\n", 1);
 }
@@ -1608,6 +1630,7 @@ static void qrfRestrictScreenWidth(qrfColData *pData, Qrf *p){
     sepW = pData->nCol*2 - 2;
   }else{
     sepW = pData->nCol*3 + 1;
+    if( p->spec.bBorder==QRF_No ) sepW -= 4;
   }
   nCol = pData->nCol;
   for(i=sumW=0; i<nCol; i++) sumW += pData->a[i].w;
@@ -1619,6 +1642,7 @@ static void qrfRestrictScreenWidth(qrfColData *pData, Qrf *p){
     sepW = pData->nCol - 1;
   }else{
     sepW = pData->nCol + 1;
+    if( p->spec.bBorder==QRF_No ) sepW -= 2;
   }
   targetW = p->spec.nScreenWidth - sepW;
 
@@ -1691,6 +1715,7 @@ static void qrfColumnar(Qrf *p){
   /* Initialize the data container */
   memset(&data, 0, sizeof(data));
   data.nCol = p->nCol;
+  data.p = p;
   data.a = sqlite3_malloc64( nColumn*sizeof(struct qrfPerCol) );
   if( data.a==0 ){
     qrfOom(p);
@@ -1821,7 +1846,12 @@ static void qrfColumnar(Qrf *p){
         colSep = BOX_13;
         rowSep = BOX_13 "\n";
       }
-      qrfBoxSeparator(p->pOut, &data, BOX_23, BOX_234, BOX_34);
+      if( p->spec.bBorder==QRF_No){
+        rowStart = "";
+        rowSep = "\n";
+      }else{
+        qrfBoxSeparator(p->pOut, &data, BOX_23, BOX_234, BOX_34);
+      }
       break;
     case QRF_STYLE_Table:
       if( data.nMargin ){
@@ -1833,7 +1863,12 @@ static void qrfColumnar(Qrf *p){
         colSep = "|";
         rowSep = "|\n";
       }
-      qrfRowSeparator(p->pOut, &data, '+');
+      if( p->spec.bBorder==QRF_No ){
+        rowStart = "";
+        rowSep = "\n";
+      }else{
+        qrfRowSeparator(p->pOut, &data, '+');
+      }
       break;
     case QRF_STYLE_Column: {
       static const char zSpace[] = "     ";
@@ -1865,7 +1900,15 @@ static void qrfColumnar(Qrf *p){
   szColSep = (int)strlen(colSep);
 
   bWW = (p->spec.bWordWrap==QRF_Yes && data.bMultiRow);
-  bRTrim = (p->spec.eStyle==QRF_STYLE_Column);
+  if( p->spec.eStyle==QRF_STYLE_Column
+   || (p->spec.bBorder==QRF_No
+       && (p->spec.eStyle==QRF_STYLE_Box || p->spec.eStyle==QRF_STYLE_Table)
+      )
+  ){
+    bRTrim = 1;
+  }else{
+    bRTrim = 0;
+  }
   for(i=0; i<data.n; i+=nColumn){
     int bMore;
     int nRow = 0;
@@ -1968,13 +2011,15 @@ static void qrfColumnar(Qrf *p){
   }
 
   /* Draw the line across the bottom of the table */
-  switch( p->spec.eStyle ){
-    case QRF_STYLE_Box:
-      qrfBoxSeparator(p->pOut, &data, BOX_12, BOX_124, BOX_14);
-      break;
-    case QRF_STYLE_Table:
-      qrfRowSeparator(p->pOut, &data, '+');
-      break;
+  if( p->spec.bBorder!=QRF_No ){
+    switch( p->spec.eStyle ){
+      case QRF_STYLE_Box:
+        qrfBoxSeparator(p->pOut, &data, BOX_12, BOX_124, BOX_14);
+        break;
+      case QRF_STYLE_Table:
+        qrfRowSeparator(p->pOut, &data, '+');
+        break;
+    }
   }
   qrfWrite(p);
 
index ddce3d1e795c879817ab48fad0992c6354581ebe..baaeb4b18d320cb3a25aff566ef67bc4627b631c 100644 (file)
@@ -37,6 +37,7 @@ struct sqlite3_qrf_spec {
   unsigned char eDfltAlign;   /* Default alignment, no covered by aAlignment */
   unsigned char eTitleAlign;  /* Alignment for column headers */
   unsigned char bSplitColumn; /* Wrap single-column output into many columns */
+  unsigned char bBorder;      /* Show outer border in Box and Table styles */
   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 */
index 7c5ffd931ab3ffe58c021576c39d7a96b416d704..0dd1cc4ff24ca68ffaa4e5f1604070ae5a8410cd 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sbuffer\soverread\sin\sfts5\sthat\smight\soccur\swhile\sprocessing\sa\scorrupt\sdb.
-D 2025-11-26T13:58:53.816
+C Add\sthe\sbBorder\soption\sto\sthe\sQRF\sspec.\s\sReflect\sthis\sin\sthe\s-border\noption\son\sthe\sTCL\sformat\smethod,\sand\sthe\s--border\soption\sto\s".mode"\nin\sthe\sCLI.\s\sAlso\sadd\sthe\s"psql"\smode\sto\sthe\sCLI.
+D 2025-11-26T16:21:56.554
 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 c4ee554743fa61858e5685a90689c011adb549a4e5467d3c639c9bc57ba00bb0
-F ext/qrf/qrf.c 838c5af2b59b88640b1fd3665396ce15b1c6ed93612bdbc18e142a81d321e097
-F ext/qrf/qrf.h fe677b8564dd8feaff6d2876a0e06c2e1d8ceaa6f00acd179da92a9e87c2955a
+F ext/qrf/README.md c63030fbaf2f5ceedc574749a0630da14bdac4f4ffe70415ddb0e64fc9876aa2
+F ext/qrf/qrf.c b134a3d07cea77d27301dca44bcd8d3cd1551cbed7e51c21854bb6fe570995fa
+F ext/qrf/qrf.h 322d48537a5aa39c206c2ec0764a7938ea7662a8c25be1c4e9d742789609ba1e
 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
 F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363
@@ -736,7 +736,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 990817862286db8f05d2274c20a730d27218c7bb1aa79da3c7c796a3d5f137b2
+F src/shell.c.in d139d8f1fe138235be68da9183fea6d2bceac642e2c3432ddebd7b8a100a46c8
 F src/sqlite.h.in f1363321ca55cc2feaa289e9fe6dfb08102a28c54edf005564711a2348b06eef
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 5d5330f5f8461f5ce74960436ddcfa53ecd09c2b8b23901e22ae38aec3243998
@@ -744,7 +744,7 @@ F src/sqliteInt.h a89c3a9296928dffcb4c287df176a739f9cf620c7c9d33aec59e8efb9b39cb
 F src/sqliteLimit.h 0a5516b4ec192a205c541e05f67009028a9451dc6678aae4cf8e68596903c246
 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
-F src/tclsqlite.c d0afbb037e9c6e505312eb811fd7ee7ce28328d57bb8c46312fd676ca4e30318
+F src/tclsqlite.c ec2ad3fbf5390c3d4307bc9d1f2a37a9c5d726b5309769dc770ab37f6812152d
 F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
 F src/test1.c 0e71fbcb484a271564e98e0158192c28c24f5521594218c3ba48bcb4cf634f91
 F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
@@ -1510,7 +1510,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 1cd0ef5c758dca528f01e47504f3b3181463a29919de06a9dffa7fe174575ead
+F test/qrf01.test 6cef9377ad7defbb9dce75e022304807b75b5f1a7e17d1cafdea05bf076cc7f9
 F test/qrf02.test 39b4afdc000bedccdafc0aecf17638df67a67aaa2d2942865ae6abcc48ba0e92
 F test/qrf03.test 9de53aea459f5a127283db03cbb6011500757685646d21aa3c29c44c6ef23e86
 F test/qrf04.test 0894692c998d2401dcc33449c02051b503ecce0c94217be54fb007c82d2d1379
@@ -1607,7 +1607,7 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
 F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
-F test/shell1.test 9438957ab1c0d4c4622b98a11648999a86b6184c8317a87d3c5cb760d2f7bca9
+F test/shell1.test 5c46dd31357c3cc23a225ea8728563059db0f457c7569624a5f6a8fe44baa671
 F test/shell2.test 103140814bdc7508aa41dd3462413cbc4aa84b4261112cb8d501d74275cb7d48
 F test/shell3.test 840192774cc4edf7653520c0434a311c7477b9bc324abbc7bd2887915792fa8c
 F test/shell4.test e25580a792b7b54560c3a76b6968bd8189261f38979fe28e6bc6312c5db280db
@@ -1616,7 +1616,7 @@ F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bd
 F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3
 F test/shell8.test 641cf21a99c59404c24e3062923734951c4099a6b6b6520de00cf7a1249ee871
 F test/shell9.test 8742a5b390cdcef6369f5aa223e415aa4255a4129ef249b177887dc635a87209
-F test/shellA.test 4b8983a40703b5550f691592b6c5bc64886c26755eeb7a474af849d1e39b51f2
+F test/shellA.test 3ee819f0e681e649b51c906a29d59abb10215c44e070d18500032f94bbc3fd3a
 F test/shellB.test de879b1ea7c25daf1a06b2c882b45a5d002e6580c81c57169ce47084cc6afb6b
 F test/shmlock.test 9f1f729a7fe2c46c88b156af819ac9b72c0714ac6f7246638a73c5752b5fd13c
 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
@@ -2180,8 +2180,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 aa9d7365bb8d8a9d44388dc89dea09428d7cea2f9fba482cb56980b51b16b143
-R 5e44b544504a3631820cb0247deb77ab
-U dan
-Z 9f53e54c4bd9a5cb67f11a90d3e4df95
+P 8b0cbc18be3c6f2501b102757af6be98c48044a296104cca7bce822ac2304515
+R 8945f4ddcddcd63749e20ffed7b156be
+U drh
+Z 40eaa1e5fedbd407b6fc2b7e3ad849db
 # Remove this line to create a well-formed Fossil manifest.
index 3d1e57cd6eed2229c0a1ab1f24c6db19afd0825f..8990fd26e9be3d908b74375a48f5bdea139136c4 100644 (file)
@@ -1 +1 @@
-8b0cbc18be3c6f2501b102757af6be98c48044a296104cca7bce822ac2304515
+02cbeb69884cd884d9b1b5f59c4168a3dc24b1a5aecc6967586c0be350b10574
index ca76c4065231b025a7b73520708e7f0c68a435a2..c1012a7d76494eb7a4a687d8c85ddb7194dd8197 100644 (file)
@@ -1428,15 +1428,16 @@ static const char *qrfQuoteNames[] =
 #define MODE_List     12  /* One record per line with a separator */
 #define MODE_Markdown 13  /* Markdown formatting */
 #define MODE_Off      14  /* No query output shown */
-#define MODE_QBox     15  /* BOX with SQL-quoted content */
-#define MODE_Quote    16  /* Quote values as for SQL */
-#define MODE_Split    17  /* Split-column mode */
-#define MODE_Table    18  /* MySQL-style table formatting */
-#define MODE_Tabs     19  /* Tab-separated values */
-#define MODE_Tcl      20  /* Space-separated list of TCL strings */
-#define MODE_Www      21  /* Full web-page output */
-
-#define MODE_BUILTIN  21  /* Maximum built-in mode */
+#define MODE_Psql     15  /* Similar to psql */
+#define MODE_QBox     16  /* BOX with SQL-quoted content */
+#define MODE_Quote    17  /* Quote values as for SQL */
+#define MODE_Split    18  /* Split-column mode */
+#define MODE_Table    19  /* MySQL-style table formatting */
+#define MODE_Tabs     20  /* Tab-separated values */
+#define MODE_Tcl      21  /* Space-separated list of TCL strings */
+#define MODE_Www      22  /* Full web-page output */
+
+#define MODE_BUILTIN  22  /* Maximum built-in mode */
 #define MODE_BATCH    50  /* Default mode for batch processing */
 #define MODE_TTY      51  /* Default mode for interactive processing */
 #define MODE_USER     75  /* First user-defined mode */
@@ -1457,6 +1458,7 @@ struct ModeInfo {
   unsigned char bHdr;    /* Show headers by default.  0: n/a, 1: no 2: yes */
   unsigned char eStyle;  /* Underlying QRF style */
   unsigned char eCx;     /* 0: other, 1: line, 2: columnar */
+  unsigned char mFlg;    /* Flags. 1=border-off 2=split-column */
 };
 
 /* String constants used by built-in modes */
@@ -1467,29 +1469,30 @@ static const char *aModeStr[] =
   /* 9    10      11      12                                            */
 
 static const ModeInfo aModeInfo[] = {
-/*   zName      eCSep  eRSep eNull eText eHdr eBlob bHdr eStyle eCx */
-  { "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,    0,   2,   2,     2 },
-  { "count",    0,     0,    0,    0,    0,    0,   0,   3,     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,    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,    10,   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,    0,   2,   7,     0 }
+/*   zName      eCSep  eRSep eNull eText eHdr eBlob bHdr eStyle eCx mFlg */
+  { "ascii",    7,     6,    9,    1,    1,    0,   1,   12,    0,  0 },
+  { "box",      0,     0,    9,    1,    1,    0,   2,   1,     2,  0 },
+  { "c",        4,     1,    10,   5,    5,    4,   1,   12,    0,  0 },
+  { "column",   0,     0,    9,    1,    1,    0,   2,   2,     2,  0 },
+  { "count",    0,     0,    0,    0,    0,    0,   0,   3,     0,  0 },
+  { "csv",      4,     5,    9,    3,    3,    0,   1,   12,    0,  0 },
+  { "html",     0,     0,    9,    4,    4,    0,   2,   7,     0,  0 },
+  { "insert",   0,     0,    10,   2,    2,    0,   1,   8,     0,  0 },
+  { "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 },
+  { "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 },
+  { "psql",     0,     0,    9,    1,    1,    0,   2,   19,    2,  1 },
+  { "qbox",     0,     0,    10,   2,    1,    0,   2,   1,     2,  0 },
+  { "quote",    4,     1,    10,   2,    2,    0,   1,   12,    0,  0 },
+  { "split",    0,     0,    9,    1,    1,    0,   1,   2,     2,  2 },
+  { "table",    0,     0,    9,    1,    1,    0,   2,   19,    2,  0 },
+  { "tabs",     8,     1,    9,    3,    3,    0,   1,   12,    0,  0 },
+  { "tcl",      3,     1,    12,   5,    5,    4,   1,   12,    0,  0 },
+  { "www",      0,     0,    9,    4,    4,    0,   2,   7,     0,  0 }
 };     /*       |     /     /      |     /    /     |    |       \
        **       |    /     /       |    /    /      |    |        \_ 2: columnar
        ** Index into aModeStr[]    |   /    /       |    |           1: line
@@ -1615,7 +1618,12 @@ static void modeChange(ShellState *p, unsigned char eMode){
     pM->spec.eBlob = pI->eBlob;
     pM->spec.bTitles = pI->bHdr;
     pM->spec.eTitle = pI->eHdr;
-    if( eMode==MODE_Split ){
+    if( pI->mFlg & 0x01 ){
+      pM->spec.bBorder = QRF_No;
+    }else{
+      pM->spec.bBorder = QRF_Auto;
+    }
+    if( pI->mFlg & 0x02 ){
       pM->spec.bSplitColumn = QRF_Yes;
       pM->bAutoScreenWidth = 1;
     }else{
@@ -7675,6 +7683,7 @@ static int modeTitleDsply(ShellState *p, int bAll){
 **                            Unspecified alignment defaults to 'L'.
 **   --blob-quote ARG         ARG can be "auto", "text", "sql", "hex", "tcl",
 **                            "json", or "size".  Default is "auto".
+**   --border on|off          Show outer border on "box" and "table" modes.
 **   --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".
@@ -7793,6 +7802,16 @@ static int dotCmdMode(ShellState *p){
         p->mode.spec.eBlob = k & 0xff;
       }
       chng = 1;
+    }else if( optionMatch(z,"border") ){
+      if( (++i)>=nArg ){
+        dotCmdError(p, i-1, "missing argument", 0);
+        return 1;
+      }
+      k = pickStr(azArg[i], 0, "auto", "off", "on", "");
+      if( k>=0 ){
+        p->mode.spec.bBorder = k & 0x3;
+      }
+      chng = 1;
     }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){
       int w;                /*   0            1  */
       if( i+1>=nArg ){
@@ -8095,6 +8114,12 @@ static int dotCmdMode(ShellState *p){
       }
       sqlite3_str_append(pDesc, "\"", 1);
     }
+    if( bAll
+     || (p->mode.spec.bBorder==QRF_No) != ((pI->mFlg&1)!=0)
+    ){
+      sqlite3_str_appendf(pDesc," --border %s",
+             p->mode.spec.bBorder==QRF_No ? "off" : "on");
+    }
     if( bAll || p->mode.spec.eBlob!=QRF_BLOB_Auto ){
       const char *azBQuote[] =
            { "auto", "text", "sql", "hex", "tcl", "json", "size" };
@@ -12807,6 +12832,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       modeChange(&data, MODE_Markdown);
     }else if( cli_strcmp(z,"-table")==0 ){
       modeChange(&data, MODE_Table);
+    }else if( cli_strcmp(z,"-psql")==0 ){
+      modeChange(&data, MODE_Psql);
     }else if( cli_strcmp(z,"-box")==0 ){
       modeChange(&data, MODE_Box);
     }else if( cli_strcmp(z,"-csv")==0 ){
index 39b1782ae6dc1301cd92bdef1d577f90c8df2702..3cedbf9c30ab0660f8072c8771b70f7b73b4ce31 100644 (file)
@@ -2065,6 +2065,7 @@ static void DbHookCmd(
 **     -splitcolumn ("auto"|"off"|"on")        Enable split-column mode
 **     -defaultalign ("auto"|"left"|...)       Default alignment
 **     -titalalign ("auto"|"left"|"right"|...) Default column name alignment
+**     -border ("auto"|"off"|"on")             Border for box and table styles
 **     -wrap NUMBER                            Max width of any single column
 **     -screenwidth NUMBER                     Width of the display TTY
 **     -linelimit NUMBER                       Max lines for any cell
@@ -2091,6 +2092,7 @@ static void DbHookCmd(
 **     -splitcolumn      bSplitColumn
 **     -defaultalign     eDfltAlign
 **     -titlealign       eTitleAlign
+**     -border           bBorder
 **     -wrap             nWrap
 **     -screenwidth      nScreenWidth
 **     -linelimit        nLineLimit
@@ -2240,13 +2242,16 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
       i++;
     }else if( strcmp(zArg,"-textjsonb")==0
            || strcmp(zArg,"-splitcolumn")==0
+           || strcmp(zArg,"-border")==0
     ){
       int v = 0;
       rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], azBool,
                               zArg, 0, &v);
       if( rc ) goto format_failed;
-      if( zArg[5]=='j' ){
+      if( zArg[1]=='t' ){
         qrf.bTextJsonb = aBoolMap[v];
+      }else if( zArg[1]=='b' ){
+        qrf.bBorder = aBoolMap[v];
       }else{
         qrf.bSplitColumn = aBoolMap[v];
       }
index 3dffa74d8239196bff54aa000cda47a45ae1c1b8..6ef8acf6c8d4e13c0102cd22889a4046481f30da 100644 (file)
@@ -49,6 +49,14 @@ do_test 1.11b {
 │ x'424c4f42' │     │ 'Ἀμήν'  │
 └─────────────┴─────┴─────────┘
 }
+do_test 1.11c {
+  set result "\n[db format -text sql -border off {SELECT * FROM t1}]"
+} {
+     a      │  b  │    c
+────────────┼─────┼────────
+1           │ 2.5 │ 'three'
+x'424c4f42' │     │ 'Ἀμήν'
+}
 do_test 1.12 {
   set result "\n[db format -text csv {SELECT * FROM t1}]"
 } {
@@ -112,6 +120,15 @@ do_test 1.31 {
 | BLOB |     | Ἀμήν  |
 +------+-----+-------+
 }
+do_test 1.32 {
+  set result "\n[db format -style table -border off {SELECT * FROM t1}]"
+} {
+ a   |  b  |   c
+-----+-----+------
+1    | 2.5 | three
+BLOB |     | Ἀμήν
+}
+
 
 do_test 1.40 {
   set result "\n[db format -style column {SELECT * FROM t1}]"
index 539d8ef830dbaa09f4c7b95874af9adfc73ea24f..a5bcd4cab17ae73ec56088c9d71cdda422fcd247 100644 (file)
@@ -1311,6 +1311,12 @@ do_test shell1-8.4 {
 +------------------+-----+
 | 6683623321994527 | -47 |
 +------------------+-----+}}
+do_test shell1-8.4b {
+  catchcmd ":memory: --psql" \
+    {SELECT ieee754_mantissa(47.49) AS M, ieee754_exponent(47.49) AS E;}
+} {0 {       M         |  E
+-----------------+----
+6683623321994527 | -47}}
 do_test_with_ansi_output shell1-8.5 {
   catchcmd ":memory: --box" {
 create table t(a text, b int);
index e3d2e1b9d0aa233ebff3a04c091fb1264ee8147e..3f0647aa3d66fc533ae1eb61337561a2e76d02a4 100644 (file)
@@ -197,6 +197,24 @@ do_test_with_ansi_output shellA-4.1 {
 │ 8 │ last line                │
 └───┴──────────────────────────┘
 }
+do_test_with_ansi_output shellA-4.1b {
+ exec {*}$CLI -noinit test.db --box --escape ascii \
+    {.mode -border off} \
+    {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
+} {
+a │            x
+──┼─────────────────────────
+1 │ line with ' single quote
+──┼─────────────────────────
+2 │ ^[[31mVT-100 codes^[[0m
+──┼─────────────────────────
+6 │ new
+  │ line
+──┼─────────────────────────
+7 │ carriage^Mreturn
+──┼─────────────────────────
+8 │ last line
+}
 do_test_with_ansi_output shellA-4.2 {
  exec {*}$CLI -noinit test.db {.mode qbox} {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
 } {
@@ -210,6 +228,18 @@ do_test_with_ansi_output shellA-4.2 {
 │ 8 │ 'last line'                               │
 └───┴───────────────────────────────────────────┘
 }
+do_test_with_ansi_output shellA-4.2b {
+ exec {*}$CLI -noinit test.db {.mode qbox -border off} \
+    {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
+} {
+a │                     x
+──┼──────────────────────────────────────────
+1 │ 'line with '' single quote'
+2 │ unistr('\u001b[31mVT-100 codes\u001b[0m')
+6 │ unistr('new\u000aline')
+7 │ unistr('carriage\u000dreturn')
+8 │ 'last line'
+}
 
 # ".mode insert"
 #