From 441db1474951bc134be72d4d83947c2b68bc8809 Mon Sep 17 00:00:00 2001 From: Alessandro Magistroni <65421435+AMagistroni@users.noreply.github.com> Date: Fri, 10 Sep 2021 20:47:59 +0200 Subject: [PATCH] Drop PK on alter column and create --- SqlSchemaCompare.Core/DbStructures/Table.cs | 11 +++----- .../TSql/Factory/TSqlTableFactory.cs | 18 ++++++++++--- .../TSql/TSqlSchemaBuilder.cs | 8 ++++-- SqlSchemaCompare.Core/UpdateSchemaManager.cs | 4 +-- SqlSchemaCompare.Test/TSql/TSqlTableTest.cs | 25 ++++++++++++++++--- 5 files changed, 48 insertions(+), 18 deletions(-) diff --git a/SqlSchemaCompare.Core/DbStructures/Table.cs b/SqlSchemaCompare.Core/DbStructures/Table.cs index e60bfdd..d76b499 100644 --- a/SqlSchemaCompare.Core/DbStructures/Table.cs +++ b/SqlSchemaCompare.Core/DbStructures/Table.cs @@ -15,22 +15,17 @@ public class TableConstraint : DbObject public enum ConstraintTypes { Default, - ForeignKey + ForeignKey, + PrimaryKey } public override DbObjectType DbObjectType => DbObjectType.TableContraint; - public string ColumnName { get; init; } + public IEnumerable ColumnName { get; init; } public ConstraintTypes ConstraintType { get; init; } public string Value { get; init; } } public IList Columns { get; } = new List(); public IList Constraints { get; } = new List(); - public string Constraint { get; private set; } - public void AdColumns(Column Colum) => Columns.Add(Colum); public void AddConstraint(TableConstraint tableConstraint) => Constraints.Add(tableConstraint); - public void SetConstraint(string constraint) - { - Constraint = constraint; - } } } diff --git a/SqlSchemaCompare.Core/TSql/Factory/TSqlTableFactory.cs b/SqlSchemaCompare.Core/TSql/Factory/TSqlTableFactory.cs index 6c35538..2c90600 100644 --- a/SqlSchemaCompare.Core/TSql/Factory/TSqlTableFactory.cs +++ b/SqlSchemaCompare.Core/TSql/Factory/TSqlTableFactory.cs @@ -2,8 +2,8 @@ using Antlr4.Runtime.Misc; using SqlSchemaCompare.Core.Common; using SqlSchemaCompare.Core.DbStructures; +using System.Collections.Generic; using System.Linq; -using System.Text; namespace SqlSchemaCompare.Core.TSql.Factory { @@ -30,7 +30,7 @@ public DbObject Create(ParserRuleContext context, ICharStream stream) } else if (columnTree.table_constraint() != null) { - table.SetConstraint(stream.GetText(new Interval(columnTree.table_constraint().start.StartIndex, columnTree.table_constraint().stop.StopIndex))); + table.AddConstraint(CreatePrimaryKeyConstraint(columnTree.table_constraint(), stream, table.Identifier)); } } return table; @@ -49,6 +49,18 @@ private Table.Column CreateColumn(TSqlParser.Column_def_table_constraintContext }; } + public Table.TableConstraint CreatePrimaryKeyConstraint(TSqlParser.Table_constraintContext constraintContext, ICharStream stream, string tableName) + { + return new Table.TableConstraint + { + Sql = stream.GetText(new Interval(constraintContext.start.StartIndex, constraintContext.stop.StopIndex)), + Name = constraintContext.id_()[0].GetText(), + ParentName = tableName, + ColumnName = constraintContext.column_name_list_with_order().id_().Select(x => x.GetText()), + ConstraintType = Table.TableConstraint.ConstraintTypes.PrimaryKey + }; + } + public Table.TableConstraint CreateAlterTable(ParserRuleContext context) { var alterTableContext = context as TSqlParser.Alter_tableContext; @@ -83,7 +95,7 @@ public Table.TableConstraint CreateAlterTable(ParserRuleContext context) Sql = alterTableContext.Start.InputStream.GetText(new Interval(alterTableContext.start.StartIndex, alterTableContext.stop.StopIndex)), Name = name, ParentName = tableName, - ColumnName = columnName, + ColumnName = new List {columnName}, ConstraintType = constraintType, Value = value.ToString() }; diff --git a/SqlSchemaCompare.Core/TSql/TSqlSchemaBuilder.cs b/SqlSchemaCompare.Core/TSql/TSqlSchemaBuilder.cs index 4df972d..37b78f3 100644 --- a/SqlSchemaCompare.Core/TSql/TSqlSchemaBuilder.cs +++ b/SqlSchemaCompare.Core/TSql/TSqlSchemaBuilder.cs @@ -53,8 +53,12 @@ private string BuildTableConstraint(Table.TableConstraint alterTable, Operation switch (operation) { case Operation.Create: - if (!resultProcessDbObject.GetDbObject(DbObjectType.Column, Operation.Create).Any(x => x.Name == alterTable.ColumnName)) + if (!resultProcessDbObject.GetDbObject(DbObjectType.Column, Operation.Create).Any(x => alterTable.ColumnName.Contains(x.Name))) { + if (alterTable.ConstraintType == Table.TableConstraint.ConstraintTypes.PrimaryKey) + { + return $"ALTER TABLE ADD {alterTable.Sql}"; + } return alterTable.Sql; } return string.Empty; @@ -81,7 +85,7 @@ private string BuildColumn(Table.Column column, Operation operation) { case Operation.Create: var sql = $"ALTER TABLE {column.ParentName} ADD { column.Sql}"; - var constraintRelated = column.Table.Constraints.SingleOrDefault(x => x.ColumnName == column.Name && x.ConstraintType == Table.TableConstraint.ConstraintTypes.Default); + var constraintRelated = column.Table.Constraints.SingleOrDefault(x => x.ColumnName.Contains(column.Name) && x.ConstraintType == Table.TableConstraint.ConstraintTypes.Default); if (constraintRelated != null) { sql = $"{sql} CONSTRAINT {constraintRelated.Name} DEFAULT {constraintRelated.Value}"; diff --git a/SqlSchemaCompare.Core/UpdateSchemaManager.cs b/SqlSchemaCompare.Core/UpdateSchemaManager.cs index d1cdac7..684ff44 100644 --- a/SqlSchemaCompare.Core/UpdateSchemaManager.cs +++ b/SqlSchemaCompare.Core/UpdateSchemaManager.cs @@ -250,11 +250,11 @@ private void ProcessTableColumn(Table table, Table destinationTable, IEnumerable resultProcessDbObject.AddOperation(columnsToDrop, Operation.Drop); var columnsOfCostraintToDropAndCreate = destinationTable - .Constraints.Select(x => x.ColumnName) + .Constraints.SelectMany(x => x.ColumnName) .Intersect(columnsToAlter.Select(x => x.Name)); var constrainttoDropAndCreate = destinationTable.Constraints - .Where(x => columnsOfCostraintToDropAndCreate.Contains(x.ColumnName)) + .Where(x => columnsOfCostraintToDropAndCreate.Intersect(x.ColumnName).Any()) .Except(resultProcessDbObject.GetDbObject(DbObjectType.TableContraint, Operation.Drop))//constraint that we have to drop .ToList(); resultProcessDbObject.AddOperation(constrainttoDropAndCreate, Operation.Drop); diff --git a/SqlSchemaCompare.Test/TSql/TSqlTableTest.cs b/SqlSchemaCompare.Test/TSql/TSqlTableTest.cs index d22b3c9..24b4374 100644 --- a/SqlSchemaCompare.Test/TSql/TSqlTableTest.cs +++ b/SqlSchemaCompare.Test/TSql/TSqlTableTest.cs @@ -41,7 +41,7 @@ [col1] [char](8) NULL, column2.Name.ShouldBe("[col1]"); column2.Sql.ShouldBe("[col1] [char](8) NULL"); - table.Constraint.ShouldBe(constraint); + table.Constraints.Single().Sql.ShouldBe(constraint); errors.Count().ShouldBe(0); } [Fact] @@ -406,7 +406,12 @@ [ID] [int] IDENTITY(1,1) NOT NULL, CREATE TABLE [dbo].[tblLookup]( [ID] [int] NOT NULL, - [description] [nvarchar](50) NOT NULL) + [description] [nvarchar](50) NOT NULL, + CONSTRAINT [PK] PRIMARY KEY CLUSTERED + ( + [ID] ASC, [description] DESC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [db] +) ON [db] GO ALTER TABLE [dbo].[tbl] WITH CHECK ADD CONSTRAINT [FK_constraint] FOREIGN KEY([column1]) @@ -423,7 +428,12 @@ [ID] [int] IDENTITY(1,1) NOT NULL, CREATE TABLE [dbo].[tblLookup]( [ID] [tinyint] NOT NULL, - [description] [nvarchar](50) NOT NULL) + [description] [nvarchar](50) NOT NULL, + CONSTRAINT [PK] PRIMARY KEY CLUSTERED + ( + [ID] ASC, [description] DESC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [db] +) ON [db] GO ALTER TABLE [dbo].[tbl] WITH CHECK ADD CONSTRAINT [FK_constraint] FOREIGN KEY([column1]) @@ -438,6 +448,9 @@ REFERENCES [dbo].[tblLookup] ([ID]) @"ALTER TABLE [dbo].[tbl] DROP CONSTRAINT [FK_constraint] GO +ALTER TABLE [dbo].[tblLookup] DROP CONSTRAINT [PK] +GO + ALTER TABLE [dbo].[tbl] ALTER COLUMN [column1] [int] NOT NULL GO @@ -448,6 +461,12 @@ ALTER TABLE [dbo].[tbl] WITH CHECK ADD CONSTRAINT [FK_constraint] FOREIGN KEY([c REFERENCES [dbo].[tblLookup] ([ID]) GO +ALTER TABLE ADD CONSTRAINT [PK] PRIMARY KEY CLUSTERED + ( + [ID] ASC, [description] DESC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [db] +GO + "); errors.ShouldBeEmpty(); }