]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the --once option to the .mode command. Improvements to help text.
authordrh <>
Fri, 14 Nov 2025 17:11:06 +0000 (17:11 +0000)
committerdrh <>
Fri, 14 Nov 2025 17:11:06 +0000 (17:11 +0000)
FossilOrigin-Name: 253980122a35f787423aaeedbec12ec94b31768f245fe1c1fcc7e08911855c60

manifest
manifest.uuid
src/shell.c.in

index daafd458cad5154dd4f52394d12285c611ef83fc..ab709ab43453d3ac2af736d19f5756c950dee14a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sharmless\scompiler\swarnings.\s\sIncorporate\s"USAGE:"\scomments\son\sdot-command\nimplementations\sinto\sthe\sCLI\s".help"\scommand\soutput.
-D 2025-11-14T14:59:43.895
+C Add\sthe\s--once\soption\sto\sthe\s.mode\scommand.\s\sImprovements\sto\shelp\stext.
+D 2025-11-14T17:11:06.215
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -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 a1c46ccb2e2eb8ffe489ee8fed03d42f386c9bd5ffa74b9fbf0fcc330c5cf18f
+F src/shell.c.in 80cddc5b2c3b9a2317ba673566b3a4091948ee640cf9e80daa432556418e61aa
 F src/sqlite.h.in 684c19c3b093cca7a38e3f6405d067777464285f17a58a78f7f89d6763e011e7
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52
@@ -2175,8 +2175,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 2220cb70c2f1ee30dcdf917a20feacdfcb3789433d0645fea626fd4c5cf0d099
-R 502efdf1aafac3b4fa047f717c227b57
+P 046bfab4a01e8a7cc58d1bdf0756c90ba354562d79e5453c08202daf648e76a6
+R 617f8c7d32295d372a6a7a285c1648b3
 U drh
-Z 84e7db1443d1d78445106107a04c9aa2
+Z 8d9d41d539e868e42ddb8706f8074151
 # Remove this line to create a well-formed Fossil manifest.
