/ Check-in [b9ac3d7e]
Login

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

Overview
Comment:Add the ".trace" option to the command-line shell.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:b9ac3d7e340eb616fd23cc7dbdef6fdd66a79fe4
User & Date: drh 2012-04-04 16:56:23
Context
2012-04-05
01:37
Performance improvements for the RowSet object when it undergoes many cycles between RowSetInsert and RowSetTest. check-in: 49d20ede user: drh tags: trunk
2012-04-04
16:56
Add the ".trace" option to the command-line shell. check-in: b9ac3d7e user: drh tags: trunk
13:58
Fix the multiplexor logging so that it works with SQLITE_ENABLE_8_3_NAMES. check-in: 9e1e2fe2 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.

   417    417   */
   418    418   struct callback_data {
   419    419     sqlite3 *db;           /* The database */
   420    420     int echoOn;            /* True to echo input commands */
   421    421     int statsOn;           /* True to display memory stats before each finalize */
   422    422     int cnt;               /* Number of records displayed so far */
   423    423     FILE *out;             /* Write results here */
          424  +  FILE *traceOut;        /* Output for sqlite3_trace() */
   424    425     int nErr;              /* Number of errors seen */
   425    426     int mode;              /* An output mode setting */
   426    427     int writableSchema;    /* True if PRAGMA writable_schema=ON */
   427    428     int showHeader;        /* True to show column names in List or Column mode */
   428    429     char *zDestTable;      /* Name of destination table when MODE_Insert */
   429    430     char separator[20];    /* Separator character for MODE_List */
   430    431     int colWidth[100];     /* Requested width of each column when in column mode*/
................................................................................
  1429   1430     ".separator STRING      Change separator used by output mode and .import\n"
  1430   1431     ".show                  Show the current values for various settings\n"
  1431   1432     ".stats ON|OFF          Turn stats on or off\n"
  1432   1433     ".tables ?TABLE?        List names of tables\n"
  1433   1434     "                         If TABLE specified, only list tables matching\n"
  1434   1435     "                         LIKE pattern TABLE.\n"
  1435   1436     ".timeout MS            Try opening locked tables for MS milliseconds\n"
         1437  +  ".trace FILE|off        Output each SQL statement as it is run\n"
  1436   1438     ".vfsname ?AUX?         Print the name of the VFS stack\n"
  1437   1439     ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
  1438   1440   ;
  1439   1441   
  1440   1442   static char zTimerHelp[] =
  1441   1443     ".timer ON|OFF          Turn the CPU timer measurement on or off\n"
  1442   1444   ;
................................................................................
  1517   1519     if( strcmp(zArg,"on")==0 ){
  1518   1520       val = 1;
  1519   1521     }else if( strcmp(zArg,"yes")==0 ){
  1520   1522       val = 1;
  1521   1523     }
  1522   1524     return val;
  1523   1525   }
         1526  +
         1527  +/*
         1528  +** Close an output file, assuming it is not stderr or stdout
         1529  +*/
         1530  +static void output_file_close(FILE *f){
         1531  +  if( f && f!=stdout && f!=stderr ) fclose(f);
         1532  +}
         1533  +
         1534  +/*
         1535  +** Try to open an output file.   The names "stdout" and "stderr" are
         1536  +** recognized and do the right thing.  NULL is returned if the output 
         1537  +** filename is "off".
         1538  +*/
         1539  +static FILE *output_file_open(const char *zFile){
         1540  +  FILE *f;
         1541  +  if( strcmp(zFile,"stdout")==0 ){
         1542  +    f = stdout;
         1543  +  }else if( strcmp(zFile, "stderr")==0 ){
         1544  +    f = stderr;
         1545  +  }else if( strcmp(zFile, "off")==0 ){
         1546  +    f = 0;
         1547  +  }else{
         1548  +    f = fopen(zFile, "wb");
         1549  +    if( f==0 ){
         1550  +      fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
         1551  +    }
         1552  +  }
         1553  +  return f;
         1554  +}
         1555  +
         1556  +/*
         1557  +** A routine for handling output from sqlite3_trace().
         1558  +*/
         1559  +static void sql_trace_callback(void *pArg, const char *z){
         1560  +  FILE *f = (FILE*)pArg;
         1561  +  if( f ) fprintf(f, "%s\n", z);
         1562  +}
  1524   1563   
  1525   1564   /*
  1526   1565   ** If an input line begins with "." then invoke this routine to
  1527   1566   ** process that line.
  1528   1567   **
  1529   1568   ** Return 1 on error, 2 to exit, and 0 otherwise.
  1530   1569   */
