Add some methods in class 'Sql' 96/285096/3
authorjh9216.park <jh9216.park@samsung.com>
Tue, 6 Dec 2022 05:17:23 +0000 (00:17 -0500)
committerjh9216.park <jh9216.park@samsung.com>
Tue, 6 Dec 2022 23:56:20 +0000 (18:56 -0500)
- Added 'Sql& SetEmptyStringAsNull(bool as_null);'
- Added 'Sql& SetEmptyVectorAsNull(bool as_null);'

Change-Id: I634dc658a5e7e11a2eac687c0600facf3e6b1a1c
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
tests/tizen-database_unittests/src/test_database.cc
tizen-database/database.hpp

index 176ef7c..36421c0 100644 (file)
@@ -239,6 +239,26 @@ TEST_F(DatabaseTest, test_reuse_result) {
   EXPECT_TRUE(ret);
 }
 
+TEST_F(DatabaseTest, test_set_empty_string_as_null) {
+  tizen_base::Database db(TEST_DB, SQLITE_OPEN_READWRITE);
+  auto q = tizen_base::Database::Sql(Q_INSERT)
+      .SetEmptyStringAsNull(true)
+      .Bind("")
+      .Bind(1234)
+      .Bind(9.216)
+      .SetEmptyVectorAsNull(true)
+      .Bind(std::vector<unsigned char> {});
+  auto r = db.Exec(q);
+  EXPECT_TRUE(static_cast<bool>(r));
+
+  r = db.Exec({ Q_SELECT });
+  auto rec = r.GetFirstRecord();
+  std::optional<std::string> ret1 = rec->Get(0);
+  EXPECT_FALSE(ret1);
+  std::optional<std::vector<unsigned char>> ret2 = rec->Get(3);
+  EXPECT_FALSE(ret2);
+}
+
 TEST_F(DatabaseTest, test_select) {
   SetDefault();
   using tizen_base::_;
index 8157659..516ae1a 100644 (file)
@@ -53,7 +53,7 @@ using DbType = std::optional<std::variant<int, double, std::string,
 class AutoDbType {
  public:
   AutoDbType() = default;
-  AutoDbType(DbType db_type) : db_type_(db_type) {}
+  explicit AutoDbType(DbType db_type) : db_type_(db_type) {}
 
   explicit operator int () {
     if (!db_type_)
@@ -141,7 +141,7 @@ class Database {
       return *this;
     }
 
-    TransactionGuard(sqlite3* db) : db_(db) {
+    explicit TransactionGuard(sqlite3* db) : db_(db) {
       if (sqlite3_exec(db, "BEGIN DEFERRED", nullptr, nullptr, nullptr)
           != SQLITE_OK) {
         throw std::runtime_error("begin transaction failed");
@@ -172,7 +172,10 @@ class Database {
     Sql(std::string query) : query_(std::move(query)) {}
 
     Sql& Bind(std::string val) {
-      bindings_.push_back(DbType(std::move(val)));
+      if (empty_string_as_null_ && val.empty())
+        bindings_.push_back(DbType(std::nullopt));
+      else
+        bindings_.push_back(DbType(std::move(val)));
       return *this;
     }
 
@@ -187,7 +190,10 @@ class Database {
     }
 
     Sql& Bind(std::vector<unsigned char> val) {
-      bindings_.push_back(DbType(std::move(val)));
+      if (empty_vector_as_null_ && val.empty())
+        bindings_.push_back(DbType(std::nullopt));
+      else
+        bindings_.push_back(DbType(std::move(val)));
       return *this;
     }
 
@@ -197,7 +203,10 @@ class Database {
     }
 
     Sql& Bind(int pos, std::string val) {
-      binding_map_[pos] = DbType(std::move(val));
+      if (empty_string_as_null_ && val.empty())
+        binding_map_[pos] = DbType(std::nullopt);
+      else
+        binding_map_[pos] = DbType(std::move(val));
       return *this;
     }
 
@@ -212,7 +221,10 @@ class Database {
     }
 
     Sql& Bind(int pos, std::vector<unsigned char> val) {
-      binding_map_[pos] = DbType(std::move(val));
+      if (empty_vector_as_null_ && val.empty())
+        binding_map_[pos] = DbType(std::nullopt);
+      else
+        binding_map_[pos] = DbType(std::move(val));
       return *this;
     }
 
@@ -222,7 +234,10 @@ class Database {
     }
 
     Sql& Bind(std::string name, std::string val) {
-      binding_name_map_[std::move(name)] = DbType(std::move(val));
+      if (empty_string_as_null_ && val.empty())
+        binding_name_map_[std::move(name)] = DbType(std::nullopt);
+      else
+        binding_name_map_[std::move(name)] = DbType(std::move(val));
       return *this;
     }
 
@@ -237,7 +252,10 @@ class Database {
     }
 
     Sql& Bind(std::string name, std::vector<unsigned char> val) {
-      binding_name_map_[std::move(name)] = DbType(std::move(val));
+      if (empty_vector_as_null_ && val.empty())
+        binding_name_map_[std::move(name)] = DbType(std::nullopt);
+      else
+        binding_name_map_[std::move(name)] = DbType(std::move(val));
       return *this;
     }
 
@@ -262,10 +280,22 @@ class Database {
       return query_;
     }
 
+    Sql& SetEmptyStringAsNull(bool as_null) {
+      empty_string_as_null_ = as_null;
+      return *this;
+    }
+
+    Sql& SetEmptyVectorAsNull(bool as_null) {
+      empty_vector_as_null_ = as_null;
+      return *this;
+    }
+
     Sql& Reset() {
       bindings_.clear();
       binding_map_.clear();
       binding_name_map_.clear();
+      empty_string_as_null_ = false;
+      empty_vector_as_null_ = false;
       return *this;
     }
 
@@ -274,6 +304,8 @@ class Database {
     std::vector<DbType> bindings_;
     std::map<int, DbType> binding_map_;
     std::map<std::string, DbType> binding_name_map_;
+    bool empty_string_as_null_ = false;
+    bool empty_vector_as_null_ = false;
   };
 
   class Result {
@@ -305,7 +337,7 @@ class Database {
 
     class Record {
      public:
-      Record(const sqlite3_stmt* stmt) : stmt_(stmt) {}
+      explicit Record(const sqlite3_stmt* stmt) : stmt_(stmt) {}
 
       AutoDbType Get(int pos) const {
         sqlite3_stmt* stmt = const_cast<sqlite3_stmt*>(stmt_);
@@ -355,7 +387,7 @@ class Database {
 
     class Iterator {
      public:
-      Iterator(sqlite3_stmt* stmt) : stmt_(stmt) {}
+      explicit Iterator(sqlite3_stmt* stmt) : stmt_(stmt) {}
 
       Record operator*() { return Record(stmt_); }