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/* 213fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** If requested, include the SQLite compiler options file for MSVC. 223fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 233fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if defined(INCLUDE_MSVC_H) 243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#include "msvc.h" 253fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 273fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 283fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** No support for loadable extensions in VxWorks. 293fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 303fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION 313fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define SQLITE_OMIT_LOAD_EXTENSION 1 323fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 333fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 343fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 3590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown** Enable large-file support for fopen() and friends on unix. 3690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown*/ 3790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifndef SQLITE_DISABLE_LFS 3890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# define _LARGE_FILE 1 3990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# ifndef _FILE_OFFSET_BITS 4090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# define _FILE_OFFSET_BITS 64 4190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# endif 4290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown# define _LARGEFILE_SOURCE 1 4390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 4490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <stdlib.h> 467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <string.h> 477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <stdio.h> 487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <assert.h> 497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include "sqlite3.h" 503fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if SQLITE_USER_AUTHENTICATION 513fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# include "sqlite3userauth.h" 523fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <ctype.h> 547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <stdarg.h> 55c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori// Begin Android Add 56c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori#ifndef NO_ANDROID_FUNCS 5755536230a14a7c199bbe41a83893c7d82e0c0a24Neil Fuller#include "IcuUtils.h" 58c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori#include <sqlite3_android.h> 59c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori#endif 60c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori// End Android Add 61c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori 628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#if !defined(_WIN32) && !defined(WIN32) 637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <signal.h> 64a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori# if !defined(__RTP__) && !defined(_WRS_KERNEL) 65a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori# include <pwd.h> 66a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori# endif 677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <unistd.h> 687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <sys/types.h> 697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if HAVE_READLINE 727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <readline/readline.h> 737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <readline/history.h> 748fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#endif 753fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 763fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if HAVE_EDITLINE 778fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich# include <editline/readline.h> 7890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 803fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if HAVE_EDITLINE || HAVE_READLINE 813fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_add_history(X) add_history(X) 833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_read_history(X) read_history(X) 843fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_write_history(X) write_history(X) 853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_stifle_history(X) stifle_history(X) 863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_readline(X) readline(X) 873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#elif HAVE_LINENOISE 893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 903fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# include "linenoise.h" 913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_add_history(X) linenoiseHistoryAdd(X) 923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_read_history(X) linenoiseHistoryLoad(X) 933fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_write_history(X) linenoiseHistorySave(X) 943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) 953fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_readline(X) linenoise(X) 963fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 973fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#else 983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 9960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# define shell_read_history(X) 1003fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_write_history(X) 1013fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define shell_stifle_history(X) 1023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 1033fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich# define SHELL_USE_LOCAL_GETLINE 1 1047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 1057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 1063fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 1077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(_WIN32) || defined(WIN32) 1087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project# include <io.h> 1099bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown# include <fcntl.h> 110253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# define isatty(h) _isatty(h) 111253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# ifndef access 112253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# define access(f,m) _access((f),(m)) 113253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# endif 114253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# undef popen 115253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# define popen _popen 116253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# undef pclose 117253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# define pclose _pclose 1187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else 119253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich /* Make sure isatty() has a prototype. */ 120253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich extern int isatty(int); 1213fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 122253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# if !defined(__RTP__) && !defined(_WRS_KERNEL) 123253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich /* popen and pclose are not C89 functions and so are 124253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich ** sometimes omitted from the <stdio.h> header */ 125253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich extern FILE *popen(const char*,const char*); 126253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich extern int pclose(FILE*); 127253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# else 128253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# define SQLITE_OMIT_POPEN 1 129253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich# endif 1307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 1317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 1327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(_WIN32_WCE) 1337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() 1347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project * thus we always assume that we have a console. That can be 1357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project * overridden with the -batch command line option. 1367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 1377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define isatty(x) 1 1387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 1397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 14090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown/* ctype macros that work with signed characters */ 14190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define IsSpace(X) isspace((unsigned char)X) 14290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define IsDigit(X) isdigit((unsigned char)X) 14390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#define ToLower(X) (char)tolower((unsigned char)X) 14490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 14560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(_WIN32) || defined(WIN32) 14660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#include <windows.h> 14760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 14860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* string conversion routines only needed on Win32 */ 14960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisextern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); 15060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisextern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); 15160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisextern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); 15208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidisextern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); 15360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 15460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* On Windows, we normally run with output mode of TEXT so that \n characters 1563fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** are automatically translated into \r\n. However, this behavior needs 1573fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** to be disabled in some cases (ex: when generating CSV output and when 1583fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** rendering quoted strings that contain \n characters). The following 1593fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** routines take care of that. 1603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 1613fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if defined(_WIN32) || defined(WIN32) 16260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic void setBinaryMode(FILE *file, int isOutput){ 16360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( isOutput ) fflush(file); 16460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis _setmode(_fileno(file), _O_BINARY); 1653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich} 16660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic void setTextMode(FILE *file, int isOutput){ 16760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( isOutput ) fflush(file); 16860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis _setmode(_fileno(file), _O_TEXT); 1693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich} 1703fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#else 17160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# define setBinaryMode(X,Y) 17260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# define setTextMode(X,Y) 1733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 1743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 1758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 1768fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* True if the timer is enabled */ 1778fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic int enableTimer = 0; 1788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 1798fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* Return the current wall-clock time */ 1808fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic sqlite3_int64 timeOfDay(void){ 1818fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich static sqlite3_vfs *clockVfs = 0; 1828fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_int64 t; 1838fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); 18460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ 1858fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich clockVfs->xCurrentTimeInt64(clockVfs, &t); 1868fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 1878fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich double r; 1888fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich clockVfs->xCurrentTime(clockVfs, &r); 1898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich t = (sqlite3_int64)(r*86400000.0); 1908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 1918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return t; 1928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 1938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 1943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) 1957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <sys/time.h> 1967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#include <sys/resource.h> 1977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 1983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* VxWorks does not support getrusage() as far as we can determine */ 1993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if defined(_WRS_KERNEL) || defined(__RTP__) 2003fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstruct rusage { 2013fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich struct timeval ru_utime; /* user CPU time used */ 2023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich struct timeval ru_stime; /* system CPU time used */ 2033fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich}; 2043fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define getrusage(A,B) memset(B,0,sizeof(*B)) 2053fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 2063fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 2077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* Saved resource information for the beginning of an operation */ 2088fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic struct rusage sBegin; /* CPU time at start */ 2098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic sqlite3_int64 iBegin; /* Wall-clock time at start */ 2107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 2117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 2127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Begin timing an operation 2137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 2147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void beginTimer(void){ 2157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( enableTimer ){ 2167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project getrusage(RUSAGE_SELF, &sBegin); 2178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich iBegin = timeOfDay(); 2187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 2197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 2207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 221a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* Return the difference of two time_structs in seconds */ 222a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic double timeDiff(struct timeval *pStart, struct timeval *pEnd){ 22360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + 224a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori (double)(pEnd->tv_sec - pStart->tv_sec); 2257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 2267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 2277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 2287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Print the timing results. 2297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 2307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void endTimer(void){ 2317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( enableTimer ){ 2328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_int64 iEnd = timeOfDay(); 2333fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich struct rusage sEnd; 2347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project getrusage(RUSAGE_SELF, &sEnd); 2358fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("Run Time: real %.3f user %f sys %f\n", 2368fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich (iEnd - iBegin)*0.001, 237a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), 238a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); 2397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 2407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 241a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 2427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define BEGIN_TIMER beginTimer() 2437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define END_TIMER endTimer() 2447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define HAS_TIMER 1 245a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 246a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#elif (defined(_WIN32) || defined(WIN32)) 247a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 248a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* Saved resource information for the beginning of an operation */ 249a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic HANDLE hProcess; 250a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic FILETIME ftKernelBegin; 251a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic FILETIME ftUserBegin; 2528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic sqlite3_int64 ftWallBegin; 2533fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichtypedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, 2543fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich LPFILETIME, LPFILETIME); 255a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic GETPROCTIMES getProcessTimesAddr = NULL; 256a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 257a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 258a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Check to see if we have timer support. Return 1 if necessary 259a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** support found (or found previously). 260a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 261a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int hasTimer(void){ 262a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( getProcessTimesAddr ){ 263a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 264a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } else { 2653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* GetProcessTimes() isn't supported in WIN95 and some other Windows 2663fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** versions. See if the version we are running on has it, and if it 2673fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** does, save off a pointer to it and the current process handle. 268a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori */ 269a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori hProcess = GetCurrentProcess(); 270a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( hProcess ){ 271a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); 272a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( NULL != hinstLib ){ 2733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich getProcessTimesAddr = 2743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); 275a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( NULL != getProcessTimesAddr ){ 276a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 277a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 27860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis FreeLibrary(hinstLib); 279a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 280a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 281a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 282a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 0; 283a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 284a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 285a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 286a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Begin timing an operation 287a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 288a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic void beginTimer(void){ 289a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( enableTimer && getProcessTimesAddr ){ 290a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori FILETIME ftCreation, ftExit; 2913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich getProcessTimesAddr(hProcess,&ftCreation,&ftExit, 2923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich &ftKernelBegin,&ftUserBegin); 2938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ftWallBegin = timeOfDay(); 294a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 295a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 296a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 297a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* Return the difference of two FILETIME structs in seconds */ 298a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic double timeDiff(FILETIME *pStart, FILETIME *pEnd){ 299a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite_int64 i64Start = *((sqlite_int64 *) pStart); 300a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite_int64 i64End = *((sqlite_int64 *) pEnd); 301a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return (double) ((i64End - i64Start) / 10000000.0); 302a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 303a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 304a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 305a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Print the timing results. 306a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 307a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic void endTimer(void){ 308a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( enableTimer && getProcessTimesAddr){ 309a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; 3108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_int64 ftWallEnd = timeOfDay(); 3113fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); 3128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("Run Time: real %.3f user %f sys %f\n", 3138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich (ftWallEnd - ftWallBegin)*0.001, 314a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori timeDiff(&ftUserBegin, &ftUserEnd), 315a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori timeDiff(&ftKernelBegin, &ftKernelEnd)); 316a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 317a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 318a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 319a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define BEGIN_TIMER beginTimer() 320a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define END_TIMER endTimer() 321a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define HAS_TIMER hasTimer() 322a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 3237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else 32460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#define BEGIN_TIMER 3257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define END_TIMER 3267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define HAS_TIMER 0 3277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 3287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 329a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 330a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Used to prevent warnings about unused parameters 331a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 332a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define UNUSED_PARAMETER(x) (void)(x) 333a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 3347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 3357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** If the following flag is set, then command execution stops 3367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** at an error if we are not interactive. 3377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 3387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int bail_on_error = 0; 3397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 3407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 3417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Threat stdin as an interactive input if the following variable 3427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is true. Otherwise, assume stdin is connected to a file or pipe. 3437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 3447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int stdin_is_interactive = 1; 3457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 3467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 34760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** On Windows systems we have to know if standard output is a console 34860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** in order to translate UTF-8 into MBCS. The following variable is 34960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** true if translation is required. 35060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 35160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic int stdout_is_console = 1; 35260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 35360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 3547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** The following is the open SQLite database. We make a pointer 3557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** to this database a static variable so that it can be accessed 3567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** by the SIGINT handler to interrupt database processing. 3577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 3583a6c79f802fabdb94367177310663397420e319fNick Kralevichstatic sqlite3 *globalDb = 0; 3597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 3607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 3617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** True if an interrupt (Control-C) has been received. 3627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 3637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic volatile int seenInterrupt = 0; 3647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 3657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 3667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This is the name of our program. It is set in main(), used 3677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** in a number of other places, mostly for error messages. 3687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 3697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char *Argv0; 3707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 3717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 3727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Prompt strings. Initialized in main. Settable with 3737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** .prompt main continue 3747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 3757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ 3767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ 3777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 3787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 37960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Render output like fprintf(). Except, if the output is going to the 38060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** console and if this is running on a Windows machine, translate the 38160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** output from UTF-8 into MBCS. 38260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 38360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(_WIN32) || defined(WIN32) 38460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisvoid utf8_printf(FILE *out, const char *zFormat, ...){ 38560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis va_list ap; 38660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis va_start(ap, zFormat); 38760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( stdout_is_console && (out==stdout || out==stderr) ){ 38860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char *z1 = sqlite3_vmprintf(zFormat, ap); 38960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); 39060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(z1); 39160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis fputs(z2, out); 39260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(z2); 39360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 39460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis vfprintf(out, zFormat, ap); 39560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 39660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis va_end(ap); 39760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 39860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#elif !defined(utf8_printf) 39960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# define utf8_printf fprintf 40060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 40160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 40260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 40360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Render output like fprintf(). This should not be used on anything that 40460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** includes string formatting (e.g. "%s"). 40560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 40660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if !defined(raw_printf) 40760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# define raw_printf fprintf 40860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 40960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 41060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 4117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Write I/O traces to the following stream. 4127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 4137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_ENABLE_IOTRACE 4147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic FILE *iotrace = 0; 4157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 4167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 4177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 4187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This routine works like printf in that its first argument is a 4197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** format string and subsequent arguments are values to be substituted 4207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** in place of % fields. The result of formatting this string 4217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is written to iotrace. 4227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 4237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_ENABLE_IOTRACE 4243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ 4257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project va_list ap; 4267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *z; 4277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( iotrace==0 ) return; 4287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project va_start(ap, zFormat); 4297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z = sqlite3_vmprintf(zFormat, ap); 4307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project va_end(ap); 43160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(iotrace, "%s", z); 4327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_free(z); 4337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 4347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 4357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 436b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis/* 437b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** Output string zUtf to stream pOut as w characters. If w is negative, 438b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** then right-justify the text. W is the width in UTF-8 characters, not 439b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** in bytes. This is different from the %*.*s specification in printf 440b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** since with %*.*s the width is measured in bytes, not characters. 441b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis*/ 442b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidisstatic void utf8_width_print(FILE *pOut, int w, const char *zUtf){ 443b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis int i; 444b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis int n; 445b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis int aw = w<0 ? -w : w; 446b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis char zBuf[1000]; 447b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3; 448b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis for(i=n=0; zUtf[i]; i++){ 449b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( (zUtf[i]&0xc0)!=0x80 ){ 450b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis n++; 451b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( n==aw ){ 452b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis do{ i++; }while( (zUtf[i]&0xc0)==0x80 ); 453b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis break; 454b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 455b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 456b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 457b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( n>=aw ){ 458b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(pOut, "%.*s", i, zUtf); 459b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else if( w<0 ){ 460b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(pOut, "%*s%s", aw-n, "", zUtf); 461b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else{ 462b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(pOut, "%s%*s", zUtf, aw-n, ""); 463b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 464b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis} 465b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis 4667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 4677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 4687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Determines if a string is a number of not. 4697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 4707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int isNumber(const char *z, int *realnum){ 4717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( *z=='-' || *z=='+' ) z++; 47290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( !IsDigit(*z) ){ 4737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 4747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 4757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z++; 4767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( realnum ) *realnum = 0; 47790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown while( IsDigit(*z) ){ z++; } 4787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( *z=='.' ){ 4797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z++; 48090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( !IsDigit(*z) ) return 0; 48190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown while( IsDigit(*z) ){ z++; } 4827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( realnum ) *realnum = 1; 4837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 4847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( *z=='e' || *z=='E' ){ 4857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z++; 4867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( *z=='+' || *z=='-' ) z++; 48790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( !IsDigit(*z) ) return 0; 48890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown while( IsDigit(*z) ){ z++; } 4897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( realnum ) *realnum = 1; 4907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 4917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return *z==0; 4927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 4937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 4947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 49560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Compute a string length that is limited to what can be stored in 49660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** lower 30 bits of a 32-bit signed integer. 49760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 49860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic int strlen30(const char *z){ 49960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *z2 = z; 50060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis while( *z2 ){ z2++; } 50160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return 0x3fffffff & (int)(z2 - z); 50260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 50360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 50460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 5057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This routine reads a line of text from FILE in, stores 5067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the text in memory obtained from malloc() and returns a pointer 5077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** to the text. NULL is returned at end of file, or if malloc() 5087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** fails. 5097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 5108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** If zLine is not NULL then it is a malloced buffer returned from 5118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** a previous call to this routine that may be reused. 5127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 5138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic char *local_getline(char *zLine, FILE *in){ 5148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nLine = zLine==0 ? 0 : 100; 5158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int n = 0; 5167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 51790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown while( 1 ){ 5187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( n+100>nLine ){ 5197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project nLine = nLine*2 + 100; 5207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zLine = realloc(zLine, nLine); 5217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zLine==0 ) return 0; 5227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 5237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( fgets(&zLine[n], nLine - n, in)==0 ){ 5247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( n==0 ){ 5257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project free(zLine); 5267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 5277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 5287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zLine[n] = 0; 5297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 5307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 5318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( zLine[n] ) n++; 5328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( n>0 && zLine[n-1]=='\n' ){ 5337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project n--; 534a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( n>0 && zLine[n-1]=='\r' ) n--; 5357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zLine[n] = 0; 53690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown break; 5377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 5387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 53960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(_WIN32) || defined(WIN32) 54060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* For interactive input on Windows systems, translate the 54160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** multi-byte characterset characters into UTF-8. */ 54208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( stdin_is_interactive && in==stdin ){ 54360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); 54460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( zTrans ){ 54560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int nTrans = strlen30(zTrans)+1; 54660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nTrans>nLine ){ 54760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis zLine = realloc(zLine, nTrans); 54860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( zLine==0 ){ 54960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(zTrans); 55060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return 0; 55160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 55260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 55360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis memcpy(zLine, zTrans, nTrans); 55460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(zTrans); 55560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 55660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 55760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif /* defined(_WIN32) || defined(WIN32) */ 5587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return zLine; 5597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 5607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 5617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 5627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Retrieve a single line of input text. 5637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 5648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** If in==0 then read from standard input and prompt before each line. 5658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** If isContinuation is true, then a continuation prompt is appropriate. 5668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** If isContinuation is zero, then the main prompt should be used. 5678fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** 5688fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** If zPrior is not NULL then it is a buffer from a prior call to this 5698fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** routine that can be reused. 5708fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** 5718fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** The result is stored in space obtained from malloc() and must either 5728fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** be freed by the caller or else passed back into this routine via the 5738fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** zPrior argument for reuse. 5747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 5758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic char *one_input_line(FILE *in, char *zPrior, int isContinuation){ 5767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zPrompt; 5777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zResult; 5787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( in!=0 ){ 5798fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zResult = local_getline(zPrior, in); 5807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 5818fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zPrompt = isContinuation ? continuePrompt : mainPrompt; 5823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if SHELL_USE_LOCAL_GETLINE 5838fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("%s", zPrompt); 5848fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich fflush(stdout); 5858fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zResult = local_getline(zPrior, stdin); 5863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#else 5873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich free(zPrior); 5883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich zResult = shell_readline(zPrompt); 5893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( zResult && *zResult ) shell_add_history(zResult); 5907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 5918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 5927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return zResult; 5937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 594b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 595b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** A variable length string to which one can append text. 596b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 597b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidistypedef struct ShellText ShellText; 598b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstruct ShellText { 599b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *z; 600b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int n; 601b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nAlloc; 602b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis}; 603b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 604b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 605b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Initialize and destroy a ShellText object 606b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 607b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void initText(ShellText *p){ 608b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis memset(p, 0, sizeof(*p)); 609b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 610b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void freeText(ShellText *p){ 611b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis free(p->z); 612b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis initText(p); 613b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 614b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 615b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* zIn is either a pointer to a NULL-terminated string in memory obtained 616b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** from malloc(), or a NULL pointer. The string pointed to by zAppend is 617b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** added to zIn, and the result returned in memory obtained from malloc(). 618b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** zIn, if it was not NULL, is freed. 619b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 620b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** If the third argument, quote, is not '\0', then it is used as a 621b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** quote character for zAppend. 622b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 623b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void appendText(ShellText *p, char const *zAppend, char quote){ 624b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int len; 625b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; 626b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nAppend = strlen30(zAppend); 627b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 628b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis len = nAppend+p->n+1; 629b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( quote ){ 630b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis len += 2; 631b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=0; i<nAppend; i++){ 632b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( zAppend[i]==quote ) len++; 633b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 634b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 635b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 636b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( p->n+len>=p->nAlloc ){ 637b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nAlloc = p->nAlloc*2 + len + 20; 638b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->z = realloc(p->z, p->nAlloc); 639b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( p->z==0 ){ 640b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis memset(p, 0, sizeof(*p)); 641b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return; 642b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 643b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 644b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 645b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( quote ){ 646b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zCsr = p->z+p->n; 647b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis *zCsr++ = quote; 648b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=0; i<nAppend; i++){ 649b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis *zCsr++ = zAppend[i]; 650b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( zAppend[i]==quote ) *zCsr++ = quote; 651b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 652b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis *zCsr++ = quote; 653b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->n = (int)(zCsr - p->z); 654b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis *zCsr = '\0'; 655b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 656b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis memcpy(p->z+p->n, zAppend, nAppend); 657b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->n += nAppend; 658b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->z[p->n] = '\0'; 659b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 660b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 661b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 662b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 663b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Attempt to determine if identifier zName needs to be quoted, either 664b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** because it contains non-alphanumeric characters, or because it is an 665b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** SQLite keyword. Be conservative in this estimate: When in doubt assume 666b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** that quoting is required. 667b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 668b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Return '"' if quoting is required. Return 0 if no quoting is required. 669b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 670b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic char quoteChar(const char *zName){ 671b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* All SQLite keywords, in alphabetical order */ 672b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis static const char *azKeywords[] = { 673b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", 674b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", 675b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", 676b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", 677b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", 678b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", 679b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", 680b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", 681b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", 682b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", 683b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", 684b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", 685b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", 686b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", 687b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", 688b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", 689b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", 690b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "WITH", "WITHOUT", 691b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }; 692b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i, lwr, upr, mid, c; 693b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; 694b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=0; zName[i]; i++){ 695b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; 696b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 697b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis lwr = 0; 698b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; 699b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis while( lwr<=upr ){ 700b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis mid = (lwr+upr)/2; 701b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis c = sqlite3_stricmp(azKeywords[mid], zName); 702b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( c==0 ) return '"'; 703b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( c<0 ){ 704b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis lwr = mid+1; 705b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 706b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis upr = mid-1; 707b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 708b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 709b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return 0; 710b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 711b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 712b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/****************************************************************************** 713b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** SHA3 hash implementation copied from ../ext/misc/shathree.c 714b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 715b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidistypedef sqlite3_uint64 u64; 716b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 717b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Macros to determine whether the machine is big or little endian, 718b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** and whether or not that determination is run-time or compile-time. 719b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 720b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** For best performance, an attempt is made to guess at the byte-order 721b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** using C-preprocessor macros. If that is unsuccessful, or if 722b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** -DSHA3_BYTEORDER=0 is set, then byte-order is determined 723b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** at run-time. 724b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 725b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#ifndef SHA3_BYTEORDER 726b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ 727b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ 728b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ 729b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis defined(__arm__) 730b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define SHA3_BYTEORDER 1234 731b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# elif defined(sparc) || defined(__ppc__) 732b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define SHA3_BYTEORDER 4321 733b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# else 734b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define SHA3_BYTEORDER 0 735b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# endif 736b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#endif 737b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 738b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 739b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 740b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** State structure for a SHA3 hash in progress 741b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 742b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidistypedef struct SHA3Context SHA3Context; 743b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstruct SHA3Context { 744b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis union { 745b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ 746b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned char x[1600]; /* ... or 1600 bytes */ 747b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } u; 748b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned nRate; /* Bytes of input accepted per Keccak iteration */ 749b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ 750b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ 751b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis}; 752b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 753b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis/* Allow the following routine to use the B0 variable, which is also 754b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** a macro in the termios.h header file */ 755b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis#undef B0 756b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis 757b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 758b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** A single step of the Keccak mixing function for a 1600-bit state 759b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 760b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void KeccakF1600Step(SHA3Context *p){ 761b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; 762b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis u64 B0, B1, B2, B3, B4; 763b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis u64 C0, C1, C2, C3, C4; 764b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis u64 D0, D1, D2, D3, D4; 765b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis static const u64 RC[] = { 766b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x0000000000000001ULL, 0x0000000000008082ULL, 767b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x800000000000808aULL, 0x8000000080008000ULL, 768b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x000000000000808bULL, 0x0000000080000001ULL, 769b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x8000000080008081ULL, 0x8000000000008009ULL, 770b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x000000000000008aULL, 0x0000000000000088ULL, 771b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x0000000080008009ULL, 0x000000008000000aULL, 772b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x000000008000808bULL, 0x800000000000008bULL, 773b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x8000000000008089ULL, 0x8000000000008003ULL, 774b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x8000000000008002ULL, 0x8000000000000080ULL, 775b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x000000000000800aULL, 0x800000008000000aULL, 776b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x8000000080008081ULL, 0x8000000000008080ULL, 777b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0x0000000080000001ULL, 0x8000000080008008ULL 778b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }; 779b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A00 (p->u.s[0]) 780b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A01 (p->u.s[1]) 781b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A02 (p->u.s[2]) 782b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A03 (p->u.s[3]) 783b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A04 (p->u.s[4]) 784b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A10 (p->u.s[5]) 785b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A11 (p->u.s[6]) 786b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A12 (p->u.s[7]) 787b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A13 (p->u.s[8]) 788b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A14 (p->u.s[9]) 789b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A20 (p->u.s[10]) 790b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A21 (p->u.s[11]) 791b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A22 (p->u.s[12]) 792b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A23 (p->u.s[13]) 793b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A24 (p->u.s[14]) 794b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A30 (p->u.s[15]) 795b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A31 (p->u.s[16]) 796b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A32 (p->u.s[17]) 797b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A33 (p->u.s[18]) 798b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A34 (p->u.s[19]) 799b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A40 (p->u.s[20]) 800b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A41 (p->u.s[21]) 801b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A42 (p->u.s[22]) 802b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A43 (p->u.s[23]) 803b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define A44 (p->u.s[24]) 804b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis# define ROL64(a,x) ((a<<x)|(a>>(64-x))) 805b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 806b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=0; i<24; i+=4){ 807b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C0 = A00^A10^A20^A30^A40; 808b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C1 = A01^A11^A21^A31^A41; 809b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C2 = A02^A12^A22^A32^A42; 810b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C3 = A03^A13^A23^A33^A43; 811b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C4 = A04^A14^A24^A34^A44; 812b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D0 = C4^ROL64(C1, 1); 813b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D1 = C0^ROL64(C2, 1); 814b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D2 = C1^ROL64(C3, 1); 815b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D3 = C2^ROL64(C4, 1); 816b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D4 = C3^ROL64(C0, 1); 817b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 818b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = (A00^D0); 819b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A11^D1), 44); 820b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A22^D2), 43); 821b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A33^D3), 21); 822b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A44^D4), 14); 823b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A00 = B0 ^((~B1)& B2 ); 824b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A00 ^= RC[i]; 825b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A11 = B1 ^((~B2)& B3 ); 826b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A22 = B2 ^((~B3)& B4 ); 827b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A33 = B3 ^((~B4)& B0 ); 828b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A44 = B4 ^((~B0)& B1 ); 829b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 830b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A20^D0), 3); 831b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A31^D1), 45); 832b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A42^D2), 61); 833b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A03^D3), 28); 834b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A14^D4), 20); 835b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A20 = B0 ^((~B1)& B2 ); 836b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A31 = B1 ^((~B2)& B3 ); 837b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A42 = B2 ^((~B3)& B4 ); 838b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A03 = B3 ^((~B4)& B0 ); 839b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A14 = B4 ^((~B0)& B1 ); 840b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 841b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A40^D0), 18); 842b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A01^D1), 1); 843b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A12^D2), 6); 844b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A23^D3), 25); 845b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A34^D4), 8); 846b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A40 = B0 ^((~B1)& B2 ); 847b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A01 = B1 ^((~B2)& B3 ); 848b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A12 = B2 ^((~B3)& B4 ); 849b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A23 = B3 ^((~B4)& B0 ); 850b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A34 = B4 ^((~B0)& B1 ); 851b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 852b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A10^D0), 36); 853b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A21^D1), 10); 854b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A32^D2), 15); 855b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A43^D3), 56); 856b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A04^D4), 27); 857b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A10 = B0 ^((~B1)& B2 ); 858b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A21 = B1 ^((~B2)& B3 ); 859b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A32 = B2 ^((~B3)& B4 ); 860b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A43 = B3 ^((~B4)& B0 ); 861b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A04 = B4 ^((~B0)& B1 ); 862b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 863b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A30^D0), 41); 864b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A41^D1), 2); 865b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A02^D2), 62); 866b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A13^D3), 55); 867b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A24^D4), 39); 868b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A30 = B0 ^((~B1)& B2 ); 869b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A41 = B1 ^((~B2)& B3 ); 870b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A02 = B2 ^((~B3)& B4 ); 871b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A13 = B3 ^((~B4)& B0 ); 872b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A24 = B4 ^((~B0)& B1 ); 873b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 874b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C0 = A00^A20^A40^A10^A30; 875b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C1 = A11^A31^A01^A21^A41; 876b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C2 = A22^A42^A12^A32^A02; 877b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C3 = A33^A03^A23^A43^A13; 878b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C4 = A44^A14^A34^A04^A24; 879b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D0 = C4^ROL64(C1, 1); 880b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D1 = C0^ROL64(C2, 1); 881b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D2 = C1^ROL64(C3, 1); 882b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D3 = C2^ROL64(C4, 1); 883b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D4 = C3^ROL64(C0, 1); 884b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 885b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = (A00^D0); 886b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A31^D1), 44); 887b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A12^D2), 43); 888b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A43^D3), 21); 889b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A24^D4), 14); 890b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A00 = B0 ^((~B1)& B2 ); 891b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A00 ^= RC[i+1]; 892b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A31 = B1 ^((~B2)& B3 ); 893b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A12 = B2 ^((~B3)& B4 ); 894b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A43 = B3 ^((~B4)& B0 ); 895b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A24 = B4 ^((~B0)& B1 ); 896b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 897b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A40^D0), 3); 898b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A21^D1), 45); 899b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A02^D2), 61); 900b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A33^D3), 28); 901b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A14^D4), 20); 902b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A40 = B0 ^((~B1)& B2 ); 903b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A21 = B1 ^((~B2)& B3 ); 904b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A02 = B2 ^((~B3)& B4 ); 905b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A33 = B3 ^((~B4)& B0 ); 906b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A14 = B4 ^((~B0)& B1 ); 907b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 908b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A30^D0), 18); 909b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A11^D1), 1); 910b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A42^D2), 6); 911b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A23^D3), 25); 912b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A04^D4), 8); 913b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A30 = B0 ^((~B1)& B2 ); 914b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A11 = B1 ^((~B2)& B3 ); 915b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A42 = B2 ^((~B3)& B4 ); 916b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A23 = B3 ^((~B4)& B0 ); 917b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A04 = B4 ^((~B0)& B1 ); 918b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 919b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A20^D0), 36); 920b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A01^D1), 10); 921b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A32^D2), 15); 922b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A13^D3), 56); 923b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A44^D4), 27); 924b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A20 = B0 ^((~B1)& B2 ); 925b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A01 = B1 ^((~B2)& B3 ); 926b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A32 = B2 ^((~B3)& B4 ); 927b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A13 = B3 ^((~B4)& B0 ); 928b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A44 = B4 ^((~B0)& B1 ); 929b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 930b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A10^D0), 41); 931b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A41^D1), 2); 932b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A22^D2), 62); 933b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A03^D3), 55); 934b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A34^D4), 39); 935b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A10 = B0 ^((~B1)& B2 ); 936b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A41 = B1 ^((~B2)& B3 ); 937b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A22 = B2 ^((~B3)& B4 ); 938b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A03 = B3 ^((~B4)& B0 ); 939b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A34 = B4 ^((~B0)& B1 ); 940b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 941b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C0 = A00^A40^A30^A20^A10; 942b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C1 = A31^A21^A11^A01^A41; 943b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C2 = A12^A02^A42^A32^A22; 944b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C3 = A43^A33^A23^A13^A03; 945b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C4 = A24^A14^A04^A44^A34; 946b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D0 = C4^ROL64(C1, 1); 947b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D1 = C0^ROL64(C2, 1); 948b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D2 = C1^ROL64(C3, 1); 949b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D3 = C2^ROL64(C4, 1); 950b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D4 = C3^ROL64(C0, 1); 951b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 952b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = (A00^D0); 953b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A21^D1), 44); 954b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A42^D2), 43); 955b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A13^D3), 21); 956b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A34^D4), 14); 957b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A00 = B0 ^((~B1)& B2 ); 958b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A00 ^= RC[i+2]; 959b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A21 = B1 ^((~B2)& B3 ); 960b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A42 = B2 ^((~B3)& B4 ); 961b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A13 = B3 ^((~B4)& B0 ); 962b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A34 = B4 ^((~B0)& B1 ); 963b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 964b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A30^D0), 3); 965b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A01^D1), 45); 966b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A22^D2), 61); 967b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A43^D3), 28); 968b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A14^D4), 20); 969b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A30 = B0 ^((~B1)& B2 ); 970b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A01 = B1 ^((~B2)& B3 ); 971b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A22 = B2 ^((~B3)& B4 ); 972b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A43 = B3 ^((~B4)& B0 ); 973b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A14 = B4 ^((~B0)& B1 ); 974b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 975b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A10^D0), 18); 976b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A31^D1), 1); 977b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A02^D2), 6); 978b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A23^D3), 25); 979b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A44^D4), 8); 980b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A10 = B0 ^((~B1)& B2 ); 981b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A31 = B1 ^((~B2)& B3 ); 982b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A02 = B2 ^((~B3)& B4 ); 983b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A23 = B3 ^((~B4)& B0 ); 984b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A44 = B4 ^((~B0)& B1 ); 985b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 986b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A40^D0), 36); 987b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A11^D1), 10); 988b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A32^D2), 15); 989b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A03^D3), 56); 990b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A24^D4), 27); 991b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A40 = B0 ^((~B1)& B2 ); 992b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A11 = B1 ^((~B2)& B3 ); 993b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A32 = B2 ^((~B3)& B4 ); 994b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A03 = B3 ^((~B4)& B0 ); 995b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A24 = B4 ^((~B0)& B1 ); 996b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 997b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A20^D0), 41); 998b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A41^D1), 2); 999b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A12^D2), 62); 1000b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A33^D3), 55); 1001b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A04^D4), 39); 1002b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A20 = B0 ^((~B1)& B2 ); 1003b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A41 = B1 ^((~B2)& B3 ); 1004b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A12 = B2 ^((~B3)& B4 ); 1005b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A33 = B3 ^((~B4)& B0 ); 1006b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A04 = B4 ^((~B0)& B1 ); 1007b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1008b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C0 = A00^A30^A10^A40^A20; 1009b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C1 = A21^A01^A31^A11^A41; 1010b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C2 = A42^A22^A02^A32^A12; 1011b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C3 = A13^A43^A23^A03^A33; 1012b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis C4 = A34^A14^A44^A24^A04; 1013b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D0 = C4^ROL64(C1, 1); 1014b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D1 = C0^ROL64(C2, 1); 1015b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D2 = C1^ROL64(C3, 1); 1016b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D3 = C2^ROL64(C4, 1); 1017b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis D4 = C3^ROL64(C0, 1); 1018b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1019b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = (A00^D0); 1020b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A01^D1), 44); 1021b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A02^D2), 43); 1022b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A03^D3), 21); 1023b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A04^D4), 14); 1024b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A00 = B0 ^((~B1)& B2 ); 1025b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A00 ^= RC[i+3]; 1026b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A01 = B1 ^((~B2)& B3 ); 1027b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A02 = B2 ^((~B3)& B4 ); 1028b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A03 = B3 ^((~B4)& B0 ); 1029b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A04 = B4 ^((~B0)& B1 ); 1030b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1031b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A10^D0), 3); 1032b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A11^D1), 45); 1033b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A12^D2), 61); 1034b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A13^D3), 28); 1035b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A14^D4), 20); 1036b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A10 = B0 ^((~B1)& B2 ); 1037b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A11 = B1 ^((~B2)& B3 ); 1038b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A12 = B2 ^((~B3)& B4 ); 1039b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A13 = B3 ^((~B4)& B0 ); 1040b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A14 = B4 ^((~B0)& B1 ); 1041b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1042b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A20^D0), 18); 1043b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A21^D1), 1); 1044b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A22^D2), 6); 1045b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A23^D3), 25); 1046b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A24^D4), 8); 1047b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A20 = B0 ^((~B1)& B2 ); 1048b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A21 = B1 ^((~B2)& B3 ); 1049b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A22 = B2 ^((~B3)& B4 ); 1050b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A23 = B3 ^((~B4)& B0 ); 1051b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A24 = B4 ^((~B0)& B1 ); 1052b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1053b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A30^D0), 36); 1054b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A31^D1), 10); 1055b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A32^D2), 15); 1056b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A33^D3), 56); 1057b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A34^D4), 27); 1058b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A30 = B0 ^((~B1)& B2 ); 1059b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A31 = B1 ^((~B2)& B3 ); 1060b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A32 = B2 ^((~B3)& B4 ); 1061b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A33 = B3 ^((~B4)& B0 ); 1062b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A34 = B4 ^((~B0)& B1 ); 1063b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1064b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B3 = ROL64((A40^D0), 41); 1065b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B4 = ROL64((A41^D1), 2); 1066b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B0 = ROL64((A42^D2), 62); 1067b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B1 = ROL64((A43^D3), 55); 1068b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis B2 = ROL64((A44^D4), 39); 1069b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A40 = B0 ^((~B1)& B2 ); 1070b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A41 = B1 ^((~B2)& B3 ); 1071b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A42 = B2 ^((~B3)& B4 ); 1072b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A43 = B3 ^((~B4)& B0 ); 1073b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis A44 = B4 ^((~B0)& B1 ); 1074b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1075b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 1076b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1077b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 1078b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Initialize a new hash. iSize determines the size of the hash 1079b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** in bits and should be one of 224, 256, 384, or 512. Or iSize 1080b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** can be zero to use the default hash size of 256 bits. 1081b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 1082b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void SHA3Init(SHA3Context *p, int iSize){ 1083b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis memset(p, 0, sizeof(*p)); 1084b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( iSize>=128 && iSize<=512 ){ 1085b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; 1086b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 1087b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nRate = (1600 - 2*256)/8; 1088b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1089b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#if SHA3_BYTEORDER==1234 1090b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* Known to be little-endian at compile-time. No-op */ 1091b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#elif SHA3_BYTEORDER==4321 1092b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->ixMask = 7; /* Big-endian */ 1093b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#else 1094b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis { 1095b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis static unsigned int one = 1; 1096b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( 1==*(unsigned char*)&one ){ 1097b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* Little endian. No byte swapping. */ 1098b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->ixMask = 0; 1099b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 1100b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* Big endian. Byte swap. */ 1101b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->ixMask = 7; 1102b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1103b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1104b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#endif 1105b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 1106b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1107b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 1108b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Make consecutive calls to the SHA3Update function to add new content 1109b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** to the hash 1110b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 1111b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void SHA3Update( 1112b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Context *p, 1113b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const unsigned char *aData, 1114b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned int nData 1115b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis){ 1116b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned int i = 0; 1117b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#if SHA3_BYTEORDER==1234 1118b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ 1119b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(; i+7<nData; i+=8){ 1120b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; 1121b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nLoaded += 8; 1122b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( p->nLoaded>=p->nRate ){ 1123b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis KeccakF1600Step(p); 1124b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nLoaded = 0; 1125b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1126b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1127b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1128b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#endif 1129b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(; i<nData; i++){ 1130b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#if SHA3_BYTEORDER==1234 1131b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->u.x[p->nLoaded] ^= aData[i]; 1132b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#elif SHA3_BYTEORDER==4321 1133b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->u.x[p->nLoaded^0x07] ^= aData[i]; 1134b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#else 1135b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; 1136b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#endif 1137b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nLoaded++; 1138b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( p->nLoaded==p->nRate ){ 1139b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis KeccakF1600Step(p); 1140b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nLoaded = 0; 1141b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1142b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1143b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 1144b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1145b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 1146b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** After all content has been added, invoke SHA3Final() to compute 1147b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** the final hash. The function returns a pointer to the binary 1148b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** hash value. 1149b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 1150b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic unsigned char *SHA3Final(SHA3Context *p){ 1151b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned int i; 1152b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( p->nLoaded==p->nRate-1 ){ 1153b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const unsigned char c1 = 0x86; 1154b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(p, &c1, 1); 1155b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 1156b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const unsigned char c2 = 0x06; 1157b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const unsigned char c3 = 0x80; 1158b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(p, &c2, 1); 1159b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nLoaded = p->nRate - 1; 1160b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(p, &c3, 1); 1161b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1162b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=0; i<p->nRate; i++){ 1163b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; 1164b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1165b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return &p->u.x[p->nRate]; 1166b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 1167b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1168b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 1169b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Implementation of the sha3(X,SIZE) function. 1170b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 1171b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default 1172b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** size is 256. If X is a BLOB, it is hashed as is. 1173b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** For all other non-NULL types of input, X is converted into a UTF-8 string 1174b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** and the string is hashed without the trailing 0x00 terminator. The hash 1175b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** of a NULL value is NULL. 1176b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 1177b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void sha3Func( 1178b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_context *context, 1179b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int argc, 1180b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_value **argv 1181b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis){ 1182b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Context cx; 1183b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int eType = sqlite3_value_type(argv[0]); 1184b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nByte = sqlite3_value_bytes(argv[0]); 1185b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int iSize; 1186b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( argc==1 ){ 1187b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis iSize = 256; 1188b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 1189b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis iSize = sqlite3_value_int(argv[1]); 1190b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ 1191b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " 1192b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "384 512", -1); 1193b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return; 1194b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1195b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1196b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( eType==SQLITE_NULL ) return; 1197b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Init(&cx, iSize); 1198b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( eType==SQLITE_BLOB ){ 1199b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte); 1200b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 1201b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte); 1202b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1203b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); 1204b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 1205b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1206b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* Compute a string using sqlite3_vsnprintf() with a maximum length 1207b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** of 50 bytes and add it to the hash. 1208b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 1209b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void hash_step_vformat( 1210b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Context *p, /* Add content to this context */ 1211b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *zFormat, 1212b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ... 1213b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis){ 1214b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis va_list ap; 1215b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int n; 1216b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char zBuf[50]; 1217b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis va_start(ap, zFormat); 1218b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); 1219b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis va_end(ap); 1220b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis n = (int)strlen(zBuf); 1221b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(p, (unsigned char*)zBuf, n); 1222b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 1223b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1224b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 1225b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Implementation of the sha3_query(SQL,SIZE) function. 1226b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 1227b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** This function compiles and runs the SQL statement(s) given in the 1228b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** argument. The results are hashed using a SIZE-bit SHA3. The default 1229b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** size is 256. 1230b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 1231b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** The format of the byte stream that is hashed is summarized as follows: 1232b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 1233b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** S<n>:<sql> 1234b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** R 1235b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** N 1236b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** I<int> 1237b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** F<ieee-float> 1238b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** B<size>:<bytes> 1239b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** T<size>:<text> 1240b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 1241b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** <sql> is the original SQL text for each statement run and <n> is 1242b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** the size of that text. The SQL text is UTF-8. A single R character 1243b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** occurs before the start of each row. N means a NULL value. 1244b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** I mean an 8-byte little-endian integer <int>. F is a floating point 1245b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** number with an 8-byte little-endian IEEE floating point value <ieee-float>. 1246b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** B means blobs of <size> bytes. T means text rendered as <size> 1247b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII 1248b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** text integers. 1249b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 1250b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** For each SQL statement in the X input, there is one S segment. Each 1251b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** S segment is followed by zero or more R segments, one for each row in the 1252b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** result set. After each R, there are one or more N, I, F, B, or T segments, 1253b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** one for each column in the result set. Segments are concatentated directly 1254b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** with no delimiters of any kind. 1255b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 1256b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void sha3QueryFunc( 1257b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_context *context, 1258b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int argc, 1259b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_value **argv 1260b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis){ 1261b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3 *db = sqlite3_context_db_handle(context); 1262b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *zSql = (const char*)sqlite3_value_text(argv[0]); 1263b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_stmt *pStmt = 0; 1264b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nCol; /* Number of columns in the result set */ 1265b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; /* Loop counter */ 1266b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int rc; 1267b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int n; 1268b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *z; 1269b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Context cx; 1270b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int iSize; 1271b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1272b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( argc==1 ){ 1273b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis iSize = 256; 1274b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 1275b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis iSize = sqlite3_value_int(argv[1]); 1276b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ 1277b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " 1278b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "384 512", -1); 1279b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return; 1280b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1281b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1282b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( zSql==0 ) return; 1283b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Init(&cx, iSize); 1284b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis while( zSql[0] ){ 1285b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); 1286b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( rc ){ 1287b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", 1288b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql, sqlite3_errmsg(db)); 1289b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_finalize(pStmt); 1290b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_result_error(context, zMsg, -1); 1291b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zMsg); 1292b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return; 1293b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1294b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( !sqlite3_stmt_readonly(pStmt) ){ 1295b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); 1296b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_finalize(pStmt); 1297b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_result_error(context, zMsg, -1); 1298b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zMsg); 1299b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return; 1300b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1301b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis nCol = sqlite3_column_count(pStmt); 1302b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis z = sqlite3_sql(pStmt); 1303b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( z==0 ){ 1304b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_finalize(pStmt); 1305b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis continue; 1306b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1307b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis n = (int)strlen(z); 1308b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis hash_step_vformat(&cx,"S%d:",n); 1309b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx,(unsigned char*)z,n); 1310b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1311b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* Compute a hash over the result of the query */ 1312b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis while( SQLITE_ROW==sqlite3_step(pStmt) ){ 1313b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx,(const unsigned char*)"R",1); 1314b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=0; i<nCol; i++){ 1315b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis switch( sqlite3_column_type(pStmt,i) ){ 1316b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis case SQLITE_NULL: { 1317b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx, (const unsigned char*)"N",1); 1318b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis break; 1319b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1320b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis case SQLITE_INTEGER: { 1321b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_uint64 u; 1322b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int j; 1323b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned char x[9]; 1324b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_int64 v = sqlite3_column_int64(pStmt,i); 1325b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis memcpy(&u, &v, 8); 1326b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(j=8; j>=1; j--){ 1327b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis x[j] = u & 0xff; 1328b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis u >>= 8; 1329b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1330b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis x[0] = 'I'; 1331b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx, x, 9); 1332b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis break; 1333b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1334b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis case SQLITE_FLOAT: { 1335b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_uint64 u; 1336b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int j; 1337b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis unsigned char x[9]; 1338b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis double r = sqlite3_column_double(pStmt,i); 1339b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis memcpy(&u, &r, 8); 1340b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(j=8; j>=1; j--){ 1341b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis x[j] = u & 0xff; 1342b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis u >>= 8; 1343b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1344b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis x[0] = 'F'; 1345b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx,x,9); 1346b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis break; 1347b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1348b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis case SQLITE_TEXT: { 1349b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int n2 = sqlite3_column_bytes(pStmt, i); 1350b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const unsigned char *z2 = sqlite3_column_text(pStmt, i); 1351b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis hash_step_vformat(&cx,"T%d:",n2); 1352b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx, z2, n2); 1353b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis break; 1354b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1355b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis case SQLITE_BLOB: { 1356b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int n2 = sqlite3_column_bytes(pStmt, i); 1357b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const unsigned char *z2 = sqlite3_column_blob(pStmt, i); 1358b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis hash_step_vformat(&cx,"B%d:",n2); 1359b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis SHA3Update(&cx, z2, n2); 1360b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis break; 1361b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1362b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1363b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1364b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1365b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_finalize(pStmt); 1366b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1367b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); 1368b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 1369b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* End of SHA3 hashing logic copy/pasted from ../ext/misc/shathree.c 1370b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis********************************************************************************/ 13717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 137260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_ENABLE_SESSION) 137360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 137460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** State information for a single open session 137560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 137660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidistypedef struct OpenSession OpenSession; 137760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstruct OpenSession { 137860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char *zName; /* Symbolic name for this session */ 137960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int nFilter; /* Number of xFilter rejection GLOB patterns */ 138060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char **azFilter; /* Array of xFilter rejection GLOB patterns */ 138160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_session *p; /* The open session */ 138260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis}; 138360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 138460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 13853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 138660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Shell output mode information from before ".explain on", 13873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** saved so that it can be restored by ".explain off" 13883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 13893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichtypedef struct SavedModeInfo SavedModeInfo; 13903fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstruct SavedModeInfo { 13913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int valid; /* Is there legit data in here? */ 13923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int mode; /* Mode prior to ".explain on" */ 13933fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int showHeader; /* The ".header" setting prior to ".explain on" */ 13943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int colWidth[100]; /* Column widths prior to ".explain on" */ 13957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}; 13967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 13977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 13983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** State information about the database connection is contained in an 13993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** instance of the following structure. 14007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 14013fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichtypedef struct ShellState ShellState; 14023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstruct ShellState { 1403a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3 *db; /* The database */ 140460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int autoExplain; /* Automatically turn on .explain mode */ 14051c7cea379348522163370244e8fbbff8a136b7faNick Kralevich int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ 1406de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori int statsOn; /* True to display memory stats before each finalize */ 14073fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int scanstatsOn; /* True to display scan stats before each finalize */ 14081c7cea379348522163370244e8fbbff8a136b7faNick Kralevich int outCount; /* Revert to stdout when reaching zero */ 14097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int cnt; /* Number of records displayed so far */ 14107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project FILE *out; /* Write results here */ 14118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich FILE *traceOut; /* Output for sqlite3_trace() */ 141290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown int nErr; /* Number of errors seen */ 14137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int mode; /* An output mode setting */ 141460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int cMode; /* temporary output mode for the current query */ 141560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int normalMode; /* Output mode before ".explain on" */ 14167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int writableSchema; /* True if PRAGMA writable_schema=ON */ 14177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int showHeader; /* True to show column names in List or Column mode */ 141808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis int nCheck; /* Number of ".check" commands run */ 14193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich unsigned shellFlgs; /* Various flags */ 14207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zDestTable; /* Name of destination table when MODE_Insert */ 142108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis char zTestcase[30]; /* Name of current test case */ 14223fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char colSeparator[20]; /* Column separator character for several modes */ 14233fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char rowSeparator[20]; /* Row separator character for MODE_Ascii */ 14247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int colWidth[100]; /* Requested width of each column when in column mode*/ 14257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int actualWidth[100]; /* Actual width of each column */ 14263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char nullValue[20]; /* The text to print when a NULL comes back from 14277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** the database */ 14287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char outfile[FILENAME_MAX]; /* Filename for *out */ 14297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project const char *zDbFilename; /* name of the database file */ 14308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zFreeOnClose; /* Filename to free when closing */ 143190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zVfs; /* Name of VFS to use */ 1432a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_stmt *pStmt; /* Current statement if any. */ 1433aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori FILE *pLog; /* Write log output here */ 14348fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int *aiIndent; /* Array of indents used in MODE_Explain */ 14358fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nIndent; /* Size of array aiIndent[] */ 14368fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int iIndent; /* Index of current op in aiIndent[] */ 143760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_ENABLE_SESSION) 143860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int nSession; /* Number of active sessions */ 143960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ 144060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 14417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}; 14427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 14437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 14443fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** These are the allowed shellFlgs values 14453fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 1446b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define SHFLG_Scratch 0x00000001 /* The --scratch option is used */ 1447b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define SHFLG_Pagecache 0x00000002 /* The --pagecache option is used */ 1448b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */ 1449b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define SHFLG_Backslash 0x00000008 /* The --backslash option is used */ 1450b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */ 1451b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define SHFLG_CountChanges 0x00000020 /* .changes setting */ 1452b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ 1453b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 1454b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 1455b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Macros for testing and setting shellFlgs 1456b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 1457b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0) 1458b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X)) 1459b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X))) 14603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 14613fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 14627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** These are the allowed modes. 14637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 14647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Line 0 /* One column per line. Blank line between records */ 14657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Column 1 /* One record per line in neat columns */ 14667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_List 2 /* One record per line with a separator */ 14677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ 14687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Html 4 /* Generate an XHTML table */ 14697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#define MODE_Insert 5 /* Generate SQL "insert" statements */ 1470e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#define MODE_Quote 6 /* Quote values as for SQL */ 1471e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */ 1472e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#define MODE_Csv 8 /* Quote strings, numbers are plain */ 1473e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ 1474e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ 1475e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#define MODE_Pretty 11 /* Pretty-print schemas */ 14767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 14777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic const char *modeDescr[] = { 14787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "line", 14797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "column", 14807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "list", 14817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "semi", 14827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "html", 14837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "insert", 1484e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "quote", 14857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "tcl", 14867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "csv", 14877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "explain", 14883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "ascii", 148960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "prettyprint", 14907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}; 14917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 14927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 14933fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** These are the column/row/line separators used by the various 14943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** import/export modes. 14953fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 14963fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define SEP_Column "|" 14973fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define SEP_Row "\n" 14983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define SEP_Tab "\t" 14993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define SEP_Space " " 15003fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define SEP_Comma "," 15013fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define SEP_CrLf "\r\n" 15023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define SEP_Unit "\x1F" 15033fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#define SEP_Record "\x1E" 15043fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 15053fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 15067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Number of elements in an array 15077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 1508a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) 1509a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 1510a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 1511aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori** A callback for the sqlite3_log() interface. 1512aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori*/ 1513aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Noristatic void shellLog(void *pArg, int iErrCode, const char *zMsg){ 15143fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *p = (ShellState*)pArg; 1515aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori if( p->pLog==0 ) return; 151660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg); 1517aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori fflush(p->pLog); 1518aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori} 1519aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori 1520aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori/* 1521a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Output the given string as a hex-encoded blob (eg. X'1234' ) 1522a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 1523a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ 1524a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int i; 1525a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori char *zBlob = (char *)pBlob; 152660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(out,"X'"); 152760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); } 152860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(out,"'"); 1529a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 15307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 15317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 1532b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** Find a string that is not found anywhere in z[]. Return a pointer 1533b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** to that string. 1534b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** 1535b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** Try to use zA and zB first. If both of those are already found in z[] 1536b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** then make up some string and store it in the buffer zBuf. 1537b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis*/ 1538b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidisstatic const char *unused_string( 1539b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis const char *z, /* Result must not appear anywhere in z */ 1540b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis const char *zA, const char *zB, /* Try these first */ 1541b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis char *zBuf /* Space to store a generated string */ 1542b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis){ 1543b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis unsigned i = 0; 1544b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( strstr(z, zA)==0 ) return zA; 1545b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( strstr(z, zB)==0 ) return zB; 1546b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis do{ 1547b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++); 1548b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }while( strstr(z,zBuf)!=0 ); 1549b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis return zBuf; 1550b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis} 1551b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis 1552b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis/* 15537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Output the given string as a quoted string using SQL quoting conventions. 1554b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 1555b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** See also: output_quoted_escaped_string() 15567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 15577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void output_quoted_string(FILE *out, const char *z){ 15587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i; 1559b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char c; 156060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis setBinaryMode(out, 1); 1561b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis for(i=0; (c = z[i])!=0 && c!='\''; i++){} 1562df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis if( c==0 ){ 1563df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis utf8_printf(out,"'%s'",z); 1564df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis }else{ 1565b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, "'"); 1566df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis while( *z ){ 1567b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis for(i=0; (c = z[i])!=0 && c!='\''; i++){} 1568df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis if( c=='\'' ) i++; 1569df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis if( i ){ 1570df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis utf8_printf(out, "%.*s", i, z); 1571df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis z += i; 1572df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis } 1573df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis if( c=='\'' ){ 1574b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(out, "'"); 1575df94a5ddeff8b445868ed01f841d7c279b93395fAlex Naidis continue; 1576b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1577b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( c==0 ){ 1578b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis break; 1579b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1580b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis z++; 1581b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1582b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, "'"); 1583b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1584b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis setTextMode(out, 1); 1585b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis} 1586b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis 1587b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis/* 1588b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** Output the given string as a quoted string using SQL quoting conventions. 1589b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** Additionallly , escape the "\n" and "\r" characters so that they do not 1590b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** get corrupted by end-of-line translation facilities in some operating 1591b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** systems. 1592b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** 1593b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** This is like output_quoted_string() but with the addition of the \r\n 1594b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis** escape mechanism. 1595b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis*/ 1596b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidisstatic void output_quoted_escaped_string(FILE *out, const char *z){ 1597b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis int i; 1598b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis char c; 1599b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis setBinaryMode(out, 1); 1600b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} 1601b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( c==0 ){ 1602b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(out,"'%s'",z); 1603b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else{ 1604b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis const char *zNL = 0; 1605b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis const char *zCR = 0; 1606b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis int nNL = 0; 1607b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis int nCR = 0; 1608b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis char zBuf1[20], zBuf2[20]; 1609b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis for(i=0; z[i]; i++){ 1610b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( z[i]=='\n' ) nNL++; 1611b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( z[i]=='\r' ) nCR++; 1612b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1613b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( nNL ){ 1614b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, "replace("); 1615b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis zNL = unused_string(z, "\\n", "\\012", zBuf1); 1616b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1617b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( nCR ){ 1618b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, "replace("); 1619b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis zCR = unused_string(z, "\\r", "\\015", zBuf2); 1620b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1621b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, "'"); 1622b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis while( *z ){ 1623b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} 1624b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( c=='\'' ) i++; 1625b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( i ){ 1626b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(out, "%.*s", i, z); 1627b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis z += i; 1628b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1629b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( c=='\'' ){ 1630474de9dc715b92c3c3d546da70d69fa3c2bd56b5Nick Kralevich raw_printf(out, "'"); 1631b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis continue; 1632474de9dc715b92c3c3d546da70d69fa3c2bd56b5Nick Kralevich } 1633b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( c==0 ){ 16347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 16357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 1636b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis z++; 1637b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( c=='\n' ){ 1638b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, "%s", zNL); 1639b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis continue; 1640b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 1641b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, "%s", zCR); 1642b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1643b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, "'"); 1644b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( nCR ){ 1645b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, ",'%s',char(13))", zCR); 1646b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 1647b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( nNL ){ 1648b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(out, ",'%s',char(10))", zNL); 16497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 16507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 165160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis setTextMode(out, 1); 16527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 16537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 16547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 16557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Output the given string as a quoted according to C or TCL quoting rules. 16567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 16577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void output_c_string(FILE *out, const char *z){ 16587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project unsigned int c; 16597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc('"', out); 16607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project while( (c = *(z++))!=0 ){ 16617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( c=='\\' ){ 16627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc(c, out); 16637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc(c, out); 16648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( c=='"' ){ 16658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich fputc('\\', out); 16668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich fputc('"', out); 16677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( c=='\t' ){ 16687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc('\\', out); 16697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc('t', out); 16707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( c=='\n' ){ 16717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc('\\', out); 16727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc('n', out); 16737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( c=='\r' ){ 16747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc('\\', out); 16757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc('r', out); 16768fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( !isprint(c&0xff) ){ 167760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(out, "\\%03o", c&0xff); 16787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 16797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc(c, out); 16807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 16817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 16827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fputc('"', out); 16837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 16847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 16857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 16867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Output the given string with characters that are special to 16877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** HTML escaped. 16887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 16897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void output_html_string(FILE *out, const char *z){ 16907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i; 16918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( z==0 ) z = ""; 16927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project while( *z ){ 169360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; z[i] 169460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis && z[i]!='<' 169560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis && z[i]!='&' 169660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis && z[i]!='>' 169760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis && z[i]!='\"' 1698a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori && z[i]!='\''; 1699a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori i++){} 17007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( i>0 ){ 170160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(out,"%.*s",i,z); 17027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( z[i]=='<' ){ 170460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(out,"<"); 17057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( z[i]=='&' ){ 170660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(out,"&"); 1707a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else if( z[i]=='>' ){ 170860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(out,">"); 1709a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else if( z[i]=='\"' ){ 171060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(out,"""); 1711a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else if( z[i]=='\'' ){ 171260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(out,"'"); 17137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 17147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 17157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z += i + 1; 17177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 17197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 17207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 17217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** If a field contains any character identified by a 1 in the following 17227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** array, then the string must be quoted for CSV. 17237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 17247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic const char needCsvQuote[] = { 172560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 172660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 172760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 172860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 173360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 173460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 173560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 173660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 173760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 173860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 173960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 174060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 17417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project}; 17427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 17437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 17443fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** Output a single term of CSV. Actually, p->colSeparator is used for 17453fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** the separator, which may or may not be a comma. p->nullValue is 17469bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** the null value. Strings are quoted if necessary. The separator 17479bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** is only issued if bSep is true. 17487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 17493fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void output_csv(ShellState *p, const char *z, int bSep){ 17507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project FILE *out = p->out; 17517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( z==0 ){ 175260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(out,"%s",p->nullValue); 17537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 17547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i; 17553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int nSep = strlen30(p->colSeparator); 17567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; z[i]; i++){ 175760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( needCsvQuote[((unsigned char*)z)[i]] 175860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis || (z[i]==p->colSeparator[0] && 17593fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){ 17607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project i = 0; 17617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 17627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( i==0 ){ 17657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project putc('"', out); 17667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; z[i]; i++){ 17677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( z[i]=='"' ) putc('"', out); 17687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project putc(z[i], out); 17697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project putc('"', out); 17717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 177260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(out, "%s", z); 17737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( bSep ){ 177660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->colSeparator); 17777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 17787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 17797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 17807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SIGINT 17817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 17827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This routine runs when the user presses Ctrl-C 17837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 17847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void interrupt_handler(int NotUsed){ 1785a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori UNUSED_PARAMETER(NotUsed); 17861c7cea379348522163370244e8fbbff8a136b7faNick Kralevich seenInterrupt++; 17871c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( seenInterrupt>2 ) exit(1); 17883a6c79f802fabdb94367177310663397420e319fNick Kralevich if( globalDb ) sqlite3_interrupt(globalDb); 17897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 17907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 17917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 179208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#ifndef SQLITE_OMIT_AUTHORIZATION 17937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 179460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** When the ".auth ON" is set, the following authorizer callback is 179560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** invoked. It always returns SQLITE_OK. 179660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 179760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic int shellAuth( 179860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis void *pClientData, 179960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int op, 180060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *zA1, 180160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *zA2, 180260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *zA3, 180360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *zA4 180460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis){ 180560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ShellState *p = (ShellState*)pClientData; 180660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis static const char *azAction[] = { 0, 180760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX", 180860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW", 180960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "CREATE_TRIGGER", "CREATE_VIEW", "DELETE", 181060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX", 181160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW", 181260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "DROP_TRIGGER", "DROP_VIEW", "INSERT", 181360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "PRAGMA", "READ", "SELECT", 181460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "TRANSACTION", "UPDATE", "ATTACH", 181560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "DETACH", "ALTER_TABLE", "REINDEX", 181660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE", 181760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "FUNCTION", "SAVEPOINT", "RECURSIVE" 181860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }; 181960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int i; 182060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *az[4]; 182160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis az[0] = zA1; 182260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis az[1] = zA2; 182360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis az[2] = zA3; 182460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis az[3] = zA4; 182508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis utf8_printf(p->out, "authorizer: %s", azAction[op]); 182660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<4; i++){ 182760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, " "); 182860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( az[i] ){ 182960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis output_c_string(p->out, az[i]); 183060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 183160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "NULL"); 183260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 183360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 183460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n"); 183560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return SQLITE_OK; 183660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 183708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#endif 183808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 1839e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani/* 1840e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** Print a schema statement. Part of MODE_Semi and MODE_Pretty output. 1841e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** 1842e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** This routine converts some CREATE TABLE statements for shadow tables 1843e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements. 1844e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani*/ 1845e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefanistatic void printSchemaLine(FILE *out, const char *z, const char *zTail){ 1846e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ 1847e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); 1848e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 1849e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani utf8_printf(out, "%s%s", z, zTail); 1850e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 1851e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani} 1852e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefanistatic void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ 1853e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char c = z[n]; 1854e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani z[n] = 0; 1855e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani printSchemaLine(out, z, zTail); 1856e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani z[n] = c; 1857e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani} 185860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 185960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 1860a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** This is the callback routine that the shell 18617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** invokes for each row of a query result. 18627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 18633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic int shell_callback( 18643fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich void *pArg, 18653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int nArg, /* Number of result columns */ 18663fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char **azArg, /* Text of each result column */ 18673fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char **azCol, /* Column names */ 18683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int *aiType /* Column types */ 18693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich){ 18707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i; 18713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *p = (ShellState*)pArg; 1872a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 187360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis switch( p->cMode ){ 18747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project case MODE_Line: { 18757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int w = 5; 18767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( azArg==0 ) break; 18777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 1878a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int len = strlen30(azCol[i] ? azCol[i] : ""); 18797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( len>w ) w = len; 18807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 188160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator); 18827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 188360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%*s = %s%s", w, azCol[i], 18843fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); 18857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 18867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 18877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 18887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project case MODE_Explain: 18897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project case MODE_Column: { 189060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13}; 189160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const int *colWidth; 189260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int showHdr; 189360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char *rowSep; 189460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->cMode==MODE_Column ){ 189560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis colWidth = p->colWidth; 189660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis showHdr = p->showHeader; 189760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rowSep = p->rowSeparator; 189860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 189960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis colWidth = aExplainWidths; 190060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis showHdr = 1; 190160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rowSep = SEP_Row; 190260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 19037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->cnt++==0 ){ 19047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 19057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int w, n; 19067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( i<ArraySize(p->colWidth) ){ 190760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis w = colWidth[i]; 19087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 19097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project w = 0; 19107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 19118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( w==0 ){ 1912a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori w = strlen30(azCol[i] ? azCol[i] : ""); 19137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( w<10 ) w = 10; 19143fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue); 19157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( w<n ) w = n; 19167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 19177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( i<ArraySize(p->actualWidth) ){ 19187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->actualWidth[i] = w; 19197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 192060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( showHdr ){ 1921b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_width_print(p->out, w, azCol[i]); 1922b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " "); 19237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 19247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 192560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( showHdr ){ 19267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 19277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int w; 19287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( i<ArraySize(p->actualWidth) ){ 19297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project w = p->actualWidth[i]; 19308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( w<0 ) w = -w; 19317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 19327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project w = 10; 19337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 193460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%-*.*s%s",w,w, 193560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "----------------------------------------------------------" 19367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "----------------------------------------------------------", 193760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis i==nArg-1 ? rowSep : " "); 19387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 19397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 19407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 19417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( azArg==0 ) break; 19427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 19437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int w; 19447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( i<ArraySize(p->actualWidth) ){ 19457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project w = p->actualWidth[i]; 19467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 19477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project w = 10; 19487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 194960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){ 1950a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori w = strlen30(azArg[i]); 19517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 19528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( i==1 && p->aiIndent && p->pStmt ){ 19538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( p->iIndent<p->nIndent ){ 195460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); 19558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 19568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->iIndent++; 19578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 1958b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue); 1959b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " "); 19607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 19617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 19627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 196360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case MODE_Semi: { /* .schema and .fullschema output */ 1964e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani printSchemaLine(p->out, azArg[0], ";\n"); 196560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis break; 196660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 196760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case MODE_Pretty: { /* .schema and .fullschema with --indent */ 196860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char *z; 196960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int j; 197060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int nParen = 0; 197160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char cEnd = 0; 197260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char c; 197360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int nLine = 0; 197460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis assert( nArg==1 ); 197560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( azArg[0]==0 ) break; 197660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 197760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 197860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ){ 197960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s;\n", azArg[0]); 198060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis break; 198160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 198260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis z = sqlite3_mprintf("%s", azArg[0]); 198360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis j = 0; 198460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; IsSpace(z[i]); i++){} 198560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(; (c = z[i])!=0; i++){ 198660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( IsSpace(c) ){ 198760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; 198860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ 198960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis j--; 199060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 199160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis z[j++] = c; 199260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 199360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis while( j>0 && IsSpace(z[j-1]) ){ j--; } 199460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis z[j] = 0; 199560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strlen30(z)>=79 ){ 199660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=j=0; (c = z[i])!=0; i++){ 199760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( c==cEnd ){ 199860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis cEnd = 0; 199960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( c=='"' || c=='\'' || c=='`' ){ 200060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis cEnd = c; 200160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( c=='[' ){ 200260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis cEnd = ']'; 200360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( c=='(' ){ 200460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis nParen++; 200560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( c==')' ){ 200660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis nParen--; 200760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nLine>0 && nParen==0 && j>0 ){ 2008e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani printSchemaLineN(p->out, z, j, "\n"); 200960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis j = 0; 201060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 201160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 201260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis z[j++] = c; 201360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nParen==1 && (c=='(' || c==',' || c=='\n') ){ 201460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( c=='\n' ) j--; 2015e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani printSchemaLineN(p->out, z, j, "\n "); 201660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis j = 0; 201760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis nLine++; 201860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis while( IsSpace(z[i+1]) ){ i++; } 201960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 202060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 202160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis z[j] = 0; 202260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 2023e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani printSchemaLine(p->out, z, ";\n"); 202460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(z); 202560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis break; 202660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 20277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project case MODE_List: { 20287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->cnt++==0 && p->showHeader ){ 20297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 203060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%s%s",azCol[i], 20313fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich i==nArg-1 ? p->rowSeparator : p->colSeparator); 20327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( azArg==0 ) break; 20357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 20367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *z = azArg[i]; 20373fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( z==0 ) z = p->nullValue; 203860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", z); 20397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( i<nArg-1 ){ 204060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->colSeparator); 20417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 204260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->rowSeparator); 20437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 20467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project case MODE_Html: { 20487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->cnt++==0 && p->showHeader ){ 204960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out,"<TR>"); 20507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 205160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out,"<TH>"); 2052a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori output_html_string(p->out, azCol[i]); 205360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out,"</TH>\n"); 20547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 205560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out,"</TR>\n"); 20567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( azArg==0 ) break; 205860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out,"<TR>"); 20597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 206060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out,"<TD>"); 20613fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); 206260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out,"</TD>\n"); 20637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 206460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out,"</TR>\n"); 20657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 20667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project case MODE_Tcl: { 20687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->cnt++==0 && p->showHeader ){ 20697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 20707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project output_c_string(p->out,azCol[i] ? azCol[i] : ""); 207160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator); 20727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 207360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->rowSeparator); 20747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( azArg==0 ) break; 20767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 20773fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); 207860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator); 20797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 208060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->rowSeparator); 20817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 20827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project case MODE_Csv: { 208460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis setBinaryMode(p->out, 1); 20857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->cnt++==0 && p->showHeader ){ 20867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 20877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); 20887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 208960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->rowSeparator); 20907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 20913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nArg>0 ){ 20929bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown for(i=0; i<nArg; i++){ 20939bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown output_csv(p, azArg[i], i<nArg-1); 20949bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown } 209560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->rowSeparator); 20967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 209760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis setTextMode(p->out, 1); 20987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 20997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 21007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project case MODE_Insert: { 21017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( azArg==0 ) break; 2102b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); 2103b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( p->showHeader ){ 2104b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(p->out,"("); 2105b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis for(i=0; i<nArg; i++){ 2106b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( i>0 ) raw_printf(p->out, ","); 2107b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( quoteChar(azCol[i]) ){ 2108b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis char *z = sqlite3_mprintf("\"%w\"", azCol[i]); 2109b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out, "%s", z); 2110b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis sqlite3_free(z); 2111b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else{ 2112b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(p->out, "%s", azCol[i]); 2113e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 2114e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 2115b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(p->out,")"); 2116b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 2117b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis p->cnt++; 2118b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis for(i=0; i<nArg; i++){ 2119b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(p->out, i>0 ? "," : " VALUES("); 2120b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ 2121b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out,"NULL"); 2122b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else if( aiType && aiType[i]==SQLITE_TEXT ){ 2123b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis output_quoted_escaped_string(p->out, azArg[i]); 2124b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else if( aiType && aiType[i]==SQLITE_INTEGER ){ 2125b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out,"%s", azArg[i]); 2126b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else if( aiType && aiType[i]==SQLITE_FLOAT ){ 2127b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis char z[50]; 2128b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis double r = sqlite3_column_double(p->pStmt, i); 2129b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis sqlite3_snprintf(50,z,"%!.20g", r); 2130b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(p->out, "%s", z); 2131b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ 2132b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis const void *pBlob = sqlite3_column_blob(p->pStmt, i); 2133b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis int nBlob = sqlite3_column_bytes(p->pStmt, i); 2134b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis output_hex_blob(p->out, pBlob, nBlob); 2135b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else if( isNumber(azArg[i], 0) ){ 2136b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out,"%s", azArg[i]); 2137b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis }else{ 2138b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis output_quoted_escaped_string(p->out, azArg[i]); 2139b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 2140b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 2141b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(p->out,");\n"); 2142b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis break; 2143b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis } 2144b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis case MODE_Quote: { 2145b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( azArg==0 ) break; 2146b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( p->cnt==0 && p->showHeader ){ 21473a6c79f802fabdb94367177310663397420e319fNick Kralevich for(i=0; i<nArg; i++){ 2148e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( i>0 ) raw_printf(p->out, ","); 2149e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani output_quoted_string(p->out, azCol[i]); 21503a6c79f802fabdb94367177310663397420e319fNick Kralevich } 2151e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(p->out,"\n"); 21523a6c79f802fabdb94367177310663397420e319fNick Kralevich } 2153e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani p->cnt++; 21547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nArg; i++){ 2155b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis if( i>0 ) raw_printf(p->out, ","); 2156a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ 2157b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out,"NULL"); 2158a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else if( aiType && aiType[i]==SQLITE_TEXT ){ 2159a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori output_quoted_string(p->out, azArg[i]); 2160b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( aiType && aiType[i]==SQLITE_INTEGER ){ 2161b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out,"%s", azArg[i]); 2162b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( aiType && aiType[i]==SQLITE_FLOAT ){ 2163b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char z[50]; 2164b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis double r = sqlite3_column_double(p->pStmt, i); 2165b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_snprintf(50,z,"%!.20g", r); 2166b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(p->out, "%s", z); 2167a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ 2168a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori const void *pBlob = sqlite3_column_blob(p->pStmt, i); 2169a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int nBlob = sqlite3_column_bytes(p->pStmt, i); 2170a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori output_hex_blob(p->out, pBlob, nBlob); 21717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( isNumber(azArg[i], 0) ){ 2172b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis utf8_printf(p->out,"%s", azArg[i]); 21737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 21747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project output_quoted_string(p->out, azArg[i]); 21757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 21767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 2177b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis raw_printf(p->out,"\n"); 21787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 21797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 21803fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich case MODE_Ascii: { 21813fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( p->cnt++==0 && p->showHeader ){ 21823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich for(i=0; i<nArg; i++){ 218360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator); 218460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : ""); 21853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 218660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->rowSeparator); 21873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 21883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( azArg==0 ) break; 21893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich for(i=0; i<nArg; i++){ 219060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator); 219160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); 21923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 219360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", p->rowSeparator); 21943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich break; 21953fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 21967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 21977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 21987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 21997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 22007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 2201a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** This is the callback routine that the SQLite library 2202a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** invokes for each row of a query result. 2203a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 2204a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int callback(void *pArg, int nArg, char **azArg, char **azCol){ 2205a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori /* since we don't have type info, call the shell_callback with a NULL value */ 2206a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return shell_callback(pArg, nArg, azArg, azCol, NULL); 2207a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 2208a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 2209a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 2210b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** This is the callback routine from sqlite3_exec() that appends all 2211b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** output onto the end of a ShellText object. 2212b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 2213b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ 2214b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellText *p = (ShellText*)pArg; 2215b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; 2216b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis UNUSED_PARAMETER(az); 2217b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( p->n ) appendText(p, "|", 0); 2218b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=0; i<nArg; i++){ 2219b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( i ) appendText(p, ",", 0); 2220b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( azArg[i] ) appendText(p, azArg[i], 0); 2221b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 2222b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return 0; 2223b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 2224b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 2225b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 2226b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Generate an appropriate SELFTEST table in the main database. 2227b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 2228b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void createSelftestTable(ShellState *p){ 2229b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zErrMsg = 0; 2230b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_exec(p->db, 2231b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "SAVEPOINT selftest_init;\n" 2232b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "CREATE TABLE IF NOT EXISTS selftest(\n" 2233b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " tno INTEGER PRIMARY KEY,\n" /* Test number */ 2234b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " op TEXT,\n" /* Operator: memo run */ 2235b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " cmd TEXT,\n" /* Command text */ 2236b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " ans TEXT\n" /* Desired answer */ 2237b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ");" 2238b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n" 2239b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "INSERT INTO [_shell$self](rowid,op,cmd)\n" 2240b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n" 2241b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " 'memo','Tests generated by --init');\n" 2242b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "INSERT INTO [_shell$self]\n" 2243b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " SELECT 'run',\n" 2244b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql " 2245b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "FROM sqlite_master ORDER BY 2'',224))',\n" 2246b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " hex(sha3_query('SELECT type,name,tbl_name,sql " 2247b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "FROM sqlite_master ORDER BY 2',224));\n" 2248b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "INSERT INTO [_shell$self]\n" 2249b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " SELECT 'run'," 2250b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||" 2251b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " printf('%w',name) || '\" NOT INDEXED'',224))',\n" 2252b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n" 2253b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " FROM (\n" 2254b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " SELECT name FROM sqlite_master\n" 2255b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " WHERE type='table'\n" 2256b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " AND name<>'selftest'\n" 2257b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " AND coalesce(rootpage,0)>0\n" 2258b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " )\n" 2259b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " ORDER BY name;\n" 2260b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "INSERT INTO [_shell$self]\n" 2261b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " VALUES('run','PRAGMA integrity_check','ok');\n" 2262b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "INSERT INTO selftest(tno,op,cmd,ans)" 2263b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n" 2264b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "DROP TABLE [_shell$self];" 2265b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ,0,0,&zErrMsg); 2266b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( zErrMsg ){ 2267b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg); 2268b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zErrMsg); 2269b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 2270b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0); 2271b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 2272b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 2273b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 2274b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 22753fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** Set the destination table field of the ShellState structure to 22767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the name of the table given. Escape any quote characters in the 22777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** table name. 22787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 22793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void set_table_name(ShellState *p, const char *zName){ 22807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i, n; 2281b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int cQuote; 22827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *z; 22837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 22847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->zDestTable ){ 22857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project free(p->zDestTable); 22867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->zDestTable = 0; 22877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 22887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zName==0 ) return; 2289b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis cQuote = quoteChar(zName); 2290b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis n = strlen30(zName); 2291b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( cQuote ) n += 2; 22927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z = p->zDestTable = malloc( n+1 ); 22937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( z==0 ){ 229460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr,"Error: out of memory\n"); 22957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project exit(1); 22967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 22977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project n = 0; 2298b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( cQuote ) z[n++] = cQuote; 22997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; zName[i]; i++){ 23007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z[n++] = zName[i]; 2301b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( zName[i]==cQuote ) z[n++] = cQuote; 23027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 2303b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( cQuote ) z[n++] = cQuote; 23047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z[n] = 0; 23057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 23067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 23077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 23087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 2309c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** Execute a query statement that will generate SQL output. Print 2310c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** the result columns, comma-separated, on a line and then add a 2311c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** semicolon terminator to the end of that line. 23127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 2313c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** If the number of columns is 1 and that column contains text "--" 231460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** then write the semicolon on a separate line. That way, if a 2315c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** "--" comment occurs at the end of the statement, the comment 2316c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown** won't consume the semicolon terminator. 23177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 2318a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int run_table_dump_query( 23193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *p, /* Query context */ 232090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zSelect, /* SELECT statement to extract content */ 232190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zFirstRow /* Print before first row, if not NULL */ 2322a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori){ 23237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_stmt *pSelect; 23247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int rc; 2325c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown int nResult; 2326c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown int i; 2327c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown const char *z; 23288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); 23297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( rc!=SQLITE_OK || !pSelect ){ 233060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, 233160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_errmsg(p->db)); 23328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; 23337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return rc; 23347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 23357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = sqlite3_step(pSelect); 2336c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown nResult = sqlite3_column_count(pSelect); 23377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project while( rc==SQLITE_ROW ){ 2338a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( zFirstRow ){ 233960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", zFirstRow); 2340a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zFirstRow = 0; 2341a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 2342c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown z = (const char*)sqlite3_column_text(pSelect, 0); 234360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", z); 234460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=1; i<nResult; i++){ 234560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i)); 2346c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown } 2347c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( z==0 ) z = ""; 2348c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; 2349c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( z[0] ){ 235060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n;\n"); 2351c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else{ 235260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, ";\n"); 235360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 23547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = sqlite3_step(pSelect); 23557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 235690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown rc = sqlite3_finalize(pSelect); 235790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( rc!=SQLITE_OK ){ 235860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, 235960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_errmsg(p->db)); 23608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; 236190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 236290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown return rc; 23637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 23647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 2365a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 2366a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Allocate space and save off current error string. 2367a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 2368a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic char *save_err_msg( 2369a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3 *db /* Database to query */ 2370a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori){ 2371a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); 23723a6c79f802fabdb94367177310663397420e319fNick Kralevich char *zErrMsg = sqlite3_malloc64(nErrMsg); 2373a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( zErrMsg ){ 2374a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); 2375a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 2376a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return zErrMsg; 2377a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 2378a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 237960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#ifdef __linux__ 238060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 238160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Attempt to display I/O stats on Linux using /proc/PID/io 238260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 238360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic void displayLinuxIoStats(FILE *out){ 238460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis FILE *in; 238560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char z[200]; 238660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); 238760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis in = fopen(z, "rb"); 238860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( in==0 ) return; 238960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis while( fgets(z, sizeof(z), in)!=0 ){ 239060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis static const struct { 239160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *zPattern; 239260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *zDesc; 239360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } aTrans[] = { 239460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis { "rchar: ", "Bytes received by read():" }, 239560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis { "wchar: ", "Bytes sent to write():" }, 239660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis { "syscr: ", "Read() system calls:" }, 239760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis { "syscw: ", "Write() system calls:" }, 239860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis { "read_bytes: ", "Bytes read from storage:" }, 239960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis { "write_bytes: ", "Bytes written to storage:" }, 240060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis { "cancelled_write_bytes: ", "Cancelled write bytes:" }, 240160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }; 240260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int i; 240360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<ArraySize(aTrans); i++){ 240460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int n = (int)strlen(aTrans[i].zPattern); 240560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strncmp(aTrans[i].zPattern, z, n)==0 ){ 240608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]); 240760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis break; 240860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 240960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 241060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 241160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis fclose(in); 241260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 241360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 241460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 2415b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 2416b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Display a single line of status using 64-bit values. 2417b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 2418b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void displayStatLine( 2419b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellState *p, /* The shell context */ 2420b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zLabel, /* Label for this one line */ 2421b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zFormat, /* Format for the result */ 2422b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int iStatusCtrl, /* Which status to display */ 2423b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int bReset /* True to reset the stats */ 2424b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis){ 2425b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_int64 iCur = -1; 2426b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_int64 iHiwtr = -1; 2427b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i, nPercent; 2428b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char zLine[200]; 2429b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset); 2430b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=0, nPercent=0; zFormat[i]; i++){ 2431b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( zFormat[i]=='%' ) nPercent++; 2432b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 2433b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( nPercent>1 ){ 2434b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr); 2435b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 2436b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr); 2437b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 2438b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(p->out, "%-36s %s\n", zLabel, zLine); 2439b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 244060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 2441a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 2442de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori** Display memory stats. 2443de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori*/ 2444de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Noristatic int display_stats( 2445de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori sqlite3 *db, /* Database to query */ 24463fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *pArg, /* Pointer to ShellState */ 2447de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori int bReset /* True to reset the stats */ 2448de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori){ 2449de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori int iCur; 2450de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori int iHiwtr; 2451de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 2452de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori if( pArg && pArg->out ){ 2453b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Memory Used:", 2454b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); 2455b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Number of Outstanding Allocations:", 2456b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); 24573fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( pArg->shellFlgs & SHFLG_Pagecache ){ 2458b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Number of Pcache Pages Used:", 2459b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); 24603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 2461b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Number of Pcache Overflow Bytes:", 2462b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); 24633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( pArg->shellFlgs & SHFLG_Scratch ){ 2464b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Number of Scratch Allocations Used:", 2465b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset); 2466b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 2467b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Number of Scratch Overflow Bytes:", 2468b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset); 2469b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Largest Allocation:", 2470b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); 2471b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Largest Pcache Allocation:", 2472b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); 2473b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Largest Scratch Allocation:", 2474b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset); 2475de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori#ifdef YYTRACKMAXSTACKDEPTH 2476b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis displayStatLine(pArg, "Deepest Parser Stack:", 2477b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); 2478de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori#endif 2479de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori } 2480de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 2481de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori if( pArg && pArg->out && db ){ 24823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( pArg->shellFlgs & SHFLG_Lookaside ){ 24833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich iHiwtr = iCur = -1; 24843fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, 24853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich &iCur, &iHiwtr, bReset); 248660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, 248760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "Lookaside Slots Used: %d (max %d)\n", 24883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich iCur, iHiwtr); 24893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, 24903fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich &iCur, &iHiwtr, bReset); 249160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Successful lookaside attempts: %d\n", 249260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis iHiwtr); 24933fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, 24943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich &iCur, &iHiwtr, bReset); 249560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Lookaside failures due to size: %d\n", 249660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis iHiwtr); 24973fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, 24983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich &iCur, &iHiwtr, bReset); 249960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n", 250060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis iHiwtr); 25013fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 2502de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori iHiwtr = iCur = -1; 2503de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); 250460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n", 250560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis iCur); 25063fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich iHiwtr = iCur = -1; 250790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); 250860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Page cache hits: %d\n", iCur); 250990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown iHiwtr = iCur = -1; 251090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); 251160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Page cache misses: %d\n", iCur); 2512de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori iHiwtr = iCur = -1; 25138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); 251460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Page cache writes: %d\n", iCur); 25158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich iHiwtr = iCur = -1; 2516de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); 251760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", 251860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis iCur); 2519de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori iHiwtr = iCur = -1; 2520de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); 252160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", 252260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis iCur); 2523de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori } 2524de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 2525de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori if( pArg && pArg->out && db && pArg->pStmt ){ 25263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 25273fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich bReset); 252860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur); 2529de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); 253060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Sort Operations: %d\n", iCur); 25313fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); 253260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); 25338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); 253460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); 2535de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori } 2536de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 253760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#ifdef __linux__ 253860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis displayLinuxIoStats(pArg->out); 253960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 254060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 2541253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich /* Do not remove this machine readable comment: extra-stats-output-here */ 2542253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich 2543de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori return 0; 2544de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori} 2545de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 2546de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori/* 25473fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** Display scan stats. 25483fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 25493fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void display_scanstats( 25503fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3 *db, /* Database to query */ 25513fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *pArg /* Pointer to ShellState */ 25523fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich){ 2553253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich#ifndef SQLITE_ENABLE_STMT_SCANSTATUS 2554253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich UNUSED_PARAMETER(db); 2555253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich UNUSED_PARAMETER(pArg); 2556253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich#else 25573fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int i, k, n, mx; 255860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "-------- scanstats --------\n"); 25593fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich mx = 0; 25603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich for(k=0; k<=mx; k++){ 25613fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich double rEstLoop = 1.0; 25623fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich for(i=n=0; 1; i++){ 25633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_stmt *p = pArg->pStmt; 25643fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_int64 nLoop, nVisit; 25653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich double rEst; 25663fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int iSid; 25673fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich const char *zExplain; 25683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){ 25693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich break; 25703fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 25713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid); 25723fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( iSid>mx ) mx = iSid; 25733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( iSid!=k ) continue; 25743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( n==0 ){ 25753fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rEstLoop = (double)nLoop; 257660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k); 25773fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 25783fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich n++; 25793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit); 25803fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst); 25813fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); 258260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain); 25833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rEstLoop *= rEst; 258460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, 25853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n", 25863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst 25873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ); 25883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 25893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 259060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out, "---------------------------\n"); 25913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 25923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich} 25933fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 25943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 25958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Parameter azArray points to a zero-terminated array of strings. zStr 25968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** points to a single nul-terminated string. Return non-zero if zStr 25978fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** is equal, according to strcmp(), to any of the strings in the array. 25988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Otherwise, return zero. 25998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 26008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic int str_in_array(const char *zStr, const char **azArray){ 26018fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int i; 26028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=0; azArray[i]; i++){ 26038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( 0==strcmp(zStr, azArray[i]) ) return 1; 26048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 26058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 0; 26068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 26078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 26088fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 26098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** If compiled statement pSql appears to be an EXPLAIN statement, allocate 26103fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** and populate the ShellState.aiIndent[] array with the number of 261160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** spaces each opcode should be indented before it is output. 26128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** 26138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** The indenting rules are: 26148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** 26158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent 26168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** all opcodes that occur between the p2 jump destination and the opcode 26178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** itself by 2 spaces. 26188fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** 26198fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** * For each "Goto", if the jump destination is earlier in the program 26208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** and ends on one of: 26218fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Yield SeekGt SeekLt RowSetRead Rewind 26228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** or if the P1 parameter is one instead of zero, 26238fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** then indent all opcodes between the earlier instruction 26248fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** and "Goto" by 2 spaces. 26258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 26263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ 26278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *zSql; /* The text of the SQL statement */ 26288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *z; /* Used to check if this is an EXPLAIN */ 26298fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int *abYield = 0; /* True if op is an OP_Yield */ 26308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ 26318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int iOp; /* Index of operation in p->aiIndent[] */ 26328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 26331c7cea379348522163370244e8fbbff8a136b7faNick Kralevich const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 26341c7cea379348522163370244e8fbbff8a136b7faNick Kralevich "NextIfOpen", "PrevIfOpen", 0 }; 26353fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", 26363fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "Rewind", 0 }; 26378fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *azGoto[] = { "Goto", 0 }; 26388fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 26398fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* Try to figure out if this is really an EXPLAIN statement. If this 26408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** cannot be verified, return early. */ 264160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( sqlite3_column_count(pSql)!=8 ){ 264260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->cMode = p->mode; 264360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return; 264460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 26458fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zSql = sqlite3_sql(pSql); 26468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zSql==0 ) return; 26478fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++); 264860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( sqlite3_strnicmp(z, "explain", 7) ){ 264960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->cMode = p->mode; 265060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return; 265160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 26528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 26538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){ 26548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int i; 26558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int iAddr = sqlite3_column_int(pSql, 0); 26568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *zOp = (const char*)sqlite3_column_text(pSql, 1); 26578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 26588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* Set p2 to the P2 field of the current opcode. Then, assuming that 26598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** p2 is an instruction address, set variable p2op to the index of that 26608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** instruction in the aiIndent[] array. p2 and p2op may be different if 26618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** the current instruction is part of a sub-program generated by an 26628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** SQL trigger or foreign key. */ 26638fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int p2 = sqlite3_column_int(pSql, 3); 26648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int p2op = (p2 + (iOp-iAddr)); 26658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 26668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* Grow the p->aiIndent array as required */ 26678fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( iOp>=nAlloc ){ 266860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( iOp==0 ){ 266960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* Do further verfication that this is explain output. Abort if 267060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** it is not */ 267160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis static const char *explainCols[] = { 267260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" }; 267360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int jj; 267460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(jj=0; jj<ArraySize(explainCols); jj++){ 267560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){ 267660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->cMode = p->mode; 267760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_reset(pSql); 267860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return; 267960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 268060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 268160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 26828fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich nAlloc += 100; 26833a6c79f802fabdb94367177310663397420e319fNick Kralevich p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); 26843a6c79f802fabdb94367177310663397420e319fNick Kralevich abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); 26858fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 26868fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich abYield[iOp] = str_in_array(zOp, azYield); 26878fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->aiIndent[iOp] = 0; 26888fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->nIndent = iOp+1; 26898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 26908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( str_in_array(zOp, azNext) ){ 26918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2; 26928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 26938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( str_in_array(zOp, azGoto) && p2op<p->nIndent 26948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich && (abYield[p2op] || sqlite3_column_int(pSql, 2)) 26958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ){ 269660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2; 26978fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 26988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 26998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 27008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->iIndent = 0; 27018fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(abYield); 27028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_reset(pSql); 27038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 27048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 27058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 27068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Free the array allocated by explain_data_prepare(). 27078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 27083fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void explain_data_delete(ShellState *p){ 27098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(p->aiIndent); 27108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->aiIndent = 0; 27118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->nIndent = 0; 27128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->iIndent = 0; 27138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 27148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 27158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 271660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Disable and restore .wheretrace and .selecttrace settings. 271760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 271860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) 271960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisextern int sqlite3SelectTrace; 272060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic int savedSelectTrace; 272160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 272260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) 272360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisextern int sqlite3WhereTrace; 272460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic int savedWhereTrace; 272560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 272660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic void disable_debug_trace_modes(void){ 272760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) 272860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis savedSelectTrace = sqlite3SelectTrace; 272960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3SelectTrace = 0; 273060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 273160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) 273260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis savedWhereTrace = sqlite3WhereTrace; 273360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3WhereTrace = 0; 273460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 273560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 273660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic void restore_debug_trace_modes(void){ 273760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) 273860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3SelectTrace = savedSelectTrace; 273960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 274060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) 274160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3WhereTrace = savedWhereTrace; 274260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 274360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 274460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 274560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 274660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Run a prepared statement 274760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 274860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic void exec_prepared_stmt( 274960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ShellState *pArg, /* Pointer to ShellState */ 275060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_stmt *pStmt, /* Statment to run */ 275160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */ 275260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis){ 275360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int rc; 275460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 275560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* perform the first step. this will tell us if we 275660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** have a result set or not and how wide it is. 275760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 275860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = sqlite3_step(pStmt); 275960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* if we have a result set... */ 276060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( SQLITE_ROW == rc ){ 276160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* if we have a callback... */ 276260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( xCallback ){ 276360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* allocate space for col name ptr, value ptr, and type */ 276460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int nCol = sqlite3_column_count(pStmt); 276560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); 276660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( !pData ){ 276760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = SQLITE_NOMEM; 276860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 276960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char **azCols = (char **)pData; /* Names of result columns */ 277060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char **azVals = &azCols[nCol]; /* Results */ 277160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int *aiTypes = (int *)&azVals[nCol]; /* Result types */ 277260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int i, x; 277360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis assert(sizeof(int) <= sizeof(char *)); 277460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* save off ptrs to column names */ 277560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<nCol; i++){ 277660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis azCols[i] = (char *)sqlite3_column_name(pStmt, i); 277760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 277860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis do{ 277960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* extract the data and data types */ 278060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<nCol; i++){ 278160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis aiTypes[i] = x = sqlite3_column_type(pStmt, i); 278260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){ 278360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis azVals[i] = ""; 278460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 278560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis azVals[i] = (char*)sqlite3_column_text(pStmt, i); 278660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 278760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ 278860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = SQLITE_NOMEM; 278960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis break; /* from for */ 279060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 279160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } /* end for */ 279260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 279360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* if data and types extracted successfully... */ 279460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( SQLITE_ROW == rc ){ 279560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* call the supplied callback with the result row data */ 279660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ 279760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = SQLITE_ABORT; 279860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 279960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = sqlite3_step(pStmt); 280060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 280160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 280260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } while( SQLITE_ROW == rc ); 280360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(pData); 280460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 280560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 280660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis do{ 280760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = sqlite3_step(pStmt); 280860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } while( rc == SQLITE_ROW ); 280960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 281060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 281160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 281260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 281360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 281460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Execute a statement or set of statements. Print 281560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** any result rows/columns depending on the current mode 2816a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** set via the supplied callback. 2817a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** 281860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** This is very similar to SQLite's built-in sqlite3_exec() 281960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** function except it takes a slightly different callback 2820a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** and callback data argument. 2821a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 2822a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Noristatic int shell_exec( 28233fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3 *db, /* An open database */ 28243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich const char *zSql, /* SQL to be evaluated */ 2825a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */ 28263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* (not the same as sqlite3_exec) */ 28273fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *pArg, /* Pointer to ShellState */ 28283fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char **pzErrMsg /* Error msg written here */ 2829a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori){ 2830a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ 2831a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int rc = SQLITE_OK; /* Return Code */ 283290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown int rc2; 2833a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori const char *zLeftover; /* Tail of unprocessed SQL */ 2834a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 2835a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( pzErrMsg ){ 2836a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori *pzErrMsg = NULL; 2837a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 2838a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 2839a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori while( zSql[0] && (SQLITE_OK == rc) ){ 284060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis static const char *zStmtSql; 2841a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); 2842a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( SQLITE_OK != rc ){ 2843a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( pzErrMsg ){ 2844a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori *pzErrMsg = save_err_msg(db); 2845a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 2846a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else{ 2847a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( !pStmt ){ 2848a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori /* this happens for a comment or white-space */ 2849a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zSql = zLeftover; 285090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown while( IsSpace(zSql[0]) ) zSql++; 2851a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori continue; 2852a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 285360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis zStmtSql = sqlite3_sql(pStmt); 2854e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( zStmtSql==0 ) zStmtSql = ""; 285560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis while( IsSpace(zStmtSql[0]) ) zStmtSql++; 2856a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 2857de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori /* save off the prepared statment handle and reset row count */ 2858de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori if( pArg ){ 2859de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori pArg->pStmt = pStmt; 2860de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori pArg->cnt = 0; 2861de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori } 2862de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 286371504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori /* echo the sql statement if echo on */ 2864b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){ 286560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); 286671504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori } 286771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori 28688fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* Show the EXPLAIN QUERY PLAN if .eqp is on */ 286960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){ 28708fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_stmt *pExplain; 287160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char *zEQP; 287260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis disable_debug_trace_modes(); 287360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); 28748fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); 28758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc==SQLITE_OK ){ 28768fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( sqlite3_step(pExplain)==SQLITE_ROW ){ 287760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0)); 287860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1)); 287960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2)); 288060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3)); 28818fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 28828fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 28838fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_finalize(pExplain); 28848fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zEQP); 288560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pArg->autoEQP>=2 ){ 288660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* Also do an EXPLAIN for ".eqp full" mode */ 288760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); 288860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); 288960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( rc==SQLITE_OK ){ 289060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pArg->cMode = MODE_Explain; 289160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis explain_data_prepare(pArg, pExplain); 289260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis exec_prepared_stmt(pArg, pExplain, xCallback); 289360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis explain_data_delete(pArg); 289460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 289560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_finalize(pExplain); 289660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(zEQP); 289760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 289860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis restore_debug_trace_modes(); 28998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 29008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 290160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pArg ){ 290260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pArg->cMode = pArg->mode; 290360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pArg->autoExplain 290460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis && sqlite3_column_count(pStmt)==8 290560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 290660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ){ 290760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pArg->cMode = MODE_Explain; 290860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 29098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 291060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* If the shell is currently in ".explain" mode, gather the extra 291160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** data required to add indents to the output.*/ 291260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pArg->cMode==MODE_Explain ){ 291360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis explain_data_prepare(pArg, pStmt); 2914a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 2915a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 2916a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 291760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis exec_prepared_stmt(pArg, pStmt, xCallback); 29188fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich explain_data_delete(pArg); 29198fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 2920de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori /* print usage stats if stats on */ 2921de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori if( pArg && pArg->statsOn ){ 2922de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori display_stats(db, pArg, 0); 2923de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori } 2924de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 29253fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* print loop-counters if required */ 29263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( pArg && pArg->scanstatsOn ){ 29273fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich display_scanstats(db, pArg); 29283fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 29293fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 293060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* Finalize the statement just executed. If this fails, save a 2931a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ** copy of the error message. Otherwise, set zSql to point to the 2932a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ** next statement to execute. */ 293390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown rc2 = sqlite3_finalize(pStmt); 293490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( rc!=SQLITE_NOMEM ) rc = rc2; 2935a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( rc==SQLITE_OK ){ 2936a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zSql = zLeftover; 293790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown while( IsSpace(zSql[0]) ) zSql++; 2938a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else if( pzErrMsg ){ 2939a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori *pzErrMsg = save_err_msg(db); 2940a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 2941de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 2942de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori /* clear saved stmt handle */ 2943de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori if( pArg ){ 2944de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori pArg->pStmt = NULL; 2945de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori } 2946a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 2947a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } /* end while */ 2948a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 2949a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return rc; 2950a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 2951a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 2952b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 2953b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Release memory previously allocated by tableColumnList(). 2954b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 2955b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void freeColumnList(char **azCol){ 2956b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; 2957b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=1; azCol[i]; i++){ 2958b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(azCol[i]); 2959b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 2960b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* azCol[0] is a static string */ 2961b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(azCol); 2962b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 2963b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 2964b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 2965b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Return a list of pointers to strings which are the names of all 2966b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** columns in table zTab. The memory to hold the names is dynamically 2967b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** allocated and must be released by the caller using a subsequent call 2968b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** to freeColumnList(). 2969b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 2970b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** The azCol[0] entry is usually NULL. However, if zTab contains a rowid 2971b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** value that needs to be preserved, then azCol[0] is filled in with the 2972b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** name of the rowid column. 2973b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** 2974b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** The first regular column in the table is azCol[1]. The list is terminated 2975b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** by an entry with azCol[i]==0. 2976b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 2977b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic char **tableColumnList(ShellState *p, const char *zTab){ 2978b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char **azCol = 0; 2979b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_stmt *pStmt; 2980b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zSql; 2981b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nCol = 0; 2982b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nAlloc = 0; 2983b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nPK = 0; /* Number of PRIMARY KEY columns seen */ 2984b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ 2985b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); 2986b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int rc; 2987b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 2988b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); 2989b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 2990b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zSql); 2991b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( rc ) return 0; 2992b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis while( sqlite3_step(pStmt)==SQLITE_ROW ){ 2993b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( nCol>=nAlloc-2 ){ 2994b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis nAlloc = nAlloc*2 + nCol + 10; 2995b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); 2996b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( azCol==0 ){ 2997b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(stderr, "Error: out of memory\n"); 2998b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis exit(1); 2999b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3000b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3001b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); 3002b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( sqlite3_column_int(pStmt, 5) ){ 3003b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis nPK++; 3004b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( nPK==1 3005b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2), 3006b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "INTEGER")==0 3007b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ){ 3008b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis isIPK = 1; 3009b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 3010b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis isIPK = 0; 3011b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3012b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3013b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3014b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_finalize(pStmt); 3015b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azCol[0] = 0; 3016b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azCol[nCol+1] = 0; 3017b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 3018b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* The decision of whether or not a rowid really needs to be preserved 3019b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table 3020b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve 3021b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** rowids on tables where the rowid is inaccessible because there are other 3022b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** columns in the table named "rowid", "_rowid_", and "oid". 3023b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis */ 3024b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( preserveRowid && isIPK ){ 3025b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* If a single PRIMARY KEY column with type INTEGER was seen, then it 3026b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID 3027b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** table or a INTEGER PRIMARY KEY DESC column, neither of which are 3028b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** ROWID aliases. To distinguish these cases, check to see if 3029b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** there is a "pk" entry in "PRAGMA index_list". There will be 3030b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. 3031b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis */ 3032b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" 3033b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " WHERE origin='pk'", zTab); 3034b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 3035b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zSql); 3036b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( rc ){ 3037b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis freeColumnList(azCol); 3038b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return 0; 3039b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3040b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = sqlite3_step(pStmt); 3041b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_finalize(pStmt); 3042b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis preserveRowid = rc==SQLITE_ROW; 3043b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3044b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( preserveRowid ){ 3045b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* Only preserve the rowid if we can find a name to use for the 3046b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** rowid */ 3047b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis static char *azRowid[] = { "rowid", "_rowid_", "oid" }; 3048b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i, j; 3049b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(j=0; j<3; j++){ 3050b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=1; i<=nCol; i++){ 3051b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break; 3052b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3053b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( i>nCol ){ 3054b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* At this point, we know that azRowid[j] is not the name of any 3055b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** ordinary column in the table. Verify that azRowid[j] is a valid 3056b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID 3057b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** tables will fail this last check */ 3058b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); 3059b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; 3060b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis break; 3061b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3062b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3063b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3064b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return azCol; 3065b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 3066b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 3067b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 3068b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Toggle the reverse_unordered_selects setting. 3069b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 3070b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void toggleSelectOrder(sqlite3 *db){ 3071b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_stmt *pStmt = 0; 3072b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int iSetting = 0; 3073b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char zStmt[100]; 3074b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0); 3075b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( sqlite3_step(pStmt)==SQLITE_ROW ){ 3076b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis iSetting = sqlite3_column_int(pStmt, 0); 3077b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3078b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_finalize(pStmt); 3079b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_snprintf(sizeof(zStmt), zStmt, 3080b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "PRAGMA reverse_unordered_selects(%d)", !iSetting); 3081b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_exec(db, zStmt, 0, 0, 0); 3082b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 30837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 30847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 30857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This is a different callback routine used for dumping the database. 30867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Each row received by this callback consists of a table name, 30877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the table type ("index" or "table") and SQL to create the table. 30887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** This routine should print text sufficient to recreate the table. 30897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 3090b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ 30917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int rc; 30927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project const char *zTable; 30937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project const char *zType; 30947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project const char *zSql; 30953fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *p = (ShellState *)pArg; 30967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 3097b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis UNUSED_PARAMETER(azNotUsed); 30987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( nArg!=3 ) return 1; 30997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zTable = azArg[0]; 31007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zType = azArg[1]; 31017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zSql = azArg[2]; 310260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 31037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( strcmp(zTable, "sqlite_sequence")==0 ){ 3104b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(p->out, "DELETE FROM sqlite_sequence;\n"); 31058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ 310660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "ANALYZE sqlite_master;\n"); 31077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strncmp(zTable, "sqlite_", 7)==0 ){ 31087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 31097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ 31107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zIns; 31117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( !p->writableSchema ){ 311260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "PRAGMA writable_schema=ON;\n"); 31137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->writableSchema = 1; 31147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 31157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zIns = sqlite3_mprintf( 31167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" 31177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "VALUES('table','%q','%q',0,'%q');", 31187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zTable, zTable, zSql); 311960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s\n", zIns); 31207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_free(zIns); 31217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 31227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 3123e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani printSchemaLine(p->out, zSql, ";\n"); 31247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 31257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 31267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( strcmp(zType, "table")==0 ){ 3127b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellText sSelect; 3128b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellText sTable; 3129b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char **azCol; 3130b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; 3131b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *savedDestTable; 3132b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int savedMode; 3133b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 3134b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azCol = tableColumnList(p, zTable); 3135b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( azCol==0 ){ 3136b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->nErr++; 3137b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis return 0; 31387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 31397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 31408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* Always quote the table name, even if it appears to be pure ascii, 31418fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** in case it is a keyword. Ex: INSERT INTO "table" ... */ 3142b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis initText(&sTable); 3143b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sTable, zTable, quoteChar(zTable)); 3144b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* If preserving the rowid, add a column list after the table name. 3145b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" 3146b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** instead of the usual "INSERT INTO tab VALUES(...)". 3147b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis */ 3148b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( azCol[0] ){ 3149b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sTable, "(", 0); 3150b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sTable, azCol[0], 0); 3151b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=1; azCol[i]; i++){ 3152b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sTable, ",", 0); 3153b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sTable, azCol[i], quoteChar(azCol[i])); 31547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 3155b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sTable, ")", 0); 31567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 31577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 3158b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* Build an appropriate SELECT statement */ 3159b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis initText(&sSelect); 3160b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSelect, "SELECT ", 0); 3161b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( azCol[0] ){ 3162b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSelect, azCol[0], 0); 3163b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSelect, ",", 0); 31647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 3165b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=1; azCol[i]; i++){ 3166b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSelect, azCol[i], quoteChar(azCol[i])); 3167b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( azCol[i+1] ){ 3168b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSelect, ",", 0); 3169b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3170b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3171b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis freeColumnList(azCol); 3172b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSelect, " FROM ", 0); 3173b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSelect, zTable, quoteChar(zTable)); 3174b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 3175b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis savedDestTable = p->zDestTable; 3176b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis savedMode = p->mode; 3177b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->zDestTable = sTable.z; 3178b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->mode = p->cMode = MODE_Insert; 3179b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0); 3180b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( (rc&0xff)==SQLITE_CORRUPT ){ 3181b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); 3182b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis toggleSelectOrder(p->db); 3183b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis shell_exec(p->db, sSelect.z, shell_callback, p, 0); 3184b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis toggleSelectOrder(p->db); 3185b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3186b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->zDestTable = savedDestTable; 3187b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->mode = savedMode; 3188b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis freeText(&sTable); 3189b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis freeText(&sSelect); 3190b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( rc ) p->nErr++; 31917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 31927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 31937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 31947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 31957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 31967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Run zQuery. Use dump_callback() as the callback routine so that 31977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the contents of the query are output as SQL statements. 31987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 31997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** If we get a SQLITE_CORRUPT error, rerun the query after appending 32007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** "ORDER BY rowid DESC" to the end. 32017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 32027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int run_schema_dump_query( 320360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ShellState *p, 320490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zQuery 32057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project){ 32067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int rc; 320790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown char *zErr = 0; 320890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); 32097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( rc==SQLITE_CORRUPT ){ 32107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zQ2; 3211a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int len = strlen30(zQuery); 321260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); 321390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( zErr ){ 321460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "/****** %s ******/\n", zErr); 321590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_free(zErr); 321690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown zErr = 0; 321790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 32187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zQ2 = malloc( len+100 ); 32197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zQ2==0 ) return rc; 32208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); 322190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); 322290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( rc ){ 322360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr); 322490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else{ 322590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown rc = SQLITE_CORRUPT; 322690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 322790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_free(zErr); 32287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project free(zQ2); 32297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 32307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return rc; 32317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 32327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 32337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 32347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Text of a help message 32357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 32367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic char zHelp[] = 323708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#ifndef SQLITE_OMIT_AUTHORIZATION 323860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".auth ON|OFF Show authorizer callbacks\n" 323908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#endif 3240a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" 32411c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ".bail on|off Stop after hitting an error. Default OFF\n" 32423a6c79f802fabdb94367177310663397420e319fNick Kralevich ".binary on|off Turn binary output on or off. Default OFF\n" 324360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".changes on|off Show number of rows changed by SQL\n" 324408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis ".check GLOB Fail if output since .testcase does not match\n" 32458fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ".clone NEWDB Clone data into NEWDB from the existing database\n" 32467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".databases List names and files of attached databases\n" 32473fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ".dbinfo ?DB? Show status information about the database\n" 32487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".dump ?TABLE? ... Dump the database in an SQL text format\n" 3249a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori " If TABLE specified, only dump tables matching\n" 3250a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori " LIKE pattern TABLE.\n" 32511c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ".echo on|off Turn command echo on or off\n" 325260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" 32537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".exit Exit this program\n" 325460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n" 325560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" 32561c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ".headers on|off Turn display of headers on or off\n" 32577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".help Show this message\n" 32587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".import FILE TABLE Import data from FILE into TABLE\n" 3259e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#ifndef SQLITE_OMIT_TEST_CONTROL 3260e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n" 3261e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#endif 32623fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ".indexes ?TABLE? Show names of all indexes\n" 32633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " If TABLE specified, only show indexes for tables\n" 3264a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori " matching LIKE pattern TABLE.\n" 32657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_ENABLE_IOTRACE 32667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".iotrace FILE Enable I/O diagnostic logging to FILE\n" 32677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 32683a6c79f802fabdb94367177310663397420e319fNick Kralevich ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" 3269e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ".lint OPTIONS Report potential schema issues. Options:\n" 3270e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " fkey-indexes Find missing foreign key indexes\n" 32717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifndef SQLITE_OMIT_LOAD_EXTENSION 32727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".load FILE ?ENTRY? Load an extension library\n" 32737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 3274aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" 32757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" 32763fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " ascii Columns/rows delimited by 0x1F and 0x1E\n" 32777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " csv Comma-separated values\n" 32787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " column Left-aligned columns. (See .width)\n" 32797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " html HTML <table> code\n" 32807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " insert SQL insert statements for TABLE\n" 32817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " line One value per line\n" 3282b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " list Values delimited by \"|\"\n" 3283e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " quote Escape answers as for SQL\n" 32847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " tabs Tab-separated values\n" 32857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " tcl TCL list elements\n" 32868fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ".nullvalue STRING Use STRING in place of NULL values\n" 32871c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ".once FILENAME Output for the next SQL command only to FILENAME\n" 328808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis ".open ?--new? ?FILE? Close existing database and reopen FILE\n" 328908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis " The --new starts with an empty file\n" 32901c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ".output ?FILENAME? Send output to FILENAME or stdout\n" 32918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ".print STRING... Print literal STRING\n" 32927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".prompt MAIN CONTINUE Replace the standard prompts\n" 32937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".quit Exit this program\n" 32947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".read FILENAME Execute SQL in FILENAME\n" 3295a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" 32968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ".save FILE Write in-memory database into FILE\n" 32973fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" 329860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" 329960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " Add --indent for pretty-printing\n" 3300b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ".selftest ?--init? Run tests defined in the SELFTEST table\n" 33013fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ".separator COL ?ROW? Change the column separator and optionally the row\n" 33023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " separator for both the output mode and .import\n" 330360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_ENABLE_SESSION) 330460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".session CMD ... Create or control sessions\n" 330560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 3306b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n" 33071c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" 33087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".show Show the current values for various settings\n" 330960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".stats ?on|off? Show stats or turn stats on or off\n" 33101c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ".system CMD ARGS... Run CMD ARGS... in a system shell\n" 3311a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ".tables ?TABLE? List names of tables\n" 3312a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori " If TABLE specified, only list tables matching\n" 3313a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori " LIKE pattern TABLE.\n" 331408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n" 33157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ".timeout MS Try opening locked tables for MS milliseconds\n" 33161c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ".timer on|off Turn SQL timer on or off\n" 33178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ".trace FILE|off Output each SQL statement as it is run\n" 331860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".vfsinfo ?AUX? Information about the top-level VFS\n" 331960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".vfslist List all available VFSes\n" 332090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown ".vfsname ?AUX? Print the name of the VFS stack\n" 3321a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" 33221c7cea379348522163370244e8fbbff8a136b7faNick Kralevich " Negative values right-justify\n" 33237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project; 33247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 332560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_ENABLE_SESSION) 332660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 332760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Print help information for the ".sessions" command 332860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 332960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisvoid session_help(ShellState *p){ 333060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, 333160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ".session ?NAME? SUBCOMMAND ?ARGS...?\n" 333260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "If ?NAME? is omitted, the first defined session is used.\n" 333360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "Subcommands:\n" 333460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " attach TABLE Attach TABLE\n" 333560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " changeset FILE Write a changeset into FILE\n" 333660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " close Close one session\n" 333760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " enable ?BOOLEAN? Set or query the enable bit\n" 333860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " filter GLOB... Reject tables matching GLOBs\n" 333960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " indirect ?BOOLEAN? Mark or query the indirect status\n" 334060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " isempty Query whether the session is empty\n" 334160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " list List currently open session names\n" 334260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " open DB NAME Open a new session on DB\n" 334360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis " patchset FILE Write a patchset into FILE\n" 334460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ); 334560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 334660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 334760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 334860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 33497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* Forward reference */ 33503fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic int process_input(ShellState *p, FILE *in); 335108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 335208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis/* 3353e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** Read the content of file zName into memory obtained from sqlite3_malloc64() 3354e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** and return a pointer to the buffer. The caller is responsible for freeing 3355e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** the memory. 3356e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** 3357e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes 3358e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** read. 335908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 3360e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** For convenience, a nul-terminator byte is always appended to the data read 3361e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** from the file before the buffer is returned. This byte is not included in 3362e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** the final value of (*pnByte), if applicable. 3363e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** 3364e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** NULL is returned if any error is encountered. The final value of *pnByte 3365e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** is undefined in this case. 336608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis*/ 3367e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefanistatic char *readFile(const char *zName, int *pnByte){ 336808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis FILE *in = fopen(zName, "rb"); 336908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis long nIn; 337008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis size_t nRead; 337108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis char *pBuf; 337208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( in==0 ) return 0; 337308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis fseek(in, 0, SEEK_END); 337408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis nIn = ftell(in); 337508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis rewind(in); 337608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis pBuf = sqlite3_malloc64( nIn+1 ); 337708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( pBuf==0 ) return 0; 337808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis nRead = fread(pBuf, nIn, 1, in); 337908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis fclose(in); 338008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( nRead!=1 ){ 338108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis sqlite3_free(pBuf); 338208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis return 0; 338308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 338408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis pBuf[nIn] = 0; 3385e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( pnByte ) *pnByte = nIn; 338608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis return pBuf; 338708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis} 338808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 33899bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown/* 33909bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** Implementation of the "readfile(X)" SQL function. The entire content 33919bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** of the file named X is read and returned as a BLOB. NULL is returned 33929bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** if the file does not exist or is unreadable. 33939bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown*/ 33949bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brownstatic void readfileFunc( 33959bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_context *context, 33969bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown int argc, 33979bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_value **argv 33989bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown){ 33999bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown const char *zName; 34009bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown void *pBuf; 3401e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int nBuf; 34029bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown 3403253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich UNUSED_PARAMETER(argc); 34049bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown zName = (const char*)sqlite3_value_text(argv[0]); 34059bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( zName==0 ) return; 3406e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani pBuf = readFile(zName, &nBuf); 3407e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( pBuf ) sqlite3_result_blob(context, pBuf, nBuf, sqlite3_free); 34089bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown} 34099bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown 34109bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown/* 34119bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** Implementation of the "writefile(X,Y)" SQL function. The argument Y 34129bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** is written into file X. The number of bytes written is returned. Or 34139bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** NULL is returned if something goes wrong, such as being unable to open 34149bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown** file X for writing. 34159bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown*/ 34169bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brownstatic void writefileFunc( 34179bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_context *context, 34189bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown int argc, 34199bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_value **argv 34209bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown){ 34219bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown FILE *out; 34229bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown const char *z; 34239bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_int64 rc; 34249bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown const char *zFile; 34259bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown 3426253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich UNUSED_PARAMETER(argc); 34279bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown zFile = (const char*)sqlite3_value_text(argv[0]); 34289bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( zFile==0 ) return; 34299bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown out = fopen(zFile, "wb"); 34309bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( out==0 ) return; 34319bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown z = (const char*)sqlite3_value_blob(argv[1]); 34329bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( z==0 ){ 34339bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown rc = 0; 34349bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown }else{ 34359bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); 34369bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown } 34379bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown fclose(out); 34389bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_result_int64(context, rc); 34399bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown} 34407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 344160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_ENABLE_SESSION) 344260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 344360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Close a single OpenSession object and release all of its associated 344460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** resources. 344560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 344660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic void session_close(OpenSession *pSession){ 344760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int i; 344860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3session_delete(pSession->p); 344960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(pSession->zName); 345060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<pSession->nFilter; i++){ 345160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(pSession->azFilter[i]); 345260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 345360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(pSession->azFilter); 345460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis memset(pSession, 0, sizeof(OpenSession)); 345560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 345660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 345760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 345860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 345960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Close all OpenSession objects and release all associated resources. 346060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 346160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_ENABLE_SESSION) 346260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic void session_close_all(ShellState *p){ 346360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int i; 346460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<p->nSession; i++){ 346560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis session_close(&p->aSession[i]); 346660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 346760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->nSession = 0; 346860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 346960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#else 347060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# define session_close_all(X) 347160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 347260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 347360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 347460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Implementation of the xFilter function for an open session. Omit 347560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** any tables named by ".session filter" but let all other table through. 347660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 347760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_ENABLE_SESSION) 347860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic int session_filter(void *pCtx, const char *zTab){ 347960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis OpenSession *pSession = (OpenSession*)pCtx; 348060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int i; 348160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<pSession->nFilter; i++){ 348260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0; 348360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 348460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return 1; 348560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 348660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 348760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 34887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 34897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Make sure the database is open. If it is not, then open it. If 34907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** the database fails to open, print an error message and exit. 34917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 34923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void open_db(ShellState *p, int keepAlive){ 34937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->db==0 ){ 34948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_initialize(); 34957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_open(p->zDbFilename, &p->db); 34963a6c79f802fabdb94367177310663397420e319fNick Kralevich globalDb = p->db; 34973a6c79f802fabdb94367177310663397420e319fNick Kralevich if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ 349860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", 34993a6c79f802fabdb94367177310663397420e319fNick Kralevich p->zDbFilename, sqlite3_errmsg(p->db)); 35008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( keepAlive ) return; 35017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project exit(1); 35027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 35037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifndef SQLITE_OMIT_LOAD_EXTENSION 35047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_enable_load_extension(p->db, 1); 35057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 35063a6c79f802fabdb94367177310663397420e319fNick Kralevich sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0, 35079bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown readfileFunc, 0, 0); 35083a6c79f802fabdb94367177310663397420e319fNick Kralevich sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0, 35099bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown writefileFunc, 0, 0); 3510b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_create_function(p->db, "sha3", 1, SQLITE_UTF8, 0, 3511b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sha3Func, 0, 0); 3512b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_create_function(p->db, "sha3", 2, SQLITE_UTF8, 0, 3513b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sha3Func, 0, 0); 3514b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_create_function(p->db, "sha3_query", 1, SQLITE_UTF8, 0, 3515b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sha3QueryFunc, 0, 0); 3516b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_create_function(p->db, "sha3_query", 2, SQLITE_UTF8, 0, 3517b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sha3QueryFunc, 0, 0); 35189bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown 3519c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori // Begin Android Add 3520c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori #ifndef NO_ANDROID_FUNCS 352155536230a14a7c199bbe41a83893c7d82e0c0a24Neil Fuller InitializeIcuOrDie(); 35223a6c79f802fabdb94367177310663397420e319fNick Kralevich int err = register_localized_collators(p->db, "en_US", 0); 3523c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori if (err != SQLITE_OK) { 3524c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori fprintf(stderr, "register_localized_collators() failed\n"); 3525c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori exit(1); 3526c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori } 35273a6c79f802fabdb94367177310663397420e319fNick Kralevich err = register_android_functions(p->db, 0); 3528c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori if (err != SQLITE_OK) { 3529c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori fprintf(stderr, "register_android_functions() failed\n"); 3530c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori exit(1); 3531c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori } 3532c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori #endif 3533c296bf9f8755fadd4e87c76f0a66d9e626c51b55Vasu Nori // End Android Add 35347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 35357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 35367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 35377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 35387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Do C-language style dequoting. 35397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 35403a6c79f802fabdb94367177310663397420e319fNick Kralevich** \a -> alarm 35413a6c79f802fabdb94367177310663397420e319fNick Kralevich** \b -> backspace 35427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** \t -> tab 35437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** \n -> newline 35443a6c79f802fabdb94367177310663397420e319fNick Kralevich** \v -> vertical tab 35453a6c79f802fabdb94367177310663397420e319fNick Kralevich** \f -> form feed 35467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** \r -> carriage return 35473a6c79f802fabdb94367177310663397420e319fNick Kralevich** \s -> space 35488fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** \" -> " 35493a6c79f802fabdb94367177310663397420e319fNick Kralevich** \' -> ' 35507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** \\ -> backslash 35513a6c79f802fabdb94367177310663397420e319fNick Kralevich** \NNN -> ascii character NNN in octal 35527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 35537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void resolve_backslashes(char *z){ 3554a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int i, j; 3555a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori char c; 35561c7cea379348522163370244e8fbbff8a136b7faNick Kralevich while( *z && *z!='\\' ) z++; 35577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=j=0; (c = z[i])!=0; i++, j++){ 35583a6c79f802fabdb94367177310663397420e319fNick Kralevich if( c=='\\' && z[i+1]!=0 ){ 35597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project c = z[++i]; 35603a6c79f802fabdb94367177310663397420e319fNick Kralevich if( c=='a' ){ 35613a6c79f802fabdb94367177310663397420e319fNick Kralevich c = '\a'; 35623a6c79f802fabdb94367177310663397420e319fNick Kralevich }else if( c=='b' ){ 35633a6c79f802fabdb94367177310663397420e319fNick Kralevich c = '\b'; 35647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( c=='t' ){ 35657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project c = '\t'; 35663a6c79f802fabdb94367177310663397420e319fNick Kralevich }else if( c=='n' ){ 35673a6c79f802fabdb94367177310663397420e319fNick Kralevich c = '\n'; 35683a6c79f802fabdb94367177310663397420e319fNick Kralevich }else if( c=='v' ){ 35693a6c79f802fabdb94367177310663397420e319fNick Kralevich c = '\v'; 35703a6c79f802fabdb94367177310663397420e319fNick Kralevich }else if( c=='f' ){ 35713a6c79f802fabdb94367177310663397420e319fNick Kralevich c = '\f'; 35727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( c=='r' ){ 35737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project c = '\r'; 35743a6c79f802fabdb94367177310663397420e319fNick Kralevich }else if( c=='"' ){ 35753a6c79f802fabdb94367177310663397420e319fNick Kralevich c = '"'; 35763a6c79f802fabdb94367177310663397420e319fNick Kralevich }else if( c=='\'' ){ 35773a6c79f802fabdb94367177310663397420e319fNick Kralevich c = '\''; 35788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( c=='\\' ){ 35798fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich c = '\\'; 35807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( c>='0' && c<='7' ){ 35817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project c -= '0'; 35827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( z[i+1]>='0' && z[i+1]<='7' ){ 35837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project i++; 35847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project c = (c<<3) + z[i] - '0'; 35857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( z[i+1]>='0' && z[i+1]<='7' ){ 35867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project i++; 35877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project c = (c<<3) + z[i] - '0'; 35887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 35897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 35907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 35917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 35927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z[j] = c; 35937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 35941c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( j<i ) z[j] = 0; 35957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 35967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 35977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 35988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Return the value of a hexadecimal digit. Return -1 if the input 35998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** is not a hex digit. 36008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 36018fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic int hexDigitValue(char c){ 36028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c>='0' && c<='9' ) return c - '0'; 36038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c>='a' && c<='f' ) return c - 'a' + 10; 36048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c>='A' && c<='F' ) return c - 'A' + 10; 36058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return -1; 36068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 36078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 36088fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 36098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Interpret zArg as an integer value, possibly with suffixes. 36108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 36118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic sqlite3_int64 integerValue(const char *zArg){ 36128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_int64 v = 0; 36138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich static const struct { char *zSuffix; int iMult; } aMult[] = { 36148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "KiB", 1024 }, 36158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "MiB", 1024*1024 }, 36168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "GiB", 1024*1024*1024 }, 36178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "KB", 1000 }, 36188fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "MB", 1000000 }, 36198fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "GB", 1000000000 }, 36208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "K", 1000 }, 36218fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "M", 1000000 }, 36228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { "G", 1000000000 }, 36238fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }; 36248fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int i; 36258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int isNeg = 0; 36268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zArg[0]=='-' ){ 36278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich isNeg = 1; 36288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zArg++; 36298fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( zArg[0]=='+' ){ 36308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zArg++; 36318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 36328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zArg[0]=='0' && zArg[1]=='x' ){ 36338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int x; 36348fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zArg += 2; 36358fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( (x = hexDigitValue(zArg[0]))>=0 ){ 36368fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich v = (v<<4) + x; 36378fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zArg++; 36388fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 36398fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 36408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( IsDigit(zArg[0]) ){ 36418fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich v = v*10 + zArg[0] - '0'; 36428fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zArg++; 36438fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 36448fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 36458fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=0; i<ArraySize(aMult); i++){ 36468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ 36478fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich v *= aMult[i].iMult; 36488fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 36498fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 36508fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 36518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return isNeg? -v : v; 36528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 36538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 36548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 36558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Interpret zArg as either an integer or a boolean value. Return 1 or 0 36568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** for TRUE and FALSE. Return the integer value if appropriate. 36577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 3658b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic int booleanValue(const char *zArg){ 36598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int i; 36608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zArg[0]=='0' && zArg[1]=='x' ){ 36618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=2; hexDigitValue(zArg[i])>=0; i++){} 36628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 36638fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} 36648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 36658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff); 36668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ 36678fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 1; 36687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 36698fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ 36708fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 0; 36717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 367260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", 36738fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zArg); 36748fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 0; 36758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 36768fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 36778fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 3678b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis** Set or clear a shell flag according to a boolean value. 3679b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis*/ 3680b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidisstatic void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){ 3681b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( booleanValue(zArg) ){ 3682b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellSetFlag(p, mFlag); 3683b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 3684b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellClearFlag(p, mFlag); 3685b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 3686b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis} 3687b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 3688b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis/* 36898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Close an output file, assuming it is not stderr or stdout 36908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 36918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic void output_file_close(FILE *f){ 36928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( f && f!=stdout && f!=stderr ) fclose(f); 36938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 36948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 36958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 36968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Try to open an output file. The names "stdout" and "stderr" are 369760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** recognized and do the right thing. NULL is returned if the output 36988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** filename is "off". 36998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 37008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic FILE *output_file_open(const char *zFile){ 37018fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich FILE *f; 37028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( strcmp(zFile,"stdout")==0 ){ 37038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich f = stdout; 37048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( strcmp(zFile, "stderr")==0 ){ 37058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich f = stderr; 37068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( strcmp(zFile, "off")==0 ){ 37078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich f = 0; 37088fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 37098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich f = fopen(zFile, "wb"); 37108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( f==0 ){ 371160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); 37128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 37138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 37148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return f; 37158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 37168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 3717e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#if !defined(SQLITE_UNTESTABLE) 3718e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) 37198fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 37208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** A routine for handling output from sqlite3_trace(). 37218fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 372274bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidisstatic int sql_trace_callback( 372374bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis unsigned mType, 372474bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis void *pArg, 372574bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis void *pP, 372674bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis void *pX 372774bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis){ 37288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich FILE *f = (FILE*)pArg; 372974bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis UNUSED_PARAMETER(mType); 373074bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis UNUSED_PARAMETER(pP); 37313fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( f ){ 373274bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis const char *z = (const char*)pX; 37333fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int i = (int)strlen(z); 37343fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich while( i>0 && z[i-1]==';' ){ i--; } 373560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(f, "%.*s;\n", i, z); 37363fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 373774bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis return 0; 37388fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 3739e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#endif 3740e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#endif 37418fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 37428fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 37438fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** A no-op routine that runs with the ".breakpoint" doc-command. This is 37448fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** a useful spot to set a debugger breakpoint. 37458fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 37468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic void test_breakpoint(void){ 37478fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich static int nCall = 0; 37488fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich nCall++; 37498fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 37508fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 37518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 37523fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** An object used to read a CSV and other files for import. 37538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 37543fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichtypedef struct ImportCtx ImportCtx; 37553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstruct ImportCtx { 37568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *zFile; /* Name of the input file */ 37578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich FILE *in; /* Read the CSV text from this input stream */ 37588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *z; /* Accumulated text for a field */ 37598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int n; /* Number of bytes in z */ 37608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nAlloc; /* Space allocated for z[] */ 37618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nLine; /* Current line number */ 37628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int cTerm; /* Character that terminated the most recent field */ 37633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int cColSep; /* The column separator character. (Usually ",") */ 37643fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int cRowSep; /* The row separator character. (Usually "\n") */ 37658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich}; 37668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 37678fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* Append a single byte to z[] */ 37683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void import_append_char(ImportCtx *p, int c){ 37698fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( p->n+1>=p->nAlloc ){ 37708fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->nAlloc += p->nAlloc + 100; 37713a6c79f802fabdb94367177310663397420e319fNick Kralevich p->z = sqlite3_realloc64(p->z, p->nAlloc); 37728fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( p->z==0 ){ 377360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "out of memory\n"); 37748fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich exit(1); 37758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 37768fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 37778fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->z[p->n++] = (char)c; 37788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 37798fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 37808fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* Read a single field of CSV text. Compatible with rfc4180 and extended 37818fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** with the option of having a separator other than ",". 37828fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** 37838fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** + Input comes from p->in. 37848fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** + Store results in p->z of length p->n. Space to hold p->z comes 37853a6c79f802fabdb94367177310663397420e319fNick Kralevich** from sqlite3_malloc64(). 37863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Use p->cSep as the column separator. The default is ",". 37873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Use p->rSep as the row separator. The default is "\n". 37888fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** + Keep track of the line number in p->nLine. 37898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** + Store the character that terminates the field in p->cTerm. Store 37908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** EOF on end-of-file. 37918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** + Report syntax errors on stderr 37928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 37933fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ 37943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int c; 37953fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int cSep = p->cColSep; 37963fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int rSep = p->cRowSep; 37978fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->n = 0; 37988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich c = fgetc(p->in); 37998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c==EOF || seenInterrupt ){ 38008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->cTerm = EOF; 38018fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 0; 38028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c=='"' ){ 38043fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int pc, ppc; 38058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int startLine = p->nLine; 38068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int cQuote = c; 38078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich pc = ppc = 0; 38088fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( 1 ){ 38098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich c = fgetc(p->in); 38103fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( c==rSep ) p->nLine++; 38118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c==cQuote ){ 38128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( pc==cQuote ){ 38138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich pc = 0; 38148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich continue; 38158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( (c==cSep && pc==cQuote) 38183fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich || (c==rSep && pc==cQuote) 38193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich || (c==rSep && pc=='\r' && ppc==cQuote) 38208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich || (c==EOF && pc==cQuote) 38218fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ){ 38228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich do{ p->n--; }while( p->z[p->n]!=cQuote ); 38238fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->cTerm = c; 38248fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 38258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( pc==cQuote && c!='\r' ){ 382760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "%s:%d: unescaped %c character\n", 38288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->zFile, p->nLine, cQuote); 38298fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c==EOF ){ 383160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n", 38328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->zFile, startLine, cQuote); 38333fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich p->cTerm = c; 38348fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 38358fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38363fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich import_append_char(p, c); 38378fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ppc = pc; 38388fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich pc = c; 38398fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 38413fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich while( c!=EOF && c!=cSep && c!=rSep ){ 38423fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich import_append_char(p, c); 38438fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich c = fgetc(p->in); 38448fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38453fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( c==rSep ){ 38468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->nLine++; 38478fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; 38488fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38498fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->cTerm = c; 38508fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 38518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( p->z ) p->z[p->n] = 0; 38528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return p->z; 38538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 38548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 38553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* Read a single field of ASCII delimited text. 38563fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** 38573fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Input comes from p->in. 38583fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Store results in p->z of length p->n. Space to hold p->z comes 38593a6c79f802fabdb94367177310663397420e319fNick Kralevich** from sqlite3_malloc64(). 38603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Use p->cSep as the column separator. The default is "\x1F". 38613fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Use p->rSep as the row separator. The default is "\x1E". 38623fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Keep track of the row number in p->nLine. 38633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Store the character that terminates the field in p->cTerm. Store 38643fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** EOF on end-of-file. 38653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** + Report syntax errors on stderr 38663fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 38673fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){ 38683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int c; 38693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int cSep = p->cColSep; 38703fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int rSep = p->cRowSep; 38713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich p->n = 0; 38723fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich c = fgetc(p->in); 38733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( c==EOF || seenInterrupt ){ 38743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich p->cTerm = EOF; 38753fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return 0; 38763fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 38773fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich while( c!=EOF && c!=cSep && c!=rSep ){ 38783fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich import_append_char(p, c); 38793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich c = fgetc(p->in); 38803fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 38813fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( c==rSep ){ 38823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich p->nLine++; 38833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 38843fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich p->cTerm = c; 38853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( p->z ) p->z[p->n] = 0; 38863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return p->z; 38873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich} 38883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 38898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 38908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Try to transfer data for table zTable. If an error is seen while 38918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** moving forward, try to go backwards. The backwards movement won't 38928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** work for WITHOUT ROWID tables. 38938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 38948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic void tryToCloneData( 38953fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *p, 38968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3 *newDb, 38978fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *zTable 38988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich){ 389960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_stmt *pQuery = 0; 39008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_stmt *pInsert = 0; 39018fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zQuery = 0; 39028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zInsert = 0; 39038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int rc; 39048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int i, j, n; 39058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nTable = (int)strlen(zTable); 39068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int k = 0; 39078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int cnt = 0; 39088fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const int spinRate = 10000; 39098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 39108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); 39118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); 39128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc ){ 391360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error %d: %s on [%s]\n", 39148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), 39158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zQuery); 39168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich goto end_data_xfer; 39178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39188fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich n = sqlite3_column_count(pQuery); 39193a6c79f802fabdb94367177310663397420e319fNick Kralevich zInsert = sqlite3_malloc64(200 + nTable + n*3); 39208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zInsert==0 ){ 392160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "out of memory\n"); 39228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich goto end_data_xfer; 39238fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39248fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_snprintf(200+nTable,zInsert, 39258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); 39268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich i = (int)strlen(zInsert); 39278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(j=1; j<n; j++){ 39288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich memcpy(zInsert+i, ",?", 2); 39298fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich i += 2; 39308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich memcpy(zInsert+i, ");", 3); 39328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); 39338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc ){ 393460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error %d: %s on [%s]\n", 39358fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), 39368fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zQuery); 39378fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich goto end_data_xfer; 39388fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39398fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(k=0; k<2; k++){ 39408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ 39418fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=0; i<n; i++){ 39428fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich switch( sqlite3_column_type(pQuery, i) ){ 39438fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich case SQLITE_NULL: { 39448fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_bind_null(pInsert, i+1); 39458fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 39468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39478fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich case SQLITE_INTEGER: { 39488fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i)); 39498fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 39508fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich case SQLITE_FLOAT: { 39528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i)); 39538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 39548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich case SQLITE_TEXT: { 39568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_bind_text(pInsert, i+1, 39578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich (const char*)sqlite3_column_text(pQuery,i), 39588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich -1, SQLITE_STATIC); 39598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 39608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich case SQLITE_BLOB: { 39628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i), 39638fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_column_bytes(pQuery,i), 39648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich SQLITE_STATIC); 39658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 39668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39678fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39688fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } /* End for */ 39698fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_step(pInsert); 39708fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ 397160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb), 39728fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_errmsg(newDb)); 39738fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39748fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_reset(pInsert); 39758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich cnt++; 39768fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( (cnt%spinRate)==0 ){ 39778fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("%c\b", "|/-\\"[(cnt/spinRate)%4]); 39788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich fflush(stdout); 39798fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39808fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } /* End while */ 39818fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc==SQLITE_DONE ) break; 39828fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_finalize(pQuery); 39838fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zQuery); 39848fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;", 39858fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zTable); 39868fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); 39878fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc ){ 398860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable); 39898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 39908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 39918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } /* End for(k=0...) */ 39928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 39938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichend_data_xfer: 39948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_finalize(pQuery); 39958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_finalize(pInsert); 39968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zQuery); 39978fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zInsert); 39988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 39998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 40008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 40018fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 40028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Try to transfer all rows of the schema that match zWhere. For 40038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** each row, invoke xForEach() on the object defined by that row. 40048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** If an error is encountered while moving forward through the 40058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** sqlite_master table, try again moving backwards. 40068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 40078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic void tryToCloneSchema( 40083fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *p, 40098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3 *newDb, 40108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *zWhere, 40113fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich void (*xForEach)(ShellState*,sqlite3*,const char*) 40128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich){ 40138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_stmt *pQuery = 0; 40148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zQuery = 0; 40158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int rc; 40168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const unsigned char *zName; 40178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const unsigned char *zSql; 40188fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zErrMsg = 0; 40198fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 40208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" 40218fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " WHERE %s", zWhere); 40228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); 40238fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc ){ 402460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: (%d) %s on [%s]\n", 40258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), 40268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zQuery); 40278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich goto end_schema_xfer; 40288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40298fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ 40308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zName = sqlite3_column_text(pQuery, 0); 40318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zSql = sqlite3_column_text(pQuery, 1); 40328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("%s... ", zName); fflush(stdout); 40338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); 40348fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zErrMsg ){ 403560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); 40368fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zErrMsg); 40378fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zErrMsg = 0; 40388fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40398fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( xForEach ){ 40408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich xForEach(p, newDb, (const char*)zName); 40418fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40428fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("done\n"); 40438fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40448fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc!=SQLITE_DONE ){ 40458fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_finalize(pQuery); 40468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zQuery); 40478fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" 40488fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " WHERE %s ORDER BY rowid DESC", zWhere); 40498fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); 40508fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc ){ 405160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: (%d) %s on [%s]\n", 40528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), 40538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zQuery); 40548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich goto end_schema_xfer; 40558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ 40578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zName = sqlite3_column_text(pQuery, 0); 40588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zSql = sqlite3_column_text(pQuery, 1); 40598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("%s... ", zName); fflush(stdout); 40608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); 40618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zErrMsg ){ 406260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); 40638fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zErrMsg); 40648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zErrMsg = 0; 40658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( xForEach ){ 40678fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich xForEach(p, newDb, (const char*)zName); 40688fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40698fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("done\n"); 40708fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40718fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40728fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichend_schema_xfer: 40738fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_finalize(pQuery); 40748fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zQuery); 40758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 40768fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 40778fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 40788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Open a new database file named "zNewDb". Try to recover as much information 40798fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** as possible out of the main database (which might be corrupt) and write it 40808fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** into zNewDb. 40818fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 40823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void tryToClone(ShellState *p, const char *zNewDb){ 40838fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int rc; 40848fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3 *newDb = 0; 40858fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( access(zNewDb,0)==0 ){ 408660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb); 40878fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return; 40888fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 40898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_open(zNewDb, &newDb); 40908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc ){ 409160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Cannot create output database: %s\n", 40928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_errmsg(newDb)); 40938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 40941c7cea379348522163370244e8fbbff8a136b7faNick Kralevich sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); 40958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); 40968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); 40978fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich tryToCloneSchema(p, newDb, "type!='table'", 0); 40988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); 40991c7cea379348522163370244e8fbbff8a136b7faNick Kralevich sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); 41008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 41018fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_close(newDb); 41027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 41037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 41047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 41051c7cea379348522163370244e8fbbff8a136b7faNick Kralevich** Change the output file back to stdout 41061c7cea379348522163370244e8fbbff8a136b7faNick Kralevich*/ 41073fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void output_reset(ShellState *p){ 41081c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( p->outfile[0]=='|' ){ 41093fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#ifndef SQLITE_OMIT_POPEN 41101c7cea379348522163370244e8fbbff8a136b7faNick Kralevich pclose(p->out); 41113fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 41121c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 41131c7cea379348522163370244e8fbbff8a136b7faNick Kralevich output_file_close(p->out); 41141c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 41151c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->outfile[0] = 0; 41161c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->out = stdout; 41171c7cea379348522163370244e8fbbff8a136b7faNick Kralevich} 41181c7cea379348522163370244e8fbbff8a136b7faNick Kralevich 41191c7cea379348522163370244e8fbbff8a136b7faNick Kralevich/* 41203fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** Run an SQL command and return the single integer result. 41213fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 41223fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic int db_int(ShellState *p, const char *zSql){ 41233fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_stmt *pStmt; 41243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int res = 0; 41253fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 41263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ 41273fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich res = sqlite3_column_int(pStmt,0); 41283fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 41293fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_finalize(pStmt); 41303fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return res; 41313fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich} 41323fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 41333fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 41343fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** Convert a 2-byte or 4-byte big-endian integer into a native integer 41353fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 413674bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidisstatic unsigned int get2byteInt(unsigned char *a){ 41373fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return (a[0]<<8) + a[1]; 41383fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich} 413974bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidisstatic unsigned int get4byteInt(unsigned char *a){ 41403fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; 41413fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich} 41423fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 41433fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 41443fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** Implementation of the ".info" command. 41453fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** 41463fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich** Return 1 on error, 2 to exit, and 0 otherwise. 41473fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich*/ 41483fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ 41493fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich static const struct { const char *zName; int ofst; } aField[] = { 41503fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "file change counter:", 24 }, 41513fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "database page count:", 28 }, 41523fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "freelist page count:", 36 }, 41533fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "schema cookie:", 40 }, 41543fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "schema format:", 44 }, 41553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "default cache size:", 48 }, 41563fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "autovacuum top root:", 52 }, 41573fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "incremental vacuum:", 64 }, 41583fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "text encoding:", 56 }, 41593fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "user version:", 60 }, 41603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "application id:", 68 }, 41613fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "software version:", 96 }, 41623fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }; 41633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich static const struct { const char *zName; const char *zSql; } aQuery[] = { 41643fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "number of tables:", 41653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "SELECT count(*) FROM %s WHERE type='table'" }, 41663fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "number of indexes:", 41673fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "SELECT count(*) FROM %s WHERE type='index'" }, 41683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "number of triggers:", 41693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "SELECT count(*) FROM %s WHERE type='trigger'" }, 41703fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "number of views:", 41713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "SELECT count(*) FROM %s WHERE type='view'" }, 41723fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "schema size:", 41733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "SELECT total(length(sql)) FROM %s" }, 41743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }; 417560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_file *pFile = 0; 41763fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int i; 41773fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char *zSchemaTab; 41783fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char *zDb = nArg>=2 ? azArg[1] : "main"; 41793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich unsigned char aHdr[100]; 41803fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich open_db(p, 0); 41813fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( p->db==0 ) return 1; 41823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); 41833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ 41843fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return 1; 41853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 41863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); 41873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( i!=SQLITE_OK ){ 418860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "unable to read database header\n"); 41893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return 1; 41903fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 41913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich i = get2byteInt(aHdr+16); 41923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( i==1 ) i = 65536; 419360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%-20s %d\n", "database page size:", i); 419460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]); 419560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]); 419660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); 4197253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich for(i=0; i<ArraySize(aField); i++){ 41983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int ofst = aField[i].ofst; 41993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich unsigned int val = get4byteInt(aHdr + ofst); 420060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%-20s %u", aField[i].zName, val); 42013fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich switch( ofst ){ 42023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich case 56: { 420360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( val==1 ) raw_printf(p->out, " (utf8)"); 420460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( val==2 ) raw_printf(p->out, " (utf16le)"); 420560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( val==3 ) raw_printf(p->out, " (utf16be)"); 42063fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 42073fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 420860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n"); 42093fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 42103fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( zDb==0 ){ 42113fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich zSchemaTab = sqlite3_mprintf("main.sqlite_master"); 42123fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(zDb,"temp")==0 ){ 42133fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master"); 42143fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else{ 42153fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); 42163fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 4217253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich for(i=0; i<ArraySize(aQuery); i++){ 42183fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); 42193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int val = db_int(p, zSql); 42203fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_free(zSql); 422160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val); 42223fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 42233fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_free(zSchemaTab); 42243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return 0; 42253fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich} 42263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 4227253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich/* 4228253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich** Print the current sqlite3_errmsg() value to stderr and return 1. 4229253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich*/ 4230253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevichstatic int shellDatabaseError(sqlite3 *db){ 4231253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich const char *zErr = sqlite3_errmsg(db); 423260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\n", zErr); 4233253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich return 1; 4234253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich} 4235253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich 4236253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich/* 4237253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich** Print an out-of-memory message to stderr and return 1. 4238253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich*/ 4239253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevichstatic int shellNomemError(void){ 424060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: out of memory\n"); 4241253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich return 1; 4242253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich} 42433fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 42443fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich/* 424508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** Compare the pattern in zGlob[] against the text in z[]. Return TRUE 424608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** if they match and FALSE (0) if they do not match. 424708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 424808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** Globbing rules: 424908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 425008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** '*' Matches any sequence of zero or more characters. 425108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 425208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** '?' Matches exactly one character. 425308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 425408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** [...] Matches one character from the enclosed list of 425508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** characters. 425608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 425708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** [^...] Matches one character not in the enclosed list. 425808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 425908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** '#' Matches any sequence of one or more digits with an 426008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** optional + or - sign in front 426108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 426208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** ' ' Any span of whitespace matches any other span of 426308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** whitespace. 426408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** 426508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** Extra whitespace at the end of z[] is ignored. 426608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis*/ 426708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidisstatic int testcase_glob(const char *zGlob, const char *z){ 426808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis int c, c2; 426908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis int invert; 427008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis int seen; 427108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 427208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( (c = (*(zGlob++)))!=0 ){ 427308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( IsSpace(c) ){ 427408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( !IsSpace(*z) ) return 0; 427508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( IsSpace(*zGlob) ) zGlob++; 427608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( IsSpace(*z) ) z++; 427708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else if( c=='*' ){ 427808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( (c=(*(zGlob++))) == '*' || c=='?' ){ 427908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c=='?' && (*(z++))==0 ) return 0; 428008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 428108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c==0 ){ 428208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis return 1; 428308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else if( c=='[' ){ 428408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( *z && testcase_glob(zGlob-1,z)==0 ){ 428508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis z++; 428608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 428708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis return (*z)!=0; 428808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 428908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( (c2 = (*(z++)))!=0 ){ 429008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( c2!=c ){ 429108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis c2 = *(z++); 429208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c2==0 ) return 0; 429308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 429408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( testcase_glob(zGlob,z) ) return 1; 429508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 429608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis return 0; 429708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else if( c=='?' ){ 429808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( (*(z++))==0 ) return 0; 429908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else if( c=='[' ){ 430008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis int prior_c = 0; 430108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis seen = 0; 430208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis invert = 0; 430308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis c = *(z++); 430408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c==0 ) return 0; 430508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis c2 = *(zGlob++); 430608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c2=='^' ){ 430708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis invert = 1; 430808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis c2 = *(zGlob++); 430908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 431008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c2==']' ){ 431108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c==']' ) seen = 1; 431208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis c2 = *(zGlob++); 431308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 431408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( c2 && c2!=']' ){ 431508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ 431608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis c2 = *(zGlob++); 431708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c>=prior_c && c<=c2 ) seen = 1; 431808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis prior_c = 0; 431908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else{ 432008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c==c2 ){ 432108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis seen = 1; 432208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 432308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis prior_c = c2; 432408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 432508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis c2 = *(zGlob++); 432608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 432708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c2==0 || (seen ^ invert)==0 ) return 0; 432808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else if( c=='#' ){ 432908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++; 433008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( !IsDigit(z[0]) ) return 0; 433108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis z++; 433208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( IsDigit(z[0]) ){ z++; } 433308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else{ 433408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c!=(*(z++)) ) return 0; 433508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 433608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 433708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis while( IsSpace(*z) ){ z++; } 433808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis return *z==0; 433908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis} 434008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 434108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 434208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis/* 434360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** Compare the string as a command-line option with either one or two 434460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis** initial "-" characters. 434560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis*/ 434660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic int optionMatch(const char *zStr, const char *zOpt){ 434760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( zStr[0]!='-' ) return 0; 434860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis zStr++; 434960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( zStr[0]=='-' ) zStr++; 435060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis return strcmp(zStr, zOpt)==0; 435160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis} 435260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 435360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis/* 435408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis** Delete a file. 435508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis*/ 435608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidisint shellDeleteFile(const char *zFilename){ 435708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis int rc; 435808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#ifdef _WIN32 435908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename); 436008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis rc = _wunlink(z); 436108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis sqlite3_free(z); 436208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#else 436308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis rc = unlink(zFilename); 436408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#endif 436508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis return rc; 436608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis} 436708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 4368e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4369e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani/* 4370e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** The implementation of SQL scalar function fkey_collate_clause(), used 4371e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** by the ".lint fkey-indexes" command. This scalar function is always 4372e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** called with four arguments - the parent table name, the parent column name, 4373e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** the child table name and the child column name. 4374e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** 4375e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col') 4376e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** 4377e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** If either of the named tables or columns do not exist, this function 4378e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** returns an empty string. An empty string is also returned if both tables 4379e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** and columns exist but have the same default collation sequence. Or, 4380e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** if both exist but the default collation sequences are different, this 4381e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** function returns the string " COLLATE <parent-collation>", where 4382e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** <parent-collation> is the default collation sequence of the parent column. 4383e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani*/ 4384e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefanistatic void shellFkeyCollateClause( 4385e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_context *pCtx, 4386e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int nVal, 4387e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_value **apVal 4388e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani){ 4389e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3 *db = sqlite3_context_db_handle(pCtx); 4390e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zParent; 4391e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zParentCol; 4392e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zParentSeq; 4393e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zChild; 4394e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zChildCol; 4395e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */ 4396e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int rc; 4397e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4398e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani assert( nVal==4 ); 4399e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zParent = (const char*)sqlite3_value_text(apVal[0]); 4400e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zParentCol = (const char*)sqlite3_value_text(apVal[1]); 4401e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zChild = (const char*)sqlite3_value_text(apVal[2]); 4402e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zChildCol = (const char*)sqlite3_value_text(apVal[3]); 4403e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4404e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); 4405e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_table_column_metadata( 4406e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0 4407e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ); 4408e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc==SQLITE_OK ){ 4409e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_table_column_metadata( 4410e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0 4411e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ); 4412e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4413e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4414e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){ 4415e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq); 4416e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); 4417e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_free(z); 4418e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4419e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani} 4420e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4421e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4422e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani/* 4423e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** The implementation of dot-command ".lint fkey-indexes". 4424e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani*/ 4425e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefanistatic int lintFkeyIndexes( 4426e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ShellState *pState, /* Current shell tool state */ 4427e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char **azArg, /* Array of arguments passed to dot command */ 4428e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int nArg /* Number of entries in azArg[] */ 4429e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani){ 4430e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3 *db = pState->db; /* Database handle to query "main" db of */ 4431e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani FILE *out = pState->out; /* Stream to write non-error output to */ 4432e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int bVerbose = 0; /* If -verbose is present */ 4433e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int bGroupByParent = 0; /* If -groupbyparent is present */ 4434e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int i; /* To iterate through azArg[] */ 4435e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zIndent = ""; /* How much to indent CREATE INDEX by */ 4436e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int rc; /* Return code */ 4437e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ 4438e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4439e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani /* 4440e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** This SELECT statement returns one row for each foreign key constraint 4441e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** in the schema of the main database. The column values are: 4442e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4443e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 0. The text of an SQL statement similar to: 4444e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4445e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?" 4446e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4447e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** This is the same SELECT that the foreign keys implementation needs 4448e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** to run internally on child tables. If there is an index that can 4449e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** be used to optimize this query, then it can also be used by the FK 4450e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** implementation to optimize DELETE or UPDATE statements on the parent 4451e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** table. 4452e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4453e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by 4454e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema 4455e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** contains an index that can be used to optimize the query. 4456e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4457e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 2. Human readable text that describes the child table and columns. e.g. 4458e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4459e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** "child_table(child_key1, child_key2)" 4460e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4461e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 3. Human readable text that describes the parent table and columns. e.g. 4462e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4463e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** "parent_table(parent_key1, parent_key2)" 4464e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4465e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4. A full CREATE INDEX statement for an index that could be used to 4466e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** optimize DELETE or UPDATE statements on the parent table. e.g. 4467e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4468e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** "CREATE INDEX child_table_child_key ON child_table(child_key)" 4469e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4470e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 5. The name of the parent table. 4471e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** 4472e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** These six values are used by the C logic below to generate the report. 4473e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani */ 4474e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zSql = 4475e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "SELECT " 4476e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '" 4477e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " 4478b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis " || fkey_collate_clause(" 4479b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" 4480e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ", " 4481e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('" 4482e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " || group_concat('*=?', ' AND ') || ')'" 4483e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ", " 4484e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " s.name || '(' || group_concat(f.[from], ', ') || ')'" 4485e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ", " 4486b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'" 4487e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ", " 4488e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))" 4489e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " || ' ON ' || quote(s.name) || '('" 4490e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " || group_concat(quote(f.[from]) ||" 4491b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis " fkey_collate_clause(" 4492b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')" 4493e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " || ');'" 4494e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ", " 4495e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " f.[table] " 4496e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f " 4497b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) " 4498e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "GROUP BY s.name, f.id " 4499e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" 4500e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ; 4501b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)"; 4502e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4503e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani for(i=2; i<nArg; i++){ 4504e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int n = (int)strlen(azArg[i]); 4505e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ 4506e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani bVerbose = 1; 4507e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4508e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){ 4509e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani bGroupByParent = 1; 4510e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zIndent = " "; 4511e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4512e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani else{ 4513e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n", 4514e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani azArg[0], azArg[1] 4515e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ); 4516e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani return SQLITE_ERROR; 4517e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4518e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4519e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4520e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani /* Register the fkey_collate_clause() SQL function */ 4521e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8, 4522e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 0, shellFkeyCollateClause, 0, 0 4523e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ); 4524e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4525e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4526e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc==SQLITE_OK ){ 4527e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); 4528e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4529e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc==SQLITE_OK ){ 4530e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_bind_int(pSql, 1, bGroupByParent); 4531e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4532e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4533e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc==SQLITE_OK ){ 4534e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int rc2; 4535e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char *zPrev = 0; 4536e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani while( SQLITE_ROW==sqlite3_step(pSql) ){ 4537e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int res = -1; 4538e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_stmt *pExplain = 0; 4539e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zEQP = (const char*)sqlite3_column_text(pSql, 0); 4540e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zGlob = (const char*)sqlite3_column_text(pSql, 1); 4541e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zFrom = (const char*)sqlite3_column_text(pSql, 2); 4542e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zTarget = (const char*)sqlite3_column_text(pSql, 3); 4543e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zCI = (const char*)sqlite3_column_text(pSql, 4); 4544e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zParent = (const char*)sqlite3_column_text(pSql, 5); 4545e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4546e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); 4547e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc!=SQLITE_OK ) break; 4548e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( SQLITE_ROW==sqlite3_step(pExplain) ){ 4549e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3); 4550b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis res = ( 4551b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis 0==sqlite3_strglob(zGlob, zPlan) 4552b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis || 0==sqlite3_strglob(zGlobIPK, zPlan) 4553b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis ); 4554e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4555e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_finalize(pExplain); 4556e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc!=SQLITE_OK ) break; 4557e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4558e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( res<0 ){ 4559e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "Error: internal error"); 4560e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani break; 4561e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 4562e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( bGroupByParent 4563e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani && (bVerbose || res==0) 4564e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) 4565e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ){ 4566e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(out, "-- Parent table %s\n", zParent); 4567e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_free(zPrev); 4568e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zPrev = sqlite3_mprintf("%s", zParent); 4569e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4570e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4571e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( res==0 ){ 4572e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); 4573e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else if( bVerbose ){ 4574e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n", 4575e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zIndent, zFrom, zTarget 4576e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ); 4577e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4578e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4579e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4580e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_free(zPrev); 4581e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4582e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc!=SQLITE_OK ){ 4583e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); 4584e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4585e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4586e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc2 = sqlite3_finalize(pSql); 4587e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ 4588e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = rc2; 4589e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); 4590e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4591e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 4592e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); 4593e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 4594e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4595e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani return rc; 4596e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani} 4597e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4598e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani/* 4599e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** Implementation of ".lint" dot command. 4600e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani*/ 4601e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefanistatic int lintDotCommand( 4602e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ShellState *pState, /* Current shell tool state */ 4603e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char **azArg, /* Array of arguments passed to dot command */ 4604e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int nArg /* Number of entries in azArg[] */ 4605e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani){ 4606e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int n; 4607e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani n = (nArg>=2 ? (int)strlen(azArg[1]) : 0); 4608e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; 4609e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani return lintFkeyIndexes(pState, azArg, nArg); 4610e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4611e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani usage: 4612e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]); 4613e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "Where sub-commands are:\n"); 4614e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, " fkey-indexes\n"); 4615e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani return SQLITE_ERROR; 4616e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani} 4617e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 4618e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 461908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis/* 46207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** If an input line begins with "." then invoke this routine to 46217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** process that line. 46227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 46237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return 1 on error, 2 to exit, and 0 otherwise. 46247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 46253fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic int do_meta_command(char *zLine, ShellState *p){ 46263a6c79f802fabdb94367177310663397420e319fNick Kralevich int h = 1; 46277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int nArg = 0; 46287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int n, c; 46297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int rc = 0; 46307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *azArg[50]; 46317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 46327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Parse the input line into tokens. 46337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 46343a6c79f802fabdb94367177310663397420e319fNick Kralevich while( zLine[h] && nArg<ArraySize(azArg) ){ 46353a6c79f802fabdb94367177310663397420e319fNick Kralevich while( IsSpace(zLine[h]) ){ h++; } 46363a6c79f802fabdb94367177310663397420e319fNick Kralevich if( zLine[h]==0 ) break; 46373a6c79f802fabdb94367177310663397420e319fNick Kralevich if( zLine[h]=='\'' || zLine[h]=='"' ){ 46383a6c79f802fabdb94367177310663397420e319fNick Kralevich int delim = zLine[h++]; 46393a6c79f802fabdb94367177310663397420e319fNick Kralevich azArg[nArg++] = &zLine[h]; 464060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis while( zLine[h] && zLine[h]!=delim ){ 46413a6c79f802fabdb94367177310663397420e319fNick Kralevich if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++; 464260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis h++; 46438fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 46443a6c79f802fabdb94367177310663397420e319fNick Kralevich if( zLine[h]==delim ){ 46453a6c79f802fabdb94367177310663397420e319fNick Kralevich zLine[h++] = 0; 46467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 46477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); 46487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 46493a6c79f802fabdb94367177310663397420e319fNick Kralevich azArg[nArg++] = &zLine[h]; 46503a6c79f802fabdb94367177310663397420e319fNick Kralevich while( zLine[h] && !IsSpace(zLine[h]) ){ h++; } 46513a6c79f802fabdb94367177310663397420e319fNick Kralevich if( zLine[h] ) zLine[h++] = 0; 46527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project resolve_backslashes(azArg[nArg-1]); 46537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 46547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 46557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 46567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Process the input line. 46577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 4658a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( nArg==0 ) return 0; /* no tokens, no error */ 4659a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori n = strlen30(azArg[0]); 46607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project c = azArg[0][0]; 466160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 466208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#ifndef SQLITE_OMIT_AUTHORIZATION 466360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){ 466460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg!=2 ){ 466560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .auth ON|OFF\n"); 466660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = 1; 466760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis goto meta_command_exit; 466860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 466960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis open_db(p, 0); 467060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( booleanValue(azArg[1]) ){ 467160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_set_authorizer(p->db, shellAuth, p); 467260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 467360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_set_authorizer(p->db, 0, 0); 467460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 467560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 467608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis#endif 467760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 46788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0) 46798fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) 46808fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ){ 46818fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *zDestFile = 0; 46828fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *zDb = 0; 4683a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3 *pDest; 4684a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_backup *pBackup; 46858fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int j; 46868fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(j=1; j<nArg; j++){ 46878fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *z = azArg[j]; 46888fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( z[0]=='-' ){ 46898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( z[0]=='-' ) z++; 46908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* No options to process at this time */ 46918fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { 469260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "unknown option: %s\n", azArg[j]); 46938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 1; 46948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 46958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( zDestFile==0 ){ 46968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zDestFile = azArg[j]; 46978fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( zDb==0 ){ 46988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zDb = zDestFile; 46998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zDestFile = azArg[j]; 47008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 470160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "too many arguments to .backup\n"); 47028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 1; 47038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 47048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 47058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zDestFile==0 ){ 470660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "missing FILENAME argument on .backup\n"); 47078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 1; 4708a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 47098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zDb==0 ) zDb = "main"; 4710a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = sqlite3_open(zDestFile, &pDest); 4711a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( rc!=SQLITE_OK ){ 471260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile); 4713a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_close(pDest); 4714a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 4715a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 47168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 4717a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); 4718a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( pBackup==0 ){ 471960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); 4720a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_close(pDest); 4721a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 4722a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 4723a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} 4724a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_backup_finish(pBackup); 4725a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( rc==SQLITE_DONE ){ 4726a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 0; 4727a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else{ 472860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); 4729a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 4730a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 4731a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_close(pDest); 4732a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else 4733a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 47341c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){ 47351c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg==2 ){ 47361c7cea379348522163370244e8fbbff8a136b7faNick Kralevich bail_on_error = booleanValue(azArg[1]); 47371c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 473860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .bail on|off\n"); 47391c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 47401c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 47417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 47427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 47433a6c79f802fabdb94367177310663397420e319fNick Kralevich if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){ 47443a6c79f802fabdb94367177310663397420e319fNick Kralevich if( nArg==2 ){ 47453a6c79f802fabdb94367177310663397420e319fNick Kralevich if( booleanValue(azArg[1]) ){ 474660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis setBinaryMode(p->out, 1); 47473a6c79f802fabdb94367177310663397420e319fNick Kralevich }else{ 474860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis setTextMode(p->out, 1); 47493a6c79f802fabdb94367177310663397420e319fNick Kralevich } 47503a6c79f802fabdb94367177310663397420e319fNick Kralevich }else{ 475160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .binary on|off\n"); 47523a6c79f802fabdb94367177310663397420e319fNick Kralevich rc = 1; 47533a6c79f802fabdb94367177310663397420e319fNick Kralevich } 47543a6c79f802fabdb94367177310663397420e319fNick Kralevich }else 47553a6c79f802fabdb94367177310663397420e319fNick Kralevich 47568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* The undocumented ".breakpoint" command causes a call to the no-op 47578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** routine named test_breakpoint(). 47588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich */ 47598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ 47608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich test_breakpoint(); 47618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else 47628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 476360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){ 476460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg==2 ){ 4765b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis setOrClearFlag(p, SHFLG_CountChanges, azArg[1]); 476660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 476760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .changes on|off\n"); 476860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = 1; 476960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 477060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 477160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 477208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis /* Cancel output redirection, if it is currently set (by .testcase) 477308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis ** Then read the content of the testcase-out.txt file and compare against 477408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis ** azArg[1]. If there are differences, report an error and exit. 477508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis */ 477608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){ 477708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis char *zRes = 0; 477808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis output_reset(p); 477908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( nArg!=2 ){ 478008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis raw_printf(stderr, "Usage: .check GLOB-PATTERN\n"); 478108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis rc = 2; 4782e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ 478308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); 478408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis rc = 2; 478508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else if( testcase_glob(azArg[1],zRes)==0 ){ 478608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis utf8_printf(stderr, 478708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", 478808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis p->zTestcase, azArg[1], zRes); 478908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis rc = 2; 479008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else{ 479108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); 479208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis p->nCheck++; 479308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 479408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis sqlite3_free(zRes); 479508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else 479608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 47971c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){ 47981c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg==2 ){ 47991c7cea379348522163370244e8fbbff8a136b7faNick Kralevich tryToClone(p, azArg[1]); 48001c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 480160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .clone FILENAME\n"); 48021c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 48031c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 48048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else 48058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 48061c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ 48073fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState data; 48087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zErrMsg = 0; 48098fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 48107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project memcpy(&data, p, sizeof(data)); 4811e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani data.showHeader = 0; 4812e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani data.cMode = data.mode = MODE_List; 4813e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": "); 48147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.cnt = 0; 4815e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list", 4816e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani callback, &data, &zErrMsg); 48177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zErrMsg ){ 481860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: %s\n", zErrMsg); 48197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_free(zErrMsg); 4820a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 48217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 48227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 48237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 48243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ 48253fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = shell_dbinfo_command(p, nArg, azArg); 48263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else 48273fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 48281c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ 4829b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *zLike = 0; 4830b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; 4831b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis int savedShowHeader = p->showHeader; 4832b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellClearFlag(p, SHFLG_PreserveRowid); 4833b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=1; i<nArg; i++){ 4834b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( azArg[i][0]=='-' ){ 4835b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *z = azArg[i]+1; 4836b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( z[0]=='-' ) z++; 4837b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strcmp(z,"preserve-rowids")==0 ){ 4838b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#ifdef SQLITE_OMIT_VIRTUALTABLE 4839b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(stderr, "The --preserve-rowids option is not compatible" 4840b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " with SQLITE_OMIT_VIRTUALTABLE\n"); 4841b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 4842b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis goto meta_command_exit; 4843b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#else 4844b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellSetFlag(p, SHFLG_PreserveRowid); 4845b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#endif 4846b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 4847b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis { 4848b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]); 4849b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 4850b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis goto meta_command_exit; 4851b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 4852b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( zLike ){ 4853b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(stderr, "Usage: .dump ?--preserve-rowids? ?LIKE-PATTERN?\n"); 4854b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 4855b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis goto meta_command_exit; 4856b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 4857b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zLike = azArg[i]; 4858b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 4859b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 48608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 4861a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori /* When playing back a "dump", the content might appear in an order 4862a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ** which causes immediate foreign key constraints to be violated. 4863a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ** So disable foreign-key constraint enforcement to prevent problems. */ 486460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n"); 486560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "BEGIN TRANSACTION;\n"); 48667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->writableSchema = 0; 4867b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis p->showHeader = 0; 4868b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis /* Set writable_schema=ON since doing so forces SQLite to initialize 4869b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** as much of the schema as it can even if the sqlite_master table is 4870b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ** corrupt. */ 487190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); 487290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown p->nErr = 0; 4873b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( zLike==0 ){ 487460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis run_schema_dump_query(p, 48757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "SELECT name, type, sql FROM sqlite_master " 487690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" 4877a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori ); 487860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis run_schema_dump_query(p, 4879a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori "SELECT name, type, sql FROM sqlite_master " 488090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown "WHERE name=='sqlite_sequence'" 48817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ); 488290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown run_table_dump_query(p, 48837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "SELECT sql FROM sqlite_master " 4884a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 48857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ); 48867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 4887b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zSql; 4888b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = sqlite3_mprintf( 4889b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "SELECT name, type, sql FROM sqlite_master " 4890b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "WHERE tbl_name LIKE %Q AND type=='table'" 4891b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " AND sql NOT NULL", zLike); 4892b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis run_schema_dump_query(p,zSql); 4893b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zSql); 4894b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = sqlite3_mprintf( 4895b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "SELECT sql FROM sqlite_master " 4896b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "WHERE sql NOT NULL" 4897b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " AND type IN ('index','trigger','view')" 4898b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " AND tbl_name LIKE %Q", zLike); 4899b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis run_table_dump_query(p, zSql, 0); 4900b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zSql); 49017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 49027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->writableSchema ){ 490360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "PRAGMA writable_schema=OFF;\n"); 49047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->writableSchema = 0; 49057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 490690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); 490790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); 490860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); 4909b94ea7b498a753b88afce0b6c54ce0f08095f03eAlex Naidis p->showHeader = savedShowHeader; 49107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 49117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 49121c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ 49131c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg==2 ){ 4914b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis setOrClearFlag(p, SHFLG_Echo, azArg[1]); 49151c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 491660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .echo on|off\n"); 49171c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 49181c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 49197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 49207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 49211c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ 49221c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg==2 ){ 492360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azArg[1],"full")==0 ){ 492460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->autoEQP = 2; 492560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 492660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->autoEQP = booleanValue(azArg[1]); 492760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 49281c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 492960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .eqp on|off|full\n"); 49301c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 493160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 49328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else 49338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 49348fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ 49358fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc); 49367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = 2; 49377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 49387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 49391c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ 494060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int val = 1; 494160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg>=2 ){ 494260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azArg[1],"auto")==0 ){ 494360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis val = 99; 494460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 494560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis val = booleanValue(azArg[1]); 49467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 494760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 494860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( val==1 && p->mode!=MODE_Explain ){ 494960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->normalMode = p->mode; 49507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_Explain; 495160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->autoExplain = 0; 495260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( val==0 ){ 495360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->mode==MODE_Explain ) p->mode = p->normalMode; 495460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->autoExplain = 0; 495560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( val==99 ){ 495660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->mode==MODE_Explain ) p->mode = p->normalMode; 495760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->autoExplain = 1; 49587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 49597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 49607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 49619bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ 49623fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState data; 49639bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown char *zErrMsg = 0; 49649bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown int doStats = 0; 496560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis memcpy(&data, p, sizeof(data)); 496660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data.showHeader = 0; 496760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data.cMode = data.mode = MODE_Semi; 496860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg==2 && optionMatch(azArg[1], "indent") ){ 496960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data.cMode = data.mode = MODE_Pretty; 497060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis nArg = 1; 497160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 49729bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( nArg!=1 ){ 497360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .fullschema ?--indent?\n"); 49749bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown rc = 1; 49759bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown goto meta_command_exit; 49769bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown } 49779bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown open_db(p, 0); 49789bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown rc = sqlite3_exec(p->db, 49799bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown "SELECT sql FROM" 49809bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" 49819bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown " FROM sqlite_master UNION ALL" 49829bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " 49833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' " 49849bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown "ORDER BY rowid", 49859bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown callback, &data, &zErrMsg 49869bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown ); 49879bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( rc==SQLITE_OK ){ 49889bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_stmt *pStmt; 49899bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown rc = sqlite3_prepare_v2(p->db, 49909bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown "SELECT rowid FROM sqlite_master" 49919bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown " WHERE name GLOB 'sqlite_stat[134]'", 49929bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown -1, &pStmt, 0); 49939bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown doStats = sqlite3_step(pStmt)==SQLITE_ROW; 49949bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_finalize(pStmt); 49959bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown } 49969bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( doStats==0 ){ 499760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "/* No STAT tables available */\n"); 49989bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown }else{ 499960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "ANALYZE sqlite_master;\n"); 50009bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'", 50019bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown callback, &data, &zErrMsg); 500260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data.cMode = data.mode = MODE_Insert; 50039bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown data.zDestTable = "sqlite_stat1"; 50049bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown shell_exec(p->db, "SELECT * FROM sqlite_stat1", 50059bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown shell_callback, &data,&zErrMsg); 50069bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown data.zDestTable = "sqlite_stat3"; 50079bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown shell_exec(p->db, "SELECT * FROM sqlite_stat3", 50089bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown shell_callback, &data,&zErrMsg); 50099bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown data.zDestTable = "sqlite_stat4"; 50109bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown shell_exec(p->db, "SELECT * FROM sqlite_stat4", 50119bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown shell_callback, &data, &zErrMsg); 501260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "ANALYZE sqlite_master;\n"); 50139bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown } 50149bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown }else 50159bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown 50161c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ 50171c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg==2 ){ 50181c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->showHeader = booleanValue(azArg[1]); 50191c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 502060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .headers on|off\n"); 50211c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 50221c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 50237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 50247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 50257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ 502660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", zHelp); 50277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 50287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 50291c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ 50301c7cea379348522163370244e8fbbff8a136b7faNick Kralevich char *zTable; /* Insert data into this table */ 50311c7cea379348522163370244e8fbbff8a136b7faNick Kralevich char *zFile; /* Name of file to extra content from */ 5032a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_stmt *pStmt = NULL; /* A statement */ 50337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int nCol; /* Number of columns in the table */ 50347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int nByte; /* Number of bytes in an SQL string */ 50357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i, j; /* Loop counters */ 50368fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int needCommit; /* True to COMMIT or ROLLBACK at end */ 50373fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int nSep; /* Number of bytes in p->colSeparator[] */ 50387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zSql; /* An SQL statement */ 50393fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ImportCtx sCtx; /* Reader context */ 50403fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ 50413fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */ 50427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 50431c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg!=3 ){ 504460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .import FILE TABLE\n"); 50451c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 50461c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 50471c7cea379348522163370244e8fbbff8a136b7faNick Kralevich zFile = azArg[1]; 50481c7cea379348522163370244e8fbbff8a136b7faNick Kralevich zTable = azArg[2]; 50498fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich seenInterrupt = 0; 50503fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich memset(&sCtx, 0, sizeof(sCtx)); 50518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 50523fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich nSep = strlen30(p->colSeparator); 50537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( nSep==0 ){ 505460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, 505560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "Error: non-null column separator required for import\n"); 5056a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 50577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 50588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( nSep>1 ){ 505960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: multi-character column separators not allowed" 50608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " for import\n"); 50618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 1; 50628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 50633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich nSep = strlen30(p->rowSeparator); 50643fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nSep==0 ){ 506560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: non-null row separator required for import\n"); 50663fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return 1; 50673fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 50683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ 50693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* When importing CSV (only), if the row separator is set to the 50703fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** default output row separator, change it to the default input 50713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** row separator. This avoids having to maintain different input 50723fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** and output row separators. */ 50733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); 50743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich nSep = strlen30(p->rowSeparator); 50753fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 50763fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nSep>1 ){ 507760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: multi-character row separators not allowed" 50783fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " for import\n"); 50793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return 1; 50803fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 50813fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.zFile = zFile; 50823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.nLine = 1; 50833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sCtx.zFile[0]=='|' ){ 50843fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#ifdef SQLITE_OMIT_POPEN 508560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: pipes are not supported in this OS\n"); 50863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return 1; 50873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#else 50883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.in = popen(sCtx.zFile+1, "r"); 50893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.zFile = "<pipe>"; 50908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich xCloser = pclose; 50913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 50928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 50933fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.in = fopen(sCtx.zFile, "rb"); 50948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich xCloser = fclose; 50958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 50963fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( p->mode==MODE_Ascii ){ 50973fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xRead = ascii_read_one_field; 50983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else{ 50993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xRead = csv_read_one_field; 51003fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 51013fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sCtx.in==0 ){ 510260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); 51038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 1; 51048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 51053fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.cColSep = p->colSeparator[0]; 51063fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.cRowSep = p->rowSeparator[0]; 510790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); 5108a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( zSql==0 ){ 510960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: out of memory\n"); 51103fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xCloser(sCtx.in); 5111a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 5112a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 5113a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori nByte = strlen30(zSql); 51148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 51153fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ 51163a6c79f802fabdb94367177310663397420e319fNick Kralevich if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){ 51178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); 51188fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char cSep = '('; 51193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich while( xRead(&sCtx) ){ 512060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z); 51218fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich cSep = ','; 51223fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sCtx.cTerm!=sCtx.cColSep ) break; 51238fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 51248fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( cSep=='(' ){ 51258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zCreate); 51263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_free(sCtx.z); 51273fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xCloser(sCtx.in); 512860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"%s: empty file\n", sCtx.zFile); 51298fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 1; 51308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 51318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zCreate = sqlite3_mprintf("%z\n)", zCreate); 51328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); 51338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zCreate); 51348fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc ){ 513560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, 51363a6c79f802fabdb94367177310663397420e319fNick Kralevich sqlite3_errmsg(p->db)); 51373fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_free(sCtx.z); 51383fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xCloser(sCtx.in); 51398fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return 1; 51408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 51418fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 51428fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 51437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_free(zSql); 51447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( rc ){ 5145a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if (pStmt) sqlite3_finalize(pStmt); 514660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); 51473fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xCloser(sCtx.in); 5148a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 51497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 5150a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori nCol = sqlite3_column_count(pStmt); 51517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_finalize(pStmt); 5152a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori pStmt = 0; 5153a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( nCol==0 ) return 0; /* no columns, no error */ 51543a6c79f802fabdb94367177310663397420e319fNick Kralevich zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); 5155a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( zSql==0 ){ 515660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: out of memory\n"); 51573fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xCloser(sCtx.in); 5158a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 5159a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 51608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); 5161a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori j = strlen30(zSql); 51627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=1; i<nCol; i++){ 51637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zSql[j++] = ','; 51647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zSql[j++] = '?'; 51657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 51667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zSql[j++] = ')'; 51677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zSql[j] = 0; 51688fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 51698fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zSql); 51707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( rc ){ 517160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); 5172a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if (pStmt) sqlite3_finalize(pStmt); 51733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xCloser(sCtx.in); 51747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 1; 51757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 51763a6c79f802fabdb94367177310663397420e319fNick Kralevich needCommit = sqlite3_get_autocommit(p->db); 51773a6c79f802fabdb94367177310663397420e319fNick Kralevich if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); 51788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich do{ 51793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int startLine = sCtx.nLine; 51808fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=0; i<nCol; i++){ 51813fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char *z = xRead(&sCtx); 51823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* 51833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** Did we reach end-of-file before finding any columns? 51843fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** If so, stop instead of NULL filling the remaining columns. 51853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich */ 51868fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( z==0 && i==0 ) break; 51873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* 51883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** Did we reach end-of-file OR end-of-line before finding any 51893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** columns in ASCII mode? If so, stop instead of NULL filling 51903fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** the remaining columns. 51913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich */ 51923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; 51938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); 51943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ 519560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "%s:%d: expected %d columns but found %d - " 51968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "filling the rest with NULL\n", 51973fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.zFile, startLine, nCol, i+1); 51983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich i += 2; 51999bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } 52007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 52017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 52023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sCtx.cTerm==sCtx.cColSep ){ 52038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich do{ 52043fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xRead(&sCtx); 52058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich i++; 52063fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }while( sCtx.cTerm==sCtx.cColSep ); 520760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "%s:%d: expected %d columns but found %d - " 52088fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "extras ignored\n", 52093fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sCtx.zFile, startLine, nCol, i); 52108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 52118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( i>=nCol ){ 52128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_step(pStmt); 52138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_reset(pStmt); 52148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc!=SQLITE_OK ){ 521560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, 521660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis startLine, sqlite3_errmsg(p->db)); 5217c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown } 52187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 52193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }while( sCtx.cTerm!=EOF ); 52208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 52213fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich xCloser(sCtx.in); 52223fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_free(sCtx.z); 52237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_finalize(pStmt); 52243a6c79f802fabdb94367177310663397420e319fNick Kralevich if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); 52257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 52267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 5227e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#ifndef SQLITE_UNTESTABLE 5228e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){ 5229e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char *zSql; 5230e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char *zCollist = 0; 5231e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_stmt *pStmt; 5232e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int tnum = 0; 5233e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int i; 5234e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( nArg!=3 ){ 5235e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"); 52361c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 52371c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 5238a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 5239e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani open_db(p, 0); 5240e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master" 5241e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " WHERE name='%q' AND type='index'", azArg[1]); 5242e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 5243e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_free(zSql); 5244e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( sqlite3_step(pStmt)==SQLITE_ROW ){ 5245e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani tnum = sqlite3_column_int(pStmt, 0); 5246e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 5247e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_finalize(pStmt); 5248e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( tnum==0 ){ 5249e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]); 5250a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 5251e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani goto meta_command_exit; 5252e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 5253e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]); 5254e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 5255e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_free(zSql); 5256e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani i = 0; 5257e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani while( sqlite3_step(pStmt)==SQLITE_ROW ){ 5258e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char zLabel[20]; 5259e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani const char *zCol = (const char*)sqlite3_column_text(pStmt,2); 5260e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani i++; 5261e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( zCol==0 ){ 5262e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( sqlite3_column_int(pStmt,1)==-1 ){ 5263e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zCol = "_ROWID_"; 5264e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 5265e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i); 5266e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zCol = zLabel; 5267e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 5268e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 5269e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( zCollist==0 ){ 5270e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zCollist = sqlite3_mprintf("\"%w\"", zCol); 5271e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 5272e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol); 5273e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 5274e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 5275e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_finalize(pStmt); 5276e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zSql = sqlite3_mprintf( 5277e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID", 5278e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani azArg[2], zCollist, zCollist); 5279e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_free(zCollist); 5280e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); 5281e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc==SQLITE_OK ){ 5282e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = sqlite3_exec(p->db, zSql, 0, 0, 0); 5283e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); 5284e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc ){ 5285e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); 5286e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 5287e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani utf8_printf(stdout, "%s;\n", zSql); 5288e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stdout, 5289e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "WARNING: writing to an imposter table will corrupt the index!\n" 5290e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ); 5291e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 5292e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 5293e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); 5294a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 52957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 5296e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_free(zSql); 52977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 5298e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ 52997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 53007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SQLITE_ENABLE_IOTRACE 53017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ 53023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); 53037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( iotrace && iotrace!=stdout ) fclose(iotrace); 53047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project iotrace = 0; 53057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( nArg<2 ){ 53067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3IoTrace = 0; 53077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(azArg[1], "-")==0 ){ 53087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3IoTrace = iotracePrintf; 53097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project iotrace = stdout; 53107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 53117790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project iotrace = fopen(azArg[1], "w"); 53127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( iotrace==0 ){ 531360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); 53147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3IoTrace = 0; 5315a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 53167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 53177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3IoTrace = iotracePrintf; 53187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 53197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 53207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 53217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 5322e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 53233a6c79f802fabdb94367177310663397420e319fNick Kralevich if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){ 53243a6c79f802fabdb94367177310663397420e319fNick Kralevich static const struct { 53253a6c79f802fabdb94367177310663397420e319fNick Kralevich const char *zLimitName; /* Name of a limit */ 53263a6c79f802fabdb94367177310663397420e319fNick Kralevich int limitCode; /* Integer code for that limit */ 53273a6c79f802fabdb94367177310663397420e319fNick Kralevich } aLimit[] = { 53283a6c79f802fabdb94367177310663397420e319fNick Kralevich { "length", SQLITE_LIMIT_LENGTH }, 53293a6c79f802fabdb94367177310663397420e319fNick Kralevich { "sql_length", SQLITE_LIMIT_SQL_LENGTH }, 53303a6c79f802fabdb94367177310663397420e319fNick Kralevich { "column", SQLITE_LIMIT_COLUMN }, 53313a6c79f802fabdb94367177310663397420e319fNick Kralevich { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH }, 53323a6c79f802fabdb94367177310663397420e319fNick Kralevich { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT }, 53333a6c79f802fabdb94367177310663397420e319fNick Kralevich { "vdbe_op", SQLITE_LIMIT_VDBE_OP }, 53343a6c79f802fabdb94367177310663397420e319fNick Kralevich { "function_arg", SQLITE_LIMIT_FUNCTION_ARG }, 53353a6c79f802fabdb94367177310663397420e319fNick Kralevich { "attached", SQLITE_LIMIT_ATTACHED }, 53363a6c79f802fabdb94367177310663397420e319fNick Kralevich { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH }, 53373a6c79f802fabdb94367177310663397420e319fNick Kralevich { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER }, 53383a6c79f802fabdb94367177310663397420e319fNick Kralevich { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH }, 53393a6c79f802fabdb94367177310663397420e319fNick Kralevich { "worker_threads", SQLITE_LIMIT_WORKER_THREADS }, 53403a6c79f802fabdb94367177310663397420e319fNick Kralevich }; 53413a6c79f802fabdb94367177310663397420e319fNick Kralevich int i, n2; 53423a6c79f802fabdb94367177310663397420e319fNick Kralevich open_db(p, 0); 53433a6c79f802fabdb94367177310663397420e319fNick Kralevich if( nArg==1 ){ 5344253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich for(i=0; i<ArraySize(aLimit); i++){ 534560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis printf("%20s %d\n", aLimit[i].zLimitName, 53463a6c79f802fabdb94367177310663397420e319fNick Kralevich sqlite3_limit(p->db, aLimit[i].limitCode, -1)); 53473a6c79f802fabdb94367177310663397420e319fNick Kralevich } 53483a6c79f802fabdb94367177310663397420e319fNick Kralevich }else if( nArg>3 ){ 534960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n"); 53503a6c79f802fabdb94367177310663397420e319fNick Kralevich rc = 1; 53513a6c79f802fabdb94367177310663397420e319fNick Kralevich goto meta_command_exit; 53523a6c79f802fabdb94367177310663397420e319fNick Kralevich }else{ 53533a6c79f802fabdb94367177310663397420e319fNick Kralevich int iLimit = -1; 53543a6c79f802fabdb94367177310663397420e319fNick Kralevich n2 = strlen30(azArg[1]); 5355253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich for(i=0; i<ArraySize(aLimit); i++){ 53563a6c79f802fabdb94367177310663397420e319fNick Kralevich if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){ 53573a6c79f802fabdb94367177310663397420e319fNick Kralevich if( iLimit<0 ){ 53583a6c79f802fabdb94367177310663397420e319fNick Kralevich iLimit = i; 53593a6c79f802fabdb94367177310663397420e319fNick Kralevich }else{ 536060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]); 53613a6c79f802fabdb94367177310663397420e319fNick Kralevich rc = 1; 53623a6c79f802fabdb94367177310663397420e319fNick Kralevich goto meta_command_exit; 53633a6c79f802fabdb94367177310663397420e319fNick Kralevich } 53643a6c79f802fabdb94367177310663397420e319fNick Kralevich } 53653a6c79f802fabdb94367177310663397420e319fNick Kralevich } 53663a6c79f802fabdb94367177310663397420e319fNick Kralevich if( iLimit<0 ){ 536760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "unknown limit: \"%s\"\n" 53683a6c79f802fabdb94367177310663397420e319fNick Kralevich "enter \".limits\" with no arguments for a list.\n", 53693a6c79f802fabdb94367177310663397420e319fNick Kralevich azArg[1]); 53703a6c79f802fabdb94367177310663397420e319fNick Kralevich rc = 1; 53713a6c79f802fabdb94367177310663397420e319fNick Kralevich goto meta_command_exit; 53723a6c79f802fabdb94367177310663397420e319fNick Kralevich } 53733a6c79f802fabdb94367177310663397420e319fNick Kralevich if( nArg==3 ){ 5374693f9c610b18f09ffe4aaa8f583362481c9e1532Nick Kralevich sqlite3_limit(p->db, aLimit[iLimit].limitCode, 5375693f9c610b18f09ffe4aaa8f583362481c9e1532Nick Kralevich (int)integerValue(azArg[2])); 53763a6c79f802fabdb94367177310663397420e319fNick Kralevich } 53773a6c79f802fabdb94367177310663397420e319fNick Kralevich printf("%20s %d\n", aLimit[iLimit].zLimitName, 53783a6c79f802fabdb94367177310663397420e319fNick Kralevich sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); 53793a6c79f802fabdb94367177310663397420e319fNick Kralevich } 53803a6c79f802fabdb94367177310663397420e319fNick Kralevich }else 53817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 5382e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){ 5383e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani open_db(p, 0); 5384e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani lintDotCommand(p, azArg, nArg); 5385e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else 5386e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 53877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifndef SQLITE_OMIT_LOAD_EXTENSION 53881c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ 53897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project const char *zFile, *zProc; 53907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zErrMsg = 0; 53911c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg<2 ){ 539260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n"); 53931c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 53941c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 53951c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 53967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zFile = azArg[1]; 53977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zProc = nArg>=3 ? azArg[2] : 0; 53988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 53997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); 54007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( rc!=SQLITE_OK ){ 540160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\n", zErrMsg); 54027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_free(zErrMsg); 54037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = 1; 54047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 54057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 54067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 54077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 54081c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='l' && strncmp(azArg[0], "log", n)==0 ){ 54091c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg!=2 ){ 541060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .log FILENAME\n"); 54111c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 54121c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 54131c7cea379348522163370244e8fbbff8a136b7faNick Kralevich const char *zFile = azArg[1]; 54141c7cea379348522163370244e8fbbff8a136b7faNick Kralevich output_file_close(p->pLog); 54151c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->pLog = output_file_open(zFile); 54161c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 5417aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori }else 5418aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori 54191c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){ 54201c7cea379348522163370244e8fbbff8a136b7faNick Kralevich const char *zMode = nArg>=2 ? azArg[1] : ""; 54211c7cea379348522163370244e8fbbff8a136b7faNick Kralevich int n2 = (int)strlen(zMode); 54221c7cea379348522163370244e8fbbff8a136b7faNick Kralevich int c2 = zMode[0]; 54231c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){ 54247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_Line; 54254b7ed9600a8a9a52e622980c609aab9038bdf6b4Alex Naidis sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); 54261c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){ 54277790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_Column; 54284b7ed9600a8a9a52e622980c609aab9038bdf6b4Alex Naidis sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); 54291c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){ 54307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_List; 54314b7ed9600a8a9a52e622980c609aab9038bdf6b4Alex Naidis sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column); 54324b7ed9600a8a9a52e622980c609aab9038bdf6b4Alex Naidis sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); 54331c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ 54347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_Html; 54351c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ 54367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_Tcl; 54373fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); 54384b7ed9600a8a9a52e622980c609aab9038bdf6b4Alex Naidis sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); 54391c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ 54407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_Csv; 54413fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); 54423fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); 54431c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ 54447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_List; 54453fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); 54461c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ 54477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->mode = MODE_Insert; 54481c7cea379348522163370244e8fbbff8a136b7faNick Kralevich set_table_name(p, nArg>=3 ? azArg[2] : "table"); 5449e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){ 5450e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani p->mode = MODE_Quote; 54513fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ 54523fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich p->mode = MODE_Ascii; 54533fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); 54543fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); 54557790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else { 545660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: mode should be one of: " 5457e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "ascii column csv html insert line list quote tabs tcl\n"); 5458a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 5459a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 546060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->cMode = p->mode; 5461a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else 5462a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 54631c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ 54641c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg==2 ){ 54653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, 54663fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); 54671c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 546860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .nullvalue STRING\n"); 5469a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 54707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 54717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 54727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 54738fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ 547408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis char *zNewFilename; /* Name of the database file to open */ 547508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis int iName = 1; /* Index in azArg[] of the filename */ 547608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis int newFlag = 0; /* True to delete file before opening */ 547708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis /* Close the existing database */ 547808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis session_close_all(p); 547908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis sqlite3_close(p->db); 54808fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->db = 0; 5481b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis p->zDbFilename = 0; 548208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis sqlite3_free(p->zFreeOnClose); 548308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis p->zFreeOnClose = 0; 548408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis /* Check for command-line arguments */ 548508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){ 548608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis const char *z = azArg[iName]; 548708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( optionMatch(z,"new") ){ 548808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis newFlag = 1; 548908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else if( z[0]=='-' ){ 549008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis utf8_printf(stderr, "unknown option: %s\n", z); 549108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis rc = 1; 549208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis goto meta_command_exit; 549308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 549408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 549508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis /* If a filename is specified, try to open it first */ 549608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0; 549708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( zNewFilename ){ 549808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( newFlag ) shellDeleteFile(zNewFilename); 549908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis p->zDbFilename = zNewFilename; 550008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis open_db(p, 1); 550108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( p->db==0 ){ 550208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); 550308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis sqlite3_free(zNewFilename); 550408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else{ 550508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis p->zFreeOnClose = zNewFilename; 550608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 550708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 550808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( p->db==0 ){ 550908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis /* As a fall-back open a TEMP database */ 551008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis p->zDbFilename = 0; 551108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis open_db(p, 0); 55128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 55138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else 55148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 55151c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='o' 55161c7cea379348522163370244e8fbbff8a136b7faNick Kralevich && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0) 55171c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ){ 55181c7cea379348522163370244e8fbbff8a136b7faNick Kralevich const char *zFile = nArg>=2 ? azArg[1] : "stdout"; 55191c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg>2 ){ 552060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]); 55211c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 55221c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 55231c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 55241c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( n>1 && strncmp(azArg[0], "once", n)==0 ){ 55251c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg<2 ){ 552660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .once FILE\n"); 55271c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 55281c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 55291c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 55301c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->outCount = 2; 55318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 55321c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->outCount = 0; 55337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 55341c7cea379348522163370244e8fbbff8a136b7faNick Kralevich output_reset(p); 55351c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( zFile[0]=='|' ){ 55363fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#ifdef SQLITE_OMIT_POPEN 553760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: pipes are not supported in this OS\n"); 55383fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 55393fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich p->out = stdout; 55403fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#else 55411c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->out = popen(zFile + 1, "w"); 55428fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( p->out==0 ){ 554360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); 55448fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->out = stdout; 55458fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = 1; 55468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 55471c7cea379348522163370244e8fbbff8a136b7faNick Kralevich sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); 55488fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 55493fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 55507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 55511c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->out = output_file_open(zFile); 55527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( p->out==0 ){ 55531c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( strcmp(zFile,"off")!=0 ){ 555460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile); 55558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 55567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project p->out = stdout; 5557a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 55587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } else { 55591c7cea379348522163370244e8fbbff8a136b7faNick Kralevich sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); 55607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 55617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 55627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 55637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 55648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){ 55658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int i; 55668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=1; i<nArg; i++){ 556760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( i>1 ) raw_printf(p->out, " "); 556860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", azArg[i]); 55698fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 557060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n"); 55718fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else 55728fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 55731c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){ 55747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( nArg >= 2) { 55757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); 55767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 55777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( nArg >= 3) { 55787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); 55797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 55807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 55817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 55821c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ 55837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = 2; 55847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 55857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 55861c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ 55871c7cea379348522163370244e8fbbff8a136b7faNick Kralevich FILE *alt; 55881c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg!=2 ){ 558960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .read FILE\n"); 55901c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 55911c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 55921c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 55931c7cea379348522163370244e8fbbff8a136b7faNick Kralevich alt = fopen(azArg[1], "rb"); 55947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( alt==0 ){ 559560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); 5596a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 55977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 5598a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = process_input(p, alt); 55997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fclose(alt); 56007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 56017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 56027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 56031c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){ 5604a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori const char *zSrcFile; 5605a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori const char *zDb; 5606a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3 *pSrc; 5607a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_backup *pBackup; 5608a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int nTimeout = 0; 5609a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 5610a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( nArg==2 ){ 5611a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zSrcFile = azArg[1]; 5612a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zDb = "main"; 56131c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( nArg==3 ){ 5614a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zSrcFile = azArg[2]; 5615a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zDb = azArg[1]; 56161c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 561760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .restore ?DB? FILE\n"); 56181c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 56191c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 5620a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 5621a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = sqlite3_open(zSrcFile, &pSrc); 5622a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( rc!=SQLITE_OK ){ 562360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); 5624a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_close(pSrc); 5625a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 5626a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 56278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 5628a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); 5629a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( pBackup==0 ){ 563060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); 5631a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_close(pSrc); 5632a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 5633a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 5634a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK 5635a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori || rc==SQLITE_BUSY ){ 5636a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( rc==SQLITE_BUSY ){ 5637a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( nTimeout++ >= 3 ) break; 5638a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_sleep(100); 5639a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 5640a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 5641a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_backup_finish(pBackup); 5642a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( rc==SQLITE_DONE ){ 5643a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 0; 5644a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ 564560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: source database is busy\n"); 5646a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 5647a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else{ 564860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); 5649a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 5650a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 5651a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_close(pSrc); 5652a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else 5653a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 56543fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 56553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){ 56563fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nArg==2 ){ 56573fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich p->scanstatsOn = booleanValue(azArg[1]); 56583fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#ifndef SQLITE_ENABLE_STMT_SCANSTATUS 565960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Warning: .scanstats not available in this build.\n"); 56603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 56613fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else{ 566260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .scanstats on|off\n"); 56633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 56643fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 56653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else 56663fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 56671c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ 56683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState data; 56697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zErrMsg = 0; 56708fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 56717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project memcpy(&data, p, sizeof(data)); 56727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.showHeader = 0; 567360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data.cMode = data.mode = MODE_Semi; 567460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg>=2 && optionMatch(azArg[1], "indent") ){ 567560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data.cMode = data.mode = MODE_Pretty; 567660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis nArg--; 567760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg==2 ) azArg[1] = azArg[2]; 567860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 567960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg==2 && azArg[1][0]!='-' ){ 56807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i; 568190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); 56827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( strcmp(azArg[1],"sqlite_master")==0 ){ 56837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *new_argv[2], *new_colv[2]; 56847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project new_argv[0] = "CREATE TABLE sqlite_master (\n" 56857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " type text,\n" 56867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " name text,\n" 56877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " tbl_name text,\n" 56887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " rootpage integer,\n" 56897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " sql text\n" 56907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ")"; 56917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project new_argv[1] = 0; 56927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project new_colv[0] = "sql"; 56937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project new_colv[1] = 0; 56947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project callback(&data, 1, new_argv, new_colv); 5695a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = SQLITE_OK; 56967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ 56977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *new_argv[2], *new_colv[2]; 56987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" 56997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " type text,\n" 57007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " name text,\n" 57017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " tbl_name text,\n" 57027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " rootpage integer,\n" 57037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " sql text\n" 57047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ")"; 57057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project new_argv[1] = 0; 57067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project new_colv[0] = "sql"; 57077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project new_colv[1] = 0; 57087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project callback(&data, 1, new_argv, new_colv); 5709a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = SQLITE_OK; 57107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 5711b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zSql; 5712b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = sqlite3_mprintf( 57137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "SELECT sql FROM " 57148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" 5715a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori " FROM sqlite_master UNION ALL" 57168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " 5717b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "WHERE lower(tbl_name) LIKE %Q" 571890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown " AND type!='meta' AND sql NOTNULL " 5719b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "ORDER BY rowid", azArg[1]); 5720b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = sqlite3_exec(p->db, zSql, callback, &data, &zErrMsg); 5721b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zSql); 57227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 57231c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else if( nArg==1 ){ 5724a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = sqlite3_exec(p->db, 57257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "SELECT sql FROM " 57268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" 5727a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori " FROM sqlite_master UNION ALL" 57288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " 57293fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' " 57308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "ORDER BY rowid", 57317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project callback, &data, &zErrMsg 57327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ); 57331c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 573460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); 57351c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 57361c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 57377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 57387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zErrMsg ){ 573960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: %s\n", zErrMsg); 57407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_free(zErrMsg); 5741a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 5742a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else if( rc != SQLITE_OK ){ 574360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr,"Error: querying schema information\n"); 5744a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 5745a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else{ 5746a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 0; 57477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 57487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 57497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 57503fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) 57513fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ 5752b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3SelectTrace = (int)integerValue(azArg[1]); 57533fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else 57543fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 57553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 575660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if defined(SQLITE_ENABLE_SESSION) 575760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ 575860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis OpenSession *pSession = &p->aSession[0]; 575960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char **azCmd = &azArg[1]; 576060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int iSes = 0; 576160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int nCmd = nArg - 1; 576260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int i; 576360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg<=1 ) goto session_syntax_error; 576460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis open_db(p, 0); 576560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nArg>=3 ){ 576660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(iSes=0; iSes<p->nSession; iSes++){ 576760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break; 576860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 576960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( iSes<p->nSession ){ 577060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession = &p->aSession[iSes]; 577160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis azCmd++; 577260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis nCmd--; 577360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 577460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession = &p->aSession[0]; 577560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis iSes = 0; 577660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 577760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 577860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 577960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session attach TABLE 578060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** Invoke the sqlite3session_attach() interface to attach a particular 578160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** table so that it is never filtered. 578260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 578360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0],"attach")==0 ){ 578460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nCmd!=2 ) goto session_syntax_error; 578560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pSession->p==0 ){ 578660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis session_not_open: 578760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "ERROR: No sessions are open\n"); 578860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 578960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = sqlite3session_attach(pSession->p, azCmd[1]); 579060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( rc ){ 579160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); 579260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = 0; 579360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 579460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 579560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 579660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 579760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session changeset FILE 579860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** .session patchset FILE 579960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** Write a changeset or patchset into a file. The file is overwritten. 580060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 580160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){ 580260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis FILE *out = 0; 580360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nCmd!=2 ) goto session_syntax_error; 580460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pSession->p==0 ) goto session_not_open; 580560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis out = fopen(azCmd[1], "wb"); 580660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( out==0 ){ 580760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); 580860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 580960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int szChng; 581060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis void *pChng; 581160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( azCmd[0][0]=='c' ){ 581260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); 581360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else{ 581460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); 581560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 581660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( rc ){ 581760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis printf("Error: error code %d\n", rc); 581860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = 0; 581960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 582060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pChng 582160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis && fwrite(pChng, szChng, 1, out)!=1 ){ 582260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n", 582360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis szChng); 582460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 582560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(pChng); 582660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis fclose(out); 582760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 582860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 582960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 583060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session close 583160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** Close the identified session 583260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 583360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0], "close")==0 ){ 583460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nCmd!=1 ) goto session_syntax_error; 583560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->nSession ){ 583660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis session_close(pSession); 583760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->aSession[iSes] = p->aSession[--p->nSession]; 583860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 583960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 584060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 584160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session enable ?BOOLEAN? 584260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** Query or set the enable flag 584360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 584460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0], "enable")==0 ){ 584560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int ii; 584660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nCmd>2 ) goto session_syntax_error; 584760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); 584860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->nSession ){ 584960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ii = sqlite3session_enable(pSession->p, ii); 585060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "session %s enable flag = %d\n", 585160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession->zName, ii); 585260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 585360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 585460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 585560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session filter GLOB .... 585660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** Set a list of GLOB patterns of table names to be excluded. 585760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 585860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0], "filter")==0 ){ 585960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int ii, nByte; 586060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nCmd<2 ) goto session_syntax_error; 586160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->nSession ){ 586260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(ii=0; ii<pSession->nFilter; ii++){ 586360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(pSession->azFilter[ii]); 586460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 586560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(pSession->azFilter); 586660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis nByte = sizeof(pSession->azFilter[0])*(nCmd-1); 586760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession->azFilter = sqlite3_malloc( nByte ); 586860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pSession->azFilter==0 ){ 586960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: out or memory\n"); 587060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis exit(1); 587160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 587260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(ii=1; ii<nCmd; ii++){ 587360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); 587460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 587560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession->nFilter = ii-1; 587660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 587760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 587860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 587960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session indirect ?BOOLEAN? 588060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** Query or set the indirect flag 588160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 588260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0], "indirect")==0 ){ 588360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int ii; 588460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nCmd>2 ) goto session_syntax_error; 588560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); 588660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->nSession ){ 588760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ii = sqlite3session_indirect(pSession->p, ii); 588860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "session %s indirect flag = %d\n", 588960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession->zName, ii); 589060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 589160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 589260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 589360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session isempty 589460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** Determine if the session is empty 589560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 589660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0], "isempty")==0 ){ 589760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int ii; 589860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nCmd!=1 ) goto session_syntax_error; 589960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->nSession ){ 590060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ii = sqlite3session_isempty(pSession->p); 590160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "session %s isempty flag = %d\n", 590260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession->zName, ii); 590360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 590460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 590560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 590660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session list 590760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** List all currently open sessions 590860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 590960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0],"list")==0 ){ 591060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<p->nSession; i++){ 591160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName); 591260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 591360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 591460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 591560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* .session open DB NAME 591660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** Open a new session called NAME on the attached database DB. 591760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** DB is normally "main". 591860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis */ 591960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(azCmd[0],"open")==0 ){ 592060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char *zName; 592160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( nCmd!=3 ) goto session_syntax_error; 592260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis zName = azCmd[2]; 592360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( zName[0]==0 ) goto session_syntax_error; 592460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<p->nSession; i++){ 592560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( strcmp(p->aSession[i].zName,zName)==0 ){ 592660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Session \"%s\" already exists\n", zName); 592760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis goto meta_command_exit; 592860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 592960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 593060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->nSession>=ArraySize(p->aSession) ){ 593160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); 593260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis goto meta_command_exit; 593360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 593460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession = &p->aSession[p->nSession]; 593560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); 593660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( rc ){ 593760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Cannot open session: error code=%d\n", rc); 593860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc = 0; 593960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis goto meta_command_exit; 594060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 594160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession->nFilter = 0; 594260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3session_table_filter(pSession->p, session_filter, pSession); 594360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->nSession++; 594460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pSession->zName = sqlite3_mprintf("%s", zName); 594560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 594660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis /* If no command name matches, show a syntax error */ 594760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis session_syntax_error: 594860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis session_help(p); 594960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 595060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 59513fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 59528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#ifdef SQLITE_DEBUG 59538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* Undocumented commands for internal testing. Subject to change 59548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** without notice. */ 59558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){ 59568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){ 59578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int i, v; 59588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=1; i<nArg; i++){ 59598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich v = booleanValue(azArg[i]); 596060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v); 59618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 59628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 59638fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( strncmp(azArg[0]+9, "integer", n-9)==0 ){ 59648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int i; sqlite3_int64 v; 59658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=1; i<nArg; i++){ 59668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char zBuf[200]; 59678fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich v = integerValue(azArg[i]); 59681c7cea379348522163370244e8fbbff8a136b7faNick Kralevich sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v); 596960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s", zBuf); 59708fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 59718fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 59728fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else 59738fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#endif 59748fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 5975b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){ 5976b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int bIsInit = 0; /* True to initialize the SELFTEST table */ 5977b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int bVerbose = 0; /* Verbose output */ 5978b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int bSelftestExists; /* True if SELFTEST already exists */ 5979b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char **azTest = 0; /* Content of the SELFTEST table */ 5980b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nRow = 0; /* Number of rows in the SELFTEST table */ 5981b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nCol = 4; /* Number of columns in the SELFTEST table */ 5982b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; /* Loop counter */ 5983b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nTest = 0; /* Number of tests runs */ 5984b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int nErr = 0; /* Number of errors seen */ 5985b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellText str; /* Answer for a query */ 5986b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis static char *azDefaultTest[] = { 5987b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 0, 0, 0, 0, 5988b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "0", "memo", "Missing SELFTEST table - default checks only", "", 5989b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "1", "run", "PRAGMA integrity_check", "ok" 5990b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }; 5991b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis static const int nDefaultRow = 2; 5992b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 5993b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis open_db(p,0); 5994b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=1; i<nArg; i++){ 5995b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *z = azArg[i]; 5996b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( z[0]=='-' && z[1]=='-' ) z++; 5997b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strcmp(z,"-init")==0 ){ 5998b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis bIsInit = 1; 5999b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6000b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strcmp(z,"-v")==0 ){ 6001b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis bVerbose++; 6002b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6003b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis { 6004b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n", 6005b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azArg[i], azArg[0]); 6006b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(stderr, "Should be one of: --init -v\n"); 6007b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 6008b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis goto meta_command_exit; 6009b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6010b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6011b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0) 6012b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis != SQLITE_OK ){ 6013b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis bSelftestExists = 0; 6014b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 6015b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis bSelftestExists = 1; 6016b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6017b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( bIsInit ){ 6018b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis createSelftestTable(p); 6019b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis bSelftestExists = 1; 6020b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6021b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( bSelftestExists ){ 6022b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = sqlite3_get_table(p->db, 6023b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno", 6024b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis &azTest, &nRow, &nCol, 0); 6025b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( rc ){ 6026b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(stderr, "Error querying the selftest table\n"); 6027b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 6028b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free_table(azTest); 6029b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis goto meta_command_exit; 6030b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( nRow==0 ){ 6031b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free_table(azTest); 6032b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azTest = azDefaultTest; 6033b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis nRow = nDefaultRow; 6034b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6035b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 6036b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azTest = azDefaultTest; 6037b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis nRow = nDefaultRow; 6038b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6039b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis initText(&str); 6040b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&str, "x", 0); 6041b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=1; i<=nRow; i++){ 6042b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int tno = atoi(azTest[i*nCol]); 6043b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *zOp = azTest[i*nCol+1]; 6044b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *zSql = azTest[i*nCol+2]; 6045b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *zAns = azTest[i*nCol+3]; 6046b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 6047b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( bVerbose>0 ){ 6048b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zQuote = sqlite3_mprintf("%q", zSql); 6049b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis printf("%d: %s %s\n", tno, zOp, zSql); 6050b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zQuote); 6051b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6052b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strcmp(zOp,"memo")==0 ){ 6053b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(p->out, "%s\n", zSql); 6054b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6055b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strcmp(zOp,"run")==0 ){ 6056b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zErrMsg = 0; 6057b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis str.n = 0; 6058b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis str.z[0] = 0; 6059b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); 6060b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis nTest++; 6061b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( bVerbose ){ 6062b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(p->out, "Result: %s\n", str.z); 6063b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6064b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( rc || zErrMsg ){ 6065b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis nErr++; 6066b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 6067b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg); 6068b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zErrMsg); 6069b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( strcmp(zAns,str.z)!=0 ){ 6070b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis nErr++; 6071b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 6072b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns); 6073b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z); 6074b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6075b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6076b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis { 6077b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(stderr, 6078b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); 6079b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 6080b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis break; 6081b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6082b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6083b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis freeText(&str); 6084b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( azTest!=azDefaultTest ) sqlite3_free_table(azTest); 6085b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest); 6086b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6087b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 60881c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ 60899bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( nArg<2 || nArg>3 ){ 609060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .separator COL ?ROW?\n"); 60911c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 60921c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 60939bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( nArg>=2 ){ 60943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, 60953fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); 60969bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown } 60979bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown if( nArg>=3 ){ 60983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, 60993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); 61009bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown } 61017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 61027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 6103b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){ 6104b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *zLike = 0; /* Which table to checksum. 0 means everything */ 6105b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int i; /* Loop counter */ 6106b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int bSchema = 0; /* Also hash the schema */ 6107b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int bSeparate = 0; /* Hash each table separately */ 6108b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int iSize = 224; /* Hash algorithm to use */ 6109b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis int bDebug = 0; /* Only show the query that would have run */ 6110b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_stmt *pStmt; /* For querying tables names */ 6111b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zSql; /* SQL to be run */ 6112b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis char *zSep; /* Separator */ 6113b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellText sSql; /* Complete SQL for the query to run the hash */ 6114b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellText sQuery; /* Set of queries used to read all content */ 6115b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis open_db(p, 0); 6116b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis for(i=1; i<nArg; i++){ 6117b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *z = azArg[i]; 6118b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( z[0]=='-' ){ 6119b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis z++; 6120b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( z[0]=='-' ) z++; 6121b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strcmp(z,"schema")==0 ){ 6122b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis bSchema = 1; 6123b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6124b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strcmp(z,"sha3-224")==0 || strcmp(z,"sha3-256")==0 6125b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis || strcmp(z,"sha3-384")==0 || strcmp(z,"sha3-512")==0 6126b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ){ 6127b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis iSize = atoi(&z[5]); 6128b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6129b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strcmp(z,"debug")==0 ){ 6130b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis bDebug = 1; 6131b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6132b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis { 6133b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n", 6134b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azArg[i], azArg[0]); 6135b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(stderr, "Should be one of: --schema" 6136b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n"); 6137b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 6138b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis goto meta_command_exit; 6139b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6140b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( zLike ){ 6141b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n"); 6142b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis rc = 1; 6143b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis goto meta_command_exit; 6144b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 6145b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zLike = z; 6146b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis bSeparate = 1; 6147b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( sqlite3_strlike("sqlite_%", zLike, 0)==0 ) bSchema = 1; 6148b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6149b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6150b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( bSchema ){ 6151b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = "SELECT lower(name) FROM sqlite_master" 6152b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " WHERE type='table' AND coalesce(rootpage,0)>1" 6153b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " UNION ALL SELECT 'sqlite_master'" 6154b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " ORDER BY 1 collate nocase"; 6155b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 6156b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = "SELECT lower(name) FROM sqlite_master" 6157b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " WHERE type='table' AND coalesce(rootpage,0)>1" 6158b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " AND name NOT LIKE 'sqlite_%'" 6159b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " ORDER BY 1 collate nocase"; 6160b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6161b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 6162b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis initText(&sQuery); 6163b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis initText(&sSql); 6164b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0); 6165b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSep = "VALUES("; 6166b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis while( SQLITE_ROW==sqlite3_step(pStmt) ){ 6167b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis const char *zTab = (const char*)sqlite3_column_text(pStmt,0); 6168b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue; 6169b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( strncmp(zTab, "sqlite_",7)!=0 ){ 6170b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery,"SELECT * FROM ", 0); 6171b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery,zTab,'"'); 6172b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery," NOT INDEXED;", 0); 6173b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( strcmp(zTab, "sqlite_master")==0 ){ 6174b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_master" 6175b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " ORDER BY name;", 0); 6176b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( strcmp(zTab, "sqlite_sequence")==0 ){ 6177b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence" 6178b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " ORDER BY name;", 0); 6179b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( strcmp(zTab, "sqlite_stat1")==0 ){ 6180b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1" 6181b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " ORDER BY tbl,idx;", 0); 6182b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( strcmp(zTab, "sqlite_stat3")==0 6183b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis || strcmp(zTab, "sqlite_stat4")==0 ){ 6184b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery, "SELECT * FROM ", 0); 6185b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery, zTab, 0); 6186b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); 6187b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6188b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSql, zSep, 0); 6189b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSql, sQuery.z, '\''); 6190b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sQuery.n = 0; 6191b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSql, ",", 0); 6192b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis appendText(&sSql, zTab, '\''); 6193b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSep = "),("; 6194b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6195b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_finalize(pStmt); 6196b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( bSeparate ){ 6197b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = sqlite3_mprintf( 6198b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%s))" 6199b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" 6200b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " FROM [sha3sum$query]", 6201b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sSql.z, iSize); 6202b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 6203b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis zSql = sqlite3_mprintf( 6204b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis "%s))" 6205b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" 6206b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis " FROM [sha3sum$query]", 6207b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sSql.z, iSize); 6208b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6209b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis freeText(&sQuery); 6210b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis freeText(&sSql); 6211b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( bDebug ){ 6212b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(p->out, "%s\n", zSql); 6213b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else{ 6214b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis shell_exec(p->db, zSql, shell_callback, p, 0); 6215b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis } 6216b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis sqlite3_free(zSql); 6217b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else 6218b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis 62191c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='s' 62201c7cea379348522163370244e8fbbff8a136b7faNick Kralevich && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) 62211c7cea379348522163370244e8fbbff8a136b7faNick Kralevich ){ 62221c7cea379348522163370244e8fbbff8a136b7faNick Kralevich char *zCmd; 62239bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown int i, x; 62241c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg<2 ){ 622560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .system COMMAND\n"); 62261c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 62271c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 62281c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 62291c7cea379348522163370244e8fbbff8a136b7faNick Kralevich zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); 62301c7cea379348522163370244e8fbbff8a136b7faNick Kralevich for(i=2; i<nArg; i++){ 62311c7cea379348522163370244e8fbbff8a136b7faNick Kralevich zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"", 62321c7cea379348522163370244e8fbbff8a136b7faNick Kralevich zCmd, azArg[i]); 62331c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 62349bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown x = system(zCmd); 62351c7cea379348522163370244e8fbbff8a136b7faNick Kralevich sqlite3_free(zCmd); 623660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( x ) raw_printf(stderr, "System command returns %d\n", x); 62371c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else 62381c7cea379348522163370244e8fbbff8a136b7faNick Kralevich 62391c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ 624060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis static const char *azBool[] = { "off", "on", "full", "unk" }; 62411c7cea379348522163370244e8fbbff8a136b7faNick Kralevich int i; 62421c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg!=1 ){ 624360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .show\n"); 62441c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 62451c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 62461c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 6247b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis utf8_printf(p->out, "%12.12s: %s\n","echo", 6248b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis azBool[ShellHasFlag(p, SHFLG_Echo)]); 624960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); 625060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%12.12s: %s\n","explain", 625160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); 625260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]); 625360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); 625460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%12.12s: ", "nullvalue"); 62553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich output_c_string(p->out, p->nullValue); 625660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n"); 625760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%12.12s: %s\n","output", 6258a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori strlen30(p->outfile) ? p->outfile : "stdout"); 625960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%12.12s: ", "colseparator"); 62603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich output_c_string(p->out, p->colSeparator); 626160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n"); 626260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out,"%12.12s: ", "rowseparator"); 62633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich output_c_string(p->out, p->rowSeparator); 626460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n"); 626560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); 626660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%12.12s: ", "width"); 62677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { 626860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "%d ", p->colWidth[i]); 62697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 627060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n"); 627108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis utf8_printf(p->out, "%12.12s: %s\n", "filename", 627208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis p->zDbFilename ? p->zDbFilename : ""); 62737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 62747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 62751c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ 62761c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg==2 ){ 62771c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->statsOn = booleanValue(azArg[1]); 627860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( nArg==1 ){ 627960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis display_stats(p->db, p, 0); 62801c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 628160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .stats ?on|off?\n"); 62821c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 62831c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 6284de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori }else 6285de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori 6286e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0) 6287e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani || (c=='i' && (strncmp(azArg[0], "indices", n)==0 6288e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani || strncmp(azArg[0], "indexes", n)==0) ) 6289e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ){ 62908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_stmt *pStmt; 62917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char **azResult; 62928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nRow, nAlloc; 62938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zSql = 0; 62948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int ii; 62958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 62968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); 6297253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( rc ) return shellDatabaseError(p->db); 6298253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich 6299253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich /* Create an SQL statement to query for the list of tables in the 6300253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich ** main and all attached databases where the table name matches the 6301253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich ** LIKE pattern bound to variable "?1". */ 6302e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( c=='t' ){ 6303e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zSql = sqlite3_mprintf( 6304e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "SELECT name FROM sqlite_master" 6305e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " WHERE type IN ('table','view')" 6306e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " AND name NOT LIKE 'sqlite_%%'" 6307e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " AND name LIKE ?1"); 6308e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else if( nArg>2 ){ 6309e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani /* It is an historical accident that the .indexes command shows an error 6310e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** when called with the wrong number of arguments whereas the .tables 6311e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani ** command does not. */ 6312e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); 6313e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = 1; 6314e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani goto meta_command_exit; 6315e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 6316e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zSql = sqlite3_mprintf( 6317e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "SELECT name FROM sqlite_master" 6318e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " WHERE type='index'" 6319e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " AND tbl_name LIKE ?1"); 6320e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 6321e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani for(ii=0; zSql && sqlite3_step(pStmt)==SQLITE_ROW; ii++){ 63228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); 6323e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( zDbName==0 || ii==0 ) continue; 6324e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( c=='t' ){ 63258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zSql = sqlite3_mprintf( 63268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "%z UNION ALL " 6327e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "SELECT '%q.' || name FROM \"%w\".sqlite_master" 63288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " WHERE type IN ('table','view')" 63298fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " AND name NOT LIKE 'sqlite_%%'" 6330e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " AND name LIKE ?1", zSql, zDbName, zDbName); 63318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 63328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zSql = sqlite3_mprintf( 63338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "%z UNION ALL " 63348fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "SELECT '%q.' || name FROM \"%w\".sqlite_master" 6335e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " WHERE type='index'" 6336e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani " AND tbl_name LIKE ?1", zSql, zDbName, zDbName); 63378fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 63387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 6339253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich rc = sqlite3_finalize(pStmt); 6340253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( zSql && rc==SQLITE_OK ){ 6341253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich zSql = sqlite3_mprintf("%z ORDER BY 1", zSql); 6342253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 6343253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich } 63448fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zSql); 6345253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( !zSql ) return shellNomemError(); 6346253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( rc ) return shellDatabaseError(p->db); 6347253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich 6348253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich /* Run the SQL statement prepared by the above block. Store the results 6349253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich ** as an array of nul-terminated strings in azResult[]. */ 63508fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich nRow = nAlloc = 0; 63518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich azResult = 0; 63528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( nArg>1 ){ 63538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); 6354a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori }else{ 63558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); 63568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 63578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich while( sqlite3_step(pStmt)==SQLITE_ROW ){ 63588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( nRow>=nAlloc ){ 63598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char **azNew; 63603a6c79f802fabdb94367177310663397420e319fNick Kralevich int n2 = nAlloc*2 + 10; 63613a6c79f802fabdb94367177310663397420e319fNick Kralevich azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); 63628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( azNew==0 ){ 6363253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich rc = shellNomemError(); 63648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 63658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 63663a6c79f802fabdb94367177310663397420e319fNick Kralevich nAlloc = n2; 63678fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich azResult = azNew; 63688fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 63698fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); 6370253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( 0==azResult[nRow] ){ 6371253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich rc = shellNomemError(); 6372253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich break; 6373253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich } 6374253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich nRow++; 6375253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich } 6376253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ 6377253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich rc = shellDatabaseError(p->db); 63788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 6379253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich 6380253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich /* Pretty-print the contents of array azResult[] to the output */ 6381253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( rc==0 && nRow>0 ){ 63827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int len, maxlen = 0; 63837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i, j; 63847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int nPrintCol, nPrintRow; 63858fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=0; i<nRow; i++){ 6386a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori len = strlen30(azResult[i]); 63877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( len>maxlen ) maxlen = len; 63887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 63897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project nPrintCol = 80/(maxlen+2); 63907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( nPrintCol<1 ) nPrintCol = 1; 63917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; 63927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<nPrintRow; i++){ 63938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(j=i; j<nRow; j+=nPrintRow){ 63948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zSp = j<nPrintRow ? "" : " "; 639560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s%-*s", zSp, maxlen, 639660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis azResult[j] ? azResult[j]:""); 63977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 639860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "\n"); 63997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 64007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 6401253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich 64028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]); 64038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(azResult); 64047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 64057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 640608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis /* Begin redirecting output to the file "testcase-out.txt" */ 640708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( c=='t' && strcmp(azArg[0],"testcase")==0 ){ 640808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis output_reset(p); 640908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis p->out = output_file_open("testcase-out.txt"); 641008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( p->out==0 ){ 6411e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); 641208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 641308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( nArg>=2 ){ 641408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]); 641508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else{ 641608f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?"); 641708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 641808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis }else 641908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis 6420e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani#ifndef SQLITE_UNTESTABLE 642190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ 642290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown static const struct { 642390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zCtrlName; /* Name of a test-control option */ 642490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown int ctrlCode; /* Integer code for that option */ 642590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } aCtrl[] = { 642690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, 642790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, 642890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, 642990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, 643090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, 643190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, 643290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, 643390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "assert", SQLITE_TESTCTRL_ASSERT }, 643490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "always", SQLITE_TESTCTRL_ALWAYS }, 643590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "reserve", SQLITE_TESTCTRL_RESERVE }, 643690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, 643790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, 643890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, 64391c7cea379348522163370244e8fbbff8a136b7faNick Kralevich { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, 64403fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, 64413fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { "imposter", SQLITE_TESTCTRL_IMPOSTER }, 644290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }; 644390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown int testctrl = -1; 64443a6c79f802fabdb94367177310663397420e319fNick Kralevich int rc2 = 0; 64453a6c79f802fabdb94367177310663397420e319fNick Kralevich int i, n2; 64468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 644790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 644890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown /* convert testctrl text option to value. allow any unique prefix 644990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown ** of the option name, or a numerical value. */ 64503a6c79f802fabdb94367177310663397420e319fNick Kralevich n2 = strlen30(azArg[1]); 6451253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich for(i=0; i<ArraySize(aCtrl); i++){ 64523a6c79f802fabdb94367177310663397420e319fNick Kralevich if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){ 645390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( testctrl<0 ){ 645490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown testctrl = aCtrl[i].ctrlCode; 645590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else{ 645660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]); 645790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown testctrl = -1; 645890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown break; 645990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 646090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 646190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 64628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]); 646390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){ 646460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); 646590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else{ 646690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown switch(testctrl){ 646790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 646890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown /* sqlite3_test_control(int, db, int) */ 646990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown case SQLITE_TESTCTRL_OPTIMIZATIONS: 647060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_RESERVE: 647190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( nArg==3 ){ 647260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int opt = (int)strtol(azArg[2], 0, 0); 64733a6c79f802fabdb94367177310663397420e319fNick Kralevich rc2 = sqlite3_test_control(testctrl, p->db, opt); 647460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); 647590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } else { 647660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", 647790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown azArg[1]); 647890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 647990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown break; 648090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 648190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown /* sqlite3_test_control(int) */ 64821c7cea379348522163370244e8fbbff8a136b7faNick Kralevich case SQLITE_TESTCTRL_PRNG_SAVE: 64831c7cea379348522163370244e8fbbff8a136b7faNick Kralevich case SQLITE_TESTCTRL_PRNG_RESTORE: 648490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown case SQLITE_TESTCTRL_PRNG_RESET: 64851c7cea379348522163370244e8fbbff8a136b7faNick Kralevich case SQLITE_TESTCTRL_BYTEORDER: 648690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( nArg==2 ){ 64873a6c79f802fabdb94367177310663397420e319fNick Kralevich rc2 = sqlite3_test_control(testctrl); 648860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); 648990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } else { 649060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: testctrl %s takes no options\n", 649160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis azArg[1]); 649290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 649390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown break; 649490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 649590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown /* sqlite3_test_control(int, uint) */ 649660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_PENDING_BYTE: 649790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( nArg==3 ){ 64988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich unsigned int opt = (unsigned int)integerValue(azArg[2]); 64993a6c79f802fabdb94367177310663397420e319fNick Kralevich rc2 = sqlite3_test_control(testctrl, opt); 650060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); 650190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } else { 650260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: testctrl %s takes a single unsigned" 650390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown " int option\n", azArg[1]); 650490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 650590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown break; 650660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 650790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown /* sqlite3_test_control(int, int) */ 650860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_ASSERT: 650960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_ALWAYS: 651060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_NEVER_CORRUPT: 651190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( nArg==3 ){ 651260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis int opt = booleanValue(azArg[2]); 65133a6c79f802fabdb94367177310663397420e319fNick Kralevich rc2 = sqlite3_test_control(testctrl, opt); 651460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); 651590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } else { 651660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", 651790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown azArg[1]); 651890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 651990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown break; 652090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 652190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown /* sqlite3_test_control(int, char *) */ 652290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_N_KEYWORD 652360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_ISKEYWORD: 652490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( nArg==3 ){ 652560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *opt = azArg[2]; 65263a6c79f802fabdb94367177310663397420e319fNick Kralevich rc2 = sqlite3_test_control(testctrl, opt); 652760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); 652890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } else { 652960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, 653060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "Error: testctrl %s takes a single char * option\n", 653160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis azArg[1]); 653290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 653390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown break; 653490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 653590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 65363fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich case SQLITE_TESTCTRL_IMPOSTER: 65373fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nArg==5 ){ 653860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis rc2 = sqlite3_test_control(testctrl, p->db, 65393fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich azArg[2], 65403fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich integerValue(azArg[3]), 65413fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich integerValue(azArg[4])); 654260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); 65433fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else{ 654460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); 65453fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 65463fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich break; 65473fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 654860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_BITVEC_TEST: 654960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_FAULT_INSTALL: 655060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: 655160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis case SQLITE_TESTCTRL_SCRATCHMALLOC: 655290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown default: 655360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, 655460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "Error: CLI support for testctrl %s not implemented\n", 655560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis azArg[1]); 655690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown break; 655790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 655890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 655990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else 6560b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis#endif /* !defined(SQLITE_UNTESTABLE) */ 656190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 65621c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){ 65638fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 65641c7cea379348522163370244e8fbbff8a136b7faNick Kralevich sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); 65657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 656660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 65671c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){ 65681c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg==2 ){ 65691c7cea379348522163370244e8fbbff8a136b7faNick Kralevich enableTimer = booleanValue(azArg[1]); 65701c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( enableTimer && !HAS_TIMER ){ 657160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: timer not available on this system.\n"); 65721c7cea379348522163370244e8fbbff8a136b7faNick Kralevich enableTimer = 0; 65731c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 65741c7cea379348522163370244e8fbbff8a136b7faNick Kralevich }else{ 657560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .timer on|off\n"); 65761c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 65771c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 65787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 657960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 65801c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ 65818fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(p, 0); 65821c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( nArg!=2 ){ 658360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .trace FILE|off\n"); 65841c7cea379348522163370244e8fbbff8a136b7faNick Kralevich rc = 1; 65851c7cea379348522163370244e8fbbff8a136b7faNick Kralevich goto meta_command_exit; 65861c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 65873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich output_file_close(p->traceOut); 65888fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->traceOut = output_file_open(azArg[1]); 65898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) 65908fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( p->traceOut==0 ){ 659174bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis sqlite3_trace_v2(p->db, 0, 0, 0); 65928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else{ 659374bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut); 65948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 65958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#endif 65968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else 65978fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 65983fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if SQLITE_USER_AUTHENTICATION 65993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ 66003fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nArg<2 ){ 660160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n"); 66023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66033fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich goto meta_command_exit; 66043fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66053fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich open_db(p, 0); 66063fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( strcmp(azArg[1],"login")==0 ){ 66073fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nArg!=4 ){ 660860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .user login USER PASSWORD\n"); 66093fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66103fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich goto meta_command_exit; 66113fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66123fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], 66133fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich (int)strlen(azArg[3])); 66143fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( rc ){ 661560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); 66163fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66173fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66183fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(azArg[1],"add")==0 ){ 66193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nArg!=5 ){ 662060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n"); 66213fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66223fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich goto meta_command_exit; 66233fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = sqlite3_user_add(p->db, azArg[2], 66253fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich azArg[3], (int)strlen(azArg[3]), 66263fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich booleanValue(azArg[4])); 66273fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( rc ){ 662860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "User-Add failed: %d\n", rc); 66293fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66303fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66313fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(azArg[1],"edit")==0 ){ 66323fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nArg!=5 ){ 663360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n"); 66343fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66353fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich goto meta_command_exit; 66363fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66373fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = sqlite3_user_change(p->db, azArg[2], 66383fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich azArg[3], (int)strlen(azArg[3]), 66393fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich booleanValue(azArg[4])); 66403fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( rc ){ 664160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "User-Edit failed: %d\n", rc); 66423fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66433fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66443fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(azArg[1],"delete")==0 ){ 66453fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( nArg!=3 ){ 664660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .user delete USER\n"); 66473fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66483fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich goto meta_command_exit; 66493fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66503fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = sqlite3_user_delete(p->db, azArg[2]); 66513fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( rc ){ 665260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "User-Delete failed: %d\n", rc); 66533fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66543fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 66553fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else{ 665660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n"); 66573fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = 1; 66583fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich goto meta_command_exit; 665960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 66603fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else 66613fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif /* SQLITE_USER_AUTHENTICATION */ 66623fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 666390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ 666460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, 666590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_libversion(), sqlite3_sourceid()); 666690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else 666790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 666860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){ 666960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis const char *zDbName = nArg==2 ? azArg[1] : "main"; 66704b7ed9600a8a9a52e622980c609aab9038bdf6b4Alex Naidis sqlite3_vfs *pVfs = 0; 667160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->db ){ 667260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); 667360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pVfs ){ 667460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); 667560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); 667660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); 667760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); 667860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 667960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 668060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 668160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 668260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){ 668360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_vfs *pVfs; 668460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_vfs *pCurrent = 0; 668560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( p->db ){ 668660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent); 668760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 668860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ 668960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName, 669060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis pVfs==pCurrent ? " <--- CURRENT" : ""); 669160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); 669260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); 669360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); 669460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( pVfs->pNext ){ 669560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(p->out, "-----------------------------------\n"); 669660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 669760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 669860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else 669960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 670090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ 670190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zDbName = nArg==2 ? azArg[1] : "main"; 670290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown char *zVfsName = 0; 670390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( p->db ){ 670490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); 670590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( zVfsName ){ 670660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(p->out, "%s\n", zVfsName); 670790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_free(zVfsName); 670890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 670990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 671090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else 671190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 67128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) 67138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ 67141c7cea379348522163370244e8fbbff8a136b7faNick Kralevich sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; 67158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else 67168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#endif 67178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 67181c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ 67197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int j; 67207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project assert( nArg<=ArraySize(azArg) ); 67217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ 67228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich p->colWidth[j-1] = (int)integerValue(azArg[j]); 67237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 67247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else 67257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 67267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project { 672760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "Error: unknown command or invalid arguments: " 67287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " \"%s\". Enter \".help\" for help\n", azArg[0]); 6729a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = 1; 67307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 67317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 67321c7cea379348522163370244e8fbbff8a136b7faNick Kralevichmeta_command_exit: 67331c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( p->outCount ){ 67341c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->outCount--; 67351c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( p->outCount==0 ) output_reset(p); 67361c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 67377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return rc; 67387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 67397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 67407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 67417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return TRUE if a semicolon occurs anywhere in the first N characters 67427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** of string z[]. 67437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 67448fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic int line_contains_semicolon(const char *z, int N){ 67457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i; 67467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(i=0; i<N; i++){ if( z[i]==';' ) return 1; } 67477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 67487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 67497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 67507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 67517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Test to see if a line consists entirely of whitespace. 67527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 67537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic int _all_whitespace(const char *z){ 67547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project for(; *z; z++){ 675590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( IsSpace(z[0]) ) continue; 67567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( *z=='/' && z[1]=='*' ){ 67577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z += 2; 67587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project while( *z && (*z!='*' || z[1]!='/') ){ z++; } 67597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( *z==0 ) return 0; 67607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z++; 67617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project continue; 67627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 67637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( *z=='-' && z[1]=='-' ){ 67647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z += 2; 67657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project while( *z && *z!='\n' ){ z++; } 67667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( *z==0 ) return 1; 67677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project continue; 67687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 67697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 67707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 67717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 1; 67727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 67737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 67747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 67757790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return TRUE if the line typed in is an SQL command terminator other 67767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** than a semi-colon. The SQL Server style "go" command is understood 67777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** as is the Oracle "/". 67787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 67798fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic int line_is_command_terminator(const char *zLine){ 678090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown while( IsSpace(zLine[0]) ){ zLine++; }; 6781a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){ 6782a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; /* Oracle */ 6783a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 678490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' 67857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project && _all_whitespace(&zLine[2]) ){ 67867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 1; /* SQL Server */ 67877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 67887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 67897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 67907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 67917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 6792a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Return true if zSql is a complete SQL statement. Return false if it 6793a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** ends in the middle of a string literal or C-style comment. 6794a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori*/ 67958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic int line_is_complete(char *zSql, int nSql){ 6796a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int rc; 6797a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( zSql==0 ) return 1; 6798a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zSql[nSql] = ';'; 6799a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zSql[nSql+1] = 0; 6800a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori rc = sqlite3_complete(zSql); 6801a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori zSql[nSql] = 0; 6802a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return rc; 6803a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori} 6804a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori 6805a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori/* 6806e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani** Run a single line of SQL 6807e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani*/ 6808e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefanistatic int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ 6809e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani int rc; 6810e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char *zErrMsg = 0; 6811e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 6812e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani open_db(p, 0); 6813b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql); 6814e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani BEGIN_TIMER; 6815e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); 6816e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani END_TIMER; 6817e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( rc || zErrMsg ){ 6818e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani char zPrefix[100]; 6819e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( in!=0 || !stdin_is_interactive ){ 6820e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_snprintf(sizeof(zPrefix), zPrefix, 6821e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani "Error: near line %d:", startline); 6822e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 6823e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); 6824e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 6825e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( zErrMsg!=0 ){ 6826e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg); 6827e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_free(zErrMsg); 6828e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani zErrMsg = 0; 6829e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani }else{ 6830e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); 6831e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 6832e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani return 1; 6833b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis }else if( ShellHasFlag(p, SHFLG_CountChanges) ){ 6834e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani raw_printf(p->out, "changes: %3d total_changes: %d\n", 6835e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani sqlite3_changes(p->db), sqlite3_total_changes(p->db)); 6836e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani } 6837e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani return 0; 6838e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani} 6839e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 6840e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani 6841e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani/* 68427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Read input from *in and process it. If *in==0 then input 68437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is interactive - the user is typing it it. Otherwise, input 68447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is coming from a file or device. A prompt is issued and history 68457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** is saved only if input is interactive. An interrupt signal will 68467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** cause this routine to exit immediately, unless input is interactive. 68477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** 68487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return the number of errors. 68497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 68503fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic int process_input(ShellState *p, FILE *in){ 68518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zLine = 0; /* A single input line */ 68528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich char *zSql = 0; /* Accumulated SQL text */ 68538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nLine; /* Length of current line */ 68548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nSql = 0; /* Bytes of zSql[] used */ 68558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nAlloc = 0; /* Allocated zSql[] space */ 68568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */ 68578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int rc; /* Error code */ 68588fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int errCnt = 0; /* Number of errors seen */ 68598fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int lineno = 0; /* Current line number */ 68608fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int startline = 0; /* Line number for start of current input */ 68617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 68627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){ 68637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fflush(p->out); 68648fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zLine = one_input_line(in, zLine, nSql>0); 68657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zLine==0 ){ 68668fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* End of input */ 686708f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( in==0 && stdin_is_interactive ) printf("\n"); 68688fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich break; 68697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 68707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( seenInterrupt ){ 68717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( in!=0 ) break; 68727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project seenInterrupt = 0; 68737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 68747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project lineno++; 68758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( nSql==0 && _all_whitespace(zLine) ){ 6876b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); 68778fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich continue; 68788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 68797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zLine && zLine[0]=='.' && nSql==0 ){ 6880b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); 68817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = do_meta_command(zLine, p); 6882a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( rc==2 ){ /* exit requested */ 68837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project break; 68847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( rc ){ 68857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project errCnt++; 68867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 68877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project continue; 68887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 68898fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){ 68907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project memcpy(zLine,";",2); 68917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 68928fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich nLine = strlen30(zLine); 68938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( nSql+nLine+2>=nAlloc ){ 68948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich nAlloc = nSql+nLine+100; 68958fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zSql = realloc(zSql, nAlloc); 68968fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( zSql==0 ){ 689760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Error: out of memory\n"); 68988fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich exit(1); 68998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 69008fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 69017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project nSqlPrior = nSql; 69028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( nSql==0 ){ 69037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i; 690490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} 69058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich assert( nAlloc>0 && zSql!=0 ); 69068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich memcpy(zSql, zLine+i, nLine+1-i); 69078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich startline = lineno; 69088fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich nSql = nLine-i; 69097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 69107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zSql[nSql++] = '\n'; 69118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich memcpy(zSql+nSql, zLine, nLine+1); 69128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich nSql += nLine; 69137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 69148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) 69157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project && sqlite3_complete(zSql) ){ 6916e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani errCnt += runOneSqlLine(p, zSql, in, startline); 69178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich nSql = 0; 69181c7cea379348522163370244e8fbbff8a136b7faNick Kralevich if( p->outCount ){ 69191c7cea379348522163370244e8fbbff8a136b7faNick Kralevich output_reset(p); 69201c7cea379348522163370244e8fbbff8a136b7faNick Kralevich p->outCount = 0; 69211c7cea379348522163370244e8fbbff8a136b7faNick Kralevich } 69228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( nSql && _all_whitespace(zSql) ){ 6923b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql); 69247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project nSql = 0; 69257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 69267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 6927e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani if( nSql && !_all_whitespace(zSql) ){ 6928e7f3e808a8a09ccddbb17168c95fdd18e88ce974Luca Stefani runOneSqlLine(p, zSql, in, startline); 69297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 6930253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich free(zSql); 69317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project free(zLine); 69328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return errCnt>0; 69337790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 69347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 69357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 69367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Return a pathname which is the user's home directory. A 69378fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** 0 return indicates an error of some kind. 69387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 693908f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidisstatic char *find_home_dir(int clearFlag){ 69408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich static char *home_dir = NULL; 694108f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis if( clearFlag ){ 694208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis free(home_dir); 694308f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis home_dir = 0; 694408f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis return 0; 694508f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis } 69468fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( home_dir ) return home_dir; 69477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 69483fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \ 69493fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich && !defined(__RTP__) && !defined(_WRS_KERNEL) 69508fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich { 69518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich struct passwd *pwent; 69528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich uid_t uid = getuid(); 69538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( (pwent=getpwuid(uid)) != NULL) { 69548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich home_dir = pwent->pw_dir; 69558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 69567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 69577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 69587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 69597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#if defined(_WIN32_WCE) 69607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() 69617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 69628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich home_dir = "/"; 69637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else 69647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 69658fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#if defined(_WIN32) || defined(WIN32) 69667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if (!home_dir) { 69677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project home_dir = getenv("USERPROFILE"); 69687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 69697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 69707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 69717790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if (!home_dir) { 69727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project home_dir = getenv("HOME"); 69737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 69747790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 69758fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#if defined(_WIN32) || defined(WIN32) 69767790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if (!home_dir) { 69777790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zDrive, *zPath; 69787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int n; 69797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zDrive = getenv("HOMEDRIVE"); 69807790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project zPath = getenv("HOMEPATH"); 69817790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zDrive && zPath ){ 6982a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori n = strlen30(zDrive) + strlen30(zPath) + 1; 69837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project home_dir = malloc( n ); 69847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( home_dir==0 ) return 0; 69857790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); 69867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return home_dir; 69877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 69887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project home_dir = "c:\\"; 69897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 69907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 69917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 69927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif /* !_WIN32_WCE */ 69937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 69947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( home_dir ){ 6995a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori int n = strlen30(home_dir) + 1; 69967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *z = malloc( n ); 69977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( z ) memcpy(z, home_dir, n); 69987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project home_dir = z; 69997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 70007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 70017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return home_dir; 70027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 70037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 70047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 70057790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Read input from the file given by sqliterc_override. Or if that 70067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** parameter is NULL, take input from ~/.sqliterc 7007a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** 7008a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori** Returns the number of errors. 70097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 70103fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void process_sqliterc( 70113fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState *p, /* Configuration data */ 70127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project const char *sqliterc_override /* Name of config file. NULL to use default */ 70137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project){ 70147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *home_dir = NULL; 70157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project const char *sqliterc = sqliterc_override; 70167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zBuf = 0; 70177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project FILE *in = NULL; 70187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 70197790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if (sqliterc == NULL) { 702008f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis home_dir = find_home_dir(0); 70217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( home_dir==0 ){ 702260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "-- warning: cannot find home directory;" 70233fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " cannot read ~/.sqliterc\n"); 70243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return; 70257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 70268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_initialize(); 70278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); 70288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqliterc = zBuf; 70297790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 70307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project in = fopen(sqliterc,"rb"); 70317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( in ){ 70327790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( stdin_is_interactive ){ 703360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc); 70347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 70353fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich process_input(p,in); 70367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project fclose(in); 70377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 70388fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_free(zBuf); 70397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 70407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 70417790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 70427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Show available command line options 70437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 704460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisstatic const char zOptions[] = 70453fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " -ascii set output mode to 'ascii'\n" 70467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " -bail stop after hitting an error\n" 70477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " -batch force batch I/O\n" 70487790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " -column set output mode to 'column'\n" 70498fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " -cmd COMMAND run \"COMMAND\" before reading stdin\n" 70507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " -csv set output mode to 'csv'\n" 7051c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown " -echo print commands before execution\n" 70528fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " -init FILENAME read/process named file\n" 7053c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown " -[no]header turn headers on or off\n" 70548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) 70558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " -heap SIZE Size of heap for memsys3 or memsys5\n" 70568fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#endif 7057c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown " -help show this message\n" 70587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " -html set output mode to HTML\n" 7059c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown " -interactive force interactive I/O\n" 70607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " -line set output mode to 'line'\n" 70617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " -list set output mode to 'list'\n" 70623fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" 70638fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " -mmap N default mmap size set to N\n" 7064c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX 7065c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown " -multiplex enable the multiplexor VFS\n" 7066c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown#endif 70673fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " -newline SEP set output row separator. Default: '\\n'\n" 70688fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich " -nullvalue TEXT set text string for NULL values. Default ''\n" 70693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" 70703fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" 70713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich " -separator SEP set output column separator. Default: '|'\n" 7072de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori " -stats print memory stats before each finalize\n" 70737790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project " -version show SQLite version\n" 707490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown " -vfs NAME use NAME as the default VFS\n" 707590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE 707690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown " -vfstrace enable tracing of all VFS calls\n" 707790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 70787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project; 70797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Projectstatic void usage(int showDetail){ 708060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, 708160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis "Usage: %s [OPTIONS] FILENAME [SQL]\n" 70827790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "FILENAME is the name of an SQLite database. A new database is created\n" 70837790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project "if the file does not previously exist.\n", Argv0); 70847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( showDetail ){ 708560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "OPTIONS include:\n%s", zOptions); 70867790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 708760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "Use the -help option for additional information\n"); 70887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 70897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project exit(1); 70907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 70917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 70927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project/* 70937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project** Initialize the state information in data 70947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project*/ 70953fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichstatic void main_init(ShellState *data) { 70967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project memset(data, 0, sizeof(*data)); 709760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data->normalMode = data->cMode = data->mode = MODE_List; 709860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data->autoExplain = 1; 70993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich memcpy(data->colSeparator,SEP_Column, 2); 71003fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich memcpy(data->rowSeparator,SEP_Row, 2); 71017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data->showHeader = 0; 71023fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich data->shellFlgs = SHFLG_Lookaside; 710390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_config(SQLITE_CONFIG_URI, 1); 7104aae12b8a5af3a1ac77382b067d9ebb350fbd0644Vasu Nori sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); 71053fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_config(SQLITE_CONFIG_MULTITHREAD); 71067790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); 71077790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); 71087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 71097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 71108fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 71118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Output text to the console in a font that attracts extra attention. 71128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 71138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#ifdef _WIN32 71148fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic void printBold(const char *zText){ 71158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); 71168fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo; 71178fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich GetConsoleScreenBufferInfo(out, &defaultScreenInfo); 71188fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich SetConsoleTextAttribute(out, 71198fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich FOREGROUND_RED|FOREGROUND_INTENSITY 71208fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ); 71218fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("%s", zText); 71228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); 71238fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 71248fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#else 71258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic void printBold(const char *zText){ 71268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("\033[1m%s\033[0m", zText); 71278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 71288fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#endif 71298fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 71308fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich/* 71318fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** Get the argument to an --option. Throw an error and die if no argument 71328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich** is available. 71338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich*/ 71348fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevichstatic char *cmdline_option_value(int argc, char **argv, int i){ 71358fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( i==argc ){ 713660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "%s: Error: missing argument to %s\n", 71378fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich argv[0], argv[argc-1]); 71388fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich exit(1); 71398fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 71408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich return argv[i]; 71418fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich} 71428fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich 714360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#ifndef SQLITE_SHELL_IS_UTF8 714460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) 714560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# define SQLITE_SHELL_IS_UTF8 (0) 714660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# else 714760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# define SQLITE_SHELL_IS_UTF8 (1) 714860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis# endif 714960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 715060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 715160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if SQLITE_SHELL_IS_UTF8 71523fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevichint SQLITE_CDECL main(int argc, char **argv){ 715360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#else 715460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidisint SQLITE_CDECL wmain(int argc, wchar_t **wargv){ 715560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis char **argv; 715660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 71577790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zErrMsg = 0; 71583fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ShellState data; 71597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project const char *zInitFile = 0; 71607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int i; 71617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int rc = 0; 71628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich int warnInmemoryDb = 0; 71633fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int readStdin = 1; 71643fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int nCmd = 0; 71653fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich char **azCmd = 0; 71667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 716760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis setBinaryMode(stdin, 0); 716860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ 716960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis stdin_is_interactive = isatty(0); 717060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis stdout_is_console = isatty(1); 717160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis 71728fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#if USE_SYSTEM_SQLITE+0!=1 717390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ 717460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", 717590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_sourceid(), SQLITE_SOURCE_ID); 717690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown exit(1); 717790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 71788fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich#endif 71797790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project main_init(&data); 718060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if !SQLITE_SHELL_IS_UTF8 718160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_initialize(); 718260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis argv = sqlite3_malloc64(sizeof(argv[0])*argc); 718360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( argv==0 ){ 718460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "out of memory\n"); 718560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis exit(1); 718660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 718760fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<argc; i++){ 718860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]); 718960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( argv[i]==0 ){ 719060fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "out of memory\n"); 719160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis exit(1); 719260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 719360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis } 719460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 719560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis assert( argc>=1 && argv && argv[0] ); 719660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis Argv0 = argv[0]; 71977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 71987790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Make sure we have a valid signal handler early, before anything 71997790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** else is done. 72007790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 72017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifdef SIGINT 72027790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project signal(SIGINT, interrupt_handler); 72037790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 72047790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 72053fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#ifdef SQLITE_SHELL_DBNAME_PROC 72063fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich { 72073fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name 72083fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** of a C-function that will provide the name of the database file. Use 72093fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** this compile-time option to embed this shell program in larger 72103fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** applications. */ 72113fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich extern void SQLITE_SHELL_DBNAME_PROC(const char**); 72123fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename); 72133fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich warnInmemoryDb = 0; 72143fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 72153fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich#endif 72163fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich 72177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Do an initial pass through the command-line argument to locate 72187790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** the name of the database file, the name of the initialization file, 721990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown ** the size of the alternative malloc heap, 72207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** and the first command to execute. 72217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 72228fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=1; i<argc; i++){ 72237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *z; 72247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project z = argv[i]; 72258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( z[0]!='-' ){ 72268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( data.zDbFilename==0 ){ 72278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich data.zDbFilename = z; 72283fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else{ 72293fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* Excesss arguments are interpreted as SQL (or dot-commands) and 72303fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** mean that nothing is read from stdin */ 72313fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich readStdin = 0; 72323fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich nCmd++; 72333fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd); 72343fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( azCmd==0 ){ 723560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr, "out of memory\n"); 72363fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich exit(1); 72373fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 72383fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich azCmd[nCmd-1] = z; 72398fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 72408fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 7241c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( z[1]=='-' ) z++; 7242c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( strcmp(z,"-separator")==0 7243c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown || strcmp(z,"-nullvalue")==0 72449bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown || strcmp(z,"-newline")==0 7245c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown || strcmp(z,"-cmd")==0 7246c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown ){ 72478fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich (void)cmdline_option_value(argc, argv, ++i); 7248c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( strcmp(z,"-init")==0 ){ 72498fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zInitFile = cmdline_option_value(argc, argv, ++i); 7250c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( strcmp(z,"-batch")==0 ){ 72518fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich /* Need to check for batch mode here to so we can avoid printing 725260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis ** informational messages (like from process_sqliterc) before 72538fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich ** we do the actual processing of arguments later in a second pass. 72548fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich */ 7255a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori stdin_is_interactive = 0; 7256c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( strcmp(z,"-heap")==0 ){ 725790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) 725890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zSize; 725990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_int64 szHeap; 726090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown 72618fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich zSize = cmdline_option_value(argc, argv, ++i); 72628fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich szHeap = integerValue(zSize); 726390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; 726490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); 726574bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis#else 726674bd39cb46f3e9465fe069b650f40ffd8298a538Alex Naidis (void)cmdline_option_value(argc, argv, ++i); 726790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 72683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(z,"-scratch")==0 ){ 72693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int n, sz; 72703fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); 72713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sz>400000 ) sz = 400000; 72723fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sz<2500 ) sz = 2500; 72733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich n = (int)integerValue(cmdline_option_value(argc,argv,++i)); 72743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( n>10 ) n = 10; 72753fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( n<1 ) n = 1; 72763fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n); 72773fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich data.shellFlgs |= SHFLG_Scratch; 72783fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(z,"-pagecache")==0 ){ 72793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int n, sz; 72803fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); 72813fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sz>70000 ) sz = 70000; 728260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis if( sz<0 ) sz = 0; 72833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich n = (int)integerValue(cmdline_option_value(argc,argv,++i)); 728460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_config(SQLITE_CONFIG_PAGECACHE, 728560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); 72863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich data.shellFlgs |= SHFLG_Pagecache; 72873fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(z,"-lookaside")==0 ){ 72883fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich int n, sz; 72893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); 72903fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sz<0 ) sz = 0; 72913fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich n = (int)integerValue(cmdline_option_value(argc,argv,++i)); 72923fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( n<0 ) n = 0; 72933fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); 72943fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; 729590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE 7296c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( strcmp(z,"-vfstrace")==0 ){ 729790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown extern int vfstrace_register( 729890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zTraceName, 729990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown const char *zOldVfsName, 730090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown int (*xOut)(const char*,void*), 730190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown void *pOutArg, 730290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown int makeDefault 730390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown ); 730490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); 730590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 730690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX 7307c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( strcmp(z,"-multiplex")==0 ){ 730890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown extern int sqlite3_multiple_initialize(const char*,int); 730990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_multiplex_initialize(0, 1); 731090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 73118fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( strcmp(z,"-mmap")==0 ){ 73128fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); 73138fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); 7314c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( strcmp(z,"-vfs")==0 ){ 73158fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i)); 731690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown if( pVfs ){ 731790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_vfs_register(pVfs, 1); 731890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else{ 731960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); 732090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown exit(1); 732190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown } 73227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 73237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 73248fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( data.zDbFilename==0 ){ 73257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#ifndef SQLITE_OMIT_MEMORYDB 73267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.zDbFilename = ":memory:"; 73278fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich warnInmemoryDb = argc==1; 73287790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#else 732960fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0); 7330a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori return 1; 73317790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project#endif 73328fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 73338fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich data.out = stdout; 73347790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 73357790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Go ahead and open the database file if it already exists. If the 73367790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** file does not exist, delay opening it. This prevents empty database 73377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** files from being created if a user mistypes the database name argument 73387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** to the sqlite command-line tool. 73397790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 73407790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( access(data.zDbFilename, 0)==0 ){ 73418fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(&data, 0); 73427790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 73437790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 73447790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Process the initialization file if there is one. If no -init option 73457790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** is given on the command line, look for a file named ~/.sqliterc and 73467790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** try to process it. 73477790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 73483fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich process_sqliterc(&data,zInitFile); 73497790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 73507790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Make a second pass through the command-line argument and set 73517790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** options. This second pass is delayed until after the initialization 73527790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** file is processed so that the command-line arguments will override 73537790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ** settings in the initialization file. 73547790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 73558fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich for(i=1; i<argc; i++){ 73567790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *z = argv[i]; 73578fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( z[0]!='-' ) continue; 73587790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( z[1]=='-' ){ z++; } 73597790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( strcmp(z,"-init")==0 ){ 73607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project i++; 73617790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-html")==0 ){ 73627790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.mode = MODE_Html; 73637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-list")==0 ){ 73647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.mode = MODE_List; 73657790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-line")==0 ){ 73667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.mode = MODE_Line; 73677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-column")==0 ){ 73687790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.mode = MODE_Column; 73697790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-csv")==0 ){ 73707790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.mode = MODE_Csv; 73713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich memcpy(data.colSeparator,",",2); 73723fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(z,"-ascii")==0 ){ 73733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich data.mode = MODE_Ascii; 73743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, 73753fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich SEP_Unit); 73763fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, 73773fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich SEP_Record); 73787790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-separator")==0 ){ 73793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, 73808fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "%s",cmdline_option_value(argc,argv,++i)); 73819bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown }else if( strcmp(z,"-newline")==0 ){ 73823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, 73839bee60b0fc0b60d4ae9e7533e0e6b7beca5f37fcJeff Brown "%s",cmdline_option_value(argc,argv,++i)); 73847790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-nullvalue")==0 ){ 73853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich sqlite3_snprintf(sizeof(data.nullValue), data.nullValue, 73868fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "%s",cmdline_option_value(argc,argv,++i)); 73877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-header")==0 ){ 73887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.showHeader = 1; 73897790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-noheader")==0 ){ 73907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project data.showHeader = 0; 73917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-echo")==0 ){ 7392b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellSetFlag(&data, SHFLG_Echo); 73938fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( strcmp(z,"-eqp")==0 ){ 73948fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich data.autoEQP = 1; 739560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis }else if( strcmp(z,"-eqpfull")==0 ){ 739660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data.autoEQP = 2; 7397de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori }else if( strcmp(z,"-stats")==0 ){ 7398de2b3240539802d409a25760d5cec9d4ebfd6686Vasu Nori data.statsOn = 1; 73993fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(z,"-scanstats")==0 ){ 74003fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich data.scanstatsOn = 1; 74013a6c79f802fabdb94367177310663397420e319fNick Kralevich }else if( strcmp(z,"-backslash")==0 ){ 74023a6c79f802fabdb94367177310663397420e319fNick Kralevich /* Undocumented command-line option: -backslash 74033a6c79f802fabdb94367177310663397420e319fNick Kralevich ** Causes C-style backslash escapes to be evaluated in SQL statements 74043a6c79f802fabdb94367177310663397420e319fNick Kralevich ** prior to sending the SQL into SQLite. Useful for injecting 74053a6c79f802fabdb94367177310663397420e319fNick Kralevich ** crazy bytes in the middle of SQL statements for testing and debugging. 74063a6c79f802fabdb94367177310663397420e319fNick Kralevich */ 7407b86c0cf2300ba27af03e33f64a4c73be84a4c8a2Alex Naidis ShellSetFlag(&data, SHFLG_Backslash); 74087790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-bail")==0 ){ 74097790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project bail_on_error = 1; 74107790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-version")==0 ){ 741190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); 74127790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 0; 74137790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-interactive")==0 ){ 74147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project stdin_is_interactive = 1; 74157790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else if( strcmp(z,"-batch")==0 ){ 74167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project stdin_is_interactive = 0; 741790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else if( strcmp(z,"-heap")==0 ){ 741890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown i++; 74193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(z,"-scratch")==0 ){ 74203fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich i+=2; 74213fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(z,"-pagecache")==0 ){ 74223fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich i+=2; 74233fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( strcmp(z,"-lookaside")==0 ){ 74243fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich i+=2; 74258fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich }else if( strcmp(z,"-mmap")==0 ){ 74268fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich i++; 742790ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else if( strcmp(z,"-vfs")==0 ){ 742890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown i++; 742990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_VFSTRACE 743090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else if( strcmp(z,"-vfstrace")==0 ){ 743190ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown i++; 743290ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 743390ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#ifdef SQLITE_ENABLE_MULTIPLEX 743490ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown }else if( strcmp(z,"-multiplex")==0 ){ 743590ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown i++; 743690ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown#endif 7437c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( strcmp(z,"-help")==0 ){ 74387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project usage(1); 7439c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( strcmp(z,"-cmd")==0 ){ 74403fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* Run commands that follow -cmd first and separately from commands 74413fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** that simply appear on the command-line. This seems goofy. It would 74423fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** be better if all commands ran in the order that they appear. But 74433fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** we retain the goofy behavior for historical compatibility. */ 7444c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( i==argc-1 ) break; 74458fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich z = cmdline_option_value(argc,argv,++i); 7446c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( z[0]=='.' ){ 7447c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown rc = do_meta_command(z, &data); 74488fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( rc && bail_on_error ) return rc==2 ? 0 : rc; 7449c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else{ 74508fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich open_db(&data, 0); 7451c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg); 7452c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( zErrMsg!=0 ){ 745360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: %s\n", zErrMsg); 7454c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( bail_on_error ) return rc!=0 ? rc : 1; 7455c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown }else if( rc!=0 ){ 745660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z); 7457c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown if( bail_on_error ) return rc; 7458c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown } 7459c82acac4e67711e8d9289b572d334298aeb5d806Jeff Brown } 74607790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 746160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); 746260fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis raw_printf(stderr,"Use -help for a list of options.\n"); 74637790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return 1; 74647790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 746560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis data.cMode = data.mode; 74667790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 74677790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project 74683fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( !readStdin ){ 74693fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich /* Run all arguments that do not begin with '-' as if they were separate 74703fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** command-line inputs, except for the argToSkip argument which contains 74713fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich ** the database filename. 74727790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 74733fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich for(i=0; i<nCmd; i++){ 74743fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( azCmd[i][0]=='.' ){ 74753fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = do_meta_command(azCmd[i], &data); 74763fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( rc ) return rc==2 ? 0 : rc; 74773fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else{ 74783fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich open_db(&data, 0); 74793fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg); 74803fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich if( zErrMsg!=0 ){ 748160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: %s\n", zErrMsg); 74823fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return rc!=0 ? rc : 1; 74833fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich }else if( rc!=0 ){ 748460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]); 74853fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich return rc; 74863fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich } 74877790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 74887790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 74893fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich free(azCmd); 74907790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 74917790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project /* Run commands received from standard input 74927790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project */ 74937790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( stdin_is_interactive ){ 74947790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zHome; 74957790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project char *zHistory = 0; 74967790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project int nHistory; 74977790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project printf( 749890ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown "SQLite version %s %.19s\n" /*extra-version-info*/ 74998fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "Enter \".help\" for usage hints.\n", 750090ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_libversion(), sqlite3_sourceid() 75017790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project ); 75028fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich if( warnInmemoryDb ){ 75038fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf("Connected to a "); 75048fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printBold("transient in-memory database"); 75058fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich printf(".\nUse \".open FILENAME\" to reopen on a " 75068fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich "persistent database.\n"); 75078fecf56c625b5691ee3381e107ccbe1ff42398b1Nick Kralevich } 750808f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis zHome = find_home_dir(0); 7509a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( zHome ){ 7510a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori nHistory = strlen30(zHome) + 20; 7511a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori if( (zHistory = malloc(nHistory))!=0 ){ 7512a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); 7513a4356a0ea71404ae414a07eafd7b95b91cc88c8cVasu Nori } 75147790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 7515253ed64ded244ef3d8a7226efb812e7989bc8026Nick Kralevich if( zHistory ){ shell_read_history(zHistory); } 75167790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = process_input(&data, 0); 75177790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project if( zHistory ){ 75183fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich shell_stifle_history(100); 75193fcd43a0f1ef02756029e12af3cb9ba9faa13364Nick Kralevich shell_write_history(zHistory); 75207790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project free(zHistory); 75217790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 75227790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project }else{ 75237790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project rc = process_input(&data, stdin); 75247790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 75257790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 75267790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project set_table_name(&data, 0); 752771504cf29d6d55df7d2aac17ecb160f7e5470553Vasu Nori if( data.db ){ 752860fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis session_close_all(&data); 752990ed05d921d6ed7f12012d9786d53f57fafee51aJeff Brown sqlite3_close(data.db); 75307790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project } 753160fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(data.zFreeOnClose); 753208f78cbf3cb8295a3b9e0be36b6778051ba4add6Alex Naidis find_home_dir(1); 753360fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#if !SQLITE_SHELL_IS_UTF8 753460fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis for(i=0; i<argc; i++) sqlite3_free(argv[i]); 753560fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis sqlite3_free(argv); 753660fa6fd5623cb0939ef089b799adeb068389218fAlex Naidis#endif 75377790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project return rc; 75387790ef5367fe6731048c3e3a1c067f94b321cb4dThe Android Open Source Project} 7539