Skip to content

Commit

Permalink
drop index and create before alter column
Browse files Browse the repository at this point in the history
  • Loading branch information
AMagistroni committed Sep 13, 2021
1 parent 064d042 commit f314a7a
Show file tree
Hide file tree
Showing 15 changed files with 243 additions and 179 deletions.
5 changes: 2 additions & 3 deletions SqlSchemaCompare.Core/Common/RelatedDbObjects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@ namespace SqlSchemaCompare.Core.Common
{
public class RelatedDbObjectsConfiguration
{
public static List<List<DbObjectType>> RelatedDbObjects = new List<List<DbObjectType>>
public static List<List<DbObjectType>> RelatedDbObjects = new()
{
new List<DbObjectType> { DbObjectType.Function },
new List<DbObjectType> { DbObjectType.StoreProcedure },
new List<DbObjectType> { DbObjectType.Table, DbObjectType.TableContraint, DbObjectType.Column },
new List<DbObjectType> { DbObjectType.Table, DbObjectType.TableDefaultContraint, DbObjectType.TableForeignKeyContraint, DbObjectType.TablePrimaryKeyContraint, DbObjectType.Column, DbObjectType.Index },
new List<DbObjectType> { DbObjectType.User, DbObjectType.Role, DbObjectType.Member },
new List<DbObjectType> { DbObjectType.View },
new List<DbObjectType> { DbObjectType.Schema },
new List<DbObjectType> { DbObjectType.Trigger, DbObjectType.EnableTrigger },
new List<DbObjectType> { DbObjectType.Type },
new List<DbObjectType> { DbObjectType.Other},
new List<DbObjectType> { DbObjectType.Index }
};

public List<DbObjectType> GetRelatedDbObjects(DbObjectType dbObject)
Expand Down
4 changes: 3 additions & 1 deletion SqlSchemaCompare.Core/DbStructures/DbObjectType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public enum DbObjectType
Member,
Type,
Index,
TableContraint,
TableDefaultContraint,
TableForeignKeyContraint,
TablePrimaryKeyContraint,
Column,
EnableTrigger,
Database,
Expand Down
6 changes: 4 additions & 2 deletions SqlSchemaCompare.Core/DbStructures/Index.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
namespace SqlSchemaCompare.Core.DbStructures
using System.Collections.Generic;

namespace SqlSchemaCompare.Core.DbStructures
{
public class Index : DbObject
{
public override DbObjectType DbObjectType => DbObjectType.Index;
public string TableName { get; set; }
public IEnumerable<string> ColumnNames { get; init; }
}
}
38 changes: 25 additions & 13 deletions SqlSchemaCompare.Core/DbStructures/Table.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using SqlSchemaCompare.Core.DbStructures;
using System.Collections.Generic;

namespace SqlSchemaCompare.Core.DbStructures
{
Expand All @@ -10,23 +11,34 @@ public class Column : DbObject {
public IList<TableConstraint> Constraints { get; } = new List<TableConstraint>();
public Table Table { get; init; }
}
public class TableConstraint : DbObject
{
public enum ConstraintTypes
{
Default,
ForeignKey,
PrimaryKey
}
public override DbObjectType DbObjectType => DbObjectType.TableContraint;
public IEnumerable<string> ColumnName { get; init; }
public ConstraintTypes ConstraintType { get; init; }

public class TableDefaultConstraint : TableConstraint
{
public override DbObjectType DbObjectType => DbObjectType.TableDefaultContraint;
public string Value { get; init; }
public Table Table { get; init; }
}

public class TableForeignKeyConstraint : TableConstraint
{
public override DbObjectType DbObjectType => DbObjectType.TableForeignKeyContraint;
}

public class TablePrimaryKeyConstraint : TableConstraint
{
public override DbObjectType DbObjectType => DbObjectType.TablePrimaryKeyContraint;
}

public IList<Column> Columns { get; } = new List<Column>();
public IList<TableConstraint> Constraints { get; } = new List<TableConstraint>();
public IList<Index> Indexes { get; } = new List<Index>();
public void AdColumns(Column Colum) => Columns.Add(Colum);
public void AddConstraint(TableConstraint tableConstraint) => Constraints.Add(tableConstraint);
public void AddIndex(Index index) => Indexes.Add(index);
}
}

public abstract class TableConstraint : DbObject
{
public Table Table { get; init; }
public IEnumerable<string> ColumnNames { get; init; }
}
4 changes: 3 additions & 1 deletion SqlSchemaCompare.Core/TSql/Factory/TSqlIndexFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Antlr4.Runtime.Misc;
using SqlSchemaCompare.Core.Common;
using SqlSchemaCompare.Core.DbStructures;
using System.Linq;

namespace SqlSchemaCompare.Core.TSql.Factory
{
Expand All @@ -16,7 +17,8 @@ public DbObject Create(ParserRuleContext context, ICharStream stream)
Name = indexContext.id_()[0].GetText(),
Schema = string.Empty,
Operation = GetOperation(indexContext.GetChild(0).GetText()),
TableName = indexContext.table_name().GetText()
ParentName = indexContext.table_name().GetText(),
ColumnNames = indexContext.column_name_list_with_order().id_().Select(x => x.GetText()),
};
}
}
Expand Down
61 changes: 30 additions & 31 deletions SqlSchemaCompare.Core/TSql/Factory/TSqlTableFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Antlr4.Runtime.Misc;
using SqlSchemaCompare.Core.Common;
using SqlSchemaCompare.Core.DbStructures;
using System;
using System.Collections.Generic;
using System.Linq;

