Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/SQLiteCpp/Column.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

#include <string>
#include <memory>
#if __cplusplus >= 201703L // C++17
#include <string_view>
#endif

// Forward declarations to avoid inclusion of <sqlite3.h> in a header
struct sqlite3_stmt;
Expand Down Expand Up @@ -103,6 +106,18 @@ class SQLITECPP_API Column
*/
std::string getString() const;

#if __cplusplus >= 201703L // C++17
/**
* @brief Return a std::string_view for a TEXT or BLOB column.
*
* Note this correctly handles strings that contain null bytes.
*
* @warning returned string_view is only valid until there is a type
* conversion or the statement is stepped or reset.
*/
std::string_view getStringView() const;
#endif

/**
* @brief Return the type of the value of the column using sqlite3_column_type()
*
Expand Down
74 changes: 74 additions & 0 deletions include/SQLiteCpp/Statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#include <string>
#include <map>
#include <memory>
#if __cplusplus >= 201703L // C++17
#include <string_view>
#endif

// Forward declarations to avoid inclusion of <sqlite3.h> in a header
struct sqlite3;
Expand Down Expand Up @@ -139,6 +142,16 @@ class SQLITECPP_API Statement
* @brief Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const double aValue);

#if __cplusplus >= 201703L // C++17
/**
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const int aIndex, const std::string_view aValue);
#endif

/**
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
Expand All @@ -157,6 +170,16 @@ 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);
#if __cplusplus >= 201703L // C++17
/**
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1).
*
* The string can contain null characters as it is binded using its size.
*
* @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 std::string_view aValue);
#endif
/**
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1).
*
Expand Down Expand Up @@ -219,6 +242,17 @@ class SQLITECPP_API Statement
{
bind(getIndex(apName), aValue);
}
#if __cplusplus >= 201703L // C++17
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const char* apName, const std::string_view aValue)
{
bind(getIndex(apName), aValue);
}
#endif
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
Expand Down Expand Up @@ -246,6 +280,19 @@ class SQLITECPP_API Statement
{
bind(getIndex(apName), apValue, aSize);
}
#if __cplusplus >= 201703L // C++17
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* The string can contain null characters as it is binded using its size.
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
void bindNoCopy(const char* apName, const std::string_view aValue)
{
bindNoCopy(getIndex(apName), aValue);
}
#endif
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
Expand Down Expand Up @@ -320,6 +367,18 @@ class SQLITECPP_API Statement
{
bind(aName.c_str(), aValue);
}

#if __cplusplus >= 201703L // C++17
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const std::string& aName, const std::string_view aValue)
{
bind(aName.c_str(), aValue);
}
#endif
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
Expand Down Expand Up @@ -347,6 +406,21 @@ class SQLITECPP_API Statement
{
bind(aName.c_str(), apValue, aSize);
}

#if __cplusplus >= 201703L // C++17
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* The string can contain null characters as it is binded using its size.
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
void bindNoCopy(const std::string& aName, const std::string& aValue)
{
bindNoCopy(aName.c_str(), aValue);
}
#endif

/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
Expand Down
17 changes: 17 additions & 0 deletions src/Column.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,23 @@ std::string Column::getString() const
return std::string(data, sqlite3_column_bytes(mStmtPtr.get(), mIndex));
}

#if __cplusplus >= 201703L // C++17
// Return a std::string_view to a TEXT or BLOB column
std::string_view Column::getStringView() const
{
// Note: using sqlite3_column_blob and not sqlite3_column_text
// - no need for sqlite3_column_text to add a \0 on the end, as we're getting the bytes length directly
// however, we need to call sqlite3_column_bytes() to ensure correct format. It's a noop on a BLOB
// or a TEXT value with the correct encoding (UTF-8). Otherwise it'll do a conversion to TEXT (UTF-8).
(void)sqlite3_column_bytes(mStmtPtr.get(), mIndex);
auto data = static_cast<const char *>(sqlite3_column_blob(mStmtPtr.get(), mIndex));

// SQLite docs: "The safest policy is to invoke… sqlite3_column_blob() followed by sqlite3_column_bytes()"
// Note: std::string is ok to pass nullptr as first arg, if length is 0
return std::string_view(data, sqlite3_column_bytes(mStmtPtr.get(), mIndex));
}
#endif

// Return the type of the value of the column
int Column::getType() const noexcept
{
Expand Down
24 changes: 24 additions & 0 deletions src/Statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,20 @@ void Statement::bind(const int aIndex, const double aValue)
check(ret);
}

#if __cplusplus >= 201703L // c++17
/**
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void Statement::bind(const int aIndex, const std::string_view aValue) {
const int ret = sqlite3_bind_text(getPreparedStatement(), aIndex, aValue.data(),
static_cast<int>(aValue.size()), SQLITE_TRANSIENT);
check(ret);
}
#endif


// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const std::string& aValue)
{
Expand All @@ -130,6 +144,16 @@ void Statement::bind(const int aIndex, const void* apValue, const int aSize)
check(ret);
}

#if __cplusplus >= 201703L // C++17
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const int aIndex, const std::string_view aValue)
{
const int ret = sqlite3_bind_text(getPreparedStatement(), aIndex, aValue.data(),
static_cast<int>(aValue.size()), SQLITE_STATIC);
check(ret);
}
#endif

// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const int aIndex, const std::string& aValue)
{
Expand Down