11c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
21c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** 2001 September 15
31c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
41c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** The author disclaims copyright to this source code.  In place of
51c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** a legal notice, here is a blessing:
61c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
71c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**    May you do good and not evil.
81c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**    May you find forgiveness for yourself and forgive others.
91c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**    May you share freely, never taking more than you give.
101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*************************************************************************
121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This file contains code to implement the "sqlite" command line
131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** utility for accessing SQLite databases.
141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
1590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* This needs to come before any includes for MSVC compiler */
171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define _CRT_SECURE_NO_WARNINGS
181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown/*
2190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown** Enable large-file support for fopen() and friends on unix.
2290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown*/
2390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifndef SQLITE_DISABLE_LFS
2490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# define _LARGE_FILE       1
2590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# ifndef _FILE_OFFSET_BITS
2690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#   define _FILE_OFFSET_BITS 64
2790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# endif
2890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# define _LARGEFILE_SOURCE 1
2990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
3090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <stdlib.h>
321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <string.h>
331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <stdio.h>
341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <assert.h>
351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include "sqlite3.h"
361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <ctype.h>
371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <stdarg.h>
381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# include <signal.h>
411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# if !defined(__RTP__) && !defined(_WRS_KERNEL)
421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#  include <pwd.h>
431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# endif
441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# include <unistd.h>
451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# include <sys/types.h>
461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifdef __OS2__
491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# include <unistd.h>
501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
5290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef HAVE_EDITLINE
5390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# include <editline/editline.h>
5490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(HAVE_READLINE) && HAVE_READLINE==1
561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# include <readline/readline.h>
571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# include <readline/history.h>
5890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
5990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
60c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown# define readline(p) local_getline(p,stdin,0)
611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# define add_history(X)
621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# define read_history(X)
631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# define write_history(X)
641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# define stifle_history(X)
651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(_WIN32) || defined(WIN32)
681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori# include <io.h>
691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define isatty(h) _isatty(h)
701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define access(f,m) _access((f),(m))
711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#else
721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* Make sure isatty() has a prototype.
731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
7490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brownextern int isatty(int);
751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(_WIN32_WCE)
781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori * thus we always assume that we have a console. That can be
801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori * overridden with the -batch command line option.
811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori */
821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define isatty(x) 1
831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
8590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown/* True if the timer is enabled */
8690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brownstatic int enableTimer = 0;
8790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
8890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown/* ctype macros that work with signed characters */
8990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define IsSpace(X)  isspace((unsigned char)X)
9090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define IsDigit(X)  isdigit((unsigned char)X)
9190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define ToLower(X)  (char)tolower((unsigned char)X)
9290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <sys/time.h>
951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <sys/resource.h>
961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* Saved resource information for the beginning of an operation */
981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic struct rusage sBegin;
991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
1011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Begin timing an operation
1021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
1031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void beginTimer(void){
1041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( enableTimer ){
1051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    getrusage(RUSAGE_SELF, &sBegin);
1061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
1071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
1081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* Return the difference of two time_structs in seconds */
1101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic double timeDiff(struct timeval *pStart, struct timeval *pEnd){
1111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
1121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         (double)(pEnd->tv_sec - pStart->tv_sec);
1131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
1141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
1161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Print the timing results.
1171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
1181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void endTimer(void){
1191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( enableTimer ){
1201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    struct rusage sEnd;
1211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    getrusage(RUSAGE_SELF, &sEnd);
1221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    printf("CPU Time: user %f sys %f\n",
1231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori       timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
1241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori       timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
1251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
1261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
1271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define BEGIN_TIMER beginTimer()
1291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define END_TIMER endTimer()
1301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define HAS_TIMER 1
1311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#elif (defined(_WIN32) || defined(WIN32))
1331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#include <windows.h>
1351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* Saved resource information for the beginning of an operation */
1371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic HANDLE hProcess;
1381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic FILETIME ftKernelBegin;
1391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic FILETIME ftUserBegin;
1401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noritypedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
1411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic GETPROCTIMES getProcessTimesAddr = NULL;
1421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
1441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Check to see if we have timer support.  Return 1 if necessary
1451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** support found (or found previously).
1461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
1471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int hasTimer(void){
1481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( getProcessTimesAddr ){
1491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 1;
1501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  } else {
1511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
1521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    ** See if the version we are running on has it, and if it does, save off
1531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    ** a pointer to it and the current process handle.
1541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    */
1551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    hProcess = GetCurrentProcess();
1561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( hProcess ){
1571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
1581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( NULL != hinstLib ){
1591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
1601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( NULL != getProcessTimesAddr ){
1611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          return 1;
1621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
1631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        FreeLibrary(hinstLib);
1641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
1651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
1661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
1671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return 0;
1681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
1691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
1711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Begin timing an operation
1721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
1731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void beginTimer(void){
1741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( enableTimer && getProcessTimesAddr ){
1751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    FILETIME ftCreation, ftExit;
1761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
1771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
1781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
1791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* Return the difference of two FILETIME structs in seconds */
1811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic double timeDiff(FILETIME *pStart, FILETIME *pEnd){
1821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
1831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
1841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return (double) ((i64End - i64Start) / 10000000.0);
1851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
1861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
1881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Print the timing results.
1891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
1901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void endTimer(void){
1911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( enableTimer && getProcessTimesAddr){
1921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
1931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
1941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    printf("CPU Time: user %f sys %f\n",
1951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori       timeDiff(&ftUserBegin, &ftUserEnd),
1961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori       timeDiff(&ftKernelBegin, &ftKernelEnd));
1971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
1981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
1991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define BEGIN_TIMER beginTimer()
2011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define END_TIMER endTimer()
2021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define HAS_TIMER hasTimer()
2031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#else
2051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define BEGIN_TIMER
2061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define END_TIMER
2071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define HAS_TIMER 0
2081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
2091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Used to prevent warnings about unused parameters
2121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define UNUSED_PARAMETER(x) (void)(x)
2141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** If the following flag is set, then command execution stops
2171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** at an error if we are not interactive.
2181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int bail_on_error = 0;
2201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Threat stdin as an interactive input if the following variable
2231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** is true.  Otherwise, assume stdin is connected to a file or pipe.
2241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int stdin_is_interactive = 1;
2261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** The following is the open SQLite database.  We make a pointer
2291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** to this database a static variable so that it can be accessed
2301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** by the SIGINT handler to interrupt database processing.
2311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic sqlite3 *db = 0;
2331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** True if an interrupt (Control-C) has been received.
2361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic volatile int seenInterrupt = 0;
2381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This is the name of our program. It is set in main(), used
2411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** in a number of other places, mostly for error messages.
2421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char *Argv0;
2441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Prompt strings. Initialized in main. Settable with
2471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**   .prompt main continue
2481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
2501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
2511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Write I/O traces to the following stream.
2541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifdef SQLITE_ENABLE_IOTRACE
2561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic FILE *iotrace = 0;
2571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
2581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This routine works like printf in that its first argument is a
2611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** format string and subsequent arguments are values to be substituted
2621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** in place of % fields.  The result of formatting this string
2631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** is written to iotrace.
2641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifdef SQLITE_ENABLE_IOTRACE
2661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void iotracePrintf(const char *zFormat, ...){
2671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  va_list ap;
2681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *z;
2691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( iotrace==0 ) return;
2701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  va_start(ap, zFormat);
2711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  z = sqlite3_vmprintf(zFormat, ap);
2721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  va_end(ap);
2731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  fprintf(iotrace, "%s", z);
2741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_free(z);
2751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
2761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
2771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
2801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Determines if a string is a number of not.
2811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
2821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int isNumber(const char *z, int *realnum){
2831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( *z=='-' || *z=='+' ) z++;
28490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( !IsDigit(*z) ){
2851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 0;
2861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
2871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  z++;
2881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( realnum ) *realnum = 0;
28990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  while( IsDigit(*z) ){ z++; }
2901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( *z=='.' ){
2911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    z++;
29290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( !IsDigit(*z) ) return 0;
29390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    while( IsDigit(*z) ){ z++; }
2941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( realnum ) *realnum = 1;
2951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
2961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( *z=='e' || *z=='E' ){
2971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    z++;
2981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( *z=='+' || *z=='-' ) z++;
29990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( !IsDigit(*z) ) return 0;
30090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    while( IsDigit(*z) ){ z++; }
3011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( realnum ) *realnum = 1;
3021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
3031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return *z==0;
3041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
3051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
3061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
3071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** A global char* and an SQL function to access its current value
3081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** from within an SQL statement. This program used to use the
3091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** sqlite_exec_printf() API to substitue a string into an SQL statement.
3101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** The correct way to do this with sqlite3 is to use the bind API, but
3111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** since the shell is built around the callback paradigm it would be a lot
3121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** of work. Instead just use this hack, which is quite harmless.
3131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
3141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic const char *zShellStatic = 0;
3151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void shellstaticFunc(
3161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_context *context,
3171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int argc,
3181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_value **argv
3191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori){
3201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  assert( 0==argc );
3211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  assert( zShellStatic );
3221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  UNUSED_PARAMETER(argc);
3231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  UNUSED_PARAMETER(argv);
3241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
3251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
3261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
3271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
3281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
3291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This routine reads a line of text from FILE in, stores
3301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** the text in memory obtained from malloc() and returns a pointer
3311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** to the text.  NULL is returned at end of file, or if malloc()
3321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** fails.
3331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
3341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** The interface is like "readline" but no command-line editing
3351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** is done.
3361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
337c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brownstatic char *local_getline(char *zPrompt, FILE *in, int csvFlag){
3381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zLine;
3391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nLine;
3401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int n;
341c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  int inQuote = 0;
3421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
3431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zPrompt && *zPrompt ){
3441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    printf("%s",zPrompt);
3451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fflush(stdout);
3461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
3471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  nLine = 100;
3481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zLine = malloc( nLine );
3491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zLine==0 ) return 0;
3501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  n = 0;
35190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  while( 1 ){
3521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( n+100>nLine ){
3531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      nLine = nLine*2 + 100;
3541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zLine = realloc(zLine, nLine);
3551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zLine==0 ) return 0;
3561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
3571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( fgets(&zLine[n], nLine - n, in)==0 ){
3581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( n==0 ){
3591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        free(zLine);
3601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        return 0;
3611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
3621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zLine[n] = 0;
3631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
3641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
365c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    while( zLine[n] ){
366c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      if( zLine[n]=='"' ) inQuote = !inQuote;
367c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      n++;
368c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }
369c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
3701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      n--;
3711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( n>0 && zLine[n-1]=='\r' ) n--;
3721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zLine[n] = 0;
37390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      break;
3741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
3751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
3761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zLine = realloc( zLine, n+1 );
3771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return zLine;
3781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
3791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
3801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
3811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Retrieve a single line of input text.
3821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
3831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** zPrior is a string of prior text retrieved.  If not the empty
3841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** string, then issue a continuation prompt.
3851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
3861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char *one_input_line(const char *zPrior, FILE *in){
3871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zPrompt;
3881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zResult;
3891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( in!=0 ){
390c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    return local_getline(0, in, 0);
3911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
3921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zPrior && zPrior[0] ){
3931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zPrompt = continuePrompt;
3941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else{
3951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zPrompt = mainPrompt;
3961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
3971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zResult = readline(zPrompt);
3981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(HAVE_READLINE) && HAVE_READLINE==1
3991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zResult && *zResult ) add_history(zResult);
4001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
4011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return zResult;
4021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
4031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
4041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristruct previous_mode_data {
4051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int valid;        /* Is there legit data in here? */
4061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int mode;
4071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int showHeader;
4081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int colWidth[100];
4091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori};
4101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
4111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
4121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** An pointer to an instance of this structure is passed from
4131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** the main program to the callback.  This is used to communicate
4141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** state and mode information.
4151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
4161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristruct callback_data {
4171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3 *db;           /* The database */
4181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int echoOn;            /* True to echo input commands */
419de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  int statsOn;           /* True to display memory stats before each finalize */
4201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int cnt;               /* Number of records displayed so far */
4211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  FILE *out;             /* Write results here */
42290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  int nErr;              /* Number of errors seen */
4231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int mode;              /* An output mode setting */
4241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int writableSchema;    /* True if PRAGMA writable_schema=ON */
4251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int showHeader;        /* True to show column names in List or Column mode */
4261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zDestTable;      /* Name of destination table when MODE_Insert */
4271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char separator[20];    /* Separator character for MODE_List */
4281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int colWidth[100];     /* Requested width of each column when in column mode*/
4291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int actualWidth[100];  /* Actual width of each column */
4301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char nullvalue[20];    /* The text to print when a NULL comes back from
4311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                         ** the database */
4321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct previous_mode_data explainPrev;
4331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                         /* Holds the mode information just before
4341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                         ** .explain ON */
4351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char outfile[FILENAME_MAX]; /* Filename for *out */
4361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *zDbFilename;    /* name of the database file */
43790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  const char *zVfs;           /* Name of VFS to use */
4381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_stmt *pStmt;   /* Current statement if any. */
4391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  FILE *pLog;            /* Write log output here */
4401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori};
4411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
4421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
4431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** These are the allowed modes.
4441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
4451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_Line     0  /* One column per line.  Blank line between records */
4461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_Column   1  /* One record per line in neat columns */
4471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_List     2  /* One record per line with a separator */
4481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */
4491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_Html     4  /* Generate an XHTML table */
4501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_Insert   5  /* Generate SQL "insert" statements */
4511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_Tcl      6  /* Generate ANSI-C or TCL quoted elements */
4521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_Csv      7  /* Quote strings, numbers are plain */
4531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define MODE_Explain  8  /* Like MODE_Column, but do not truncate data */
4541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
4551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic const char *modeDescr[] = {
4561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "line",
4571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "column",
4581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "list",
4591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "semi",
4601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "html",
4611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "insert",
4621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "tcl",
4631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "csv",
4641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "explain",
4651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori};
4661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
4671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
4681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Number of elements in an array
4691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
4701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
4711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
4721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
4731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Compute a string length that is limited to what can be stored in
4741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** lower 30 bits of a 32-bit signed integer.
4751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
4761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int strlen30(const char *z){
4771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *z2 = z;
4781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  while( *z2 ){ z2++; }
4791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return 0x3fffffff & (int)(z2 - z);
4801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
4811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
4821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
4831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** A callback for the sqlite3_log() interface.
4841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
4851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void shellLog(void *pArg, int iErrCode, const char *zMsg){
4861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct callback_data *p = (struct callback_data*)pArg;
4871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( p->pLog==0 ) return;
4881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
4891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  fflush(p->pLog);
4901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
4911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
4921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
4931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Output the given string as a hex-encoded blob (eg. X'1234' )
4941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
4951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
4961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i;
4971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zBlob = (char *)pBlob;
4981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  fprintf(out,"X'");
4991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
5001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  fprintf(out,"'");
5011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
5021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
5031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
5041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Output the given string as a quoted string using SQL quoting conventions.
5051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
5061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void output_quoted_string(FILE *out, const char *z){
5071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i;
5081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nSingle = 0;
5091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(i=0; z[i]; i++){
5101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( z[i]=='\'' ) nSingle++;
5111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
5121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( nSingle==0 ){
5131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(out,"'%s'",z);
5141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else{
5151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(out,"'");
5161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    while( *z ){
5171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; z[i] && z[i]!='\''; i++){}
5181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( i==0 ){
5191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(out,"''");
5201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        z++;
5211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else if( z[i]=='\'' ){
5221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(out,"%.*s''",i,z);
5231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        z += i+1;
5241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else{
5251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(out,"%s",z);
5261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        break;
5271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
5281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
5291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(out,"'");
5301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
5311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
5321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
5331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
5341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Output the given string as a quoted according to C or TCL quoting rules.
5351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
5361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void output_c_string(FILE *out, const char *z){
5371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  unsigned int c;
5381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  fputc('"', out);
5391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  while( (c = *(z++))!=0 ){
5401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( c=='\\' ){
5411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc(c, out);
5421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc(c, out);
5431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( c=='\t' ){
5441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc('\\', out);
5451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc('t', out);
5461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( c=='\n' ){
5471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc('\\', out);
5481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc('n', out);
5491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( c=='\r' ){
5501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc('\\', out);
5511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc('r', out);
5521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( !isprint(c) ){
5531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(out, "\\%03o", c&0xff);
5541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
5551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fputc(c, out);
5561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
5571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
5581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  fputc('"', out);
5591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
5601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
5611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
5621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Output the given string with characters that are special to
5631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** HTML escaped.
5641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
5651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void output_html_string(FILE *out, const char *z){
5661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i;
5671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  while( *z ){
5681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    for(i=0;   z[i]
5691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            && z[i]!='<'
5701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            && z[i]!='&'
5711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            && z[i]!='>'
5721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            && z[i]!='\"'
5731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            && z[i]!='\'';
5741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        i++){}
5751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( i>0 ){
5761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(out,"%.*s",i,z);
5771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
5781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( z[i]=='<' ){
5791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(out,"&lt;");
5801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( z[i]=='&' ){
5811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(out,"&amp;");
5821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( z[i]=='>' ){
5831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(out,"&gt;");
5841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( z[i]=='\"' ){
5851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(out,"&quot;");
5861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( z[i]=='\'' ){
5871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(out,"&#39;");
5881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
5891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
5901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
5911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    z += i + 1;
5921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
5931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
5941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
5951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
5961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** If a field contains any character identified by a 1 in the following
5971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** array, then the string must be quoted for CSV.
5981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
5991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic const char needCsvQuote[] = {
6001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 0, 1, 0, 0, 0, 0, 1,   0, 0, 0, 0, 0, 0, 0, 0,
6031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
6041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
6051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
6061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
6071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 1,
6081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori};
6171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
6181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
6191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Output a single term of CSV.  Actually, p->separator is used for
6201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** the separator, which may or may not be a comma.  p->nullvalue is
621c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** the null value.  Strings are quoted if necessary.
6221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
6231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void output_csv(struct callback_data *p, const char *z, int bSep){
6241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  FILE *out = p->out;
6251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( z==0 ){
6261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(out,"%s",p->nullvalue);
6271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else{
6281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int i;
6291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int nSep = strlen30(p->separator);
6301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    for(i=0; z[i]; i++){
6311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( needCsvQuote[((unsigned char*)z)[i]]
6321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         || (z[i]==p->separator[0] &&
6331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori             (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
6341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        i = 0;
6351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        break;
6361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
6371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
6381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( i==0 ){
6391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      putc('"', out);
6401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; z[i]; i++){
6411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( z[i]=='"' ) putc('"', out);
6421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        putc(z[i], out);
6431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
6441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      putc('"', out);
6451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
6461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(out, "%s", z);
6471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
6481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
6491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( bSep ){
6501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out, "%s", p->separator);
6511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
6521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
6531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
6541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifdef SIGINT
6551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
6561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This routine runs when the user presses Ctrl-C
6571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
6581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void interrupt_handler(int NotUsed){
6591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  UNUSED_PARAMETER(NotUsed);
6601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  seenInterrupt = 1;
6611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( db ) sqlite3_interrupt(db);
6621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
6631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
6641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
6651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
6661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This is the callback routine that the shell
6671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** invokes for each row of a query result.
6681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
6691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
6701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i;
6711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct callback_data *p = (struct callback_data*)pArg;
6721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
6731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  switch( p->mode ){
6741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_Line: {
6751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int w = 5;
6761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( azArg==0 ) break;
6771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nArg; i++){
6781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        int len = strlen30(azCol[i] ? azCol[i] : "");
6791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( len>w ) w = len;
6801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
6811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->cnt++>0 ) fprintf(p->out,"\n");
6821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nArg; i++){
6831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out,"%*s = %s\n", w, azCol[i],
6841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                azArg[i] ? azArg[i] : p->nullvalue);
6851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
6861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
6871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
6881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_Explain:
6891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_Column: {
6901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->cnt++==0 ){
6911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        for(i=0; i<nArg; i++){
6921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          int w, n;
6931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( i<ArraySize(p->colWidth) ){
6941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            w = p->colWidth[i];
6951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }else{
6961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            w = 0;
6971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }
6981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( w<=0 ){
6991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            w = strlen30(azCol[i] ? azCol[i] : "");
7001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            if( w<10 ) w = 10;
7011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
7021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            if( w<n ) w = n;
7031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }
7041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( i<ArraySize(p->actualWidth) ){
7051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            p->actualWidth[i] = w;
7061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }
7071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( p->showHeader ){
7081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");
7091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }
7101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
7111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( p->showHeader ){
7121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          for(i=0; i<nArg; i++){
7131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            int w;
7141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            if( i<ArraySize(p->actualWidth) ){
7151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori               w = p->actualWidth[i];
7161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            }else{
7171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori               w = 10;
7181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            }
7191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
7201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                   "----------------------------------------------------------",
7211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                    i==nArg-1 ? "\n": "  ");
7221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }
7231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
7241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
7251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( azArg==0 ) break;
7261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nArg; i++){
7271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        int w;
7281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( i<ArraySize(p->actualWidth) ){
7291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori           w = p->actualWidth[i];
7301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else{
7311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori           w = 10;
7321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
7331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( p->mode==MODE_Explain && azArg[i] &&
7341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori           strlen30(azArg[i])>w ){
7351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          w = strlen30(azArg[i]);
7361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
7371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out,"%-*.*s%s",w,w,
7381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
7391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
7401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
7411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
7421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_Semi:
7431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_List: {
7441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->cnt++==0 && p->showHeader ){
7451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        for(i=0; i<nArg; i++){
7461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
7471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
7481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
7491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( azArg==0 ) break;
7501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nArg; i++){
7511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        char *z = azArg[i];
7521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( z==0 ) z = p->nullvalue;
7531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out, "%s", z);
7541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( i<nArg-1 ){
7551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out, "%s", p->separator);
7561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else if( p->mode==MODE_Semi ){
7571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out, ";\n");
7581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else{
7591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out, "\n");
7601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
7611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
7621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
7631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
7641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_Html: {
7651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->cnt++==0 && p->showHeader ){
7661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out,"<TR>");
7671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        for(i=0; i<nArg; i++){
7681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out,"<TH>");
7691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          output_html_string(p->out, azCol[i]);
7701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out,"</TH>\n");
7711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
7721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out,"</TR>\n");
7731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
7741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( azArg==0 ) break;
7751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out,"<TR>");
7761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nArg; i++){
7771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out,"<TD>");
7781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
7791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out,"</TD>\n");
7801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
7811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out,"</TR>\n");
7821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
7831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
7841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_Tcl: {
7851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->cnt++==0 && p->showHeader ){
7861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        for(i=0; i<nArg; i++){
7871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          output_c_string(p->out,azCol[i] ? azCol[i] : "");
7881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out, "%s", p->separator);
7891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
7901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out,"\n");
7911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
7921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( azArg==0 ) break;
7931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nArg; i++){
7941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
7951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out, "%s", p->separator);
7961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
7971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out,"\n");
7981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
7991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
8001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_Csv: {
8011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->cnt++==0 && p->showHeader ){
8021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        for(i=0; i<nArg; i++){
8031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
8041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
8051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(p->out,"\n");
8061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
8071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( azArg==0 ) break;
8081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nArg; i++){
8091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        output_csv(p, azArg[i], i<nArg-1);
8101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
8111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out,"\n");
8121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
8131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
8141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    case MODE_Insert: {
8151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->cnt++;
8161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( azArg==0 ) break;
8171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
8181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nArg; i++){
8191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        char *zSep = i>0 ? ",": "";
8201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
8211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out,"%sNULL",zSep);
8221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else if( aiType && aiType[i]==SQLITE_TEXT ){
8231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( zSep[0] ) fprintf(p->out,"%s",zSep);
8241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          output_quoted_string(p->out, azArg[i]);
8251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
8261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out,"%s%s",zSep, azArg[i]);
8271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
8281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          const void *pBlob = sqlite3_column_blob(p->pStmt, i);
8291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          int nBlob = sqlite3_column_bytes(p->pStmt, i);
8301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( zSep[0] ) fprintf(p->out,"%s",zSep);
8311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          output_hex_blob(p->out, pBlob, nBlob);
8321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else if( isNumber(azArg[i], 0) ){
8331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(p->out,"%s%s",zSep, azArg[i]);
8341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else{
8351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( zSep[0] ) fprintf(p->out,"%s",zSep);
8361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          output_quoted_string(p->out, azArg[i]);
8371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
8381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
8391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out,");\n");
8401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;
8411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
8421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
8431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return 0;
8441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
8451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
8461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
8471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This is the callback routine that the SQLite library
8481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** invokes for each row of a query result.
8491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
8501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int callback(void *pArg, int nArg, char **azArg, char **azCol){
8511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* since we don't have type info, call the shell_callback with a NULL value */
8521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return shell_callback(pArg, nArg, azArg, azCol, NULL);
8531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
8541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
8551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
8561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Set the destination table field of the callback_data structure to
8571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** the name of the table given.  Escape any quote characters in the
8581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** table name.
8591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
8601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void set_table_name(struct callback_data *p, const char *zName){
8611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i, n;
8621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int needQuote;
8631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *z;
8641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
8651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( p->zDestTable ){
8661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    free(p->zDestTable);
8671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    p->zDestTable = 0;
8681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
8691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zName==0 ) return;
8701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
8711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(i=n=0; zName[i]; i++, n++){
8721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
8731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      needQuote = 1;
8741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zName[i]=='\'' ) n++;
8751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
8761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
8771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( needQuote ) n += 2;
8781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  z = p->zDestTable = malloc( n+1 );
8791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( z==0 ){
8801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(stderr,"Error: out of memory\n");
8811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    exit(1);
8821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
8831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  n = 0;
8841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( needQuote ) z[n++] = '\'';
8851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(i=0; zName[i]; i++){
8861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    z[n++] = zName[i];
8871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zName[i]=='\'' ) z[n++] = '\'';
8881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
8891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( needQuote ) z[n++] = '\'';
8901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  z[n] = 0;
8911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
8921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
8931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* zIn is either a pointer to a NULL-terminated string in memory obtained
8941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** from malloc(), or a NULL pointer. The string pointed to by zAppend is
8951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** added to zIn, and the result returned in memory obtained from malloc().
8961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** zIn, if it was not NULL, is freed.
8971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
8981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** If the third argument, quote, is not '\0', then it is used as a
8991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** quote character for zAppend.
9001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
9011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char *appendText(char *zIn, char const *zAppend, char quote){
9021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int len;
9031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i;
9041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nAppend = strlen30(zAppend);
9051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nIn = (zIn?strlen30(zIn):0);
9061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
9071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  len = nAppend+nIn+1;
9081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( quote ){
9091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    len += 2;
9101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    for(i=0; i<nAppend; i++){
9111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zAppend[i]==quote ) len++;
9121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
9131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
9141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
9151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zIn = (char *)realloc(zIn, len);
9161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( !zIn ){
9171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 0;
9181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
9191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
9201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( quote ){
9211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zCsr = &zIn[nIn];
9221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    *zCsr++ = quote;
9231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    for(i=0; i<nAppend; i++){
9241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      *zCsr++ = zAppend[i];
9251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zAppend[i]==quote ) *zCsr++ = quote;
9261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
9271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    *zCsr++ = quote;
9281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    *zCsr++ = '\0';
9291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    assert( (zCsr-zIn)==len );
9301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else{
9311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    memcpy(&zIn[nIn], zAppend, nAppend);
9321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zIn[len-1] = '\0';
9331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
9341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
9351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return zIn;
9361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
9371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
9381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
9391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
940c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** Execute a query statement that will generate SQL output.  Print
941c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** the result columns, comma-separated, on a line and then add a
942c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** semicolon terminator to the end of that line.
9431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
944c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** If the number of columns is 1 and that column contains text "--"
945c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** then write the semicolon on a separate line.  That way, if a
946c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** "--" comment occurs at the end of the statement, the comment
947c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** won't consume the semicolon terminator.
9481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
9491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int run_table_dump_query(
95090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  struct callback_data *p, /* Query context */
95190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  const char *zSelect,     /* SELECT statement to extract content */
95290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  const char *zFirstRow    /* Print before first row, if not NULL */
9531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori){
9541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_stmt *pSelect;
9551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc;
956c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  int nResult;
957c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  int i;
958c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  const char *z;
95990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
9601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( rc!=SQLITE_OK || !pSelect ){
96190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
96290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    p->nErr++;
9631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return rc;
9641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
9651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  rc = sqlite3_step(pSelect);
966c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  nResult = sqlite3_column_count(pSelect);
9671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  while( rc==SQLITE_ROW ){
9681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zFirstRow ){
96990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(p->out, "%s", zFirstRow);
9701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zFirstRow = 0;
9711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
972c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    z = (const char*)sqlite3_column_text(pSelect, 0);
973c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    fprintf(p->out, "%s", z);
974c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    for(i=1; i<nResult; i++){
975c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
976c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }
977c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( z==0 ) z = "";
978c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
979c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( z[0] ){
980c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      fprintf(p->out, "\n;\n");
981c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else{
982c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      fprintf(p->out, ";\n");
983c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }
9841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_step(pSelect);
9851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
98690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  rc = sqlite3_finalize(pSelect);
98790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( rc!=SQLITE_OK ){
98890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
98990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    p->nErr++;
99090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }
99190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  return rc;
9921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
9931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
9941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
9951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Allocate space and save off current error string.
9961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
9971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char *save_err_msg(
9981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3 *db            /* Database to query */
9991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori){
10001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
10011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zErrMsg = sqlite3_malloc(nErrMsg);
10021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zErrMsg ){
10031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
10041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
10051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return zErrMsg;
10061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
10071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
10081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
1009de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori** Display memory stats.
1010de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori*/
1011de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Noristatic int display_stats(
1012de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  sqlite3 *db,                /* Database to query */
1013de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  struct callback_data *pArg, /* Pointer to struct callback_data */
1014de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  int bReset                  /* True to reset the stats */
1015de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori){
1016de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  int iCur;
1017de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  int iHiwtr;
1018de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1019de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  if( pArg && pArg->out ){
1020de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1021de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1022de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
1023de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Memory Used:                         %d (max %d) bytes\n", iCur, iHiwtr);
1024de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1025de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
102690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Number of Outstanding Allocations:   %d (max %d)\n", iCur, iHiwtr);
1027de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori/*
1028de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori** Not currently used by the CLI.
1029de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    iHiwtr = iCur = -1;
1030de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1031de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    fprintf(pArg->out, "Number of Pcache Pages Used:         %d (max %d) pages\n", iCur, iHiwtr);
1032de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori*/
1033de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1034de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1035de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Number of Pcache Overflow Bytes:     %d (max %d) bytes\n", iCur, iHiwtr);
1036de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori/*
1037de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori** Not currently used by the CLI.
1038de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    iHiwtr = iCur = -1;
1039de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1040de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    fprintf(pArg->out, "Number of Scratch Allocations Used:  %d (max %d)\n", iCur, iHiwtr);
1041de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori*/
1042de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1043de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1044de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Number of Scratch Overflow Bytes:    %d (max %d) bytes\n", iCur, iHiwtr);
1045de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1046de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1047de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Largest Allocation:                  %d bytes\n", iHiwtr);
1048de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1049de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1050de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Largest Pcache Allocation:           %d bytes\n", iHiwtr);
1051de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1052de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1053de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Largest Scratch Allocation:          %d bytes\n", iHiwtr);
1054de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori#ifdef YYTRACKMAXSTACKDEPTH
1055de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1056de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1057de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Deepest Parser Stack:                %d (max %d)\n", iCur, iHiwtr);
1058de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori#endif
1059de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  }
1060de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1061de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  if( pArg && pArg->out && db ){
1062de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1063de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1064de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Lookaside Slots Used:                %d (max %d)\n", iCur, iHiwtr);
106590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
106690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Successful lookaside attempts:       %d\n", iHiwtr);
106790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
106890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Lookaside failures due to size:      %d\n", iHiwtr);
106990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
107090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Lookaside failures due to OOM:       %d\n", iHiwtr);
1071de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1072de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
107390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Pager Heap Usage:                    %d bytes\n", iCur);    iHiwtr = iCur = -1;
107490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
107590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Page cache hits:                     %d\n", iCur);
107690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    iHiwtr = iCur = -1;
107790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
107890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Page cache misses:                   %d\n", iCur);
1079de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1080de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1081de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n", iCur);
1082de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1083de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1084de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n", iCur);
1085de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  }
1086de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1087de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  if( pArg && pArg->out && db && pArg->pStmt ){
1088de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1089de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
1090de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1091de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Sort Operations:                     %d\n", iCur);
1092de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1093de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
1094de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  }
1095de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1096de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  return 0;
1097de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori}
1098de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1099de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori/*
11001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Execute a statement or set of statements.  Print
11011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** any result rows/columns depending on the current mode
11021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** set via the supplied callback.
11031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
11041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This is very similar to SQLite's built-in sqlite3_exec()
11051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** function except it takes a slightly different callback
11061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** and callback data argument.
11071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
11081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int shell_exec(
11091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3 *db,                                /* An open database */
11101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *zSql,                           /* SQL to be evaluated */
11111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int (*xCallback)(void*,int,char**,char**,int*),   /* Callback function */
11121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                                              /* (not the same as sqlite3_exec) */
11131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct callback_data *pArg,                 /* Pointer to struct callback_data */
11141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char **pzErrMsg                             /* Error msg written here */
11151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori){
11161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_stmt *pStmt = NULL;     /* Statement to execute. */
11171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc = SQLITE_OK;             /* Return Code */
111890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  int rc2;
11191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *zLeftover;          /* Tail of unprocessed SQL */
11201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
11211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( pzErrMsg ){
11221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    *pzErrMsg = NULL;
11231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
11241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
11251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  while( zSql[0] && (SQLITE_OK == rc) ){
11261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
11271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( SQLITE_OK != rc ){
11281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( pzErrMsg ){
11291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        *pzErrMsg = save_err_msg(db);
11301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
11311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
11321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( !pStmt ){
11331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        /* this happens for a comment or white-space */
11341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zSql = zLeftover;
113590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        while( IsSpace(zSql[0]) ) zSql++;
11361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        continue;
11371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
11381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1139de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      /* save off the prepared statment handle and reset row count */
1140de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      if( pArg ){
1141de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        pArg->pStmt = pStmt;
1142de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        pArg->cnt = 0;
1143de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      }
1144de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
114571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      /* echo the sql statement if echo on */
1146de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      if( pArg && pArg->echoOn ){
114771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori        const char *zStmtSql = sqlite3_sql(pStmt);
1148de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
114971504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      }
115071504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori
115190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      /* Output TESTCTRL_EXPLAIN text of requested */
115290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( pArg && pArg->mode==MODE_Explain ){
115390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        const char *zExplain = 0;
115490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
115590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( zExplain && zExplain[0] ){
115690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          fprintf(pArg->out, "%s", zExplain);
115790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        }
115890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
115990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
11601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      /* perform the first step.  this will tell us if we
11611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      ** have a result set or not and how wide it is.
11621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      */
11631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = sqlite3_step(pStmt);
11641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      /* if we have a result set... */
11651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( SQLITE_ROW == rc ){
11661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        /* if we have a callback... */
11671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( xCallback ){
11681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          /* allocate space for col name ptr, value ptr, and type */
11691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          int nCol = sqlite3_column_count(pStmt);
11701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
11711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( !pData ){
11721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            rc = SQLITE_NOMEM;
11731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }else{
11741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            char **azCols = (char **)pData;      /* Names of result columns */
11751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            char **azVals = &azCols[nCol];       /* Results */
11761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            int *aiTypes = (int *)&azVals[nCol]; /* Result types */
11771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            int i;
11781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            assert(sizeof(int) <= sizeof(char *));
11791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            /* save off ptrs to column names */
11801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            for(i=0; i<nCol; i++){
11811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              azCols[i] = (char *)sqlite3_column_name(pStmt, i);
11821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            }
11831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            do{
11841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              /* extract the data and data types */
11851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              for(i=0; i<nCol; i++){
11861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                azVals[i] = (char *)sqlite3_column_text(pStmt, i);
11871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                aiTypes[i] = sqlite3_column_type(pStmt, i);
11881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
11891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                  rc = SQLITE_NOMEM;
11901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                  break; /* from for */
11911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                }
11921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              } /* end for */
11931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
11941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              /* if data and types extracted successfully... */
11951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              if( SQLITE_ROW == rc ){
11961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                /* call the supplied callback with the result row data */
11971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
11981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                  rc = SQLITE_ABORT;
11991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                }else{
12001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                  rc = sqlite3_step(pStmt);
12011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                }
12021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              }
12031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            } while( SQLITE_ROW == rc );
12041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            sqlite3_free(pData);
12051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }
12061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else{
12071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          do{
12081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            rc = sqlite3_step(pStmt);
12091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          } while( rc == SQLITE_ROW );
12101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
12111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
12121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
1213de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      /* print usage stats if stats on */
1214de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      if( pArg && pArg->statsOn ){
1215de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        display_stats(db, pArg, 0);
1216de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      }
1217de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
12181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      /* Finalize the statement just executed. If this fails, save a
12191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      ** copy of the error message. Otherwise, set zSql to point to the
12201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      ** next statement to execute. */
122190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      rc2 = sqlite3_finalize(pStmt);
122290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( rc!=SQLITE_NOMEM ) rc = rc2;
12231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( rc==SQLITE_OK ){
12241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zSql = zLeftover;
122590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        while( IsSpace(zSql[0]) ) zSql++;
12261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else if( pzErrMsg ){
12271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        *pzErrMsg = save_err_msg(db);
12281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
1229de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1230de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      /* clear saved stmt handle */
1231de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      if( pArg ){
1232de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        pArg->pStmt = NULL;
1233de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      }
12341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
12351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  } /* end while */
12361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
12371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return rc;
12381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
12391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
12401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
12411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
12421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This is a different callback routine used for dumping the database.
12431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Each row received by this callback consists of a table name,
12441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** the table type ("index" or "table") and SQL to create the table.
12451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** This routine should print text sufficient to recreate the table.
12461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
12471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
12481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc;
12491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *zTable;
12501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *zType;
12511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *zSql;
12521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *zPrepStmt = 0;
12531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct callback_data *p = (struct callback_data *)pArg;
12541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
12551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  UNUSED_PARAMETER(azCol);
12561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( nArg!=3 ) return 1;
12571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zTable = azArg[0];
12581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zType = azArg[1];
12591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zSql = azArg[2];
12601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
12611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( strcmp(zTable, "sqlite_sequence")==0 ){
12621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zPrepStmt = "DELETE FROM sqlite_sequence;\n";
12631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else if( strcmp(zTable, "sqlite_stat1")==0 ){
12641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out, "ANALYZE sqlite_master;\n");
12651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else if( strncmp(zTable, "sqlite_", 7)==0 ){
12661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 0;
12671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
12681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zIns;
12691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( !p->writableSchema ){
12701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out, "PRAGMA writable_schema=ON;\n");
12711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->writableSchema = 1;
12721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
12731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zIns = sqlite3_mprintf(
12741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori       "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
12751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori       "VALUES('table','%q','%q',0,'%q');",
12761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori       zTable, zTable, zSql);
12771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out, "%s\n", zIns);
12781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_free(zIns);
12791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 0;
12801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else{
12811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out, "%s;\n", zSql);
12821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
12831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
12841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( strcmp(zType, "table")==0 ){
12851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_stmt *pTableInfo = 0;
12861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zSelect = 0;
12871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zTableInfo = 0;
12881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zTmp = 0;
12891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int nRow = 0;
1290c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    int kk;
12911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
12921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
12931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zTableInfo = appendText(zTableInfo, zTable, '"');
12941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zTableInfo = appendText(zTableInfo, ");", 0);
12951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
12961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
12971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    free(zTableInfo);
12981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc!=SQLITE_OK || !pTableInfo ){
12991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
13001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
13011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
13021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1303c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( !isalpha(zTable[0]) ){
1304c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      kk = 0;
1305c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else{
1306c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      for(kk=1; isalnum(zTable[kk]); kk++){}
1307c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }
1308c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    zTmp = appendText(zTmp, zTable, zTable[kk] ? '"' : 0);
13091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zTmp ){
13101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSelect = appendText(zSelect, zTmp, '\'');
13111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
13121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
13131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_step(pTableInfo);
13141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    while( rc==SQLITE_ROW ){
13151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
13161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSelect = appendText(zSelect, "quote(", 0);
13171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSelect = appendText(zSelect, zText, '"');
13181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = sqlite3_step(pTableInfo);
13191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( rc==SQLITE_ROW ){
1320c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        zSelect = appendText(zSelect, "), ", 0);
13211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else{
13221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zSelect = appendText(zSelect, ") ", 0);
13231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
13241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      nRow++;
13251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
13261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_finalize(pTableInfo);
13271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc!=SQLITE_OK || nRow==0 ){
13281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      free(zSelect);
13291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
13301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
13311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zSelect = appendText(zSelect, "|| ')' FROM  ", 0);
13321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zSelect = appendText(zSelect, zTable, '"');
13331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
133490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    rc = run_table_dump_query(p, zSelect, zPrepStmt);
13351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc==SQLITE_CORRUPT ){
13361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
133790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      run_table_dump_query(p, zSelect, 0);
13381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
13391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zSelect ) free(zSelect);
13401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
13411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return 0;
13421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
13431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
13441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
13451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Run zQuery.  Use dump_callback() as the callback routine so that
13461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** the contents of the query are output as SQL statements.
13471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
13481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** If we get a SQLITE_CORRUPT error, rerun the query after appending
13491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** "ORDER BY rowid DESC" to the end.
13501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
13511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int run_schema_dump_query(
13521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct callback_data *p,
135390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  const char *zQuery
13541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori){
13551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc;
135690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  char *zErr = 0;
135790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
13581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( rc==SQLITE_CORRUPT ){
13591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zQ2;
13601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int len = strlen30(zQuery);
136190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
136290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( zErr ){
136390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(p->out, "/****** %s ******/\n", zErr);
136490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_free(zErr);
136590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      zErr = 0;
136690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
13671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zQ2 = malloc( len+100 );
13681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zQ2==0 ) return rc;
13691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
137090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
137190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( rc ){
137290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
137390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else{
137490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      rc = SQLITE_CORRUPT;
137590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
137690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_free(zErr);
13771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    free(zQ2);
13781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
13791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return rc;
13801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
13811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
13821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
13831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Text of a help message
13841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
13851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char zHelp[] =
13861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
13871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".bail ON|OFF           Stop after hitting an error.  Default OFF\n"
13881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".databases             List names and files of attached databases\n"
13891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
13901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         If TABLE specified, only dump tables matching\n"
13911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         LIKE pattern TABLE.\n"
13921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".echo ON|OFF           Turn command echo on or off\n"
13931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".exit                  Exit this program\n"
13941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".explain ?ON|OFF?      Turn output mode suitable for EXPLAIN on or off.\n"
13951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         With no args, it turns EXPLAIN on.\n"
13961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".header(s) ON|OFF      Turn display of headers on or off\n"
13971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".help                  Show this message\n"
13981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".import FILE TABLE     Import data from FILE into TABLE\n"
13991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".indices ?TABLE?       Show names of all indices\n"
14001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         If TABLE specified, only show indices for tables\n"
14011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         matching LIKE pattern TABLE.\n"
14021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifdef SQLITE_ENABLE_IOTRACE
14031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".iotrace FILE          Enable I/O diagnostic logging to FILE\n"
14041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
14051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifndef SQLITE_OMIT_LOAD_EXTENSION
14061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".load FILE ?ENTRY?     Load an extension library\n"
14071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
14081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".log FILE|off          Turn logging on or off.  FILE can be stderr/stdout\n"
14091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
14101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         csv      Comma-separated values\n"
14111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         column   Left-aligned columns.  (See .width)\n"
14121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         html     HTML <table> code\n"
14131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         insert   SQL insert statements for TABLE\n"
14141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         line     One value per line\n"
14151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         list     Values delimited by .separator string\n"
14161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         tabs     Tab-separated values\n"
14171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         tcl      TCL list elements\n"
14181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".nullvalue STRING      Print STRING in place of NULL values\n"
14191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".output FILENAME       Send output to FILENAME\n"
14201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".output stdout         Send output to the screen\n"
14211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
14221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".quit                  Exit this program\n"
14231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".read FILENAME         Execute SQL in FILENAME\n"
14241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
14251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".schema ?TABLE?        Show the CREATE statements\n"
14261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         If TABLE specified, only show tables matching\n"
14271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         LIKE pattern TABLE.\n"
14281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".separator STRING      Change separator used by output mode and .import\n"
14291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".show                  Show the current values for various settings\n"
1430de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  ".stats ON|OFF          Turn stats on or off\n"
14311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".tables ?TABLE?        List names of tables\n"
14321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         If TABLE specified, only list tables matching\n"
14331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "                         LIKE pattern TABLE.\n"
14341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".timeout MS            Try opening locked tables for MS milliseconds\n"
143590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  ".vfsname ?AUX?         Print the name of the VFS stack\n"
14361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
14371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori;
14381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
14391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char zTimerHelp[] =
14401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ".timer ON|OFF          Turn the CPU timer measurement on or off\n"
14411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori;
14421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
14431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/* Forward reference */
14441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int process_input(struct callback_data *p, FILE *in);
14451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
14461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
14471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Make sure the database is open.  If it is not, then open it.  If
14481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** the database fails to open, print an error message and exit.
14491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
14501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void open_db(struct callback_data *p){
14511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( p->db==0 ){
14521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_open(p->zDbFilename, &p->db);
14531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    db = p->db;
14541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( db && sqlite3_errcode(db)==SQLITE_OK ){
14551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
14561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          shellstaticFunc, 0, 0);
14571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
14581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
14591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
14601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          p->zDbFilename, sqlite3_errmsg(db));
14611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      exit(1);
14621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
14631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifndef SQLITE_OMIT_LOAD_EXTENSION
14641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_enable_load_extension(p->db, 1);
14651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
14661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
14671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
14681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
14691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
14701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Do C-language style dequoting.
14711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
14721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**    \t    -> tab
14731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**    \n    -> newline
14741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**    \r    -> carriage return
14751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**    \NNN  -> ascii character NNN in octal
14761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**    \\    -> backslash
14771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
14781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void resolve_backslashes(char *z){
14791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i, j;
14801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char c;
14811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(i=j=0; (c = z[i])!=0; i++, j++){
14821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( c=='\\' ){
14831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      c = z[++i];
14841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( c=='n' ){
14851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        c = '\n';
14861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else if( c=='t' ){
14871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        c = '\t';
14881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else if( c=='r' ){
14891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        c = '\r';
14901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else if( c>='0' && c<='7' ){
14911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        c -= '0';
14921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( z[i+1]>='0' && z[i+1]<='7' ){
14931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          i++;
14941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          c = (c<<3) + z[i] - '0';
14951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( z[i+1]>='0' && z[i+1]<='7' ){
14961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            i++;
14971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            c = (c<<3) + z[i] - '0';
14981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }
14991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
15001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
15011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
15021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    z[j] = c;
15031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
15041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  z[j] = 0;
15051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
15061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
15071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
15081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Interpret zArg as a boolean value.  Return either 0 or 1.
15091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
15101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int booleanValue(char *zArg){
15111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int val = atoi(zArg);
15121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int j;
15131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(j=0; zArg[j]; j++){
151490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    zArg[j] = ToLower(zArg[j]);
15151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
15161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( strcmp(zArg,"on")==0 ){
15171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    val = 1;
15181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else if( strcmp(zArg,"yes")==0 ){
15191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    val = 1;
15201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
15211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return val;
15221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
15231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
15241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
15251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** If an input line begins with "." then invoke this routine to
15261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** process that line.
15271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
15281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Return 1 on error, 2 to exit, and 0 otherwise.
15291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
15301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int do_meta_command(char *zLine, struct callback_data *p){
15311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i = 1;
15321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nArg = 0;
15331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int n, c;
15341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc = 0;
15351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *azArg[50];
15361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
15371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* Parse the input line into tokens.
15381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  */
15391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  while( zLine[i] && nArg<ArraySize(azArg) ){
154090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    while( IsSpace(zLine[i]) ){ i++; }
15411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zLine[i]==0 ) break;
15421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zLine[i]=='\'' || zLine[i]=='"' ){
15431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int delim = zLine[i++];
15441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      azArg[nArg++] = &zLine[i];
15451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      while( zLine[i] && zLine[i]!=delim ){ i++; }
15461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zLine[i]==delim ){
15471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zLine[i++] = 0;
15481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
15491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
15501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
15511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      azArg[nArg++] = &zLine[i];
155290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
15531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zLine[i] ) zLine[i++] = 0;
15541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      resolve_backslashes(azArg[nArg-1]);
15551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
15561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
15571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
15581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* Process the input line.
15591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  */
15601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( nArg==0 ) return 0; /* no tokens, no error */
15611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  n = strlen30(azArg[0]);
15621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  c = azArg[0][0];
15631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
15641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    const char *zDestFile;
15651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    const char *zDb;
15661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3 *pDest;
15671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_backup *pBackup;
15681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg==2 ){
15691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zDestFile = azArg[1];
15701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zDb = "main";
15711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
15721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zDestFile = azArg[2];
15731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zDb = azArg[1];
15741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
15751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_open(zDestFile, &pDest);
15761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc!=SQLITE_OK ){
15771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
15781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_close(pDest);
15791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
15801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
15811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
15821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
15831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( pBackup==0 ){
15841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
15851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_close(pDest);
15861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
15871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
15881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
15891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_backup_finish(pBackup);
15901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc==SQLITE_DONE ){
15911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 0;
15921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
15931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
15941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
15951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
15961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_close(pDest);
15971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
15981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
15991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
16001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    bail_on_error = booleanValue(azArg[1]);
16011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
16021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
16031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
16041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    struct callback_data data;
16051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zErrMsg = 0;
16061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
16071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    memcpy(&data, p, sizeof(data));
16081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.showHeader = 1;
16091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.mode = MODE_Column;
16101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.colWidth[0] = 3;
16111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.colWidth[1] = 15;
16121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.colWidth[2] = 58;
16131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.cnt = 0;
16141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
16151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zErrMsg ){
16161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: %s\n", zErrMsg);
16171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_free(zErrMsg);
16181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
16191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
16201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
16211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
16221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
16231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
16241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    /* When playing back a "dump", the content might appear in an order
16251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    ** which causes immediate foreign key constraints to be violated.
16261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    ** So disable foreign-key constraint enforcement to prevent problems. */
16271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
16281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out, "BEGIN TRANSACTION;\n");
16291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    p->writableSchema = 0;
163090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
163190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    p->nErr = 0;
16321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg==1 ){
16331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      run_schema_dump_query(p,
16341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name, type, sql FROM sqlite_master "
163590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
16361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
16371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      run_schema_dump_query(p,
16381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name, type, sql FROM sqlite_master "
163990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        "WHERE name=='sqlite_sequence'"
16401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
164190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      run_table_dump_query(p,
16421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT sql FROM sqlite_master "
16431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
16441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
16451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
16461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int i;
16471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=1; i<nArg; i++){
16481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zShellStatic = azArg[i];
16491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        run_schema_dump_query(p,
16501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "SELECT name, type, sql FROM sqlite_master "
16511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "WHERE tbl_name LIKE shellstatic() AND type=='table'"
165290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          "  AND sql NOT NULL");
165390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        run_table_dump_query(p,
16541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "SELECT sql FROM sqlite_master "
16551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "WHERE sql NOT NULL"
16561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "  AND type IN ('index','trigger','view')"
16571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "  AND tbl_name LIKE shellstatic()", 0
16581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        );
16591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zShellStatic = 0;
16601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
16611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
16621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( p->writableSchema ){
16631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
16641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->writableSchema = 0;
16651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
166690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
166790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
166890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
16691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
16701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
16711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
16721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    p->echoOn = booleanValue(azArg[1]);
16731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
16741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
16751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='e' && strncmp(azArg[0], "exit", n)==0  && nArg==1 ){
16761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = 2;
16771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
16781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
16791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
16801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
16811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if(val == 1) {
16821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if(!p->explainPrev.valid) {
16831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        p->explainPrev.valid = 1;
16841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        p->explainPrev.mode = p->mode;
16851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        p->explainPrev.showHeader = p->showHeader;
16861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
16871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
16881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      /* We could put this code under the !p->explainValid
16891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      ** condition so that it does not execute if we are already in
16901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      ** explain mode. However, always executing it allows us an easy
16911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      ** was to reset to explain mode in case the user previously
16921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      ** did an .explain followed by a .width, .mode or .header
16931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      ** command.
16941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      */
16951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_Explain;
16961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->showHeader = 1;
16971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      memset(p->colWidth,0,ArraySize(p->colWidth));
16981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[0] = 4;                  /* addr */
16991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[1] = 13;                 /* opcode */
17001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[2] = 4;                  /* P1 */
17011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[3] = 4;                  /* P2 */
17021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[4] = 4;                  /* P3 */
17031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[5] = 13;                 /* P4 */
17041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[6] = 2;                  /* P5 */
17051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[7] = 13;                  /* Comment */
17061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if (p->explainPrev.valid) {
17071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->explainPrev.valid = 0;
17081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = p->explainPrev.mode;
17091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->showHeader = p->explainPrev.showHeader;
17101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
17111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
17121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
17131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
17141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
17151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
17161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    p->showHeader = booleanValue(azArg[1]);
17171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
17181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
17191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
17201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(stderr,"%s",zHelp);
17211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( HAS_TIMER ){
17221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"%s",zTimerHelp);
17231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
17241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
17251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
17261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
17271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zTable = azArg[2];    /* Insert data into this table */
17281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zFile = azArg[1];     /* The file from which to extract data */
17291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_stmt *pStmt = NULL; /* A statement */
17301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int nCol;                   /* Number of columns in the table */
17311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int nByte;                  /* Number of bytes in an SQL string */
17321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int i, j;                   /* Loop counters */
17331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int nSep;                   /* Number of bytes in p->separator[] */
17341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zSql;                 /* An SQL statement */
17351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zLine;                /* A single line of input from the file */
17361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char **azCol;               /* zLine[] broken up into columns */
17371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zCommit;              /* How to commit changes */
17381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    FILE *in;                   /* The input file */
17391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int lineno = 0;             /* Line number of input file */
17401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
17411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
17421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    nSep = strlen30(p->separator);
17431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nSep==0 ){
17441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: non-null separator required for import\n");
17451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
17461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
174790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
17481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zSql==0 ){
17491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: out of memory\n");
17501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
17511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
17521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    nByte = strlen30(zSql);
17531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
17541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_free(zSql);
17551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc ){
17561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if (pStmt) sqlite3_finalize(pStmt);
17571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
17581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
17591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
17601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    nCol = sqlite3_column_count(pStmt);
17611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_finalize(pStmt);
17621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    pStmt = 0;
17631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nCol==0 ) return 0; /* no columns, no error */
17641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zSql = malloc( nByte + 20 + nCol*2 );
17651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zSql==0 ){
17661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: out of memory\n");
17671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
17681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
176990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
17701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    j = strlen30(zSql);
17711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    for(i=1; i<nCol; i++){
17721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSql[j++] = ',';
17731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSql[j++] = '?';
17741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
17751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zSql[j++] = ')';
17761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zSql[j] = 0;
17771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
17781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    free(zSql);
17791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc ){
17801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
17811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if (pStmt) sqlite3_finalize(pStmt);
17821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
17831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
17841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    in = fopen(zFile, "rb");
17851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( in==0 ){
17861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
17871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_finalize(pStmt);
17881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
17891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
17901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
17911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( azCol==0 ){
17921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: out of memory\n");
17931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fclose(in);
17941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_finalize(pStmt);
17951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
17961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
17971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
17981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zCommit = "COMMIT";
1799c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    while( (zLine = local_getline(0, in, 1))!=0 ){
1800c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      char *z, c;
1801c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      int inQuote = 0;
18021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      lineno++;
18031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      azCol[0] = zLine;
1804c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      for(i=0, z=zLine; (c = *z)!=0; z++){
1805c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( c=='"' ) inQuote = !inQuote;
1806c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( c=='\n' ) lineno++;
1807c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
18081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          *z = 0;
18091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          i++;
18101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          if( i<nCol ){
18111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            azCol[i] = &z[nSep];
18121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            z += nSep-1;
18131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          }
18141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
18151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      } /* end for */
18161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      *z = 0;
18171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( i+1!=nCol ){
18181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr,
18191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                "Error: %s line %d: expected %d columns of data but found %d\n",
18201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                zFile, lineno, nCol, i+1);
18211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zCommit = "ROLLBACK";
18221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        free(zLine);
18231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        rc = 1;
18241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        break; /* from while */
18251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
18261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nCol; i++){
1827c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( azCol[i][0]=='"' ){
1828c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          int k;
1829c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          for(z=azCol[i], j=1, k=0; z[j]; j++){
1830c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown            if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1831c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown            z[k++] = z[j];
1832c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          }
1833c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          z[k] = 0;
1834c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        }
18351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
18361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
18371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_step(pStmt);
18381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = sqlite3_reset(pStmt);
18391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      free(zLine);
18401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( rc!=SQLITE_OK ){
18411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
18421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zCommit = "ROLLBACK";
18431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        rc = 1;
18441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        break; /* from while */
18451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
18461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    } /* end while */
18471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    free(azCol);
18481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fclose(in);
18491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_finalize(pStmt);
18501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_exec(p->db, zCommit, 0, 0, 0);
18511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
18521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
18531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
18541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    struct callback_data data;
18551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zErrMsg = 0;
18561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
18571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    memcpy(&data, p, sizeof(data));
18581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.showHeader = 0;
18591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.mode = MODE_List;
18601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg==1 ){
18611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = sqlite3_exec(p->db,
18621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name FROM sqlite_master "
18631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
18641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "UNION ALL "
18651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name FROM sqlite_temp_master "
18661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE type='index' "
18671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "ORDER BY 1",
18681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        callback, &data, &zErrMsg
18691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
18701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
18711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zShellStatic = azArg[1];
18721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = sqlite3_exec(p->db,
18731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name FROM sqlite_master "
18741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE type='index' AND tbl_name LIKE shellstatic() "
18751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "UNION ALL "
18761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name FROM sqlite_temp_master "
18771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE type='index' AND tbl_name LIKE shellstatic() "
18781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "ORDER BY 1",
18791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        callback, &data, &zErrMsg
18801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
18811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zShellStatic = 0;
18821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
18831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zErrMsg ){
18841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: %s\n", zErrMsg);
18851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_free(zErrMsg);
18861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
18871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( rc != SQLITE_OK ){
18881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
18891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
18901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
18911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
18921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
18931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifdef SQLITE_ENABLE_IOTRACE
18941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
18951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    extern void (*sqlite3IoTrace)(const char*, ...);
18961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( iotrace && iotrace!=stdout ) fclose(iotrace);
18971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    iotrace = 0;
18981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg<2 ){
18991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3IoTrace = 0;
19001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(azArg[1], "-")==0 ){
19011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3IoTrace = iotracePrintf;
19021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      iotrace = stdout;
19031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
19041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      iotrace = fopen(azArg[1], "w");
19051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( iotrace==0 ){
19061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
19071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        sqlite3IoTrace = 0;
19081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        rc = 1;
19091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else{
19101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        sqlite3IoTrace = iotracePrintf;
19111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
19121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
19131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
19141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
19151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
19161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifndef SQLITE_OMIT_LOAD_EXTENSION
19171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
19181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    const char *zFile, *zProc;
19191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zErrMsg = 0;
19201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zFile = azArg[1];
19211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zProc = nArg>=3 ? azArg[2] : 0;
19221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
19231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
19241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc!=SQLITE_OK ){
19251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: %s\n", zErrMsg);
19261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_free(zErrMsg);
19271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
19281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
19291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
19301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
19311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
193290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
19331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    const char *zFile = azArg[1];
19341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
19351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fclose(p->pLog);
19361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->pLog = 0;
19371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
19381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( strcmp(zFile,"stdout")==0 ){
19391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->pLog = stdout;
19401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(zFile, "stderr")==0 ){
19411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->pLog = stderr;
19421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(zFile, "off")==0 ){
19431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->pLog = 0;
19441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
19451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->pLog = fopen(zFile, "w");
19461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->pLog==0 ){
19471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
19481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
19491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
19501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
19511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
19521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
19531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int n2 = strlen30(azArg[1]);
19541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
19551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        ||
19561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
19571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_Line;
19581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
19591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              ||
19601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori              (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
19611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_Column;
19621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
19631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_List;
19641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
19651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_Html;
19661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
19671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_Tcl;
19681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
19691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_Csv;
19701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
19711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
19721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_List;
19731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
19741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
19751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_Insert;
19761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      set_table_name(p, "table");
19771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else {
19781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: mode should be one of: "
19791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         "column csv html insert line list tabs tcl\n");
19801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
19811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
19821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
19831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
19841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
19851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int n2 = strlen30(azArg[1]);
19861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
19871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->mode = MODE_Insert;
19881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      set_table_name(p, azArg[2]);
19891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else {
19901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: invalid arguments: "
19911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        " \"%s\". Enter \".help\" for help\n", azArg[2]);
19921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
19931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
19941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
19951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
19961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
19971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
19981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                     "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
19991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
20001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
20011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
20021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( p->out!=stdout ){
20031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fclose(p->out);
20041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( strcmp(azArg[1],"stdout")==0 ){
20061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->out = stdout;
20071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
20081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
20091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->out = fopen(azArg[1], "wb");
20101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->out==0 ){
20111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
20121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        p->out = stdout;
20131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        rc = 1;
20141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      } else {
20151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
20161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
20171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
20191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
20201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
20211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg >= 2) {
20221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
20231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg >= 3) {
20251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
20261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
20281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
20291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
20301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = 2;
20311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
20321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
20331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
20341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    FILE *alt = fopen(azArg[1], "rb");
20351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( alt==0 ){
20361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
20371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
20381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
20391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = process_input(p, alt);
20401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fclose(alt);
20411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
20431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
20441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
20451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    const char *zSrcFile;
20461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    const char *zDb;
20471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3 *pSrc;
20481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_backup *pBackup;
20491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int nTimeout = 0;
20501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
20511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg==2 ){
20521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSrcFile = azArg[1];
20531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zDb = "main";
20541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
20551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSrcFile = azArg[2];
20561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zDb = azArg[1];
20571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = sqlite3_open(zSrcFile, &pSrc);
20591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc!=SQLITE_OK ){
20601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
20611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_close(pSrc);
20621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
20631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
20651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
20661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( pBackup==0 ){
20671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
20681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_close(pSrc);
20691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
20701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
20721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          || rc==SQLITE_BUSY  ){
20731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( rc==SQLITE_BUSY ){
20741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( nTimeout++ >= 3 ) break;
20751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        sqlite3_sleep(100);
20761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
20771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_backup_finish(pBackup);
20791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( rc==SQLITE_DONE ){
20801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 0;
20811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
20821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: source database is busy\n");
20831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
20841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
20851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
20861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
20871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
20881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_close(pSrc);
20891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
20901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
20911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
20921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    struct callback_data data;
20931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zErrMsg = 0;
20941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
20951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    memcpy(&data, p, sizeof(data));
20961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.showHeader = 0;
20971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.mode = MODE_Semi;
20981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg>1 ){
20991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int i;
210090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
21011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( strcmp(azArg[1],"sqlite_master")==0 ){
21021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        char *new_argv[2], *new_colv[2];
21031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        new_argv[0] = "CREATE TABLE sqlite_master (\n"
21041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  type text,\n"
21051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  name text,\n"
21061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  tbl_name text,\n"
21071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  rootpage integer,\n"
21081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  sql text\n"
21091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      ")";
21101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        new_argv[1] = 0;
21111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        new_colv[0] = "sql";
21121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        new_colv[1] = 0;
21131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        callback(&data, 1, new_argv, new_colv);
21141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        rc = SQLITE_OK;
21151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
21161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        char *new_argv[2], *new_colv[2];
21171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
21181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  type text,\n"
21191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  name text,\n"
21201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  tbl_name text,\n"
21211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  rootpage integer,\n"
21221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      "  sql text\n"
21231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                      ")";
21241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        new_argv[1] = 0;
21251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        new_colv[0] = "sql";
21261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        new_colv[1] = 0;
21271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        callback(&data, 1, new_argv, new_colv);
21281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        rc = SQLITE_OK;
21291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else{
21301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zShellStatic = azArg[1];
21311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        rc = sqlite3_exec(p->db,
21321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "SELECT sql FROM "
21331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
21341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "     FROM sqlite_master UNION ALL"
21351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
213690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          "WHERE lower(tbl_name) LIKE shellstatic()"
213790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          "  AND type!='meta' AND sql NOTNULL "
21381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          "ORDER BY substr(type,2,1), name",
21391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          callback, &data, &zErrMsg);
21401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zShellStatic = 0;
21411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
21421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
21431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = sqlite3_exec(p->db,
21441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         "SELECT sql FROM "
21451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
21461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         "     FROM sqlite_master UNION ALL"
21471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
21481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
21491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         "ORDER BY substr(type,2,1), name",
21501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         callback, &data, &zErrMsg
21511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
21521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
21531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zErrMsg ){
21541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: %s\n", zErrMsg);
21551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_free(zErrMsg);
21561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
21571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( rc != SQLITE_OK ){
21581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: querying schema information\n");
21591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
21601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
21611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 0;
21621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
21631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
21641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
21651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
21661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_snprintf(sizeof(p->separator), p->separator,
21671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                     "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
21681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
21691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
21701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
21711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int i;
21721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
21731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
21741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
21751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
21761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"%9.9s: ", "nullvalue");
21771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      output_c_string(p->out, p->nullvalue);
21781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out, "\n");
21791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"%9.9s: %s\n","output",
21801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori            strlen30(p->outfile) ? p->outfile : "stdout");
21811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"%9.9s: ", "separator");
21821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      output_c_string(p->out, p->separator);
21831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out, "\n");
2184de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
21851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"%9.9s: ","width");
21861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
21871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(p->out,"%d ",p->colWidth[i]);
21881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
21891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(p->out,"\n");
21901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
21911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
2192de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2193de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    p->statsOn = booleanValue(azArg[1]);
2194de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  }else
2195de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
21961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
21971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char **azResult;
21981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int nRow;
21991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zErrMsg;
22001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
22011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( nArg==1 ){
22021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = sqlite3_get_table(p->db,
22031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name FROM sqlite_master "
22041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
22051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "UNION ALL "
22061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name FROM sqlite_temp_master "
22071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE type IN ('table','view') "
22081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "ORDER BY 1",
22091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        &azResult, &nRow, 0, &zErrMsg
22101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
22111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
22121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zShellStatic = azArg[1];
22131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = sqlite3_get_table(p->db,
22141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name FROM sqlite_master "
22151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE type IN ('table','view') AND name LIKE shellstatic() "
22161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "UNION ALL "
22171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "SELECT name FROM sqlite_temp_master "
22181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "WHERE type IN ('table','view') AND name LIKE shellstatic() "
22191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "ORDER BY 1",
22201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        &azResult, &nRow, 0, &zErrMsg
22211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
22221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zShellStatic = 0;
22231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
22241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zErrMsg ){
22251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: %s\n", zErrMsg);
22261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_free(zErrMsg);
22271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
22281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( rc != SQLITE_OK ){
22291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
22301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = 1;
22311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
22321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int len, maxlen = 0;
22331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int i, j;
22341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int nPrintCol, nPrintRow;
22351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=1; i<=nRow; i++){
22361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( azResult[i]==0 ) continue;
22371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        len = strlen30(azResult[i]);
22381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( len>maxlen ) maxlen = len;
22391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
22401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      nPrintCol = 80/(maxlen+2);
22411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( nPrintCol<1 ) nPrintCol = 1;
22421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
22431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      for(i=0; i<nPrintRow; i++){
22441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        for(j=i+1; j<=nRow; j+=nPrintRow){
22451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          char *zSp = j<=nPrintRow ? "" : "  ";
22461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
22471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
22481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        printf("\n");
22491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
22501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
22511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_free_table(azResult);
22521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
22531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
225490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
225590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    static const struct {
225690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown       const char *zCtrlName;   /* Name of a test-control option */
225790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown       int ctrlCode;            /* Integer code for that option */
225890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    } aCtrl[] = {
225990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "prng_save",             SQLITE_TESTCTRL_PRNG_SAVE              },
226090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "prng_restore",          SQLITE_TESTCTRL_PRNG_RESTORE           },
226190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "prng_reset",            SQLITE_TESTCTRL_PRNG_RESET             },
226290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "bitvec_test",           SQLITE_TESTCTRL_BITVEC_TEST            },
226390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "fault_install",         SQLITE_TESTCTRL_FAULT_INSTALL          },
226490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "benign_malloc_hooks",   SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS    },
226590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "pending_byte",          SQLITE_TESTCTRL_PENDING_BYTE           },
226690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "assert",                SQLITE_TESTCTRL_ASSERT                 },
226790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "always",                SQLITE_TESTCTRL_ALWAYS                 },
226890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "reserve",               SQLITE_TESTCTRL_RESERVE                },
226990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },
227090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
227190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "scratchmalloc",         SQLITE_TESTCTRL_SCRATCHMALLOC          },
227290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    };
227390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    int testctrl = -1;
227490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    int rc = 0;
227590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    int i, n;
227690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    open_db(p);
227790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
227890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    /* convert testctrl text option to value. allow any unique prefix
227990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    ** of the option name, or a numerical value. */
228090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    n = strlen30(azArg[1]);
228190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
228290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
228390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( testctrl<0 ){
228490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          testctrl = aCtrl[i].ctrlCode;
228590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        }else{
228690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
228790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          testctrl = -1;
228890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
228990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        }
229090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
229190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
229290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( testctrl<0 ) testctrl = atoi(azArg[1]);
229390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
229490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
229590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else{
229690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      switch(testctrl){
229790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
229890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int, db, int) */
229990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_OPTIMIZATIONS:
230090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_RESERVE:
230190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==3 ){
230290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            int opt = (int)strtol(azArg[2], 0, 0);
230390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl, p->db, opt);
230490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
230590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
230690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes a single int option\n",
230790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                    azArg[1]);
230890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
230990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
231090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
231190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int) */
231290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_PRNG_SAVE:
231390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_PRNG_RESTORE:
231490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_PRNG_RESET:
231590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==2 ){
231690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl);
231790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
231890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
231990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
232090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
232190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
232290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
232390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int, uint) */
232490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_PENDING_BYTE:
232590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==3 ){
232690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            unsigned int opt = (unsigned int)atoi(azArg[2]);
232790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl, opt);
232890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
232990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
233090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes a single unsigned"
233190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                           " int option\n", azArg[1]);
233290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
233390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
233490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
233590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int, int) */
233690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_ASSERT:
233790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_ALWAYS:
233890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==3 ){
233990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            int opt = atoi(azArg[2]);
234090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl, opt);
234190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
234290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
234390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes a single int option\n",
234490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                            azArg[1]);
234590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
234690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
234790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
234890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int, char *) */
234990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_N_KEYWORD
235090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_ISKEYWORD:
235190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==3 ){
235290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            const char *opt = azArg[2];
235390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl, opt);
235490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
235590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
235690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
235790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                            azArg[1]);
235890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
235990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
236090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
236190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
236290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_BITVEC_TEST:
236390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_FAULT_INSTALL:
236490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
236590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_SCRATCHMALLOC:
236690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        default:
236790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
236890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                  azArg[1]);
236990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
237090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
237190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
237290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }else
237390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
23741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
23751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(p);
23761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_busy_timeout(p->db, atoi(azArg[1]));
23771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
23781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
237990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
238090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown   && nArg==2
238190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  ){
23821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    enableTimer = booleanValue(azArg[1]);
23831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
23841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
238590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
238690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    printf("SQLite %s %s\n" /*extra-version-info*/,
238790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_libversion(), sqlite3_sourceid());
238890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }else
238990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
239090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
239190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    const char *zDbName = nArg==2 ? azArg[1] : "main";
239290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    char *zVfsName = 0;
239390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( p->db ){
239490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
239590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( zVfsName ){
239690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        printf("%s\n", zVfsName);
239790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_free(zVfsName);
239890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
239990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
240090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }else
240190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
24021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
24031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int j;
24041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    assert( nArg<=ArraySize(azArg) );
24051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
24061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->colWidth[j-1] = atoi(azArg[j]);
24071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
24081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else
24091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
24101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  {
24111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(stderr, "Error: unknown command or invalid arguments: "
24121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      " \"%s\". Enter \".help\" for help\n", azArg[0]);
24131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = 1;
24141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
24151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
24161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return rc;
24171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
24181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
24191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
24201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Return TRUE if a semicolon occurs anywhere in the first N characters
24211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** of string z[].
24221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
24231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int _contains_semicolon(const char *z, int N){
24241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i;
24251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(i=0; i<N; i++){  if( z[i]==';' ) return 1; }
24261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return 0;
24271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
24281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
24291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
24301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Test to see if a line consists entirely of whitespace.
24311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
24321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int _all_whitespace(const char *z){
24331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(; *z; z++){
243490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( IsSpace(z[0]) ) continue;
24351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( *z=='/' && z[1]=='*' ){
24361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      z += 2;
24371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      while( *z && (*z!='*' || z[1]!='/') ){ z++; }
24381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( *z==0 ) return 0;
24391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      z++;
24401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      continue;
24411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
24421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( *z=='-' && z[1]=='-' ){
24431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      z += 2;
24441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      while( *z && *z!='\n' ){ z++; }
24451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( *z==0 ) return 1;
24461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      continue;
24471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
24481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 0;
24491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
24501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return 1;
24511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
24521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
24531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
24541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Return TRUE if the line typed in is an SQL command terminator other
24551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** than a semi-colon.  The SQL Server style "go" command is understood
24561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** as is the Oracle "/".
24571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
24581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int _is_command_terminator(const char *zLine){
245990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  while( IsSpace(zLine[0]) ){ zLine++; };
24601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
24611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 1;  /* Oracle */
24621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
246390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
24641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori         && _all_whitespace(&zLine[2]) ){
24651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 1;  /* SQL Server */
24661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
24671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return 0;
24681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
24691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
24701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
24711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Return true if zSql is a complete SQL statement.  Return false if it
24721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** ends in the middle of a string literal or C-style comment.
24731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
24741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int _is_complete(char *zSql, int nSql){
24751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc;
24761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zSql==0 ) return 1;
24771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zSql[nSql] = ';';
24781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zSql[nSql+1] = 0;
24791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  rc = sqlite3_complete(zSql);
24801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  zSql[nSql] = 0;
24811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return rc;
24821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
24831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
24841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
24851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Read input from *in and process it.  If *in==0 then input
24861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** is interactive - the user is typing it it.  Otherwise, input
24871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** is coming from a file or device.  A prompt is issued and history
24881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** is saved only if input is interactive.  An interrupt signal will
24891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** cause this routine to exit immediately, unless input is interactive.
24901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
24911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Return the number of errors.
24921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
24931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int process_input(struct callback_data *p, FILE *in){
24941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zLine = 0;
24951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zSql = 0;
24961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nSql = 0;
24971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nSqlPrior = 0;
24981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zErrMsg;
24991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc;
25001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int errCnt = 0;
25011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int lineno = 0;
25021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int startline = 0;
25031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
25041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
25051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fflush(p->out);
25061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    free(zLine);
25071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zLine = one_input_line(zSql, in);
25081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zLine==0 ){
25091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      break;  /* We have reached EOF */
25101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
25111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( seenInterrupt ){
25121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( in!=0 ) break;
25131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      seenInterrupt = 0;
25141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
25151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    lineno++;
25161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
25171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zLine && zLine[0]=='.' && nSql==0 ){
25181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( p->echoOn ) printf("%s\n", zLine);
25191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = do_meta_command(zLine, p);
25201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( rc==2 ){ /* exit requested */
25211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        break;
25221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else if( rc ){
25231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        errCnt++;
25241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
25251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      continue;
25261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
25271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
25281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      memcpy(zLine,";",2);
25291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
25301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    nSqlPrior = nSql;
25311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zSql==0 ){
25321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int i;
253390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
25341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zLine[i]!=0 ){
25351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        nSql = strlen30(zLine);
25361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        zSql = malloc( nSql+3 );
25371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( zSql==0 ){
25381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(stderr, "Error: out of memory\n");
25391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          exit(1);
25401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
25411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        memcpy(zSql, zLine, nSql+1);
25421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        startline = lineno;
25431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
25441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
25451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int len = strlen30(zLine);
25461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSql = realloc( zSql, nSql + len + 4 );
25471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zSql==0 ){
25481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr,"Error: out of memory\n");
25491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        exit(1);
25501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
25511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSql[nSql++] = '\n';
25521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      memcpy(&zSql[nSql], zLine, len+1);
25531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      nSql += len;
25541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
25551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
25561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                && sqlite3_complete(zSql) ){
25571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      p->cnt = 0;
25581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      open_db(p);
25591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      BEGIN_TIMER;
25601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
25611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      END_TIMER;
25621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( rc || zErrMsg ){
25631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        char zPrefix[100];
25641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( in!=0 || !stdin_is_interactive ){
25651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          sqlite3_snprintf(sizeof(zPrefix), zPrefix,
25661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                           "Error: near line %d:", startline);
25671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else{
25681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
25691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
25701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( zErrMsg!=0 ){
25711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
25721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          sqlite3_free(zErrMsg);
25731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          zErrMsg = 0;
25741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }else{
25751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
25761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
25771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        errCnt++;
25781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
25791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      free(zSql);
25801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zSql = 0;
25811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      nSql = 0;
25821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
25831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
25841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zSql ){
258590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( !_all_whitespace(zSql) ){
258690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
258790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
25881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    free(zSql);
25891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
25901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  free(zLine);
25911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return errCnt;
25921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
25931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
25941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
25951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Return a pathname which is the user's home directory.  A
25961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** 0 return indicates an error of some kind.  Space to hold the
25971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** resulting string is obtained from malloc().  The calling
25981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** function should free the result.
25991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
26001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic char *find_home_dir(void){
26011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *home_dir = NULL;
26021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
26041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct passwd *pwent;
26051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  uid_t uid = getuid();
26061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( (pwent=getpwuid(uid)) != NULL) {
26071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    home_dir = pwent->pw_dir;
26081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
26091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
26101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(_WIN32_WCE)
26121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
26131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori   */
26141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  home_dir = strdup("/");
26151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#else
26161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
26181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if (!home_dir) {
26191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    home_dir = getenv("USERPROFILE");
26201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
26211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
26221c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if (!home_dir) {
26241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    home_dir = getenv("HOME");
26251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
26261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
26281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if (!home_dir) {
26291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *zDrive, *zPath;
26301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int n;
26311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zDrive = getenv("HOMEDRIVE");
26321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zPath = getenv("HOMEPATH");
26331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zDrive && zPath ){
26341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      n = strlen30(zDrive) + strlen30(zPath) + 1;
26351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      home_dir = malloc( n );
26361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( home_dir==0 ) return 0;
26371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
26381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return home_dir;
26391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
26401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    home_dir = "c:\\";
26411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
26421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
26431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif /* !_WIN32_WCE */
26451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( home_dir ){
26471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    int n = strlen30(home_dir) + 1;
26481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *z = malloc( n );
26491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( z ) memcpy(z, home_dir, n);
26501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    home_dir = z;
26511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
26521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return home_dir;
26541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
26551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
26571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Read input from the file given by sqliterc_override.  Or if that
26581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** parameter is NULL, take input from ~/.sqliterc
26591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori**
26601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Returns the number of errors.
26611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
26621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic int process_sqliterc(
26631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct callback_data *p,        /* Configuration data */
26641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *sqliterc_override   /* Name of config file. NULL to use default */
26651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori){
26661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *home_dir = NULL;
26671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *sqliterc = sqliterc_override;
26681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zBuf = 0;
26691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  FILE *in = NULL;
26701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int nBuf;
26711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc = 0;
26721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
26731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if (sqliterc == NULL) {
26741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    home_dir = find_home_dir();
26751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( home_dir==0 ){
26761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if !defined(__RTP__) && !defined(_WRS_KERNEL)
26771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
26781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
26791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
26801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
26811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    nBuf = strlen30(home_dir) + 16;
26821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zBuf = malloc( nBuf );
26831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zBuf==0 ){
26841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"%s: Error: out of memory\n",Argv0);
26851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
26861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
26871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
26881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    free(home_dir);
26891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    sqliterc = (const char*)zBuf;
26901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
26911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  in = fopen(sqliterc,"rb");
26921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( in ){
26931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( stdin_is_interactive ){
26941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
26951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
26961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    rc = process_input(p,in);
26971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fclose(in);
26981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
26991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  free(zBuf);
27001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return rc;
27011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
27021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
27031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
27041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Show available command line options
27051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
27061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic const char zOptions[] =
27071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -bail                stop after hitting an error\n"
27081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -batch               force batch I/O\n"
27091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -column              set output mode to 'column'\n"
2710c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -cmd command         run \"command\" before reading stdin\n"
27111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -csv                 set output mode to 'csv'\n"
2712c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -echo                print commands before execution\n"
2713c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -init filename       read/process named file\n"
2714c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -[no]header          turn headers on or off\n"
2715c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -help                show this message\n"
27161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -html                set output mode to HTML\n"
2717c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -interactive         force interactive I/O\n"
27181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -line                set output mode to 'line'\n"
27191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -list                set output mode to 'list'\n"
2720c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX
2721c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -multiplex           enable the multiplexor VFS\n"
2722c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown#endif
2723c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -nullvalue 'text'    set text string for NULL values\n"
27241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -separator 'x'       set output field separator (|)\n"
2725de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  "   -stats               print memory stats before each finalize\n"
27261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  "   -version             show SQLite version\n"
272790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  "   -vfs NAME            use NAME as the default VFS\n"
272890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE
272990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  "   -vfstrace            enable tracing of all VFS calls\n"
273090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
27311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori;
27321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void usage(int showDetail){
27331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  fprintf(stderr,
27341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      "Usage: %s [OPTIONS] FILENAME [SQL]\n"
27351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      "FILENAME is the name of an SQLite database. A new database is created\n"
27361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      "if the file does not previously exist.\n", Argv0);
27371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( showDetail ){
27381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(stderr, "OPTIONS include:\n%s", zOptions);
27391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else{
27401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(stderr, "Use the -help option for additional information\n");
27411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
27421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  exit(1);
27431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
27441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
27451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori/*
27461c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori** Initialize the state information in data
27471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori*/
27481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noristatic void main_init(struct callback_data *data) {
27491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  memset(data, 0, sizeof(*data));
27501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  data->mode = MODE_List;
27511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  memcpy(data->separator,"|", 2);
27521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  data->showHeader = 0;
275390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  sqlite3_config(SQLITE_CONFIG_URI, 1);
27541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
27551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
27561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
275771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
27581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
27591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
27601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Noriint main(int argc, char **argv){
27611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zErrMsg = 0;
27621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  struct callback_data data;
27631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  const char *zInitFile = 0;
27641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  char *zFirstCmd = 0;
27651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int i;
27661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  int rc = 0;
27671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
276890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
276990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
277090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            sqlite3_sourceid(), SQLITE_SOURCE_ID);
277190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    exit(1);
277290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }
27731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  Argv0 = argv[0];
27741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  main_init(&data);
27751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  stdin_is_interactive = isatty(0);
27761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
27771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* Make sure we have a valid signal handler early, before anything
27781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** else is done.
27791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  */
27801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifdef SIGINT
27811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  signal(SIGINT, interrupt_handler);
27821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
27831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
27841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* Do an initial pass through the command-line argument to locate
27851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** the name of the database file, the name of the initialization file,
278690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  ** the size of the alternative malloc heap,
27871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** and the first command to execute.
27881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  */
27891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(i=1; i<argc-1; i++){
27901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *z;
27911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( argv[i][0]!='-' ) break;
27921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    z = argv[i];
2793c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( z[1]=='-' ) z++;
2794c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( strcmp(z,"-separator")==0
2795c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown     || strcmp(z,"-nullvalue")==0
2796c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown     || strcmp(z,"-cmd")==0
2797c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    ){
27981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      i++;
2799c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-init")==0 ){
28001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      i++;
28011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zInitFile = argv[i];
28021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    /* Need to check for batch mode here to so we can avoid printing
28031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    ** informational messages (like from process_sqliterc) before
28041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    ** we do the actual processing of arguments later in a second pass.
28051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    */
2806c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-batch")==0 ){
28071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      stdin_is_interactive = 0;
2808c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-heap")==0 ){
280990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
281090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      int j, c;
281190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      const char *zSize;
281290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_int64 szHeap;
281390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
281490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      zSize = argv[++i];
281590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      szHeap = atoi(zSize);
281690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      for(j=0; (c = zSize[j])!=0; j++){
281790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( c=='M' ){ szHeap *= 1000000; break; }
281890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( c=='K' ){ szHeap *= 1000; break; }
281990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( c=='G' ){ szHeap *= 1000000000; break; }
282090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
282190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
282290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
282390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
282490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE
2825c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-vfstrace")==0 ){
282690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      extern int vfstrace_register(
282790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         const char *zTraceName,
282890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         const char *zOldVfsName,
282990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         int (*xOut)(const char*,void*),
283090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         void *pOutArg,
283190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         int makeDefault
283290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      );
283390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
283490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
283590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX
2836c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-multiplex")==0 ){
283790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      extern int sqlite3_multiple_initialize(const char*,int);
283890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_multiplex_initialize(0, 1);
283990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
2840c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-vfs")==0 ){
284190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
284290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( pVfs ){
284390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_vfs_register(pVfs, 1);
284490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }else{
284590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
284690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        exit(1);
284790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
28481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
28491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
28501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( i<argc ){
28511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
28521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
28531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#else
28541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.zDbFilename = argv[i++];
28551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
28561c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else{
28571c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifndef SQLITE_OMIT_MEMORYDB
28581c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.zDbFilename = ":memory:";
28591c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#else
28601c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    data.zDbFilename = 0;
28611c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
28621c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
28631c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( i<argc ){
28641c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    zFirstCmd = argv[i++];
28651c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
28661c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( i<argc ){
28671c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
28681c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(stderr,"Use -help for a list of options.\n");
28691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 1;
28701c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
28711c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  data.out = stdout;
28721c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
28731c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#ifdef SQLITE_OMIT_MEMORYDB
28741c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( data.zDbFilename==0 ){
28751c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
28761c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return 1;
28771c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
28781c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
28791c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
28801c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* Go ahead and open the database file if it already exists.  If the
28811c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** file does not exist, delay opening it.  This prevents empty database
28821c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** files from being created if a user mistypes the database name argument
28831c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** to the sqlite command-line tool.
28841c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  */
28851c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( access(data.zDbFilename, 0)==0 ){
28861c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    open_db(&data);
28871c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
28881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
28891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* Process the initialization file if there is one.  If no -init option
28901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** is given on the command line, look for a file named ~/.sqliterc and
28911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** try to process it.
28921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  */
28931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  rc = process_sqliterc(&data,zInitFile);
28941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( rc>0 ){
28951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    return rc;
28961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
28971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
28981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  /* Make a second pass through the command-line argument and set
28991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** options.  This second pass is delayed until after the initialization
29001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** file is processed so that the command-line arguments will override
29011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  ** settings in the initialization file.
29021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  */
29031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  for(i=1; i<argc && argv[i][0]=='-'; i++){
29041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    char *z = argv[i];
29051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( z[1]=='-' ){ z++; }
29061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( strcmp(z,"-init")==0 ){
29071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      i++;
29081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-html")==0 ){
29091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      data.mode = MODE_Html;
29101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-list")==0 ){
29111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      data.mode = MODE_List;
29121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-line")==0 ){
29131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      data.mode = MODE_Line;
29141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-column")==0 ){
29151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      data.mode = MODE_Column;
29161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-csv")==0 ){
29171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      data.mode = MODE_Csv;
29181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      memcpy(data.separator,",",2);
29191c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-separator")==0 ){
29201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      i++;
29211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if(i>=argc){
2922c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        fprintf(stderr,"%s: Error: missing argument for option: %s\n",
2923c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown                        Argv0, z);
29241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr,"Use -help for a list of options.\n");
29251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        return 1;
29261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
29271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_snprintf(sizeof(data.separator), data.separator,
29281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                       "%.*s",(int)sizeof(data.separator)-1,argv[i]);
29291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-nullvalue")==0 ){
29301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      i++;
29311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if(i>=argc){
2932c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        fprintf(stderr,"%s: Error: missing argument for option: %s\n",
2933c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown                        Argv0, z);
29341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr,"Use -help for a list of options.\n");
29351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        return 1;
29361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
29371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
29381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori                       "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
29391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-header")==0 ){
29401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      data.showHeader = 1;
29411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-noheader")==0 ){
29421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      data.showHeader = 0;
29431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-echo")==0 ){
29441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      data.echoOn = 1;
2945de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    }else if( strcmp(z,"-stats")==0 ){
2946de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      data.statsOn = 1;
29471c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-bail")==0 ){
29481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      bail_on_error = 1;
29491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-version")==0 ){
295090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
29511c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 0;
29521c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-interactive")==0 ){
29531c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      stdin_is_interactive = 1;
29541c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else if( strcmp(z,"-batch")==0 ){
29551c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      stdin_is_interactive = 0;
295690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else if( strcmp(z,"-heap")==0 ){
295790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      i++;
295890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else if( strcmp(z,"-vfs")==0 ){
295990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      i++;
296090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE
296190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else if( strcmp(z,"-vfstrace")==0 ){
296290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      i++;
296390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
296490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX
296590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else if( strcmp(z,"-multiplex")==0 ){
296690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      i++;
296790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
2968c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-help")==0 ){
29691c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      usage(1);
2970c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-cmd")==0 ){
2971c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      if( i==argc-1 ) break;
2972c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      i++;
2973c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      z = argv[i];
2974c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      if( z[0]=='.' ){
2975c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        rc = do_meta_command(z, &data);
2976c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( rc && bail_on_error ) return rc;
2977c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      }else{
2978c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        open_db(&data);
2979c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
2980c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( zErrMsg!=0 ){
2981c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          fprintf(stderr,"Error: %s\n", zErrMsg);
2982c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          if( bail_on_error ) return rc!=0 ? rc : 1;
2983c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        }else if( rc!=0 ){
2984c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
2985c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          if( bail_on_error ) return rc;
2986c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        }
2987c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      }
29881c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
29891c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
29901c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      fprintf(stderr,"Use -help for a list of options.\n");
29911c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      return 1;
29921c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
29931c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
29941c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori
29951c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  if( zFirstCmd ){
29961c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    /* Run just the command that follows the database name
29971c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    */
29981c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( zFirstCmd[0]=='.' ){
29991c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = do_meta_command(zFirstCmd, &data);
30001c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
30011c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      open_db(&data);
30021c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
30031c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zErrMsg!=0 ){
30041c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr,"Error: %s\n", zErrMsg);
30051c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        return rc!=0 ? rc : 1;
30061c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }else if( rc!=0 ){
30071c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
30081c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        return rc;
30091c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
30101c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
30111c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }else{
30121c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    /* Run commands received from standard input
30131c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    */
30141c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    if( stdin_is_interactive ){
30151c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      char *zHome;
30161c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      char *zHistory = 0;
30171c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      int nHistory;
30181c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      printf(
301990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        "SQLite version %s %.19s\n" /*extra-version-info*/
30201c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "Enter \".help\" for instructions\n"
30211c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        "Enter SQL statements terminated with a \";\"\n",
302290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_libversion(), sqlite3_sourceid()
30231c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      );
30241c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      zHome = find_home_dir();
30251c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zHome ){
30261c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        nHistory = strlen30(zHome) + 20;
30271c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        if( (zHistory = malloc(nHistory))!=0 ){
30281c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori          sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
30291c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        }
30301c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
30311c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#if defined(HAVE_READLINE) && HAVE_READLINE==1
30321c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zHistory ) read_history(zHistory);
30331c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori#endif
30341c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = process_input(&data, 0);
30351c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      if( zHistory ){
30361c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        stifle_history(100);
30371c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        write_history(zHistory);
30381c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori        free(zHistory);
30391c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      }
30401c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      free(zHome);
30411c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }else{
30421c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori      rc = process_input(&data, stdin);
30431c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori    }
30441c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
30451c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  set_table_name(&data, 0);
304671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  if( data.db ){
304790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_close(data.db);
30481c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  }
30491c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori  return rc;
30501c9f731c5a080b9b26a36b58da954b793ad3cd3bVasu Nori}
3051