................................................................................
  1928   1967         rc = 1;
  1929   1968       }
  1930   1969     }else
  1931   1970   #endif
  1932   1971   
  1933   1972     if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
  1934   1973       const char *zFile = azArg[1];
  1935         -    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
  1936         -      fclose(p->pLog);
  1937         -      p->pLog = 0;
  1938         -    }
  1939         -    if( strcmp(zFile,"stdout")==0 ){
  1940         -      p->pLog = stdout;
  1941         -    }else if( strcmp(zFile, "stderr")==0 ){
  1942         -      p->pLog = stderr;
  1943         -    }else if( strcmp(zFile, "off")==0 ){
  1944         -      p->pLog = 0;
  1945         -    }else{
  1946         -      p->pLog = fopen(zFile, "w");
  1947         -      if( p->pLog==0 ){
  1948         -        fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
  1949         -      }
  1950         -    }
         1974  +    output_file_close(p->pLog);
         1975  +    p->pLog = output_file_open(zFile);
  1951   1976     }else
  1952   1977   
  1953   1978     if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
  1954   1979       int n2 = strlen30(azArg[1]);
  1955   1980       if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
  1956   1981           ||
  1957   1982           (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
................................................................................
  1996   2021   
  1997   2022     if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
  1998   2023       sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
  1999   2024                        "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
  2000   2025     }else
  2001   2026   
  2002   2027     if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
  2003         -    if( p->out!=stdout ){
  2004         -      if( p->outfile[0]=='|' ){
  2005         -        pclose(p->out);
  2006         -      }else{
  2007         -        fclose(p->out);
  2008         -      }
         2028  +    if( p->outfile[0]=='|' ){
         2029  +      pclose(p->out);
         2030  +    }else{
         2031  +      output_file_close(p->out);
  2009   2032       }
  2010         -    if( strcmp(azArg[1],"stdout")==0 ){
  2011         -      p->out = stdout;
  2012         -      sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
  2013         -    }else if( azArg[1][0]=='|' ){
         2033  +    p->outfile[0] = 0;
         2034  +    if( azArg[1][0]=='|' ){
  2014   2035         p->out = popen(&azArg[1][1], "w");
  2015   2036         if( p->out==0 ){
  2016   2037           fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
  2017   2038           p->out = stdout;
  2018   2039           rc = 1;
  2019   2040         }else{
  2020   2041           sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
  2021   2042         }
  2022   2043       }else{
  2023         -      p->out = fopen(azArg[1], "wb");
         2044  +      p->out = output_file_open(azArg[1]);
  2024   2045         if( p->out==0 ){
  2025         -        fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
         2046  +        if( strcmp(azArg[1],"off")!=0 ){
         2047  +          fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
         2048  +        }
  2026   2049           p->out = stdout;
  2027   2050           rc = 1;
  2028   2051         } else {
  2029         -         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
         2052  +        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
  2030   2053         }
  2031   2054       }
  2032   2055     }else
  2033   2056   
  2034   2057     if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
  2035   2058       if( nArg >= 2) {
  2036   2059         strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
................................................................................
  2392   2415       
  2393   2416     if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
  2394   2417      && nArg==2
  2395   2418     ){
  2396   2419       enableTimer = booleanValue(azArg[1]);
  2397   2420     }else
  2398   2421     
         2422  +  if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
         2423  +    output_file_close(p->traceOut);
         2424  +    p->traceOut = output_file_open(azArg[1]);
         2425  +#ifndef SQLITE_OMIT_TRACE
         2426  +    if( p->traceOut==0 ){
         2427  +      sqlite3_trace(p->db, 0, 0);
         2428  +    }else{
         2429  +      sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
         2430  +    }
         2431  +#endif
         2432  +  }else
         2433  +
  2399   2434     if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
  2400   2435       printf("SQLite %s %s\n" /*extra-version-info*/,
  2401   2436           sqlite3_libversion(), sqlite3_sourceid());
  2402   2437     }else
  2403   2438   
  2404   2439     if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
  2405   2440       const char *zDbName = nArg==2 ? azArg[1] : "main";