]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the "--timeout SECONDS" option to the ".progress" command in the CLI.
authordrh <>
Sun, 1 Feb 2026 21:10:04 +0000 (21:10 +0000)
committerdrh <>
Sun, 1 Feb 2026 21:10:04 +0000 (21:10 +0000)
FossilOrigin-Name: 8eb5c88aeb37279f68f5bb0b268339a8f6fb0b927b1e398ac4c83bf42c281273

manifest
manifest.uuid
src/shell.c.in

index a129b52173d1be3bdbfc698ce6a8e105dde504b6..3fd234cd5cf944d8a864a6aef67b18d378211157 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enhance\sthe\s".timer"\scommand\sin\sthe\sCLI\sto\saccept\sthe\s"once"\sargument,\sand\nso\sthat\sit\sleaves\sits\slast\sreal-time\sresult\sin\sthe\s$TIMER\svariable.\s\sAlso\nfix\sa\sharmless\swarning\sfrom\san\searlier\scheck-in.
-D 2026-02-01T15:58:37.050
+C Add\sthe\s"--timeout\sSECONDS"\soption\sto\sthe\s".progress"\scommand\sin\sthe\sCLI.
+D 2026-02-01T21:10:04.562
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -739,7 +739,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 47aa7fdc9ec4c19b103ac5e79d7887d30119b5675309facf5eed1118391c868b
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
 F src/select.c 098caf322d17cd480a5ebd81b9252b9ad90c72be7d5cdc5875e4a0a43e0ba965
-F src/shell.c.in 4dfd1ff15cdfac8778a5dcd6c0f3db1789d0919e79c9725cc7255d1d9bb1e273
+F src/shell.c.in fe1ad71964401a1bd1fc396aa524634096bcbe6cb20b0091a19490e1789431fb
 F src/sqlite.h.in 8bcbaecfe2cbecf8c5c1381354fcdd7d307443e88b4953fccb222456c1267b61
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
@@ -2194,8 +2194,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 3a4f9a323da90611d7eda51b90cb058175ddde0a128e1ff00ce58cc83af0f376
-R af9796fbe8093a32969c1859761a2b45
+P 8ad7dffc261cbb3f7c9b4d38b04282c805c1c047fb431076f85e577c81f21574
+R 2d766d3f9106b9758f2dee16c9d48a97
 U drh
-Z 7d607b0d09ce1651ab8b2dc2f7cb7118
+Z 9b3d450c8e9b37984aed24bcaa27a771
 # Remove this line to create a well-formed Fossil manifest.
index 672fb6d74d2a769f394f0cf7939d7cb6760ba219..611282c802eab77bae1b406805abcf6efa0acd3e 100644 (file)
@@ -1 +1 @@
-8ad7dffc261cbb3f7c9b4d38b04282c805c1c047fb431076f85e577c81f21574
+8eb5c88aeb37279f68f5bb0b268339a8f6fb0b927b1e398ac4c83bf42c281273
index 7d689cf1a5161328c38d0b87af0e55195bbe5261..28770664d8a3c8bfcc448cf65d88e77eb264395c 100644 (file)
@@ -1129,6 +1129,7 @@ struct ShellState {
   u8 enableTimer;        /* Enable the timer.  2: permanently 1: only once */
   int inputNesting;      /* Track nesting level of .read and other redirects */
   double prevTimer;      /* Last reported timer value */
+  double tmProgress;     /* --timeout option for .progress */
   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) */
@@ -1224,6 +1225,7 @@ static ShellState shellState;
                                    ** callback limit is reached, and for each
                                    ** top-level SQL statement */
 #define SHELL_PROGRESS_ONCE  0x04  /* Cancel the --limit after firing once */
+#define SHELL_PROGRESS_TMOUT 0x08  /* Stop after tmProgress seconds */
 
 /* Names of values for Mode.spec.eEsc and Mode.spec.eText
 */
