diff --git a/src/Migrator.Tests/Providers/Generic/Generic_CopyDataFromTableToTableBase.cs b/src/Migrator.Tests/Providers/Generic/Generic_CopyDataFromTableToTableBase.cs new file mode 100644 index 00000000..9d387916 --- /dev/null +++ b/src/Migrator.Tests/Providers/Generic/Generic_CopyDataFromTableToTableBase.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using System.Data; +using DotNetProjects.Migrator.Framework; +using Migrator.Tests.Providers.Base; +using Migrator.Tests.Providers.Generic.Models; +using NUnit.Framework; + +namespace Migrator.Tests.Providers.Generic; + +public abstract class Generic_CopyDataFromTableToTableBase : TransformationProviderBase +{ + [Test] + public void CopyDataFromTableToTable_Success() + { + // Arrange + const string tableNameSource = "SourceTable"; + const string columnName1Source = "SourceColumn1"; + const string columnName2Source = "SourceColumn2"; + const string columnName3Source = "SourceColumn3"; + + const string tableNameTarget = "TargetTable"; + const string columnName1Target = "TargetColumn1"; + const string columnName2Target = "TargetColumn2"; + const string columnName3Target = "TargetColumn3"; + + Provider.AddTable(tableNameSource, + new Column(columnName1Source, DbType.Int32), + new Column(columnName2Source, DbType.String), + new Column(columnName3Source, DbType.Int32) + ); + + Provider.AddTable(tableNameTarget, + new Column(columnName1Target, DbType.Int32), + new Column(columnName2Target, DbType.String), + new Column(columnName3Target, DbType.Int32) + ); + + Provider.Insert(tableNameSource, [columnName1Source, columnName2Source, columnName3Source], [2, "Hello2", 22]); + Provider.Insert(tableNameSource, [columnName1Source, columnName2Source, columnName3Source], [1, "Hello1", 11]); + + // Act + Provider.CopyDataFromTableToTable( + tableNameSource, + [columnName1Source, columnName2Source, columnName3Source], + tableNameTarget, + [columnName1Target, columnName2Target, columnName3Target], + [columnName1Source]); + + // Assert + List targetRows = []; + using (var cmd = Provider.CreateCommand()) + using (var reader = Provider.Select(cmd, tableNameTarget, [columnName1Target, columnName2Target, columnName3Target])) + { + while (reader.Read()) + { + targetRows.Add(new CopyDataFromTableToTableModel + { + Column1 = reader.GetInt32(0), + Column2 = reader.GetString(1), + Column3 = reader.GetInt32(2), + }); + } + } + + List expectedTargetRows = [ + new CopyDataFromTableToTableModel{ Column1 = 1, Column2 = "Hello1", Column3 = 11 }, + new CopyDataFromTableToTableModel{ Column1 = 2, Column2 = "Hello2", Column3 = 22 }, + ]; + + Assert.That(targetRows, Is.EquivalentTo(expectedTargetRows).Using((x, y) => + x.Column1 == y.Column1 && + x.Column2 == y.Column2 && + x.Column3 == y.Column3)); + } +} \ No newline at end of file diff --git a/src/Migrator.Tests/Providers/Generic/Models/CopyDataFromTableToTableModel.cs b/src/Migrator.Tests/Providers/Generic/Models/CopyDataFromTableToTableModel.cs new file mode 100644 index 00000000..f1904b58 --- /dev/null +++ b/src/Migrator.Tests/Providers/Generic/Models/CopyDataFromTableToTableModel.cs @@ -0,0 +1,8 @@ +namespace Migrator.Tests.Providers.Generic.Models; + +public class CopyDataFromTableToTableModel +{ + public int Column1 { get; set; } + public string Column2 { get; set; } + public int Column3 { get; set; } +} \ No newline at end of file diff --git a/src/Migrator.Tests/Providers/OracleProvider/OracleTransformationProvider_CopyDataFromTableToTableTests.cs b/src/Migrator.Tests/Providers/OracleProvider/OracleTransformationProvider_CopyDataFromTableToTableTests.cs new file mode 100644 index 00000000..9652a6b3 --- /dev/null +++ b/src/Migrator.Tests/Providers/OracleProvider/OracleTransformationProvider_CopyDataFromTableToTableTests.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Migrator.Tests.Providers.Generic; +using NUnit.Framework; + +namespace Migrator.Tests.Providers.OracleProvider; + +[TestFixture] +[Category("Oracle")] +public class OracleTransformationProvider_CopyDataFromTableToTableTests : Generic_CopyDataFromTableToTableBase +{ + [SetUp] + public async Task SetUpAsync() + { + await BeginOracleTransactionAsync(); + } +} \ No newline at end of file diff --git a/src/Migrator.Tests/Providers/PostgreSQL/PostgreSQLTransformationProvider_CopyDataFromTableToTableTests.cs b/src/Migrator.Tests/Providers/PostgreSQL/PostgreSQLTransformationProvider_CopyDataFromTableToTableTests.cs new file mode 100644 index 00000000..4bf485d8 --- /dev/null +++ b/src/Migrator.Tests/Providers/PostgreSQL/PostgreSQLTransformationProvider_CopyDataFromTableToTableTests.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Migrator.Tests.Providers.Generic; +using NUnit.Framework; + +namespace Migrator.Tests.Providers.PostgreSQL; + +[TestFixture] +[Category("Postgre")] +public class PostgreSQLTransformationProvider_CopyDataFromTableToTableTests : Generic_CopyDataFromTableToTableBase +{ + [SetUp] + public async Task SetUpAsync() + { + await BeginPostgreSQLTransactionAsync(); + } +} \ No newline at end of file diff --git a/src/Migrator.Tests/Providers/SQLServer/SQLServerTransformationProvider_ChangeColumnTests.cs b/src/Migrator.Tests/Providers/SQLServer/SQLServerTransformationProvider_ChangeColumnTests.cs index ed6b6af0..25199843 100644 --- a/src/Migrator.Tests/Providers/SQLServer/SQLServerTransformationProvider_ChangeColumnTests.cs +++ b/src/Migrator.Tests/Providers/SQLServer/SQLServerTransformationProvider_ChangeColumnTests.cs @@ -35,4 +35,22 @@ public void ChangeColumn_DateTimeToDateTime2_Success() Assert.That(columnBefore.Type == DbType.DateTime); Assert.That(columnAfter.Type == DbType.DateTime2); } + + [Test, Ignore("This issue is not yet fixed. See https://github.com/dotnetprojects/Migrator.NET/issues/132")] + public void ChangeColumn_WithUniqueThenReChangeToNonUnique_UniqueConstraintShouldBeRemoved() + { + // Arrange + const string tableName = "TestTable"; + const string columnName = "TestColumn"; + + Provider.AddTable(tableName, new Column(columnName, DbType.Int32, ColumnProperty.NotNull)); + + // Act + Provider.ChangeColumn(tableName, new Column(columnName, DbType.Int32, ColumnProperty.NotNull | ColumnProperty.Unique)); + Provider.ChangeColumn(tableName, new Column(columnName, DbType.Int32, ColumnProperty.NotNull)); + + // Assert + var indexes = Provider.GetIndexes(tableName); + Assert.That(indexes, Is.Empty); + } } \ No newline at end of file diff --git a/src/Migrator.Tests/Providers/SQLServer/SQLServerTransformationProvider_CopyDataFromTableToTableTests.cs b/src/Migrator.Tests/Providers/SQLServer/SQLServerTransformationProvider_CopyDataFromTableToTableTests.cs new file mode 100644 index 00000000..dcab7bf4 --- /dev/null +++ b/src/Migrator.Tests/Providers/SQLServer/SQLServerTransformationProvider_CopyDataFromTableToTableTests.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Migrator.Tests.Providers.Generic; +using NUnit.Framework; + +namespace Migrator.Tests.Providers.SQLServer; + +[TestFixture] +[Category("SqlServer")] +public class SQLServerTransformationProvider_CopyDataFromTableToTableTests : Generic_CopyDataFromTableToTableBase +{ + [SetUp] + public async Task SetUpAsync() + { + await BeginSQLServerTransactionAsync(); + } +} \ No newline at end of file diff --git a/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_ChangeColumnTests.cs b/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_ChangeColumnTests.cs index a2ec2e7d..6819f858 100644 --- a/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_ChangeColumnTests.cs +++ b/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_ChangeColumnTests.cs @@ -43,6 +43,9 @@ public void ChangeColumn_HavingColumnPropertyUniqueAndIndex_RebuildSucceeds() Provider.ExecuteNonQuery($"INSERT INTO {testTableName} ({propertyName1}, {propertyName2}) VALUES (2, 3)"); // Assert + var createScriptAfter = ((SQLiteTransformationProvider)Provider).GetSqlCreateTableScript(testTableName); + Assert.That(createScriptAfter, Does.Contain("Color2 TEXT NULL UNIQUE")); + using var command = Provider.GetCommand(); using var reader = Provider.ExecuteQuery(command, $"SELECT COUNT(*) as Count from {testTableName}"); reader.Read(); @@ -65,4 +68,26 @@ public void ChangeColumn_HavingColumnPropertyUniqueAndIndex_RebuildSucceeds() Assert.That(indexAfter.Name, Is.EqualTo(indexName)); CollectionAssert.AreEquivalent(indexAfter.KeyColumns, new string[] { propertyName1, propertyName2 }); } + + [Test] + public void ChangeColumn_StringFromNullToNotNull_StillNotNull() + { + // Arrange + const string testTableName = "MyDefaultTestTable"; + const string propertyName1 = "Color1"; + const string propertyName2 = "Color2"; + + Provider.AddTable(testTableName, + new Column(propertyName1, DbType.Int32, ColumnProperty.PrimaryKey), + new Column(propertyName2, DbType.String, 100, ColumnProperty.Null) + ); + + // Act + Provider.ChangeColumn(table: testTableName, new Column(propertyName2, DbType.String, ColumnProperty.NotNull)); + + + // Assert + var createScriptAfter = ((SQLiteTransformationProvider)Provider).GetSqlCreateTableScript(testTableName); + Assert.That(createScriptAfter, Does.Contain("Color2 TEXT NOT NULL")); + } } \ No newline at end of file diff --git a/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_CopyDataFromTableToTableTests.cs b/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_CopyDataFromTableToTableTests.cs new file mode 100644 index 00000000..87647cfb --- /dev/null +++ b/src/Migrator.Tests/Providers/SQLite/SQLiteTransformationProvider_CopyDataFromTableToTableTests.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Migrator.Tests.Providers.Generic; +using NUnit.Framework; + +namespace Migrator.Tests.Providers.SQLite; + +[TestFixture] +[Category("SQLite")] +public class SQLiteTransformationProvider_CopyDataFromTableToTableTests : Generic_CopyDataFromTableToTableBase +{ + [SetUp] + public async Task SetUpAsync() + { + await BeginSQLiteTransactionAsync(); + } +} diff --git a/src/Migrator/Framework/ITransformationProvider.cs b/src/Migrator/Framework/ITransformationProvider.cs index cad4b97e..835974a7 100644 --- a/src/Migrator/Framework/ITransformationProvider.cs +++ b/src/Migrator/Framework/ITransformationProvider.cs @@ -343,6 +343,16 @@ public interface ITransformationProvider : IDisposable /// bool ConstraintExists(string table, string name); + /// + /// Copies data from source table to target table using INSERT INTO...SELECT..FROM + /// + /// + /// + /// + /// + /// Sort source by these columns. must contain the . + void CopyDataFromTableToTable(string sourceTableName, List sourceColumnNames, string targetTableName, List targetColumnNames, List orderBySourceColumns); + /// /// Check to see if a primary key constraint exists on the table /// diff --git a/src/Migrator/Providers/Impl/Oracle/OracleTransformationProvider.cs b/src/Migrator/Providers/Impl/Oracle/OracleTransformationProvider.cs index f14d1900..031bbc02 100644 --- a/src/Migrator/Providers/Impl/Oracle/OracleTransformationProvider.cs +++ b/src/Migrator/Providers/Impl/Oracle/OracleTransformationProvider.cs @@ -818,6 +818,59 @@ protected override void ConfigureParameterWithValue(IDbDataParameter parameter, } } + public override void CopyDataFromTableToTable(string sourceTableName, List sourceColumnNames, string targetTableName, List targetColumnNames, List orderBySourceColumns) + { + orderBySourceColumns ??= []; + + if (!TableExists(sourceTableName)) + { + throw new Exception($"Source table '{QuoteTableNameIfRequired(sourceTableName)}' does not exist"); + } + + if (!TableExists(targetTableName)) + { + throw new Exception($"Target table '{QuoteTableNameIfRequired(targetTableName)}' does not exist"); + } + + var sourceColumnsConcatenated = sourceColumnNames.Concat(orderBySourceColumns); + + foreach (var column in sourceColumnsConcatenated) + { + if (!ColumnExists(sourceTableName, column)) + { + throw new Exception($"Column {column} in source table does not exist."); + } + } + + foreach (var column in targetColumnNames) + { + if (!ColumnExists(targetTableName, column)) + { + throw new Exception($"Column {column} in target table does not exist."); + } + } + + if (!orderBySourceColumns.All(x => sourceColumnNames.Contains(x))) + { + throw new Exception($"All columns in {nameof(orderBySourceColumns)} must be in {nameof(sourceColumnNames)}"); + } + + var sourceTableNameQuoted = QuoteTableNameIfRequired(sourceTableName); + var targetTableNameQuoted = QuoteTableNameIfRequired(targetTableName); + + var sourceColumnNamesQuoted = sourceColumnNames.Select(QuoteColumnNameIfRequired).ToList(); + var targetColumnNamesQuoted = targetColumnNames.Select(QuoteColumnNameIfRequired).ToList(); + var orderBySourceColumnsQuoted = orderBySourceColumns.Select(QuoteColumnNameIfRequired).ToList(); + + var sourceColumnsJoined = string.Join(", ", sourceColumnNamesQuoted); + var targetColumnsJoined = string.Join(", ", targetColumnNamesQuoted); + var orderBySourceColumnsJoined = string.Join(", ", orderBySourceColumnsQuoted); + + + var sql = $"INSERT INTO {targetTableNameQuoted} ({targetColumnsJoined}) SELECT {sourceColumnsJoined} FROM {sourceTableNameQuoted} ORDER BY {orderBySourceColumnsJoined}"; + ExecuteNonQuery(sql); + } + public override void RemoveColumnDefaultValue(string table, string column) { var sql = string.Format("ALTER TABLE {0} MODIFY {1} DEFAULT NULL", table, column); diff --git a/src/Migrator/Providers/Impl/PostgreSQL/PostgreSQLTransformationProvider.cs b/src/Migrator/Providers/Impl/PostgreSQL/PostgreSQLTransformationProvider.cs index 76adbe8a..bc1d98ab 100644 --- a/src/Migrator/Providers/Impl/PostgreSQL/PostgreSQLTransformationProvider.cs +++ b/src/Migrator/Providers/Impl/PostgreSQL/PostgreSQLTransformationProvider.cs @@ -862,6 +862,59 @@ public override void UpdateTargetFromSource(string tableSourceNotQuoted, string ExecuteNonQuery(sql); } + public override void CopyDataFromTableToTable(string sourceTableName, List sourceColumnNames, string targetTableName, List targetColumnNames, List orderBySourceColumns) + { + orderBySourceColumns ??= []; + + if (!TableExists(sourceTableName)) + { + throw new Exception($"Source table '{QuoteTableNameIfRequired(sourceTableName)}' does not exist"); + } + + if (!TableExists(targetTableName)) + { + throw new Exception($"Target table '{QuoteTableNameIfRequired(targetTableName)}' does not exist"); + } + + var sourceColumnsConcatenated = sourceColumnNames.Concat(orderBySourceColumns); + + foreach (var column in sourceColumnsConcatenated) + { + if (!ColumnExists(sourceTableName, column)) + { + throw new Exception($"Column {column} in source table does not exist."); + } + } + + foreach (var column in targetColumnNames) + { + if (!ColumnExists(targetTableName, column)) + { + throw new Exception($"Column {column} in target table does not exist."); + } + } + + if (!orderBySourceColumns.All(x => sourceColumnNames.Contains(x))) + { + throw new Exception($"All columns in {nameof(orderBySourceColumns)} must be in {nameof(sourceColumnNames)}"); + } + + var sourceTableNameQuoted = QuoteTableNameIfRequired(sourceTableName); + var targetTableNameQuoted = QuoteTableNameIfRequired(targetTableName); + + var sourceColumnNamesQuoted = sourceColumnNames.Select(QuoteColumnNameIfRequired).ToList(); + var targetColumnNamesQuoted = targetColumnNames.Select(QuoteColumnNameIfRequired).ToList(); + var orderBySourceColumnsQuoted = orderBySourceColumns.Select(QuoteColumnNameIfRequired).ToList(); + + var sourceColumnsJoined = string.Join(", ", sourceColumnNamesQuoted); + var targetColumnsJoined = string.Join(", ", targetColumnNamesQuoted); + var orderBySourceColumnsJoined = string.Join(", ", orderBySourceColumnsQuoted); + + + var sql = $"INSERT INTO {targetTableNameQuoted} ({targetColumnsJoined}) SELECT {sourceColumnsJoined} FROM {sourceTableNameQuoted} ORDER BY {orderBySourceColumnsJoined}"; + ExecuteNonQuery(sql); + } + protected override void ConfigureParameterWithValue(IDbDataParameter parameter, int index, object value) { if (value is ushort) @@ -879,4 +932,5 @@ protected override void ConfigureParameterWithValue(IDbDataParameter parameter, base.ConfigureParameterWithValue(parameter, index, value); } } + } diff --git a/src/Migrator/Providers/Impl/SQLite/SQLiteTransformationProvider.cs b/src/Migrator/Providers/Impl/SQLite/SQLiteTransformationProvider.cs index f878b361..81f766f2 100644 --- a/src/Migrator/Providers/Impl/SQLite/SQLiteTransformationProvider.cs +++ b/src/Migrator/Providers/Impl/SQLite/SQLiteTransformationProvider.cs @@ -1777,6 +1777,59 @@ public override void AddCheckConstraint(string constraintName, string tableName, RecreateTable(sqliteTableInfo); } + public override void CopyDataFromTableToTable(string sourceTableName, List sourceColumnNames, string targetTableName, List targetColumnNames, List orderBySourceColumns) + { + orderBySourceColumns ??= []; + + if (!TableExists(sourceTableName)) + { + throw new Exception($"Source table '{QuoteTableNameIfRequired(sourceTableName)}' does not exist"); + } + + if (!TableExists(targetTableName)) + { + throw new Exception($"Target table '{QuoteTableNameIfRequired(targetTableName)}' does not exist"); + } + + var sourceColumnsConcatenated = sourceColumnNames.Concat(orderBySourceColumns); + + foreach (var column in sourceColumnsConcatenated) + { + if (!ColumnExists(sourceTableName, column)) + { + throw new Exception($"Column {column} in source table does not exist."); + } + } + + foreach (var column in targetColumnNames) + { + if (!ColumnExists(targetTableName, column)) + { + throw new Exception($"Column {column} in target table does not exist."); + } + } + + if (!orderBySourceColumns.All(x => sourceColumnNames.Contains(x))) + { + throw new Exception($"All columns in {nameof(orderBySourceColumns)} must be in {nameof(sourceColumnNames)}"); + } + + var sourceTableNameQuoted = QuoteTableNameIfRequired(sourceTableName); + var targetTableNameQuoted = QuoteTableNameIfRequired(targetTableName); + + var sourceColumnNamesQuoted = sourceColumnNames.Select(QuoteColumnNameIfRequired).ToList(); + var targetColumnNamesQuoted = targetColumnNames.Select(QuoteColumnNameIfRequired).ToList(); + var orderBySourceColumnsQuoted = orderBySourceColumns.Select(QuoteColumnNameIfRequired).ToList(); + + var sourceColumnsJoined = string.Join(", ", sourceColumnNamesQuoted); + var targetColumnsJoined = string.Join(", ", targetColumnNamesQuoted); + var orderBySourceColumnsJoined = string.Join(", ", orderBySourceColumnsQuoted); + + + var sql = $"INSERT INTO {targetTableNameQuoted} ({targetColumnsJoined}) SELECT {sourceColumnsJoined} FROM {sourceTableNameQuoted} ORDER BY {orderBySourceColumnsJoined}"; + ExecuteNonQuery(sql); + } + public List GetCheckConstraints(string tableName) { if (!TableExists(tableName)) diff --git a/src/Migrator/Providers/Impl/SqlServer/SqlServerTransformationProvider.cs b/src/Migrator/Providers/Impl/SqlServer/SqlServerTransformationProvider.cs index 4c946679..9f675da3 100644 --- a/src/Migrator/Providers/Impl/SqlServer/SqlServerTransformationProvider.cs +++ b/src/Migrator/Providers/Impl/SqlServer/SqlServerTransformationProvider.cs @@ -69,6 +69,59 @@ protected virtual void CreateConnection(string providerName) Dialect.RegisterProperty(ColumnProperty.CaseSensitive, "COLLATE " + collationString.Replace("_CI_", "_CS_")); } + public override void CopyDataFromTableToTable(string sourceTableName, List sourceColumnNames, string targetTableName, List targetColumnNames, List orderBySourceColumns) + { + orderBySourceColumns ??= []; + + if (!TableExists(sourceTableName)) + { + throw new Exception($"Source table '{QuoteTableNameIfRequired(sourceTableName)}' does not exist"); + } + + if (!TableExists(targetTableName)) + { + throw new Exception($"Target table '{QuoteTableNameIfRequired(targetTableName)}' does not exist"); + } + + var sourceColumnsConcatenated = sourceColumnNames.Concat(orderBySourceColumns); + + foreach (var column in sourceColumnsConcatenated) + { + if (!ColumnExists(sourceTableName, column)) + { + throw new Exception($"Column {column} in source table does not exist."); + } + } + + foreach (var column in targetColumnNames) + { + if (!ColumnExists(targetTableName, column)) + { + throw new Exception($"Column {column} in target table does not exist."); + } + } + + if (!orderBySourceColumns.All(x => sourceColumnNames.Contains(x))) + { + throw new Exception($"All columns in {nameof(orderBySourceColumns)} must be in {nameof(sourceColumnNames)}"); + } + + var sourceTableNameQuoted = QuoteTableNameIfRequired(sourceTableName); + var targetTableNameQuoted = QuoteTableNameIfRequired(targetTableName); + + var sourceColumnNamesQuoted = sourceColumnNames.Select(QuoteColumnNameIfRequired).ToList(); + var targetColumnNamesQuoted = targetColumnNames.Select(QuoteColumnNameIfRequired).ToList(); + var orderBySourceColumnsQuoted = orderBySourceColumns.Select(QuoteColumnNameIfRequired).ToList(); + + var sourceColumnsJoined = string.Join(", ", sourceColumnNamesQuoted); + var targetColumnsJoined = string.Join(", ", targetColumnNamesQuoted); + var orderBySourceColumnsJoined = string.Join(", ", orderBySourceColumnsQuoted); + + + var sql = $"INSERT INTO {targetTableNameQuoted} ({targetColumnsJoined}) SELECT {sourceColumnsJoined} FROM {sourceTableNameQuoted} ORDER BY {orderBySourceColumnsJoined}"; + ExecuteNonQuery(sql); + } + public override bool TableExists(string tableName) { // This is not clean! Usually you should use schema as well as this query will find tables in other tables as well! diff --git a/src/Migrator/Providers/NoOpTransformationProvider.cs b/src/Migrator/Providers/NoOpTransformationProvider.cs index b99cd0b1..145918df 100644 --- a/src/Migrator/Providers/NoOpTransformationProvider.cs +++ b/src/Migrator/Providers/NoOpTransformationProvider.cs @@ -597,4 +597,9 @@ public void UpdateTargetFromSource(string tableSourceNotQuoted, string tableTarg { throw new NotImplementedException(); } + + public virtual void CopyDataFromTableToTable(string sourceTableName, List sourceColumnNames, string targetTableName, List targetColumnNames, List orderBySourceColumns) + { + throw new NotImplementedException(); + } } diff --git a/src/Migrator/Providers/TransformationProvider.cs b/src/Migrator/Providers/TransformationProvider.cs index d3b6f8ed..34ce47cd 100644 --- a/src/Migrator/Providers/TransformationProvider.cs +++ b/src/Migrator/Providers/TransformationProvider.cs @@ -2232,4 +2232,9 @@ protected void ValidateIndex(string tableName, Index index) } } } + + public virtual void CopyDataFromTableToTable(string sourceTableName, List sourceColumnNames, string targetTableName, List targetColumnNames, List orderBySourceColumns) + { + throw new NotImplementedException(); + } }