You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
9.5 KiB
258 lines
9.5 KiB
using OpenDBDiff.Abstractions.Schema;
|
|
using OpenDBDiff.Abstractions.Schema.Model;
|
|
using OpenDBDiff.SqlServer.Schema.Model.Util;
|
|
using OpenDBDiff.SqlServer.Schema.Options;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace OpenDBDiff.SqlServer.Schema.Model
|
|
{
|
|
public abstract class Code : SQLServerSchemaBase, ICode
|
|
{
|
|
protected string sql = null;
|
|
protected string typeName = "";
|
|
private int deepMax = 0;
|
|
private int deepMin = 0;
|
|
private ScriptAction addAction;
|
|
private ScriptAction dropAction;
|
|
|
|
public Code(ISchemaBase parent, ObjectType type, ScriptAction addAction, ScriptAction dropAction)
|
|
: base(parent, type)
|
|
{
|
|
DependenciesIn = new List<String>();
|
|
DependenciesOut = new List<String>();
|
|
typeName = GetObjectTypeName(ObjectType);
|
|
/*Por el momento, solo los Assemblys manejan deep de dependencias*/
|
|
if (this.ObjectType == ObjectType.Assembly)
|
|
{
|
|
deepMax = 501;
|
|
deepMin = 500;
|
|
}
|
|
this.addAction = addAction;
|
|
this.dropAction = dropAction;
|
|
}
|
|
|
|
public override SQLScript Create()
|
|
{
|
|
int iCount = DependenciesCount;
|
|
if (iCount > 0) iCount = iCount * -1;
|
|
if (!GetWasInsertInDiffList(addAction))
|
|
{
|
|
SetWasInsertInDiffList(addAction);
|
|
return new SQLScript(this.ToSqlAdd(), iCount, addAction);
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
public override SQLScript Drop()
|
|
{
|
|
int iCount = DependenciesCount;
|
|
if (!GetWasInsertInDiffList(dropAction))
|
|
{
|
|
SetWasInsertInDiffList(dropAction);
|
|
return new SQLScript(this.ToSqlDrop(), iCount, dropAction);
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
private static string GetObjectTypeName(ObjectType type)
|
|
{
|
|
if (type == ObjectType.Rule) return "RULE";
|
|
if (type == ObjectType.Trigger) return "TRIGGER";
|
|
if (type == ObjectType.View) return "VIEW";
|
|
if (type == ObjectType.Function) return "FUNCTION";
|
|
if (type == ObjectType.StoredProcedure) return "PROCEDURE";
|
|
if (type == ObjectType.CLRStoredProcedure) return "PROCEDURE";
|
|
if (type == ObjectType.CLRTrigger) return "TRIGGER";
|
|
if (type == ObjectType.CLRFunction) return "FUNCTION";
|
|
if (type == ObjectType.Assembly) return "ASSEMBLY";
|
|
return "";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Names collection of dependant objects of the object
|
|
/// </summary>
|
|
public List<String> DependenciesOut { get; set; }
|
|
|
|
/// <summary>
|
|
/// Names collection of objects which the object depends on
|
|
/// </summary>
|
|
public List<String> DependenciesIn { get; set; }
|
|
|
|
public Boolean IsSchemaBinding { get; set; }
|
|
|
|
public string Text { get; set; }
|
|
|
|
public override int DependenciesCount
|
|
{
|
|
get
|
|
{
|
|
int iCount = 0;
|
|
if (this.DependenciesOut.Any())
|
|
{
|
|
Dictionary<string, bool> depencyTracker = new Dictionary<string, bool>();
|
|
iCount = DependenciesCountFilter(this.FullName, depencyTracker);
|
|
}
|
|
return iCount;
|
|
}
|
|
}
|
|
|
|
private int DependenciesCountFilter(string FullName, Dictionary<string, bool> depencyTracker)
|
|
{
|
|
int count = 0;
|
|
ICode item;
|
|
try
|
|
{
|
|
item = (ICode)((Database)Parent).Find(FullName);
|
|
if (item != null)
|
|
{
|
|
for (int j = 0; j < item.DependenciesOut.Count; j++)
|
|
{
|
|
if (!depencyTracker.ContainsKey(FullName.ToUpper()))
|
|
{
|
|
depencyTracker.Add(FullName.ToUpper(), true);
|
|
}
|
|
count += 1 + DependenciesCountFilter(item.DependenciesOut[j], depencyTracker);
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates if there are dependant tables on the object which must be rebuild
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Boolean HasToRebuild
|
|
{
|
|
get
|
|
{
|
|
for (int j = 0; j < DependenciesIn.Count; j++)
|
|
{
|
|
ISchemaBase item = ((Database)Parent).Find(DependenciesIn[j]);
|
|
if (item != null)
|
|
{
|
|
if ((item.Status == ObjectStatus.Rebuild) || (item.Status == ObjectStatus.RebuildDependencies))
|
|
return true;
|
|
}
|
|
};
|
|
return IsSchemaBinding;
|
|
}
|
|
}
|
|
|
|
private SQLScriptList RebuildDependencies(List<string> depends, int deepMin, int deepMax)
|
|
{
|
|
int newDeepMax = (deepMax != 0) ? deepMax + 1 : 0;
|
|
int newDeepMin = (deepMin != 0) ? deepMin - 1 : 0;
|
|
SQLScriptList list = new SQLScriptList();
|
|
for (int j = 0; j < depends.Count; j++)
|
|
{
|
|
ISchemaBase item = ((Database)Parent).Find(depends[j]);
|
|
if (item != null)
|
|
{
|
|
if ((item.Status != ObjectStatus.Create) && (item.Status != ObjectStatus.Drop))
|
|
{
|
|
if ((item.ObjectType != ObjectType.CLRStoredProcedure) && (item.ObjectType != ObjectType.Assembly) && (item.ObjectType != ObjectType.UserDataType) && (item.ObjectType != ObjectType.View) && (item.ObjectType != ObjectType.Function))
|
|
{
|
|
newDeepMin = 0;
|
|
newDeepMax = 0;
|
|
}
|
|
if (item.Status != ObjectStatus.Drop)
|
|
{
|
|
if (!((item.Parent.HasState(ObjectStatus.Rebuild)) && (item.ObjectType == ObjectType.Trigger)))
|
|
list.Add(item.Drop(), newDeepMin);
|
|
}
|
|
if ((this.Status != ObjectStatus.Drop) && (item.Status != ObjectStatus.Create))
|
|
list.Add(item.Create(), newDeepMax);
|
|
if (item.IsCodeType)
|
|
list.AddRange(RebuildDependencies(((ICode)item).DependenciesOut, newDeepMin, newDeepMax));
|
|
}
|
|
}
|
|
};
|
|
return list;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rebuilds the object and all its dependant objects.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public SQLScriptList Rebuild()
|
|
{
|
|
SQLScriptList list = new SQLScriptList();
|
|
list.AddRange(RebuildDependencies());
|
|
if (this.Status != ObjectStatus.Create) list.Add(Drop(), deepMin);
|
|
if (this.Status != ObjectStatus.Drop) list.Add(Create(), deepMax);
|
|
return list;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rebuilds the dependant objects.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public SQLScriptList RebuildDependencies()
|
|
{
|
|
return RebuildDependencies(this.DependenciesOut, deepMin, deepMax);
|
|
}
|
|
|
|
public override string ToSql()
|
|
{
|
|
if (String.IsNullOrEmpty(sql))
|
|
sql = FormatCode.FormatCreate(typeName, Text, this);
|
|
return sql;
|
|
}
|
|
|
|
public override string ToSqlAdd()
|
|
{
|
|
string sql = ToSql();
|
|
sql += this.ExtendedProperties.ToSql();
|
|
return sql;
|
|
}
|
|
|
|
public override string ToSqlDrop()
|
|
{
|
|
return String.Format("DROP {0} {1}\r\nGO\r\n", typeName, FullName);
|
|
}
|
|
|
|
public virtual bool CompareExceptWhitespace(ICode obj)
|
|
{
|
|
if (obj == null) throw new ArgumentNullException("obj");
|
|
string sql1 = this.ToSql();
|
|
string sql2 = obj.ToSql();
|
|
|
|
Regex whitespace = new Regex(@"\s");
|
|
sql1 = whitespace.Replace(this.ToSql(), "");
|
|
sql2 = whitespace.Replace(obj.ToSql(), "");
|
|
|
|
if (((Database)RootParent).Options.Comparison.CaseSensityInCode == Options.SqlOptionComparison.CaseSensityOptions.CaseInsensity)
|
|
return (sql1.Equals(sql2, StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
return (sql1.Equals(sql2, StringComparison.InvariantCulture));
|
|
}
|
|
|
|
public virtual bool Compare(ICode obj)
|
|
{
|
|
if (obj == null) throw new ArgumentNullException("obj");
|
|
string sql1 = this.ToSql();
|
|
string sql2 = obj.ToSql();
|
|
if (((Database)RootParent).Options.Comparison.IgnoreWhiteSpacesInCode)
|
|
{
|
|
Regex whitespace = new Regex(@"\s");
|
|
sql1 = whitespace.Replace(this.ToSql(), "");
|
|
sql2 = whitespace.Replace(obj.ToSql(), "");
|
|
}
|
|
if (((Database)RootParent).Options.Comparison.CaseSensityInCode == SqlOptionComparison.CaseSensityOptions.CaseInsensity)
|
|
return (sql1.Equals(sql2, StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
return (sql1.Equals(sql2, StringComparison.InvariantCulture));
|
|
}
|
|
}
|
|
}
|