?? cryptshell.c
字號:
}
for(i=0; i<nCol; 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;
}
}
free(azCol);
fclose(in);
sqlite3_finalize(pStmt);
sqlite3_exec(p->db, zCommit, 0, 0, 0);
}else
if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
struct callback_data data;
char *zErrMsg = 0;
open_db(p);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.mode = MODE_List;
zShellStatic = azArg[1];
sqlite3_exec(p->db,
"SELECT name FROM sqlite_master "
"WHERE type='index' AND tbl_name LIKE shellstatic() "
"UNION ALL "
"SELECT name FROM sqlite_temp_master "
"WHERE type='index' AND tbl_name LIKE shellstatic() "
"ORDER BY 1",
callback, &data, &zErrMsg
);
zShellStatic = 0;
if( zErrMsg ){
fprintf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
}else
#ifdef SQLITE_ENABLE_IOTRACE
if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
extern void (*sqlite3IoTrace)(const char*, ...);
if( iotrace && iotrace!=stdout ) fclose(iotrace);
iotrace = 0;
if( nArg<2 ){
sqlite3IoTrace = 0;
}else if( strcmp(azArg[1], "-")==0 ){
sqlite3IoTrace = iotracePrintf;
iotrace = stdout;
}else{
iotrace = fopen(azArg[1], "w");
if( iotrace==0 ){
fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
sqlite3IoTrace = 0;
}else{
sqlite3IoTrace = iotracePrintf;
}
}
}else
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
const char *zFile, *zProc;
char *zErrMsg = 0;
int rc;
zFile = azArg[1];
zProc = nArg>=3 ? azArg[2] : 0;
open_db(p);
rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "%s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
}
}else
#endif
if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
int n2 = strlen(azArg[1]);
if( strncmp(azArg[1],"line",n2)==0
||
strncmp(azArg[1],"lines",n2)==0 ){
p->mode = MODE_Line;
}else if( strncmp(azArg[1],"column",n2)==0
||
strncmp(azArg[1],"columns",n2)==0 ){
p->mode = MODE_Column;
}else if( strncmp(azArg[1],"list",n2)==0 ){
p->mode = MODE_List;
}else if( strncmp(azArg[1],"html",n2)==0 ){
p->mode = MODE_Html;
}else if( strncmp(azArg[1],"tcl",n2)==0 ){
p->mode = MODE_Tcl;
}else if( strncmp(azArg[1],"csv",n2)==0 ){
p->mode = MODE_Csv;
sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
}else if( strncmp(azArg[1],"tabs",n2)==0 ){
p->mode = MODE_List;
sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
}else if( strncmp(azArg[1],"insert",n2)==0 ){
p->mode = MODE_Insert;
if( nArg>=3 ){
set_table_name(p, azArg[2]);
}else{
set_table_name(p, "table");
}
}else {
fprintf(stderr,"mode should be one of: "
"column csv html insert line list tabs tcl\n");
}
}else
if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
"%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
}else
if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
if( p->out!=stdout ){
fclose(p->out);
}
if( strcmp(azArg[1],"stdout")==0 ){
p->out = stdout;
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
}else{
p->out = fopen(azArg[1], "wb");
if( p->out==0 ){
fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
p->out = stdout;
} else {
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
}
}
}else
if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
if( nArg >= 2) {
strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
}
if( nArg >= 3) {
strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
}
}else
if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
rc = 2;
}else
if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
FILE *alt = fopen(azArg[1], "rb");
if( alt==0 ){
fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
}else{
process_input(p, alt);
fclose(alt);
}
}else
#ifdef SQLITE_HAS_CODEC
if( c=='r' && strncmp(azArg[0],"rekey", n)==0 && nArg==4 ){
char *zOld = p->zKey;
if( zOld==0 ) zOld = "";
if( strcmp(azArg[1],zOld) ){
fprintf(stderr,"old key is incorrect\n");
}else if( strcmp(azArg[2], azArg[3]) ){
fprintf(stderr,"2nd copy of new key does not match the 1st\n");
}else{
sqlite3_free(p->zKey);
p->zKey = sqlite3_mprintf("%s", azArg[2]);
sqlite3_rekey(p->db, p->zKey, strlen(p->zKey));
}
}else
#endif
if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
struct callback_data data;
char *zErrMsg = 0;
open_db(p);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.mode = MODE_Semi;
if( nArg>1 ){
int i;
for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
if( strcmp(azArg[1],"sqlite_master")==0 ){
char *new_argv[2], *new_colv[2];
new_argv[0] = "CREATE TABLE sqlite_master (\n"
" type text,\n"
" name text,\n"
" tbl_name text,\n"
" rootpage integer,\n"
" sql text\n"
")";
new_argv[1] = 0;
new_colv[0] = "sql";
new_colv[1] = 0;
callback(&data, 1, new_argv, new_colv);
}else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
char *new_argv[2], *new_colv[2];
new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
" type text,\n"
" name text,\n"
" tbl_name text,\n"
" rootpage integer,\n"
" sql text\n"
")";
new_argv[1] = 0;
new_colv[0] = "sql";
new_colv[1] = 0;
callback(&data, 1, new_argv, new_colv);
}else{
zShellStatic = azArg[1];
sqlite3_exec(p->db,
"SELECT sql FROM "
" (SELECT * FROM sqlite_master UNION ALL"
" SELECT * FROM sqlite_temp_master) "
"WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
"ORDER BY substr(type,2,1), name",
callback, &data, &zErrMsg);
zShellStatic = 0;
}
}else{
sqlite3_exec(p->db,
"SELECT sql FROM "
" (SELECT * FROM sqlite_master UNION ALL"
" SELECT * FROM sqlite_temp_master) "
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
"ORDER BY substr(type,2,1), name",
callback, &data, &zErrMsg
);
}
if( zErrMsg ){
fprintf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
}else
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]);
}else
if( c=='s' && strncmp(azArg[0], "show", n)==0){
int i;
fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
fprintf(p->out,"%9.9s: ", "nullvalue");
output_c_string(p->out, p->nullvalue);
fprintf(p->out, "\n");
fprintf(p->out,"%9.9s: %s\n","output",
strlen(p->outfile) ? p->outfile : "stdout");
fprintf(p->out,"%9.9s: ", "separator");
output_c_string(p->out, p->separator);
fprintf(p->out, "\n");
fprintf(p->out,"%9.9s: ","width");
for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
fprintf(p->out,"%d ",p->colWidth[i]);
}
fprintf(p->out,"\n");
}else
if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
char **azResult;
int nRow, rc;
char *zErrMsg;
open_db(p);
if( nArg==1 ){
rc = sqlite3_get_table(p->db,
"SELECT name FROM sqlite_master "
"WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
"UNION ALL "
"SELECT name FROM sqlite_temp_master "
"WHERE type IN ('table','view') "
"ORDER BY 1",
&azResult, &nRow, 0, &zErrMsg
);
}else{
zShellStatic = azArg[1];
rc = sqlite3_get_table(p->db,
"SELECT name FROM sqlite_master "
"WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
"UNION ALL "
"SELECT name FROM sqlite_temp_master "
"WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
"ORDER BY 1",
&azResult, &nRow, 0, &zErrMsg
);
zShellStatic = 0;
}
if( zErrMsg ){
fprintf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
if( rc==SQLITE_OK ){
int len, maxlen = 0;
int i, j;
int nPrintCol, nPrintRow;
for(i=1; i<=nRow; i++){
if( azResult[i]==0 ) continue;
len = strlen(azResult[i]);
if( len>maxlen ) maxlen = len;
}
nPrintCol = 80/(maxlen+2);
if( nPrintCol<1 ) nPrintCol = 1;
nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
for(i=0; i<nPrintRow; i++){
for(j=i+1; j<=nRow; j+=nPrintRow){
char *zSp = j<=nPrintRow ? "" : " ";
printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
}
printf("\n");
}
}else{
rc = 1;
}
sqlite3_free_table(azResult);
}else
if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
open_db(p);
sqlite3_busy_timeout(p->db, atoi(azArg[1]));
}else
#if HAS_TIMER
if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
enableTimer = booleanValue(azArg[1]);
}else
#endif
if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
int j;
assert( nArg<=ArraySize(azArg) );
for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
p->colWidth[j-1] = atoi(azArg[j]);
}
}else
{
fprintf(stderr, "unknown command or invalid arguments: "
" \"%s\". Enter \".help\" for help\n", azArg[0]);
}
return rc;
}
/*
** Return TRUE if a semicolon occurs anywhere in the first N characters
** of string z[].
*/
static int _contains_semicolon(const char *z, int N){
int i;
for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
return 0;
}
/*
** Test to see if a line consists entirely of whitespace.
*/
static int _all_whitespace(const char *z){
for(; *z; z++){
if( isspace(*(unsigned char*)z) ) continue;
if( *z=='/' && z[1]=='*' ){
z += 2;
while( *z && (*z!='*' || z[1]!='/') ){ z++; }
if( *z==0 ) return 0;
z++;
continue;
}
if( *z=='-' && z[1]=='-' ){
z += 2;
while( *z && *z!='\n' ){ z++; }
if( *z==0 ) return 1;
continue;
}
return 0;
}
return 1;
}
/*
** Return TRUE if the line typed in is an SQL command terminator other
** than a semi-colon. The SQL Server style "go" command is understood
** as is the Oracle "/".
*/
static int _is_command_terminator(const char *zLine){
while( isspace(*(unsigned char*)zLine) ){ zLine++; };
if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
&& _all_whitespace(&zLine[2]) ){
return 1; /* SQL Server */
}
return 0;
}
/*
** Read input from *in and process it. If *in==0 then input
** is interactive - the user is typing it it. Otherwise, input
** is coming from a file or device. A prompt is issued and history
** is saved only if input is interactive. An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
**
** 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;
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
fflush(p->out);
free(zLine);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -