Sqlite: Add blob support

Change-Id: Ic2ec5f20c8585241b9e9aaa8465e70b6ab4f004c
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2020-05-26 20:31:41 +02:00
parent 22c33fb859
commit 9c44f8d88d
8 changed files with 204 additions and 38 deletions

View File

@@ -197,6 +197,17 @@ void BaseStatement::bind(int index, Utils::SmallStringView text)
checkForBindingError(resultCode);
}
void BaseStatement::bind(int index, Utils::span<const byte> bytes)
{
int resultCode = sqlite3_bind_blob64(m_compiledStatement.get(),
index,
bytes.data(),
static_cast<long long>(bytes.size()),
SQLITE_STATIC);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode);
}
void BaseStatement::bind(int index, const Value &value)
{
switch (value.type()) {
@@ -433,8 +444,9 @@ Database &BaseStatement::database() const
return m_database;
}
template <typename StringType>
static StringType textForColumn(sqlite3_stmt *sqlStatment, int column)
namespace {
template<typename StringType>
StringType textForColumn(sqlite3_stmt *sqlStatment, int column)
{
const char *text = reinterpret_cast<const char*>(sqlite3_column_text(sqlStatment, column));
std::size_t size = std::size_t(sqlite3_column_bytes(sqlStatment, column));
@@ -442,20 +454,40 @@ static StringType textForColumn(sqlite3_stmt *sqlStatment, int column)
return StringType(text, size);
}
template <typename StringType>
static StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
Utils::span<const byte> blobForColumn(sqlite3_stmt *sqlStatment, int column)
{
const byte *blob = reinterpret_cast<const byte *>(sqlite3_column_blob(sqlStatment, column));
std::size_t size = std::size_t(sqlite3_column_bytes(sqlStatment, column));
return {blob, size};
}
Utils::span<const byte> convertToBlobForColumn(sqlite3_stmt *sqlStatment, int column)
{
int dataType = sqlite3_column_type(sqlStatment, column);
if (dataType == SQLITE_BLOB)
return blobForColumn(sqlStatment, column);
return {};
}
template<typename StringType>
StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
{
int dataType = sqlite3_column_type(sqlStatment, column);
switch (dataType) {
case SQLITE_INTEGER:
case SQLITE_FLOAT:
case SQLITE3_TEXT: return textForColumn<StringType>(sqlStatment, column);
case SQLITE_BLOB:
case SQLITE_NULL: break;
case SQLITE_INTEGER:
case SQLITE_FLOAT:
case SQLITE3_TEXT:
return textForColumn<StringType>(sqlStatment, column);
case SQLITE_BLOB:
case SQLITE_NULL:
break;
}
return StringType{"", 0};
}
} // namespace
int BaseStatement::fetchIntValue(int column) const
{
@@ -501,6 +533,14 @@ double BaseStatement::fetchDoubleValue(int column) const
return sqlite3_column_double(m_compiledStatement.get(), column);
}
Utils::span<const byte> BaseStatement::fetchBlobValue(int column) const
{
checkIfIsReadyToFetchValues();
checkColumnIsValid(column);
return convertToBlobForColumn(m_compiledStatement.get(), column);
}
template<>
double BaseStatement::fetchValue<double>(int column) const
{

View File

@@ -33,6 +33,7 @@
#include <utils/smallstringvector.h>
#include <utils/optional.h>
#include <utils/span.h>
#include <cstdint>
#include <memory>
@@ -69,6 +70,7 @@ public:
double fetchDoubleValue(int column) const;
Utils::SmallStringView fetchSmallStringViewValue(int column) const;
ValueView fetchValueView(int column) const;
Utils::span<const byte> fetchBlobValue(int column) const;
template<typename Type>
Type fetchValue(int column) const;
int columnCount() const;
@@ -80,6 +82,7 @@ public:
void bind(int index, void *pointer);
void bind(int index, Utils::SmallStringView fetchValue);
void bind(int index, const Value &fetchValue);
void bind(int index, Utils::span<const byte> bytes);
void bind(int index, uint value) { bind(index, static_cast<long long>(value)); }
@@ -362,6 +365,7 @@ private:
operator long long() { return statement.fetchLongLongValue(column); }
operator double() { return statement.fetchDoubleValue(column); }
operator Utils::SmallStringView() { return statement.fetchSmallStringViewValue(column); }
operator Utils::span<const Sqlite::byte>() { return statement.fetchBlobValue(column); }
operator ValueView() { return statement.fetchValueView(column); }
StatementImplementation &statement;

View File

@@ -73,4 +73,6 @@ enum class OpenMode : char
enum class ChangeType : int { Delete = 9, Insert = 18, Update = 23 };
enum class byte : unsigned char {};
} // namespace Sqlite