From 2c92e07f337e42cf58970443f9de678f85a9b2a4 Mon Sep 17 00:00:00 2001 From: rtk0c Date: Thu, 19 Oct 2023 22:50:07 -0700 Subject: The great renaming: switch to "module style" --- source/20-codegen-compiler/SQLiteHelper.hpp | 220 ---------------------------- 1 file changed, 220 deletions(-) delete mode 100644 source/20-codegen-compiler/SQLiteHelper.hpp (limited to 'source/20-codegen-compiler/SQLiteHelper.hpp') diff --git a/source/20-codegen-compiler/SQLiteHelper.hpp b/source/20-codegen-compiler/SQLiteHelper.hpp deleted file mode 100644 index c24e476..0000000 --- a/source/20-codegen-compiler/SQLiteHelper.hpp +++ /dev/null @@ -1,220 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct SQLiteDatabase { - sqlite3* database = nullptr; - - ~SQLiteDatabase() { - // NOTE: calling with NULL is a harmless no-op - int result = sqlite3_close(database); - assert(result == SQLITE_OK); - } - - operator sqlite3*() const { return database; } - sqlite3** operator&() { return &database; } -}; - -struct SQLiteStatement { - sqlite3_stmt* stmt = nullptr; - - SQLiteStatement(const SQLiteStatement&) = delete; - SQLiteStatement& operator=(const SQLiteStatement&) = delete; - - SQLiteStatement() = default; - - SQLiteStatement(sqlite3* database, std::string_view sql) { - Initialize(database, sql); - } - - ~SQLiteStatement() { - // NOTE: calling with NULL is a harmless no-op - // NOTE: we don't care about the error code, because they are returned if the statement has errored in the most recent execution - // but deleting it will succeeed anyways - sqlite3_finalize(stmt); - } - - operator sqlite3_stmt*() const { return stmt; } - sqlite3_stmt** operator&() { return &stmt; } - - void Initialize(sqlite3* database, std::string_view sql) { - int result = sqlite3_prepare_v2(database, sql.data(), sql.size(), &stmt, nullptr); - if (result != SQLITE_OK) { - auto msg = fmt::format( - "Failed to prepare SQLite3 statement, error message: {}", - sqlite3_errmsg(sqlite3_db_handle(stmt))); - throw std::runtime_error(msg); - } - } - - bool InitializeLazily(sqlite3* database, std::string_view sql) { - if (!stmt) { - Initialize(database, sql); - return true; - } - return false; - } -}; - -struct SQLiteRunningStatement { - sqlite3_stmt* stmt; - - SQLiteRunningStatement(sqlite3_stmt* stmt) - : stmt{ stmt } { - } - - SQLiteRunningStatement(const SQLiteStatement& stmt) - : stmt{ stmt.stmt } { - } - - ~SQLiteRunningStatement() { - sqlite3_clear_bindings(stmt); - sqlite3_reset(stmt); - } - - void BindArgument(int index, int32_t value) { - sqlite3_bind_int(stmt, index, (int)value); - } - - void BindArgument(int index, uint32_t value) { - sqlite3_bind_int(stmt, index, (int)value); - } - - void BindArgument(int index, int64_t value) { - sqlite3_bind_int64(stmt, index, value); - } - - void BindArgument(int index, uint64_t value) { - sqlite3_bind_int64(stmt, index, (int64_t)value); - } - - void BindArgument(int index, const char* value) { - sqlite3_bind_text(stmt, index, value, -1, nullptr); - } - - void BindArgument(int index, std::string_view value) { - sqlite3_bind_text(stmt, index, value.data(), value.size(), nullptr); - } - - void BindArgument(int index, std::nullptr_t) { - // Noop - } - - template - void BindArguments(Ts&&... args) { - // NOTE: SQLite3 argument index starts at 1 - size_t idx = 1; - auto HandleEachArgument = [this, &idx](T&& arg) { - BindArgument(idx, std::forward(arg)); - ++idx; - }; - (HandleEachArgument(std::forward(args)), ...); - } - - int Step() { - return sqlite3_step(stmt); - } - - void StepAndCheck(int forErr) { - int err = sqlite3_step(stmt); - assert(err == forErr); - } - - int StepAndCheckError() { - int err = sqlite3_step(stmt); - if (err != SQLITE_DONE || err != SQLITE_ROW) { - auto msg = fmt::format( - "Error {} executing SQLite3 statement, error message: {}", - sqlite3_errstr(err), - sqlite3_errmsg(sqlite3_db_handle(stmt))); - throw std::runtime_error(msg); - } - return err; - } - - void StepUntilDone() { - while (true) { - int err = sqlite3_step(stmt); - // SQLITE_OK is never returned for sqlite3_step() //TODO fact check this - if (err == SQLITE_DONE) { - break; - } - if (err == SQLITE_ROW) { - continue; - } - - auto msg = fmt::format( - "Error {} executing SQLite3 statement, error message: {}", - sqlite3_errstr(err), - sqlite3_errmsg(sqlite3_db_handle(stmt))); - throw std::runtime_error(msg); - } - } - - using TimePoint = std::chrono::time_point; - using TpFromUnixTimestamp = std::pair; - using TpFromDateTime = std::pair; - - // TODO replace with overloads? - template - auto ResultColumn(int column) const { - if constexpr (std::is_enum_v) { - auto value = sqlite3_column_int64(stmt, column); - return static_cast(value); - } else if constexpr (std::is_same_v || std::is_same_v) { - return (T)sqlite3_column_int(stmt, column); - } else if constexpr (std::is_same_v) { - return (T)sqlite3_column_int64(stmt, column); - } else if constexpr (std::is_same_v) { - return (const char*)sqlite3_column_text(stmt, column); - } else if constexpr (std::is_same_v || std::is_same_v) { - // SQLite3 uses `unsigned char` to represent UTF-8 code units, on all platforms we care about this is the same as plain `char` - auto cstr = (const char*)sqlite3_column_text(stmt, column); - // For std::string_view, this finds size based on null terminator and stores reference to pointer - // For std::string, this also allocates buffer and copies `cstr` content - return T(cstr); - } else if constexpr (std::is_same_v) { - auto unixTimestamp = sqlite3_column_int64(stmt, column); - auto chrono = std::chrono::seconds(unixTimestamp); - return TimePoint(chrono); - } else if constexpr (std::is_same_v) { - // TODO wait for libstdc++ and libc++ implement c++20 std::chrono addition -#ifdef _MSC_VER - auto datetime = (const char*)sqlite3_column_text(stmt, column); - if (datetime) { - std::stringstream ss(datetime); - TimePoint timepoint; - ss >> std::chrono::parse("%F %T", timepoint); - return timepoint; - } else { - return TimePoint(); - } -#else - static_assert(false && sizeof(T), "Unimplemented"); -#endif - } else { - static_assert(false && sizeof(T), "Unknown type"); - } - } - - template - auto ResultColumns() { - // NOTE: SQLite3 column index starts at 0 - // NOTE: ((size_t)-1) + 1 == 0 - size_t idx = -1; - // NOTE: std::make_tuple() -- variadic template function - // std::tuple() -- CTAD constructor - // Both of these cause make the comma operator unsequenced, not viable here - return std::tuple{ (++idx, ResultColumn(idx))... }; - } -}; -- cgit v1.2.3-70-g09d2