From 6a367c50e2400ec61c8e0ded3fcac805b1f2245e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Rombauts?= Date: Sat, 9 Mar 2013 17:54:58 +0100 Subject: [PATCH] Added binding of a binary blob of data --- src/SQLiteC++/Column.h | 2 +- src/SQLiteC++/Statement.cpp | 15 +++++++++++++++ src/SQLiteC++/Statement.h | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/SQLiteC++/Column.h b/src/SQLiteC++/Column.h index 78a390a..0377820 100644 --- a/src/SQLiteC++/Column.h +++ b/src/SQLiteC++/Column.h @@ -95,7 +95,7 @@ public: * Return either : * - size in bytes (not in characters) of the string returned by getText() without the '\0' terminator * - size in bytes of the string representation of the numerical value (integer or double) - * - TODO size in bytes of the binary blob returned by getBlob() + * - size in bytes of the binary blob returned by getBlob() * - 0 for a NULL value */ int getBytes(void) const throw(); diff --git a/src/SQLiteC++/Statement.cpp b/src/SQLiteC++/Statement.cpp index b6b5c74..6039fb3 100644 --- a/src/SQLiteC++/Statement.cpp +++ b/src/SQLiteC++/Statement.cpp @@ -76,6 +76,13 @@ void Statement::bind(const int aIndex, const char* apValue) // throw(SQLite::Exc check(ret); } +// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement +void Statement::bind(const int aIndex, const void* apValue, const int aSize) // throw(SQLite::Exception) +{ + int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, -1, SQLITE_TRANSIENT); + check(ret); +} + // Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement void Statement::bind(const int aIndex) // throw(SQLite::Exception) { @@ -124,6 +131,14 @@ void Statement::bind(const char* apName, const char* apValue) // throw(SQLite::E check(ret); } +// Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement +void Statement::bind(const char* apName, const void* apValue, const int aSize) // throw(SQLite::Exception) +{ + int index = sqlite3_bind_parameter_index(mStmtPtr, apName); + int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_TRANSIENT); + check(ret); +} + // Bind a NULL value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement void Statement::bind(const char* apName) // throw(SQLite::Exception) { diff --git a/src/SQLiteC++/Statement.h b/src/SQLiteC++/Statement.h index c28b118..dd10e48 100644 --- a/src/SQLiteC++/Statement.h +++ b/src/SQLiteC++/Statement.h @@ -61,6 +61,14 @@ public: // Can use the parameter index, starting from "1", to the higher NNN value, // or the complete parameter name "?NNN", ":VVV", "@VVV" or "$VVV" // (prefixed with the corresponding sign "?", ":", "@" or "$") + // + // Note that for text and blob values, the SQLITE_TRANSIENT flag is used, + // which tell the sqlite library to make its own copy of the data before the bind() call returns. + // This choice is done to prevent any common misuses, like passing a pointer to a + // dynamic allocated and temporary variable (a std::string for instance). + // This is under-optimized for static data (a static text define in code) + // as well as for dynamic allocated buffer which could be transfer to sqlite + // instead of being copied. /** * Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) @@ -75,13 +83,23 @@ public: */ void bind(const int aIndex, const double& aValue) ; // throw(SQLite::Exception); /** - * Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use */ void bind(const int aIndex, const std::string& aValue) ; // throw(SQLite::Exception); /** - * Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use */ void bind(const int aIndex, const char* apValue) ; // throw(SQLite::Exception); + /** + * @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use + */ + void bind(const int aIndex, const void* apValue, const int aSize) ; // throw(SQLite::Exception); /** * Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) */ @@ -100,13 +118,23 @@ public: */ void bind(const char* apName, const double& aValue) ; // throw(SQLite::Exception); /** - * Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use */ void bind(const char* apName, const std::string& aValue) ; // throw(SQLite::Exception); /** - * Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use */ void bind(const char* apName, const char* apValue) ; // throw(SQLite::Exception); + /** + * @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use + */ + void bind(const char* apName, const void* apValue, const int aSize) ; // throw(SQLite::Exception); /** * Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) */