Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
entity.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
7#include "../database_types.h"
9#include <string>
10#include <vector>
11#include <memory>
12#include <type_traits>
13#include <chrono>
14#include <unordered_map>
15#include <functional>
16#include <mutex>
17#include <optional>
18
19namespace database::orm
20{
21 // Forward declarations
22 class entity_base;
23 class field_metadata;
24 class entity_metadata;
25
26 // Type traits for type safety (C++17 compatible)
27 template<typename T, typename = void>
28 struct is_entity : std::false_type {};
29
30 template<typename T>
31 struct is_entity<T, std::void_t<
32 typename T::primary_key_type,
33 decltype(std::declval<T>().table_name()),
34 decltype(std::declval<T>().get_metadata())
35 >> : std::is_convertible<decltype(std::declval<T>().table_name()), std::string> {};
36
37 template<typename T>
38 inline constexpr bool is_entity_v = is_entity<T>::value;
39
40 template<typename T>
41 inline constexpr bool is_field_type_v =
42 std::is_same_v<T, int32_t> ||
43 std::is_same_v<T, int64_t> ||
44 std::is_same_v<T, double> ||
45 std::is_same_v<T, std::string> ||
46 std::is_same_v<T, bool> ||
47 std::is_same_v<T, std::chrono::system_clock::time_point>;
48
49 // Forward declaration with SFINAE constraint
50 template<typename EntityType, typename = std::enable_if_t<is_entity_v<EntityType>>>
51 class query_builder;
52
53 // Field constraint types
54 enum class field_constraint {
55 none = 0,
56 primary_key = 1,
57 not_null = 2,
58 unique = 4,
60 index = 16,
61 foreign_key = 32,
62 default_now = 64
63 };
64
66 return static_cast<field_constraint>(static_cast<int>(a) | static_cast<int>(b));
67 }
68
69 inline bool has_constraint(field_constraint constraints, field_constraint check) {
70 return (static_cast<int>(constraints) & static_cast<int>(check)) != 0;
71 }
72
78 {
79 public:
80 field_metadata(const std::string& name,
81 const std::string& type_name,
83 const std::string& index_name = "",
84 const std::string& foreign_table = "",
85 const std::string& foreign_field = "");
86
87 const std::string& name() const { return name_; }
88 const std::string& type_name() const { return type_name_; }
90 const std::string& index_name() const { return index_name_; }
91 const std::string& foreign_table() const { return foreign_table_; }
92 const std::string& foreign_field() const { return foreign_field_; }
93
101
102 std::string to_sql_definition() const;
103
104 private:
105 std::string name_;
106 std::string type_name_;
108 std::string index_name_;
109 std::string foreign_table_;
110 std::string foreign_field_;
111 };
112
118 {
119 public:
120 entity_metadata(const std::string& table_name);
121
122 void add_field(const field_metadata& field);
123 const std::vector<field_metadata>& fields() const { return fields_; }
124 const std::string& table_name() const { return table_name_; }
125
126 const field_metadata* get_primary_key() const;
127 std::vector<const field_metadata*> get_indexes() const;
128 std::vector<const field_metadata*> get_foreign_keys() const;
129
130 std::string create_table_sql() const;
131 std::string create_indexes_sql() const;
132
133 private:
134 std::string table_name_;
135 std::vector<field_metadata> fields_;
136 };
137
143 {
144 public:
145 virtual ~entity_base() = default;
146 virtual std::string table_name() const = 0;
147 virtual const entity_metadata& get_metadata() const = 0;
148
149 // CRUD operations
150 virtual bool save() = 0;
151 virtual bool load() = 0;
152 virtual bool update() = 0;
153 virtual bool remove() = 0;
154
155 protected:
156 entity_base() = default;
157 };
158
163 template<typename T, typename = std::enable_if_t<is_field_type_v<T>>>
165 {
166 public:
168 : value_(value), metadata_(metadata) {}
169
170 T& get() { return value_; }
171 const T& get() const { return value_; }
172 const field_metadata& metadata() const { return metadata_; }
173
174 field_accessor& operator=(const T& value) {
175 value_ = value;
176 return *this;
177 }
178
179 operator T&() { return value_; }
180 operator const T&() const { return value_; }
181
182 private:
185 };
186
191 template<typename EntityType, typename>
193 {
194 public:
195 query_builder(std::shared_ptr<core::database_backend> db);
196
197 // Query building methods
198 query_builder& where(const std::string& condition);
199 query_builder& order_by(const std::string& field, bool ascending = true);
202
203 // Join operations
204 template<typename OtherEntity>
205 std::enable_if_t<is_entity_v<OtherEntity>, query_builder&> join(const std::string& condition);
206
207 template<typename OtherEntity>
208 std::enable_if_t<is_entity_v<OtherEntity>, query_builder&> left_join(const std::string& condition);
209
210 // Execution methods
211 std::vector<EntityType> execute();
212 std::optional<EntityType> first();
213 size_t count();
214
215 // Aggregation methods
216 double sum(const std::string& field);
217 double avg(const std::string& field);
218 core::database_value min(const std::string& field);
219 core::database_value max(const std::string& field);
220
221 private:
222 std::shared_ptr<core::database_backend> db_;
223 std::string where_clause_;
224 std::string order_clause_;
225 std::string join_clause_;
226 size_t limit_count_ = 0;
227 size_t offset_count_ = 0;
228
229 std::string build_query() const;
230 EntityType map_result_to_entity(const core::database_result& result, size_t row) const;
231 };
232
247 {
248 public:
252 entity_manager() = default;
253
254
255 template<typename EntityType>
256 std::enable_if_t<is_entity_v<EntityType>> register_entity();
257
258 template<typename EntityType>
259 std::enable_if_t<is_entity_v<EntityType>, const entity_metadata&> get_metadata();
260
261 template<typename EntityType>
262 std::enable_if_t<is_entity_v<EntityType>, query_builder<EntityType>> query(std::shared_ptr<core::database_backend> db);
263
264 // Schema operations
265 bool create_tables(std::shared_ptr<core::database_backend> db);
266 bool drop_tables(std::shared_ptr<core::database_backend> db);
267 bool sync_schema(std::shared_ptr<core::database_backend> db);
268
269 private:
270 std::unordered_map<std::string, std::unique_ptr<entity_metadata>> metadata_cache_;
271 };
272
273 // Helper macros for entity definition
274 #define ENTITY_FIELD(type, name, ...) \
275 private: \
276 type name##_; \
277 static inline field_metadata name##_metadata_{#name, #type, __VA_ARGS__}; \
278 public: \
279 field_accessor<type> name{name##_, name##_metadata_}; \
280 static const field_metadata& name##_field() { return name##_metadata_; }
281
282 #define ENTITY_TABLE(table_name) \
283 public: \
284 std::string table_name() const override { return table_name; } \
285 using primary_key_type = decltype(id_); \
286 private: \
287 static inline entity_metadata metadata_{table_name};
288
289 #define ENTITY_METADATA() \
290 public: \
291 const entity_metadata& get_metadata() const override { \
292 static std::once_flag init_flag; \
293 std::call_once(init_flag, [this]() { initialize_metadata(); }); \
294 return metadata_; \
295 } \
296 private: \
297 static void initialize_metadata();
298
299 // Constraint helper functions
305
306 inline field_constraint index(const std::string& name = "") {
308 }
309
310 inline field_constraint foreign_key(const std::string& table, const std::string& field) {
312 }
313
314} // namespace database::orm
Base class for all ORM entities.
Definition entity.h:143
virtual const entity_metadata & get_metadata() const =0
virtual ~entity_base()=default
virtual bool update()=0
virtual bool remove()=0
virtual std::string table_name() const =0
Manages entity metadata and provides factory methods.
Definition entity.h:247
std::enable_if_t< is_entity_v< EntityType > > register_entity()
std::enable_if_t< is_entity_v< EntityType >, const entity_metadata & > get_metadata()
bool drop_tables(std::shared_ptr< core::database_backend > db)
Definition entity.cpp:200
bool sync_schema(std::shared_ptr< core::database_backend > db)
Definition entity.cpp:223
std::unordered_map< std::string, std::unique_ptr< entity_metadata > > metadata_cache_
Definition entity.h:270
std::enable_if_t< is_entity_v< EntityType >, query_builder< EntityType > > query(std::shared_ptr< core::database_backend > db)
bool create_tables(std::shared_ptr< core::database_backend > db)
Definition entity.cpp:166
entity_manager()=default
Default constructor - used by database_context.
Metadata for entire entities including table mapping and relationships.
Definition entity.h:118
std::string create_table_sql() const
Definition entity.cpp:123
void add_field(const field_metadata &field)
Definition entity.cpp:87
std::vector< const field_metadata * > get_foreign_keys() const
Definition entity.cpp:112
std::vector< const field_metadata * > get_indexes() const
Definition entity.cpp:101
std::string create_indexes_sql() const
Definition entity.cpp:146
entity_metadata(const std::string &table_name)
Definition entity.cpp:82
const std::vector< field_metadata > & fields() const
Definition entity.h:123
const field_metadata * get_primary_key() const
Definition entity.cpp:92
std::vector< field_metadata > fields_
Definition entity.h:135
const std::string & table_name() const
Definition entity.h:124
Template class for type-safe field access.
Definition entity.h:165
field_accessor & operator=(const T &value)
Definition entity.h:174
const field_metadata & metadata_
Definition entity.h:184
field_accessor(T &value, const field_metadata &metadata)
Definition entity.h:167
const T & get() const
Definition entity.h:171
const field_metadata & metadata() const
Definition entity.h:172
Metadata for entity fields including constraints and relationships.
Definition entity.h:78
std::string to_sql_definition() const
Definition entity.cpp:39
field_constraint constraints_
Definition entity.h:107
bool is_foreign_key() const
Definition entity.h:99
field_metadata(const std::string &name, const std::string &type_name, field_constraint constraints=field_constraint::none, const std::string &index_name="", const std::string &foreign_table="", const std::string &foreign_field="")
Definition entity.cpp:24
const std::string & index_name() const
Definition entity.h:90
field_constraint constraints() const
Definition entity.h:89
bool is_primary_key() const
Definition entity.h:94
bool is_auto_increment() const
Definition entity.h:97
const std::string & name() const
Definition entity.h:87
const std::string & type_name() const
Definition entity.h:88
bool has_default_now() const
Definition entity.h:100
const std::string & foreign_table() const
Definition entity.h:91
const std::string & foreign_field() const
Definition entity.h:92
Template query builder for type-safe ORM queries.
Definition entity.h:193
query_builder & offset(size_t count)
core::database_value min(const std::string &field)
std::optional< EntityType > first()
core::database_value max(const std::string &field)
query_builder & where(const std::string &condition)
std::shared_ptr< core::database_backend > db_
Definition entity.h:222
EntityType map_result_to_entity(const core::database_result &result, size_t row) const
std::enable_if_t< is_entity_v< OtherEntity >, query_builder & > left_join(const std::string &condition)
std::enable_if_t< is_entity_v< OtherEntity >, query_builder & > join(const std::string &condition)
query_builder(std::shared_ptr< core::database_backend > db)
query_builder & limit(size_t count)
std::vector< EntityType > execute()
query_builder & order_by(const std::string &field, bool ascending=true)
double sum(const std::string &field)
double avg(const std::string &field)
std::string build_query() const
Abstract interface for database backends.
Defines the enumeration of supported database types.
std::vector< database_row > database_result
std::variant< std::string, int64_t, double, bool, std::nullptr_t > database_value
field_constraint operator|(field_constraint a, field_constraint b)
Definition entity.h:65
field_constraint auto_increment()
Definition entity.h:303
field_constraint unique()
Definition entity.h:302
constexpr bool is_entity_v
Definition entity.h:38
field_constraint not_null()
Definition entity.h:301
field_constraint primary_key()
Definition entity.h:300
bool has_constraint(field_constraint constraints, field_constraint check)
Definition entity.h:69
field_constraint default_now()
Definition entity.h:304
constexpr bool is_field_type_v
Definition entity.h:41