aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sqlite.h.in20
-rw-r--r--src/vdbeblob.c25
2 files changed, 42 insertions, 3 deletions
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 5e32c10c7..8ff8ab78f 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -4791,7 +4791,25 @@ int sqlite3_blob_open(
);
/*
-** CAPI3REF: Move a BLOB Handle
+** CAPI3REF: Move a BLOB Handle to a New Row
+**
+** This function is used to move an existing blob handle so that it points
+** to a different row of the same database table. The new row is identified
+** by the rowid value passed as the second argument. Only the row can be
+** changed, the database, table and column on which the blob handle is open
+** remain the same. Moving an existing blob handle to a new row can be
+** faster than closing the existing handle and opening a new one.
+**
+** The new row must meet the same criteria as for [sqlite3_blob_open()] -
+** it must exist and there must be either a blob or text value stored in
+** the nominated column. If the new row is not present in the table, or if
+** it does not contain a blob or text value, or if another error occurs, an
+** SQLite error code is returned and the blob handle is considered aborted.
+** All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
+** [sqlite3_blob_reopen()] on an aborted blob handle immediately return
+** SQLITE_ABORT.
+**
+** This function sets the database handle error code and message.
*/
SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
diff --git a/src/vdbeblob.c b/src/vdbeblob.c
index 129aad736..1bfce65a6 100644
--- a/src/vdbeblob.c
+++ b/src/vdbeblob.c
@@ -33,16 +33,37 @@ struct Incrblob {
};
+/*
+** This function is used by both blob_open() and blob_reopen(). It seeks
+** the b-tree cursor associated with blob handle p to point to row iRow.
+** If successful, SQLITE_OK is returned and subsequent calls to
+** sqlite3_blob_read() or sqlite3_blob_write() access the specified row.
+**
+** If an error occurs, or if the specified row does not exist or does not
+** contain a value of type TEXT or BLOB in the column nominated when the
+** blob handle was opened, then an error code is returned and *pzErr may
+** be set to point to a buffer containing an error message. It is the
+** responsibility of the caller to free the error message buffer using
+** sqlite3DbFree().
+**
+** If an error does occur, then the b-tree cursor is closed. All subsequent
+** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will
+** immediately return SQLITE_ABORT.
+*/
static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
int rc; /* Error code */
char *zErr = 0; /* Error message */
Vdbe *v = (Vdbe *)p->pStmt;
+ /* Set the value of the SQL statements only variable to integer iRow.
+ ** This is done directly instead of using sqlite3_bind_int64() to avoid
+ ** triggering asserts related to mutexes.
+ */
+ assert( v->aVar[0].flags&MEM_Int );
v->aVar[0].u.i = iRow;
- rc = sqlite3_step(p->pStmt);
+ rc = sqlite3_step(p->pStmt);
if( rc==SQLITE_ROW ){
- Vdbe *v = (Vdbe *)p->pStmt;
u32 type = v->apCsr[0]->aType[p->iCol];
if( type<12 ){
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",