update bundled sqlite to 3.8.1

Change-Id: Id75bf901c9014419eddbe2d0e5a75ee274b17914
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Fatih Aşıcı <fatih.asici@gmail.com>
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
Mark Brand 2013-11-13 11:38:18 +01:00 committed by The Qt Project
parent 34ff885bff
commit 06d1c149c7
3 changed files with 9811 additions and 6436 deletions

View File

@ -53,7 +53,6 @@
# include <readline/history.h>
#endif
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
# define readline(p) local_getline(p,stdin,0)
# define add_history(X)
# define read_history(X)
# define write_history(X)
@ -65,13 +64,18 @@
#define isatty(h) _isatty(h)
#define access(f,m) _access((f),(m))
#undef popen
#define popen(a,b) _popen((a),(b))
#define popen _popen
#undef pclose
#define pclose(x) _pclose(x)
#define pclose _pclose
#else
/* Make sure isatty() has a prototype.
*/
extern int isatty(int);
/* popen and pclose are not C89 functions and so are sometimes omitted from
** the <stdio.h> header */
extern FILE *popen(const char*,const char*);
extern int pclose(FILE*);
#endif
#if defined(_WIN32_WCE)
@ -332,23 +336,13 @@ static void shellstaticFunc(
** to the text. NULL is returned at end of file, or if malloc()
** fails.
**
** The interface is like "readline" but no command-line editing
** is done.
** If zLine is not NULL then it is a malloced buffer returned from
** a previous call to this routine that may be reused.
*/
static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
char *zLine;
int nLine;
int n;
int inQuote = 0;
static char *local_getline(char *zLine, FILE *in){
int nLine = zLine==0 ? 0 : 100;
int n = 0;
if( zPrompt && *zPrompt ){
printf("%s",zPrompt);
fflush(stdout);
}
nLine = 100;
zLine = malloc( nLine );
if( zLine==0 ) return 0;
n = 0;
while( 1 ){
if( n+100>nLine ){
nLine = nLine*2 + 100;
@ -363,42 +357,48 @@ static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
zLine[n] = 0;
break;
}
while( zLine[n] ){
if( zLine[n]=='"' ) inQuote = !inQuote;
n++;
}
if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
while( zLine[n] ) n++;
if( n>0 && zLine[n-1]=='\n' ){
n--;
if( n>0 && zLine[n-1]=='\r' ) n--;
zLine[n] = 0;
break;
}
}
zLine = realloc( zLine, n+1 );
return zLine;
}
/*
** Retrieve a single line of input text.
**
** zPrior is a string of prior text retrieved. If not the empty
** string, then issue a continuation prompt.
** If in==0 then read from standard input and prompt before each line.
** If isContinuation is true, then a continuation prompt is appropriate.
** If isContinuation is zero, then the main prompt should be used.
**
** If zPrior is not NULL then it is a buffer from a prior call to this
** routine that can be reused.
**
** The result is stored in space obtained from malloc() and must either
** be freed by the caller or else passed back into this routine via the
** zPrior argument for reuse.
*/
static char *one_input_line(const char *zPrior, FILE *in){
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
char *zPrompt;
char *zResult;
if( in!=0 ){
return local_getline(0, in, 0);
}
if( zPrior && zPrior[0] ){
zPrompt = continuePrompt;
zResult = local_getline(zPrior, in);
}else{
zPrompt = mainPrompt;
}
zResult = readline(zPrompt);
zPrompt = isContinuation ? continuePrompt : mainPrompt;
#if defined(HAVE_READLINE) && HAVE_READLINE==1
if( zResult && *zResult ) add_history(zResult);
free(zPrior);
zResult = readline(zPrompt);
if( zResult && *zResult ) add_history(zResult);
#else
printf("%s", zPrompt);
fflush(stdout);
zResult = local_getline(zPrior, stdin);
#endif
}
return zResult;
}
@ -554,7 +554,7 @@ static void output_c_string(FILE *out, const char *z){
}else if( c=='\r' ){
fputc('\\', out);
fputc('r', out);
}else if( !isprint(c) ){
}else if( !isprint(c&0xff) ){
fprintf(out, "\\%03o", c&0xff);
}else{
fputc(c, out);
@ -974,7 +974,7 @@ static int run_table_dump_query(
rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
if( rc!=SQLITE_OK || !pSelect ){
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
p->nErr++;
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
return rc;
}
rc = sqlite3_step(pSelect);
@ -1001,7 +1001,7 @@ static int run_table_dump_query(
rc = sqlite3_finalize(pSelect);
if( rc!=SQLITE_OK ){
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
p->nErr++;
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
}
return rc;
}
@ -1109,6 +1109,8 @@ static int display_stats(
fprintf(pArg->out, "Sort Operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
}
return 0;
@ -1192,7 +1194,7 @@ static int shell_exec(
char **azCols = (char **)pData; /* Names of result columns */
char **azVals = &azCols[nCol]; /* Results */
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
int i;
int i, x;
assert(sizeof(int) <= sizeof(char *));
/* save off ptrs to column names */
for(i=0; i<nCol; i++){
@ -1201,8 +1203,12 @@ static int shell_exec(
do{
/* extract the data and data types */
for(i=0; i<nCol; i++){
azVals[i] = (char *)sqlite3_column_text(pStmt, i);
aiTypes[i] = sqlite3_column_type(pStmt, i);
aiTypes[i] = x = sqlite3_column_type(pStmt, i);
if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
azVals[i] = "";
}else{
azVals[i] = (char*)sqlite3_column_text(pStmt, i);
}
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
rc = SQLITE_NOMEM;
break; /* from for */
@ -1278,7 +1284,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
if( strcmp(zTable, "sqlite_sequence")==0 ){
zPrepStmt = "DELETE FROM sqlite_sequence;\n";
}else if( strcmp(zTable, "sqlite_stat1")==0 ){
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
fprintf(p->out, "ANALYZE sqlite_master;\n");
}else if( strncmp(zTable, "sqlite_", 7)==0 ){
return 0;
@ -1490,6 +1496,7 @@ static void open_db(struct callback_data *p){
** \t -> tab
** \n -> newline
** \r -> carriage return
** \" -> "
** \NNN -> ascii character NNN in octal
** \\ -> backslash
*/
@ -1505,6 +1512,8 @@ static void resolve_backslashes(char *z){
c = '\t';
}else if( c=='r' ){
c = '\r';
}else if( c=='\\' ){
c = '\\';
}else if( c>='0' && c<='7' ){
c -= '0';
if( z[i+1]>='0' && z[i+1]<='7' ){
@ -1523,21 +1532,14 @@ static void resolve_backslashes(char *z){
}
/*
** Interpret zArg as a boolean value. Return either 0 or 1.
** Return the value of a hexadecimal digit. Return -1 if the input
** is not a hex digit.
*/
static int booleanValue(char *zArg){
int i;
for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
if( i>0 && zArg[i]==0 ) return atoi(zArg);
if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
return 1;
}
if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
return 0;
}
fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
zArg);
return 0;
static int hexDigitValue(char c){
if( c>='0' && c<='9' ) return c - '0';
if( c>='a' && c<='f' ) return c - 'a' + 10;
if( c>='A' && c<='F' ) return c - 'A' + 10;
return -1;
}
/*
@ -1564,11 +1566,20 @@ static sqlite3_int64 integerValue(const char *zArg){
}else if( zArg[0]=='+' ){
zArg++;
}
while( isdigit(zArg[0]) ){
v = v*10 + zArg[0] - '0';
zArg++;
if( zArg[0]=='0' && zArg[1]=='x' ){
int x;
zArg += 2;
while( (x = hexDigitValue(zArg[0]))>=0 ){
v = (v<<4) + x;
zArg++;
}
}else{
while( IsDigit(zArg[0]) ){
v = v*10 + zArg[0] - '0';
zArg++;
}
}
for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
for(i=0; i<ArraySize(aMult); i++){
if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
v *= aMult[i].iMult;
break;
@ -1577,6 +1588,29 @@ static sqlite3_int64 integerValue(const char *zArg){
return isNeg? -v : v;
}
/*
** Interpret zArg as either an integer or a boolean value. Return 1 or 0
** for TRUE and FALSE. Return the integer value if appropriate.
*/
static int booleanValue(char *zArg){
int i;
if( zArg[0]=='0' && zArg[1]=='x' ){
for(i=2; hexDigitValue(zArg[i])>=0; i++){}
}else{
for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
}
if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
return 1;
}
if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
return 0;
}
fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
zArg);
return 0;
}
/*
** Close an output file, assuming it is not stderr or stdout
*/
@ -1623,6 +1657,105 @@ static void test_breakpoint(void){
nCall++;
}
/*
** An object used to read a CSV file
*/
typedef struct CSVReader CSVReader;
struct CSVReader {
const char *zFile; /* Name of the input file */
FILE *in; /* Read the CSV text from this input stream */
char *z; /* Accumulated text for a field */
int n; /* Number of bytes in z */
int nAlloc; /* Space allocated for z[] */
int nLine; /* Current line number */
int cTerm; /* Character that terminated the most recent field */
int cSeparator; /* The separator character. (Usually ",") */
};
/* Append a single byte to z[] */
static void csv_append_char(CSVReader *p, int c){
if( p->n+1>=p->nAlloc ){
p->nAlloc += p->nAlloc + 100;
p->z = sqlite3_realloc(p->z, p->nAlloc);
if( p->z==0 ){
fprintf(stderr, "out of memory\n");
exit(1);
}
}
p->z[p->n++] = (char)c;
}
/* Read a single field of CSV text. Compatible with rfc4180 and extended
** with the option of having a separator other than ",".
**
** + Input comes from p->in.
** + Store results in p->z of length p->n. Space to hold p->z comes
** from sqlite3_malloc().
** + Use p->cSep as the separator. The default is ",".
** + Keep track of the line number in p->nLine.
** + Store the character that terminates the field in p->cTerm. Store
** EOF on end-of-file.
** + Report syntax errors on stderr
*/
static char *csv_read_one_field(CSVReader *p){
int c, pc;
int cSep = p->cSeparator;
p->n = 0;
c = fgetc(p->in);
if( c==EOF || seenInterrupt ){
p->cTerm = EOF;
return 0;
}
if( c=='"' ){
int startLine = p->nLine;
int cQuote = c;
pc = 0;
while( 1 ){
c = fgetc(p->in);
if( c=='\n' ) p->nLine++;
if( c==cQuote ){
if( pc==cQuote ){
pc = 0;
continue;
}
}
if( (c==cSep && pc==cQuote)
|| (c=='\n' && pc==cQuote)
|| (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote)
|| (c==EOF && pc==cQuote)
){
do{ p->n--; }while( p->z[p->n]!=cQuote );
p->cTerm = c;
break;
}
if( pc==cQuote && c!='\r' ){
fprintf(stderr, "%s:%d: unescaped %c character\n",
p->zFile, p->nLine, cQuote);
}
if( c==EOF ){
fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
p->zFile, startLine, cQuote);
p->cTerm = EOF;
break;
}
csv_append_char(p, c);
pc = c;
}
}else{
while( c!=EOF && c!=cSep && c!='\n' ){
csv_append_char(p, c);
c = fgetc(p->in);
}
if( c=='\n' ){
p->nLine++;
if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
}
p->cTerm = c;
}
if( p->z ) p->z[p->n] = 0;
return p->z;
}
/*
** If an input line begins with "." then invoke this routine to
** process that line.
@ -1644,7 +1777,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( zLine[i]=='\'' || zLine[i]=='"' ){
int delim = zLine[i++];
azArg[nArg++] = &zLine[i];
while( zLine[i] && zLine[i]!=delim ){ i++; }
while( zLine[i] && zLine[i]!=delim ){
if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
i++;
}
if( zLine[i]==delim ){
zLine[i++] = 0;
}
@ -1665,7 +1801,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
const char *zDestFile = 0;
const char *zDb = 0;
const char *zKey = 0;
sqlite3 *pDest;
sqlite3_backup *pBackup;
int j;
@ -1673,9 +1808,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
const char *z = azArg[j];
if( z[0]=='-' ){
while( z[0]=='-' ) z++;
if( strcmp(z,"key")==0 && j<nArg-1 ){
zKey = azArg[++j];
}else
/* No options to process at this time */
{
fprintf(stderr, "unknown option: %s\n", azArg[j]);
return 1;
@ -1701,11 +1834,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite3_close(pDest);
return 1;
}
#ifdef SQLITE_HAS_CODEC
sqlite3_key(pDest, zKey, (int)strlen(zKey));
#else
(void)zKey;
#endif
open_db(p);
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
if( pBackup==0 ){
@ -1808,7 +1936,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
if( nArg>1 && (rc = atoi(azArg[1]))!=0 ) exit(rc);
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
rc = 2;
}else
@ -1861,48 +1989,98 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
char *zTable = azArg[2]; /* Insert data into this table */
char *zFile = azArg[1]; /* The file from which to extract data */
char *zFile = azArg[1]; /* Name of file to extra content from */
sqlite3_stmt *pStmt = NULL; /* A statement */
int nCol; /* Number of columns in the table */
int nByte; /* Number of bytes in an SQL string */
int i, j; /* Loop counters */
int needCommit; /* True to COMMIT or ROLLBACK at end */
int nSep; /* Number of bytes in p->separator[] */
char *zSql; /* An SQL statement */
char *zLine; /* A single line of input from the file */
char **azCol; /* zLine[] broken up into columns */
char *zCommit; /* How to commit changes */
FILE *in; /* The input file */
int lineno = 0; /* Line number of input file */
CSVReader sCsv; /* Reader context */
int (*xCloser)(FILE*); /* Procedure to close th3 connection */
seenInterrupt = 0;
memset(&sCsv, 0, sizeof(sCsv));
open_db(p);
nSep = strlen30(p->separator);
if( nSep==0 ){
fprintf(stderr, "Error: non-null separator required for import\n");
return 1;
}
if( nSep>1 ){
fprintf(stderr, "Error: multi-character separators not allowed"
" for import\n");
return 1;
}
sCsv.zFile = zFile;
sCsv.nLine = 1;
if( sCsv.zFile[0]=='|' ){
sCsv.in = popen(sCsv.zFile+1, "r");
sCsv.zFile = "<pipe>";
xCloser = pclose;
}else{
sCsv.in = fopen(sCsv.zFile, "rb");
xCloser = fclose;
}
if( sCsv.in==0 ){
fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
return 1;
}
sCsv.cSeparator = p->separator[0];
zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
if( zSql==0 ){
fprintf(stderr, "Error: out of memory\n");
xCloser(sCsv.in);
return 1;
}
nByte = strlen30(zSql);
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '(';
while( csv_read_one_field(&sCsv) ){
zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
cSep = ',';
if( sCsv.cTerm!=sCsv.cSeparator ) break;
}
if( cSep=='(' ){
sqlite3_free(zCreate);
sqlite3_free(sCsv.z);
xCloser(sCsv.in);
fprintf(stderr,"%s: empty file\n", sCsv.zFile);
return 1;
}
zCreate = sqlite3_mprintf("%z\n)", zCreate);
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
sqlite3_free(zCreate);
if( rc ){
fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
sqlite3_errmsg(db));
sqlite3_free(sCsv.z);
xCloser(sCsv.in);
return 1;
}
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
}
sqlite3_free(zSql);
if( rc ){
if (pStmt) sqlite3_finalize(pStmt);
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
xCloser(sCsv.in);
return 1;
}
nCol = sqlite3_column_count(pStmt);
sqlite3_finalize(pStmt);
pStmt = 0;
if( nCol==0 ) return 0; /* no columns, no error */
zSql = malloc( nByte + 20 + nCol*2 );
zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
if( zSql==0 ){
fprintf(stderr, "Error: out of memory\n");
xCloser(sCsv.in);
return 1;
}
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
j = strlen30(zSql);
for(i=1; i<nCol; i++){
zSql[j++] = ',';
@ -1911,79 +2089,52 @@ static int do_meta_command(char *zLine, struct callback_data *p){
zSql[j++] = ')';
zSql[j] = 0;
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
free(zSql);
sqlite3_free(zSql);
if( rc ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
if (pStmt) sqlite3_finalize(pStmt);
xCloser(sCsv.in);
return 1;
}
in = fopen(zFile, "rb");
if( in==0 ){
fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
sqlite3_finalize(pStmt);
return 1;
}
azCol = malloc( sizeof(azCol[0])*(nCol+1) );
if( azCol==0 ){
fprintf(stderr, "Error: out of memory\n");
fclose(in);
sqlite3_finalize(pStmt);
return 1;
}
sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
zCommit = "COMMIT";
while( (zLine = local_getline(0, in, 1))!=0 ){
char *z, c;
int inQuote = 0;
lineno++;
azCol[0] = zLine;
for(i=0, z=zLine; (c = *z)!=0; z++){
if( c=='"' ) inQuote = !inQuote;
if( c=='\n' ) lineno++;
if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
*z = 0;
i++;
if( i<nCol ){
azCol[i] = &z[nSep];
z += nSep-1;
}
}
} /* end for */
*z = 0;
if( i+1!=nCol ){
fprintf(stderr,
"Error: %s line %d: expected %d columns of data but found %d\n",
zFile, lineno, nCol, i+1);
zCommit = "ROLLBACK";
free(zLine);
rc = 1;
break; /* from while */
}
needCommit = sqlite3_get_autocommit(db);
if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
do{
int startLine = sCsv.nLine;
for(i=0; i<nCol; i++){
if( azCol[i][0]=='"' ){
int k;
for(z=azCol[i], j=1, k=0; z[j]; j++){
if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
z[k++] = z[j];
}
z[k] = 0;
char *z = csv_read_one_field(&sCsv);
if( z==0 && i==0 ) break;
sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
fprintf(stderr, "%s:%d: expected %d columns but found %d - "
"filling the rest with NULL\n",
sCsv.zFile, startLine, nCol, i+1);
i++;
while( i<nCol ){ sqlite3_bind_null(pStmt, i); i++; }
}
sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
}
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
free(zLine);
if( rc!=SQLITE_OK ){
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
zCommit = "ROLLBACK";
rc = 1;
break; /* from while */
if( sCsv.cTerm==sCsv.cSeparator ){
do{
csv_read_one_field(&sCsv);
i++;
}while( sCsv.cTerm==sCsv.cSeparator );
fprintf(stderr, "%s:%d: expected %d columns but found %d - "
"extras ignored\n",
sCsv.zFile, startLine, nCol, i);
}
} /* end while */
free(azCol);
fclose(in);
if( i>=nCol ){
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ){
fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
sqlite3_errmsg(db));
}
}
}while( sCsv.cTerm!=EOF );
xCloser(sCsv.in);
sqlite3_free(sCsv.z);
sqlite3_finalize(pStmt);
sqlite3_exec(p->db, zCommit, 0, 0, 0);
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
}else
if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
@ -2305,6 +2456,29 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
}else
#ifdef SQLITE_DEBUG
/* Undocumented commands for internal testing. Subject to change
** without notice. */
if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
int i, v;
for(i=1; i<nArg; i++){
v = booleanValue(azArg[i]);
fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
}
}
if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
int i; sqlite3_int64 v;
for(i=1; i<nArg; i++){
char zBuf[200];
v = integerValue(azArg[i]);
sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);
fprintf(p->out, "%s", zBuf);
}
}
}else
#endif
if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
sqlite3_snprintf(sizeof(p->separator), p->separator,
"%.*s", (int)sizeof(p->separator)-1, azArg[1]);
@ -2458,7 +2632,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
}
}
if( testctrl<0 ) testctrl = atoi(azArg[1]);
if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
}else{
@ -2492,7 +2666,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
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);
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
} else {
@ -2505,7 +2679,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
case SQLITE_TESTCTRL_ASSERT:
case SQLITE_TESTCTRL_ALWAYS:
if( nArg==3 ){
int opt = atoi(azArg[2]);
int opt = booleanValue(azArg[2]);
rc = sqlite3_test_control(testctrl, opt);
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
} else {
@ -2542,7 +2716,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
open_db(p);
sqlite3_busy_timeout(p->db, atoi(azArg[1]));
sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));
}else
if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
@ -2592,7 +2766,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
int j;
assert( nArg<=ArraySize(azArg) );
for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
p->colWidth[j-1] = atoi(azArg[j]);
p->colWidth[j-1] = (int)integerValue(azArg[j]);
}
}else
@ -2609,7 +2783,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
** Return TRUE if a semicolon occurs anywhere in the first N characters
** of string z[].
*/
static int _contains_semicolon(const char *z, int N){
static int line_contains_semicolon(const char *z, int N){
int i;
for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
return 0;
@ -2644,7 +2818,7 @@ static int _all_whitespace(const char *z){
** than a semi-colon. The SQL Server style "go" command is understood
** as is the Oracle "/".
*/
static int _is_command_terminator(const char *zLine){
static int line_is_command_terminator(const char *zLine){
while( IsSpace(zLine[0]) ){ zLine++; };
if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
return 1; /* Oracle */
@ -2660,7 +2834,7 @@ static int _is_command_terminator(const char *zLine){
** Return true if zSql is a complete SQL statement. Return false if it
** ends in the middle of a string literal or C-style comment.
*/
static int _is_complete(char *zSql, int nSql){
static int line_is_complete(char *zSql, int nSql){
int rc;
if( zSql==0 ) return 1;
zSql[nSql] = ';';
@ -2680,20 +2854,21 @@ static int _is_complete(char *zSql, int nSql){
** Return the number of errors.
*/
static int process_input(struct callback_data *p, FILE *in){
char *zLine = 0;
char *zSql = 0;
int nSql = 0;
int nSqlPrior = 0;
char *zErrMsg;
int rc;
int errCnt = 0;
int lineno = 0;
int startline = 0;
char *zLine = 0; /* A single input line */
char *zSql = 0; /* Accumulated SQL text */
int nLine; /* Length of current line */
int nSql = 0; /* Bytes of zSql[] used */
int nAlloc = 0; /* Allocated zSql[] space */
int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
char *zErrMsg; /* Error message returned */
int rc; /* Error code */
int errCnt = 0; /* Number of errors seen */
int lineno = 0; /* Current line number */
int startline = 0; /* Line number for start of current input */
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
fflush(p->out);
free(zLine);
zLine = one_input_line(zSql, in);
zLine = one_input_line(in, zLine, nSql>0);
if( zLine==0 ){
/* End of input */
if( stdin_is_interactive ) printf("\n");
@ -2704,7 +2879,7 @@ static int process_input(struct callback_data *p, FILE *in){
seenInterrupt = 0;
}
lineno++;
if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
if( nSql==0 && _all_whitespace(zLine) ) continue;
if( zLine && zLine[0]=='.' && nSql==0 ){
if( p->echoOn ) printf("%s\n", zLine);
rc = do_meta_command(zLine, p);
@ -2715,35 +2890,32 @@ static int process_input(struct callback_data *p, FILE *in){
}
continue;
}
if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
memcpy(zLine,";",2);
}
nSqlPrior = nSql;
if( zSql==0 ){
int i;
for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
if( zLine[i]!=0 ){
nSql = strlen30(zLine);
zSql = malloc( nSql+3 );
if( zSql==0 ){
fprintf(stderr, "Error: out of memory\n");
exit(1);
}
memcpy(zSql, zLine, nSql+1);
startline = lineno;
}
}else{
int len = strlen30(zLine);
zSql = realloc( zSql, nSql + len + 4 );
nLine = strlen30(zLine);
if( nSql+nLine+2>=nAlloc ){
nAlloc = nSql+nLine+100;
zSql = realloc(zSql, nAlloc);
if( zSql==0 ){
fprintf(stderr,"Error: out of memory\n");
fprintf(stderr, "Error: out of memory\n");
exit(1);
}
zSql[nSql++] = '\n';
memcpy(&zSql[nSql], zLine, len+1);
nSql += len;
}
if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
nSqlPrior = nSql;
if( nSql==0 ){
int i;
for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
assert( nAlloc>0 && zSql!=0 );
memcpy(zSql, zLine+i, nLine+1-i);
startline = lineno;
nSql = nLine-i;
}else{
zSql[nSql++] = '\n';
memcpy(zSql+nSql, zLine, nLine+1);
nSql += nLine;
}
if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
&& sqlite3_complete(zSql) ){
p->cnt = 0;
open_db(p);
@ -2767,16 +2939,12 @@ static int process_input(struct callback_data *p, FILE *in){
}
errCnt++;
}
free(zSql);
zSql = 0;
nSql = 0;
}else if( zSql && _all_whitespace(zSql) ){
free(zSql);
zSql = 0;
}else if( nSql && _all_whitespace(zSql) ){
nSql = 0;
}
}
if( zSql ){
if( nSql ){
if( !_all_whitespace(zSql) ){
fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
}
@ -3024,7 +3192,6 @@ int main(int argc, char **argv){
stdin_is_interactive = 0;
}else if( strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
int j, c;
const char *zSize;
sqlite3_int64 szHeap;

File diff suppressed because it is too large Load Diff

View File

@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.7.17"
#define SQLITE_VERSION_NUMBER 3007017
#define SQLITE_SOURCE_ID "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
#define SQLITE_VERSION "3.8.1"
#define SQLITE_VERSION_NUMBER 3008001
#define SQLITE_SOURCE_ID "2013-10-17 12:57:35 c78be6d786c19073b3a6730dfe3fb1be54f5657a"
/*
** CAPI3REF: Run-Time Library Version Numbers
@ -478,11 +478,15 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@ -499,6 +503,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
/*
** CAPI3REF: Flags For File Open Operations
@ -1612,27 +1617,27 @@ struct sqlite3_mem_methods {
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd> This option takes a single argument of type int. If non-zero, then
** <dd>^(This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling
** is globally disabled. If URI handling is globally enabled, all filenames
** is globally disabled.)^ ^If URI handling is globally enabled, all filenames
** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
** connection is opened. If it is globally disabled, filenames are
** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. By default, URI handling is globally
** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.
** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd> This option takes a single integer argument which is interpreted as
** <dd>^This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer. The default setting is determined
** full table scans in the query optimizer. ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** malfunction when the optimization is enabled. Providing the ability to
** when the optimization is enabled. Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
@ -1661,16 +1666,16 @@ struct sqlite3_mem_methods {
**
** [[SQLITE_CONFIG_MMAP_SIZE]]
** <dt>SQLITE_CONFIG_MMAP_SIZE
** <dd>SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
** The default setting can be overridden by each database connection using
** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
** [SQLITE_FCNTL_MMAP_SIZE] file control. The maximum allowed mmap size
** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size
** cannot be changed at run-time. Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.
** If either argument to this option is negative, then that argument is
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
** </dl>
*/
@ -2557,9 +2562,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the
** callback function X. ^The parameter N is the number of
** callback function X. ^The parameter N is the approximate number of
** [virtual machine instructions] that are evaluated between successive
** invocations of the callback X.
** invocations of the callback X. ^If N is less than one then the progress
** handler is disabled.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
@ -4179,41 +4185,49 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
**
** The following two functions may be used by scalar SQL functions to
** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. This may
** be used, for example, to add a regular-expression matching scalar
** function. The compiled version of the regular expression is stored as
** metadata associated with the SQL value passed as the regular expression
** pattern. The compiled regular expression can be reused on multiple
** invocations of the same function so that the original pattern string
** does not need to be recompiled on each invocation.
** some circumstances the associated metadata may be preserved. An example
** of where this might be useful is in a regular-expression matching
** function. The compiled version of the regular expression can be stored as
** metadata associated with the pattern string.
** Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If no metadata has been ever
** been set for the Nth argument of the function, or if the corresponding
** function parameter has changed since the meta-data was set,
** then sqlite3_get_auxdata() returns a NULL pointer.
** value to the application-defined function. ^If there is no metadata
** associated with the function argument, this sqlite3_get_auxdata() interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata() interface saves the metadata
** pointed to by its 3rd parameter as the metadata for the N-th
** argument of the application-defined function. Subsequent
** calls to sqlite3_get_auxdata() might return this data, if it has
** not been destroyed.
** ^If it is not NULL, SQLite will invoke the destructor
** function given by the 4th parameter to sqlite3_set_auxdata() on
** the metadata when the corresponding function parameter changes
** or when the SQL statement completes, whichever comes first.
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function. ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
** NULL if the metadata has been discarded.
** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
** SQLite will invoke the destructor function X with parameter P exactly
** once, when the metadata is discarded.
** SQLite is free to discard the metadata at any time, including: <ul>
** <li> when the corresponding function parameter changes, or
** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
** SQL statement, or
** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
** <li> during the original sqlite3_set_auxdata() call when a memory
** allocation error occurs. </ul>)^
**
** SQLite is free to call the destructor and drop metadata on any
** parameter of any function at any time. ^The only guarantee is that
** the destructor will be called before the metadata is dropped.
** Note the last bullet in particular. The destructor X in
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the
** function implementation should not make any use of P after
** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
** expressions that are constant at compile time. This includes literal
** values and [parameters].)^
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
** These routines must be called from the same thread in which
** the SQL function is running.
@ -4518,6 +4532,11 @@ SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
SQLITE_API int sqlite3_key_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The key */
);
/*
** Change the key on an open database. If the current database is not
@ -4531,6 +4550,11 @@ SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
SQLITE_API int sqlite3_rekey_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The new key */
);
/*
** Specify the activation key for a SEE database. Unless
@ -5116,10 +5140,23 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** on the list of automatic extensions is a harmless no-op. ^No entry point
** will be called more than once for each database connection that is opened.
**
** See also: [sqlite3_reset_auto_extension()].
** See also: [sqlite3_reset_auto_extension()]
** and [sqlite3_cancel_auto_extension()]
*/
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
/*
** CAPI3REF: Cancel Automatic Extension Loading
**
** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
** initialization routine X that was registered using a prior call to
** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
** routine returns 1 if initialization routine X was successfully
** unregistered and it returns 0 if X was not on the list of initialization
** routines.
*/
SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
/*
** CAPI3REF: Reset Automatic Extension Loading
**
@ -6232,6 +6269,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
** resolved.)^ ^The highwater mark is always 0.
** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
@ -6244,7 +6287,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_HIT 7
#define SQLITE_DBSTATUS_CACHE_MISS 8
#define SQLITE_DBSTATUS_CACHE_WRITE 9
#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/*
@ -6298,11 +6342,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** A non-zero value in this counter may indicate an opportunity to
** improvement performance by adding permanent indices that do not
** need to be reinitialized each time the statement is run.</dd>
**
** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
** <dd>^This is the number of virtual machine operations executed
** by the prepared statement if that number is less than or equal
** to 2147483647. The number of virtual machine operations can be
** used as a proxy for the total work done by the prepared statement.
** If the number of virtual machine operations exceeds 2147483647
** then the value returned by this statement status code is undefined.
** </dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
#define SQLITE_STMTSTATUS_VM_STEP 4
/*
** CAPI3REF: Custom Page Cache Object
@ -7181,7 +7235,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif
#endif
#endif /* _SQLITE3_H_ */
/*
** 2010 August 30