SQLiteCpp icon indicating copy to clipboard operation
SQLiteCpp copied to clipboard

[Request] support query with bindWithZeroBlob

Open TridentTD opened this issue 6 years ago • 3 comments

Wish query insert statement that support with ZeroBlob. And then can write blob data by chunked buffer/block.
And can read blob data by chunked buffer/block too.

( These APIs will be suitable for small memory such as many MCUs. )

TridentTD avatar Jun 22 '19 06:06 TridentTD

Thanks for the suggestion!

Would you be able to provide a first implementation of these?

Cheers!

SRombauts avatar Aug 25 '19 20:08 SRombauts

These are Blob.h and Blob.cpp that can read/write data with chunked buffer.

// Blob.h file

#pragma once

#include "Exception.h"
#include <string>

struct sqlite3;
struct sqlite3_blob;

namespace SQLite
{

// Forward declaration
class Database;
extern const int OK; ///< SQLITE_OK

class Blob{
public:
  Blob(Database& aDatabase, const char* table_name, const char* column_name, long long rowid);
  ~Blob();

  int   size();
  int   read(unsigned char* buffer, int buffer_len, int offset=-1);
  void  write(unsigned char* buffer, int buffer_len, int offset=-1);
  void  position( int offset);
  int   position();

private:
  sqlite3*        mpSQLite;
  sqlite3_blob*   mpBlob;
  std::string     mTableName;
  std::string     mColumnName;
  long long       mRowId;
  int             mOffset;

  inline void check(const int aRet) const
  {
      if (SQLite::OK != aRet)
      {
          throw SQLite::Exception(mpSQLite, aRet);
      }
  }
};

}  // namespace SQLite

// Blob.cpp  file

#include "Blob.h"
#include "Database.h"
#include "Exception.h"

#include "sqlite/sqlite3.h"

namespace SQLite
{

Blob::Blob(Database& aDatabase, const char* table_name, const char* column_name, long long rowid)
: mTableName(table_name), mColumnName(column_name), mRowId(rowid), mOffset(0)
{
  mpSQLite = aDatabase.mpSQLite;
  const int ret = sqlite3_blob_open(mpSQLite, "main", mTableName.c_str(), mColumnName.c_str(), mRowId, 1, &mpBlob);
  check(ret);
}

Blob::~Blob(){
  sqlite3_blob_close(mpBlob);
}

int Blob::size() {
  return sqlite3_blob_bytes(mpBlob);
}

int Blob::position() {
  return mOffset;
}

void Blob::position( int offset){
  if(offset >= 0) mOffset = offset;
  if(mOffset >= size() ) mOffset = size();
}

int Blob::read(unsigned char* buffer, int buffer_len, int offset) {
  this->position(offset);
  memset(buffer,0, buffer_len);

  if(mOffset >= size() ) return 0;

  int len = (size() > mOffset + buffer_len)? buffer_len : (size() - mOffset);
  const int ret = sqlite3_blob_read(mpBlob, buffer, len, mOffset);
  mOffset += len;

  check(ret);
  return len;
}

void Blob::write(unsigned char* buffer, int buffer_len, int offset){
  this->position(offset);

  const int ret = sqlite3_blob_write(mpBlob, buffer, buffer_len, mOffset);

  mOffset += buffer_len;
  if( mOffset > size() ) mOffset = size();
  check(ret);
}


}  // namespace SQLite

TridentTD avatar Sep 02 '19 08:09 TridentTD

Hi Sébastien, Hi TridentTD, First of all, big thanks for the friendly C++ packaging of SQLite. I am enjoying this.

Is there any progress on this?

I would like to create a 'typed blob' = {typeinfo + blobdata} without having to copy/move the blobdata extra times for this. The class Blob would be made for this, wouldn't it?

Spammed avatar Dec 18 '20 18:12 Spammed