version 1.12, 2015/04/19 14:25:05 |
version 1.13, 2015/09/12 02:08:36 |
|
|
#if defined(_WIN32) || defined(WIN32) |
#if defined(_WIN32) || defined(WIN32) |
# include <io.h> |
# include <io.h> |
# include <fcntl.h> |
# include <fcntl.h> |
#define isatty(h) _isatty(h) |
# define isatty(h) _isatty(h) |
#ifndef access |
# ifndef access |
# define access(f,m) _access((f),(m)) |
# define access(f,m) _access((f),(m)) |
#endif |
# endif |
#undef popen |
# undef popen |
#define popen _popen |
# define popen _popen |
#undef pclose |
# undef pclose |
#define pclose _pclose |
# define pclose _pclose |
#else |
#else |
/* Make sure isatty() has a prototype. |
/* Make sure isatty() has a prototype. */ |
*/ |
extern int isatty(int); |
extern int isatty(int); |
|
|
|
#if !defined(__RTP__) && !defined(_WRS_KERNEL) |
# if !defined(__RTP__) && !defined(_WRS_KERNEL) |
/* popen and pclose are not C89 functions and so are sometimes omitted from |
/* popen and pclose are not C89 functions and so are |
** the <stdio.h> header */ |
** sometimes omitted from the <stdio.h> header */ |
extern FILE *popen(const char*,const char*); |
extern FILE *popen(const char*,const char*); |
extern int pclose(FILE*); |
extern int pclose(FILE*); |
#else |
# else |
# define SQLITE_OMIT_POPEN 1 |
# define SQLITE_OMIT_POPEN 1 |
|
# endif |
#endif |
#endif |
|
|
#endif |
|
|
|
#if defined(_WIN32_WCE) |
#if defined(_WIN32_WCE) |
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() |
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() |
* thus we always assume that we have a console. That can be |
* thus we always assume that we have a console. That can be |
|
|
** to this database a static variable so that it can be accessed |
** to this database a static variable so that it can be accessed |
** by the SIGINT handler to interrupt database processing. |
** by the SIGINT handler to interrupt database processing. |
*/ |
*/ |
static sqlite3 *db = 0; |
static sqlite3 *globalDb = 0; |
|
|
/* |
/* |
** True if an interrupt (Control-C) has been received. |
** True if an interrupt (Control-C) has been received. |
|
|
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ |
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ |
int statsOn; /* True to display memory stats before each finalize */ |
int statsOn; /* True to display memory stats before each finalize */ |
int scanstatsOn; /* True to display scan stats before each finalize */ |
int scanstatsOn; /* True to display scan stats before each finalize */ |
|
int backslashOn; /* Resolve C-style \x escapes in SQL input text */ |
int outCount; /* Revert to stdout when reaching zero */ |
int outCount; /* Revert to stdout when reaching zero */ |
int cnt; /* Number of records displayed so far */ |
int cnt; /* Number of records displayed so far */ |
FILE *out; /* Write results here */ |
FILE *out; /* Write results here */ |
|
|
UNUSED_PARAMETER(NotUsed); |
UNUSED_PARAMETER(NotUsed); |
seenInterrupt++; |
seenInterrupt++; |
if( seenInterrupt>2 ) exit(1); |
if( seenInterrupt>2 ) exit(1); |
if( db ) sqlite3_interrupt(db); |
if( globalDb ) sqlite3_interrupt(globalDb); |
} |
} |
#endif |
#endif |
|
|
|
|
case MODE_Insert: { |
case MODE_Insert: { |
p->cnt++; |
p->cnt++; |
if( azArg==0 ) break; |
if( azArg==0 ) break; |
fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable); |
fprintf(p->out,"INSERT INTO %s",p->zDestTable); |
|
if( p->showHeader ){ |
|
fprintf(p->out,"("); |
|
for(i=0; i<nArg; i++){ |
|
char *zSep = i>0 ? ",": ""; |
|
fprintf(p->out, "%s%s", zSep, azCol[i]); |
|
} |
|
fprintf(p->out,")"); |
|
} |
|
fprintf(p->out," VALUES("); |
for(i=0; i<nArg; i++){ |
for(i=0; i<nArg; i++){ |
char *zSep = i>0 ? ",": ""; |
char *zSep = i>0 ? ",": ""; |
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ |
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ |
|
|
sqlite3 *db /* Database to query */ |
sqlite3 *db /* Database to query */ |
){ |
){ |
int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); |
int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); |
char *zErrMsg = sqlite3_malloc(nErrMsg); |
char *zErrMsg = sqlite3_malloc64(nErrMsg); |
if( zErrMsg ){ |
if( zErrMsg ){ |
memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); |
memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); |
} |
} |
|
|
sqlite3 *db, /* Database to query */ |
sqlite3 *db, /* Database to query */ |
ShellState *pArg /* Pointer to ShellState */ |
ShellState *pArg /* Pointer to ShellState */ |
){ |
){ |
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS |
|
UNUSED_PARAMETER(db); |
|
UNUSED_PARAMETER(pArg); |
|
#else |
int i, k, n, mx; |
int i, k, n, mx; |
fprintf(pArg->out, "-------- scanstats --------\n"); |
fprintf(pArg->out, "-------- scanstats --------\n"); |
mx = 0; |
mx = 0; |
|
|
/* Grow the p->aiIndent array as required */ |
/* Grow the p->aiIndent array as required */ |
if( iOp>=nAlloc ){ |
if( iOp>=nAlloc ){ |
nAlloc += 100; |
nAlloc += 100; |
p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int)); |
p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); |
abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int)); |
abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); |
} |
} |
abYield[iOp] = str_in_array(zOp, azYield); |
abYield[iOp] = str_in_array(zOp, azYield); |
p->aiIndent[iOp] = 0; |
p->aiIndent[iOp] = 0; |
|
|
if( xCallback ){ |
if( xCallback ){ |
/* allocate space for col name ptr, value ptr, and type */ |
/* allocate space for col name ptr, value ptr, and type */ |
int nCol = sqlite3_column_count(pStmt); |
int nCol = sqlite3_column_count(pStmt); |
void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1); |
void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); |
if( !pData ){ |
if( !pData ){ |
rc = SQLITE_NOMEM; |
rc = SQLITE_NOMEM; |
}else{ |
}else{ |
|
|
static char zHelp[] = |
static char zHelp[] = |
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" |
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" |
".bail on|off Stop after hitting an error. Default OFF\n" |
".bail on|off Stop after hitting an error. Default OFF\n" |
|
".binary on|off Turn binary output on or off. Default OFF\n" |
".clone NEWDB Clone data into NEWDB from the existing database\n" |
".clone NEWDB Clone data into NEWDB from the existing database\n" |
".databases List names and files of attached databases\n" |
".databases List names and files of attached databases\n" |
".dbinfo ?DB? Show status information about the database\n" |
".dbinfo ?DB? Show status information about the database\n" |
|
|
#ifdef SQLITE_ENABLE_IOTRACE |
#ifdef SQLITE_ENABLE_IOTRACE |
".iotrace FILE Enable I/O diagnostic logging to FILE\n" |
".iotrace FILE Enable I/O diagnostic logging to FILE\n" |
#endif |
#endif |
|
".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" |
#ifndef SQLITE_OMIT_LOAD_EXTENSION |
#ifndef SQLITE_OMIT_LOAD_EXTENSION |
".load FILE ?ENTRY? Load an extension library\n" |
".load FILE ?ENTRY? Load an extension library\n" |
#endif |
#endif |
|
|
long nIn; |
long nIn; |
void *pBuf; |
void *pBuf; |
|
|
|
UNUSED_PARAMETER(argc); |
zName = (const char*)sqlite3_value_text(argv[0]); |
zName = (const char*)sqlite3_value_text(argv[0]); |
if( zName==0 ) return; |
if( zName==0 ) return; |
in = fopen(zName, "rb"); |
in = fopen(zName, "rb"); |
|
|
fseek(in, 0, SEEK_END); |
fseek(in, 0, SEEK_END); |
nIn = ftell(in); |
nIn = ftell(in); |
rewind(in); |
rewind(in); |
pBuf = sqlite3_malloc( nIn ); |
pBuf = sqlite3_malloc64( nIn ); |
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ |
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ |
sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); |
sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); |
}else{ |
}else{ |
|
|
sqlite3_int64 rc; |
sqlite3_int64 rc; |
const char *zFile; |
const char *zFile; |
|
|
|
UNUSED_PARAMETER(argc); |
zFile = (const char*)sqlite3_value_text(argv[0]); |
zFile = (const char*)sqlite3_value_text(argv[0]); |
if( zFile==0 ) return; |
if( zFile==0 ) return; |
out = fopen(zFile, "wb"); |
out = fopen(zFile, "wb"); |
|
|
if( p->db==0 ){ |
if( p->db==0 ){ |
sqlite3_initialize(); |
sqlite3_initialize(); |
sqlite3_open(p->zDbFilename, &p->db); |
sqlite3_open(p->zDbFilename, &p->db); |
db = p->db; |
globalDb = p->db; |
if( db && sqlite3_errcode(db)==SQLITE_OK ){ |
if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){ |
sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0, |
sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0, |
shellstaticFunc, 0, 0); |
shellstaticFunc, 0, 0); |
} |
} |
if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){ |
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ |
fprintf(stderr,"Error: unable to open database \"%s\": %s\n", |
fprintf(stderr,"Error: unable to open database \"%s\": %s\n", |
p->zDbFilename, sqlite3_errmsg(db)); |
p->zDbFilename, sqlite3_errmsg(p->db)); |
if( keepAlive ) return; |
if( keepAlive ) return; |
exit(1); |
exit(1); |
} |
} |
#ifndef SQLITE_OMIT_LOAD_EXTENSION |
#ifndef SQLITE_OMIT_LOAD_EXTENSION |
sqlite3_enable_load_extension(p->db, 1); |
sqlite3_enable_load_extension(p->db, 1); |
#endif |
#endif |
sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, |
sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0, |
readfileFunc, 0, 0); |
readfileFunc, 0, 0); |
sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, |
sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0, |
writefileFunc, 0, 0); |
writefileFunc, 0, 0); |
} |
} |
} |
} |
|
|
/* |
/* |
** Do C-language style dequoting. |
** Do C-language style dequoting. |
** |
** |
|
** \a -> alarm |
|
** \b -> backspace |
** \t -> tab |
** \t -> tab |
** \n -> newline |
** \n -> newline |
|
** \v -> vertical tab |
|
** \f -> form feed |
** \r -> carriage return |
** \r -> carriage return |
|
** \s -> space |
** \" -> " |
** \" -> " |
** \NNN -> ascii character NNN in octal |
** \' -> ' |
** \\ -> backslash |
** \\ -> backslash |
|
** \NNN -> ascii character NNN in octal |
*/ |
*/ |
static void resolve_backslashes(char *z){ |
static void resolve_backslashes(char *z){ |
int i, j; |
int i, j; |
char c; |
char c; |
while( *z && *z!='\\' ) z++; |
while( *z && *z!='\\' ) z++; |
for(i=j=0; (c = z[i])!=0; i++, j++){ |
for(i=j=0; (c = z[i])!=0; i++, j++){ |
if( c=='\\' ){ |
if( c=='\\' && z[i+1]!=0 ){ |
c = z[++i]; |
c = z[++i]; |
if( c=='n' ){ |
if( c=='a' ){ |
c = '\n'; |
c = '\a'; |
|
}else if( c=='b' ){ |
|
c = '\b'; |
}else if( c=='t' ){ |
}else if( c=='t' ){ |
c = '\t'; |
c = '\t'; |
|
}else if( c=='n' ){ |
|
c = '\n'; |
|
}else if( c=='v' ){ |
|
c = '\v'; |
|
}else if( c=='f' ){ |
|
c = '\f'; |
}else if( c=='r' ){ |
}else if( c=='r' ){ |
c = '\r'; |
c = '\r'; |
|
}else if( c=='"' ){ |
|
c = '"'; |
|
}else if( c=='\'' ){ |
|
c = '\''; |
}else if( c=='\\' ){ |
}else if( c=='\\' ){ |
c = '\\'; |
c = '\\'; |
}else if( c>='0' && c<='7' ){ |
}else if( c>='0' && c<='7' ){ |
|
|
static void import_append_char(ImportCtx *p, int c){ |
static void import_append_char(ImportCtx *p, int c){ |
if( p->n+1>=p->nAlloc ){ |
if( p->n+1>=p->nAlloc ){ |
p->nAlloc += p->nAlloc + 100; |
p->nAlloc += p->nAlloc + 100; |
p->z = sqlite3_realloc(p->z, p->nAlloc); |
p->z = sqlite3_realloc64(p->z, p->nAlloc); |
if( p->z==0 ){ |
if( p->z==0 ){ |
fprintf(stderr, "out of memory\n"); |
fprintf(stderr, "out of memory\n"); |
exit(1); |
exit(1); |
|
|
** |
** |
** + Input comes from p->in. |
** + Input comes from p->in. |
** + Store results in p->z of length p->n. Space to hold p->z comes |
** + Store results in p->z of length p->n. Space to hold p->z comes |
** from sqlite3_malloc(). |
** from sqlite3_malloc64(). |
** + Use p->cSep as the column separator. The default is ",". |
** + Use p->cSep as the column separator. The default is ",". |
** + Use p->rSep as the row separator. The default is "\n". |
** + Use p->rSep as the row separator. The default is "\n". |
** + Keep track of the line number in p->nLine. |
** + Keep track of the line number in p->nLine. |
|
|
** |
** |
** + Input comes from p->in. |
** + Input comes from p->in. |
** + Store results in p->z of length p->n. Space to hold p->z comes |
** + Store results in p->z of length p->n. Space to hold p->z comes |
** from sqlite3_malloc(). |
** from sqlite3_malloc64(). |
** + Use p->cSep as the column separator. The default is "\x1F". |
** + Use p->cSep as the column separator. The default is "\x1F". |
** + Use p->rSep as the row separator. The default is "\x1E". |
** + Use p->rSep as the row separator. The default is "\x1E". |
** + Keep track of the row number in p->nLine. |
** + Keep track of the row number in p->nLine. |
|
|
goto end_data_xfer; |
goto end_data_xfer; |
} |
} |
n = sqlite3_column_count(pQuery); |
n = sqlite3_column_count(pQuery); |
zInsert = sqlite3_malloc(200 + nTable + n*3); |
zInsert = sqlite3_malloc64(200 + nTable + n*3); |
if( zInsert==0 ){ |
if( zInsert==0 ){ |
fprintf(stderr, "out of memory\n"); |
fprintf(stderr, "out of memory\n"); |
goto end_data_xfer; |
goto end_data_xfer; |
|
|
fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); |
fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); |
fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); |
fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); |
fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); |
fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); |
for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){ |
for(i=0; i<ArraySize(aField); i++){ |
int ofst = aField[i].ofst; |
int ofst = aField[i].ofst; |
unsigned int val = get4byteInt(aHdr + ofst); |
unsigned int val = get4byteInt(aHdr + ofst); |
fprintf(p->out, "%-20s %u", aField[i].zName, val); |
fprintf(p->out, "%-20s %u", aField[i].zName, val); |
|
|
}else{ |
}else{ |
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); |
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); |
} |
} |
for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){ |
for(i=0; i<ArraySize(aQuery); i++){ |
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); |
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); |
int val = db_int(p, zSql); |
int val = db_int(p, zSql); |
sqlite3_free(zSql); |
sqlite3_free(zSql); |
|
|
** Return 1 on error, 2 to exit, and 0 otherwise. |
** Return 1 on error, 2 to exit, and 0 otherwise. |
*/ |
*/ |
static int do_meta_command(char *zLine, ShellState *p){ |
static int do_meta_command(char *zLine, ShellState *p){ |
int i = 1; |
int h = 1; |
int nArg = 0; |
int nArg = 0; |
int n, c; |
int n, c; |
int rc = 0; |
int rc = 0; |
|
|
|
|
/* Parse the input line into tokens. |
/* Parse the input line into tokens. |
*/ |
*/ |
while( zLine[i] && nArg<ArraySize(azArg) ){ |
while( zLine[h] && nArg<ArraySize(azArg) ){ |
while( IsSpace(zLine[i]) ){ i++; } |
while( IsSpace(zLine[h]) ){ h++; } |
if( zLine[i]==0 ) break; |
if( zLine[h]==0 ) break; |
if( zLine[i]=='\'' || zLine[i]=='"' ){ |
if( zLine[h]=='\'' || zLine[h]=='"' ){ |
int delim = zLine[i++]; |
int delim = zLine[h++]; |
azArg[nArg++] = &zLine[i]; |
azArg[nArg++] = &zLine[h]; |
while( zLine[i] && zLine[i]!=delim ){ |
while( zLine[h] && zLine[h]!=delim ){ |
if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++; |
if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++; |
i++; |
h++; |
} |
} |
if( zLine[i]==delim ){ |
if( zLine[h]==delim ){ |
zLine[i++] = 0; |
zLine[h++] = 0; |
} |
} |
if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); |
if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); |
}else{ |
}else{ |
azArg[nArg++] = &zLine[i]; |
azArg[nArg++] = &zLine[h]; |
while( zLine[i] && !IsSpace(zLine[i]) ){ i++; } |
while( zLine[h] && !IsSpace(zLine[h]) ){ h++; } |
if( zLine[i] ) zLine[i++] = 0; |
if( zLine[h] ) zLine[h++] = 0; |
resolve_backslashes(azArg[nArg-1]); |
resolve_backslashes(azArg[nArg-1]); |
} |
} |
} |
} |
|
|
} |
} |
}else |
}else |
|
|
|
if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){ |
|
if( nArg==2 ){ |
|
if( booleanValue(azArg[1]) ){ |
|
setBinaryMode(p->out); |
|
}else{ |
|
setTextMode(p->out); |
|
} |
|
}else{ |
|
fprintf(stderr, "Usage: .binary on|off\n"); |
|
rc = 1; |
|
} |
|
}else |
|
|
/* The undocumented ".breakpoint" command causes a call to the no-op |
/* The undocumented ".breakpoint" command causes a call to the no-op |
** routine named test_breakpoint(). |
** routine named test_breakpoint(). |
*/ |
*/ |
|
|
nByte = strlen30(zSql); |
nByte = strlen30(zSql); |
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ |
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ |
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){ |
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){ |
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); |
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); |
char cSep = '('; |
char cSep = '('; |
while( xRead(&sCtx) ){ |
while( xRead(&sCtx) ){ |
|
|
sqlite3_free(zCreate); |
sqlite3_free(zCreate); |
if( rc ){ |
if( rc ){ |
fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, |
fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, |
sqlite3_errmsg(db)); |
sqlite3_errmsg(p->db)); |
sqlite3_free(sCtx.z); |
sqlite3_free(sCtx.z); |
xCloser(sCtx.in); |
xCloser(sCtx.in); |
return 1; |
return 1; |
|
|
sqlite3_free(zSql); |
sqlite3_free(zSql); |
if( rc ){ |
if( rc ){ |
if (pStmt) sqlite3_finalize(pStmt); |
if (pStmt) sqlite3_finalize(pStmt); |
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); |
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); |
xCloser(sCtx.in); |
xCloser(sCtx.in); |
return 1; |
return 1; |
} |
} |
|
|
sqlite3_finalize(pStmt); |
sqlite3_finalize(pStmt); |
pStmt = 0; |
pStmt = 0; |
if( nCol==0 ) return 0; /* no columns, no error */ |
if( nCol==0 ) return 0; /* no columns, no error */ |
zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 ); |
zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); |
if( zSql==0 ){ |
if( zSql==0 ){ |
fprintf(stderr, "Error: out of memory\n"); |
fprintf(stderr, "Error: out of memory\n"); |
xCloser(sCtx.in); |
xCloser(sCtx.in); |
|
|
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
sqlite3_free(zSql); |
sqlite3_free(zSql); |
if( rc ){ |
if( rc ){ |
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); |
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); |
if (pStmt) sqlite3_finalize(pStmt); |
if (pStmt) sqlite3_finalize(pStmt); |
xCloser(sCtx.in); |
xCloser(sCtx.in); |
return 1; |
return 1; |
} |
} |
needCommit = sqlite3_get_autocommit(db); |
needCommit = sqlite3_get_autocommit(p->db); |
if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0); |
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); |
do{ |
do{ |
int startLine = sCtx.nLine; |
int startLine = sCtx.nLine; |
for(i=0; i<nCol; i++){ |
for(i=0; i<nCol; i++){ |
|
|
rc = sqlite3_reset(pStmt); |
rc = sqlite3_reset(pStmt); |
if( rc!=SQLITE_OK ){ |
if( rc!=SQLITE_OK ){ |
fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, |
fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, |
sqlite3_errmsg(db)); |
sqlite3_errmsg(p->db)); |
} |
} |
} |
} |
}while( sCtx.cTerm!=EOF ); |
}while( sCtx.cTerm!=EOF ); |
|
|
xCloser(sCtx.in); |
xCloser(sCtx.in); |
sqlite3_free(sCtx.z); |
sqlite3_free(sCtx.z); |
sqlite3_finalize(pStmt); |
sqlite3_finalize(pStmt); |
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); |
}else |
}else |
|
|
if( c=='i' && (strncmp(azArg[0], "indices", n)==0 |
if( c=='i' && (strncmp(azArg[0], "indices", n)==0 |
|
|
} |
} |
}else |
}else |
#endif |
#endif |
|
if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){ |
|
static const struct { |
|
const char *zLimitName; /* Name of a limit */ |
|
int limitCode; /* Integer code for that limit */ |
|
} aLimit[] = { |
|
{ "length", SQLITE_LIMIT_LENGTH }, |
|
{ "sql_length", SQLITE_LIMIT_SQL_LENGTH }, |
|
{ "column", SQLITE_LIMIT_COLUMN }, |
|
{ "expr_depth", SQLITE_LIMIT_EXPR_DEPTH }, |
|
{ "compound_select", SQLITE_LIMIT_COMPOUND_SELECT }, |
|
{ "vdbe_op", SQLITE_LIMIT_VDBE_OP }, |
|
{ "function_arg", SQLITE_LIMIT_FUNCTION_ARG }, |
|
{ "attached", SQLITE_LIMIT_ATTACHED }, |
|
{ "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH }, |
|
{ "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER }, |
|
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH }, |
|
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS }, |
|
}; |
|
int i, n2; |
|
open_db(p, 0); |
|
if( nArg==1 ){ |
|
for(i=0; i<ArraySize(aLimit); i++){ |
|
printf("%20s %d\n", aLimit[i].zLimitName, |
|
sqlite3_limit(p->db, aLimit[i].limitCode, -1)); |
|
} |
|
}else if( nArg>3 ){ |
|
fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n"); |
|
rc = 1; |
|
goto meta_command_exit; |
|
}else{ |
|
int iLimit = -1; |
|
n2 = strlen30(azArg[1]); |
|
for(i=0; i<ArraySize(aLimit); i++){ |
|
if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){ |
|
if( iLimit<0 ){ |
|
iLimit = i; |
|
}else{ |
|
fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]); |
|
rc = 1; |
|
goto meta_command_exit; |
|
} |
|
} |
|
} |
|
if( iLimit<0 ){ |
|
fprintf(stderr, "unknown limit: \"%s\"\n" |
|
"enter \".limits\" with no arguments for a list.\n", |
|
azArg[1]); |
|
rc = 1; |
|
goto meta_command_exit; |
|
} |
|
if( nArg==3 ){ |
|
sqlite3_limit(p->db, aLimit[iLimit].limitCode, |
|
(int)integerValue(azArg[2])); |
|
} |
|
printf("%20s %d\n", aLimit[iLimit].zLimitName, |
|
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); |
|
} |
|
}else |
|
|
#ifndef SQLITE_OMIT_LOAD_EXTENSION |
#ifndef SQLITE_OMIT_LOAD_EXTENSION |
if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ |
if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ |
|
|
const char *zSavedFilename = p->zDbFilename; |
const char *zSavedFilename = p->zDbFilename; |
char *zNewFilename = 0; |
char *zNewFilename = 0; |
p->db = 0; |
p->db = 0; |
if( nArg>=2 ){ |
if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]); |
p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]); |
p->zDbFilename = zNewFilename; |
} |
|
open_db(p, 1); |
open_db(p, 1); |
if( p->db!=0 ){ |
if( p->db!=0 ){ |
sqlite3_close(savedDb); |
sqlite3_close(savedDb); |
|
|
while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
if( nRow>=nAlloc ){ |
if( nRow>=nAlloc ){ |
char **azNew; |
char **azNew; |
int n = nAlloc*2 + 10; |
int n2 = nAlloc*2 + 10; |
azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n); |
azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); |
if( azNew==0 ){ |
if( azNew==0 ){ |
fprintf(stderr, "Error: out of memory\n"); |
fprintf(stderr, "Error: out of memory\n"); |
break; |
break; |
} |
} |
nAlloc = n; |
nAlloc = n2; |
azResult = azNew; |
azResult = azNew; |
} |
} |
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); |
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); |
|
|
{ "imposter", SQLITE_TESTCTRL_IMPOSTER }, |
{ "imposter", SQLITE_TESTCTRL_IMPOSTER }, |
}; |
}; |
int testctrl = -1; |
int testctrl = -1; |
int rc = 0; |
int rc2 = 0; |
int i, n; |
int i, n2; |
open_db(p, 0); |
open_db(p, 0); |
|
|
/* convert testctrl text option to value. allow any unique prefix |
/* convert testctrl text option to value. allow any unique prefix |
** of the option name, or a numerical value. */ |
** of the option name, or a numerical value. */ |
n = strlen30(azArg[1]); |
n2 = strlen30(azArg[1]); |
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){ |
for(i=0; i<ArraySize(aCtrl); i++){ |
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ |
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){ |
if( testctrl<0 ){ |
if( testctrl<0 ){ |
testctrl = aCtrl[i].ctrlCode; |
testctrl = aCtrl[i].ctrlCode; |
}else{ |
}else{ |
|
|
case SQLITE_TESTCTRL_RESERVE: |
case SQLITE_TESTCTRL_RESERVE: |
if( nArg==3 ){ |
if( nArg==3 ){ |
int opt = (int)strtol(azArg[2], 0, 0); |
int opt = (int)strtol(azArg[2], 0, 0); |
rc = sqlite3_test_control(testctrl, p->db, opt); |
rc2 = sqlite3_test_control(testctrl, p->db, opt); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); |
} else { |
} else { |
fprintf(stderr,"Error: testctrl %s takes a single int option\n", |
fprintf(stderr,"Error: testctrl %s takes a single int option\n", |
azArg[1]); |
azArg[1]); |
|
|
case SQLITE_TESTCTRL_PRNG_RESET: |
case SQLITE_TESTCTRL_PRNG_RESET: |
case SQLITE_TESTCTRL_BYTEORDER: |
case SQLITE_TESTCTRL_BYTEORDER: |
if( nArg==2 ){ |
if( nArg==2 ){ |
rc = sqlite3_test_control(testctrl); |
rc2 = sqlite3_test_control(testctrl); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); |
} else { |
} else { |
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]); |
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]); |
} |
} |
|
|
case SQLITE_TESTCTRL_PENDING_BYTE: |
case SQLITE_TESTCTRL_PENDING_BYTE: |
if( nArg==3 ){ |
if( nArg==3 ){ |
unsigned int opt = (unsigned int)integerValue(azArg[2]); |
unsigned int opt = (unsigned int)integerValue(azArg[2]); |
rc = sqlite3_test_control(testctrl, opt); |
rc2 = sqlite3_test_control(testctrl, opt); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); |
} else { |
} else { |
fprintf(stderr,"Error: testctrl %s takes a single unsigned" |
fprintf(stderr,"Error: testctrl %s takes a single unsigned" |
" int option\n", azArg[1]); |
" int option\n", azArg[1]); |
|
|
case SQLITE_TESTCTRL_NEVER_CORRUPT: |
case SQLITE_TESTCTRL_NEVER_CORRUPT: |
if( nArg==3 ){ |
if( nArg==3 ){ |
int opt = booleanValue(azArg[2]); |
int opt = booleanValue(azArg[2]); |
rc = sqlite3_test_control(testctrl, opt); |
rc2 = sqlite3_test_control(testctrl, opt); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); |
} else { |
} else { |
fprintf(stderr,"Error: testctrl %s takes a single int option\n", |
fprintf(stderr,"Error: testctrl %s takes a single int option\n", |
azArg[1]); |
azArg[1]); |
|
|
case SQLITE_TESTCTRL_ISKEYWORD: |
case SQLITE_TESTCTRL_ISKEYWORD: |
if( nArg==3 ){ |
if( nArg==3 ){ |
const char *opt = azArg[2]; |
const char *opt = azArg[2]; |
rc = sqlite3_test_control(testctrl, opt); |
rc2 = sqlite3_test_control(testctrl, opt); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); |
} else { |
} else { |
fprintf(stderr,"Error: testctrl %s takes a single char * option\n", |
fprintf(stderr,"Error: testctrl %s takes a single char * option\n", |
azArg[1]); |
azArg[1]); |
|
|
|
|
case SQLITE_TESTCTRL_IMPOSTER: |
case SQLITE_TESTCTRL_IMPOSTER: |
if( nArg==5 ){ |
if( nArg==5 ){ |
rc = sqlite3_test_control(testctrl, p->db, |
rc2 = sqlite3_test_control(testctrl, p->db, |
azArg[2], |
azArg[2], |
integerValue(azArg[3]), |
integerValue(azArg[3]), |
integerValue(azArg[4])); |
integerValue(azArg[4])); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2); |
}else{ |
}else{ |
fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); |
fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); |
} |
} |
|
|
&& sqlite3_complete(zSql) ){ |
&& sqlite3_complete(zSql) ){ |
p->cnt = 0; |
p->cnt = 0; |
open_db(p, 0); |
open_db(p, 0); |
|
if( p->backslashOn ) resolve_backslashes(zSql); |
BEGIN_TIMER; |
BEGIN_TIMER; |
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); |
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); |
END_TIMER; |
END_TIMER; |
|
|
data.statsOn = 1; |
data.statsOn = 1; |
}else if( strcmp(z,"-scanstats")==0 ){ |
}else if( strcmp(z,"-scanstats")==0 ){ |
data.scanstatsOn = 1; |
data.scanstatsOn = 1; |
|
}else if( strcmp(z,"-backslash")==0 ){ |
|
/* Undocumented command-line option: -backslash |
|
** Causes C-style backslash escapes to be evaluated in SQL statements |
|
** prior to sending the SQL into SQLite. Useful for injecting |
|
** crazy bytes in the middle of SQL statements for testing and debugging. |
|
*/ |
|
data.backslashOn = 1; |
}else if( strcmp(z,"-bail")==0 ){ |
}else if( strcmp(z,"-bail")==0 ){ |
bail_on_error = 1; |
bail_on_error = 1; |
}else if( strcmp(z,"-version")==0 ){ |
}else if( strcmp(z,"-version")==0 ){ |
|
|
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |
} |
} |
} |
} |
if( zHistory ) shell_read_history(zHistory); |
if( zHistory ){ shell_read_history(zHistory); } |
rc = process_input(&data, 0); |
rc = process_input(&data, 0); |
if( zHistory ){ |
if( zHistory ){ |
shell_stifle_history(100); |
shell_stifle_history(100); |