/ Check-in [ad84ca24]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the ".progress" command to the CLI.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ad84ca24ff760f7a2b128f2eeb4d799a97f84b8b8a8bb8d9657c4c555f6ccf47
User & Date: drh 2019-02-04 14:53:18
Context
2019-02-04
16:25
Fix problems with SAVEPOINT and related commands within transactions on a corrupt database that include fts5 or some other virtual tables. check-in: b0da6e0d user: dan tags: trunk
14:53
Add the ".progress" command to the CLI. check-in: ad84ca24 user: drh tags: trunk
14:00
Fix another potential buffer overread in fts5. check-in: 14fba4cc user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.in.

  1024   1024     int mode;              /* An output mode setting */
  1025   1025     int modePrior;         /* Saved mode */
  1026   1026     int cMode;             /* temporary output mode for the current query */
  1027   1027     int normalMode;        /* Output mode before ".explain on" */
  1028   1028     int writableSchema;    /* True if PRAGMA writable_schema=ON */
  1029   1029     int showHeader;        /* True to show column names in List or Column mode */
  1030   1030     int nCheck;            /* Number of ".check" commands run */
         1031  +  unsigned nProgress;    /* Number of progress callbacks encountered */
         1032  +  unsigned mxProgress;   /* Maximum progress callbacks before failing */
         1033  +  unsigned flgProgress;  /* Flags for the progress callback */
  1031   1034     unsigned shellFlgs;    /* Various flags */
  1032   1035     sqlite3_int64 szMax;   /* --maxsize argument to .open */
  1033   1036     char *zDestTable;      /* Name of destination table when MODE_Insert */
  1034   1037     char *zTempFile;       /* Temporary file that might need deleting */
  1035   1038     char zTestcase[30];    /* Name of current test case */
  1036   1039     char colSeparator[20]; /* Column separator character for several modes */
  1037   1040     char rowSeparator[20]; /* Row separator character for MODE_Ascii */
................................................................................
  1078   1081   
  1079   1082   /* Allowed values for ShellState.eTraceType
  1080   1083   */
  1081   1084   #define SHELL_TRACE_PLAIN      0      /* Show input SQL text */
  1082   1085   #define SHELL_TRACE_EXPANDED   1      /* Show expanded SQL text */
  1083   1086   #define SHELL_TRACE_NORMALIZED 2      /* Show normalized SQL text */
  1084   1087   
         1088  +/* Bits in the ShellState.flgProgress variable */
         1089  +#define PROGRESS_QUIET   0x01         /* Omit announcing every progress callback */
         1090  +#define PROGRESS_RESET   0x02         /* Reset the count when the progres
         1091  +                                      ** callback limit is reached, and for each
         1092  +                                      ** top-level SQL statement */
         1093  +#define PROGRESS_ONCE    0x04         /* Cancel the --limit after firing once */
         1094  +
  1085   1095   /*
  1086   1096   ** These are the allowed shellFlgs values
  1087   1097   */
  1088   1098   #define SHFLG_Pagecache      0x00000001 /* The --pagecache option is used */
  1089   1099   #define SHFLG_Lookaside      0x00000002 /* Lookaside memory is used */
  1090   1100   #define SHFLG_Backslash      0x00000004 /* The --backslash option is used */
  1091   1101   #define SHFLG_PreserveRowid  0x00000008 /* .dump preserves rowid values */
