17790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
27790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 2001 September 15
37790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
47790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** The author disclaims copyright to this source code.  In place of
57790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** a legal notice, here is a blessing:
67790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
77790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**    May you do good and not evil.
87790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**    May you find forgiveness for yourself and forgive others.
97790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**    May you share freely, never taking more than you give.
107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*************************************************************************
127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This file contains code to implement the "sqlite" command line
137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** utility for accessing SQLite databases.
147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
1590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
16a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* This needs to come before any includes for MSVC compiler */
17a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define _CRT_SECURE_NO_WARNINGS
187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
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
317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <stdlib.h>
327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <string.h>
337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <stdio.h>
347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <assert.h>
357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include "sqlite3.h"
367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <ctype.h>
377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <stdarg.h>
38c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori// Begin Android Add
39c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori#ifndef NO_ANDROID_FUNCS
40c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori#include <sqlite3_android.h>
41c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori#endif
42c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori// End Android Add
43c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori
447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <signal.h>
46a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori# if !defined(__RTP__) && !defined(_WRS_KERNEL)
47a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#  include <pwd.h>
48a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori# endif
497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <unistd.h>
507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <sys/types.h>
517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef __OS2__
547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <unistd.h>
557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
5790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef HAVE_EDITLINE
5890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# include <editline/editline.h>
5990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(HAVE_READLINE) && HAVE_READLINE==1
617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <readline/readline.h>
627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <readline/history.h>
6390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
6490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
65c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown# define readline(p) local_getline(p,stdin,0)
667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# define add_history(X)
677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# define read_history(X)
687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# define write_history(X)
697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# define stifle_history(X)
707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(_WIN32) || defined(WIN32)
737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <io.h>
74a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define isatty(h) _isatty(h)
75a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define access(f,m) _access((f),(m))
767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else
777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* Make sure isatty() has a prototype.
787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
7990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brownextern int isatty(int);
807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(_WIN32_WCE)
837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project * thus we always assume that we have a console. That can be
857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project * overridden with the -batch command line option.
867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */
877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define isatty(x) 1
887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
9090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown/* True if the timer is enabled */
9190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brownstatic int enableTimer = 0;
9290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
9390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown/* ctype macros that work with signed characters */
9490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define IsSpace(X)  isspace((unsigned char)X)
9590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define IsDigit(X)  isdigit((unsigned char)X)
9690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define ToLower(X)  (char)tolower((unsigned char)X)
9790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
98a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <sys/time.h>
1007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <sys/resource.h>
1017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* Saved resource information for the beginning of an operation */
1037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic struct rusage sBegin;
1047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
1067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Begin timing an operation
1077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
1087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void beginTimer(void){
1097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( enableTimer ){
1107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    getrusage(RUSAGE_SELF, &sBegin);
1117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
1127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
1137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
114a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* Return the difference of two time_structs in seconds */
115a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic double timeDiff(struct timeval *pStart, struct timeval *pEnd){
11671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
117a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori         (double)(pEnd->tv_sec - pStart->tv_sec);
1187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
1197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
1217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Print the timing results.
1227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
1237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void endTimer(void){
1247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( enableTimer ){
1257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    struct rusage sEnd;
1267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    getrusage(RUSAGE_SELF, &sEnd);
1277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    printf("CPU Time: user %f sys %f\n",
128a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori       timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
129a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori       timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
1307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
1317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
132a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define BEGIN_TIMER beginTimer()
1347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define END_TIMER endTimer()
1357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define HAS_TIMER 1
136a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
137a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#elif (defined(_WIN32) || defined(WIN32))
138a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
139a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#include <windows.h>
140a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
141a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* Saved resource information for the beginning of an operation */
142a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic HANDLE hProcess;
143a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic FILETIME ftKernelBegin;
144a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic FILETIME ftUserBegin;
145a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noritypedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
146a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic GETPROCTIMES getProcessTimesAddr = NULL;
147a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
148a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
149a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Check to see if we have timer support.  Return 1 if necessary
150a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** support found (or found previously).
151a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
152a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int hasTimer(void){
153a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( getProcessTimesAddr ){
154a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    return 1;
155a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  } else {
156a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
157a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    ** See if the version we are running on has it, and if it does, save off
158a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    ** a pointer to it and the current process handle.
159a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    */
160a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    hProcess = GetCurrentProcess();
161a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( hProcess ){
162a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
163a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( NULL != hinstLib ){
164a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
165a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        if( NULL != getProcessTimesAddr ){
166a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          return 1;
167a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        }
16871504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori        FreeLibrary(hinstLib);
169a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }
170a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
171a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }
172a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  return 0;
173a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
174a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
175a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
176a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Begin timing an operation
177a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
178a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic void beginTimer(void){
179a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( enableTimer && getProcessTimesAddr ){
180a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    FILETIME ftCreation, ftExit;
181a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
182a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }
183a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
184a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
185a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* Return the difference of two FILETIME structs in seconds */
186a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic double timeDiff(FILETIME *pStart, FILETIME *pEnd){
187a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
188a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
189a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  return (double) ((i64End - i64Start) / 10000000.0);
190a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
191a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
192a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
193a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Print the timing results.
194a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
195a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic void endTimer(void){
196a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( enableTimer && getProcessTimesAddr){
197a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
198a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
199a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    printf("CPU Time: user %f sys %f\n",
200a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori       timeDiff(&ftUserBegin, &ftUserEnd),
201a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori       timeDiff(&ftKernelBegin, &ftKernelEnd));
202a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }
203a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
204a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
205a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define BEGIN_TIMER beginTimer()
206a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define END_TIMER endTimer()
207a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define HAS_TIMER hasTimer()
208a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
2097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else
21071504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori#define BEGIN_TIMER
2117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define END_TIMER
2127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define HAS_TIMER 0
2137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
2147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
215a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
216a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Used to prevent warnings about unused parameters
217a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
218a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define UNUSED_PARAMETER(x) (void)(x)
219a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
2207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** If the following flag is set, then command execution stops
2227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** at an error if we are not interactive.
2237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int bail_on_error = 0;
2257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Threat stdin as an interactive input if the following variable
2287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is true.  Otherwise, assume stdin is connected to a file or pipe.
2297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int stdin_is_interactive = 1;
2317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** The following is the open SQLite database.  We make a pointer
2347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** to this database a static variable so that it can be accessed
2357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** by the SIGINT handler to interrupt database processing.
2367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic sqlite3 *db = 0;
2387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** True if an interrupt (Control-C) has been received.
2417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic volatile int seenInterrupt = 0;
2437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This is the name of our program. It is set in main(), used
2467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** in a number of other places, mostly for error messages.
2477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char *Argv0;
2497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Prompt strings. Initialized in main. Settable with
2527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**   .prompt main continue
2537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
2557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
2567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Write I/O traces to the following stream.
2597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_ENABLE_IOTRACE
2617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic FILE *iotrace = 0;
2627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
2637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This routine works like printf in that its first argument is a
2667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** format string and subsequent arguments are values to be substituted
2677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** in place of % fields.  The result of formatting this string
2687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is written to iotrace.
2697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_ENABLE_IOTRACE
2717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void iotracePrintf(const char *zFormat, ...){
2727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  va_list ap;
2737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *z;
2747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( iotrace==0 ) return;
2757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  va_start(ap, zFormat);
2767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  z = sqlite3_vmprintf(zFormat, ap);
2777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  va_end(ap);
2787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  fprintf(iotrace, "%s", z);
2797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  sqlite3_free(z);
2807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
2817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
2827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Determines if a string is a number of not.
2867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int isNumber(const char *z, int *realnum){
2887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( *z=='-' || *z=='+' ) z++;
28990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( !IsDigit(*z) ){
2907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    return 0;
2917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
2927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  z++;
2937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( realnum ) *realnum = 0;
29490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  while( IsDigit(*z) ){ z++; }
2957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( *z=='.' ){
2967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    z++;
29790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( !IsDigit(*z) ) return 0;
29890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    while( IsDigit(*z) ){ z++; }
2997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( realnum ) *realnum = 1;
3007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
3017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( *z=='e' || *z=='E' ){
3027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    z++;
3037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( *z=='+' || *z=='-' ) z++;
30490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( !IsDigit(*z) ) return 0;
30590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    while( IsDigit(*z) ){ z++; }
3067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( realnum ) *realnum = 1;
3077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
3087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return *z==0;
3097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
3107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
3117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
31271504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori** A global char* and an SQL function to access its current value
31371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori** from within an SQL statement. This program used to use the
3147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** sqlite_exec_printf() API to substitue a string into an SQL statement.
3157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** The correct way to do this with sqlite3 is to use the bind API, but
3167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** since the shell is built around the callback paradigm it would be a lot
3177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** of work. Instead just use this hack, which is quite harmless.
3187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
3197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic const char *zShellStatic = 0;
3207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void shellstaticFunc(
3217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  sqlite3_context *context,
3227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int argc,
3237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  sqlite3_value **argv
3247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project){
3257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  assert( 0==argc );
3267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  assert( zShellStatic );
327a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  UNUSED_PARAMETER(argc);
328a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  UNUSED_PARAMETER(argv);
3297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
3307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
3317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
3327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
3337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
3347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This routine reads a line of text from FILE in, stores
3357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the text in memory obtained from malloc() and returns a pointer
3367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** to the text.  NULL is returned at end of file, or if malloc()
3377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** fails.
3387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
3397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** The interface is like "readline" but no command-line editing
3407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is done.
3417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
342c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brownstatic char *local_getline(char *zPrompt, FILE *in, int csvFlag){
3437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zLine;
3447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int nLine;
3457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int n;
346c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  int inQuote = 0;
3477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
3487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( zPrompt && *zPrompt ){
3497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    printf("%s",zPrompt);
3507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fflush(stdout);
3517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
3527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  nLine = 100;
3537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  zLine = malloc( nLine );
3547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( zLine==0 ) return 0;
3557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  n = 0;
35690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  while( 1 ){
3577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( n+100>nLine ){
3587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      nLine = nLine*2 + 100;
3597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zLine = realloc(zLine, nLine);
3607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zLine==0 ) return 0;
3617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
3627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( fgets(&zLine[n], nLine - n, in)==0 ){
3637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( n==0 ){
3647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        free(zLine);
3657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        return 0;
3667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
3677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zLine[n] = 0;
3687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
3697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
370c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    while( zLine[n] ){
371c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      if( zLine[n]=='"' ) inQuote = !inQuote;
372c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      n++;
373c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }
374c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
3757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      n--;
376a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( n>0 && zLine[n-1]=='\r' ) n--;
3777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zLine[n] = 0;
37890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      break;
3797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
3807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
3817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  zLine = realloc( zLine, n+1 );
3827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return zLine;
3837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
3847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
3857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
3867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Retrieve a single line of input text.
3877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
3887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** zPrior is a string of prior text retrieved.  If not the empty
3897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** string, then issue a continuation prompt.
3907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
3917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char *one_input_line(const char *zPrior, FILE *in){
3927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zPrompt;
3937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zResult;
3947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( in!=0 ){
395c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    return local_getline(0, in, 0);
3967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
3977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( zPrior && zPrior[0] ){
3987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zPrompt = continuePrompt;
3997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else{
4007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zPrompt = mainPrompt;
4017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
4027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  zResult = readline(zPrompt);
4037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(HAVE_READLINE) && HAVE_READLINE==1
4047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( zResult && *zResult ) add_history(zResult);
4057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
4067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return zResult;
4077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
4087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
4097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstruct previous_mode_data {
4107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int valid;        /* Is there legit data in here? */
4117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int mode;
4127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int showHeader;
4137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int colWidth[100];
4147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project};
4157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
4167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
4177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** An pointer to an instance of this structure is passed from
4187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the main program to the callback.  This is used to communicate
4197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** state and mode information.
4207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
4217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstruct callback_data {
422a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  sqlite3 *db;           /* The database */
4237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int echoOn;            /* True to echo input commands */
424de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  int statsOn;           /* True to display memory stats before each finalize */
4257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int cnt;               /* Number of records displayed so far */
4267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  FILE *out;             /* Write results here */
42790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  int nErr;              /* Number of errors seen */
4287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int mode;              /* An output mode setting */
4297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int writableSchema;    /* True if PRAGMA writable_schema=ON */
4307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int showHeader;        /* True to show column names in List or Column mode */
4317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zDestTable;      /* Name of destination table when MODE_Insert */
4327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char separator[20];    /* Separator character for MODE_List */
4337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int colWidth[100];     /* Requested width of each column when in column mode*/
4347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int actualWidth[100];  /* Actual width of each column */
4357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char nullvalue[20];    /* The text to print when a NULL comes back from
4367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                         ** the database */
4377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  struct previous_mode_data explainPrev;
4387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                         /* Holds the mode information just before
4397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                         ** .explain ON */
4407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char outfile[FILENAME_MAX]; /* Filename for *out */
4417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  const char *zDbFilename;    /* name of the database file */
44290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  const char *zVfs;           /* Name of VFS to use */
443a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  sqlite3_stmt *pStmt;   /* Current statement if any. */
444aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori  FILE *pLog;            /* Write log output here */
4457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project};
4467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
4477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
4487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** These are the allowed modes.
4497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
4507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Line     0  /* One column per line.  Blank line between records */
4517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Column   1  /* One record per line in neat columns */
4527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_List     2  /* One record per line with a separator */
4537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */
4547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Html     4  /* Generate an XHTML table */
4557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Insert   5  /* Generate SQL "insert" statements */
4567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Tcl      6  /* Generate ANSI-C or TCL quoted elements */
4577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Csv      7  /* Quote strings, numbers are plain */
4587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Explain  8  /* Like MODE_Column, but do not truncate data */
4597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
4607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic const char *modeDescr[] = {
4617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "line",
4627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "column",
4637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "list",
4647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "semi",
4657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "html",
4667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "insert",
4677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "tcl",
4687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "csv",
4697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "explain",
4707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project};
4717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
4727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
4737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Number of elements in an array
4747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
475a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
476a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
477a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
478a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Compute a string length that is limited to what can be stored in
479a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** lower 30 bits of a 32-bit signed integer.
480a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
481a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int strlen30(const char *z){
482a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  const char *z2 = z;
483a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  while( *z2 ){ z2++; }
484a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  return 0x3fffffff & (int)(z2 - z);
485a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
486a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
487a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
488aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori** A callback for the sqlite3_log() interface.
489aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori*/
490aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Noristatic void shellLog(void *pArg, int iErrCode, const char *zMsg){
491aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori  struct callback_data *p = (struct callback_data*)pArg;
492aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori  if( p->pLog==0 ) return;
493aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori  fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
494aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori  fflush(p->pLog);
495aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori}
496aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori
497aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori/*
498a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Output the given string as a hex-encoded blob (eg. X'1234' )
499a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
500a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
501a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int i;
502a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  char *zBlob = (char *)pBlob;
503a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  fprintf(out,"X'");
504a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
505a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  fprintf(out,"'");
506a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
5077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
5087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
5097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Output the given string as a quoted string using SQL quoting conventions.
5107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
5117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void output_quoted_string(FILE *out, const char *z){
5127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int i;
5137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int nSingle = 0;
5147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(i=0; z[i]; i++){
5157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( z[i]=='\'' ) nSingle++;
5167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
5177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( nSingle==0 ){
5187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(out,"'%s'",z);
5197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else{
5207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(out,"'");
5217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    while( *z ){
5227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; z[i] && z[i]!='\''; i++){}
5237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( i==0 ){
5247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(out,"''");
5257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        z++;
5267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else if( z[i]=='\'' ){
5277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(out,"%.*s''",i,z);
5287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        z += i+1;
5297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else{
5307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(out,"%s",z);
5317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        break;
5327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
5337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
5347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(out,"'");
5357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
5367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
5377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
5387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
5397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Output the given string as a quoted according to C or TCL quoting rules.
5407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
5417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void output_c_string(FILE *out, const char *z){
5427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  unsigned int c;
5437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  fputc('"', out);
5447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  while( (c = *(z++))!=0 ){
5457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( c=='\\' ){
5467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc(c, out);
5477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc(c, out);
5487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( c=='\t' ){
5497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc('\\', out);
5507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc('t', out);
5517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( c=='\n' ){
5527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc('\\', out);
5537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc('n', out);
5547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( c=='\r' ){
5557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc('\\', out);
5567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc('r', out);
5577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( !isprint(c) ){
5587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(out, "\\%03o", c&0xff);
5597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
5607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fputc(c, out);
5617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
5627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
5637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  fputc('"', out);
5647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
5657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
5667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
5677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Output the given string with characters that are special to
5687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** HTML escaped.
5697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
5707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void output_html_string(FILE *out, const char *z){
5717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int i;
5727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  while( *z ){
57371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori    for(i=0;   z[i]
57471504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori            && z[i]!='<'
57571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori            && z[i]!='&'
57671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori            && z[i]!='>'
57771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori            && z[i]!='\"'
578a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            && z[i]!='\'';
579a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        i++){}
5807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( i>0 ){
5817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(out,"%.*s",i,z);
5827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
5837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( z[i]=='<' ){
5847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(out,"&lt;");
5857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( z[i]=='&' ){
5867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(out,"&amp;");
587a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( z[i]=='>' ){
588a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(out,"&gt;");
589a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( z[i]=='\"' ){
590a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(out,"&quot;");
591a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( z[i]=='\'' ){
592a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(out,"&#39;");
5937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
5947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
5957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
5967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    z += i + 1;
5977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
5987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
5997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
6007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
6017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** If a field contains any character identified by a 1 in the following
6027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** array, then the string must be quoted for CSV.
6037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
6047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic const char needCsvQuote[] = {
60571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
60671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
60771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 0, 1, 0, 0, 0, 0, 1,   0, 0, 0, 0, 0, 0, 0, 0,
60871504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
60971504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
61071504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
61171504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
61271504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 1,
61371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
61471504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
61571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
61671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
61771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
61871504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
61971504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
62071504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
6217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project};
6227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
6237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
6247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Output a single term of CSV.  Actually, p->separator is used for
6257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the separator, which may or may not be a comma.  p->nullvalue is
626c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** the null value.  Strings are quoted if necessary.
6277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
6287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void output_csv(struct callback_data *p, const char *z, int bSep){
6297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  FILE *out = p->out;
6307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( z==0 ){
6317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(out,"%s",p->nullvalue);
6327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else{
6337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int i;
634a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    int nSep = strlen30(p->separator);
6357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    for(i=0; z[i]; i++){
63671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      if( needCsvQuote[((unsigned char*)z)[i]]
63771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori         || (z[i]==p->separator[0] &&
6387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project             (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
6397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        i = 0;
6407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        break;
6417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
6427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
6437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( i==0 ){
6447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      putc('"', out);
6457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; z[i]; i++){
6467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( z[i]=='"' ) putc('"', out);
6477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        putc(z[i], out);
6487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
6497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      putc('"', out);
6507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
6517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(out, "%s", z);
6527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
6537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
6547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( bSep ){
6557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out, "%s", p->separator);
6567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
6577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
6587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
6597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SIGINT
6607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
6617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This routine runs when the user presses Ctrl-C
6627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
6637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void interrupt_handler(int NotUsed){
664a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  UNUSED_PARAMETER(NotUsed);
6657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  seenInterrupt = 1;
6667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( db ) sqlite3_interrupt(db);
6677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
6687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
6697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
6707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
671a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** This is the callback routine that the shell
6727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** invokes for each row of a query result.
6737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
674a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
6757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int i;
6767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  struct callback_data *p = (struct callback_data*)pArg;
677a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
6787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  switch( p->mode ){
6797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_Line: {
6807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int w = 5;
6817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( azArg==0 ) break;
6827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nArg; i++){
683a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        int len = strlen30(azCol[i] ? azCol[i] : "");
6847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( len>w ) w = len;
6857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
6867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( p->cnt++>0 ) fprintf(p->out,"\n");
6877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nArg; i++){
6887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out,"%*s = %s\n", w, azCol[i],
6897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                azArg[i] ? azArg[i] : p->nullvalue);
6907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
6917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
6927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
6937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_Explain:
6947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_Column: {
6957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( p->cnt++==0 ){
6967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        for(i=0; i<nArg; i++){
6977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          int w, n;
6987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          if( i<ArraySize(p->colWidth) ){
6997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            w = p->colWidth[i];
7007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          }else{
7017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            w = 0;
7027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          }
7037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          if( w<=0 ){
704a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            w = strlen30(azCol[i] ? azCol[i] : "");
7057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            if( w<10 ) w = 10;
706a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
7077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            if( w<n ) w = n;
7087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          }
7097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          if( i<ArraySize(p->actualWidth) ){
7107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            p->actualWidth[i] = w;
7117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          }
7127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          if( p->showHeader ){
7137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");
7147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          }
7157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
7167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( p->showHeader ){
7177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          for(i=0; i<nArg; i++){
7187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            int w;
7197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            if( i<ArraySize(p->actualWidth) ){
7207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project               w = p->actualWidth[i];
7217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            }else{
7227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project               w = 10;
7237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            }
7247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
7257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                   "----------------------------------------------------------",
7267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                    i==nArg-1 ? "\n": "  ");
7277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          }
7287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
7297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
7307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( azArg==0 ) break;
7317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nArg; i++){
7327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        int w;
7337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( i<ArraySize(p->actualWidth) ){
7347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project           w = p->actualWidth[i];
7357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }else{
7367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project           w = 10;
7377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
73871504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori        if( p->mode==MODE_Explain && azArg[i] &&
739a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori           strlen30(azArg[i])>w ){
740a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          w = strlen30(azArg[i]);
7417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
7427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out,"%-*.*s%s",w,w,
7437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
7447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
7457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
7467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
7477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_Semi:
7487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_List: {
7497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( p->cnt++==0 && p->showHeader ){
7507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        for(i=0; i<nArg; i++){
7517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
7527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
7537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
7547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( azArg==0 ) break;
7557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nArg; i++){
7567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        char *z = azArg[i];
7577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( z==0 ) z = p->nullvalue;
7587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out, "%s", z);
7597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( i<nArg-1 ){
7607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          fprintf(p->out, "%s", p->separator);
7617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }else if( p->mode==MODE_Semi ){
7627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          fprintf(p->out, ";\n");
7637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }else{
7647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          fprintf(p->out, "\n");
7657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
7667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
7677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
7687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
7697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_Html: {
7707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( p->cnt++==0 && p->showHeader ){
7717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out,"<TR>");
7727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        for(i=0; i<nArg; i++){
773a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          fprintf(p->out,"<TH>");
774a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          output_html_string(p->out, azCol[i]);
775a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          fprintf(p->out,"</TH>\n");
7767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
7777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out,"</TR>\n");
7787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
7797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( azArg==0 ) break;
7807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out,"<TR>");
7817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nArg; i++){
7827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out,"<TD>");
7837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
7847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out,"</TD>\n");
7857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
7867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out,"</TR>\n");
7877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
7887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
7897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_Tcl: {
7907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( p->cnt++==0 && p->showHeader ){
7917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        for(i=0; i<nArg; i++){
7927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          output_c_string(p->out,azCol[i] ? azCol[i] : "");
7937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          fprintf(p->out, "%s", p->separator);
7947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
7957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out,"\n");
7967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
7977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( azArg==0 ) break;
7987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nArg; i++){
7997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
8007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out, "%s", p->separator);
8017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
8027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out,"\n");
8037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
8047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
8057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_Csv: {
8067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( p->cnt++==0 && p->showHeader ){
8077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        for(i=0; i<nArg; i++){
8087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
8097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
8107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(p->out,"\n");
8117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
8127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( azArg==0 ) break;
8137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nArg; i++){
8147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        output_csv(p, azArg[i], i<nArg-1);
8157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
8167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out,"\n");
8177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
8187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
8197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    case MODE_Insert: {
820a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      p->cnt++;
8217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( azArg==0 ) break;
8227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
8237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nArg; i++){
8247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        char *zSep = i>0 ? ",": "";
825a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
8267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          fprintf(p->out,"%sNULL",zSep);
827a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        }else if( aiType && aiType[i]==SQLITE_TEXT ){
828a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          if( zSep[0] ) fprintf(p->out,"%s",zSep);
829a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          output_quoted_string(p->out, azArg[i]);
830a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
831a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          fprintf(p->out,"%s%s",zSep, azArg[i]);
832a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
833a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          const void *pBlob = sqlite3_column_blob(p->pStmt, i);
834a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          int nBlob = sqlite3_column_bytes(p->pStmt, i);
835a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          if( zSep[0] ) fprintf(p->out,"%s",zSep);
836a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          output_hex_blob(p->out, pBlob, nBlob);
8377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }else if( isNumber(azArg[i], 0) ){
8387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          fprintf(p->out,"%s%s",zSep, azArg[i]);
8397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }else{
8407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          if( zSep[0] ) fprintf(p->out,"%s",zSep);
8417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          output_quoted_string(p->out, azArg[i]);
8427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
8437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
8447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out,");\n");
8457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;
8467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
8477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
8487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return 0;
8497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
8507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
8517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
852a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** This is the callback routine that the SQLite library
853a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** invokes for each row of a query result.
854a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
855a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int callback(void *pArg, int nArg, char **azArg, char **azCol){
856a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  /* since we don't have type info, call the shell_callback with a NULL value */
857a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  return shell_callback(pArg, nArg, azArg, azCol, NULL);
858a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
859a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
860a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
8617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Set the destination table field of the callback_data structure to
8627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the name of the table given.  Escape any quote characters in the
8637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** table name.
8647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
8657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void set_table_name(struct callback_data *p, const char *zName){
8667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int i, n;
8677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int needQuote;
8687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *z;
8697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
8707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( p->zDestTable ){
8717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    free(p->zDestTable);
8727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    p->zDestTable = 0;
8737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
8747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( zName==0 ) return;
8757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
8767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(i=n=0; zName[i]; i++, n++){
8777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
8787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      needQuote = 1;
8797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zName[i]=='\'' ) n++;
8807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
8817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
8827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( needQuote ) n += 2;
8837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  z = p->zDestTable = malloc( n+1 );
8847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( z==0 ){
885a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    fprintf(stderr,"Error: out of memory\n");
8867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    exit(1);
8877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
8887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  n = 0;
8897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( needQuote ) z[n++] = '\'';
8907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(i=0; zName[i]; i++){
8917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    z[n++] = zName[i];
8927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zName[i]=='\'' ) z[n++] = '\'';
8937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
8947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( needQuote ) z[n++] = '\'';
8957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  z[n] = 0;
8967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
8977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
8987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* zIn is either a pointer to a NULL-terminated string in memory obtained
8997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** from malloc(), or a NULL pointer. The string pointed to by zAppend is
9007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** added to zIn, and the result returned in memory obtained from malloc().
9017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** zIn, if it was not NULL, is freed.
9027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
90371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori** If the third argument, quote, is not '\0', then it is used as a
9047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** quote character for zAppend.
9057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
9067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char *appendText(char *zIn, char const *zAppend, char quote){
9077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int len;
9087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int i;
909a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int nAppend = strlen30(zAppend);
910a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int nIn = (zIn?strlen30(zIn):0);
9117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
9127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  len = nAppend+nIn+1;
9137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( quote ){
9147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    len += 2;
9157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    for(i=0; i<nAppend; i++){
9167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zAppend[i]==quote ) len++;
9177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
9187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
9197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
9207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  zIn = (char *)realloc(zIn, len);
9217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( !zIn ){
9227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    return 0;
9237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
9247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
9257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( quote ){
9267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zCsr = &zIn[nIn];
9277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    *zCsr++ = quote;
9287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    for(i=0; i<nAppend; i++){
9297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      *zCsr++ = zAppend[i];
9307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zAppend[i]==quote ) *zCsr++ = quote;
9317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
9327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    *zCsr++ = quote;
9337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    *zCsr++ = '\0';
9347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    assert( (zCsr-zIn)==len );
9357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else{
9367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    memcpy(&zIn[nIn], zAppend, nAppend);
9377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zIn[len-1] = '\0';
9387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
9397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
9407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return zIn;
9417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
9427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
9437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
9447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
945c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** Execute a query statement that will generate SQL output.  Print
946c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** the result columns, comma-separated, on a line and then add a
947c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** semicolon terminator to the end of that line.
9487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
949c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** If the number of columns is 1 and that column contains text "--"
950c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** then write the semicolon on a separate line.  That way, if a
951c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** "--" comment occurs at the end of the statement, the comment
952c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** won't consume the semicolon terminator.
9537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
954a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int run_table_dump_query(
95590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  struct callback_data *p, /* Query context */
95690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  const char *zSelect,     /* SELECT statement to extract content */
95790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  const char *zFirstRow    /* Print before first row, if not NULL */
958a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori){
9597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  sqlite3_stmt *pSelect;
9607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int rc;
961c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  int nResult;
962c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  int i;
963c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  const char *z;
96490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
9657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( rc!=SQLITE_OK || !pSelect ){
96690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
96790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    p->nErr++;
9687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    return rc;
9697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
9707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  rc = sqlite3_step(pSelect);
971c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  nResult = sqlite3_column_count(pSelect);
9727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  while( rc==SQLITE_ROW ){
973a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( zFirstRow ){
97490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(p->out, "%s", zFirstRow);
975a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zFirstRow = 0;
976a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
977c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    z = (const char*)sqlite3_column_text(pSelect, 0);
978c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    fprintf(p->out, "%s", z);
979c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    for(i=1; i<nResult; i++){
980c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
981c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }
982c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( z==0 ) z = "";
983c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
984c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( z[0] ){
985c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      fprintf(p->out, "\n;\n");
986c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else{
987c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      fprintf(p->out, ";\n");
988c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }
9897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = sqlite3_step(pSelect);
9907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
99190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  rc = sqlite3_finalize(pSelect);
99290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( rc!=SQLITE_OK ){
99390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
99490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    p->nErr++;
99590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }
99690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  return rc;
9977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
9987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
999a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
1000a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Allocate space and save off current error string.
1001a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
1002a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic char *save_err_msg(
1003a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  sqlite3 *db            /* Database to query */
1004a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori){
1005a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1006a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  char *zErrMsg = sqlite3_malloc(nErrMsg);
1007a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( zErrMsg ){
1008a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1009a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }
1010a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  return zErrMsg;
1011a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
1012a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1013a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
1014de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori** Display memory stats.
1015de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori*/
1016de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Noristatic int display_stats(
1017de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  sqlite3 *db,                /* Database to query */
1018de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  struct callback_data *pArg, /* Pointer to struct callback_data */
1019de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  int bReset                  /* True to reset the stats */
1020de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori){
1021de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  int iCur;
1022de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  int iHiwtr;
1023de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1024de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  if( pArg && pArg->out ){
1025de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1026de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1027de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
1028de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Memory Used:                         %d (max %d) bytes\n", iCur, iHiwtr);
1029de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1030de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
103190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Number of Outstanding Allocations:   %d (max %d)\n", iCur, iHiwtr);
1032de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori/*
1033de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori** Not currently used by the CLI.
1034de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    iHiwtr = iCur = -1;
1035de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1036de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    fprintf(pArg->out, "Number of Pcache Pages Used:         %d (max %d) pages\n", iCur, iHiwtr);
1037de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori*/
1038de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1039de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1040de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Number of Pcache Overflow Bytes:     %d (max %d) bytes\n", iCur, iHiwtr);
1041de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori/*
1042de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori** Not currently used by the CLI.
1043de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    iHiwtr = iCur = -1;
1044de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1045de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori**    fprintf(pArg->out, "Number of Scratch Allocations Used:  %d (max %d)\n", iCur, iHiwtr);
1046de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori*/
1047de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1048de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1049de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Number of Scratch Overflow Bytes:    %d (max %d) bytes\n", iCur, iHiwtr);
1050de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1051de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1052de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Largest Allocation:                  %d bytes\n", iHiwtr);
1053de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1054de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1055de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Largest Pcache Allocation:           %d bytes\n", iHiwtr);
1056de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1057de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1058de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Largest Scratch Allocation:          %d bytes\n", iHiwtr);
1059de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori#ifdef YYTRACKMAXSTACKDEPTH
1060de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1061de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1062de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Deepest Parser Stack:                %d (max %d)\n", iCur, iHiwtr);
1063de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori#endif
1064de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  }
1065de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1066de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  if( pArg && pArg->out && db ){
1067de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1068de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1069de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Lookaside Slots Used:                %d (max %d)\n", iCur, iHiwtr);
107090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
107190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Successful lookaside attempts:       %d\n", iHiwtr);
107290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
107390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Lookaside failures due to size:      %d\n", iHiwtr);
107490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
107590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Lookaside failures due to OOM:       %d\n", iHiwtr);
1076de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1077de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
107890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Pager Heap Usage:                    %d bytes\n", iCur);    iHiwtr = iCur = -1;
107990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
108090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Page cache hits:                     %d\n", iCur);
108190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    iHiwtr = iCur = -1;
108290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
108390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(pArg->out, "Page cache misses:                   %d\n", iCur);
1084de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1085de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1086de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n", iCur);
1087de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iHiwtr = iCur = -1;
1088de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1089de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n", iCur);
1090de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  }
1091de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1092de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  if( pArg && pArg->out && db && pArg->pStmt ){
1093de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1094de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
1095de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1096de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Sort Operations:                     %d\n", iCur);
1097de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1098de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
1099de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  }
1100de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1101de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  return 0;
1102de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori}
1103de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1104de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori/*
110571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori** Execute a statement or set of statements.  Print
110671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori** any result rows/columns depending on the current mode
1107a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** set via the supplied callback.
1108a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori**
110971504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori** This is very similar to SQLite's built-in sqlite3_exec()
111071504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori** function except it takes a slightly different callback
1111a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** and callback data argument.
1112a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
1113a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int shell_exec(
1114a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  sqlite3 *db,                                /* An open database */
1115a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  const char *zSql,                           /* SQL to be evaluated */
1116a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int (*xCallback)(void*,int,char**,char**,int*),   /* Callback function */
1117a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                                              /* (not the same as sqlite3_exec) */
1118a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  struct callback_data *pArg,                 /* Pointer to struct callback_data */
1119a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  char **pzErrMsg                             /* Error msg written here */
1120a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori){
1121a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  sqlite3_stmt *pStmt = NULL;     /* Statement to execute. */
1122a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int rc = SQLITE_OK;             /* Return Code */
112390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  int rc2;
1124a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  const char *zLeftover;          /* Tail of unprocessed SQL */
1125a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1126a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( pzErrMsg ){
1127a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    *pzErrMsg = NULL;
1128a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }
1129a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1130a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  while( zSql[0] && (SQLITE_OK == rc) ){
1131a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1132a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( SQLITE_OK != rc ){
1133a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( pzErrMsg ){
1134a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        *pzErrMsg = save_err_msg(db);
1135a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }
1136a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else{
1137a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( !pStmt ){
1138a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        /* this happens for a comment or white-space */
1139a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        zSql = zLeftover;
114090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        while( IsSpace(zSql[0]) ) zSql++;
1141a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        continue;
1142a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }
1143a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1144de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      /* save off the prepared statment handle and reset row count */
1145de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      if( pArg ){
1146de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        pArg->pStmt = pStmt;
1147de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        pArg->cnt = 0;
1148de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      }
1149de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
115071504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      /* echo the sql statement if echo on */
1151de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      if( pArg && pArg->echoOn ){
115271504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori        const char *zStmtSql = sqlite3_sql(pStmt);
1153de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
115471504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      }
115571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori
115690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      /* Output TESTCTRL_EXPLAIN text of requested */
115790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( pArg && pArg->mode==MODE_Explain ){
115890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        const char *zExplain = 0;
115990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
116090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( zExplain && zExplain[0] ){
116190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          fprintf(pArg->out, "%s", zExplain);
116290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        }
116390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
116490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
1165a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      /* perform the first step.  this will tell us if we
1166a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      ** have a result set or not and how wide it is.
1167a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      */
1168a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = sqlite3_step(pStmt);
1169a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      /* if we have a result set... */
1170a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( SQLITE_ROW == rc ){
1171a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        /* if we have a callback... */
1172a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        if( xCallback ){
1173a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          /* allocate space for col name ptr, value ptr, and type */
1174a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          int nCol = sqlite3_column_count(pStmt);
1175a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1176a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          if( !pData ){
1177a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            rc = SQLITE_NOMEM;
1178a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          }else{
1179a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            char **azCols = (char **)pData;      /* Names of result columns */
1180a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            char **azVals = &azCols[nCol];       /* Results */
1181a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1182a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            int i;
118371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori            assert(sizeof(int) <= sizeof(char *));
1184a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            /* save off ptrs to column names */
1185a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            for(i=0; i<nCol; i++){
1186a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori              azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1187a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            }
1188a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            do{
1189a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori              /* extract the data and data types */
1190a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori              for(i=0; i<nCol; i++){
1191a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1192a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                aiTypes[i] = sqlite3_column_type(pStmt, i);
1193a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1194a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                  rc = SQLITE_NOMEM;
1195a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                  break; /* from for */
1196a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                }
1197a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori              } /* end for */
1198a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1199a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori              /* if data and types extracted successfully... */
120071504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori              if( SQLITE_ROW == rc ){
1201a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                /* call the supplied callback with the result row data */
1202a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1203a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                  rc = SQLITE_ABORT;
1204a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                }else{
1205a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                  rc = sqlite3_step(pStmt);
1206a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                }
1207a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori              }
1208a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            } while( SQLITE_ROW == rc );
1209a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            sqlite3_free(pData);
1210a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          }
1211a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        }else{
1212a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          do{
1213a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            rc = sqlite3_step(pStmt);
1214a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          } while( rc == SQLITE_ROW );
1215a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        }
1216a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }
1217a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1218de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      /* print usage stats if stats on */
1219de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      if( pArg && pArg->statsOn ){
1220de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        display_stats(db, pArg, 0);
1221de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      }
1222de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
122371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      /* Finalize the statement just executed. If this fails, save a
1224a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      ** copy of the error message. Otherwise, set zSql to point to the
1225a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      ** next statement to execute. */
122690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      rc2 = sqlite3_finalize(pStmt);
122790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( rc!=SQLITE_NOMEM ) rc = rc2;
1228a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( rc==SQLITE_OK ){
1229a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        zSql = zLeftover;
123090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        while( IsSpace(zSql[0]) ) zSql++;
1231a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }else if( pzErrMsg ){
1232a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        *pzErrMsg = save_err_msg(db);
1233a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }
1234de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
1235de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      /* clear saved stmt handle */
1236de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      if( pArg ){
1237de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori        pArg->pStmt = NULL;
1238de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      }
1239a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
1240a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  } /* end while */
1241a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1242a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  return rc;
1243a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
1244a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
12457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
12467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
12477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This is a different callback routine used for dumping the database.
12487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Each row received by this callback consists of a table name,
12497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the table type ("index" or "table") and SQL to create the table.
12507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This routine should print text sufficient to recreate the table.
12517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
12527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
12537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int rc;
12547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  const char *zTable;
12557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  const char *zType;
12567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  const char *zSql;
1257a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  const char *zPrepStmt = 0;
12587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  struct callback_data *p = (struct callback_data *)pArg;
12597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1260a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  UNUSED_PARAMETER(azCol);
12617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( nArg!=3 ) return 1;
12627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  zTable = azArg[0];
12637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  zType = azArg[1];
12647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  zSql = azArg[2];
126571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori
12667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( strcmp(zTable, "sqlite_sequence")==0 ){
1267a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    zPrepStmt = "DELETE FROM sqlite_sequence;\n";
12687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else if( strcmp(zTable, "sqlite_stat1")==0 ){
12697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out, "ANALYZE sqlite_master;\n");
12707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else if( strncmp(zTable, "sqlite_", 7)==0 ){
12717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    return 0;
12727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
12737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zIns;
12747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( !p->writableSchema ){
12757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out, "PRAGMA writable_schema=ON;\n");
12767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->writableSchema = 1;
12777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
12787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zIns = sqlite3_mprintf(
12797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project       "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
12807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project       "VALUES('table','%q','%q',0,'%q');",
12817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project       zTable, zTable, zSql);
12827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out, "%s\n", zIns);
12837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_free(zIns);
12847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    return 0;
12857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else{
12867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out, "%s;\n", zSql);
12877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
12887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
12897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( strcmp(zType, "table")==0 ){
12907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_stmt *pTableInfo = 0;
12917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zSelect = 0;
12927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zTableInfo = 0;
12937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zTmp = 0;
1294a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    int nRow = 0;
1295c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    int kk;
129671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori
12977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
12987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zTableInfo = appendText(zTableInfo, zTable, '"');
12997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zTableInfo = appendText(zTableInfo, ");", 0);
13007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
13017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
1302a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    free(zTableInfo);
13037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( rc!=SQLITE_OK || !pTableInfo ){
13047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      return 1;
13057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
13067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
13077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1308c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( !isalpha(zTable[0]) ){
1309c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      kk = 0;
1310c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else{
1311c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      for(kk=1; isalnum(zTable[kk]); kk++){}
1312c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }
1313c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    zTmp = appendText(zTmp, zTable, zTable[kk] ? '"' : 0);
13147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zTmp ){
13157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zSelect = appendText(zSelect, zTmp, '\'');
13167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
13177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
13187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = sqlite3_step(pTableInfo);
13197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    while( rc==SQLITE_ROW ){
13207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
13217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zSelect = appendText(zSelect, "quote(", 0);
13227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zSelect = appendText(zSelect, zText, '"');
13237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      rc = sqlite3_step(pTableInfo);
13247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( rc==SQLITE_ROW ){
1325c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        zSelect = appendText(zSelect, "), ", 0);
13267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else{
13277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        zSelect = appendText(zSelect, ") ", 0);
13287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
1329a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      nRow++;
13307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
13317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = sqlite3_finalize(pTableInfo);
1332a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( rc!=SQLITE_OK || nRow==0 ){
1333a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      free(zSelect);
13347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      return 1;
13357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
13367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zSelect = appendText(zSelect, "|| ')' FROM  ", 0);
13377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zSelect = appendText(zSelect, zTable, '"');
13387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
133990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    rc = run_table_dump_query(p, zSelect, zPrepStmt);
13407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( rc==SQLITE_CORRUPT ){
13417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
134290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      run_table_dump_query(p, zSelect, 0);
13437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
13447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zSelect ) free(zSelect);
13457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
13467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return 0;
13477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
13487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
13497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
13507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Run zQuery.  Use dump_callback() as the callback routine so that
13517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the contents of the query are output as SQL statements.
13527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
13537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** If we get a SQLITE_CORRUPT error, rerun the query after appending
13547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** "ORDER BY rowid DESC" to the end.
13557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
13567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int run_schema_dump_query(
135771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  struct callback_data *p,
135890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  const char *zQuery
13597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project){
13607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int rc;
136190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  char *zErr = 0;
136290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
13637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( rc==SQLITE_CORRUPT ){
13647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zQ2;
1365a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    int len = strlen30(zQuery);
136690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
136790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( zErr ){
136890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(p->out, "/****** %s ******/\n", zErr);
136990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_free(zErr);
137090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      zErr = 0;
137190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
13727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zQ2 = malloc( len+100 );
13737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zQ2==0 ) return rc;
13747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
137590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
137690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( rc ){
137790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
137890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else{
137990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      rc = SQLITE_CORRUPT;
138090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
138190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_free(zErr);
13827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    free(zQ2);
13837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
13847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return rc;
13857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
13867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
13877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
13887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Text of a help message
13897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
13907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char zHelp[] =
1391a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
13927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".bail ON|OFF           Stop after hitting an error.  Default OFF\n"
13937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".databases             List names and files of attached databases\n"
13947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
1395a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         If TABLE specified, only dump tables matching\n"
1396a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         LIKE pattern TABLE.\n"
13977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".echo ON|OFF           Turn command echo on or off\n"
13987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".exit                  Exit this program\n"
1399a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  ".explain ?ON|OFF?      Turn output mode suitable for EXPLAIN on or off.\n"
1400a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         With no args, it turns EXPLAIN on.\n"
14017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".header(s) ON|OFF      Turn display of headers on or off\n"
14027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".help                  Show this message\n"
14037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".import FILE TABLE     Import data from FILE into TABLE\n"
1404a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  ".indices ?TABLE?       Show names of all indices\n"
1405a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         If TABLE specified, only show indices for tables\n"
1406a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         matching LIKE pattern TABLE.\n"
14077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_ENABLE_IOTRACE
14087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".iotrace FILE          Enable I/O diagnostic logging to FILE\n"
14097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
14107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifndef SQLITE_OMIT_LOAD_EXTENSION
14117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".load FILE ?ENTRY?     Load an extension library\n"
14127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
1413aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori  ".log FILE|off          Turn logging on or off.  FILE can be stderr/stdout\n"
14147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
14157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "                         csv      Comma-separated values\n"
14167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "                         column   Left-aligned columns.  (See .width)\n"
14177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "                         html     HTML <table> code\n"
14187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "                         insert   SQL insert statements for TABLE\n"
14197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "                         line     One value per line\n"
14207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "                         list     Values delimited by .separator string\n"
14217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "                         tabs     Tab-separated values\n"
14227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "                         tcl      TCL list elements\n"
14237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".nullvalue STRING      Print STRING in place of NULL values\n"
14247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".output FILENAME       Send output to FILENAME\n"
14257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".output stdout         Send output to the screen\n"
14267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
14277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".quit                  Exit this program\n"
14287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".read FILENAME         Execute SQL in FILENAME\n"
1429a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
14307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".schema ?TABLE?        Show the CREATE statements\n"
1431a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         If TABLE specified, only show tables matching\n"
1432a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         LIKE pattern TABLE.\n"
14337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".separator STRING      Change separator used by output mode and .import\n"
14347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".show                  Show the current values for various settings\n"
1435de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  ".stats ON|OFF          Turn stats on or off\n"
1436a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  ".tables ?TABLE?        List names of tables\n"
1437a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         If TABLE specified, only list tables matching\n"
1438a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  "                         LIKE pattern TABLE.\n"
14397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".timeout MS            Try opening locked tables for MS milliseconds\n"
144090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  ".vfsname ?AUX?         Print the name of the VFS stack\n"
1441a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
1442a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori;
1443a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1444a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic char zTimerHelp[] =
14457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ".timer ON|OFF          Turn the CPU timer measurement on or off\n"
14467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project;
14477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
14487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* Forward reference */
14497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int process_input(struct callback_data *p, FILE *in);
14507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
14517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
14527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Make sure the database is open.  If it is not, then open it.  If
14537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the database fails to open, print an error message and exit.
14547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
14557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void open_db(struct callback_data *p){
14567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( p->db==0 ){
14577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_open(p->zDbFilename, &p->db);
14587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    db = p->db;
14597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( db && sqlite3_errcode(db)==SQLITE_OK ){
14607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
14617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          shellstaticFunc, 0, 0);
14627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
14637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
146471504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
14657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          p->zDbFilename, sqlite3_errmsg(db));
14667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      exit(1);
14677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
14687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifndef SQLITE_OMIT_LOAD_EXTENSION
14697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_enable_load_extension(p->db, 1);
14707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
1471c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori    // Begin Android Add
1472c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori    #ifndef NO_ANDROID_FUNCS
1473c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori        int err = register_localized_collators(db, "en_US", 0);
1474c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori        if (err != SQLITE_OK) {
1475c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori          fprintf(stderr, "register_localized_collators() failed\n");
1476c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori          exit(1);
1477c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori        }
1478c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori        err = register_android_functions(db, 0);
1479c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori        if (err != SQLITE_OK) {
1480c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori          fprintf(stderr, "register_android_functions() failed\n");
1481c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori          exit(1);
1482c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori        }
1483c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori    #endif
1484c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori    // End Android Add
14857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
14867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
14877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
14887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
14897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Do C-language style dequoting.
14907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
14917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**    \t    -> tab
14927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**    \n    -> newline
14937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**    \r    -> carriage return
14947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**    \NNN  -> ascii character NNN in octal
14957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**    \\    -> backslash
14967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
14977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void resolve_backslashes(char *z){
1498a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int i, j;
1499a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  char c;
15007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(i=j=0; (c = z[i])!=0; i++, j++){
15017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( c=='\\' ){
15027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      c = z[++i];
15037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( c=='n' ){
15047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        c = '\n';
15057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else if( c=='t' ){
15067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        c = '\t';
15077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else if( c=='r' ){
15087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        c = '\r';
15097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else if( c>='0' && c<='7' ){
15107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        c -= '0';
15117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( z[i+1]>='0' && z[i+1]<='7' ){
15127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          i++;
15137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          c = (c<<3) + z[i] - '0';
15147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          if( z[i+1]>='0' && z[i+1]<='7' ){
15157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            i++;
15167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            c = (c<<3) + z[i] - '0';
15177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          }
15187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
15197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
15207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
15217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    z[j] = c;
15227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
15237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  z[j] = 0;
15247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
15257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
15267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
15277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Interpret zArg as a boolean value.  Return either 0 or 1.
15287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
15297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int booleanValue(char *zArg){
15307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int val = atoi(zArg);
15317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int j;
15327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(j=0; zArg[j]; j++){
153390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    zArg[j] = ToLower(zArg[j]);
15347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
15357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( strcmp(zArg,"on")==0 ){
15367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    val = 1;
15377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else if( strcmp(zArg,"yes")==0 ){
15387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    val = 1;
15397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
15407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return val;
15417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
15427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
15437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
15447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** If an input line begins with "." then invoke this routine to
15457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** process that line.
15467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
15477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return 1 on error, 2 to exit, and 0 otherwise.
15487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
15497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int do_meta_command(char *zLine, struct callback_data *p){
15507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int i = 1;
15517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int nArg = 0;
15527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int n, c;
15537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int rc = 0;
15547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *azArg[50];
15557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
15567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  /* Parse the input line into tokens.
15577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  */
15587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  while( zLine[i] && nArg<ArraySize(azArg) ){
155990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    while( IsSpace(zLine[i]) ){ i++; }
15607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zLine[i]==0 ) break;
15617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zLine[i]=='\'' || zLine[i]=='"' ){
15627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int delim = zLine[i++];
15637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      azArg[nArg++] = &zLine[i];
15647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      while( zLine[i] && zLine[i]!=delim ){ i++; }
15657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zLine[i]==delim ){
15667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        zLine[i++] = 0;
15677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
15687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
15697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
15707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      azArg[nArg++] = &zLine[i];
157190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
15727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zLine[i] ) zLine[i++] = 0;
15737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      resolve_backslashes(azArg[nArg-1]);
15747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
15757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
15767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
15777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  /* Process the input line.
15787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  */
1579a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( nArg==0 ) return 0; /* no tokens, no error */
1580a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  n = strlen30(azArg[0]);
15817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  c = azArg[0][0];
1582a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
1583a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    const char *zDestFile;
1584a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    const char *zDb;
1585a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3 *pDest;
1586a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3_backup *pBackup;
1587a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( nArg==2 ){
1588a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zDestFile = azArg[1];
1589a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zDb = "main";
1590a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else{
1591a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zDestFile = azArg[2];
1592a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zDb = azArg[1];
1593a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
1594a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    rc = sqlite3_open(zDestFile, &pDest);
1595a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( rc!=SQLITE_OK ){
1596a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
1597a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      sqlite3_close(pDest);
1598a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
1599a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
1600a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    open_db(p);
1601a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1602a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( pBackup==0 ){
1603a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1604a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      sqlite3_close(pDest);
1605a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
1606a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
1607a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1608a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3_backup_finish(pBackup);
1609a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( rc==SQLITE_DONE ){
1610a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 0;
1611a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else{
1612a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1613a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
1614a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
1615a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3_close(pDest);
1616a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }else
1617a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
1618a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
16197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    bail_on_error = booleanValue(azArg[1]);
16207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
16217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1622a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
16237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    struct callback_data data;
16247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zErrMsg = 0;
16257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(p);
16267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    memcpy(&data, p, sizeof(data));
16277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.showHeader = 1;
16287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.mode = MODE_Column;
16297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.colWidth[0] = 3;
16307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.colWidth[1] = 15;
16317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.colWidth[2] = 58;
16327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.cnt = 0;
16337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
16347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zErrMsg ){
16357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(stderr,"Error: %s\n", zErrMsg);
16367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_free(zErrMsg);
1637a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
16387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
16397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
16407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1641a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
16427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(p);
1643a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    /* When playing back a "dump", the content might appear in an order
1644a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    ** which causes immediate foreign key constraints to be violated.
1645a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    ** So disable foreign-key constraint enforcement to prevent problems. */
1646a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
16477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out, "BEGIN TRANSACTION;\n");
16487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    p->writableSchema = 0;
164990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
165090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    p->nErr = 0;
16517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( nArg==1 ){
165271504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      run_schema_dump_query(p,
16537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "SELECT name, type, sql FROM sqlite_master "
165490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
1655a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      );
165671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      run_schema_dump_query(p,
1657a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "SELECT name, type, sql FROM sqlite_master "
165890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        "WHERE name=='sqlite_sequence'"
16597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      );
166090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      run_table_dump_query(p,
16617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "SELECT sql FROM sqlite_master "
1662a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
16637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      );
16647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
16657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int i;
16667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=1; i<nArg; i++){
16677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        zShellStatic = azArg[i];
16687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        run_schema_dump_query(p,
16697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          "SELECT name, type, sql FROM sqlite_master "
16707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          "WHERE tbl_name LIKE shellstatic() AND type=='table'"
167190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          "  AND sql NOT NULL");
167290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        run_table_dump_query(p,
16737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          "SELECT sql FROM sqlite_master "
16747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          "WHERE sql NOT NULL"
16757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          "  AND type IN ('index','trigger','view')"
1676a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          "  AND tbl_name LIKE shellstatic()", 0
16777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        );
16787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        zShellStatic = 0;
16797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
16807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
16817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( p->writableSchema ){
16827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
16837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->writableSchema = 0;
16847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
168590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
168690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
168790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
16887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
16897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1690a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
16917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    p->echoOn = booleanValue(azArg[1]);
16927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
16937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1694a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='e' && strncmp(azArg[0], "exit", n)==0  && nArg==1 ){
16957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = 2;
16967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
16977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1698a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
16997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
17007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if(val == 1) {
17017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if(!p->explainPrev.valid) {
17027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        p->explainPrev.valid = 1;
17037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        p->explainPrev.mode = p->mode;
17047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        p->explainPrev.showHeader = p->showHeader;
17057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
17067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
17077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      /* We could put this code under the !p->explainValid
17087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      ** condition so that it does not execute if we are already in
17097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      ** explain mode. However, always executing it allows us an easy
17107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      ** was to reset to explain mode in case the user previously
17117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      ** did an .explain followed by a .width, .mode or .header
17127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      ** command.
17137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      */
17147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_Explain;
17157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->showHeader = 1;
17167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      memset(p->colWidth,0,ArraySize(p->colWidth));
17177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[0] = 4;                  /* addr */
17187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[1] = 13;                 /* opcode */
17197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[2] = 4;                  /* P1 */
17207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[3] = 4;                  /* P2 */
17217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[4] = 4;                  /* P3 */
17227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[5] = 13;                 /* P4 */
17237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[6] = 2;                  /* P5 */
17247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[7] = 13;                  /* Comment */
17257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if (p->explainPrev.valid) {
17267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->explainPrev.valid = 0;
17277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = p->explainPrev.mode;
17287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->showHeader = p->explainPrev.showHeader;
17297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
17307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
17317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
17327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
17337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
1734a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
17357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    p->showHeader = booleanValue(azArg[1]);
17367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
17377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
17387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1739a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    fprintf(stderr,"%s",zHelp);
1740a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( HAS_TIMER ){
1741a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"%s",zTimerHelp);
1742a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
17437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
17447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1745a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
17467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zTable = azArg[2];    /* Insert data into this table */
17477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zFile = azArg[1];     /* The file from which to extract data */
1748a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3_stmt *pStmt = NULL; /* A statement */
17497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int nCol;                   /* Number of columns in the table */
17507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int nByte;                  /* Number of bytes in an SQL string */
17517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int i, j;                   /* Loop counters */
17527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int nSep;                   /* Number of bytes in p->separator[] */
17537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zSql;                 /* An SQL statement */
17547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zLine;                /* A single line of input from the file */
17557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char **azCol;               /* zLine[] broken up into columns */
175671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori    char *zCommit;              /* How to commit changes */
17577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    FILE *in;                   /* The input file */
17587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int lineno = 0;             /* Line number of input file */
17597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
17607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(p);
1761a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    nSep = strlen30(p->separator);
17627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( nSep==0 ){
1763a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: non-null separator required for import\n");
1764a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
17657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
176690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
1767a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( zSql==0 ){
1768a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: out of memory\n");
1769a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
1770a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
1771a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    nByte = strlen30(zSql);
17727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
17737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_free(zSql);
17747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( rc ){
1775a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if (pStmt) sqlite3_finalize(pStmt);
17767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1777a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
17787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
1779a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    nCol = sqlite3_column_count(pStmt);
17807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_finalize(pStmt);
1781a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    pStmt = 0;
1782a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( nCol==0 ) return 0; /* no columns, no error */
17837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zSql = malloc( nByte + 20 + nCol*2 );
1784a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( zSql==0 ){
1785a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: out of memory\n");
1786a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
1787a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
178890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
1789a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    j = strlen30(zSql);
17907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    for(i=1; i<nCol; i++){
17917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zSql[j++] = ',';
17927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zSql[j++] = '?';
17937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
17947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zSql[j++] = ')';
17957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zSql[j] = 0;
17967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
17977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    free(zSql);
17987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( rc ){
17997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1800a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if (pStmt) sqlite3_finalize(pStmt);
18017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      return 1;
18027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
18037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    in = fopen(zFile, "rb");
18047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( in==0 ){
1805a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
18067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_finalize(pStmt);
1807a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
18087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
18097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
18107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( azCol==0 ){
1811a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: out of memory\n");
18127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fclose(in);
1813a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      sqlite3_finalize(pStmt);
1814a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
18157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
18167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
18177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zCommit = "COMMIT";
1818c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    while( (zLine = local_getline(0, in, 1))!=0 ){
1819c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      char *z, c;
1820c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      int inQuote = 0;
18217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      lineno++;
18227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      azCol[0] = zLine;
1823c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      for(i=0, z=zLine; (c = *z)!=0; z++){
1824c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( c=='"' ) inQuote = !inQuote;
1825c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( c=='\n' ) lineno++;
1826c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
18277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          *z = 0;
18287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          i++;
18297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          if( i<nCol ){
18307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            azCol[i] = &z[nSep];
18317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project            z += nSep-1;
18327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          }
18337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
1834a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      } /* end for */
18357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      *z = 0;
18367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( i+1!=nCol ){
1837a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        fprintf(stderr,
1838a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                "Error: %s line %d: expected %d columns of data but found %d\n",
1839a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                zFile, lineno, nCol, i+1);
18407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        zCommit = "ROLLBACK";
1841a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        free(zLine);
1842a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        rc = 1;
1843a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        break; /* from while */
18447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
18457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nCol; i++){
1846c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( azCol[i][0]=='"' ){
1847c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          int k;
1848c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          for(z=azCol[i], j=1, k=0; z[j]; j++){
1849c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown            if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1850c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown            z[k++] = z[j];
1851c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          }
1852c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          z[k] = 0;
1853c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        }
18547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
18557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
18567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_step(pStmt);
18577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      rc = sqlite3_reset(pStmt);
18587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      free(zLine);
18597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( rc!=SQLITE_OK ){
18607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
18617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        zCommit = "ROLLBACK";
18627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        rc = 1;
1863a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        break; /* from while */
18647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
1865a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    } /* end while */
18667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    free(azCol);
18677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fclose(in);
18687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_finalize(pStmt);
18697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_exec(p->db, zCommit, 0, 0, 0);
18707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
18717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
1872a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
18737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    struct callback_data data;
18747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zErrMsg = 0;
18757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(p);
18767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    memcpy(&data, p, sizeof(data));
18777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.showHeader = 0;
18787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.mode = MODE_List;
1879a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( nArg==1 ){
1880a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = sqlite3_exec(p->db,
1881a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "SELECT name FROM sqlite_master "
1882a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1883a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "UNION ALL "
1884a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "SELECT name FROM sqlite_temp_master "
1885a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "WHERE type='index' "
1886a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "ORDER BY 1",
1887a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        callback, &data, &zErrMsg
1888a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      );
1889a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else{
1890a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zShellStatic = azArg[1];
1891a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = sqlite3_exec(p->db,
1892a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "SELECT name FROM sqlite_master "
1893a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "WHERE type='index' AND tbl_name LIKE shellstatic() "
1894a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "UNION ALL "
1895a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "SELECT name FROM sqlite_temp_master "
1896a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "WHERE type='index' AND tbl_name LIKE shellstatic() "
1897a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "ORDER BY 1",
1898a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        callback, &data, &zErrMsg
1899a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      );
1900a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zShellStatic = 0;
1901a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
19027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zErrMsg ){
19037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(stderr,"Error: %s\n", zErrMsg);
19047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_free(zErrMsg);
1905a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
1906a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( rc != SQLITE_OK ){
1907a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1908a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
19097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
19107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
19117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
19127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_ENABLE_IOTRACE
19137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
19147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    extern void (*sqlite3IoTrace)(const char*, ...);
19157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( iotrace && iotrace!=stdout ) fclose(iotrace);
19167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    iotrace = 0;
19177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( nArg<2 ){
19187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3IoTrace = 0;
19197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(azArg[1], "-")==0 ){
19207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3IoTrace = iotracePrintf;
19217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      iotrace = stdout;
19227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
19237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      iotrace = fopen(azArg[1], "w");
19247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( iotrace==0 ){
1925a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
19267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        sqlite3IoTrace = 0;
1927a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        rc = 1;
19287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else{
19297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        sqlite3IoTrace = iotracePrintf;
19307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
19317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
19327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
19337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
19347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
19357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifndef SQLITE_OMIT_LOAD_EXTENSION
19367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
19377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    const char *zFile, *zProc;
19387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zErrMsg = 0;
19397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zFile = azArg[1];
19407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zProc = nArg>=3 ? azArg[2] : 0;
19417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(p);
19427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
19437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( rc!=SQLITE_OK ){
1944a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: %s\n", zErrMsg);
19457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_free(zErrMsg);
19467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      rc = 1;
19477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
19487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
19497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
19507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
195190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
1952aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori    const char *zFile = azArg[1];
1953aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1954aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori      fclose(p->pLog);
1955aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori      p->pLog = 0;
1956aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori    }
1957aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori    if( strcmp(zFile,"stdout")==0 ){
1958aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori      p->pLog = stdout;
1959aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori    }else if( strcmp(zFile, "stderr")==0 ){
1960aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori      p->pLog = stderr;
1961aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori    }else if( strcmp(zFile, "off")==0 ){
1962aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori      p->pLog = 0;
1963aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori    }else{
1964aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori      p->pLog = fopen(zFile, "w");
1965aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori      if( p->pLog==0 ){
1966aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori        fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1967aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori      }
1968aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori    }
1969aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori  }else
1970aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori
1971a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
1972a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    int n2 = strlen30(azArg[1]);
1973a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
19747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        ||
1975a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
19767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_Line;
1977a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
19787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project              ||
1979a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori              (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
19807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_Column;
1981a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
19827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_List;
1983a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
19847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_Html;
1985a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
19867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_Tcl;
1987a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
19887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_Csv;
19897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
1990a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
19917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_List;
19927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
1993a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
19947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->mode = MODE_Insert;
1995a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      set_table_name(p, "table");
19967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else {
1997a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"Error: mode should be one of: "
19987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project         "column csv html insert line list tabs tcl\n");
1999a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
2000a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
2001a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }else
2002a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
2003a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2004a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    int n2 = strlen30(azArg[1]);
2005a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2006a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      p->mode = MODE_Insert;
2007a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      set_table_name(p, azArg[2]);
2008a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else {
2009a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: invalid arguments: "
2010a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        " \"%s\". Enter \".help\" for help\n", azArg[2]);
2011a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
20127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
20137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
20147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
20157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
20167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
20177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                     "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
20187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
20197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
20207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
20217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( p->out!=stdout ){
20227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fclose(p->out);
20237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
20247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( strcmp(azArg[1],"stdout")==0 ){
20257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->out = stdout;
20267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
20277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
20287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->out = fopen(azArg[1], "wb");
20297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( p->out==0 ){
2030a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
20317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        p->out = stdout;
2032a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        rc = 1;
20337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      } else {
20347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
20357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
20367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
20377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
20387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
20397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
20407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( nArg >= 2) {
20417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
20427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
20437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( nArg >= 3) {
20447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
20457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
20467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
20477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2048a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
20497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    rc = 2;
20507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
20517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2052a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
20537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    FILE *alt = fopen(azArg[1], "rb");
20547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( alt==0 ){
2055a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2056a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
20577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
2058a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = process_input(p, alt);
20597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fclose(alt);
20607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
20617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
20627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2063a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
2064a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    const char *zSrcFile;
2065a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    const char *zDb;
2066a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3 *pSrc;
2067a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3_backup *pBackup;
2068a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    int nTimeout = 0;
2069a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
2070a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( nArg==2 ){
2071a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zSrcFile = azArg[1];
2072a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zDb = "main";
2073a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else{
2074a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zSrcFile = azArg[2];
2075a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zDb = azArg[1];
2076a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
2077a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    rc = sqlite3_open(zSrcFile, &pSrc);
2078a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( rc!=SQLITE_OK ){
2079a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
2080a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      sqlite3_close(pSrc);
2081a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
2082a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
2083a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    open_db(p);
2084a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2085a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( pBackup==0 ){
2086a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2087a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      sqlite3_close(pSrc);
2088a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
2089a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
2090a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2091a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          || rc==SQLITE_BUSY  ){
2092a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( rc==SQLITE_BUSY ){
2093a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        if( nTimeout++ >= 3 ) break;
2094a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        sqlite3_sleep(100);
2095a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }
2096a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
2097a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3_backup_finish(pBackup);
2098a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( rc==SQLITE_DONE ){
2099a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 0;
2100a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2101a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: source database is busy\n");
2102a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
2103a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else{
2104a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2105a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
2106a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }
2107a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    sqlite3_close(pSrc);
2108a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }else
2109a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
2110a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
21117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    struct callback_data data;
21127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zErrMsg = 0;
21137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(p);
21147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    memcpy(&data, p, sizeof(data));
21157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.showHeader = 0;
21167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.mode = MODE_Semi;
21177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( nArg>1 ){
21187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int i;
211990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
21207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( strcmp(azArg[1],"sqlite_master")==0 ){
21217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        char *new_argv[2], *new_colv[2];
21227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        new_argv[0] = "CREATE TABLE sqlite_master (\n"
21237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  type text,\n"
21247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  name text,\n"
21257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  tbl_name text,\n"
21267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  rootpage integer,\n"
21277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  sql text\n"
21287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      ")";
21297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        new_argv[1] = 0;
21307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        new_colv[0] = "sql";
21317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        new_colv[1] = 0;
21327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        callback(&data, 1, new_argv, new_colv);
2133a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        rc = SQLITE_OK;
21347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
21357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        char *new_argv[2], *new_colv[2];
21367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
21377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  type text,\n"
21387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  name text,\n"
21397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  tbl_name text,\n"
21407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  rootpage integer,\n"
21417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      "  sql text\n"
21427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                      ")";
21437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        new_argv[1] = 0;
21447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        new_colv[0] = "sql";
21457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        new_colv[1] = 0;
21467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        callback(&data, 1, new_argv, new_colv);
2147a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        rc = SQLITE_OK;
21487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else{
21497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        zShellStatic = azArg[1];
2150a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        rc = sqlite3_exec(p->db,
21517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          "SELECT sql FROM "
2152a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
2153a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          "     FROM sqlite_master UNION ALL"
2154a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
215590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          "WHERE lower(tbl_name) LIKE shellstatic()"
215690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          "  AND type!='meta' AND sql NOTNULL "
21577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          "ORDER BY substr(type,2,1), name",
21587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          callback, &data, &zErrMsg);
21597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        zShellStatic = 0;
21607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
21617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
2162a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = sqlite3_exec(p->db,
21637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project         "SELECT sql FROM "
2164a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori         "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
2165a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori         "     FROM sqlite_master UNION ALL"
2166a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori         "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
21677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project         "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
21687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project         "ORDER BY substr(type,2,1), name",
21697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project         callback, &data, &zErrMsg
21707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      );
21717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
21727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zErrMsg ){
21737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(stderr,"Error: %s\n", zErrMsg);
21747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_free(zErrMsg);
2175a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
2176a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( rc != SQLITE_OK ){
2177a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"Error: querying schema information\n");
2178a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
2179a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else{
2180a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 0;
21817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
21827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
21837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
21847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
21857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_snprintf(sizeof(p->separator), p->separator,
21867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                     "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
21877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
21887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2189a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
21907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int i;
21917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
21927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
21937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
21947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
21957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"%9.9s: ", "nullvalue");
21967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      output_c_string(p->out, p->nullvalue);
21977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out, "\n");
21987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"%9.9s: %s\n","output",
2199a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori            strlen30(p->outfile) ? p->outfile : "stdout");
22007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"%9.9s: ", "separator");
22017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      output_c_string(p->out, p->separator);
22027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out, "\n");
2203de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
22047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"%9.9s: ","width");
22057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
22067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(p->out,"%d ",p->colWidth[i]);
22077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
22087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(p->out,"\n");
22097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
22107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2211de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2212de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    p->statsOn = booleanValue(azArg[1]);
2213de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  }else
2214de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori
2215a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
22167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char **azResult;
2217a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    int nRow;
22187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zErrMsg;
22197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(p);
22207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( nArg==1 ){
22217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      rc = sqlite3_get_table(p->db,
22227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "SELECT name FROM sqlite_master "
2223a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
22247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "UNION ALL "
22257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "SELECT name FROM sqlite_temp_master "
22267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "WHERE type IN ('table','view') "
22277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "ORDER BY 1",
22287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        &azResult, &nRow, 0, &zErrMsg
22297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      );
22307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
22317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zShellStatic = azArg[1];
22327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      rc = sqlite3_get_table(p->db,
22337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "SELECT name FROM sqlite_master "
2234a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "WHERE type IN ('table','view') AND name LIKE shellstatic() "
22357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "UNION ALL "
22367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "SELECT name FROM sqlite_temp_master "
2237a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "WHERE type IN ('table','view') AND name LIKE shellstatic() "
22387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        "ORDER BY 1",
22397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        &azResult, &nRow, 0, &zErrMsg
22407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      );
22417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zShellStatic = 0;
22427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
22437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zErrMsg ){
22447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(stderr,"Error: %s\n", zErrMsg);
22457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_free(zErrMsg);
2246a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
2247a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else if( rc != SQLITE_OK ){
2248a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2249a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = 1;
2250a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    }else{
22517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int len, maxlen = 0;
22527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int i, j;
22537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int nPrintCol, nPrintRow;
22547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=1; i<=nRow; i++){
22557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( azResult[i]==0 ) continue;
2256a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        len = strlen30(azResult[i]);
22577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( len>maxlen ) maxlen = len;
22587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
22597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      nPrintCol = 80/(maxlen+2);
22607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( nPrintCol<1 ) nPrintCol = 1;
22617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
22627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      for(i=0; i<nPrintRow; i++){
22637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        for(j=i+1; j<=nRow; j+=nPrintRow){
22647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          char *zSp = j<=nPrintRow ? "" : "  ";
22657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
22667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
22677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        printf("\n");
22687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
22697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
22707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_free_table(azResult);
22717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
22727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
227390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
227490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    static const struct {
227590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown       const char *zCtrlName;   /* Name of a test-control option */
227690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown       int ctrlCode;            /* Integer code for that option */
227790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    } aCtrl[] = {
227890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "prng_save",             SQLITE_TESTCTRL_PRNG_SAVE              },
227990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "prng_restore",          SQLITE_TESTCTRL_PRNG_RESTORE           },
228090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "prng_reset",            SQLITE_TESTCTRL_PRNG_RESET             },
228190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "bitvec_test",           SQLITE_TESTCTRL_BITVEC_TEST            },
228290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "fault_install",         SQLITE_TESTCTRL_FAULT_INSTALL          },
228390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "benign_malloc_hooks",   SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS    },
228490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "pending_byte",          SQLITE_TESTCTRL_PENDING_BYTE           },
228590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "assert",                SQLITE_TESTCTRL_ASSERT                 },
228690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "always",                SQLITE_TESTCTRL_ALWAYS                 },
228790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "reserve",               SQLITE_TESTCTRL_RESERVE                },
228890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },
228990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
229090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      { "scratchmalloc",         SQLITE_TESTCTRL_SCRATCHMALLOC          },
229190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    };
229290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    int testctrl = -1;
229390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    int rc = 0;
229490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    int i, n;
229590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    open_db(p);
229690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
229790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    /* convert testctrl text option to value. allow any unique prefix
229890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    ** of the option name, or a numerical value. */
229990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    n = strlen30(azArg[1]);
230090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
230190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
230290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( testctrl<0 ){
230390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          testctrl = aCtrl[i].ctrlCode;
230490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        }else{
230590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
230690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          testctrl = -1;
230790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
230890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        }
230990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
231090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
231190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( testctrl<0 ) testctrl = atoi(azArg[1]);
231290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
231390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
231490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else{
231590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      switch(testctrl){
231690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
231790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int, db, int) */
231890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_OPTIMIZATIONS:
231990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_RESERVE:
232090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==3 ){
232190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            int opt = (int)strtol(azArg[2], 0, 0);
232290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl, p->db, opt);
232390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
232490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
232590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes a single int option\n",
232690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                    azArg[1]);
232790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
232890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
232990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
233090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int) */
233190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_PRNG_SAVE:
233290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_PRNG_RESTORE:
233390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_PRNG_RESET:
233490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==2 ){
233590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl);
233690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
233790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
233890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
233990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
234090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
234190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
234290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int, uint) */
234390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_PENDING_BYTE:
234490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==3 ){
234590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            unsigned int opt = (unsigned int)atoi(azArg[2]);
234690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl, opt);
234790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
234890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
234990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes a single unsigned"
235090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                           " int option\n", azArg[1]);
235190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
235290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
235390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
235490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int, int) */
235590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_ASSERT:
235690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_ALWAYS:
235790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==3 ){
235890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            int opt = atoi(azArg[2]);
235990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl, opt);
236090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
236190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
236290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes a single int option\n",
236390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                            azArg[1]);
236490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
236590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
236690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
236790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        /* sqlite3_test_control(int, char *) */
236890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_N_KEYWORD
236990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_ISKEYWORD:
237090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          if( nArg==3 ){
237190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            const char *opt = azArg[2];
237290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            rc = sqlite3_test_control(testctrl, opt);
237390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            printf("%d (0x%08x)\n", rc, rc);
237490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          } else {
237590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
237690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                            azArg[1]);
237790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          }
237890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
237990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
238090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
238190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_BITVEC_TEST:
238290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_FAULT_INSTALL:
238390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
238490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        case SQLITE_TESTCTRL_SCRATCHMALLOC:
238590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        default:
238690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
238790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown                  azArg[1]);
238890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown          break;
238990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
239090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
239190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }else
239290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
2393a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
23947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(p);
23957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_busy_timeout(p->db, atoi(azArg[1]));
23967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
239771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori
239890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
239990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown   && nArg==2
240090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  ){
24017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    enableTimer = booleanValue(azArg[1]);
24027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
240371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori
240490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
240590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    printf("SQLite %s %s\n" /*extra-version-info*/,
240690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_libversion(), sqlite3_sourceid());
240790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }else
240890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
240990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
241090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    const char *zDbName = nArg==2 ? azArg[1] : "main";
241190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    char *zVfsName = 0;
241290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( p->db ){
241390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
241490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( zVfsName ){
241590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        printf("%s\n", zVfsName);
241690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_free(zVfsName);
241790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
241890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
241990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }else
242090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
2421a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
24227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int j;
24237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    assert( nArg<=ArraySize(azArg) );
24247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
24257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->colWidth[j-1] = atoi(azArg[j]);
24267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
24277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else
24287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
24297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  {
2430a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    fprintf(stderr, "Error: unknown command or invalid arguments: "
24317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      " \"%s\". Enter \".help\" for help\n", azArg[0]);
2432a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    rc = 1;
24337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
24347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
24357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return rc;
24367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
24377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
24387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
24397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return TRUE if a semicolon occurs anywhere in the first N characters
24407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** of string z[].
24417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
24427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int _contains_semicolon(const char *z, int N){
24437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int i;
24447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(i=0; i<N; i++){  if( z[i]==';' ) return 1; }
24457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return 0;
24467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
24477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
24487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
24497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Test to see if a line consists entirely of whitespace.
24507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
24517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int _all_whitespace(const char *z){
24527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(; *z; z++){
245390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( IsSpace(z[0]) ) continue;
24547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( *z=='/' && z[1]=='*' ){
24557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      z += 2;
24567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      while( *z && (*z!='*' || z[1]!='/') ){ z++; }
24577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( *z==0 ) return 0;
24587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      z++;
24597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      continue;
24607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
24617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( *z=='-' && z[1]=='-' ){
24627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      z += 2;
24637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      while( *z && *z!='\n' ){ z++; }
24647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( *z==0 ) return 1;
24657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      continue;
24667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
24677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    return 0;
24687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
24697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return 1;
24707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
24717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
24727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
24737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return TRUE if the line typed in is an SQL command terminator other
24747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** than a semi-colon.  The SQL Server style "go" command is understood
24757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** as is the Oracle "/".
24767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
24777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int _is_command_terminator(const char *zLine){
247890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  while( IsSpace(zLine[0]) ){ zLine++; };
2479a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2480a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    return 1;  /* Oracle */
2481a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }
248290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
24837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project         && _all_whitespace(&zLine[2]) ){
24847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    return 1;  /* SQL Server */
24857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
24867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return 0;
24877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
24887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
24897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
2490a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Return true if zSql is a complete SQL statement.  Return false if it
2491a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** ends in the middle of a string literal or C-style comment.
2492a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/
2493a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int _is_complete(char *zSql, int nSql){
2494a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int rc;
2495a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( zSql==0 ) return 1;
2496a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  zSql[nSql] = ';';
2497a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  zSql[nSql+1] = 0;
2498a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  rc = sqlite3_complete(zSql);
2499a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  zSql[nSql] = 0;
2500a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  return rc;
2501a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori}
2502a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori
2503a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/*
25047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Read input from *in and process it.  If *in==0 then input
25057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is interactive - the user is typing it it.  Otherwise, input
25067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is coming from a file or device.  A prompt is issued and history
25077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is saved only if input is interactive.  An interrupt signal will
25087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** cause this routine to exit immediately, unless input is interactive.
25097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project**
25107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return the number of errors.
25117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
25127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int process_input(struct callback_data *p, FILE *in){
25137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zLine = 0;
25147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zSql = 0;
25157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int nSql = 0;
25167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int nSqlPrior = 0;
25177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zErrMsg;
25187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int rc;
25197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int errCnt = 0;
25207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int lineno = 0;
25217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int startline = 0;
25227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
25237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
25247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fflush(p->out);
25257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    free(zLine);
25267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zLine = one_input_line(zSql, in);
25277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zLine==0 ){
25287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      break;  /* We have reached EOF */
25297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
25307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( seenInterrupt ){
25317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( in!=0 ) break;
25327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      seenInterrupt = 0;
25337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
25347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    lineno++;
25357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
25367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zLine && zLine[0]=='.' && nSql==0 ){
2537a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( p->echoOn ) printf("%s\n", zLine);
25387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      rc = do_meta_command(zLine, p);
2539a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( rc==2 ){ /* exit requested */
25407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        break;
25417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }else if( rc ){
25427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        errCnt++;
25437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
25447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      continue;
25457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
2546a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
25477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      memcpy(zLine,";",2);
25487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
25497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    nSqlPrior = nSql;
25507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zSql==0 ){
25517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int i;
255290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
25537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zLine[i]!=0 ){
2554a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        nSql = strlen30(zLine);
2555a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        zSql = malloc( nSql+3 );
25567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( zSql==0 ){
2557a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          fprintf(stderr, "Error: out of memory\n");
25587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          exit(1);
25597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
25607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        memcpy(zSql, zLine, nSql+1);
25617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        startline = lineno;
25627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
25637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
2564a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      int len = strlen30(zLine);
2565a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      zSql = realloc( zSql, nSql + len + 4 );
25667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zSql==0 ){
2567a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        fprintf(stderr,"Error: out of memory\n");
25687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        exit(1);
25697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
25707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zSql[nSql++] = '\n';
25717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      memcpy(&zSql[nSql], zLine, len+1);
25727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      nSql += len;
25737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
25747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
25757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                && sqlite3_complete(zSql) ){
25767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      p->cnt = 0;
25777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      open_db(p);
25787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      BEGIN_TIMER;
2579a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
25807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      END_TIMER;
25817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( rc || zErrMsg ){
25827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        char zPrefix[100];
25837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( in!=0 || !stdin_is_interactive ){
258471504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori          sqlite3_snprintf(sizeof(zPrefix), zPrefix,
2585a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori                           "Error: near line %d:", startline);
25867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }else{
2587a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
25887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
25897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        if( zErrMsg!=0 ){
2590a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
25917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          sqlite3_free(zErrMsg);
25927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project          zErrMsg = 0;
25937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }else{
2594a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
25957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        }
25967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        errCnt++;
25977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
25987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      free(zSql);
25997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zSql = 0;
26007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      nSql = 0;
26017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
26027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
26037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( zSql ){
260490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    if( !_all_whitespace(zSql) ){
260590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
260690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }
26077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    free(zSql);
26087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
26097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  free(zLine);
26107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return errCnt;
26117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
26127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
26147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return a pathname which is the user's home directory.  A
26157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 0 return indicates an error of some kind.  Space to hold the
26167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** resulting string is obtained from malloc().  The calling
26177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** function should free the result.
26187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
26197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char *find_home_dir(void){
26207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *home_dir = NULL;
26217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
2622a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
26237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  struct passwd *pwent;
26247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  uid_t uid = getuid();
26257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( (pwent=getpwuid(uid)) != NULL) {
26267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    home_dir = pwent->pw_dir;
26277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
26287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
26297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(_WIN32_WCE)
26317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
26327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project   */
26337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  home_dir = strdup("/");
26347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else
26357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
26377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if (!home_dir) {
26387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    home_dir = getenv("USERPROFILE");
26397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
26407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
26417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if (!home_dir) {
26437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    home_dir = getenv("HOME");
26447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
26457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
26477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if (!home_dir) {
26487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *zDrive, *zPath;
26497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    int n;
26507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zDrive = getenv("HOMEDRIVE");
26517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zPath = getenv("HOMEPATH");
26527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zDrive && zPath ){
2653a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      n = strlen30(zDrive) + strlen30(zPath) + 1;
26547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      home_dir = malloc( n );
26557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( home_dir==0 ) return 0;
26567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
26577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      return home_dir;
26587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
26597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    home_dir = "c:\\";
26607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
26617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
26627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif /* !_WIN32_WCE */
26647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( home_dir ){
2666a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    int n = strlen30(home_dir) + 1;
26677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *z = malloc( n );
26687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( z ) memcpy(z, home_dir, n);
26697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    home_dir = z;
26707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
26717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return home_dir;
26737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
26747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
26767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Read input from the file given by sqliterc_override.  Or if that
26777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** parameter is NULL, take input from ~/.sqliterc
2678a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori**
2679a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Returns the number of errors.
26807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
2681a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int process_sqliterc(
26827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  struct callback_data *p,        /* Configuration data */
26837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  const char *sqliterc_override   /* Name of config file. NULL to use default */
26847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project){
26857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *home_dir = NULL;
26867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  const char *sqliterc = sqliterc_override;
26877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zBuf = 0;
26887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  FILE *in = NULL;
26897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int nBuf;
2690a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  int rc = 0;
26917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
26927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if (sqliterc == NULL) {
26937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    home_dir = find_home_dir();
26947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( home_dir==0 ){
2695a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#if !defined(__RTP__) && !defined(_WRS_KERNEL)
2696a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
2697a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#endif
2698a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
26997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
2700a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    nBuf = strlen30(home_dir) + 16;
27017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zBuf = malloc( nBuf );
27027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zBuf==0 ){
2703a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2704a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      return 1;
27057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
27067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
27077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    free(home_dir);
27087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    sqliterc = (const char*)zBuf;
27097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
27107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  in = fopen(sqliterc,"rb");
27117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( in ){
27127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( stdin_is_interactive ){
2713a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
27147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
2715a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    rc = process_input(p,in);
27167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fclose(in);
27177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
27187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  free(zBuf);
2719a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  return rc;
27207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
27217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
27227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
27237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Show available command line options
27247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
272571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Noristatic const char zOptions[] =
27267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -bail                stop after hitting an error\n"
27277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -batch               force batch I/O\n"
27287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -column              set output mode to 'column'\n"
2729c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -cmd command         run \"command\" before reading stdin\n"
27307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -csv                 set output mode to 'csv'\n"
2731c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -echo                print commands before execution\n"
2732c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -init filename       read/process named file\n"
2733c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -[no]header          turn headers on or off\n"
2734c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -help                show this message\n"
27357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -html                set output mode to HTML\n"
2736c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -interactive         force interactive I/O\n"
27377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -line                set output mode to 'line'\n"
27387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -list                set output mode to 'list'\n"
2739c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX
2740c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -multiplex           enable the multiplexor VFS\n"
2741c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown#endif
2742c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown  "   -nullvalue 'text'    set text string for NULL values\n"
27437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -separator 'x'       set output field separator (|)\n"
2744de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori  "   -stats               print memory stats before each finalize\n"
27457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  "   -version             show SQLite version\n"
274690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  "   -vfs NAME            use NAME as the default VFS\n"
274790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE
274890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  "   -vfstrace            enable tracing of all VFS calls\n"
274990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
27507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project;
27517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void usage(int showDetail){
27527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  fprintf(stderr,
275371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori      "Usage: %s [OPTIONS] FILENAME [SQL]\n"
27547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      "FILENAME is the name of an SQLite database. A new database is created\n"
27557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      "if the file does not previously exist.\n", Argv0);
27567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( showDetail ){
27577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(stderr, "OPTIONS include:\n%s", zOptions);
27587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else{
27597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    fprintf(stderr, "Use the -help option for additional information\n");
27607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
27617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  exit(1);
27627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
27637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
27647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/*
27657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Initialize the state information in data
27667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/
27677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void main_init(struct callback_data *data) {
27687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  memset(data, 0, sizeof(*data));
27697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  data->mode = MODE_List;
27707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  memcpy(data->separator,"|", 2);
27717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  data->showHeader = 0;
277290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  sqlite3_config(SQLITE_CONFIG_URI, 1);
2773aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori  sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
27747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
27757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
277671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
27777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
27787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
27797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectint main(int argc, char **argv){
27807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zErrMsg = 0;
27817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  struct callback_data data;
27827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  const char *zInitFile = 0;
27837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  char *zFirstCmd = 0;
27847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int i;
27857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  int rc = 0;
27867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
278790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
278890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
278990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown            sqlite3_sourceid(), SQLITE_SOURCE_ID);
279090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    exit(1);
279190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  }
27927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  Argv0 = argv[0];
27937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  main_init(&data);
27947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  stdin_is_interactive = isatty(0);
27957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
27967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  /* Make sure we have a valid signal handler early, before anything
27977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** else is done.
27987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  */
27997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SIGINT
28007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  signal(SIGINT, interrupt_handler);
28017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
28027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
28037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  /* Do an initial pass through the command-line argument to locate
28047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** the name of the database file, the name of the initialization file,
280590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown  ** the size of the alternative malloc heap,
28067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** and the first command to execute.
28077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  */
28087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(i=1; i<argc-1; i++){
28097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *z;
28107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( argv[i][0]!='-' ) break;
28117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    z = argv[i];
2812c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( z[1]=='-' ) z++;
2813c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    if( strcmp(z,"-separator")==0
2814c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown     || strcmp(z,"-nullvalue")==0
2815c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown     || strcmp(z,"-cmd")==0
2816c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    ){
28177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      i++;
2818c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-init")==0 ){
28197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      i++;
28207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zInitFile = argv[i];
2821a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    /* Need to check for batch mode here to so we can avoid printing
282271504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori    ** informational messages (like from process_sqliterc) before
2823a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    ** we do the actual processing of arguments later in a second pass.
2824a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    */
2825c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-batch")==0 ){
2826a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      stdin_is_interactive = 0;
2827c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-heap")==0 ){
282890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
282990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      int j, c;
283090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      const char *zSize;
283190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_int64 szHeap;
283290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown
283390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      zSize = argv[++i];
283490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      szHeap = atoi(zSize);
283590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      for(j=0; (c = zSize[j])!=0; j++){
283690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( c=='M' ){ szHeap *= 1000000; break; }
283790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( c=='K' ){ szHeap *= 1000; break; }
283890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        if( c=='G' ){ szHeap *= 1000000000; break; }
283990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
284090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
284190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
284290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
284390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE
2844c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-vfstrace")==0 ){
284590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      extern int vfstrace_register(
284690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         const char *zTraceName,
284790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         const char *zOldVfsName,
284890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         int (*xOut)(const char*,void*),
284990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         void *pOutArg,
285090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown         int makeDefault
285190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      );
285290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
285390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
285490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX
2855c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-multiplex")==0 ){
285690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      extern int sqlite3_multiple_initialize(const char*,int);
285790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_multiplex_initialize(0, 1);
285890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
2859c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-vfs")==0 ){
286090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
286190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      if( pVfs ){
286290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_vfs_register(pVfs, 1);
286390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }else{
286490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
286590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        exit(1);
286690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      }
28677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
28687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
28697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( i<argc ){
2870a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
28717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
28727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else
28737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.zDbFilename = argv[i++];
28747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
28757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else{
28767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifndef SQLITE_OMIT_MEMORYDB
28777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.zDbFilename = ":memory:";
28787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else
28797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    data.zDbFilename = 0;
28807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
28817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
28827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( i<argc ){
28837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    zFirstCmd = argv[i++];
28847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
2885a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( i<argc ){
2886a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2887a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    fprintf(stderr,"Use -help for a list of options.\n");
2888a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    return 1;
2889a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }
28907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  data.out = stdout;
28917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
28927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_OMIT_MEMORYDB
28937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( data.zDbFilename==0 ){
2894a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2895a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    return 1;
28967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
28977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
28987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
28997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  /* Go ahead and open the database file if it already exists.  If the
29007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** file does not exist, delay opening it.  This prevents empty database
29017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** files from being created if a user mistypes the database name argument
29027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** to the sqlite command-line tool.
29037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  */
29047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( access(data.zDbFilename, 0)==0 ){
29057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    open_db(&data);
29067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
29077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
29087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  /* Process the initialization file if there is one.  If no -init option
29097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** is given on the command line, look for a file named ~/.sqliterc and
29107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** try to process it.
29117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  */
2912a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  rc = process_sqliterc(&data,zInitFile);
2913a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  if( rc>0 ){
2914a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori    return rc;
2915a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori  }
29167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
29177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  /* Make a second pass through the command-line argument and set
29187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** options.  This second pass is delayed until after the initialization
29197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** file is processed so that the command-line arguments will override
29207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  ** settings in the initialization file.
29217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  */
29227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  for(i=1; i<argc && argv[i][0]=='-'; i++){
29237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    char *z = argv[i];
29247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( z[1]=='-' ){ z++; }
29257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( strcmp(z,"-init")==0 ){
29267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      i++;
29277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-html")==0 ){
29287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      data.mode = MODE_Html;
29297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-list")==0 ){
29307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      data.mode = MODE_List;
29317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-line")==0 ){
29327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      data.mode = MODE_Line;
29337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-column")==0 ){
29347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      data.mode = MODE_Column;
29357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-csv")==0 ){
29367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      data.mode = MODE_Csv;
29377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      memcpy(data.separator,",",2);
29387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-separator")==0 ){
29397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      i++;
2940a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if(i>=argc){
2941c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        fprintf(stderr,"%s: Error: missing argument for option: %s\n",
2942c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown                        Argv0, z);
2943a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        fprintf(stderr,"Use -help for a list of options.\n");
2944a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        return 1;
2945a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }
29467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_snprintf(sizeof(data.separator), data.separator,
29477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                       "%.*s",(int)sizeof(data.separator)-1,argv[i]);
29487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-nullvalue")==0 ){
29497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      i++;
2950a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if(i>=argc){
2951c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        fprintf(stderr,"%s: Error: missing argument for option: %s\n",
2952c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown                        Argv0, z);
2953a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        fprintf(stderr,"Use -help for a list of options.\n");
2954a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        return 1;
2955a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }
29567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
29577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project                       "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
29587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-header")==0 ){
29597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      data.showHeader = 1;
29607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-noheader")==0 ){
29617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      data.showHeader = 0;
29627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-echo")==0 ){
29637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      data.echoOn = 1;
2964de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori    }else if( strcmp(z,"-stats")==0 ){
2965de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori      data.statsOn = 1;
29667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-bail")==0 ){
29677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      bail_on_error = 1;
29687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-version")==0 ){
296990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
29707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      return 0;
29717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-interactive")==0 ){
29727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      stdin_is_interactive = 1;
29737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else if( strcmp(z,"-batch")==0 ){
29747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      stdin_is_interactive = 0;
297590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else if( strcmp(z,"-heap")==0 ){
297690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      i++;
297790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else if( strcmp(z,"-vfs")==0 ){
297890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      i++;
297990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE
298090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else if( strcmp(z,"-vfstrace")==0 ){
298190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      i++;
298290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
298390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX
298490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    }else if( strcmp(z,"-multiplex")==0 ){
298590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown      i++;
298690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif
2987c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-help")==0 ){
29887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      usage(1);
2989c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown    }else if( strcmp(z,"-cmd")==0 ){
2990c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      if( i==argc-1 ) break;
2991c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      i++;
2992c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      z = argv[i];
2993c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      if( z[0]=='.' ){
2994c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        rc = do_meta_command(z, &data);
2995c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( rc && bail_on_error ) return rc;
2996c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      }else{
2997c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        open_db(&data);
2998c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
2999c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        if( zErrMsg!=0 ){
3000c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          fprintf(stderr,"Error: %s\n", zErrMsg);
3001c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          if( bail_on_error ) return rc!=0 ? rc : 1;
3002c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        }else if( rc!=0 ){
3003c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3004c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown          if( bail_on_error ) return rc;
3005c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown        }
3006c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown      }
30077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
3008a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
30097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      fprintf(stderr,"Use -help for a list of options.\n");
30107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      return 1;
30117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
30127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
30137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project
30147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  if( zFirstCmd ){
30157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    /* Run just the command that follows the database name
30167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    */
30177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( zFirstCmd[0]=='.' ){
3018a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = do_meta_command(zFirstCmd, &data);
30197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
30207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      open_db(&data);
3021a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
3022a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( zErrMsg!=0 ){
3023a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        fprintf(stderr,"Error: %s\n", zErrMsg);
3024a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        return rc!=0 ? rc : 1;
3025a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      }else if( rc!=0 ){
3026a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3027a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        return rc;
30287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
30297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
30307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }else{
30317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    /* Run commands received from standard input
30327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    */
30337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    if( stdin_is_interactive ){
30347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      char *zHome;
30357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      char *zHistory = 0;
30367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      int nHistory;
30377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      printf(
303890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        "SQLite version %s %.19s\n" /*extra-version-info*/
3039a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "Enter \".help\" for instructions\n"
3040a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        "Enter SQL statements terminated with a \";\"\n",
304190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown        sqlite3_libversion(), sqlite3_sourceid()
30427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      );
30437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      zHome = find_home_dir();
3044a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori      if( zHome ){
3045a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        nHistory = strlen30(zHome) + 20;
3046a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        if( (zHistory = malloc(nHistory))!=0 ){
3047a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori          sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3048a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori        }
30497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
30507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(HAVE_READLINE) && HAVE_READLINE==1
30517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zHistory ) read_history(zHistory);
30527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif
30537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      rc = process_input(&data, 0);
30547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      if( zHistory ){
30557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        stifle_history(100);
30567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        write_history(zHistory);
30577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project        free(zHistory);
30587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      }
30597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      free(zHome);
30607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }else{
30617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project      rc = process_input(&data, stdin);
30627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project    }
30637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
30647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  set_table_name(&data, 0);
306571504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori  if( data.db ){
306690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown    sqlite3_close(data.db);
30677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  }
30687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project  return rc;
30697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}
3070