Lightweight 0.20260303.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 <cstddef>
13#include <cstdint>
14#include <functional>
15#include <map>
16#include <set>
17#include <string>
18#include <string_view>
19#include <variant>
20#include <vector>
21
22namespace Lightweight
23{
24
25class SqlQueryFormatter;
26
27namespace detail
28{
29
30 template <typename T>
32 {
33 static_assert(AlwaysFalse<T>, "Unsupported type for SQL column definition.");
34 };
35
36 template <>
37 struct SqlColumnTypeDefinitionOf<std::string>
38 {
39 static constexpr auto value = SqlColumnTypeDefinitions::Text {};
40 };
41
42 template <>
43 struct SqlColumnTypeDefinitionOf<bool>
44 {
45 static constexpr auto value = SqlColumnTypeDefinitions::Bool {};
46 };
47
48 template <>
49 struct SqlColumnTypeDefinitionOf<char>
50 {
51 static constexpr auto value = SqlColumnTypeDefinitions::Char { 1 };
52 };
53
54 template <>
55 struct SqlColumnTypeDefinitionOf<SqlDate>
56 {
57 static constexpr auto value = SqlColumnTypeDefinitions::Date {};
58 };
59
60 template <>
61 struct SqlColumnTypeDefinitionOf<SqlDateTime>
62 {
63 static constexpr auto value = SqlColumnTypeDefinitions::DateTime {};
64 };
65
66 template <>
67 struct SqlColumnTypeDefinitionOf<SqlTime>
68 {
69 static constexpr auto value = SqlColumnTypeDefinitions::Time {};
70 };
71
72 template <size_t Precision, size_t Scale>
73 struct SqlColumnTypeDefinitionOf<SqlNumeric<Precision, Scale>>
74 {
75 static constexpr auto value = SqlColumnTypeDefinitions::Decimal { .precision = Precision, .scale = Scale };
76 };
77
78 template <>
79 struct SqlColumnTypeDefinitionOf<SqlGuid>
80 {
81 static constexpr auto value = SqlColumnTypeDefinitions::Guid {};
82 };
83
84 template <typename T>
85 requires(detail::OneOf<T, int16_t, uint16_t>)
86 struct SqlColumnTypeDefinitionOf<T>
87 {
88 static constexpr auto value = SqlColumnTypeDefinitions::Smallint {};
89 };
90
91 template <typename T>
92 requires(detail::OneOf<T, int32_t, uint32_t>)
93 struct SqlColumnTypeDefinitionOf<T>
94 {
95 static constexpr auto value = SqlColumnTypeDefinitions::Integer {};
96 };
97
98 template <typename T>
99 requires(detail::OneOf<T, int64_t, uint64_t>)
100 struct SqlColumnTypeDefinitionOf<T>
101 {
102 static constexpr auto value = SqlColumnTypeDefinitions::Bigint {};
103 };
104
105 template <typename T>
106 requires(detail::OneOf<T, float, double>)
107 struct SqlColumnTypeDefinitionOf<T>
108 {
109 static constexpr auto value = SqlColumnTypeDefinitions::Real {};
110 };
111
112 template <size_t N, typename CharT>
113 requires(detail::OneOf<CharT, char>)
114 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::VARIABLE_SIZE>>
115 {
116 static constexpr auto value = SqlColumnTypeDefinitions::Varchar { N };
117 };
118
119 template <size_t N, typename CharT>
120 requires(detail::OneOf<CharT, char16_t, char32_t, wchar_t>)
121 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::VARIABLE_SIZE>>
122 {
123 static constexpr auto value = SqlColumnTypeDefinitions::NVarchar { N };
124 };
125
126 template <size_t N, typename CharT>
127 requires(detail::OneOf<CharT, char>)
128 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::FIXED_SIZE>>
129 {
130 static constexpr auto value = SqlColumnTypeDefinitions::Char { N };
131 };
132
133 template <size_t N, typename CharT>
134 requires(detail::OneOf<CharT, char16_t, char32_t, wchar_t>)
135 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::FIXED_SIZE>>
136 {
137 static constexpr auto value = SqlColumnTypeDefinitions::NChar { N };
138 };
139
140 template <size_t N, typename CharT>
141 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::FIXED_SIZE_RIGHT_TRIMMED>>
142 {
143 static constexpr auto value = SqlColumnTypeDefinitions::Char { N };
144 };
145
146 template <size_t N, typename CharT>
147 requires(detail::OneOf<CharT, char16_t, char32_t, wchar_t>)
148 struct SqlColumnTypeDefinitionOf<SqlFixedString<N, CharT, SqlFixedStringMode::FIXED_SIZE_RIGHT_TRIMMED>>
149 {
150 static constexpr auto value = SqlColumnTypeDefinitions::NChar { N };
151 };
152
153 template <size_t N, typename CharT>
154 requires(detail::OneOf<CharT, char>)
155 struct SqlColumnTypeDefinitionOf<SqlDynamicString<N, CharT>>
156 {
157 static constexpr auto value = SqlColumnTypeDefinitions::Varchar { N };
158 };
159
160 template <size_t N, typename CharT>
161 requires(detail::OneOf<CharT, char8_t, char16_t, char32_t, wchar_t>)
162 struct SqlColumnTypeDefinitionOf<SqlDynamicString<N, CharT>>
163 {
164 static constexpr auto value = SqlColumnTypeDefinitions::NVarchar { N };
165 };
166
167 template <typename T>
168 struct SqlColumnTypeDefinitionOf<std::optional<T>>
169 {
170 static constexpr auto value = SqlColumnTypeDefinitionOf<T>::value;
171 };
172
173 template <>
174 struct SqlColumnTypeDefinitionOf<SqlText>
175 {
176 static constexpr auto value = SqlColumnTypeDefinitions::Text {};
177 };
178
179 template <size_t N>
180 struct SqlColumnTypeDefinitionOf<SqlDynamicBinary<N>>
181 {
182 static constexpr auto value = SqlColumnTypeDefinitions::VarBinary { N };
183 };
184
185} // namespace detail
186
187/// @brief Represents a SQL column type definition of T.
188///
189/// @ingroup QueryBuilder
190template <typename T>
191constexpr auto SqlColumnTypeDefinitionOf = detail::SqlColumnTypeDefinitionOf<T>::value;
192
193/// @brief Represents a primary key type.
194///
195/// This enumeration represents the primary key type of a column.
196///
197/// @ingroup QueryBuilder
198enum class SqlPrimaryKeyType : uint8_t
199{
200 NONE,
201 MANUAL,
202 AUTO_INCREMENT,
203 GUID,
204};
205
206/// @brief Represents a foreign key reference definition.
207///
208/// @ingroup QueryBuilder
210{
211 /// The table name that the foreign key references.
212 std::string tableName;
213
214 /// The column name that the foreign key references.
215 std::string columnName;
216};
217
218/// @brief Represents a SQL column declaration.
219///
220/// @ingroup QueryBuilder
222{
223 /// The name of the column.
224 std::string name;
225
226 /// The type of the column.
227 SqlColumnTypeDefinition type;
228
229 /// The primary key type of the column.
230 SqlPrimaryKeyType primaryKey { SqlPrimaryKeyType::NONE };
231
232 /// The foreign key reference definition of the column.
233 std::optional<SqlForeignKeyReferenceDefinition> foreignKey {};
234
235 /// Indicates if the column is required (non-nullable).
236 bool required { false };
237
238 /// Indicates if the column is unique.
239 bool unique { false };
240
241 /// The default value of the column.
242 std::string defaultValue {};
243
244 /// Indicates if the column is indexed.
245 bool index { false };
246
247 /// The 1-based index in the primary key (0 if not part of a specific order).
248 uint16_t primaryKeyIndex { 0 };
249};
250
251/// @brief Represents a composite foreign key constraint.
252///
253/// @ingroup QueryBuilder
255{
256 /// The columns in the current table.
257 std::vector<std::string> columns;
258
259 /// The referenced table name.
261
262 /// The referenced columns in the referenced table.
263 std::vector<std::string> referencedColumns;
264};
265
266struct SqlCreateTablePlan
267{
268 std::string schemaName;
269 std::string tableName;
270 std::vector<SqlColumnDeclaration> columns;
271 std::vector<SqlCompositeForeignKeyConstraint> foreignKeys;
272 bool ifNotExists { false }; ///< If true, generates CREATE TABLE IF NOT EXISTS.
273};
274
275namespace SqlAlterTableCommands
276{
277
278 struct RenameTable
279 {
280 std::string_view newTableName;
281 };
282
283 struct AddColumn
284 {
285 std::string columnName;
286 SqlColumnTypeDefinition columnType;
287 SqlNullable nullable = SqlNullable::Null;
288 };
289
290 struct AlterColumn
291 {
292 std::string columnName;
293 SqlColumnTypeDefinition columnType;
294 SqlNullable nullable = SqlNullable::Null;
295 };
296
297 struct AddIndex
298 {
299 std::string_view columnName;
300 bool unique = false;
301 };
302
303 struct RenameColumn
304 {
305 std::string_view oldColumnName;
306 std::string_view newColumnName;
307 };
308
309 struct DropColumn
310 {
311 std::string_view columnName;
312 };
313
314 struct DropIndex
315 {
316 std::string_view columnName;
317 };
318
319 struct AddForeignKey
320 {
321 std::string columnName;
322 SqlForeignKeyReferenceDefinition referencedColumn;
323 };
324
325 struct AddCompositeForeignKey
326 {
327 std::vector<std::string> columns;
328 std::string referencedTableName;
329 std::vector<std::string> referencedColumns;
330 };
331
332 struct DropForeignKey
333 {
334 std::string columnName;
335 };
336
337 /// Adds a column only if it does not already exist.
339 {
340 /// The name of the column to add.
341 std::string columnName;
342 /// The type of the column to add.
343 SqlColumnTypeDefinition columnType;
344 /// Whether the column is nullable.
345 SqlNullable nullable = SqlNullable::Null;
346 };
347
348 /// Drops a column only if it exists.
350 {
351 /// The name of the column to drop.
352 std::string columnName;
353 };
354
355 /// Drops an index only if it exists.
357 {
358 /// The name of the column whose index to drop.
359 std::string columnName;
360 };
361
362} // namespace SqlAlterTableCommands
363
364/// @brief Represents a single SQL ALTER TABLE command.
365///
366/// @ingroup QueryBuilder
367using SqlAlterTableCommand = std::variant<SqlAlterTableCommands::RenameTable,
368 SqlAlterTableCommands::AddColumn,
370 SqlAlterTableCommands::AlterColumn,
371 SqlAlterTableCommands::AddIndex,
372 SqlAlterTableCommands::RenameColumn,
373 SqlAlterTableCommands::DropColumn,
375 SqlAlterTableCommands::DropIndex,
377 SqlAlterTableCommands::AddForeignKey,
378 SqlAlterTableCommands::AddCompositeForeignKey,
379 SqlAlterTableCommands::DropForeignKey>;
380
381/// @brief Represents a SQL ALTER TABLE plan on a given table.
382///
383/// @ingroup QueryBuilder
385{
386 /// The schema name of the table to alter.
387 std::string_view schemaName;
388
389 /// The name of the table to alter.
390 std::string_view tableName;
391
392 /// The list of commands to execute on the table.
393 std::vector<SqlAlterTableCommand> commands;
394};
395
396/// @brief Represents a SQL DROP TABLE plan.
397///
398/// @ingroup QueryBuilder
400{
401 /// The schema name of the table to drop.
402 std::string_view schemaName;
403
404 /// The name of the table to drop.
405 std::string_view tableName;
406
407 /// If true, generates DROP TABLE IF EXISTS instead of DROP TABLE.
408 bool ifExists { false };
409
410 /// If true, drops all foreign key constraints referencing this table first.
411 /// On PostgreSQL, uses CASCADE. On MS SQL, drops FK constraints explicitly.
412 bool cascade { false };
413};
414
415/// @brief Represents a raw SQL plan.
416///
417/// @ingroup QueryBuilder
419{
420 /// The raw SQL to execute.
421 std::string_view sql;
422};
423
424/// @brief Represents a SQL INSERT data plan for migrations.
425///
426/// This structure represents an INSERT statement for a migration plan.
427///
428/// @ingroup QueryBuilder
430{
431 /// The schema name of the table to insert into.
432 std::string schemaName;
433
434 /// The name of the table to insert into.
435 std::string tableName;
436
437 /// The columns and their values to insert.
438 std::vector<std::pair<std::string, SqlVariant>> columns;
439};
440
441/// @brief Represents a SQL UPDATE data plan for migrations.
442///
443/// This structure represents an UPDATE statement for a migration plan.
444///
445/// @ingroup QueryBuilder
447{
448 /// The schema name of the table to update.
449 std::string schemaName;
450
451 /// The name of the table to update.
452 std::string tableName;
453
454 /// The columns and their values to set.
455 std::vector<std::pair<std::string, SqlVariant>> setColumns;
456
457 /// @brief Column-to-expression assignments that cannot be represented as a literal value.
458 ///
459 /// Each entry is `(column name, raw SQL expression)`. The expression is emitted verbatim
460 /// after `"col" = ` at SQL-rendering time — used for things like `set TARGET = SOURCE` or
461 /// `set CTR = CTR + 1` where the RHS references another column or contains arithmetic.
462 /// Entries here are appended to the SET clause after `setColumns`.
463 std::vector<std::pair<std::string, std::string>> setExpressions;
464
465 /// The column name for the WHERE clause.
466 std::string whereColumn;
467
468 /// The comparison operator for the WHERE clause (e.g., "=", "<>", etc.).
469 std::string whereOp;
470
471 /// The value for the WHERE clause.
473
474 /// @brief Pre-rendered WHERE-clause body (the text after `WHERE`), used when the
475 /// condition cannot be expressed with the simple `(whereColumn op whereValue)`
476 /// triple — e.g. composite `AND`/`OR`/`NOT`, `IS NULL`, `IN (subquery)`, or
477 /// `EXISTS (subquery)`. When non-empty, this takes precedence over the
478 /// structured triple at SQL-emission time.
479 std::string whereExpression;
480};
481
482/// @brief Represents a SQL DELETE data plan for migrations.
483///
484/// This structure represents a DELETE statement for a migration plan.
485///
486/// @ingroup QueryBuilder
488{
489 /// The schema name of the table to delete from.
490 std::string schemaName;
491
492 /// The name of the table to delete from.
493 std::string tableName;
494
495 /// The column name for the WHERE clause.
496 std::string whereColumn;
497
498 /// The comparison operator for the WHERE clause (e.g., "=", "<>", etc.).
499 std::string whereOp;
500
501 /// The value for the WHERE clause.
503
504 /// Pre-rendered WHERE-clause body. See `SqlUpdateDataPlan::whereExpression`.
505 std::string whereExpression;
506};
507
508/// @brief Represents a SQL CREATE INDEX plan for migrations.
509///
510/// This structure represents a CREATE INDEX statement for a migration plan.
511///
512/// @ingroup QueryBuilder
514{
515 /// The schema name of the table to create the index on.
516 std::string schemaName;
517
518 /// The name of the index to create.
519 std::string indexName;
520
521 /// The name of the table to create the index on.
522 std::string tableName;
523
524 /// The columns to include in the index.
525 std::vector<std::string> columns;
526
527 /// If true, creates a UNIQUE index.
528 bool unique { false };
529
530 /// If true, generates CREATE INDEX IF NOT EXISTS.
531 bool ifNotExists { false };
532};
533
534// clang-format off
535
536/// @brief Represents a single SQL migration plan element.
537///
538/// This variant represents a single SQL migration plan element.
539///
540/// @ingroup QueryBuilder
541using SqlMigrationPlanElement = std::variant<
542 SqlCreateTablePlan,
550>;
551
552// clang-format on
553
554/// @brief Canonical compat-flag name requesting LUpd-compatible client-side string
555/// truncation. Kept with the consumer (`MigrationRenderContext`) so there is a single
556/// source of truth; `Lightweight::Config::CompatFlagLupTruncate` aliases this value.
557inline constexpr std::string_view CompatFlagLupTruncateName = "lup-truncate";
558
559/// @brief Opt-in behavioural knobs that the `ToSql` migration-plan renderer honours.
560///
561/// When a profile declares a `compat:` flag (see `Lightweight::Config::CompatFlags`), dbtool
562/// / dbtool-gui construct one of these and pass it alongside the formatter so migration
563/// rendering can diverge from strict behaviour per-run.
564///
565/// The context is mutable across successive `ToSql` calls within the same migration run:
566/// it accumulates a column-width cache populated from `CreateTable` / `AlterTable` steps as
567/// they are rendered, so later `Insert` / `Update` steps can truncate oversize values
568/// without a server round-trip.
569///
570/// Default-constructed instances are strict (no truncation, no logging); this is the shape
571/// used by code paths that don't care about compat, so existing callers keep their
572/// behaviour.
573struct [[nodiscard]] MigrationRenderContext
574{
575 /// When true, string values in `Insert` / `Update` steps are truncated to the
576 /// destination column's declared character width and the truncation is logged via
577 /// `SqlLogger::OnWarning`. Mirrors LUpd's client-side clipping behaviour; see
578 /// `Lightweight::Config::CompatFlagLupTruncate`.
579 bool lupTruncate = false;
580
581 /// Per-(schema, table, column) cache of declared character widths. Populated lazily
582 /// from `SqlCreateTablePlan` / `SqlAlterTablePlan` as they are rendered; the key is
583 /// (`schema`, `table`, `column`). A zero/absent entry means "no known width" and the
584 /// truncation layer leaves the value alone.
586 {
587 std::string schema; ///< Schema label (empty for engines without schemas, e.g. SQLite).
588 std::string table; ///< Table name.
589 std::string column; ///< Column name.
590 /// Total ordering on (schema, table, column) — defaulted three-way comparison.
591 auto operator<=>(ColumnKey const&) const = default;
592 };
593
594 /// @brief How a column's declared width is counted. The truncation layer must match
595 /// the server's interpretation: a VARCHAR(100) on MSSQL holds 100 *bytes*, but an
596 /// NVARCHAR(100) holds 100 *characters*. Truncating to 100 characters when the
597 /// server budget is 100 bytes still overflows on multi-byte source data.
598 enum class WidthUnit : uint8_t
599 {
600 Characters,
601 Bytes,
602 };
603
604 struct ColumnWidth
605 {
606 std::size_t value { 0 };
607 WidthUnit unit { WidthUnit::Characters };
608 };
609
610 /// Cache of declared character widths, populated lazily as plan elements render.
611 std::map<ColumnKey, ColumnWidth> columnWidths;
612
613 /// @brief Optional fallback that fetches column widths for a `(schema, table)` from
614 /// the live database when the cache has no entry for it.
615 ///
616 /// The renderer calls this once per `(schema, table)` it can't satisfy from
617 /// `columnWidths`. Implementations should issue a single `INFORMATION_SCHEMA.COLUMNS`
618 /// (or equivalent) query and write every char/varchar column's declared width back
619 /// into `columnWidths`. They may also write a sentinel (e.g. an empty entry) when the
620 /// table doesn't exist, so the renderer doesn't keep retrying. Default-empty means
621 /// "no fallback" — i.e. only widths declared by the same migration plan are
622 /// considered.
623 std::function<void(MigrationRenderContext&, std::string_view /*schema*/, std::string_view /*table*/)> widthLookup;
624
625 /// @brief Tables for which the lookup has already been attempted, so we don't
626 /// re-query for every INSERT against the same table.
627 struct TableKey
628 {
629 std::string schema; ///< Schema label (empty when the engine reports none).
630 std::string table; ///< Table name.
631 /// Total ordering on (schema, table) — defaulted three-way comparison.
632 auto operator<=>(TableKey const&) const = default;
633 };
634 /// Tables for which `widthLookup` has already been called; prevents repeat queries.
635 std::set<TableKey> lookupAttempted;
636
637 /// @brief Identity of the migration currently being rendered. Set by
638 /// `MigrationManager::ApplySingleMigration` before `ToSql` is called for each
639 /// step so warnings (e.g. `lup-truncate`) can attribute themselves to the
640 /// offending migration. Empty / zero when rendering happens outside a migration
641 /// run (e.g. unit tests calling `ToSql` directly).
643 /// Timestamp of the migration currently being rendered (0 outside a migration run).
644 std::uint64_t activeMigrationTimestamp = 0;
645};
646
647/// Formats the given SQL migration plan element as a list of SQL statements.
648///
649/// @param formatter The SQL query formatter to use.
650/// @param element The SQL migration plan element to format.
651///
652/// @return A list of SQL statements.
653///
654/// @ingroup QueryBuilder
655[[nodiscard]] LIGHTWEIGHT_API std::vector<std::string> ToSql(SqlQueryFormatter const& formatter,
656 SqlMigrationPlanElement const& element);
657
658/// @overload
659/// Rendering variant that consults a `MigrationRenderContext` for compat flags
660/// and column-width tracking. Updates `context` in place when the rendered step declares
661/// new columns.
662[[nodiscard]] LIGHTWEIGHT_API std::vector<std::string> ToSql(SqlQueryFormatter const& formatter,
663 SqlMigrationPlanElement const& element,
664 MigrationRenderContext& context);
665
666/// @brief Represents a SQL migration plan.
667///
668/// This structure represents a SQL migration plan that can be executed on a database.
669///
670/// @ingroup QueryBuilder
671struct [[nodiscard]] SqlMigrationPlan
672{
673 /// The SQL query formatter to use.
675 /// The migration plan steps.
676 std::vector<SqlMigrationPlanElement> steps {};
677
678 /// Converts the migration plan to a list of SQL statements.
679 [[nodiscard]] LIGHTWEIGHT_API std::vector<std::string> ToSql() const;
680};
681
682/// @brief Formats the given SQL migration plan as a list of SQL statements.
683///
684/// @param formatter The SQL query formatter to use.
685/// @param plans The SQL migration plans to format.
686///
687/// @return A list of SQL statements.
688///
689/// @ingroup QueryBuilder
690[[nodiscard]] LIGHTWEIGHT_API std::vector<std::string> ToSql(SqlQueryFormatter const& formatter,
691 std::vector<SqlMigrationPlan> const& plans);
692
693} // namespace Lightweight
API to format SQL queries for different SQL dialects.
std::variant< SqlAlterTableCommands::RenameTable, SqlAlterTableCommands::AddColumn, SqlAlterTableCommands::AddColumnIfNotExists, SqlAlterTableCommands::AlterColumn, SqlAlterTableCommands::AddIndex, SqlAlterTableCommands::RenameColumn, SqlAlterTableCommands::DropColumn, SqlAlterTableCommands::DropColumnIfExists, SqlAlterTableCommands::DropIndex, SqlAlterTableCommands::DropIndexIfExists, SqlAlterTableCommands::AddForeignKey, SqlAlterTableCommands::AddCompositeForeignKey, SqlAlterTableCommands::DropForeignKey > SqlAlterTableCommand
Represents a single SQL ALTER TABLE command.
LIGHTWEIGHT_API std::vector< std::string > ToSql(SqlQueryFormatter const &formatter, SqlMigrationPlanElement const &element)
SqlPrimaryKeyType
Represents a primary key type.
std::variant< SqlCreateTablePlan, SqlAlterTablePlan, SqlDropTablePlan, SqlCreateIndexPlan, SqlRawSqlPlan, SqlInsertDataPlan, SqlUpdateDataPlan, SqlDeleteDataPlan > SqlMigrationPlanElement
Represents a single SQL migration plan element.
constexpr auto SqlColumnTypeDefinitionOf
Represents a SQL column type definition of T.
std::string schema
Schema label (empty for engines without schemas, e.g. SQLite).
auto operator<=>(ColumnKey const &) const =default
Total ordering on (schema, table, column) — defaulted three-way comparison.
Tables for which the lookup has already been attempted, so we don't re-query for every INSERT against...
std::string schema
Schema label (empty when the engine reports none).
auto operator<=>(TableKey const &) const =default
Total ordering on (schema, table) — defaulted three-way comparison.
Opt-in behavioural knobs that the ToSql migration-plan renderer honours.
std::string activeMigrationTitle
Identity of the migration currently being rendered. Set by MigrationManager::ApplySingleMigration bef...
std::map< ColumnKey, ColumnWidth > columnWidths
Cache of declared character widths, populated lazily as plan elements render.
WidthUnit
How a column's declared width is counted. The truncation layer must match the server's interpretation...
std::function< void(MigrationRenderContext &, std::string_view, std::string_view)> widthLookup
Optional fallback that fetches column widths for a (schema, table) from the live database when the ca...
std::set< TableKey > lookupAttempted
Tables for which widthLookup has already been called; prevents repeat queries.
Adds a column only if it does not already exist.
SqlNullable nullable
Whether the column is nullable.
SqlColumnTypeDefinition columnType
The type of the column to add.
std::string columnName
The name of the column to add.
std::string columnName
The name of the column to drop.
std::string columnName
The name of the column whose index to drop.
Represents a SQL ALTER TABLE plan on a given table.
std::string_view schemaName
The schema name of the table to alter.
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.
std::string defaultValue
The default value of the column.
bool unique
Indicates if the column is unique.
uint16_t primaryKeyIndex
The 1-based index in the primary key (0 if not part of a specific order).
Represents a composite foreign key constraint.
std::vector< std::string > columns
The columns in the current table.
std::string referencedTableName
The referenced table name.
std::vector< std::string > referencedColumns
The referenced columns in the referenced table.
Represents a SQL CREATE INDEX plan for migrations.
std::vector< std::string > columns
The columns to include in the index.
std::string schemaName
The schema name of the table to create the index on.
bool ifNotExists
If true, generates CREATE INDEX IF NOT EXISTS.
std::string indexName
The name of the index to create.
std::string tableName
The name of the table to create the index on.
bool unique
If true, creates a UNIQUE index.
Represents a SQL DELETE data plan for migrations.
std::string whereExpression
Pre-rendered WHERE-clause body. See SqlUpdateDataPlan::whereExpression.
std::string whereOp
The comparison operator for the WHERE clause (e.g., "=", "<>", etc.).
std::string tableName
The name of the table to delete from.
std::string whereColumn
The column name for the WHERE clause.
std::string schemaName
The schema name of the table to delete from.
SqlVariant whereValue
The value for the WHERE clause.
Represents a SQL DROP TABLE plan.
std::string_view schemaName
The schema name of the table to drop.
std::string_view tableName
The name of the table to drop.
bool ifExists
If true, generates DROP TABLE IF EXISTS instead of DROP TABLE.
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 INSERT data plan for migrations.
std::vector< std::pair< std::string, SqlVariant > > columns
The columns and their values to insert.
std::string schemaName
The schema name of the table to insert into.
std::string tableName
The name of the table to insert into.
Represents a SQL migration plan.
SqlQueryFormatter const & formatter
The SQL query formatter to use.
LIGHTWEIGHT_API std::vector< std::string > ToSql() const
Converts the migration plan to a list of SQL statements.
Represents a raw SQL plan.
std::string_view sql
The raw SQL to execute.
Represents a SQL UPDATE data plan for migrations.
std::string schemaName
The schema name of the table to update.
SqlVariant whereValue
The value for the WHERE clause.
std::string whereExpression
Pre-rendered WHERE-clause body (the text after WHERE), used when the condition cannot be expressed wi...
std::vector< std::pair< std::string, SqlVariant > > setColumns
The columns and their values to set.
std::string tableName
The name of the table to update.
std::string whereOp
The comparison operator for the WHERE clause (e.g., "=", "<>", etc.).
std::vector< std::pair< std::string, std::string > > setExpressions
Column-to-expression assignments that cannot be represented as a literal value.
std::string whereColumn
The column name for the WHERE clause.
Represents a value that can be any of the supported SQL data types.