version 1.5, 2013/03/18 10:50:25 |
version 1.6, 2013/06/09 14:51:57 |
|
|
#define IsDigit(X) isdigit((unsigned char)X) |
#define IsDigit(X) isdigit((unsigned char)X) |
#define ToLower(X) (char)tolower((unsigned char)X) |
#define ToLower(X) (char)tolower((unsigned char)X) |
|
|
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) |
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \ |
|
&& !defined(__minux) |
#include <sys/time.h> |
#include <sys/time.h> |
#include <sys/resource.h> |
#include <sys/resource.h> |
|
|
|
|
** Interpret zArg as a boolean value. Return either 0 or 1. |
** Interpret zArg as a boolean value. Return either 0 or 1. |
*/ |
*/ |
static int booleanValue(char *zArg){ |
static int booleanValue(char *zArg){ |
int val = atoi(zArg); |
int i; |
int j; |
for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} |
for(j=0; zArg[j]; j++){ |
if( i>0 && zArg[i]==0 ) return atoi(zArg); |
zArg[j] = ToLower(zArg[j]); |
if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ |
|
return 1; |
} |
} |
if( strcmp(zArg,"on")==0 ){ |
if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ |
val = 1; |
return 0; |
}else if( strcmp(zArg,"yes")==0 ){ |
|
val = 1; |
|
} |
} |
return val; |
fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", |
|
zArg); |
|
return 0; |
} |
} |
|
|
/* |
/* |
|
** Interpret zArg as an integer value, possibly with suffixes. |
|
*/ |
|
static sqlite3_int64 integerValue(const char *zArg){ |
|
sqlite3_int64 v = 0; |
|
static const struct { char *zSuffix; int iMult; } aMult[] = { |
|
{ "KiB", 1024 }, |
|
{ "MiB", 1024*1024 }, |
|
{ "GiB", 1024*1024*1024 }, |
|
{ "KB", 1000 }, |
|
{ "MB", 1000000 }, |
|
{ "GB", 1000000000 }, |
|
{ "K", 1000 }, |
|
{ "M", 1000000 }, |
|
{ "G", 1000000000 }, |
|
}; |
|
int i; |
|
int isNeg = 0; |
|
if( zArg[0]=='-' ){ |
|
isNeg = 1; |
|
zArg++; |
|
}else if( zArg[0]=='+' ){ |
|
zArg++; |
|
} |
|
while( isdigit(zArg[0]) ){ |
|
v = v*10 + zArg[0] - '0'; |
|
zArg++; |
|
} |
|
for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){ |
|
if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ |
|
v *= aMult[i].iMult; |
|
break; |
|
} |
|
} |
|
return isNeg? -v : v; |
|
} |
|
|
|
/* |
** Close an output file, assuming it is not stderr or stdout |
** Close an output file, assuming it is not stderr or stdout |
*/ |
*/ |
static void output_file_close(FILE *f){ |
static void output_file_close(FILE *f){ |
|
|
if( nArg==0 ) return 0; /* no tokens, no error */ |
if( nArg==0 ) return 0; /* no tokens, no error */ |
n = strlen30(azArg[0]); |
n = strlen30(azArg[0]); |
c = azArg[0][0]; |
c = azArg[0][0]; |
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){ |
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){ |
const char *zDestFile; |
const char *zDestFile = 0; |
const char *zDb; |
const char *zDb = 0; |
|
const char *zKey = 0; |
sqlite3 *pDest; |
sqlite3 *pDest; |
sqlite3_backup *pBackup; |
sqlite3_backup *pBackup; |
if( nArg==2 ){ |
int j; |
zDestFile = azArg[1]; |
for(j=1; j<nArg; j++){ |
zDb = "main"; |
const char *z = azArg[j]; |
}else{ |
if( z[0]=='-' ){ |
zDestFile = azArg[2]; |
while( z[0]=='-' ) z++; |
zDb = azArg[1]; |
if( strcmp(z,"key")==0 && j<nArg-1 ){ |
|
zKey = azArg[++j]; |
|
}else |
|
{ |
|
fprintf(stderr, "unknown option: %s\n", azArg[j]); |
|
return 1; |
|
} |
|
}else if( zDestFile==0 ){ |
|
zDestFile = azArg[j]; |
|
}else if( zDb==0 ){ |
|
zDb = zDestFile; |
|
zDestFile = azArg[j]; |
|
}else{ |
|
fprintf(stderr, "too many arguments to .backup\n"); |
|
return 1; |
|
} |
} |
} |
|
if( zDestFile==0 ){ |
|
fprintf(stderr, "missing FILENAME argument on .backup\n"); |
|
return 1; |
|
} |
|
if( zDb==0 ) zDb = "main"; |
rc = sqlite3_open(zDestFile, &pDest); |
rc = sqlite3_open(zDestFile, &pDest); |
if( rc!=SQLITE_OK ){ |
if( rc!=SQLITE_OK ){ |
fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile); |
fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile); |
sqlite3_close(pDest); |
sqlite3_close(pDest); |
return 1; |
return 1; |
} |
} |
|
#ifdef SQLITE_HAS_CODEC |
|
sqlite3_key(pDest, zKey, (int)strlen(zKey)); |
|
#else |
|
(void)zKey; |
|
#endif |
open_db(p); |
open_db(p); |
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); |
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); |
if( pBackup==0 ){ |
if( pBackup==0 ){ |
|
|
p->echoOn = booleanValue(azArg[1]); |
p->echoOn = booleanValue(azArg[1]); |
}else |
}else |
|
|
if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){ |
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ |
|
if( nArg>1 && (rc = atoi(azArg[1]))!=0 ) exit(rc); |
rc = 2; |
rc = 2; |
}else |
}else |
|
|
|
|
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " |
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " |
"WHERE lower(tbl_name) LIKE shellstatic()" |
"WHERE lower(tbl_name) LIKE shellstatic()" |
" AND type!='meta' AND sql NOTNULL " |
" AND type!='meta' AND sql NOTNULL " |
"ORDER BY substr(type,2,1), " |
"ORDER BY rowid", |
" CASE type WHEN 'view' THEN rowid ELSE name END", |
|
callback, &data, &zErrMsg); |
callback, &data, &zErrMsg); |
zShellStatic = 0; |
zShellStatic = 0; |
} |
} |
|
|
" FROM sqlite_master UNION ALL" |
" FROM sqlite_master UNION ALL" |
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " |
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " |
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" |
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" |
"ORDER BY substr(type,2,1)," |
"ORDER BY rowid", |
" CASE type WHEN 'view' THEN rowid ELSE name END", |
|
callback, &data, &zErrMsg |
callback, &data, &zErrMsg |
); |
); |
} |
} |
|
|
for(i=0; i<nPrintRow; i++){ |
for(i=0; i<nPrintRow; i++){ |
for(j=i; j<nRow; j+=nPrintRow){ |
for(j=i; j<nRow; j+=nPrintRow){ |
char *zSp = j<nPrintRow ? "" : " "; |
char *zSp = j<nPrintRow ? "" : " "; |
printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : ""); |
fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : ""); |
} |
} |
printf("\n"); |
fprintf(p->out, "\n"); |
} |
} |
} |
} |
for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]); |
for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]); |
|
|
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); |
rc = sqlite3_test_control(testctrl, p->db, opt); |
printf("%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
} 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: |
if( nArg==2 ){ |
if( nArg==2 ){ |
rc = sqlite3_test_control(testctrl); |
rc = sqlite3_test_control(testctrl); |
printf("%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
} else { |
} else { |
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]); |
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]); |
} |
} |
|
|
/* sqlite3_test_control(int, uint) */ |
/* sqlite3_test_control(int, uint) */ |
case SQLITE_TESTCTRL_PENDING_BYTE: |
case SQLITE_TESTCTRL_PENDING_BYTE: |
if( nArg==3 ){ |
if( nArg==3 ){ |
unsigned int opt = (unsigned int)atoi(azArg[2]); |
unsigned int opt = (unsigned int)integerValue(azArg[2]); |
rc = sqlite3_test_control(testctrl, opt); |
rc = sqlite3_test_control(testctrl, opt); |
printf("%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
} 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]); |
|
|
if( nArg==3 ){ |
if( nArg==3 ){ |
int opt = atoi(azArg[2]); |
int opt = atoi(azArg[2]); |
rc = sqlite3_test_control(testctrl, opt); |
rc = sqlite3_test_control(testctrl, opt); |
printf("%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
} 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]); |
|
|
if( nArg==3 ){ |
if( nArg==3 ){ |
const char *opt = azArg[2]; |
const char *opt = azArg[2]; |
rc = sqlite3_test_control(testctrl, opt); |
rc = sqlite3_test_control(testctrl, opt); |
printf("%d (0x%08x)\n", rc, rc); |
fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
} 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]); |
|
|
}else |
}else |
|
|
if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ |
if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ |
printf("SQLite %s %s\n" /*extra-version-info*/, |
fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, |
sqlite3_libversion(), sqlite3_sourceid()); |
sqlite3_libversion(), sqlite3_sourceid()); |
}else |
}else |
|
|
|
|
if( p->db ){ |
if( p->db ){ |
sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); |
sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); |
if( zVfsName ){ |
if( zVfsName ){ |
printf("%s\n", zVfsName); |
fprintf(p->out, "%s\n", zVfsName); |
sqlite3_free(zVfsName); |
sqlite3_free(zVfsName); |
} |
} |
} |
} |
|
|
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) |
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) |
if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ |
if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ |
extern int sqlite3WhereTrace; |
extern int sqlite3WhereTrace; |
sqlite3WhereTrace = atoi(azArg[1]); |
sqlite3WhereTrace = booleanValue(azArg[1]); |
}else |
}else |
#endif |
#endif |
|
|
|
|
free(zSql); |
free(zSql); |
zSql = 0; |
zSql = 0; |
nSql = 0; |
nSql = 0; |
|
}else if( zSql && _all_whitespace(zSql) ){ |
|
free(zSql); |
|
zSql = 0; |
|
nSql = 0; |
} |
} |
} |
} |
if( zSql ){ |
if( zSql ){ |
|
|
" -interactive force interactive I/O\n" |
" -interactive force interactive I/O\n" |
" -line set output mode to 'line'\n" |
" -line set output mode to 'line'\n" |
" -list set output mode to 'list'\n" |
" -list set output mode to 'list'\n" |
|
" -mmap N default mmap size set to N\n" |
#ifdef SQLITE_ENABLE_MULTIPLEX |
#ifdef SQLITE_ENABLE_MULTIPLEX |
" -multiplex enable the multiplexor VFS\n" |
" -multiplex enable the multiplexor VFS\n" |
#endif |
#endif |
|
|
sqlite3_int64 szHeap; |
sqlite3_int64 szHeap; |
|
|
zSize = cmdline_option_value(argc, argv, ++i); |
zSize = cmdline_option_value(argc, argv, ++i); |
szHeap = atoi(zSize); |
szHeap = integerValue(zSize); |
for(j=0; (c = zSize[j])!=0; j++){ |
|
if( c=='M' ){ szHeap *= 1000000; break; } |
|
if( c=='K' ){ szHeap *= 1000; break; } |
|
if( c=='G' ){ szHeap *= 1000000000; break; } |
|
} |
|
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; |
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; |
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); |
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); |
#endif |
#endif |
|
|
extern int sqlite3_multiple_initialize(const char*,int); |
extern int sqlite3_multiple_initialize(const char*,int); |
sqlite3_multiplex_initialize(0, 1); |
sqlite3_multiplex_initialize(0, 1); |
#endif |
#endif |
|
}else if( strcmp(z,"-mmap")==0 ){ |
|
sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); |
|
sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); |
}else if( strcmp(z,"-vfs")==0 ){ |
}else if( strcmp(z,"-vfs")==0 ){ |
sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i)); |
sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i)); |
if( pVfs ){ |
if( pVfs ){ |
|
|
stdin_is_interactive = 0; |
stdin_is_interactive = 0; |
}else if( strcmp(z,"-heap")==0 ){ |
}else if( strcmp(z,"-heap")==0 ){ |
i++; |
i++; |
|
}else if( strcmp(z,"-mmap")==0 ){ |
|
i++; |
}else if( strcmp(z,"-vfs")==0 ){ |
}else if( strcmp(z,"-vfs")==0 ){ |
i++; |
i++; |
#ifdef SQLITE_ENABLE_VFSTRACE |
#ifdef SQLITE_ENABLE_VFSTRACE |
|
|
z = cmdline_option_value(argc,argv,++i); |
z = cmdline_option_value(argc,argv,++i); |
if( z[0]=='.' ){ |
if( z[0]=='.' ){ |
rc = do_meta_command(z, &data); |
rc = do_meta_command(z, &data); |
if( rc && bail_on_error ) return rc; |
if( rc && bail_on_error ) return rc==2 ? 0 : rc; |
}else{ |
}else{ |
open_db(&data); |
open_db(&data); |
rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg); |
rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg); |
|
|
*/ |
*/ |
if( zFirstCmd[0]=='.' ){ |
if( zFirstCmd[0]=='.' ){ |
rc = do_meta_command(zFirstCmd, &data); |
rc = do_meta_command(zFirstCmd, &data); |
|
if( rc==2 ) rc = 0; |
}else{ |
}else{ |
open_db(&data); |
open_db(&data); |
rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg); |
rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg); |