Expand Down Expand Up @@ -49,56 +50,54 @@ private Table.Column CreateColumn(TSqlParser.Column_def_table_constraintContext
};
}

public Table.TableConstraint CreatePrimaryKeyConstraint(TSqlParser.Table_constraintContext constraintContext, ICharStream stream, Table table)
private Table.TablePrimaryKeyConstraint CreatePrimaryKeyConstraint(TSqlParser.Table_constraintContext constraintContext, ICharStream stream, Table table)
{
return new Table.TableConstraint
return new Table.TablePrimaryKeyConstraint
{
Sql = stream.GetText(new Interval(constraintContext.start.StartIndex, constraintContext.stop.StopIndex)),
Name = constraintContext.constraint?.GetText(),
ParentName = table.Identifier,
ColumnName = constraintContext.column_name_list_with_order().id_().Select(x => x.GetText()),
ConstraintType = Table.TableConstraint.ConstraintTypes.PrimaryKey,
ColumnNames = constraintContext.column_name_list_with_order().id_().Select(x => x.GetText()),
Table = table
};
}

public Table.TableConstraint CreateAlterTable(ParserRuleContext context)
internal TableConstraint CreateAlterTable(ParserRuleContext context)
{
var alterTableContext = context as TSqlParser.Alter_tableContext;
var tableName = alterTableContext.children[2].GetText();

string name = string.Empty;
string columnName = string.Empty;
string value = string.Empty;

Table.TableConstraint.ConstraintTypes constraintType = Table.TableConstraint.ConstraintTypes.ForeignKey;
if ((alterTableContext.fk != null) || (alterTableContext.constraint != null))
{
columnName = alterTableContext.fk?.GetText();
name = alterTableContext.constraint != null ? alterTableContext.constraint.GetText() : default;
constraintType = Table.TableConstraint.ConstraintTypes.ForeignKey;
return CreateForeignKeyConstraint(alterTableContext);
}
else if (alterTableContext.column_def_table_constraints() != null) {
var constraint = ((TSqlParser.Column_def_table_constraintContext)alterTableContext.column_def_table_constraints().children[0]).table_constraint();
if (constraint.CONSTRAINT() != null)
{
name = constraint.id_()[0].GetText();
}
columnName = constraint.forColumn.GetText();
constraintType = Table.TableConstraint.ConstraintTypes.Default;
if (constraint.DEFAULT() != null)
{
value = constraint.default_value_column.GetText();
}
return CreateDefaultConstraint(alterTableContext);
}
return new Table.TableConstraint

throw new NotImplementedException();
}

private Table.TableForeignKeyConstraint CreateForeignKeyConstraint(TSqlParser.Alter_tableContext alterTableContext)
{
return new Table.TableForeignKeyConstraint
{
Sql = alterTableContext.Start.InputStream.GetText(new Interval(alterTableContext.start.StartIndex, alterTableContext.stop.StopIndex)),
Name = alterTableContext.constraint != null ? alterTableContext.constraint.GetText() : default,
ParentName = alterTableContext.children[2].GetText(),
ColumnNames = new List<string> { alterTableContext.fk?.GetText() }
};
}

