From 901b631ba558f19160dffad688521905518708d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Rombauts?= Date: Mon, 12 Jun 2023 20:45:10 +0200 Subject: [PATCH] Add 6 Statement::bind() overrides using size_t for blobs Fix #430 for a better support of standard containers Also add a couple of tests (not covering all variants) --- include/SQLiteCpp/Statement.h | 24 +++++++++++++++++++++++ tests/Statement_test.cpp | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/include/SQLiteCpp/Statement.h b/include/SQLiteCpp/Statement.h index ba846a8d..c602d48d 100644 --- a/include/SQLiteCpp/Statement.h +++ b/include/SQLiteCpp/Statement.h @@ -156,6 +156,10 @@ class SQLITECPP_API Statement * @note 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); + void bind(const int aIndex, const void* apValue, const size_t aSize) + { + bind(aIndex, apValue, static_cast(aSize)); + } /** * @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1). * @@ -178,6 +182,10 @@ class SQLITECPP_API Statement * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. */ void bindNoCopy(const int aIndex, const void* apValue, const int aSize); + void bindNoCopy(const int aIndex, const void* apValue, const size_t aSize) + { + bindNoCopy(aIndex, apValue, static_cast(aSize)); + } /** * @brief Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -240,6 +248,10 @@ class SQLITECPP_API Statement { bind(getIndex(apName), apValue, aSize); } + void bind(const char* apName, const void* apValue, const size_t aSize) + { + bind(getIndex(apName), apValue, aSize); + } /** * @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -271,6 +283,10 @@ class SQLITECPP_API Statement { bindNoCopy(getIndex(apName), apValue, aSize); } + void bindNoCopy(const char* apName, const void* apValue, const size_t aSize) + { + bindNoCopy(getIndex(apName), apValue, aSize); + } /** * @brief Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -337,6 +353,10 @@ class SQLITECPP_API Statement { bind(aName.c_str(), apValue, aSize); } + void bind(const std::string& aName, const void* apValue, const size_t aSize) + { + bind(aName.c_str(), apValue, aSize); + } /** * @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -368,6 +388,10 @@ class SQLITECPP_API Statement { bindNoCopy(aName.c_str(), apValue, aSize); } + void bindNoCopy(const std::string& aName, const void* apValue, const size_t aSize) + { + bindNoCopy(aName.c_str(), apValue, aSize); + } /** * @brief Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * diff --git a/tests/Statement_test.cpp b/tests/Statement_test.cpp index 0976ce18..9f9999f5 100644 --- a/tests/Statement_test.cpp +++ b/tests/Statement_test.cpp @@ -407,6 +407,24 @@ TEST(Statement, bindings) EXPECT_EQ(7, query.getColumn(0).getInt64()); EXPECT_EQ(12345678900000LL, query.getColumn(2).getInt64()); } + + // reset() with clearbindings() and new bindings + insert.reset(); + insert.clearBindings(); + + // Height row with a vector of unsigned char as blob + { + const std::vector blob = { 'b','l','\0','b' }; + insert.bind(3, blob.data(), blob.size()); + EXPECT_EQ(1, insert.exec()); + EXPECT_EQ(SQLITE_DONE, db.getErrorCode()); + + // Check the result + query.executeStep(); + EXPECT_TRUE(query.hasRow()); + EXPECT_FALSE(query.isDone()); + EXPECT_EQ(0, memcmp(blob.data(), &query.getColumn(3).getString()[0], blob.size())); + } } TEST(Statement, bindNoCopy) @@ -447,6 +465,24 @@ TEST(Statement, bindNoCopy) EXPECT_EQ(0, memcmp(&txt2[0], &query.getColumn(2).getString()[0], txt2.size())); EXPECT_EQ(0, memcmp(blob, &query.getColumn(3).getString()[0], sizeof(blob))); } + + // reset() with clearbindings() and new bindings + insert.reset(); + insert.clearBindings(); + + // Insert a second row with a vector of unsigned char as blob + { + const std::vector blob = { 'b','l','\0','b' }; + insert.bindNoCopy(3, blob.data(), blob.size()); + EXPECT_EQ(1, insert.exec()); + EXPECT_EQ(SQLITE_DONE, db.getErrorCode()); + + // Check the result + query.executeStep(); + EXPECT_TRUE(query.hasRow()); + EXPECT_FALSE(query.isDone()); + EXPECT_EQ(0, memcmp(blob.data(), &query.getColumn(3).getString()[0], blob.size())); + } } TEST(Statement, bindByName)