1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-03 16:53:36 +03:00

Updated shell to output blobs in X'1234' form when in "insert" mode. Ticket [72adc99de9].

FossilOrigin-Name: a2ad9e6363308b7137fcb1916769151b96933cdb
This commit is contained in:
shane
2009-10-22 17:30:15 +00:00
parent e6ab069274
commit 626a6e4aa2
3 changed files with 166 additions and 23 deletions

View File

@@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Add\smarkings\son\stest\sevidence\sfor\sR-30323-21917.
D 2009-10-22T00:20:18
C Updated\sshell\sto\soutput\sblobs\sin\sX'1234'\sform\swhen\sin\s"insert"\smode.\s\sTicket\s[72adc99de9].
D 2009-10-22T17:30:16
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -164,7 +161,7 @@ F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
F src/resolve.c 3ac31c7181fab03732125fdedf7c2091a5c07f1b
F src/rowset.c c64dafba1f9fd876836c8db8682966b9d197eb1f
F src/select.c cbe366a0ce114856e66f5daf0f848d7c48a88298
F src/shell.c 9a9fab0d54332c7e20876286dc48a145fd9dd462
F src/shell.c 47dc8e71891a4b42ce1cff2625f2c88fa1d59a21
F src/sqlite.h.in 5853e42a4066a6c9c3bf6592a9d57d0012bfdb90
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h 3b00a3ce79e60c5a47c342b738c8b75013f3ec84
@@ -764,14 +761,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 5354ace55f448d10128e2bfe4b904a1441e3bf10
R b245b9c1f74645196c42f63cc83aa54d
U drh
Z 7e2aafe0748c57a887b2da682c0b0c54
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFK36VGoxKgR168RlERAkxbAJ0Rs1ALNw2b4OGeLkxym5lGuB+r5wCfUq2t
TZYbIm/ITCW5tXtbYNlXCU0=
=WVSC
-----END PGP SIGNATURE-----
P e51af74c3aeb82604841cc83a490351d1422e838
R 5e972fea3b82d3b02406cd88c5212c96
U shane
Z 205a2d1cb1ef075c240f437a28ecdf29

View File

@@ -1 +1 @@
e51af74c3aeb82604841cc83a490351d1422e838
a2ad9e6363308b7137fcb1916769151b96933cdb

View File

