diff options
Diffstat (limited to 'include/fud_sqlite.hpp')
-rw-r--r-- | include/fud_sqlite.hpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/include/fud_sqlite.hpp b/include/fud_sqlite.hpp index 7ab3ef8..4f4c60f 100644 --- a/include/fud_sqlite.hpp +++ b/include/fud_sqlite.hpp @@ -21,7 +21,6 @@ #include <fud_result.hpp> #include <fud_status.hpp> #include <fud_string.hpp> -#include <memory> #include <sqlite3.h> namespace fud { @@ -66,11 +65,23 @@ class SqliteDb { bool revalidate(); + Result<SqliteStatement, FudStatus> prepare(const String& sql); + FudStatus exec( const String& statement, int (*callback)(void*, int, char**, char**), void* context, - std::unique_ptr<SqliteErrorMsg> errorMessage); + Option<SqliteErrorMsg&>& errorMessage); + + template <typename T> + FudStatus bind(SqliteStatement& statement, int index, T value); + + FudStatus step(SqliteStatement& statement); + + Result<int32_t, FudStatus> columnInt32(SqliteStatement& statement, int index); + Result<int64_t, FudStatus> columnInt64(SqliteStatement& statement, int index); + Result<double, FudStatus> columnDouble(SqliteStatement& statement, int index); + Result<StringView, FudStatus> columnText(SqliteStatement& statement, int index); [[nodiscard]] constexpr int errorCode() const { @@ -90,8 +101,6 @@ class SqliteDb { [[nodiscard]] int open(); - Result<SqliteStatement, FudStatus> prepare(const String& sql); - // private data members String m_name{}; @@ -124,8 +133,6 @@ class SqliteStatement { sqlite3_stmt* statement(); - int step(); - FudStatus reset(); [[nodiscard]] constexpr int errorCode() const @@ -139,7 +146,6 @@ class SqliteStatement { } private: - String m_input{}; const char* m_tail{nullptr}; FudStatus m_status{FudStatus::ObjectInvalid}; int m_errorCode{0}; @@ -158,10 +164,45 @@ class SqliteErrorMsg { SqliteErrorMsg& operator=(const SqliteErrorMsg&) = delete; SqliteErrorMsg& operator=(SqliteErrorMsg&& rhs) noexcept; + void setMessage(char* newMessage); + + [[nodiscard]] const char* message() const + { + return m_errorMsg; + } + private: char* m_errorMsg{nullptr}; }; +template <typename T> +FudStatus SqliteDb::bind(SqliteStatement& statement, int index, T value) +{ + static_assert(std::is_same_v<T, int32_t>|| std::is_same_v<T, int64_t> || std::is_same_v<T, double> || std::is_same_v<T, StringView>); + if (index < 0) { + return FudStatus::ArgumentInvalid; + } + if constexpr (std::is_same_v<T, int32_t>) { + m_errorCode = sqlite3_bind_int(statement.statement(), index, value); + } else if constexpr (std::is_same_v<T, int64_t>) { + m_errorCode = sqlite3_bind_int64(statement.statement(), index, value); + } else if constexpr (std::is_same_v<T, double>) { + m_errorCode = sqlite3_bind_double(statement.statement(), index, value); + } else if constexpr (std::is_same_v<T, StringView>) { + if (value.length() > std::numeric_limits<int>::max()) { + return FudStatus::ArgumentInvalid; + } + int stringLength = static_cast<int>(value.length()); + m_errorCode = ::sqlite3_bind_text(statement.statement(), index, value.c_str(), stringLength, nullptr); + } else { + return FudStatus::Failure; + } + if (m_errorCode != SQLITE_OK) { + return FudStatus::Failure; + } + return FudStatus::Success; +} + } // namespace fud #endif |