diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/test1.c | 123 | ||||
-rw-r--r-- | src/vdbeblob.c | 26 |
2 files changed, 99 insertions, 50 deletions
diff --git a/src/test1.c b/src/test1.c index 6ea6e8297..a29c91fca 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1590,6 +1590,82 @@ static int test_table_column_metadata( #ifndef SQLITE_OMIT_INCRBLOB +static int blobHandleFromObj( + Tcl_Interp *interp, + Tcl_Obj *pObj, + sqlite3_blob **ppBlob +){ + char *z; + int n; + + z = Tcl_GetStringFromObj(pObj, &n); + if( n==0 ){ + *ppBlob = 0; + }else{ + int notUsed; + Tcl_Channel channel; + ClientData instanceData; + + channel = Tcl_GetChannel(interp, z, ¬Used); + if( !channel ) return TCL_ERROR; + + Tcl_Flush(channel); + Tcl_Seek(channel, 0, SEEK_SET); + + instanceData = Tcl_GetChannelInstanceData(channel); + *ppBlob = *((sqlite3_blob **)instanceData); + } + + return TCL_OK; +} + +/* +** sqlite3_blob_bytes CHANNEL +*/ +static int test_blob_bytes( + ClientData clientData, /* Not used */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3_blob *pBlob; + int nByte; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); + return TCL_ERROR; + } + + if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; + nByte = sqlite3_blob_bytes(pBlob); + Tcl_SetObjResult(interp, Tcl_NewIntObj(nByte)); + + return TCL_OK; +} + +/* +** sqlite3_blob_close CHANNEL +*/ +static int test_blob_close( + ClientData clientData, /* Not used */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3_blob *pBlob; + int nByte; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); + return TCL_ERROR; + } + + if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; + sqlite3_blob_close(pBlob); + + return TCL_OK; +} + /* ** sqlite3_blob_read CHANNEL OFFSET N ** @@ -1611,10 +1687,7 @@ static int test_blob_read( int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ - Tcl_Channel channel; - ClientData instanceData; sqlite3_blob *pBlob; - int notUsed; int nByte; int iOffset; unsigned char *zBuf; @@ -1625,18 +1698,13 @@ static int test_blob_read( return TCL_ERROR; } - channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), ¬Used); - if( !channel - || TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) + if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; + if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) || TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte) - || nByte<0 || iOffset<0 ){ return TCL_ERROR; } - instanceData = Tcl_GetChannelInstanceData(channel); - pBlob = *((sqlite3_blob **)instanceData); - zBuf = (unsigned char *)Tcl_Alloc(nByte); rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset); if( rc==SQLITE_OK ){ @@ -1669,10 +1737,7 @@ static int test_blob_write( int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ - Tcl_Channel channel; - ClientData instanceData; sqlite3_blob *pBlob; - int notUsed; int iOffset; int rc; @@ -1684,14 +1749,11 @@ static int test_blob_write( return TCL_ERROR; } - channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), ¬Used); - if( !channel || TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ + if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; + if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ return TCL_ERROR; } - instanceData = Tcl_GetChannelInstanceData(channel); - pBlob = *((sqlite3_blob **)instanceData); - zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf); if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){ return TCL_ERROR; @@ -1711,10 +1773,7 @@ static int test_blob_reopen( Tcl_Obj *CONST objv[] /* Command arguments */ ){ Tcl_WideInt iRowid; - Tcl_Channel channel; - ClientData instanceData; sqlite3_blob *pBlob; - int notUsed; int rc; unsigned char *zBuf; @@ -1725,20 +1784,8 @@ static int test_blob_reopen( return TCL_ERROR; } - channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), ¬Used); - if( !channel || TCL_OK!=Tcl_GetWideIntFromObj(interp, objv[2], &iRowid) ){ - return TCL_ERROR; - } - - if( TCL_OK!=(rc = Tcl_Flush(channel)) ){ - return rc; - } - if( TCL_OK!=(rc = Tcl_Seek(channel, 0, SEEK_SET)) ){ - return rc; - } - - instanceData = Tcl_GetChannelInstanceData(channel); - pBlob = *((sqlite3_blob **)instanceData); + if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; + if( Tcl_GetWideIntFromObj(interp, objv[2], &iRowid) ) return TCL_ERROR; rc = sqlite3_blob_reopen(pBlob, iRowid); if( rc!=SQLITE_OK ){ @@ -5371,9 +5418,11 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #endif #ifndef SQLITE_OMIT_INCRBLOB - { "sqlite3_blob_read", test_blob_read, 0 }, - { "sqlite3_blob_write", test_blob_write, 0 }, + { "sqlite3_blob_read", test_blob_read, 0 }, + { "sqlite3_blob_write", test_blob_write, 0 }, { "sqlite3_blob_reopen", test_blob_reopen, 0 }, + { "sqlite3_blob_bytes", test_blob_bytes, 0 }, + { "sqlite3_blob_close", test_blob_close, 0 }, #endif { "pcache_stats", test_pcache_stats, 0 }, #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 1bfce65a6..f43fc6499 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -150,12 +150,11 @@ int sqlite3_blob_open( {OP_Halt, 0, 0, 0}, /* 11 */ }; - Vdbe *v = 0; int rc = SQLITE_OK; char *zErr = 0; Table *pTab; - Parse *pParse; - Incrblob *pBlob; + Parse *pParse = 0; + Incrblob *pBlob = 0; flags = !!flags; /* flags = (flags ? 1 : 0); */ *ppBlob = 0; @@ -163,15 +162,15 @@ int sqlite3_blob_open( sqlite3_mutex_enter(db->mutex); pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); + if( !pBlob ) goto blob_open_out; pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); - if( pParse==0 || pBlob==0 ){ - assert( db->mallocFailed ); - goto blob_open_out; - } + if( !pParse ) goto blob_open_out; do { memset(pParse, 0, sizeof(Parse)); pParse->db = db; + sqlite3DbFree(db, zErr); + zErr = 0; sqlite3BtreeEnterAll(db); pTab = sqlite3LocateTable(pParse, 0, zTable, zDb); @@ -197,7 +196,7 @@ int sqlite3_blob_open( } /* Now search pTab for the exact column. */ - for(iCol=0; iCol < pTab->nCol; iCol++) { + for(iCol=0; iCol<pTab->nCol; iCol++) { if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ break; } @@ -251,11 +250,15 @@ int sqlite3_blob_open( } } - v = sqlite3VdbeCreate(db); - if( v ){ + pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db); + assert( pBlob->pStmt || db->mallocFailed ); + if( pBlob->pStmt ){ + Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); + /* Configure the OP_Transaction */ sqlite3VdbeChangeP1(v, 0, iDb); sqlite3VdbeChangeP2(v, 0, flags); @@ -298,11 +301,9 @@ int sqlite3_blob_open( } pBlob->flags = flags; - pBlob->pStmt = (sqlite3_stmt *)v; pBlob->iCol = iCol; pBlob->db = db; sqlite3BtreeLeaveAll(db); - v = 0; if( db->mallocFailed ){ goto blob_open_out; } @@ -314,7 +315,6 @@ blob_open_out: if( rc==SQLITE_OK && db->mallocFailed==0 ){ *ppBlob = (sqlite3_blob *)pBlob; }else{ - if( v ) sqlite3VdbeFinalize(v); if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); sqlite3DbFree(db, pBlob); } |