From 66c1546a0b2513a6bff23631fb502df689c8a35b Mon Sep 17 00:00:00 2001
From: Xiaoge Su <magichp@gmail.com>
Date: Tue, 24 May 2022 00:34:05 -0700
Subject: [PATCH] Supports string_view for bind

---
 include/SQLiteCpp/Statement.h | 57 ++++++++++++++++++++++++++++++++++-
 src/Statement.cpp             | 16 ++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/include/SQLiteCpp/Statement.h b/include/SQLiteCpp/Statement.h
index c81e215d..6c576f13 100644
--- a/include/SQLiteCpp/Statement.h
+++ b/include/SQLiteCpp/Statement.h
@@ -14,6 +14,7 @@
 #include <SQLiteCpp/Utils.h> // SQLITECPP_PURE_FUNC
 
 #include <string>
+#include <string_view>
 #include <map>
 #include <memory>
 
@@ -152,6 +153,12 @@ class Statement
      * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
      */
     void bind(const int aIndex, const char*         apValue);
+    /**
+     * @brief Bind a text 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 apValue);
     /**
      * @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
      *
@@ -166,6 +173,14 @@ class 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 std::string&    aValue);
+    /**
+     * @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);
     /**
      * @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
      *
@@ -224,6 +239,15 @@ class Statement
     {
         bind(getIndex(apName), aValue);
     }
+    /**
+     * @brief Bind a string_view 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);
+    }
     /**
      * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
      *
@@ -253,6 +277,17 @@ class Statement
     {
         bindNoCopy(getIndex(apName), aValue);
     }
+    /**
+     * @brief Bind a string_view 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);
+    }
     /**
      * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
      *
@@ -321,6 +356,15 @@ class Statement
     {
         bind(aName.c_str(), aValue);
     }
+    /**
+     * @brief Bind a string_view 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);
+    }
     /**
      * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
      *
@@ -350,6 +394,17 @@ class Statement
     {
         bindNoCopy(aName.c_str(), aValue);
     }
+    /**
+     * @brief Bind a string_view 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_view aValue)
+    {
+        bindNoCopy(aName.c_str(), aValue);
+    }
     /**
      * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
      *
@@ -705,7 +760,7 @@ class Statement
     int                     mColumnCount{0};        //!< Number of columns in the result of the prepared statement
     bool                    mbHasRow{false};        //!< true when a row has been fetched with executeStep()
     bool                    mbDone{false};          //!< true when the last executeStep() had no more row to fetch
-    
+
     /// Map of columns index by name (mutable so getColumnIndex can be const)
     mutable std::map<std::string, int>  mColumnNames{};
 };
diff --git a/src/Statement.cpp b/src/Statement.cpp
index 64e16d2d..3879ec9c 100644
--- a/src/Statement.cpp
+++ b/src/Statement.cpp
@@ -105,6 +105,14 @@ void Statement::bind(const int aIndex, const std::string& aValue)
     check(ret);
 }
 
+// Bind a string_view value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
+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);
+}
+
 // Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
 void Statement::bind(const int aIndex, const char* apValue)
 {
@@ -119,6 +127,14 @@ void Statement::bind(const int aIndex, const void* apValue, const int aSize)
     check(ret);
 }
 
+// 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);
+}
+
 // 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)
 {