5#include "../DataMapper/BelongsTo.hpp"
6#include "../DataMapper/Field.hpp"
7#include "../DataMapper/Record.hpp"
10#include "MigrationPlan.hpp"
12#include <reflection-cpp/reflection.hpp>
79 std::string columnName, SqlColumnTypeDefinition columnType = SqlColumnTypeDefinitions::Bigint {});
83 SqlColumnTypeDefinition columnType,
88 SqlColumnTypeDefinition columnType,
93 std::string referencedTableName,
94 std::vector<std::string> referencedColumns);
106 SqlCreateTablePlan& _plan;
133 template <auto MemberPo
inter>
136 return AddColumn(std::string(FieldNameOf<MemberPointer>),
142 SqlColumnTypeDefinition columnType);
149 template <auto MemberPo
inter>
152 return AddNotRequiredColumn(std::string(FieldNameOf<MemberPointer>),
184 SqlColumnTypeDefinition columnType,
185 SqlNullable nullable);
203 SqlColumnTypeDefinition columnType);
207 SqlColumnTypeDefinition columnType);
259 SqlColumnTypeDefinition columnType,
279 std::string referencedTableName,
280 std::vector<std::string> referencedColumns);
288 template <
typename Record>
293#if defined(LIGHTWEIGHT_CXX26_REFLECTION)
294 constexpr auto ctx = std::meta::access_context::current();
295 template for (
constexpr auto el: define_static_array(nonstatic_data_members_of(^^Record, ctx)))
297 using FieldType =
typename[:std::meta::type_of(el):];
300 if constexpr (IsAutoIncrementPrimaryKey<FieldType>)
302 std::string(FieldNameOf<el>),
303 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
304 else if constexpr (FieldType::IsPrimaryKey)
305 builder.
PrimaryKey(std::string(FieldNameOf<el>),
306 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
307 else if constexpr (IsBelongsTo<FieldType>)
309 constexpr size_t referencedFieldIndex = []()
constexpr ->
size_t {
310 auto index = size_t(-1);
311 EnumerateRecordMembers<typename FieldType::ReferencedRecord>(
312 [&index]<
size_t J,
typename ReferencedFieldType>()
constexpr ->
void {
313 if constexpr (IsField<ReferencedFieldType>)
314 if constexpr (ReferencedFieldType::IsPrimaryKey)
320 std::string(FieldNameOf<el>),
321 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value,
322 SqlForeignKeyReferenceDefinition {
323 .tableName = std::string { RecordTableName<typename FieldType::ReferencedRecord> },
324 .columnName = std::string { FieldNameOf<FieldType::ReferencedField> } });
331 else if constexpr (FieldType::IsMandatory)
333 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
335 builder.
Column(std::string(FieldNameOf<el>),
336 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
340 EnumerateRecordMembers<Record>([&builder]<
size_t I,
typename FieldType>() {
341 if constexpr (FieldWithStorage<FieldType>)
343 if constexpr (IsAutoIncrementPrimaryKey<FieldType>)
345 std::string(FieldNameAt<I, Record>()),
346 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
347 else if constexpr (FieldType::IsPrimaryKey)
348 builder.
PrimaryKey(std::string(FieldNameAt<I, Record>()),
349 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
350 else if constexpr (IsBelongsTo<FieldType>)
352 constexpr size_t referencedFieldIndex = []()
constexpr ->
size_t {
353 auto index = size_t(-1);
354 EnumerateRecordMembers<typename FieldType::ReferencedRecord>(
355 [&index]<
size_t J,
typename ReferencedFieldType>()
constexpr ->
void {
356 if constexpr (IsField<ReferencedFieldType>)
357 if constexpr (ReferencedFieldType::IsPrimaryKey)
363 std::string(FieldNameAt<I, Record>()),
364 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value,
365 SqlForeignKeyReferenceDefinition {
366 .tableName = std::string { RecordTableName<typename FieldType::ReferencedRecord> },
368 std::string { FieldNameAt<referencedFieldIndex, typename FieldType::ReferencedRecord>() } });
373 else if constexpr (FieldType::IsMandatory)
375 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
377 builder.
Column(std::string(FieldNameAt<I, Record>()),
378 detail::SqlColumnTypeDefinitionOf<typename FieldType::ValueType>::value);
399 template <
typename T>
402 _plan.columns.emplace_back(std::move(columnName),
SqlVariant(value));
437 template <
typename T>
440 _plan.setColumns.emplace_back(std::move(columnName),
SqlVariant(value));
453 _plan.setExpressions.emplace_back(std::move(columnName), std::move(expression));
458 template <
typename T>
461 _plan.whereColumn = std::move(columnName);
462 _plan.whereOp = std::move(op);
476 _plan.whereExpression = std::move(expression);
498 template <
typename T>
501 _plan.whereColumn = std::move(columnName);
502 _plan.whereOp = std::move(op);
510 _plan.whereExpression = std::move(expression);
525 _formatter { formatter },
526 _migrationPlan { .formatter = formatter }
568 template <
typename Record>
573 auto builder = CreateTable(RecordTableName<Record>);
574 detail::PopulateCreateTableBuilder<Record>(builder);
579 template <
typename Record>
583 return AlterTable(RecordTableName<Record>);
602 std::string tableName,
603 std::vector<std::string> columns,
604 bool unique =
false);
628 std::string tableName,
629 std::vector<std::string> columns,
638 std::string tableName,
639 std::vector<std::string> columns);
655 std::vector<std::string> columns,
683 std::
string _schemaName;
Query builder for building ALTER TABLE queries.
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()
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.
SqlAlterTableQueryBuilder & AddNotRequiredColumn()
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)
Query builder for building CREATE TABLE queries.
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.
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.
SqlMigrationDeleteBuilder & Where(std::string columnName, std::string op, T const &value)
Adds a WHERE condition to the DELETE.
SqlMigrationDeleteBuilder(SqlDeleteDataPlan &plan)
Constructs a migration DELETE builder.
SqlMigrationDeleteBuilder & WhereExpression(std::string expression)
Pre-rendered WHERE-clause body. See SqlMigrationUpdateBuilder::WhereExpression.
Query builder for building INSERT queries in migrations.
SqlMigrationInsertBuilder(SqlInsertDataPlan &plan)
Constructs a migration INSERT builder.
SqlMigrationInsertBuilder & Set(std::string columnName, T const &value)
Sets a column value for the INSERT.
LIGHTWEIGHT_API SqlMigrationInsertBuilder & IfNotExists(std::vector< std::string > keyColumns)
Makes the INSERT skip its row when a row with the same key values already exists.
Query builder for building SQL migration queries.
LIGHTWEIGHT_API SqlCreateTableQueryBuilder CreateTable(std::string_view tableName)
Creates a new table.
SqlCreateTableQueryBuilder CreateTable()
Creates a new table for the given record type.
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)
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.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & BeginTransaction()
Starts a transaction.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & CreateIndex(std::string indexName, std::string tableName, std::vector< std::string > columns, SqlCreateIndexOptions options)
LIGHTWEIGHT_API SqlMigrationQueryBuilder & DropTableCascade(std::string_view tableName)
SqlMigrationQueryBuilder(SqlQueryFormatter const &formatter)
Constructs a migration query builder.
LIGHTWEIGHT_API SqlMigrationQueryBuilder & DropDatabase(std::string_view databaseName)
Drops a database.
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.
SqlMigrationUpdateBuilder & Where(std::string columnName, std::string op, T const &value)
Adds a WHERE condition to the UPDATE.
SqlMigrationUpdateBuilder & WhereExpression(std::string expression)
Supplies a pre-rendered WHERE-clause body for cases that don't fit the simple (column,...
SqlMigrationUpdateBuilder & Set(std::string columnName, T const &value)
Sets a column value for the UPDATE.
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...
SqlMigrationUpdateBuilder(SqlUpdateDataPlan &plan)
Constructs a migration UPDATE builder.
Represents a record type that can be used with the DataMapper.
std::remove_cvref_t< decltype(std::declval< MemberClassType< decltype(Field)> >().*Field)>::ValueType ReferencedFieldTypeOf
Retrieves the type of a member field in a record.
IndexType
Index type for simplified CreateIndex API.
constexpr auto SqlColumnTypeDefinitionOf
Represents a SQL column type definition of T.
@ NonUnique
Regular (non-unique) index.
Represents a SQL ALTER TABLE plan on a given table.
Represents a SQL column declaration.
Optional settings for SqlMigrationQueryBuilder::CreateIndex.
IndexType type
Whether the index enforces uniqueness.
std::string whereExpression
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.