Lightweight 0.20250904.0
Loading...
Searching...
No Matches
MigrationPlan.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "../Api.hpp"
6#include "../SqlColumnTypeDefinitions.hpp"
7#include "../SqlDataBinder.hpp"
8#include "../Utils.hpp"
9
10#include <reflection-cpp/reflection.hpp>
11
12#include <string>
13#include <string_view>
14#include <variant>
15#include <vector>
16
17namespace Lightweight
18{
19
20class SqlQueryFormatter;
21
22namespace detail
23{
24
25 template <typename T>
26 struct SqlColumnTypeDefinitionOf
27 {
28 static_assert(AlwaysFalse<T>, "Unsupported type for SQL column definition.");
29 };
30
31 template <>
32 struct SqlColumnTypeDefinitionOf<bool>
33 {
34 static constexpr auto value = SqlColumnTypeDefinitions::Bool {};
35 };
36
37 template <>
38 struct SqlColumnTypeDefinitionOf<char>
39 {
40 static constexpr auto value = SqlColumnTypeDefinitions::Char { 1 };
41 };
42
43 template <>
44 struct SqlColumnTypeDefinitionOf<SqlDate>
45 {
46 static constexpr auto value = SqlColumnTypeDefinitions::Date {};
47 };
48
49 template <>
50 struct SqlColumnTypeDefinitionOf<SqlDateTime>
51 {
52 static constexpr auto value = SqlColumnTypeDefinitions::DateTime {};
53 };
54
55 template <>
56 struct SqlColumnTypeDefinitionOf<SqlTime>
57 {
58 static constexpr auto value = SqlColumnTypeDefinitions::Time {};
59 };
60
61 template <size_t Precision, size_t Scale>
62 struct SqlColumnTypeDefinitionOf<SqlNumeric<Precision, Scale>>
63 {
64 static constexpr auto value = SqlColumnTypeDefinitions::Decimal { .precision = Precision, .scale = Scale };
65 };
66
67 template <>
68 struct SqlColumnTypeDefinitionOf<SqlGuid>
69 {
70 static constexpr auto value = SqlColumnTypeDefinitions::Guid {};
71 };
72
73 template <typename T>
74 requires(detail::OneOf<T, int16_t, uint16_t>)
75 struct SqlColumnTypeDefinitionOf<T>
76 {
77 static constexpr auto value = SqlColumnTypeDefinitions::Smallint {};
78 };
79
80 template <typename T>
81 requires(detail::OneOf<T, int32_t, uint32_t>)
82 struct SqlColumnTypeDefinitionOf<T>
83 {
84 static constexpr auto value = SqlColumnTypeDefinitions::Integer {};
85 };
86
87 template <typename T>
88 requires(detail::OneOf<T, int64_t, uint64_t>)
89 struct SqlColumnTypeDefinitionOf<T>
90 {
91 static constexpr auto value = SqlColumnTypeDefinitions::Bigint {};
92 };
93
94 template <typename T>
95 requires(detail::OneOf<T, float, double>)
96 struct SqlColumnTypeDefinitionOf<T>
97 {
98 static constexpr auto value = SqlColumnTypeDefinitions::Real {};
99 };
100
101 template <size_t N, typename CharT>
102 requires(detail::OneOf<CharT, char>)
103 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::VARIABLE_SIZE>>
104 {
105 static constexpr auto value = SqlColumnTypeDefinitions::Varchar { N };
106 };
107
108 template <size_t N, typename CharT>
109 requires(detail::OneOf<CharT, char16_t, char32_t, wchar_t>)
110 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::VARIABLE_SIZE>>
111 {
112 static constexpr auto value = SqlColumnTypeDefinitions::NVarchar { N };
113 };
114
115 template <size_t N, typename CharT>
116 requires(detail::OneOf<CharT, char>)
117 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::FIXED_SIZE>>
118 {
119 static constexpr auto value = SqlColumnTypeDefinitions::Char { N };
120 };
121
122 template <size_t N, typename CharT>
123 requires(detail::OneOf<CharT, char16_t, char32_t, wchar_t>)
124 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::FIXED_SIZE>>
125 {
126 static constexpr auto value = SqlColumnTypeDefinitions::NChar { N };
127 };
128
129 template <size_t N, typename CharT>
130 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::FIXED_SIZE_RIGHT_TRIMMED>>
131 {
132 static constexpr auto value = SqlColumnTypeDefinitions::Char { N };
133 };
134
135 template <size_t N, typename CharT>
136 requires(detail::OneOf<CharT, char16_t, char32_t, wchar_t>)
137 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::FIXED_SIZE_RIGHT_TRIMMED>>
138 {
139 static constexpr auto value = SqlColumnTypeDefinitions::NChar { N };
140 };
141
142 template <size_t N, typename CharT>
143 requires(detail::OneOf<CharT, char>)
144 struct SqlColumnTypeDefinitionOf<SqlDynamicString<N, CharT>>
145 {
146 static constexpr auto value = SqlColumnTypeDefinitions::Varchar { N };
147 };
148
149 template <size_t N, typename CharT>
150 requires(detail::OneOf<CharT, char8_t, char16_t, char32_t, wchar_t>)
151 struct SqlColumnTypeDefinitionOf<SqlDynamicString<N, CharT>>
152 {
153 static constexpr auto value = SqlColumnTypeDefinitions::NVarchar { N };
154 };
155
156 template <typename T>
157 struct SqlColumnTypeDefinitionOf<std::optional<T>>
158 {
159 static constexpr auto value = SqlColumnTypeDefinitionOf<T>::value;
160 };
161
162} // namespace detail
163
164/// @brief Represents a SQL column type definition of T.
165///
166/// @ingroup QueryBuilder
167template <typename T>
168constexpr auto SqlColumnTypeDefinitionOf = detail::SqlColumnTypeDefinitionOf<T>::value;
169
170/// @brief Represents a primary key type.
171///
172/// This enumeration represents the primary key type of a column.
173///
174/// @ingroup QueryBuilder
175enum class SqlPrimaryKeyType : uint8_t
176{
177 NONE,
178 MANUAL,
179 AUTO_INCREMENT,
180 GUID,
181};
182
183/// @brief Represents a foreign key reference definition.
184///
185/// @ingroup QueryBuilder
187{
188 /// The table name that the foreign key references.
189 std::string tableName;
190
191 /// The column name that the foreign key references.
192 std::string columnName;
193};
194
195/// @brief Represents a SQL column declaration.
196///
197/// @ingroup QueryBuilder
199{
200 /// The name of the column.
201 std::string name;
202
203 /// The type of the column.
204 SqlColumnTypeDefinition type;
205
206 /// The primary key type of the column.
207 SqlPrimaryKeyType primaryKey { SqlPrimaryKeyType::NONE };
208
209 /// The foreign key reference definition of the column.
210 std::optional<SqlForeignKeyReferenceDefinition> foreignKey {};
211
212 /// Indicates if the column is required (non-nullable).
213 bool required { false };
214
215 /// Indicates if the column is unique.
216 bool unique { false };
217
218 /// Indicates if the column is indexed.
219 bool index { false };
220};
221
222struct SqlCreateTablePlan
223{
224 std::string tableName;
225 std::vector<SqlColumnDeclaration> columns;
226};
227
228enum class SqlNullable : uint8_t
229{
230 NotNull,
231 Null,
232};
233
234namespace SqlAlterTableCommands
235{
236
237 struct RenameTable
238 {
239 std::string_view newTableName;
240 };
241
242 struct AddColumn
243 {
244 std::string columnName;
245 SqlColumnTypeDefinition columnType;
246 SqlNullable nullable = SqlNullable::Null;
247 };
248
249 struct AlterColumn
250 {
251 std::string columnName;
252 SqlColumnTypeDefinition columnType;
253 SqlNullable nullable = SqlNullable::Null;
254 };
255
256 struct AddIndex
257 {
258 std::string_view columnName;
259 bool unique = false;
260 };
261
262 struct RenameColumn
263 {
264 std::string_view oldColumnName;
265 std::string_view newColumnName;
266 };
267
268 struct DropColumn
269 {
270 std::string_view columnName;
271 };
272
273 struct DropIndex
274 {
275 std::string_view columnName;
276 };
277
278 struct AddForeignKey
279 {
280 std::string columnName;
281 SqlForeignKeyReferenceDefinition referencedColumn;
282 };
283
284 struct DropForeignKey
285 {
286 std::string columnName;
287 };
288
289} // namespace SqlAlterTableCommands
290
291/// @brief Represents a single SQL ALTER TABLE command.
292///
293/// @ingroup QueryBuilder
294using SqlAlterTableCommand = std::variant<SqlAlterTableCommands::RenameTable,
295 SqlAlterTableCommands::AddColumn,
296 SqlAlterTableCommands::AlterColumn,
297 SqlAlterTableCommands::AddIndex,
298 SqlAlterTableCommands::RenameColumn,
299 SqlAlterTableCommands::DropColumn,
300 SqlAlterTableCommands::DropIndex,
301 SqlAlterTableCommands::AddForeignKey,
302 SqlAlterTableCommands::DropForeignKey>;
303
304/// @brief Represents a SQL ALTER TABLE plan on a given table.
305///
306/// @ingroup QueryBuilder
308{
309 /// The name of the table to alter.
310 std::string_view tableName;
311
312 /// The list of commands to execute on the table.
313 std::vector<SqlAlterTableCommand> commands;
314};
315
316/// @brief Represents a SQL DROP TABLE plan.
317///
318/// @ingroup QueryBuilder
320{
321 /// The name of the table to drop.
322 std::string_view tableName;
323};
324
325// clang-format off
326
327/// @brief Represents a single SQL migration plan element.
328///
329/// This variant represents a single SQL migration plan element.
330///
331/// @ingroup QueryBuilder
332using SqlMigrationPlanElement = std::variant<
333 SqlCreateTablePlan,
336>;
337
338// clang-format on
339
340/// Formats the given SQL migration plan element as a list of SQL statements.
341///
342/// @param formatter The SQL query formatter to use.
343/// @param element The SQL migration plan element to format.
344///
345/// @return A list of SQL statements.
346///
347/// @ingroup QueryBuilder
348[[nodiscard]] LIGHTWEIGHT_API std::vector<std::string> ToSql(SqlQueryFormatter const& formatter,
349 SqlMigrationPlanElement const& element);
350
351/// @brief Represents a SQL migration plan.
352///
353/// This structure represents a SQL migration plan that can be executed on a database.
354///
355/// @ingroup QueryBuilder
356struct [[nodiscard]] SqlMigrationPlan
357{
358 SqlQueryFormatter const& formatter;
359 std::vector<SqlMigrationPlanElement> steps {};
360
361 [[nodiscard]] LIGHTWEIGHT_API std::vector<std::string> ToSql() const;
362};
363
364} // namespace Lightweight
API to format SQL queries for different SQL dialects.
Represents a SQL ALTER TABLE plan on a given table.
std::string_view tableName
The name of the table to alter.
std::vector< SqlAlterTableCommand > commands
The list of commands to execute on the table.
Represents a SQL column declaration.
bool required
Indicates if the column is required (non-nullable).
bool index
Indicates if the column is indexed.
SqlColumnTypeDefinition type
The type of the column.
std::string name
The name of the column.
std::optional< SqlForeignKeyReferenceDefinition > foreignKey
The foreign key reference definition of the column.
SqlPrimaryKeyType primaryKey
The primary key type of the column.
bool unique
Indicates if the column is unique.
Represents a SQL DROP TABLE plan.
std::string_view tableName
The name of the table to drop.
Represents a foreign key reference definition.
std::string tableName
The table name that the foreign key references.
std::string columnName
The column name that the foreign key references.
Represents a SQL migration plan.