From 01d9778a1fe29b15fd7728fa6487ba1839844fa8 Mon Sep 17 00:00:00 2001 From: "jh9216.park" Date: Thu, 5 Jan 2023 19:15:18 -0500 Subject: [PATCH] Add some methods - Result.GetColumnCount() added - Record.GetString() added - AutoDbType.GetType() added - Enhance exception handling Change-Id: If471d192e0ff286c7fd1e77f831206000c6dd733 Signed-off-by: jh9216.park --- .../tizen-database_unittests/src/test_database.cc | 56 ++++++++++++++++++++++ tizen-database/database.hpp | 56 ++++++++++++++++++++-- 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/tests/tizen-database_unittests/src/test_database.cc b/tests/tizen-database_unittests/src/test_database.cc index d4239a4..b6d2180 100644 --- a/tests/tizen-database_unittests/src/test_database.cc +++ b/tests/tizen-database_unittests/src/test_database.cc @@ -545,3 +545,59 @@ TEST_F(DatabaseTest, test_nullptr_bind) { auto r = db.Exec(q); ASSERT_TRUE(r); } + +TEST_F(DatabaseTest, test_get_column_count) { + SetDefault(); + using tizen_base::_; + tizen_base::Database db(TEST_DB, SQLITE_OPEN_READWRITE); + auto r = db.Exec({ Q_SELECT }); + + EXPECT_TRUE(r); + EXPECT_EQ(r.GetColumnCount(), 4); +} + +TEST_F(DatabaseTest, test_invalid_type_cast) { + SetDefault(); + using tizen_base::_; + tizen_base::Database db(TEST_DB, SQLITE_OPEN_READWRITE); + auto r = db.Exec({ Q_SELECT }); + + EXPECT_TRUE(r); + auto cnt = r.GetColumnCount(); + EXPECT_EQ(cnt, 4); + + for (const auto& i : r) { + auto t = i.Get(0); + EXPECT_EQ(t.GetType(), SQLITE_TEXT); + + bool error = false; + try { + int name = static_cast(i.Get(0)); + (void)name; + } catch (const tizen_base::DbException&) { + error = true; + } + + EXPECT_TRUE(error); + } +} + +TEST_F(DatabaseTest, test_get_string) { + SetDefault(); + using tizen_base::_; + tizen_base::Database db(TEST_DB, SQLITE_OPEN_READWRITE); + auto r = db.Exec({ Q_SELECT }); + + EXPECT_TRUE(r); + auto cnt = r.GetColumnCount(); + EXPECT_EQ(cnt, 4); + + for (const auto& i : r) { + auto t = i.Get(1); + EXPECT_EQ(t.GetType(), SQLITE_INTEGER); + + auto val = i.GetString(1); + EXPECT_TRUE(val); + EXPECT_EQ(*val, "1234"); + } +} \ No newline at end of file diff --git a/tizen-database/database.hpp b/tizen-database/database.hpp index 88cb2a6..d69c378 100644 --- a/tizen-database/database.hpp +++ b/tizen-database/database.hpp @@ -79,17 +79,28 @@ class DbException : public std::runtime_error { class AutoDbType { public: AutoDbType() = default; - explicit AutoDbType(DbType db_type) : db_type_(db_type) {} + explicit AutoDbType(DbType db_type, int real_type) + : db_type_(db_type), real_type_(real_type) {} + + int GetType() const { + return real_type_; + } explicit operator int () { if (!db_type_) throw DbException("invalid type conversion from nullopt to int"); + if (real_type_ != SQLITE_INTEGER) + throw DbException("invalid type conversion to int"); + return std::get(*db_type_); } explicit operator int64_t () { if (!db_type_) - throw DbException("invalid type conversion from nullopt to int"); + throw DbException("invalid type conversion from nullopt to int64_t"); + if (real_type_ != SQLITE_INTEGER) + throw DbException("invalid type conversion to int64_t"); + return std::get(*db_type_); } @@ -99,6 +110,9 @@ class AutoDbType { "invalid type conversion from nullopt to string"); } + if (real_type_ != SQLITE_TEXT) + throw DbException("invalid type conversion to string"); + return std::get(*db_type_); } @@ -108,6 +122,9 @@ class AutoDbType { "invalid type conversion from nullopt to double"); } + if (real_type_ != SQLITE_FLOAT) + throw DbException("invalid type conversion to double"); + return std::get(*db_type_); } @@ -117,41 +134,60 @@ class AutoDbType { "invalid type conversion from nullopt to std::vector"); } + if (real_type_ != SQLITE_BLOB) + throw DbException("invalid type conversion to std::vector"); + return std::get>(*db_type_); } operator std::optional () { if (!db_type_) return std::nullopt; + if (real_type_ != SQLITE_INTEGER) + throw DbException("invalid type conversion to int"); + return std::get(*db_type_); } operator std::optional () { if (!db_type_) return std::nullopt; + if (real_type_ != SQLITE_INTEGER) + throw DbException("invalid type conversion to int64_t"); + return std::get(*db_type_); } operator std::optional () { if (!db_type_) return std::nullopt; + if (real_type_ != SQLITE_TEXT) + throw DbException("invalid type conversion to string"); + return std::get(*db_type_); } operator std::optional () { if (!db_type_) return std::nullopt; + if (real_type_ != SQLITE_FLOAT) + throw DbException("invalid type conversion to double"); + return std::get(*db_type_); } operator std::optional> () { if (!db_type_) return std::nullopt; + if (real_type_ != SQLITE_BLOB) + throw DbException("invalid type conversion to std::vector"); + return std::get>(*db_type_); } private: DbType db_type_; + int real_type_; }; using _ = AutoDbType; @@ -435,6 +471,16 @@ class Database { public: explicit Record(const sqlite3_stmt* stmt) : stmt_(stmt) {} + std::optional GetString(int pos) const { + sqlite3_stmt* stmt = const_cast(stmt_); + const char* text = reinterpret_cast( + sqlite3_column_text(stmt, pos)); + if (!text) + return std::nullopt; + + return text; + } + AutoDbType Get(int pos) const { sqlite3_stmt* stmt = const_cast(stmt_); int type = sqlite3_column_type(stmt, pos); @@ -463,7 +509,7 @@ class Database { throw DbException("invalid column type", type); } - return AutoDbType(dbt); + return AutoDbType(dbt, type); } template @@ -594,6 +640,10 @@ class Database { is_done_ = is_done; } + size_t GetColumnCount() const { + return sqlite3_column_count(stmt_); + } + private: friend class Database; Result(sqlite3_stmt* stmt, sqlite3* db, std::string query, bool is_done) -- 2.7.4