From 7c6625fc436a83a909552d693e75d839576a80a2 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Fri, 28 Mar 2025 07:19:19 +0100 Subject: [PATCH] Added is_primary and is_nullable --- include/sqlgen/dynamic/types.hpp | 36 ++++++++-------- include/sqlgen/parsing/is_nullable.hpp | 25 +++++++---- include/sqlgen/parsing/to_create_table.hpp | 50 ++++++++++++++++++---- 3 files changed, 77 insertions(+), 34 deletions(-) diff --git a/include/sqlgen/dynamic/types.hpp b/include/sqlgen/dynamic/types.hpp index 54a92f0..b979427 100644 --- a/include/sqlgen/dynamic/types.hpp +++ b/include/sqlgen/dynamic/types.hpp @@ -7,58 +7,60 @@ namespace sqlgen::dynamic::types { struct Properties { - bool primary = false; - bool nullable = false; + bool primary = false; + bool nullable = false; }; // To be used as the default value. -struct Unknown {}; +struct Unknown { + Properties properties; +}; struct Boolean { - Properties properties; + Properties properties; }; struct Float32 { - Properties properties; + Properties properties; }; struct Float64 { - Properties properties; + Properties properties; }; struct Int8 { - Properties properties; + Properties properties; }; struct Int16 { - Properties properties; + Properties properties; }; struct Int32 { - Properties properties; + Properties properties; }; struct Int64 { - Properties properties; + Properties properties; }; struct Text { - Properties properties; + Properties properties; }; struct Timestamp { - std::string tz; - Properties properties; + std::string tz; + Properties properties; }; struct TimestampWithTZ { - std::string tz; - Properties properties; + std::string tz; + Properties properties; }; struct VarChar { - uint16_t length; - Properties properties; + uint16_t length; + Properties properties; }; } // namespace sqlgen::dynamic::types diff --git a/include/sqlgen/parsing/is_nullable.hpp b/include/sqlgen/parsing/is_nullable.hpp index 66373d8..f6e0b15 100644 --- a/include/sqlgen/parsing/is_nullable.hpp +++ b/include/sqlgen/parsing/is_nullable.hpp @@ -5,36 +5,43 @@ #include #include +#include "has_reflection_method.hpp" + namespace sqlgen::parsing { -/// Determines whether a field in a named tuple is required. -/// General case - most fields are required. template -class has_nullopt; +class is_ptr; template -class has_nullopt : public std::false_type {}; +class is_ptr : public std::false_type {}; template -class has_nullopt> : public std::true_type {}; +class is_ptr> : public std::true_type {}; template -class has_nullopt> : public std::true_type {}; +class is_ptr> : public std::true_type {}; template -class has_nullopt> : public std::true_type {}; +class is_optional; + +template +class is_optional : public std::false_type {}; + +template +class is_optional> : public std::true_type {}; template consteval bool is_nullable() { if constexpr (has_reflection_method) { return is_nullable(); } else { - return has_nullopt::value; + return is_ptr>::value || + is_optional>::value; } } template -constexpr bool is_nullable_v = is_nullable>(); +constexpr bool is_nullable_v = is_nullable(); } // namespace sqlgen::parsing diff --git a/include/sqlgen/parsing/to_create_table.hpp b/include/sqlgen/parsing/to_create_table.hpp index fa7171f..f6ecd3f 100644 --- a/include/sqlgen/parsing/to_create_table.hpp +++ b/include/sqlgen/parsing/to_create_table.hpp @@ -11,51 +11,85 @@ #include "../dynamic/CreateTable.hpp" #include "../dynamic/Table.hpp" #include "../dynamic/Type.hpp" +#include "has_reflection_method.hpp" +#include "is_nullable.hpp" +#include "is_primary_key.hpp" namespace sqlgen::parsing { namespace internal { -template -std::string to_name() { - using Name = typename FieldType::Name; +template +std::string to_colname() { return Name().str(); } -template +template dynamic::Type to_type() { - using T = std::remove_cvref_t; - if constexpr (std::is_same_v) { + using T = std::remove_cvref_t; + if constexpr (is_primary_key_v) { + return to_type().visit( + [](auto _t) -> dynamic::Type { + _t.properties.primary = true; + return _t; + }); + + } else if constexpr (is_nullable_v) { + const auto set_nullable = [](auto _t) -> dynamic::Type { + _t.properties.nullable = true; + return _t; + }; + if constexpr (is_ptr::value) { + return to_type().visit(set_nullable); + } else { + return to_type().visit(set_nullable); + } + + } else if constexpr (has_reflection_method_v) { + return to_type(); + + } else if constexpr (std::is_same_v) { return types::Boolean{}; + } else if constexpr (std::is_integral_v && std::is_signed_v) { if constexpr (sizeof(T) == 1) { return types::Int8{}; + } else if constexpr (sizeof(T) == 2) { return types::Int16{}; + } else if constexpr (sizeof(T) == 4) { return types::Int32{}; + } else if constexpr (sizeof(T) == 8) { return types::Int64{}; + } else { static_assert(rfl::always_false_v, "Unsupported signed integer."); } } else if constexpr (std::is_integral_v && !std::is_signed_v) { if constexpr (sizeof(T) == 1) { return types::UInt8{}; + } else if constexpr (sizeof(T) == 2) { return types::UInt16{}; + } else if constexpr (sizeof(T) == 4) { return types::UInt32{}; + } else if constexpr (sizeof(T) == 8) { return types::UInt64{}; + } else { static_assert(rfl::always_false_v, "Unsupported unsigned integer."); } } else if constexpr (std::is_floating_point_v) { if constexpr (sizeof(T) == 4) { return types::Float32{}; + } else if constexpr (sizeof(T) == 8) { return types::Float64{}; + } else { static_assert(rfl::always_false_v, "Unsupported floating point value."); @@ -67,8 +101,8 @@ dynamic::Type to_type() { template dynamic::Column to_column() { - return dynamic::Column{.name = to_name(), - .type = to_type()}; + return dynamic::Column{.name = to_colname(), + .type = to_type()}; } template