@@ -1277,6 +1277,7 @@ struct callback_data {
** .explain ON */
char outfile[FILENAME_MAX]; /* Filename for *out */
const char *zDbFilename; /* name of the database file */
sqlite3_stmt *pStmt; /* Current statement if any. */
};
/*
@@ -1319,6 +1320,17 @@ static int strlen30(const char *z){
return 0x3fffffff & (int)(z2 - z);
}
/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
int i;
char *zBlob = (char *)pBlob;
fprintf(out,"X'");
for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
fprintf(out,"'");
}
/*
** Output the given string as a quoted string using SQL quoting conventions.
*/
@@ -1483,10 +1495,10 @@ static void interrupt_handler(int NotUsed){
#endif
/*
** This is the callback routine that the SQLite library
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int callback(void *pArg, int nArg, char **azArg, char **azCol){
static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
int i;
struct callback_data *p = (struct callback_data*)pArg;
switch( p->mode ){
@@ -1637,6 +1649,11 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
char *zSep = i>0 ? ",": "";
if( azArg[i]==0 ){
fprintf(p->out,"%sNULL",zSep);
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
int nBlob = sqlite3_column_bytes(p->pStmt, i);
if( zSep[0] ) fprintf(p->out,"%s",zSep);
output_hex_blob(p->out, pBlob, nBlob);
}else if( isNumber(azArg[i], 0) ){
fprintf(p->out,"%s%s",zSep, azArg[i]);
}else{
@@ -1651,6 +1668,15 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
return 0;
}
/*
** This is the callback routine that the SQLite library
** invokes for each row of a query result.
*/
static int callback(void *pArg, int nArg, char **azArg, char **azCol){
/* since we don't have type info, call the shell_callback with a NULL value */
return shell_callback(pArg, nArg, azArg, azCol, NULL);
}
/*
** Set the destination table field of the callback_data structure to
** the name of the table given. Escape any quote characters in the
@@ -1766,6 +1792,133 @@ static int run_table_dump_query(
return sqlite3_finalize(pSelect);
}
/*
** Allocate space and save off current error string.
*/
static char *save_err_msg(
sqlite3 *db /* Database to query */
){
int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
char *zErrMsg = sqlite3_malloc(nErrMsg);
if( zErrMsg ){
memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
}
return zErrMsg;
}
/*
** Execute a statement or set of statements. Print
** any result rows/columns depending on the current mode
** set via the supplied callback.
**
** This is very similar to SQLite's built-in sqlite3_exec()
** function except it takes a slightly different callback
** and callback data argument.
*/
static int shell_exec(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
/* (not the same as sqlite3_exec) */
struct callback_data *pArg, /* Pointer to struct callback_data */
char **pzErrMsg /* Error msg written here */
){
sqlite3_stmt *pStmt = NULL;
int rc, rc2;
if( pzErrMsg ){
*pzErrMsg = NULL;
}
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
if( (SQLITE_OK != rc) || !pStmt ){
if( pzErrMsg ){
*pzErrMsg = save_err_msg(db);
}
}else{
/* perform the first step. this will tell us if we
** have a result set or not and how wide it is.
*/
rc = sqlite3_step(pStmt);
/* if we have a result set... */
if( SQLITE_ROW == rc ){
/* if callback... */
if( xCallback ){
/* allocate space for col name ptr, value ptr, and type */
int nCol = sqlite3_column_count(pStmt);
void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
if( !pData ){
rc = SQLITE_NOMEM;
}else{
char **azCols = (char **)pData; /* Names of result columns */
char **azVals = &azCols[nCol]; /* Results */
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
int i;
assert(sizeof(int) <= sizeof(char *));
/* save off ptrs to column names */
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
/* save off the prepared statment handle */
if( pArg ){
pArg->pStmt = pStmt;
}
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);
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
rc = SQLITE_NOMEM;
break; /* from for */
}
} /* end for */
/* if data and types extracted successfully... */
if( SQLITE_ROW == rc ){
/* call the supplied callback with the result row data */
if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
rc = SQLITE_ABORT;
}else{
rc = sqlite3_step(pStmt);
}
}
} while( SQLITE_ROW == rc );
sqlite3_free(pData);
if( pArg ){
pArg->pStmt = NULL;
}
}
}else{
do{
rc = sqlite3_step(pStmt);
} while( rc == SQLITE_ROW );
}
}
/* if the last sqlite3_step() didn't complete successfully... */
if( (SQLITE_OK != rc) && (SQLITE_DONE != rc) ){
if( pzErrMsg ){
*pzErrMsg = save_err_msg(db);
}
}else{
rc = SQLITE_OK;
}
rc2 = sqlite3_finalize(pStmt);
/* if the last sqlite3_finalize() didn't complete successfully
** AND we don't have a save error from sqlite3_step ... */
if( (SQLITE_OK != rc2) && (SQLITE_OK == rc) ){
rc = rc2;
if( pzErrMsg ){
*pzErrMsg = save_err_msg(db);
}
}
}
return rc;
}
/*
** This is a different callback routine used for dumping the database.
@@ -2910,7 +3063,7 @@ static int process_input(struct callback_data *p, FILE *in){
p->cnt = 0;
open_db(p);
BEGIN_TIMER;
rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
END_TIMER;
if( rc || zErrMsg ){
char zPrefix[100];
@@ -3229,7 +3382,7 @@ int main(int argc, char **argv){
}else{
int rc;
open_db(&data);
rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
if( rc!=0 && zErrMsg!=0 ){
fprintf(stderr,"SQL error: %s\n", zErrMsg);
exit(1);