]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the blobio.c extension module implementing readblob() and writeblob().
authordrh <drh@noemail.net>
Sat, 30 Mar 2019 17:30:50 +0000 (17:30 +0000)
committerdrh <drh@noemail.net>
Sat, 30 Mar 2019 17:30:50 +0000 (17:30 +0000)
Experimental.

FossilOrigin-Name: e3fde56da46e9592143b8beeee5eba4d74b8ef67edb7bf73a85edd2e0f7a8d21

ext/misc/blobio.c [new file with mode: 0644]
manifest
manifest.uuid

diff --git a/ext/misc/blobio.c b/ext/misc/blobio.c
new file mode 100644 (file)
index 0000000..65ca467
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+** 2019-03-30
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** An SQL function that uses the incremental BLOB I/O mechanism of SQLite
+** to read or write part of a blob.  This is intended for debugging use
+** in the CLI.
+**
+**      readblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,N)
+**
+** Returns N bytes of the blob starting at OFFSET.
+**
+**      writeblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,NEWDATA)
+**
+** NEWDATA must be a blob.  The content of NEWDATA overwrites the
+** existing BLOB data at SCHEMA.TABLE.COLUMN for row ROWID beginning
+** at OFFSET bytes into the blob.
+*/
+#include "sqlite3ext.h"
+SQLITE_EXTENSION_INIT1
+#include <assert.h>
+#include <string.h>
+
+static void readblobFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  sqlite3_blob *pBlob = 0;
+  const char *zSchema;
+  const char *zTable;
+  const char *zColumn;
+  sqlite3_int64 iRowid;
+  int iOfst;
+  unsigned char *aData;
+  int nData;
+  sqlite3 *db;
+  int rc;
+
+  zSchema = (const char*)sqlite3_value_text(argv[0]);
+  zTable = (const char*)sqlite3_value_text(argv[1]);
+  if( zTable==0 ){
+    sqlite3_result_error(context, "bad table name", -1);
+    return;
+  }
+  zColumn = (const char*)sqlite3_value_text(argv[2]);
+  if( zTable==0 ){
+    sqlite3_result_error(context, "bad column name", -1);
+    return;
+  }
+  iRowid = sqlite3_value_int64(argv[3]);
+  iOfst = sqlite3_value_int(argv[4]);
+  nData = sqlite3_value_int(argv[5]);
+  if( nData<=0 ) return;
+  aData = sqlite3_malloc64( nData+1 );
+  if( aData==0 ){
+    sqlite3_result_error_nomem(context);
+    return;
+  }
+  db = sqlite3_context_db_handle(context);
+  rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 0, &pBlob);
+  if( rc ){
+    sqlite3_free(aData);
+    sqlite3_result_error(context, "cannot open BLOB pointer", -1);
+    return;
+  }
+  rc = sqlite3_blob_read(pBlob, aData, nData, iOfst);
+  sqlite3_blob_close(pBlob);
+  if( rc ){
+    sqlite3_free(aData);
+    sqlite3_result_error(context, "BLOB write failed", -1);
+  }else{
+    sqlite3_result_blob(context, aData, nData, sqlite3_free);
+  }
+}    
+
+static void writeblobFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  sqlite3_blob *pBlob = 0;
+  const char *zSchema;
+  const char *zTable;
+  const char *zColumn;
+  sqlite3_int64 iRowid;
+  int iOfst;
+  unsigned char *aData;
+  int nData;
+  sqlite3 *db;
+  int rc;
+
+  zSchema = (const char*)sqlite3_value_text(argv[0]);
+  zTable = (const char*)sqlite3_value_text(argv[1]);
+  if( zTable==0 ){
+    sqlite3_result_error(context, "bad table name", -1);
+    return;
+  }
+  zColumn = (const char*)sqlite3_value_text(argv[2]);
+  if( zTable==0 ){
+    sqlite3_result_error(context, "bad column name", -1);
+    return;
+  }
+  iRowid = sqlite3_value_int64(argv[3]);
+  iOfst = sqlite3_value_int(argv[4]);
+  if( sqlite3_value_type(argv[5])!=SQLITE_BLOB ){
+    sqlite3_result_error(context, "6th argument must be a BLOB", -1);
+    return;
+  }
+  nData = sqlite3_value_bytes(argv[5]);
+  aData = (unsigned char *)sqlite3_value_blob(argv[5]);
+  db = sqlite3_context_db_handle(context);
+  rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 1, &pBlob);
+  if( rc ){
+    sqlite3_result_error(context, "cannot open BLOB pointer", -1);
+    return;
+  }
+  rc = sqlite3_blob_write(pBlob, aData, nData, iOfst);
+  sqlite3_blob_close(pBlob);
+  if( rc ){
+    sqlite3_result_error(context, "BLOB write failed", -1);
+  }
+}    
+
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int sqlite3_blobio_init(
+  sqlite3 *db, 
+  char **pzErrMsg, 
+  const sqlite3_api_routines *pApi
+){
+  int rc = SQLITE_OK;
+  SQLITE_EXTENSION_INIT2(pApi);
+  (void)pzErrMsg;  /* Unused parameter */
+  rc = sqlite3_create_function(db, "readblob", 6, SQLITE_UTF8, 0,
+                               readblobFunc, 0, 0);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_create_function(db, "writeblob", 6, SQLITE_UTF8, 0,
+                               writeblobFunc, 0, 0);
+  }
+  return rc;
+}
index 33e41e24f51132c85131bd67829c3976c59dfca8..5219d533a65c2eda24035abd56e6c1f6ec162f47 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\san\sextra\sIO-error\stest\sto\swindowfault.test.
-D 2019-03-30T17:07:23.564
+C Add\sthe\sblobio.c\sextension\smodule\simplementing\sreadblob()\sand\swriteblob().\nExperimental.
+D 2019-03-30T17:30:50.464
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -277,6 +277,7 @@ F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f23
 F ext/misc/amatch.c 50a9ef2d38dabfa371f8c1904097d493271e63d58ccb0e9b79a4fa4a94e66660
 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
 F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7
+F ext/misc/blobio.c 085bbfa57ea58bb15d994ba4cd397bff6f0c38c4f618adbc62cf4d3780e5d88a
 F ext/misc/btreeinfo.c 4f0ebf278f46e68e6306c667917766cebc5550fd35d5de17847988e22892d4d2
 F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
 F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
@@ -1813,7 +1814,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c2edbf3b8c643edcd5823eb907fd7531cf5be8a8b6a014fa1b123eb0ea3231cf
-R 86d53f0a0cd55849b6bfbfc0814c8bf0
-U dan
-Z 7c8bdcb225b3e1ae6999bd7e018164b5
+P 5b8c44cd39c529e8adbc51f67088409e963515b988868856120a59e6c7160210
+R 34637151831985d0fc29dd4ea445150f
+U drh
+Z 97f8c049c6327eff8377c297f32c8976
index f057f0ba06e35f0ef364035700bfbc519fa2611c..fe43a957fda0284ebbe7a021720ac4feef9f74c7 100644 (file)
@@ -1 +1 @@
-5b8c44cd39c529e8adbc51f67088409e963515b988868856120a59e6c7160210
\ No newline at end of file
+e3fde56da46e9592143b8beeee5eba4d74b8ef67edb7bf73a85edd2e0f7a8d21
\ No newline at end of file