index bef4e23e54b53ab557d4474ccc969f43e034c218..8aacf80ba640c809759e0113b9df0ce373f28569 100644 (file)
@@ -1 +1 @@
-046bfab4a01e8a7cc58d1bdf0756c90ba354562d79e5453c08202daf648e76a6
+253980122a35f787423aaeedbec12ec94b31768f245fe1c1fcc7e08911855c60
index f8d3bb8eab5b6632bcac1627ef33e87088d6bfdd..bb79a756817988f0e8fb55e873ec66491e881566 100644 (file)
@@ -1273,9 +1273,9 @@ struct ShellState {
   u8 eRestoreState;      /* See comments above doAutoDetectRestore() */
   unsigned statsOn;      /* True to display memory stats before each finalize */
   unsigned mEqpLines;    /* Mask of vertical lines in the EQP output graph */
+  u8 nPopOutput;         /* Revert .output settings when reaching zero */
+  u8 nPopMode;           /* Revert .mode settings when reaching zero */
   int inputNesting;      /* Track nesting level of .read and other redirects */
-  int outCount;          /* Revert to stdout when reaching zero */
-  int cnt;               /* Number of records displayed so far */
   i64 lineno;            /* Line number of last line read from in */
   const char *zInFile;   /* Name of the input file */
   int openFlags;         /* Additional flags to open.  (SQLITE_OPEN_NOFOLLOW) */
@@ -1617,6 +1617,23 @@ static int modeFind(const char *zName){
   return -1;
 }
 
+/*
+** Save or restore the current output mode
+*/
+static void modePush(ShellState *p){
+  if( p->nPopMode==0 ){
+    modeFree(&p->modePrior);
+    modeDup(&p->modePrior,&p->mode);
+  }
+}
+static void modePop(ShellState *p){
+  if( p->modePrior.spec.iVersion>0 ){
+    modeFree(&p->mode);
+    p->mode = p->modePrior;
+    memset(&p->modePrior, 0, sizeof(p->modePrior));
+  }
+}
+
 
 /*
 ** A callback for the sqlite3_log() interface.
@@ -1861,21 +1878,6 @@ edit_func_end:
 }
 #endif /* SQLITE_NOHAVE_SYSTEM */
 
-/*
-** Save or restore the current output mode
-*/
-static void outputModePush(ShellState *p){
-  modeFree(&p->modePrior);
-  modeDup(&p->modePrior,&p->mode);
-  p->priorShFlgs = p->shellFlgs;
-}
-static void outputModePop(ShellState *p){
-  modeFree(&p->mode);
-  p->mode = p->modePrior;
-  modeInit(&p->modePrior);
-  p->shellFlgs = p->priorShFlgs;
-}
-
 /*
 ** Set output mode to text or binary for Windows.
 */
@@ -3150,10 +3152,9 @@ static int shell_exec(
       if( zStmtSql==0 ) zStmtSql = "";
       while( IsSpace(zStmtSql[0]) ) zStmtSql++;
 
-      /* save off the prepared statement handle and reset row count */
+      /* save off the prepared statement handle */
       if( pArg ){
         pArg->pStmt = pStmt;
-        pArg->cnt = 0;
       }
      
       /* Show the EXPLAIN QUERY PLAN if .eqp is on */
@@ -3908,6 +3909,7 @@ static int showHelp(FILE *out, const char *zPattern){
   int j = 0;
   int n = 0;
   char *zPat;
+  const char *zHit = 0;
   if( zPattern==0 ){
     /* Show just the first line for all help topics */
     zPattern = "[a-z]";
@@ -3939,7 +3941,8 @@ static int showHelp(FILE *out, const char *zPattern){
   shell_check_oom(zPat);
   for(i=0; i<ArraySize(azHelp); i++){
     if( sqlite3_strglob(zPat, azHelp[i])==0 ){
-      cli_printf(out, "%s\n", azHelp[i]);
+      if( zHit ) cli_printf(out, "%s\n", zHit);
+      zHit = azHelp[i];
       j = i+1;
       n++;
     }
@@ -3952,11 +3955,14 @@ static int showHelp(FILE *out, const char *zPattern){
       }else{
         /* when zPattern is a prefix of exactly one command, then include
         ** the details of that command, which should begin at offset j */
+        cli_printf(out, "%s\n", zHit);
         while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
           cli_printf(out, "%s\n", azHelp[j]);
           j++;
         }
       }
+    }else{
+      cli_printf(out, "%s\n", zHit);
     }
   }
   sqlite3_free(zPat);
@@ -5223,7 +5229,7 @@ static void output_reset(ShellState *p){
         sqlite3_sleep(2000);
       }
       sqlite3_free(zCmd);
-      outputModePop(p);
+      modePop(p);
       p->doXdgOpen = 0;
     }
 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
@@ -7283,73 +7289,57 @@ static int modeTitleDsply(ShellState *p, int bAll){
 /*
 ** DOT-COMMAND:  .mode
 **
-** USAGE:  .mode [MODE] [OPTIONS]
+** USAGE: .mode [MODE] [OPTIONS]
 **
 ** Change the output mode to MODE and/or apply OPTIONS to the
 ** output mode.  If no arguments, show the current output mode
 ** and relevant options.
 **
 ** Options:
-**
 **   --align  STRING          Set the alignment of text in columnar modes
 **                            String consists of characters 'L', 'C', 'R'
 **                            meaning "left", "centered", and "right", with
 **                            one letter per column starting from the left.
 **                            Unspecified alignment defaults to 'L'.
-**
 **   --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".
-**
 **   --colsep  STRING         Use STRING as the column separator
-**
 **   --escape  ESC            Enable/disable escaping of control characters
 **                            in output. ESC can be "off", "ascii", or
 **                            "symbol".
-**
 **   --linelimit N            Set the maximum number of output lines to show for
 **                            any single SQL value to N. Longer values are
 **                            truncated. Zero means "no limit". Only works
 **                            in "line" mode and in columnar modes.
-**
 **   --null  STRING           Render SQL NULL values as the given string
-**
+**   --once                   Setting changes to the left are reverted after
+**                            the next SQL command.
 **   --quote  ARG             Enable/disable quoting of text. ARG can be
 **                            "off", "on", "sql", "csv", "html", "tcl",
 **                            or "json".  "off" means show the text as-is.
 **                            "on and "sql" are synonyms.
-**
 **   --reset                  Changes all mode settings back to their default.
-**
 **   --rowsep  STRING         Use STRING as the row separator
-**
 **   --screenwidth N          Declare the screen width of the output device
 **                            to be N characters.  An attempt may be made to
 **                            wrap output text to fit within this limit. Zero
 **                            means "no limit".  Or N can be "auto" to set the
 **                            width automatically.
-**
 **   --tablename  NAME        Set the name of the table for "insert" mode.
-**
 **   --textjsonb  BOOLEAN     If enabled, JSONB text is displayed as text JSON.
-**
 **   --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".
-**
 **   -v|--verbose             Verbose output
-**
 **   --widths  LIST           Set the columns widths for columnar modes. The
 **                            argument is a list of integers, one for each
 **                            column. A "0" width means use a dynamic width
 **                            based on the actual width of data. If there are
 **                            fewer entries in LIST than columns, "0" is used
 **                            for the unspecified widths.
-**
 **   --wordwrap  BOOLEAN      Enable/disable word wrapping
-**
 **   --wrap  N                Wrap columns wider than N characters
-**
 **   --ww                     Shorthand for "--wordwrap on"
 */
 static int dotCmdMode(ShellState *p){
@@ -7512,6 +7502,10 @@ static int dotCmdMode(ShellState *p){
       p->mode.spec.eText = QRF_TEXT_Plain;
       p->mode.spec.eBlob = QRF_BLOB_Text;
       chng = 1;
+    }else if( optionMatch(z,"once") ){
+      p->nPopMode = 0;
+      modePush(p);
+      p->nPopMode = 1;
     }else if( optionMatch(z,"reset") ){
       int saved_eMode = p->mode.eMode;
       modeFree(&p->mode);
@@ -7634,6 +7628,7 @@ static int dotCmdMode(ShellState *p){
     char *zDesc;
     const char *zSetting;
 
+    if( p->nPopMode ) sqlite3_str_appendall(pDesc, "--once ");
     sqlite3_str_appendall(pDesc,pI->zName);
     if( bAll || (p->mode.spec.nAlign && pI->eCx==2) ){
       int ii;
@@ -7741,40 +7736,29 @@ static int dotCmdMode(ShellState *p){
 ** into /dev/null or the equivalent.
 **
 ** Options:
-**
 **   --bom             Prepend a byte-order mark to the output
-**
 **   -e                Accumulate output in a temporary text file then
 **                     launch a text editor when the redirection ends.
-**
 **   --error-prefix X  Use X as the left-margin prefix for error messages.
 **                     Set to an empty string to restore the default.
-**
 **   --glob GLOB       Raise an error if the memory buffer does not match
 **                     the GLOB pattern.
-**
 **   --keep            Continue using the same "memory" buffer.  Do not
 **                     reset it or delete it.  Useful in combination with
 **                     --glob, --not-glob, and/or --verify.
-**
 **   ---notglob GLOB   Raise an error if the memory buffer does not match
 **                     the GLOB pattern.
-**
 **   --plain           Use plain text rather than HTML tables with -w
-**
 **   --show            Write the memory buffer to the screen, for debugging.
-**
 **   --verify ENDMARK  Read subsequent lines of text until the first line
 **                     that matches ENDMARK.  Discard the ENDMARK.  Compare
 **                     the text against the accumulated output in memory and
 **                     raise an error if there are any differences.
-**
 **   -w                Show the output in a web browser.  Output is
 **                     written into a temporary HTML file until the
 **                     redirect ends, then the web browser is launched.
 **                     Query results  are shown as HTML tables, unless
 **                     the --plain is used too.
-**
 **   -x                Show the output in a spreadsheet.  Output is
 **                     written to a temp file as CSV then the spreadsheet
 **                     is launched when
@@ -7788,15 +7772,11 @@ static int dotCmdMode(ShellState *p){
 ** or -x options is used.
 **
 ** Options:
-**
 **   -e                Capture output into a temporary file then bring up
 **                     a text editor on that temporary file.
-**
 **   --plain           Use plain text rather than HTML tables with -w
-**
 **   -w                Capture output into an HTML file then bring up that
 **                     file in a web browser
-**
 **   -x                Show the output in a spreadsheet.  Output is
 **                     written to a temp file as CSV then the spreadsheet
 **                     is launched when
@@ -7915,9 +7895,9 @@ static int dotCmdOutput(ShellState *p){
     shell_check_oom(zFile);
   }
   if( bOnce ){
-    p->outCount = 2;
+    p->nPopOutput = 2;
   }else{
-    p->outCount = 0;
+    p->nPopOutput = 0;
   }
   if( eCheck ){
     char *zTest;
@@ -7966,7 +7946,7 @@ static int dotCmdOutput(ShellState *p){
 #ifndef SQLITE_NOHAVE_SYSTEM
   if( eMode=='e' || eMode=='x' || eMode=='w' ){
     p->doXdgOpen = 1;
-    outputModePush(p);
+    modePush(p);
     if( eMode=='x' ){
       /* spreadsheet mode.  Output as CSV. */
       newTempFile(p, "csv");
@@ -11467,9 +11447,9 @@ static int do_meta_command(const char *zLine, ShellState *p){
   }
 
 meta_command_exit:
-  if( p->outCount ){
-    p->outCount--;
-    if( p->outCount==0 ) output_reset(p);
+  if( p->nPopOutput ){
+    p->nPopOutput--;
+    if( p->nPopOutput==0 ) output_reset(p);
   }
   p->bSafeMode = p->bSafeModePersist;
   return rc;
@@ -11896,12 +11876,16 @@ static int process_input(ShellState *p, const char *zSrc){
       errCnt += runOneSqlLine(p, zSql, p->in, startline);
       CONTINUE_PROMPT_RESET;
       nSql = 0;
-      if( p->outCount ){
+      if( p->nPopOutput ){
         output_reset(p);
-        p->outCount = 0;
+        p->nPopOutput = 0;
       }else{
         clearTempFile(p);
       }
+      if( p->nPopMode ){
+        modePop(p);
+        p->nPopMode = 0;
+      }
       p->bSafeMode = p->bSafeModePersist;
       qss = QSS_Start;
     }else if( nSql && QSS_PLAINWHITE(qss) ){