................................................................................
  1777   1787         utf8_printf(p->out, "QUERY PLAN\n");
  1778   1788       }
  1779   1789       p->sGraph.zPrefix[0] = 0;
  1780   1790       eqp_render_level(p, 0);
  1781   1791       eqp_reset(p);
  1782   1792     }
  1783   1793   }
         1794  +
         1795  +/*
         1796  +** Progress handler callback.
         1797  +*/
         1798  +static int progress_handler(void *pClientData) {
         1799  +  ShellState *p = (ShellState*)pClientData;
         1800  +  p->nProgress++;
         1801  +  if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
         1802  +    raw_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
         1803  +    if( p->flgProgress & PROGRESS_RESET ) p->nProgress = 0;
         1804  +    if( p->flgProgress & PROGRESS_ONCE ) p->mxProgress = 0;
         1805  +    return 1;
         1806  +  }
         1807  +  if( (p->flgProgress & PROGRESS_QUIET)==0 ){
         1808  +    raw_printf(p->out, "Progress %u\n", p->nProgress);
         1809  +  }
         1810  +  return 0;
         1811  +}
  1784   1812   
  1785   1813   /*
  1786   1814   ** This is the callback routine that the shell
  1787   1815   ** invokes for each row of a query result.
  1788   1816   */
  1789   1817   static int shell_callback(
  1790   1818     void *pArg,
................................................................................
  3464   3492   #endif
  3465   3493     "        --new           Initialize FILE to an empty database",
  3466   3494     "        --readonly      Open FILE readonly",
  3467   3495     "        --zip           FILE is a ZIP archive",
  3468   3496     ".output ?FILE?           Send output to FILE or stdout if FILE is omitted",
  3469   3497     "     If FILE begins with '|' then open it as a pipe.",
  3470   3498     ".print STRING...         Print literal STRING",
         3499  +  ".progress N              Invoke progress handler after every N opcodes",
         3500  +  "   --limit N                 Interrupt after N progress callbacks",
         3501  +  "   --once                    Do no more than one progress interrupt",
         3502  +  "   --quiet|-q                No output except at interrupts",
         3503  +  "   --reset                   Reset the count for each input and interrupt",
  3471   3504     ".prompt MAIN CONTINUE    Replace the standard prompts",
  3472   3505     ".quit                    Exit this program",
  3473   3506     ".read FILE               Read input from FILE",
  3474   3507     ".restore ?DB? FILE       Restore content of DB (default \"main\") from FILE",
  3475   3508     ".save FILE               Write in-memory database into FILE",
  3476   3509     ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
  3477   3510     ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
................................................................................
  6995   7028       int i;
  6996   7029       for(i=1; i<nArg; i++){
  6997   7030         if( i>1 ) raw_printf(p->out, " ");
  6998   7031         utf8_printf(p->out, "%s", azArg[i]);
  6999   7032       }
  7000   7033       raw_printf(p->out, "\n");
  7001   7034     }else
         7035  +
         7036  +  if( c=='p' && n>=3 && strncmp(azArg[0], "progress", n)==0 ){
         7037  +    int i;
         7038  +    int n = 0;
         7039  +    p->flgProgress = 0;
         7040  +    p->mxProgress = 0;
         7041  +    p->nProgress = 0;
         7042  +    for(i=1; i<nArg; i++){
         7043  +      const char *z = azArg[i];
         7044  +      if( z[0]=='-' ){
         7045  +        z++;
         7046  +        if( z[0]=='-' ) z++;
         7047  +        if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
         7048  +          p->flgProgress |= PROGRESS_QUIET;
         7049  +          continue;
         7050  +        }
         7051  +        if( strcmp(z,"reset")==0 ){
         7052  +          p->flgProgress |= PROGRESS_RESET;
         7053  +          continue;
         7054  +        }
         7055  +        if( strcmp(z,"once")==0 ){
         7056  +          p->flgProgress |= PROGRESS_ONCE;
         7057  +          continue;
         7058  +        }
         7059  +        if( strcmp(z,"limit")==0 ){
         7060  +          if( i+1>=nArg ){
         7061  +            utf8_printf(stderr, "Error: missing argument on --limit\n");
         7062  +            rc = 1;
         7063  +            goto meta_command_exit;
         7064  +          }else{
         7065  +            p->mxProgress = (int)integerValue(azArg[++i]);
         7066  +          }
         7067  +          continue;
         7068  +        }
         7069  +        utf8_printf(stderr, "Error: unknown option: \"%s\"\n", azArg[i]);
         7070  +        rc = 1;
         7071  +        goto meta_command_exit;
         7072  +      }else{
         7073  +        n = (int)integerValue(z);
         7074  +      }
         7075  +    }
         7076  +    open_db(p, 0);
         7077  +    sqlite3_progress_handler(p->db, n, progress_handler, p);
         7078  +  }else
  7002   7079   
  7003   7080     if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
  7004   7081       if( nArg >= 2) {
  7005   7082         strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
  7006   7083       }
  7007   7084       if( nArg >= 3) {
  7008   7085         strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
................................................................................
  8331   8408   */
  8332   8409   static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
  8333   8410     int rc;
  8334   8411     char *zErrMsg = 0;
  8335   8412   
  8336   8413     open_db(p, 0);
  8337   8414     if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
         8415  +  if( p->flgProgress & PROGRESS_RESET ) p->nProgress = 0;
  8338   8416     BEGIN_TIMER;
  8339   8417     rc = shell_exec(p, zSql, &zErrMsg);
  8340   8418     END_TIMER;
  8341   8419     if( rc || zErrMsg ){
  8342   8420       char zPrefix[100];
  8343   8421       if( in!=0 || !stdin_is_interactive ){
  8344   8422         sqlite3_snprintf(sizeof(zPrefix), zPrefix,