private Table.TableDefaultConstraint CreateDefaultConstraint(TSqlParser.Alter_tableContext alterTableContext)
{
var constraint = ((TSqlParser.Column_def_table_constraintContext)alterTableContext.column_def_table_constraints().children[0]).table_constraint();
return new Table.TableDefaultConstraint
{
Sql = alterTableContext.Start.InputStream.GetText(new Interval(alterTableContext.start.StartIndex, alterTableContext.stop.StopIndex)),
Name = name,
ParentName = tableName,
ColumnName = new List<string> {columnName},
ConstraintType = constraintType,
Value = value.ToString()
Name = constraint.CONSTRAINT() != null ? constraint.id_()[0].GetText() : string.Empty,
ParentName = alterTableContext.children[2].GetText(),
ColumnNames = new List<string> { constraint.forColumn.GetText() },
Value = constraint.DEFAULT() != null ? constraint.default_value_column.GetText() : string.Empty
};
}
}
Expand Down
4 changes: 3 additions & 1 deletion SqlSchemaCompare.Core/TSql/TSqlParserUpdateListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ public override void ExitCreate_type([NotNull] TSqlParser.Create_typeContext con

public override void ExitCreate_index([NotNull] TSqlParser.Create_indexContext context)
{
DbObjects.Add(_indexFactory.Create(context, _stream));
var index = _indexFactory.Create(context, _stream);
var table = DbObjects.OfType<Table>().Single(x => x.Identifier == index.ParentName);
table.AddIndex(index as DbStructures.Index);
}

public override void ExitAlter_table([NotNull] TSqlParser.Alter_tableContext context)
Expand Down
14 changes: 8 additions & 6 deletions SqlSchemaCompare.Core/TSql/TSqlSchemaBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public string Build(DbObject dbObject, Operation operation, ResultProcessDbObjec
return dbObject.DbObjectType switch
{
DbObjectType.Table => BuildCreateDropTable(dbObject as Table, operation),
DbObjectType.TableContraint => BuildTableConstraint(dbObject as Table.TableConstraint, operation, resultProcessDbObject),
DbObjectType.TableDefaultContraint => BuildTableConstraint(dbObject as TableConstraint, operation, resultProcessDbObject),
DbObjectType.TablePrimaryKeyContraint => BuildTableConstraint(dbObject as TableConstraint, operation, resultProcessDbObject),
DbObjectType.TableForeignKeyContraint => BuildTableConstraint(dbObject as TableConstraint, operation, resultProcessDbObject),
DbObjectType.Column => BuildColumn(dbObject as Table.Column, operation),
DbObjectType.View => BuildView(dbObject as View, operation),
DbObjectType.StoreProcedure => BuildStoreProcedure(dbObject as StoreProcedure, operation),
Expand Down Expand Up @@ -48,14 +50,14 @@ public string BuildSeparator()
{
return "GO\r\n";
}
private string BuildTableConstraint(Table.TableConstraint constraint, Operation operation, ResultProcessDbObject resultProcessDbObject)
private string BuildTableConstraint(TableConstraint constraint, Operation operation, ResultProcessDbObject resultProcessDbObject)
{
switch (operation)
{
case Operation.Create:
if (!resultProcessDbObject.GetDbObject(DbObjectType.Column, Operation.Create).Any(x => constraint.ColumnName.Contains(x.Name)))
if (!resultProcessDbObject.GetDbObject(DbObjectType.Column, Operation.Create).Any(x => constraint.ColumnNames.Contains(x.Name)))
{
if (constraint.ConstraintType == Table.TableConstraint.ConstraintTypes.PrimaryKey)
if (constraint is Table.TablePrimaryKeyConstraint)
{
return $"ALTER TABLE {constraint.ParentName} ADD {constraint.Sql}";
}
Expand Down Expand Up @@ -106,7 +108,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.Contains(column.Name) && x.ConstraintType == Table.TableConstraint.ConstraintTypes.Default);
var constraintRelated = column.Table.Constraints.OfType<Table.TableDefaultConstraint>().SingleOrDefault(x => x.ColumnNames.Contains(column.Name));
if (constraintRelated != null)
{
sql = $"{sql} CONSTRAINT {constraintRelated.Name} DEFAULT {constraintRelated.Value}";
Expand Down Expand Up @@ -193,7 +195,7 @@ private string BuildIndex(Index dbObject, Operation operation)
return operation switch
{
Operation.Create => dbObject.Sql,
Operation.Drop => $"DROP INDEX {dbObject.Identifier} ON {dbObject.TableName}",
Operation.Drop => $"DROP INDEX {dbObject.Identifier} ON {dbObject.ParentName}",
_ => throw new NotSupportedException($"Operation not supported on TYPE"),
};
}
Expand Down
Loading

0 comments on commit f314a7a

Please sign in to comment.