LibDatabase: Support all C++ integral types in SQL storage

This commit is contained in:
Timothy Flynn 2025-10-07 15:39:00 -04:00 committed by Andreas Kling
parent 187d02c45d
commit 411aed96ab

View file

@ -38,6 +38,21 @@ static constexpr StringView sql_error(int error_code)
} \
})
#define ENUMERATE_SQL_TYPES \
__ENUMERATE_TYPE(String) \
__ENUMERATE_TYPE(UnixDateTime) \
__ENUMERATE_TYPE(i8) \
__ENUMERATE_TYPE(i16) \
__ENUMERATE_TYPE(i32) \
__ENUMERATE_TYPE(long) \
__ENUMERATE_TYPE(long long) \
__ENUMERATE_TYPE(u8) \
__ENUMERATE_TYPE(u16) \
__ENUMERATE_TYPE(u32) \
__ENUMERATE_TYPE(unsigned long) \
__ENUMERATE_TYPE(unsigned long long) \
__ENUMERATE_TYPE(bool)
ErrorOr<NonnullRefPtr<Database>> Database::create(ByteString const& directory, StringView name)
{
TRY(Core::Directory::create(directory, Core::Directory::CreateDirectories::Yes));
@ -107,18 +122,21 @@ void Database::apply_placeholder(StatementID statement_id, int index, ValueType
StringView string { value };
SQL_MUST(sqlite3_bind_text(statement, index, string.characters_without_null_termination(), static_cast<int>(string.length()), SQLITE_TRANSIENT));
} else if constexpr (IsSame<ValueType, UnixDateTime>) {
SQL_MUST(sqlite3_bind_int64(statement, index, value.offset_to_epoch().to_milliseconds()));
} else if constexpr (IsSame<ValueType, int>) {
SQL_MUST(sqlite3_bind_int(statement, index, value));
} else if constexpr (IsSame<ValueType, bool>) {
SQL_MUST(sqlite3_bind_int(statement, index, static_cast<int>(value)));
apply_placeholder(statement_id, index, value.offset_to_epoch().to_milliseconds());
} else if constexpr (IsIntegral<ValueType>) {
if constexpr (sizeof(ValueType) <= sizeof(int))
SQL_MUST(sqlite3_bind_int(statement, index, static_cast<int>(value)));
else
SQL_MUST(sqlite3_bind_int64(statement, index, static_cast<sqlite3_int64>(value)));
} else {
static_assert(DependentFalse<ValueType>);
}
}
template DATABASE_API void Database::apply_placeholder(StatementID, int, String const&);
template DATABASE_API void Database::apply_placeholder(StatementID, int, UnixDateTime const&);
template DATABASE_API void Database::apply_placeholder(StatementID, int, int const&);
template DATABASE_API void Database::apply_placeholder(StatementID, int, bool const&);
#define __ENUMERATE_TYPE(type) \
template DATABASE_API void Database::apply_placeholder(StatementID, int, type const&);
ENUMERATE_SQL_TYPES
#undef __ENUMERATE_TYPE
template<typename ValueType>
ValueType Database::result_column(StatementID statement_id, int column)
@ -129,20 +147,21 @@ ValueType Database::result_column(StatementID statement_id, int column)
auto const* text = reinterpret_cast<char const*>(sqlite3_column_text(statement, column));
return MUST(String::from_utf8(StringView { text, strlen(text) }));
} else if constexpr (IsSame<ValueType, UnixDateTime>) {
auto milliseconds = sqlite3_column_int64(statement, column);
auto milliseconds = result_column<sqlite3_int64>(statement_id, column);
return UnixDateTime::from_milliseconds_since_epoch(milliseconds);
} else if constexpr (IsSame<ValueType, int>) {
return sqlite3_column_int(statement, column);
} else if constexpr (IsSame<ValueType, bool>) {
return static_cast<bool>(sqlite3_column_int(statement, column));
} else if constexpr (IsIntegral<ValueType>) {
if constexpr (sizeof(ValueType) <= sizeof(int))
return static_cast<ValueType>(sqlite3_column_int(statement, column));
else
return static_cast<ValueType>(sqlite3_column_int64(statement, column));
} else {
static_assert(DependentFalse<ValueType>);
}
VERIFY_NOT_REACHED();
}
template DATABASE_API String Database::result_column(StatementID, int);
template DATABASE_API UnixDateTime Database::result_column(StatementID, int);
template DATABASE_API int Database::result_column(StatementID, int);
template DATABASE_API bool Database::result_column(StatementID, int);
#define __ENUMERATE_TYPE(type) \
template DATABASE_API type Database::result_column(StatementID, int);
ENUMERATE_SQL_TYPES
#undef __ENUMERATE_TYPE
}