@@ -1406,7 +1408,7 @@ static sqlite3_int64 iBegin;  /* Wall-clock time at start */
 ** Begin timing an operation
 */
 static void beginTimer(ShellState *p){
-  if( p->enableTimer ){
+  if( p->enableTimer || (p->flgProgress & SHELL_PROGRESS_TMOUT)!=0 ){
     getrusage(RUSAGE_SELF, &sBegin);
     iBegin = timeOfDay();
   }
@@ -1418,6 +1420,14 @@ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
          (double)(pEnd->tv_sec - pStart->tv_sec);
 }
 
+/* Return the time since the start of the timer in
+** seconds. */
+static double elapseTime(ShellState *NotUsed){
+  (void)NotUsed;
+  if( iBegin==0 ) return 0.0;
+  return (timeOfDay() - iBegin)*0.000001;
+}
+
 /*
 ** Print the timing results.
 */
@@ -1432,11 +1442,13 @@ static void endTimer(ShellState *p){
           timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
           timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
     if( p->enableTimer==1 ) p->enableTimer = 0;
+    iBegin = 0;
   }
 }
 
 #define BEGIN_TIMER(X) beginTimer(X)
 #define END_TIMER(X)   endTimer(X)
+#define ELAPSE_TIME(X) elapseTime(X)
 #define HAS_TIMER 1
 
 #elif (defined(_WIN32) || defined(WIN32))
@@ -1482,7 +1494,9 @@ static int hasTimer(void){
 ** Begin timing an operation
 */
 static void beginTimer(ShellState *p){
-  if( p->enableTimer && getProcessTimesAddr ){
+  if( (p->enableTimer || (p->flgProgress & SHELL_PROGRESS_TMOUT)!=0)
+   && getProcessTimesAddr
+  ){
     FILETIME ftCreation, ftExit;
     getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
                         &ftKernelBegin,&ftUserBegin);
@@ -1497,6 +1511,14 @@ static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
   return (double) ((i64End - i64Start) / 10000000.0);
 }
 
+/* Return the time since the start of the timer in
+** seconds. */
+static double elapseTime(ShellState *NotUsed){
+  (void)NotUsed;
+  if( ftWallBegin==0 ) return 0.0;
+  return (timeOfDay() - ftWallBegin)*0.000001;
+}
+
 /*
 ** Print the timing results.
 */
@@ -1520,15 +1542,18 @@ static void endTimer(ShellState *p){
           timeDiff(&ftKernelBegin, &ftKernelEnd));
 #endif
     if( p->enableTimer==1 ) p->enableTimer = 0;
+    ftWallBegin = 0;
   }
 }
 
 #define BEGIN_TIMER(X) beginTimer(X)
+#define ELAPSE_TIME(X) elapseTime(X)
 #define END_TIMER(X)   endTimer(X)
 #define HAS_TIMER      hasTimer()
 
 #else
 #define BEGIN_TIMER(X) /* no-op */
+#define ELAPSE_TIME(X) 0.0
 #define END_TIMER(X)   /*no-op*/
 #define HAS_TIMER 0
 #endif
@@ -2458,6 +2483,13 @@ shellFormatSchema_finish:
 static int progress_handler(void *pClientData) {
   ShellState *p = (ShellState*)pClientData;
   p->nProgress++;
+  if( (p->flgProgress & SHELL_PROGRESS_TMOUT)!=0
+   && ELAPSE_TIME(p)>=p->tmProgress
+  ){
+    cli_printf(p->out, "Progress timeout after %.6f seconds\n", 
+               ELAPSE_TIME(p));
+    return 1;
+  }
   if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
     cli_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
     if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
@@ -3819,6 +3851,7 @@ static const char *(azHelp[]) = {
   "   --once                    Do no more than one progress interrupt",
   "   --quiet|-q                No output except at interrupts",
   "   --reset                   Reset the count for each input and interrupt",
+  "   --timeout S               Halt after running for S seconds",
 #endif
   ".prompt MAIN CONTINUE    Replace the standard prompts",
 #ifndef SQLITE_SHELL_FIDDLE
@@ -10243,6 +10276,19 @@ static int do_meta_command(const char *zLine, ShellState *p){
           p->flgProgress |= SHELL_PROGRESS_ONCE;
           continue;
         }
+        if( cli_strcmp(z,"timeout")==0 ){
+          if( i==nArg-1 ){
+            dotCmdError(p, i, "missing argument", 0);
+            return 1;
+          }
+          i++;
+          p->tmProgress = atof(azArg[i]);
+          if( p->tmProgress>0.0 ){
+            p->flgProgress = SHELL_PROGRESS_QUIET|SHELL_PROGRESS_TMOUT;
+            if( nn==0 ) nn = 100;
+          }
+          continue;
+        }
         if( cli_strcmp(z,"limit")==0 ){
           if( i+1>=nArg ){
             eputz("Error: missing argument on --limit\n");