📄 shell.c
字号:
open_db(p); fprintf(p->out, "BEGIN TRANSACTION;\n"); if( nArg==1 ){ run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type=='table'", 0 ); run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0 ); }else{ int i; for(i=1; i<nArg; i++){ zShellStatic = azArg[i]; run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE tbl_name LIKE shellstatic() AND type=='table'" " AND sql NOT NULL", 0); run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE tbl_name LIKE shellstatic() AND type!='table'" " AND type!='meta' AND sql NOT NULL", 0); zShellStatic = 0; } } if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(p->out, "COMMIT;\n"); } }else if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){ int j; char *z = azArg[1]; int val = atoi(azArg[1]); for(j=0; z[j]; j++){ z[j] = tolower((unsigned char)z[j]); } if( strcmp(z,"on")==0 ){ val = 1; }else if( strcmp(z,"yes")==0 ){ val = 1; } p->echoOn = val; }else if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ rc = 1; }else if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ int j; static char zOne[] = "1"; char *z = nArg>=2 ? azArg[1] : zOne; int val = atoi(z); for(j=0; z[j]; j++){ z[j] = tolower((unsigned char)z[j]); } if( strcmp(z,"on")==0 ){ val = 1; }else if( strcmp(z,"yes")==0 ){ val = 1; } if(val == 1) { if(!p->explainPrev.valid) { p->explainPrev.valid = 1; p->explainPrev.mode = p->mode; p->explainPrev.showHeader = p->showHeader; memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth)); } /* We could put this code under the !p->explainValid ** condition so that it does not execute if we are already in ** explain mode. However, always executing it allows us an easy ** was to reset to explain mode in case the user previously ** did an .explain followed by a .width, .mode or .header ** command. */ p->mode = MODE_Column; p->showHeader = 1; memset(p->colWidth,0,ArraySize(p->colWidth)); p->colWidth[0] = 4; p->colWidth[1] = 12; p->colWidth[2] = 10; p->colWidth[3] = 10; p->colWidth[4] = 35; }else if (p->explainPrev.valid) { p->explainPrev.valid = 0; p->mode = p->explainPrev.mode; p->showHeader = p->explainPrev.showHeader; memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth)); } }else if( c=='h' && (strncmp(azArg[0], "header", n)==0 || strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){ int j; char *z = azArg[1]; int val = atoi(azArg[1]); for(j=0; z[j]; j++){ z[j] = tolower((unsigned char)z[j]); } if( strcmp(z,"on")==0 ){ val = 1; }else if( strcmp(z,"yes")==0 ){ val = 1; } p->showHeader = val; }else if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ fprintf(stderr,zHelp); }else 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 */ sqlite3_stmt *pStmt; /* A statement */ int rc; /* Result code */ int nCol; /* Number of columns in the table */ int nByte; /* Number of bytes in an SQL string */ int i, j; /* Loop counters */ 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 */ nSep = strlen(p->separator); if( nSep==0 ){ fprintf(stderr, "non-null separator required for import\n"); return 0; } zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); if( zSql==0 ) return 0; nByte = strlen(zSql); rc = sqlite3_prepare(p->db, zSql, 0, &pStmt, 0); sqlite3_free(zSql); if( rc ){ fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); nCol = 0; }else{ nCol = sqlite3_column_count(pStmt); } sqlite3_finalize(pStmt); if( nCol==0 ) return 0; zSql = malloc( nByte + 20 + nCol*2 ); if( zSql==0 ) return 0; sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable); j = strlen(zSql); for(i=1; i<nCol; i++){ zSql[j++] = ','; zSql[j++] = '?'; } zSql[j++] = ')'; zSql[j] = 0; rc = sqlite3_prepare(p->db, zSql, 0, &pStmt, 0); free(zSql); if( rc ){ fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); sqlite3_finalize(pStmt); return 0; } in = fopen(zFile, "rb"); if( in==0 ){ fprintf(stderr, "cannot open file: %s\n", zFile); sqlite3_finalize(pStmt); return 0; } azCol = malloc( sizeof(azCol[0])*(nCol+1) ); if( azCol==0 ) return 0; sqlite3_exec(p->db, "BEGIN", 0, 0, 0); zCommit = "COMMIT"; while( (zLine = local_getline(0, in))!=0 ){ char *z; i = 0; lineno++; azCol[0] = zLine; for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){ if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){ *z = 0; i++; if( i<nCol ){ azCol[i] = &z[nSep]; z += nSep-1; } } } if( i+1!=nCol ){ fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n", zFile, lineno, nCol, i+1); zCommit = "ROLLBACK"; break; } 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"; 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 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; strcpy(p->separator, ","); }else if( strncmp(azArg[1],"tabs",n2)==0 ){ p->mode = MODE_List; strcpy(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 on of: " "column csv html insert line list tabs tcl\n"); } }else if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) { sprintf(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; strcpy(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 { strcpy(p->outfile,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 = 1; }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 " "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 ){ sprintf(p->separator, "%.*s", (int)ArraySize(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') " "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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -