Lightweight 0.20260921.0
Loading...
Searching...
No Matches
Migrate.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "../DataMapper/BelongsTo.hpp"
6#include "../DataMapper/Field.hpp"
7#include "../DataMapper/Record.hpp"
8#include "../Utils.hpp"
9#include "Core.hpp"
10#include "MigrationPlan.hpp"
11
12#include <reflection-cpp/reflection.hpp>
13
14namespace Lightweight
15{
16
17/// @brief Index type for simplified CreateIndex API.
18/// @ingroup QueryBuilder
19enum class IndexType : std::uint8_t
20{
21 NonUnique, ///< Regular (non-unique) index
22 Unique ///< Unique index
23};
24
25/// @brief Query builder for building CREATE TABLE queries.
26///
27/// @see SqlQueryBuilder
28/// @ingroup QueryBuilder
29class [[nodiscard]] SqlCreateTableQueryBuilder final
30{
31 public:
32 /// Constructs a CREATE TABLE query builder.
33 explicit SqlCreateTableQueryBuilder(SqlCreateTablePlan& plan):
34 _plan { plan }
35 {
36 }
37
38 /// Adds a new column to the table.
40
41 /// Creates a new nullable column.
42 LIGHTWEIGHT_API SqlCreateTableQueryBuilder& Column(std::string columnName, SqlColumnTypeDefinition columnType);
43
44 /// Creates a new column that is non-nullable.
45 LIGHTWEIGHT_API SqlCreateTableQueryBuilder& RequiredColumn(std::string columnName, SqlColumnTypeDefinition columnType);
46
47 /// Adds the created_at and updated_at columns to the table.
49
50 /// Creates a new primary key column.
51 /// Primary keys are always required, unique, have an index, and are non-nullable.
52 LIGHTWEIGHT_API SqlCreateTableQueryBuilder& PrimaryKey(std::string columnName, SqlColumnTypeDefinition columnType);
53
54 /// Creates a new primary key column with auto-increment.
56 std::string columnName, SqlColumnTypeDefinition columnType = SqlColumnTypeDefinitions::Bigint {});
57
58 /// Creates a new nullable foreign key column.
59 LIGHTWEIGHT_API SqlCreateTableQueryBuilder& ForeignKey(std::string columnName,
60 SqlColumnTypeDefinition columnType,
62
63 /// Creates a new non-nullable foreign key column.
64 LIGHTWEIGHT_API SqlCreateTableQueryBuilder& RequiredForeignKey(std::string columnName,
65 SqlColumnTypeDefinition columnType,
67
68 /// Adds a composite foreign key constraint.
69 LIGHTWEIGHT_API SqlCreateTableQueryBuilder& ForeignKey(std::vector<std::string> columns,
70 std::string referencedTableName,
71 std::vector<std::string> referencedColumns);
72
73 /// Enables the UNIQUE constraint on the last declared column.
75
76 /// Enables the INDEX constraint on the last declared column.
78
79 /// Enables the UNIQUE and INDEX constraint on the last declared column and makes it an index.
81
82 private:
83 SqlCreateTablePlan& _plan;
84};
85
86/// @brief Query builder for building ALTER TABLE queries.
87///
88/// @see SqlQueryBuilder
89/// @ingroup QueryBuilder
90class [[nodiscard]] SqlAlterTableQueryBuilder final
91{
92 public:
93 /// Constructs an ALTER TABLE query builder.
95 _plan { plan }
96 {
97 }
98
99 /// Renames the table.
100 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& RenameTo(std::string_view newTableName);
101
102 /// Adds a new column to the table that is non-nullable.
103 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddColumn(std::string columnName, SqlColumnTypeDefinition columnType);
104
105 /// Adds a new column to the table that is non-nullable.
106 ///
107 /// @tparam MemberPointer The pointer to the member field in the record.
108 ///
109 /// @see AddColumn(std::string, SqlColumnTypeDefinition)
110 template <auto MemberPointer>
112 {
113 return AddColumn(std::string(FieldNameOf<MemberPointer>),
115 }
116
117 /// Adds a new column to the table that is nullable.
118 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddNotRequiredColumn(std::string columnName,
119 SqlColumnTypeDefinition columnType);
120
121 /// Adds a new column to the table that is nullable.
122 ///
123 /// @tparam MemberPointer The pointer to the member field in the record.
124 ///
125 /// @see AddNotRequiredColumn(std::string, SqlColumnTypeDefinition)
126 template <auto MemberPointer>
128 {
129 return AddNotRequiredColumn(std::string(FieldNameOf<MemberPointer>),
131 }
132
133 /// @brief Alters the column to have a new non-nullable type.
134 ///
135 /// @param columnName The name of the column to alter.
136 /// @param columnType The new type of the column.
137 /// @param nullable The new nullable state of the column.
138 ///
139 /// @return The current query builder for chaining.
140 ///
141 /// @see SqlColumnTypeDefinition
142 ///
143 /// @note On SQLite, `ALTER COLUMN` has no native SQL form: it is applied by rebuilding the table,
144 /// which only happens through @ref SqlMigration::MigrationManager. Executing the generated `ToSql()`
145 /// text yourself (the formatter emits a `-- LIGHTWEIGHT_SQLITE_GUARD:` sentinel comment for SQLite)
146 /// would silently do nothing — apply the migration via the manager, as shown below.
147 ///
148 /// @code
149 /// auto widen = SqlMigration::Migration<202602010001>(
150 /// "widen column",
151 /// [](SqlMigrationQueryBuilder& plan) {
152 /// plan.AlterTable("Table").AlterColumn("column", Integer {}, SqlNullable::NotNull);
153 /// },
154 /// [](SqlMigrationQueryBuilder&) {});
155 ///
156 /// auto& manager = SqlMigration::MigrationManager::GetInstance();
157 /// manager.CreateMigrationHistory();
158 /// manager.ApplyPendingMigrations();
159 /// @endcode
160 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AlterColumn(std::string columnName,
161 SqlColumnTypeDefinition columnType,
162 SqlNullable nullable);
163
164 /// Renames a column.
165 /// @param oldColumnName The old column name.
166 /// @param newColumnName The new column name.
167 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& RenameColumn(std::string_view oldColumnName, std::string_view newColumnName);
168
169 /// Drops a column from the table.
170 /// @param columnName The name of the column to drop.
171 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& DropColumn(std::string_view columnName);
172
173 /// Adds a new column to the table only if it does not already exist.
174 ///
175 /// @note Database support varies:
176 /// - PostgreSQL: Native IF NOT EXISTS support
177 /// - SQL Server: Uses conditional IF NOT EXISTS query
178 /// - SQLite: Limited support (may require raw SQL)
179 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddColumnIfNotExists(std::string columnName,
180 SqlColumnTypeDefinition columnType);
181
182 /// Adds a new nullable column to the table only if it does not already exist.
183 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddNotRequiredColumnIfNotExists(std::string columnName,
184 SqlColumnTypeDefinition columnType);
185
186 /// Drops a column from the table only if it exists.
187 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& DropColumnIfExists(std::string_view columnName);
188
189 /// Add an index to the table for the specified column.
190 /// @param columnName The name of the column to index.
191 ///
192 /// @code
193 /// SqlQueryBuilder q;
194 /// q.Migration().AlterTable("Table").AddIndex("column");
195 /// // Will execute CREATE INDEX "Table_column_index" ON "Table" ("column");
196 /// @endcode
197 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddIndex(std::string_view columnName);
198
199 /// Add an index to the table for the specified column that is unique.
200 /// @param columnName The name of the column to index.
201 ///
202 /// @code
203 /// SqlQueryBuilder q;
204 /// q.Migration().AlterTable("Table").AddUniqueIndex("column");
205 /// // Will execute CREATE UNIQUE INDEX "Table_column_index" ON "Table" ("column");
206 /// @endcode
207 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddUniqueIndex(std::string_view columnName);
208
209 /// Drop an index from the table for the specified column.
210 /// @param columnName The name of the column to drop the index from.
211 ///
212 /// @code
213 /// SqlQueryBuilder q;
214 /// q.Migration().AlterTable("Table").DropIndex("column");
215 /// // Will execute DROP INDEX "Table_column_index";
216 /// @endcode
217 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& DropIndex(std::string_view columnName);
218
219 /// Drop an index from the table only if it exists.
220 /// @param columnName The name of the column to drop the index from.
221 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& DropIndexIfExists(std::string_view columnName);
222
223 /// Adds a foreign key column @p columnName to @p referencedColumn to an existing column.
224 ///
225 /// @param columnName The name of the column to add.
226 /// @param referencedColumn The column to reference.
227 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddForeignKey(std::string columnName,
228 SqlForeignKeyReferenceDefinition referencedColumn);
229
230 /// Adds a foreign key column @p columnName of type @p columnType to @p referencedColumn.
231 ///
232 /// @param columnName The name of the column to add.
233 /// @param columnType The type of the column to add.
234 /// @param referencedColumn The column to reference.
235 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddForeignKeyColumn(std::string columnName,
236 SqlColumnTypeDefinition columnType,
237 SqlForeignKeyReferenceDefinition referencedColumn);
238
239 /// Adds a nullable foreign key column @p columnName of type @p columnType to @p referencedColumn.
240 ///
241 /// @param columnName The name of the column to add.
242 /// @param columnType The type of the column to add.
243 /// @param referencedColumn The column to reference.
245 std::string columnName, SqlColumnTypeDefinition columnType, SqlForeignKeyReferenceDefinition referencedColumn);
246
247 /// Drops a foreign key for the column @p columnName from the table.
248 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& DropForeignKey(std::string columnName);
249
250 /// Adds a composite foreign key constraint.
251 ///
252 /// @param columns The columns in the current table.
253 /// @param referencedTableName The referenced table name.
254 /// @param referencedColumns The referenced columns in the referenced table.
255 LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddCompositeForeignKey(std::vector<std::string> columns,
256 std::string referencedTableName,
257 std::vector<std::string> referencedColumns);
258
259 private:
260 SqlAlterTablePlan& _plan;
261};
262
263namespace detail
264{
265 template <typename Record>
266 void PopulateCreateTableBuilder(SqlCreateTableQueryBuilder& builder)
267 {
268 static_assert(DataMapperRecord<Record>, "Record must satisfy DataMapperRecord");
269
270#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
271 constexpr auto ctx = std::meta::access_context::current();
272 template for (constexpr auto el: define_static_array(nonstatic_data_members_of(^^Record, ctx)))
273 {
274 using FieldType = typename[:std::meta::type_of(el):];
275 if constexpr (FieldWithStorage<FieldType>)
276 {
277 if constexpr (IsAutoIncrementPrimaryKey<FieldType>)
279 std::string(FieldNameOf<el>),
280 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
281 else if constexpr (FieldType::IsPrimaryKey)
282 builder.PrimaryKey(std::string(FieldNameOf<el>),
283 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
284 else if constexpr (IsBelongsTo<FieldType>)
285 {
286 constexpr size_t referencedFieldIndex = []() constexpr -> size_t {
287 auto index = size_t(-1);
288 EnumerateRecordMembers<typename FieldType::ReferencedRecord>(
289 [&index]<size_t J, typename ReferencedFieldType>() constexpr -> void {
290 if constexpr (IsField<ReferencedFieldType>)
291 if constexpr (ReferencedFieldType::IsPrimaryKey)
292 index = J;
293 });
294 return index;
295 }();
296 builder.ForeignKey(
297 std::string(FieldNameOf<el>),
298 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value,
299 SqlForeignKeyReferenceDefinition {
300 .tableName = std::string { RecordTableName<typename FieldType::ReferencedRecord> },
301 .columnName = std::string { FieldNameOf<FieldType::ReferencedField> } });
302 // A foreign key is the column every HasMany load filters on, and none of the
303 // supported engines indexes one implicitly - only MySQL does. Without this the
304 // relation query is a full table scan per owner, which measured 36x slower on
305 // SQLite (6270 ms vs 174 ms for 1000 owners x 10 children).
306 builder.Index();
307 }
308 else if constexpr (FieldType::IsMandatory)
309 builder.RequiredColumn(std::string(FieldNameOf<el>),
310 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
311 else
312 builder.Column(std::string(FieldNameOf<el>),
313 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
314 }
315 }
316#else
317 EnumerateRecordMembers<Record>([&builder]<size_t I, typename FieldType>() {
318 if constexpr (FieldWithStorage<FieldType>)
319 {
320 if constexpr (IsAutoIncrementPrimaryKey<FieldType>)
322 std::string(FieldNameAt<I, Record>()),
323 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
324 else if constexpr (FieldType::IsPrimaryKey)
325 builder.PrimaryKey(std::string(FieldNameAt<I, Record>()),
326 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
327 else if constexpr (IsBelongsTo<FieldType>)
328 {
329 constexpr size_t referencedFieldIndex = []() constexpr -> size_t {
330 auto index = size_t(-1);
331 EnumerateRecordMembers<typename FieldType::ReferencedRecord>(
332 [&index]<size_t J, typename ReferencedFieldType>() constexpr -> void {
333 if constexpr (IsField<ReferencedFieldType>)
334 if constexpr (ReferencedFieldType::IsPrimaryKey)
335 index = J;
336 });
337 return index;
338 }();
339 builder.ForeignKey(
340 std::string(FieldNameAt<I, Record>()),
341 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value,
342 SqlForeignKeyReferenceDefinition {
343 .tableName = std::string { RecordTableName<typename FieldType::ReferencedRecord> },
344 .columnName =
345 std::string { FieldNameAt<referencedFieldIndex, typename FieldType::ReferencedRecord>() } });
346 // See the comment in the reflection branch above: an unindexed foreign key turns
347 // every HasMany load into a full table scan.
348 builder.Index();
349 }
350 else if constexpr (FieldType::IsMandatory)
351 builder.RequiredColumn(std::string(FieldNameAt<I, Record>()),
352 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
353 else
354 builder.Column(std::string(FieldNameAt<I, Record>()),
355 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
356 }
357 });
358#endif
359 }
360} // namespace detail
361
362/// @brief Query builder for building INSERT queries in migrations.
363///
364/// @see SqlMigrationQueryBuilder
365/// @ingroup QueryBuilder
366class [[nodiscard]] SqlMigrationInsertBuilder final
367{
368 public:
369 /// Constructs a migration INSERT builder.
371 _plan { plan }
372 {
373 }
374
375 /// Sets a column value for the INSERT.
376 template <typename T>
377 SqlMigrationInsertBuilder& Set(std::string columnName, T const& value)
378 {
379 _plan.columns.emplace_back(std::move(columnName), SqlVariant(value));
380 return *this;
381 }
382
383 private:
384 SqlInsertDataPlan& _plan;
385};
386
387/// @brief Query builder for building UPDATE queries in migrations.
388///
389/// @see SqlMigrationQueryBuilder
390/// @ingroup QueryBuilder
391class [[nodiscard]] SqlMigrationUpdateBuilder final
392{
393 public:
394 /// Constructs a migration UPDATE builder.
396 _plan { plan }
397 {
398 }
399
400 /// Sets a column value for the UPDATE.
401 template <typename T>
402 SqlMigrationUpdateBuilder& Set(std::string columnName, T const& value)
403 {
404 _plan.setColumns.emplace_back(std::move(columnName), SqlVariant(value));
405 return *this;
406 }
407
408 /// @brief Sets a column to a raw SQL expression — for column-to-column copies
409 /// or arithmetic that cannot be represented as a literal value.
410 ///
411 /// @param columnName The target column.
412 /// @param expression The raw SQL fragment (e.g. `"OTHER_COL"`, `"CTR" + 1`) emitted
413 /// verbatim after the `=`. The caller is responsible for any
414 /// identifier quoting.
415 SqlMigrationUpdateBuilder& SetExpression(std::string columnName, std::string expression)
416 {
417 _plan.setExpressions.emplace_back(std::move(columnName), std::move(expression));
418 return *this;
419 }
420
421 /// Adds a WHERE condition to the UPDATE.
422 template <typename T>
423 SqlMigrationUpdateBuilder& Where(std::string columnName, std::string op, T const& value)
424 {
425 _plan.whereColumn = std::move(columnName);
426 _plan.whereOp = std::move(op);
427 _plan.whereValue = SqlVariant(value);
428 return *this;
429 }
430
431 /// @brief Supplies a pre-rendered WHERE-clause body for cases that don't fit the
432 /// simple `(column, op, value)` form — composite `AND`/`OR`/`NOT`, `IS NULL`,
433 /// `IN (subquery)`, `EXISTS (subquery)`, etc.
434 ///
435 /// The text is emitted verbatim after `WHERE` at execution time; the caller is
436 /// responsible for dialect-safe quoting.
437 /// @param expression Pre-rendered SQL clause body (without the leading `WHERE`).
439 {
440 _plan.whereExpression = std::move(expression);
441 return *this;
442 }
443
444 private:
445 SqlUpdateDataPlan& _plan;
446};
447
448/// @brief Query builder for building DELETE queries in migrations.
449///
450/// @see SqlMigrationQueryBuilder
451/// @ingroup QueryBuilder
452class [[nodiscard]] SqlMigrationDeleteBuilder final
453{
454 public:
455 /// Constructs a migration DELETE builder.
457 _plan { plan }
458 {
459 }
460
461 /// Adds a WHERE condition to the DELETE.
462 template <typename T>
463 SqlMigrationDeleteBuilder& Where(std::string columnName, std::string op, T const& value)
464 {
465 _plan.whereColumn = std::move(columnName);
466 _plan.whereOp = std::move(op);
467 _plan.whereValue = SqlVariant(value);
468 return *this;
469 }
470
471 /// Pre-rendered WHERE-clause body. See `SqlMigrationUpdateBuilder::WhereExpression`.
473 {
474 _plan.whereExpression = std::move(expression);
475 return *this;
476 }
477
478 private:
479 SqlDeleteDataPlan& _plan;
480};
481
482/// @brief Query builder for building SQL migration queries.
483/// @ingroup QueryBuilder
484class [[nodiscard]] SqlMigrationQueryBuilder final
485{
486 public:
487 /// Constructs a migration query builder.
488 explicit SqlMigrationQueryBuilder(SqlQueryFormatter const& formatter):
489 _formatter { formatter },
490 _migrationPlan { .formatter = formatter }
491 {
492 }
493
494 /// Sets the schema name for the migration.
495 LIGHTWEIGHT_API SqlMigrationQueryBuilder& WithSchema(std::string schemaName);
496
497 /// Creates a new database.
498 LIGHTWEIGHT_API SqlMigrationQueryBuilder& CreateDatabase(std::string_view databaseName);
499
500 /// Drops a database.
501 LIGHTWEIGHT_API SqlMigrationQueryBuilder& DropDatabase(std::string_view databaseName);
502
503 /// Creates a new table.
504 LIGHTWEIGHT_API SqlCreateTableQueryBuilder CreateTable(std::string_view tableName);
505
506 /// Creates a new table only if it does not already exist.
507 ///
508 /// @note Database support:
509 /// - SQLite: Native CREATE TABLE IF NOT EXISTS
510 /// - PostgreSQL: Native CREATE TABLE IF NOT EXISTS
511 /// - SQL Server: Uses conditional IF NOT EXISTS block
512 LIGHTWEIGHT_API SqlCreateTableQueryBuilder CreateTableIfNotExists(std::string_view tableName);
513
514 /// Alters an existing table.
515 LIGHTWEIGHT_API SqlAlterTableQueryBuilder AlterTable(std::string_view tableName);
516
517 /// Drops a table.
518 LIGHTWEIGHT_API SqlMigrationQueryBuilder& DropTable(std::string_view tableName);
519
520 /// Drops a table if it exists.
521 LIGHTWEIGHT_API SqlMigrationQueryBuilder& DropTableIfExists(std::string_view tableName);
522
523 /// Drops a table and all foreign key constraints referencing it.
524 /// On PostgreSQL, uses CASCADE. On MS SQL, drops FK constraints first.
525 LIGHTWEIGHT_API SqlMigrationQueryBuilder& DropTableCascade(std::string_view tableName);
526
527 /// Creates a new table for the given record type.
528 template <typename Record>
530 {
531 static_assert(DataMapperRecord<Record>, "Record must satisfy DataMapperRecord");
532
533 auto builder = CreateTable(RecordTableName<Record>);
534 detail::PopulateCreateTableBuilder<Record>(builder);
535 return builder;
536 }
537
538 /// Alters an existing table.
539 template <typename Record>
541 {
542 static_assert(DataMapperRecord<Record>, "Record must satisfy DataMapperRecord");
543 return AlterTable(RecordTableName<Record>);
544 }
545
546 /// Executes raw SQL.
547 LIGHTWEIGHT_API SqlMigrationQueryBuilder& RawSql(std::string_view sql);
548
549 /// Creates an index on a table.
550 ///
551 /// @param indexName The name of the index to create.
552 /// @param tableName The name of the table to create the index on.
553 /// @param columns The columns to include in the index.
554 /// @param unique If true, creates a UNIQUE index.
555 ///
556 /// @code
557 /// SqlQueryBuilder q;
558 /// q.Migration().CreateIndex("idx_user_email", "users", {"email"});
559 /// // Will execute CREATE INDEX "idx_user_email" ON "users" ("email");
560 /// @endcode
561 LIGHTWEIGHT_API SqlMigrationQueryBuilder& CreateIndex(std::string indexName,
562 std::string tableName,
563 std::vector<std::string> columns,
564 bool unique = false);
565
566 /// Creates a unique index on a table.
567 ///
568 /// @param indexName The name of the index to create.
569 /// @param tableName The name of the table to create the index on.
570 /// @param columns The columns to include in the index.
571 LIGHTWEIGHT_API SqlMigrationQueryBuilder& CreateUniqueIndex(std::string indexName,
572 std::string tableName,
573 std::vector<std::string> columns);
574
575 /// Creates an index on a table with auto-generated name.
576 ///
577 /// The index name is automatically generated as `idx_{tableName}_{col1}_{col2}_...`
578 ///
579 /// @param tableName The name of the table to create the index on.
580 /// @param columns The columns to include in the index.
581 /// @param type The type of index (NonUnique or Unique).
582 ///
583 /// @code
584 /// SqlQueryBuilder q;
585 /// q.Migration().CreateIndex("users", {"email"}, IndexType::Unique);
586 /// // Will execute CREATE UNIQUE INDEX "idx_users_email" ON "users" ("email");
587 /// @endcode
588 LIGHTWEIGHT_API SqlMigrationQueryBuilder& CreateIndex(std::string tableName,
589 std::vector<std::string> columns,
591
592 /// Creates an INSERT statement for the migration.
593 LIGHTWEIGHT_API SqlMigrationInsertBuilder Insert(std::string_view tableName);
594
595 /// Creates an UPDATE statement for the migration.
596 LIGHTWEIGHT_API SqlMigrationUpdateBuilder Update(std::string_view tableName);
597
598 /// Creates a DELETE statement for the migration.
599 LIGHTWEIGHT_API SqlMigrationDeleteBuilder Delete(std::string_view tableName);
600
601 /// Executes SQL interactively via a callback.
602 LIGHTWEIGHT_API SqlMigrationQueryBuilder& Native(std::function<std::string(SqlConnection&)> callback);
603
604 /// Starts a transaction.
606
607 /// Commits a transaction.
609
610 /// Gets the migration plan.
611 [[nodiscard]] LIGHTWEIGHT_API SqlMigrationPlan const& GetPlan() const&;
612
613 /// Gets the migration plan.
614 ///
615 /// @note This method is destructive and will invalidate the current builder.
616 LIGHTWEIGHT_API SqlMigrationPlan GetPlan() &&;
617
618 private:
619 SqlQueryFormatter const& _formatter;
620 std::string _schemaName;
621 SqlMigrationPlan _migrationPlan;
622};
623
624} // namespace Lightweight
Query builder for building ALTER TABLE queries.
Definition Migrate.hpp:91
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & DropIndex(std::string_view columnName)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & DropIndexIfExists(std::string_view columnName)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & DropColumn(std::string_view columnName)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddColumn(std::string columnName, SqlColumnTypeDefinition columnType)
Adds a new column to the table that is non-nullable.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & RenameColumn(std::string_view oldColumnName, std::string_view newColumnName)
SqlAlterTableQueryBuilder & AddColumn()
Definition Migrate.hpp:111
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & RenameTo(std::string_view newTableName)
Renames the table.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddIndex(std::string_view columnName)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddNotRequiredForeignKeyColumn(std::string columnName, SqlColumnTypeDefinition columnType, SqlForeignKeyReferenceDefinition referencedColumn)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddNotRequiredColumn(std::string columnName, SqlColumnTypeDefinition columnType)
Adds a new column to the table that is nullable.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddUniqueIndex(std::string_view columnName)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & DropColumnIfExists(std::string_view columnName)
Drops a column from the table only if it exists.
SqlAlterTableQueryBuilder(SqlAlterTablePlan &plan)
Constructs an ALTER TABLE query builder.
Definition Migrate.hpp:94
SqlAlterTableQueryBuilder & AddNotRequiredColumn()
Definition Migrate.hpp:127
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & DropForeignKey(std::string columnName)
Drops a foreign key for the column columnName from the table.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AlterColumn(std::string columnName, SqlColumnTypeDefinition columnType, SqlNullable nullable)
Alters the column to have a new non-nullable type.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddForeignKey(std::string columnName, SqlForeignKeyReferenceDefinition referencedColumn)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddColumnIfNotExists(std::string columnName, SqlColumnTypeDefinition columnType)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddNotRequiredColumnIfNotExists(std::string columnName, SqlColumnTypeDefinition columnType)
Adds a new nullable column to the table only if it does not already exist.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddForeignKeyColumn(std::string columnName, SqlColumnTypeDefinition columnType, SqlForeignKeyReferenceDefinition referencedColumn)
LIGHTWEIGHT_API SqlAlterTableQueryBuilder & AddCompositeForeignKey(std::vector< std::string > columns, std::string referencedTableName, std::vector< std::string > referencedColumns)
Represents a connection to a SQL database.
Query builder for building CREATE TABLE queries.
Definition Migrate.hpp:30
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & ForeignKey(std::vector< std::string > columns, std::string referencedTableName, std::vector< std::string > referencedColumns)
Adds a composite foreign key constraint.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & Timestamps()
Adds the created_at and updated_at columns to the table.
SqlCreateTableQueryBuilder(SqlCreateTablePlan &plan)
Constructs a CREATE TABLE query builder.
Definition Migrate.hpp:33
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & RequiredColumn(std::string columnName, SqlColumnTypeDefinition columnType)
Creates a new column that is non-nullable.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & RequiredForeignKey(std::string columnName, SqlColumnTypeDefinition columnType, SqlForeignKeyReferenceDefinition foreignKey)
Creates a new non-nullable foreign key column.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & ForeignKey(std::string columnName, SqlColumnTypeDefinition columnType, SqlForeignKeyReferenceDefinition foreignKey)
Creates a new nullable foreign key column.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & Index()
Enables the INDEX constraint on the last declared column.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & UniqueIndex()
Enables the UNIQUE and INDEX constraint on the last declared column and makes it an index.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & PrimaryKey(std::string columnName, SqlColumnTypeDefinition columnType)
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & Column(SqlColumnDeclaration column)
Adds a new column to the table.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & Column(std::string columnName, SqlColumnTypeDefinition columnType)
Creates a new nullable column.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & PrimaryKeyWithAutoIncrement(std::string columnName, SqlColumnTypeDefinition columnType=SqlColumnTypeDefinitions::Bigint {})
Creates a new primary key column with auto-increment.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder & Unique()
Enables the UNIQUE constraint on the last declared column.
Query builder for building DELETE queries in migrations.
Definition Migrate.hpp:453
SqlMigrationDeleteBuilder & Where(std::string columnName, std::string op, T const &value)
Adds a WHERE condition to the DELETE.
Definition Migrate.hpp:463
SqlMigrationDeleteBuilder(SqlDeleteDataPlan &plan)
Constructs a migration DELETE builder.
Definition Migrate.hpp:456
SqlMigrationDeleteBuilder & WhereExpression(std::string expression)
Pre-rendered WHERE-clause body. See SqlMigrationUpdateBuilder::WhereExpression.
Definition Migrate.hpp:472
Query builder for building INSERT queries in migrations.
Definition Migrate.hpp:367
SqlMigrationInsertBuilder(SqlInsertDataPlan &plan)
Constructs a migration INSERT builder.
Definition Migrate.hpp:370
SqlMigrationInsertBuilder & Set(std::string columnName, T const &value)
Sets a column value for the INSERT.
Definition Migrate.hpp:377
Query builder for building SQL migration queries.
Definition Migrate.hpp:485
LIGHTWEIGHT_API SqlCreateTableQueryBuilder CreateTable(std::string_view tableName)
Creates a new table.
SqlCreateTableQueryBuilder CreateTable()
Creates a new table for the given record type.
Definition Migrate.hpp:529
LIGHTWEIGHT_API SqlMigrationQueryBuilder & CommitTransaction()
Commits a transaction.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & RawSql(std::string_view sql)
Executes raw SQL.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & CreateIndex(std::string indexName, std::string tableName, std::vector< std::string > columns, bool unique=false)
LIGHTWEIGHT_API SqlMigrationDeleteBuilder Delete(std::string_view tableName)
Creates a DELETE statement for the migration.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder AlterTable(std::string_view tableName)
Alters an existing table.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder CreateTableIfNotExists(std::string_view tableName)
LIGHTWEIGHT_API SqlMigrationPlan const & GetPlan() const &
Gets the migration plan.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & DropTable(std::string_view tableName)
Drops a table.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & CreateIndex(std::string tableName, std::vector< std::string > columns, IndexType type=IndexType::NonUnique)
LIGHTWEIGHT_API SqlMigrationUpdateBuilder Update(std::string_view tableName)
Creates an UPDATE statement for the migration.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & WithSchema(std::string schemaName)
Sets the schema name for the migration.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & CreateUniqueIndex(std::string indexName, std::string tableName, std::vector< std::string > columns)
LIGHTWEIGHT_API SqlMigrationInsertBuilder Insert(std::string_view tableName)
Creates an INSERT statement for the migration.
SqlAlterTableQueryBuilder AlterTable()
Alters an existing table.
Definition Migrate.hpp:540
LIGHTWEIGHT_API SqlMigrationQueryBuilder & BeginTransaction()
Starts a transaction.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & DropTableCascade(std::string_view tableName)
SqlMigrationQueryBuilder(SqlQueryFormatter const &formatter)
Constructs a migration query builder.
Definition Migrate.hpp:488
LIGHTWEIGHT_API SqlMigrationQueryBuilder & DropDatabase(std::string_view databaseName)
Drops a database.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & Native(std::function< std::string(SqlConnection &)> callback)
Executes SQL interactively via a callback.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & DropTableIfExists(std::string_view tableName)
Drops a table if it exists.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & CreateDatabase(std::string_view databaseName)
Creates a new database.
Query builder for building UPDATE queries in migrations.
Definition Migrate.hpp:392
SqlMigrationUpdateBuilder & Where(std::string columnName, std::string op, T const &value)
Adds a WHERE condition to the UPDATE.
Definition Migrate.hpp:423
SqlMigrationUpdateBuilder & WhereExpression(std::string expression)
Supplies a pre-rendered WHERE-clause body for cases that don't fit the simple (column,...
Definition Migrate.hpp:438
SqlMigrationUpdateBuilder & Set(std::string columnName, T const &value)
Sets a column value for the UPDATE.
Definition Migrate.hpp:402
SqlMigrationUpdateBuilder & SetExpression(std::string columnName, std::string expression)
Sets a column to a raw SQL expression — for column-to-column copies or arithmetic that cannot be repr...
Definition Migrate.hpp:415
SqlMigrationUpdateBuilder(SqlUpdateDataPlan &plan)
Constructs a migration UPDATE builder.
Definition Migrate.hpp:395
API to format SQL queries for different SQL dialects.
Represents a record type that can be used with the DataMapper.
Definition Record.hpp:52
std::remove_cvref_t< decltype(std::declval< MemberClassType< decltype(Field)> >().*Field)>::ValueType ReferencedFieldTypeOf
Retrieves the type of a member field in a record.
Definition Field.hpp:396
IndexType
Index type for simplified CreateIndex API.
Definition Migrate.hpp:20
constexpr auto SqlColumnTypeDefinitionOf
Represents a SQL column type definition of T.
@ NonUnique
Regular (non-unique) index.
@ Unique
Unique index.
Represents a SQL ALTER TABLE plan on a given table.
Represents a SQL column declaration.
Represents a SQL DELETE data plan for migrations.
Represents a foreign key reference definition.
Represents a SQL INSERT data plan for migrations.
Represents a SQL migration plan.
Represents a SQL UPDATE data plan for migrations.
Represents a value that can be any of the supported SQL data types.