Initial commit
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareAssemblies : CompareBase<Assembly>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<Assembly, Root> originFields, Assembly node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
Assembly newNode = (Assembly)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
|
||||
if (node.Text.Equals(originFields[node.FullName].Text))
|
||||
{
|
||||
if (!node.PermissionSet.Equals(originFields[node.FullName].PermissionSet))
|
||||
newNode.Status += (int)ObjectStatus.PermissionSet;
|
||||
if (!node.Owner.Equals(originFields[node.FullName].Owner))
|
||||
newNode.Status += (int)ObjectStatus.ChangeOwner;
|
||||
}
|
||||
else
|
||||
newNode.Status = ObjectStatus.Rebuild;
|
||||
|
||||
originFields[node.FullName].Files.ForEach(item =>
|
||||
{
|
||||
if (!newNode.Files.Contains(item.FullName))
|
||||
newNode.Files.Add(new AssemblyFile(newNode, item, ObjectStatus.Drop));
|
||||
else
|
||||
item.Status = ObjectStatus.Alter;
|
||||
});
|
||||
newNode.Files.ForEach(item =>
|
||||
{
|
||||
if (!originFields[node.FullName].Files.Contains(item.FullName))
|
||||
{
|
||||
item.Status = ObjectStatus.Create;
|
||||
}
|
||||
});
|
||||
CompareExtendedProperties(originFields[node.FullName], newNode);
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoNew<Root>(SchemaList<Assembly, Root> originFields, Assembly node)
|
||||
{
|
||||
bool pass = true;
|
||||
Assembly newNode = (Assembly)node.Clone(originFields.Parent);
|
||||
if ((((Database)newNode.RootParent).Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2005)
|
||||
&& (((Database)node.RootParent).Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008))
|
||||
pass = node.FullName.Equals("Microsoft.SqlServer.Types");
|
||||
if (pass)
|
||||
{
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
90
OpenDBDiff.Schema.SQLServer.Generates/Compare/CompareBase.cs
Normal file
90
OpenDBDiff.Schema.SQLServer.Generates/Compare/CompareBase.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal abstract class CompareBase<T> where T : ISchemaBase
|
||||
{
|
||||
protected virtual void DoUpdate<Root>(SchemaList<T, Root> originFields, T node) where Root : ISchemaBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void DoNew<Root>(SchemaList<T, Root> originFields, T node) where Root : ISchemaBase
|
||||
{
|
||||
T newNode = node;//.Clone(originFields.Parent);
|
||||
newNode.Parent = originFields.Parent;
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
|
||||
protected void DoDelete(T node)
|
||||
{
|
||||
node.Status = ObjectStatus.Drop;
|
||||
}
|
||||
|
||||
public void GenerateDifferences<Root>(SchemaList<T, Root> originFields, SchemaList<T, Root> destinationFields) where Root : ISchemaBase
|
||||
{
|
||||
bool has = true;
|
||||
int destinationIndex = 0;
|
||||
int originIndex = 0;
|
||||
int destinationCount = destinationFields.Count;
|
||||
int originCount = originFields.Count;
|
||||
T node;
|
||||
|
||||
while (has)
|
||||
{
|
||||
has = false;
|
||||
if (destinationCount > destinationIndex)
|
||||
{
|
||||
node = destinationFields[destinationIndex];
|
||||
Generate.RaiseOnCompareProgress("Comparing Destination {0}: [{1}]", node.ObjectType, node.Name);
|
||||
if (!originFields.Contains(node.FullName))
|
||||
{
|
||||
Generate.RaiseOnCompareProgress("Adding {0}: [{1}]", node.ObjectType, node.Name);
|
||||
DoNew<Root>(originFields, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
Generate.RaiseOnCompareProgress("Updating {0}: [{1}]", node.ObjectType, node.Name);
|
||||
DoUpdate<Root>(originFields, node);
|
||||
}
|
||||
|
||||
destinationIndex++;
|
||||
has = true;
|
||||
}
|
||||
|
||||
if (originCount > originIndex)
|
||||
{
|
||||
node = originFields[originIndex];
|
||||
Generate.RaiseOnCompareProgress("Comparing Source {0}: [{1}]", node.ObjectType, node.Name);
|
||||
if (!destinationFields.Contains(node.FullName))
|
||||
{
|
||||
Generate.RaiseOnCompareProgress("Deleting {0}: [{1}]", node.ObjectType, node.Name);
|
||||
DoDelete(node);
|
||||
}
|
||||
|
||||
originIndex++;
|
||||
has = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void CompareExtendedProperties(ISQLServerSchemaBase origin, ISQLServerSchemaBase destination)
|
||||
{
|
||||
List<ExtendedProperty> dropList = (from node in origin.ExtendedProperties
|
||||
where !destination.ExtendedProperties.Exists(item => item.Name.Equals(node.Name, StringComparison.CurrentCultureIgnoreCase))
|
||||
select node).ToList<ExtendedProperty>();
|
||||
List<ExtendedProperty> addList = (from node in destination.ExtendedProperties
|
||||
where !origin.ExtendedProperties.Exists(item => item.Name.Equals(node.Name, StringComparison.CurrentCultureIgnoreCase))
|
||||
select node).ToList<ExtendedProperty>();
|
||||
dropList.ForEach(item => { item.Status = ObjectStatus.Drop; });
|
||||
addList.ForEach(item => { item.Status = ObjectStatus.Create; });
|
||||
origin.ExtendedProperties.AddRange(addList);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareCLRFunction : CompareBase<CLRFunction>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<CLRFunction, Root> originFields, CLRFunction node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
CLRFunction newNode = node; //.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareCLRStoredProcedure : CompareBase<CLRStoredProcedure>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<CLRStoredProcedure, Root> originFields, CLRStoredProcedure node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
CLRStoredProcedure newNode = node; //.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareCLRTriggers : CompareBase<CLRTrigger>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<CLRTrigger, Root> originFields, CLRTrigger node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
CLRTrigger newNode = node;
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
CompareExtendedProperties(newNode, originFields[node.FullName]);
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
public class CompareColumns
|
||||
{
|
||||
public void GenerateDifferences<T>(Columns<T> originFields, Columns<T> destinationFields) where T : ISchemaBase
|
||||
{
|
||||
int restPosition = 0;
|
||||
int sumPosition = 0;
|
||||
|
||||
foreach (Column node in originFields)
|
||||
{
|
||||
if (!destinationFields.Contains(node.FullName))
|
||||
{
|
||||
node.Status = ObjectStatus.Drop;
|
||||
restPosition++;
|
||||
}
|
||||
else
|
||||
originFields[node.FullName].Position -= restPosition;
|
||||
}
|
||||
foreach (Column node in destinationFields)
|
||||
{
|
||||
if (!originFields.Contains(node.FullName))
|
||||
{
|
||||
Column newNode = node.Clone(originFields.Parent);
|
||||
if ((newNode.Position == 1) || ((newNode.DefaultConstraint == null) && (!newNode.IsNullable) && (!newNode.IsComputed) && (!newNode.IsIdentity) && (!newNode.IsIdentityForReplication)))
|
||||
{
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
newNode.Parent.Status = ObjectStatus.Rebuild;
|
||||
}
|
||||
else
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
sumPosition++;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Column originField = originFields[node.FullName];
|
||||
/*ColumnConstraint oldDefault = null;
|
||||
if (originField.DefaultConstraint != null)
|
||||
oldDefault = originField.DefaultConstraint.Clone(originField);*/
|
||||
Boolean IsColumnEqual = Column.Compare(originField, node);
|
||||
if ((!IsColumnEqual) || (originField.Position != node.Position))
|
||||
{
|
||||
if (Column.CompareIdentity(originField, node))
|
||||
{
|
||||
|
||||
if (node.HasToRebuildOnlyConstraint)
|
||||
{
|
||||
node.Status = ObjectStatus.Alter;
|
||||
if ((originField.IsNullable) && (!node.IsNullable))
|
||||
node.Status += (int)ObjectStatus.Update;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node.HasToRebuild(originField.Position + sumPosition, originField.Type, originField.IsFileStream))
|
||||
node.Status = ObjectStatus.Rebuild;
|
||||
else
|
||||
{
|
||||
if (!IsColumnEqual)
|
||||
{
|
||||
node.Status = ObjectStatus.Alter;
|
||||
if ((originField.IsNullable) && (!node.IsNullable))
|
||||
node.Status += (int)ObjectStatus.Update;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.Status != ObjectStatus.Rebuild)
|
||||
{
|
||||
if (!Column.CompareRule(originField, node))
|
||||
{
|
||||
node.Status += (int)ObjectStatus.Bind;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
node.Status = ObjectStatus.Rebuild;
|
||||
}
|
||||
originFields[node.FullName] = node.Clone(originFields.Parent);
|
||||
}
|
||||
originFields[node.FullName].DefaultConstraint = CompareColumnsConstraints.GenerateDifferences(originField, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareColumnsConstraints : CompareBase<ColumnConstraint>
|
||||
{
|
||||
public static ColumnConstraint GenerateDifferences(Column originFields, Column destinationFields)
|
||||
{
|
||||
if ((originFields.DefaultConstraint == null) && (destinationFields.DefaultConstraint != null))
|
||||
{
|
||||
originFields.DefaultConstraint = destinationFields.DefaultConstraint.Clone(originFields);
|
||||
originFields.DefaultConstraint.Status = ObjectStatus.Create;
|
||||
originFields.DefaultConstraint.Parent.Status = ObjectStatus.Original;
|
||||
originFields.DefaultConstraint.Parent.Parent.Status = ObjectStatus.Alter;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((originFields.DefaultConstraint != null) && (destinationFields.DefaultConstraint != null))
|
||||
{
|
||||
if (!ColumnConstraint.Compare(originFields.DefaultConstraint, destinationFields.DefaultConstraint))
|
||||
{
|
||||
originFields.DefaultConstraint = destinationFields.DefaultConstraint.Clone(originFields);
|
||||
//Indico que hay un ALTER TABLE, pero sobre la columna, no seteo ningun estado.
|
||||
originFields.DefaultConstraint.Status = ObjectStatus.Alter;
|
||||
originFields.DefaultConstraint.Parent.Status = ObjectStatus.Original;
|
||||
originFields.DefaultConstraint.Parent.Parent.Status = ObjectStatus.Alter;
|
||||
}
|
||||
}
|
||||
else
|
||||
if ((originFields.DefaultConstraint != null) && (destinationFields.DefaultConstraint == null))
|
||||
{
|
||||
originFields.DefaultConstraint.Status = ObjectStatus.Drop;
|
||||
originFields.DefaultConstraint.Parent.Status = ObjectStatus.Original;
|
||||
originFields.DefaultConstraint.Parent.Parent.Status = ObjectStatus.Alter;
|
||||
}
|
||||
}
|
||||
/*foreach (ColumnConstraint node in destinationFields)
|
||||
{
|
||||
if (!originFields.Exists(node.FullName))
|
||||
{
|
||||
node.Status = ObjectStatusType.CreateStatus;
|
||||
originFields.Parent.Status = ObjectStatusType.OriginalStatus;
|
||||
originFields.Parent.Parent.Status = ObjectStatusType.AlterStatus;
|
||||
originFields.Add(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ColumnConstraint.Compare(originFields[node.FullName], node))
|
||||
{
|
||||
ColumnConstraint newNode = node.Clone(originFields.Parent);
|
||||
//Indico que hay un ALTER TABLE, pero sobre la columna, no seteo ningun estado.
|
||||
newNode.Status = ObjectStatusType.AlterStatus;
|
||||
newNode.Parent.Status = ObjectStatusType.OriginalStatus;
|
||||
newNode.Parent.Parent.Status = ObjectStatusType.AlterStatus;
|
||||
originFields[node.FullName] = newNode;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MarkDrop(originFields, destinationFields, node =>
|
||||
{
|
||||
node.Status = ObjectStatusType.DropStatus;
|
||||
originFields.Parent.Status = ObjectStatusType.OriginalStatus;
|
||||
originFields.Parent.Parent.Status = ObjectStatusType.AlterStatus;
|
||||
}
|
||||
);
|
||||
*/
|
||||
return originFields.DefaultConstraint;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareConstraints : CompareBase<Constraint>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<Constraint, Root> originFields, Constraint node)
|
||||
{
|
||||
Constraint origin = originFields[node.FullName];
|
||||
if (!Constraint.Compare(origin, node))
|
||||
{
|
||||
Constraint newNode = (Constraint)node.Clone(originFields.Parent);
|
||||
if (node.IsDisabled == origin.IsDisabled)
|
||||
{
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
}
|
||||
else
|
||||
newNode.Status = ObjectStatus.Alter + (int)ObjectStatus.Disabled;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node.IsDisabled != origin.IsDisabled)
|
||||
{
|
||||
Constraint newNode = (Constraint)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Disabled;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoNew<Root>(SchemaList<Constraint, Root> originFields, Constraint node)
|
||||
{
|
||||
Constraint newNode = (Constraint)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareDDLTriggers : CompareBase<Trigger>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<Trigger, Root> originFields, Trigger node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
Trigger newNode = (Trigger)node.Clone(originFields.Parent);
|
||||
if (!newNode.Text.Equals(originFields[node.FullName].Text))
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
if (node.IsDisabled != originFields[node.FullName].IsDisabled)
|
||||
newNode.Status = newNode.Status + (int)ObjectStatus.Disabled;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoNew<Root>(SchemaList<Trigger, Root> originFields, Trigger node)
|
||||
{
|
||||
Trigger newNode = (Trigger)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using OpenDBDiff.Schema.Misc;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal static class CompareDatabase
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates the differences to migrate a schema from origin to destination
|
||||
/// </summary>
|
||||
/// <param name="origin">The Origin schema is the schema before our generated actions are applied.</param>
|
||||
/// <param name="destination">The Destination schema is the schema after our actions are applied.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="SchemaException"></exception>
|
||||
public static Database GenerateDifferences(Database origin, Database destination)
|
||||
{
|
||||
try
|
||||
{
|
||||
Database data = origin;
|
||||
(new CompareTables()).GenerateDifferences<Database>(origin.Tables, destination.Tables);
|
||||
(new CompareAssemblies()).GenerateDifferences<Database>(origin.Assemblies, destination.Assemblies);
|
||||
(new CompareUserDataTypes()).GenerateDifferences<Database>(origin.UserTypes, destination.UserTypes);
|
||||
(new CompareXMLSchemas()).GenerateDifferences<Database>(origin.XmlSchemas, destination.XmlSchemas);
|
||||
(new CompareSchemas()).GenerateDifferences<Database>(origin.Schemas, destination.Schemas);
|
||||
(new CompareFileGroups()).GenerateDifferences<Database>(origin.FileGroups, destination.FileGroups);
|
||||
(new CompareRules()).GenerateDifferences<Database>(origin.Rules, destination.Rules);
|
||||
(new CompareDDLTriggers()).GenerateDifferences<Database>(origin.DDLTriggers, destination.DDLTriggers);
|
||||
(new CompareSynonyms()).GenerateDifferences<Database>(origin.Synonyms, destination.Synonyms);
|
||||
(new CompareUsers()).GenerateDifferences<Database>(origin.Users, destination.Users);
|
||||
(new CompareStoredProcedures()).GenerateDifferences<Database>(origin.Procedures, destination.Procedures);
|
||||
(new CompareCLRStoredProcedure()).GenerateDifferences<Database>(origin.CLRProcedures, destination.CLRProcedures);
|
||||
(new CompareCLRFunction()).GenerateDifferences<Database>(origin.CLRFunctions, destination.CLRFunctions);
|
||||
(new CompareViews()).GenerateDifferences<Database>(origin.Views, destination.Views);
|
||||
(new CompareFunctions()).GenerateDifferences<Database>(origin.Functions, destination.Functions);
|
||||
(new CompareRoles()).GenerateDifferences<Database>(origin.Roles, destination.Roles);
|
||||
(new ComparePartitionFunction()).GenerateDifferences<Database>(origin.PartitionFunctions, destination.PartitionFunctions);
|
||||
(new ComparePartitionSchemes()).GenerateDifferences<Database>(origin.PartitionSchemes, destination.PartitionSchemes);
|
||||
(new CompareTableType()).GenerateDifferences<Database>(origin.TablesTypes, destination.TablesTypes);
|
||||
(new CompareFullText()).GenerateDifferences<Database>(origin.FullText, destination.FullText);
|
||||
data.SourceInfo = destination.Info;
|
||||
return data;
|
||||
}
|
||||
catch (SchemaException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new SchemaException(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareFileGroups : CompareBase<FileGroup>
|
||||
{
|
||||
protected override void DoNew<Root>(SchemaList<FileGroup, Root> originFields, FileGroup node)
|
||||
{
|
||||
FileGroup newNode = (FileGroup)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
/*If the Logical File Name exists in another filegroup,
|
||||
* we must change the new Logical File Name.
|
||||
*/
|
||||
originFields.ForEach(file =>
|
||||
{
|
||||
if (file.Status != ObjectStatus.Drop)
|
||||
{
|
||||
file.Files.ForEach(group =>
|
||||
{
|
||||
newNode.Files.ForEach(ngroup =>
|
||||
{
|
||||
if (group.CompareFullNameTo(group.FullName, ngroup.FullName) == 0)
|
||||
{
|
||||
newNode.Files[ngroup.FullName].Name = group.Name + "_2";
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
|
||||
protected override void DoUpdate<Root>(SchemaList<FileGroup, Root> originFields, FileGroup node)
|
||||
{
|
||||
if (!FileGroup.Compare(node, originFields[node.FullName]))
|
||||
{
|
||||
FileGroup newNode = (FileGroup)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareFullText : CompareBase<FullText>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<FullText, Root> originFields, FullText node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
FullText newNode = node; //.Clone(originFields.Parent);
|
||||
if (node.IsDefault != originFields[node.FullName].IsDefault)
|
||||
newNode.Status += (int)ObjectStatus.Disabled;
|
||||
if (!node.Owner.Equals(originFields[node.FullName].Owner))
|
||||
newNode.Status += (int)ObjectStatus.ChangeOwner;
|
||||
if (node.IsAccentSensity != originFields[node.FullName].IsAccentSensity)
|
||||
newNode.Status += (int)ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareFullTextIndex : CompareBase<FullTextIndex>
|
||||
{
|
||||
protected override void DoNew<Root>(SchemaList<FullTextIndex, Root> originFields, FullTextIndex node)
|
||||
{
|
||||
FullTextIndex newNode = (FullTextIndex)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
|
||||
protected override void DoUpdate<Root>(SchemaList<FullTextIndex, Root> originFields, FullTextIndex node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
FullTextIndex newNode = (FullTextIndex)node.Clone(originFields.Parent);
|
||||
if (node.IsDisabled != originFields[node.FullName].IsDisabled)
|
||||
newNode.Status += (int)ObjectStatus.Disabled;
|
||||
else
|
||||
newNode.Status += (int)ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareFunctions : CompareBase<Function>
|
||||
{
|
||||
protected override void DoNew<Root>(SchemaList<Function, Root> originFields, Function node)
|
||||
{
|
||||
Function newNode = (Function)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
newNode.DependenciesIn.ForEach(dep =>
|
||||
{
|
||||
ISchemaBase item = ((Database)((ISchemaBase)originFields.Parent)).Find(dep);
|
||||
if (item != null)
|
||||
{
|
||||
if (item.IsCodeType)
|
||||
((ICode)item).DependenciesOut.Add(newNode.FullName);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected override void DoUpdate<Root>(SchemaList<Function, Root> originFields, Function node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
Function newNode = (Function)node.Clone(originFields.Parent);
|
||||
newNode.DependenciesIn.AddRange(originFields[node.FullName].DependenciesIn);
|
||||
newNode.DependenciesOut.AddRange(originFields[node.FullName].DependenciesOut);
|
||||
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
if (newNode.IsSchemaBinding)
|
||||
newNode.Status += (int)ObjectStatus.RebuildDependencies;
|
||||
if (newNode.HasToRebuild)
|
||||
newNode.Status += (int)ObjectStatus.Rebuild;
|
||||
else
|
||||
newNode.Status += (int)ObjectStatus.AlterBody;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareIndexes : CompareBase<Index>
|
||||
{
|
||||
protected override void DoNew<Root>(SchemaList<Index, Root> originFields, Index node)
|
||||
{
|
||||
Index newNode = (Index)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
|
||||
protected override void DoUpdate<Root>(SchemaList<Index, Root> originFields, Index node)
|
||||
{
|
||||
if (!Index.Compare(node, originFields[node.FullName]))
|
||||
{
|
||||
Index newNode = (Index)node.Clone(originFields.Parent);
|
||||
if (!Index.CompareExceptIsDisabled(node, originFields[node.FullName]))
|
||||
{
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
}
|
||||
else
|
||||
newNode.Status = ObjectStatus.Disabled;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class ComparePartitionFunction : CompareBase<PartitionFunction>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<PartitionFunction, Root> originFields, PartitionFunction node)
|
||||
{
|
||||
if (!PartitionFunction.Compare(node, originFields[node.FullName]))
|
||||
{
|
||||
PartitionFunction newNode = node; //.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Rebuild;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!PartitionFunction.CompareValues(node, originFields[node.FullName]))
|
||||
{
|
||||
PartitionFunction newNode = node.Clone(originFields.Parent);
|
||||
if (newNode.Values.Count == originFields[node.FullName].Values.Count)
|
||||
newNode.Status = ObjectStatus.Rebuild;
|
||||
else
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
newNode.Old = originFields[node.FullName].Clone(originFields.Parent);
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class ComparePartitionSchemes : CompareBase<PartitionScheme>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<PartitionScheme, Root> originFields, PartitionScheme node)
|
||||
{
|
||||
if (!PartitionScheme.Compare(node, originFields[node.FullName]))
|
||||
{
|
||||
PartitionScheme newNode = node; //.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Rebuild;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareRoles : CompareBase<Role>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<Role, Root> originFields, Role node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
Role newNode = node;
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareRules : CompareBase<Rule>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<Rule, Root> originFields, Rule node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
Rule newNode = node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoNew<Root>(SchemaList<Rule, Root> originFields, Rule node)
|
||||
{
|
||||
Rule newNode = node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareSchemas : CompareBase<Model.Schema>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareStoredProcedures : CompareBase<StoredProcedure>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<StoredProcedure, Root> originFields, StoredProcedure node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
StoredProcedure newNode = node; //.Clone(originFields.Parent);
|
||||
|
||||
if (node.CompareExceptWhitespace(originFields[node.FullName]))
|
||||
{
|
||||
newNode.Status = ObjectStatus.AlterWhitespace;
|
||||
}
|
||||
else
|
||||
{
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
}
|
||||
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareSynonyms : CompareBase<Synonym>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<Synonym, Root> originFields, Synonym node)
|
||||
{
|
||||
if (!Synonym.Compare(node, originFields[node.FullName]))
|
||||
{
|
||||
Synonym newNode = node; //.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareTableType : CompareBase<TableType>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<TableType, Root> originFields, TableType node)
|
||||
{
|
||||
if (node.Status != ObjectStatus.Drop)
|
||||
{
|
||||
TableType tablaOriginal = originFields[node.FullName];
|
||||
(new CompareColumns()).GenerateDifferences<TableType>(tablaOriginal.Columns, node.Columns);
|
||||
(new CompareConstraints()).GenerateDifferences<TableType>(tablaOriginal.Constraints, node.Constraints);
|
||||
(new CompareIndexes()).GenerateDifferences<TableType>(tablaOriginal.Indexes, node.Indexes);
|
||||
}
|
||||
}
|
||||
|
||||
/*public static void GenerateDifferences(SchemaList<TableType, Database> originTables, SchemaList<TableType, Database> destinationTables)
|
||||
{
|
||||
MarkDrop(originTables, destinationTables);
|
||||
|
||||
foreach (TableType node in destinationTables)
|
||||
{
|
||||
if (!originTables.Exists(node.FullName))
|
||||
{
|
||||
node.Status = ObjectStatusType.CreateStatus;
|
||||
node.Parent = originTables.Parent;
|
||||
originTables.Add(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node.Status != ObjectStatusType.DropStatus)
|
||||
{
|
||||
TableType tablaOriginal = originTables[node.FullName];
|
||||
CompareColumns.GenerateDifferences<TableType>(tablaOriginal.Columns, node.Columns);
|
||||
CompareConstraints.GenerateDifferences<TableType>(tablaOriginal.Constraints, node.Constraints);
|
||||
CompareIndexes.GenerateDifferences(tablaOriginal.Indexes, node.Indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareTables : CompareBase<Table>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<Table, Root> originFields, Table node)
|
||||
{
|
||||
if (node.Status != ObjectStatus.Drop)
|
||||
{
|
||||
Table tablaOriginal = originFields[node.FullName];
|
||||
tablaOriginal.OriginalTable = (Table)originFields[node.FullName].Clone((Database)tablaOriginal.Parent);
|
||||
(new CompareColumns()).GenerateDifferences<Table>(tablaOriginal.Columns, node.Columns);
|
||||
(new CompareConstraints()).GenerateDifferences<Table>(tablaOriginal.Constraints, node.Constraints);
|
||||
(new CompareIndexes()).GenerateDifferences<Table>(tablaOriginal.Indexes, node.Indexes);
|
||||
(new CompareTablesOptions()).GenerateDifferences<Table>(tablaOriginal.Options, node.Options);
|
||||
(new CompareTriggers()).GenerateDifferences<Table>(tablaOriginal.Triggers, node.Triggers);
|
||||
(new CompareCLRTriggers()).GenerateDifferences<Table>(tablaOriginal.CLRTriggers, node.CLRTriggers);
|
||||
(new CompareFullTextIndex()).GenerateDifferences<Table>(tablaOriginal.FullTextIndex, node.FullTextIndex);
|
||||
if (!Table.CompareFileGroup(tablaOriginal, node))
|
||||
{
|
||||
tablaOriginal.FileGroup = node.FileGroup;
|
||||
/*Esto solo aplica a las tablas heap, el resto hace el campo en el filegroup del indice clustered*/
|
||||
if (!tablaOriginal.HasClusteredIndex)
|
||||
tablaOriginal.Status = ObjectStatus.Rebuild;
|
||||
}
|
||||
if (!Table.CompareFileGroupText(tablaOriginal, node))
|
||||
{
|
||||
tablaOriginal.FileGroupText = node.FileGroupText;
|
||||
tablaOriginal.Status = ObjectStatus.Rebuild;
|
||||
}
|
||||
if (node.HasChangeTracking != tablaOriginal.HasChangeTracking)
|
||||
{
|
||||
tablaOriginal.HasChangeTracking = node.HasChangeTracking;
|
||||
tablaOriginal.HasChangeTrackingTrackColumn = node.HasChangeTrackingTrackColumn;
|
||||
tablaOriginal.Status += (int)ObjectStatus.Disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara las colecciones de tablas de dos bases diferentes y marca el estado de los objetos
|
||||
/// dependiendo si existen o si deben borrarse.
|
||||
/// </summary>
|
||||
/// <param name="originTables"></param>
|
||||
/// Tablas originales, donde se guardaran los estados de las tablas.
|
||||
/// <param name="destinationTables">
|
||||
/// Tablas comparativas, que se usa para comparar con la base original.
|
||||
/// </param>
|
||||
/*public static void GenerateDifferences(SchemaList<Table, Database> originTables, SchemaList<Table, Database> destinationTables)
|
||||
{
|
||||
MarkDrop(originTables, destinationTables);
|
||||
|
||||
foreach (Table node in destinationTables)
|
||||
{
|
||||
if (!originTables.Exists(node.FullName))
|
||||
{
|
||||
node.Status = ObjectStatusType.CreateStatus;
|
||||
node.Parent = originTables.Parent;
|
||||
originTables.Add(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node.Status != ObjectStatusType.DropStatus)
|
||||
{
|
||||
Table tablaOriginal = originTables[node.FullName];
|
||||
tablaOriginal.OriginalTable = (Table)originTables[node.FullName].Clone((Database)tablaOriginal.Parent);
|
||||
CompareColumns.GenerateDifferences<Table>(tablaOriginal.Columns, node.Columns);
|
||||
CompareConstraints.GenerateDifferences<Table>(tablaOriginal.Constraints, node.Constraints);
|
||||
CompareIndexes.GenerateDifferences(tablaOriginal.Indexes, node.Indexes);
|
||||
CompareTablesOptions.GenerateDifferences(tablaOriginal.Options, node.Options);
|
||||
(new CompareTriggers()).GenerateDifferences<Table>(tablaOriginal.Triggers, node.Triggers);
|
||||
(new CompareCLRTriggers()).GenerateDifferences<Table>(tablaOriginal.CLRTriggers, node.CLRTriggers);
|
||||
if (!Table.CompareFileGroup(tablaOriginal, node))
|
||||
{
|
||||
tablaOriginal.FileGroup = node.FileGroup;
|
||||
//Esto solo aplica a las tablas heap, el resto hace el campo en el filegroup del indice clustered
|
||||
if (!tablaOriginal.HasClusteredIndex)
|
||||
tablaOriginal.Status = ObjectStatusType.RebuildStatus;
|
||||
}
|
||||
if (!Table.CompareFileGroupText(tablaOriginal, node))
|
||||
{
|
||||
tablaOriginal.FileGroupText = node.FileGroupText;
|
||||
tablaOriginal.Status = ObjectStatusType.RebuildStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareTablesOptions : CompareBase<TableOption>
|
||||
{
|
||||
protected override void DoNew<Root>(SchemaList<TableOption, Root> originFields, TableOption node)
|
||||
{
|
||||
TableOption newNode = (TableOption)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
|
||||
protected override void DoUpdate<Root>(SchemaList<TableOption, Root> originFields, TableOption node)
|
||||
{
|
||||
if (!TableOption.Compare(node, originFields[node.FullName]))
|
||||
{
|
||||
TableOption newNode = (TableOption)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareTriggers : CompareBase<Trigger>
|
||||
{
|
||||
protected override void DoNew<Root>(SchemaList<Trigger, Root> originFields, Trigger node)
|
||||
{
|
||||
Trigger newNode = (Trigger)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
|
||||
protected override void DoUpdate<Root>(SchemaList<Trigger, Root> originFields, Trigger node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
Trigger newNode = (Trigger)node.Clone(originFields.Parent);
|
||||
if (!newNode.Text.Equals(originFields[node.FullName].Text))
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
if (node.IsDisabled != originFields[node.FullName].IsDisabled)
|
||||
newNode.Status = newNode.Status + (int)ObjectStatus.Disabled;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareUserDataTypes : CompareBase<UserDataType>
|
||||
{
|
||||
protected override void DoNew<Root>(SchemaList<UserDataType, Root> originFields, UserDataType node)
|
||||
{
|
||||
UserDataType newNode = (UserDataType)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
Boolean HasAssembly = originFields.Exists(item => item.AssemblyFullName.Equals(node.AssemblyFullName) && item.IsAssembly);
|
||||
if (HasAssembly)
|
||||
newNode.Status += (int)ObjectStatus.DropOlder;
|
||||
originFields.Add(newNode);
|
||||
}
|
||||
|
||||
protected override void DoUpdate<Root>(SchemaList<UserDataType, Root> originFields, UserDataType node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
UserDataType newNode = (UserDataType)node.Clone(originFields.Parent);
|
||||
newNode.Dependencies.AddRange(originFields[node.FullName].Dependencies);
|
||||
|
||||
if (!UserDataType.CompareDefault(node, originFields[node.FullName]))
|
||||
{
|
||||
if (!String.IsNullOrEmpty(node.Default.Name))
|
||||
newNode.Default.Status = ObjectStatus.Create;
|
||||
else
|
||||
newNode.Default.Status = ObjectStatus.Drop;
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!UserDataType.CompareRule(node, originFields[node.FullName]))
|
||||
{
|
||||
if (!String.IsNullOrEmpty(node.Rule.Name))
|
||||
newNode.Rule.Status = ObjectStatus.Create;
|
||||
else
|
||||
newNode.Rule.Status = ObjectStatus.Drop;
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
}
|
||||
else
|
||||
newNode.Status = ObjectStatus.Rebuild;
|
||||
}
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareUsers : CompareBase<User>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareViews : CompareBase<View>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<View, Root> originFields, View node)
|
||||
{
|
||||
View original = originFields[node.FullName];
|
||||
if (!node.Compare(original))
|
||||
{
|
||||
View newNode = (View)node.Clone(originFields.Parent);
|
||||
newNode.DependenciesOut.AddRange(original.DependenciesOut);
|
||||
newNode.DependenciesIn.AddRange(original.DependenciesIn);
|
||||
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
newNode.Indexes = original.Indexes;
|
||||
newNode.Triggers = original.Triggers;
|
||||
|
||||
if (newNode.IsSchemaBinding)
|
||||
newNode.Status += (int)ObjectStatus.RebuildDependencies;
|
||||
if (newNode.HasToRebuild)
|
||||
newNode.Status += (int)ObjectStatus.Rebuild;
|
||||
else
|
||||
newNode.Status += (int)ObjectStatus.AlterBody;
|
||||
|
||||
originFields[node.FullName] = newNode;
|
||||
original = newNode;
|
||||
}
|
||||
(new CompareIndexes()).GenerateDifferences<View>(original.Indexes, node.Indexes);
|
||||
(new CompareTriggers()).GenerateDifferences<View>(original.Triggers, node.Triggers);
|
||||
}
|
||||
|
||||
protected override void DoNew<Root>(SchemaList<View, Root> originFields, View node)
|
||||
{
|
||||
View newNode = (View)node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Create;
|
||||
originFields.Add(newNode);
|
||||
newNode.DependenciesIn.ForEach(dep =>
|
||||
{
|
||||
ISchemaBase item = ((Database)((ISchemaBase)originFields.Parent)).Find(dep);
|
||||
if (item != null)
|
||||
{
|
||||
if (item.IsCodeType)
|
||||
((ICode)item).DependenciesOut.Add(newNode.FullName);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Compare
|
||||
{
|
||||
internal class CompareXMLSchemas : CompareBase<XMLSchema>
|
||||
{
|
||||
protected override void DoUpdate<Root>(SchemaList<XMLSchema, Root> originFields, XMLSchema node)
|
||||
{
|
||||
if (!node.Compare(originFields[node.FullName]))
|
||||
{
|
||||
XMLSchema newNode = node.Clone(originFields.Parent);
|
||||
newNode.Status = ObjectStatus.Alter;
|
||||
originFields[node.FullName] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
191
OpenDBDiff.Schema.SQLServer.Generates/Generates/Generate.cs
Normal file
191
OpenDBDiff.Schema.SQLServer.Generates/Generates/Generate.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using OpenDBDiff.Schema.Errors;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.Misc;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Compare;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class Generate
|
||||
{
|
||||
private readonly List<MessageLog> messages;
|
||||
private ProgressEventArgs currentlyReading;
|
||||
|
||||
public Generate()
|
||||
{
|
||||
messages = new List<MessageLog>();
|
||||
OnReading += Generate_OnReading;
|
||||
}
|
||||
|
||||
public static int MaxValue
|
||||
{
|
||||
get { return Constants.READING_MAX; }
|
||||
}
|
||||
|
||||
public string ConnectionString { get; set; }
|
||||
|
||||
private string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
string name;
|
||||
using (var conn = new SqlConnection(ConnectionString))
|
||||
{
|
||||
name = conn.Database;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public SqlOption Options { get; set; }
|
||||
|
||||
private event ProgressEventHandler.ProgressHandler OnReading;
|
||||
|
||||
public event ProgressEventHandler.ProgressHandler OnProgress;
|
||||
|
||||
private void Generate_OnReading(ProgressEventArgs e)
|
||||
{
|
||||
if (OnProgress != null) OnProgress(e);
|
||||
}
|
||||
|
||||
public void RaiseOnReading(ProgressEventArgs e)
|
||||
{
|
||||
this.currentlyReading = e;
|
||||
if (OnReading != null) OnReading(e);
|
||||
}
|
||||
|
||||
public void RaiseOnReadingOne(object name)
|
||||
{
|
||||
if (name != null && this.OnReading != null && this.currentlyReading != null)
|
||||
{
|
||||
var eOne = new ProgressEventArgs(this.currentlyReading.Message, this.currentlyReading.Progress);
|
||||
eOne.Message = eOne.Message.Replace("...", String.Format(": [{0}]", name));
|
||||
this.OnReading(eOne);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Genera el schema de la base de datos seleccionada y devuelve un objeto Database.
|
||||
/// </summary>
|
||||
public Database Process()
|
||||
{
|
||||
string error = "";
|
||||
var databaseSchema = new Database();
|
||||
|
||||
//tables.OnTableProgress += new Progress.ProgressHandler(tables_OnTableProgress);
|
||||
databaseSchema.Options = Options;
|
||||
databaseSchema.Name = Name;
|
||||
databaseSchema.Info = (new GenerateDatabase(ConnectionString, Options)).Get(databaseSchema);
|
||||
/*Thread t1 = new Thread(delegate()
|
||||
{
|
||||
try
|
||||
{*/
|
||||
(new GenerateRules(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateTables(this)).Fill(databaseSchema, ConnectionString, messages);
|
||||
(new GenerateViews(this)).Fill(databaseSchema, ConnectionString, messages);
|
||||
|
||||
if (Options.Ignore.FilterIndex)
|
||||
{
|
||||
(new GenerateIndex(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateFullTextIndex(this)).Fill(databaseSchema, ConnectionString);
|
||||
}
|
||||
(new GenerateUserDataTypes(this)).Fill(databaseSchema, ConnectionString, messages);
|
||||
(new GenerateXMLSchemas(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateSchemas(this)).Fill(databaseSchema, ConnectionString);
|
||||
/*}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = ex.StackTrace;
|
||||
}
|
||||
});
|
||||
Thread t2 = new Thread(delegate()
|
||||
{
|
||||
try
|
||||
{*/
|
||||
|
||||
//not supported in azure yet
|
||||
if (databaseSchema.Info.Version != DatabaseInfo.SQLServerVersion.SQLServerAzure10)
|
||||
{
|
||||
(new GeneratePartitionFunctions(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GeneratePartitionScheme(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateFileGroups(this)).Fill(databaseSchema, ConnectionString);
|
||||
}
|
||||
|
||||
(new GenerateDDLTriggers(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateSynonyms(this)).Fill(databaseSchema, ConnectionString);
|
||||
|
||||
//not supported in azure yet
|
||||
if (databaseSchema.Info.Version != DatabaseInfo.SQLServerVersion.SQLServerAzure10)
|
||||
{
|
||||
(new GenerateAssemblies(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateFullText(this)).Fill(databaseSchema, ConnectionString);
|
||||
}
|
||||
/*}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = ex.StackTrace;
|
||||
}
|
||||
});
|
||||
Thread t3 = new Thread(delegate()
|
||||
{
|
||||
try
|
||||
{*/
|
||||
(new GenerateStoredProcedures(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateFunctions(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateTriggers(this)).Fill(databaseSchema, ConnectionString, messages);
|
||||
(new GenerateTextObjects(this)).Fill(databaseSchema, ConnectionString);
|
||||
(new GenerateUsers(this)).Fill(databaseSchema, ConnectionString);
|
||||
/*}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = ex.StackTrace;
|
||||
}
|
||||
});
|
||||
t1.Start();
|
||||
t2.Start();
|
||||
t3.Start();
|
||||
t1.Join();
|
||||
t2.Join();
|
||||
t3.Join();*/
|
||||
if (String.IsNullOrEmpty(error))
|
||||
{
|
||||
/*Las propiedades extendidas deben ir despues de haber capturado el resto de los objetos de la base*/
|
||||
(new GenerateExtendedProperties(this)).Fill(databaseSchema, ConnectionString, messages);
|
||||
databaseSchema.BuildDependency();
|
||||
return databaseSchema;
|
||||
}
|
||||
else
|
||||
throw new SchemaException(error);
|
||||
}
|
||||
|
||||
private void tables_OnTableProgress(object sender, ProgressEventArgs e)
|
||||
{
|
||||
ProgressEventHandler.RaiseOnChange(e);
|
||||
}
|
||||
|
||||
// TODO: Static because Compare method is static; static events are not my favorite
|
||||
public static event ProgressEventHandler.ProgressHandler OnCompareProgress;
|
||||
|
||||
internal static void RaiseOnCompareProgress(string formatString, params object[] formatParams)
|
||||
{
|
||||
OnCompareProgress?.Invoke(new ProgressEventArgs(String.Format(formatString, formatParams), -1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the differences to migrate a schema from origin to destination
|
||||
/// </summary>
|
||||
/// <param name="origin">The Origin schema is the schema before our generated actions are applied.</param>
|
||||
/// <param name="destination">The Destination schema is the schema after our actions are applied.</param>
|
||||
/// <returns></returns>
|
||||
public static Database Compare(Database origin, Database destination)
|
||||
{
|
||||
Database merge = CompareDatabase.GenerateDifferences(origin, destination);
|
||||
return merge;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateAssemblies
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateAssemblies(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQLFiles()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetAssemblyFiles");
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetAssemblies");
|
||||
}
|
||||
|
||||
private static string ToHex(byte[] stream)
|
||||
{
|
||||
return ByteToHexEncoder.ByteArrayToHex(stream);
|
||||
}
|
||||
|
||||
private static void FillFiles(Database database, string connectionString)
|
||||
{
|
||||
if (database.Options.Ignore.FilterAssemblies)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQLFiles(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
if (((int)reader["FileId"]) != 1)
|
||||
{
|
||||
Assembly assem = database.Assemblies[reader["Name"].ToString()];
|
||||
AssemblyFile file = new AssemblyFile(assem, reader["FileName"].ToString(), ToHex((byte[])reader["FileContent"]));
|
||||
assem.Files.Add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
int lastViewId = 0;
|
||||
if (database.Options.Ignore.FilterAssemblies)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
Assembly item = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
if (lastViewId != (int)reader["assembly_id"])
|
||||
{
|
||||
item = new Assembly(database)
|
||||
{
|
||||
Id = (int)reader["assembly_id"],
|
||||
Name = reader["Name"].ToString(),
|
||||
Owner = reader["Owner"].ToString(),
|
||||
CLRName = reader["clr_name"].ToString(),
|
||||
PermissionSet = reader["permission_set_desc"].ToString(),
|
||||
Text = ToHex((byte[])reader["content"]),
|
||||
Visible = (bool)reader["is_visible"]
|
||||
};
|
||||
lastViewId = item.Id;
|
||||
database.Assemblies.Add(item);
|
||||
}
|
||||
if (!String.IsNullOrEmpty(reader["Dependency"].ToString()))
|
||||
item.DependenciesOut.Add(reader["Dependency"].ToString());
|
||||
if (!String.IsNullOrEmpty(reader["ObjectDependency"].ToString()))
|
||||
item.DependenciesOut.Add(reader["ObjectDependency"].ToString());
|
||||
if (!String.IsNullOrEmpty(reader["UDTName"].ToString()))
|
||||
item.DependenciesOut.Add(reader["UDTName"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
FillFiles(database, connectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Text;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateConstraint
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateConstraint(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
#region Check Functions...
|
||||
public void FillCheck(Database database, string connectionString)
|
||||
{
|
||||
int parentId = 0;
|
||||
ISchemaBase table = null;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(ConstraintSQLCommand.GetCheck(database.Info.Version), conn))
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading constraint...", Constants.READING_CONSTRAINTS));
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
Constraint item = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
root.RaiseOnReadingOne(reader["Name"]);
|
||||
if (parentId != (int)reader["parent_object_id"])
|
||||
{
|
||||
parentId = (int)reader["parent_object_id"];
|
||||
if (reader["ObjectType"].ToString().Trim().Equals("U"))
|
||||
table = database.Tables.Find(parentId);
|
||||
else
|
||||
table = database.TablesTypes.Find(parentId);
|
||||
}
|
||||
if (table != null)
|
||||
{
|
||||
item = new Constraint(table);
|
||||
item.Id = (int)reader["id"];
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.Type = Constraint.ConstraintType.Check;
|
||||
item.Definition = reader["Definition"].ToString();
|
||||
item.WithNoCheck = (bool)reader["WithCheck"];
|
||||
item.IsDisabled = (bool)reader["is_disabled"];
|
||||
item.Owner = reader["Owner"].ToString();
|
||||
if (database.Options.Ignore.FilterNotForReplication)
|
||||
item.NotForReplication = (bool)reader["is_not_for_replication"];
|
||||
if (reader["ObjectType"].ToString().Trim().Equals("U"))
|
||||
((Table)table).Constraints.Add(item);
|
||||
else
|
||||
((TableType)table).Constraints.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ForeignKey Functions...
|
||||
|
||||
private static string GetSQLForeignKey()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetForeignKeys");
|
||||
}
|
||||
|
||||
private static void FillForeignKey(Database database, string connectionString)
|
||||
{
|
||||
int lastid = 0;
|
||||
int parentId = 0;
|
||||
Table table = null;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQLForeignKey(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
Constraint con = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
if (parentId != (int)reader["parent_object_id"])
|
||||
{
|
||||
parentId = (int)reader["parent_object_id"];
|
||||
table = database.Tables.Find(parentId);
|
||||
}
|
||||
|
||||
if (table != null)
|
||||
{
|
||||
if (lastid != (int)reader["object_id"])
|
||||
{
|
||||
con = new Constraint(table);
|
||||
con.Id = (int)reader["object_id"];
|
||||
con.Name = reader["Name"].ToString();
|
||||
con.Type = Constraint.ConstraintType.ForeignKey;
|
||||
con.WithNoCheck = (bool)reader["is_not_trusted"];
|
||||
con.RelationalTableFullName = "[" + reader["ReferenceOwner"].ToString() + "].[" + reader["TableRelationalName"].ToString() + "]";
|
||||
con.RelationalTableId = (int)reader["TableRelationalId"];
|
||||
con.Owner = reader["Owner"].ToString();
|
||||
con.IsDisabled = (bool)reader["is_disabled"];
|
||||
con.OnDeleteCascade = (byte)reader["delete_referential_action"];
|
||||
con.OnUpdateCascade = (byte)reader["update_referential_action"];
|
||||
if (database.Options.Ignore.FilterNotForReplication)
|
||||
con.NotForReplication = (bool)reader["is_not_for_replication"];
|
||||
lastid = (int)reader["object_id"];
|
||||
table.Constraints.Add(con);
|
||||
}
|
||||
ConstraintColumn ccon = new ConstraintColumn(con);
|
||||
ccon.Name = reader["ColumnName"].ToString();
|
||||
ccon.ColumnRelationalName = reader["ColumnRelationalName"].ToString();
|
||||
ccon.ColumnRelationalId = (int)reader["ColumnRelationalId"];
|
||||
ccon.Id = (int)reader["ColumnId"];
|
||||
ccon.KeyOrder = con.Columns.Count;
|
||||
ccon.ColumnRelationalDataTypeId = (int)reader["user_type_id"];
|
||||
//table.DependenciesCount++;
|
||||
con.Columns.Add(ccon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UniqueKey Functions...
|
||||
private static void FillUniqueKey(Database database, string connectionString)
|
||||
{
|
||||
int lastId = 0;
|
||||
int parentId = 0;
|
||||
bool change = false;
|
||||
ISchemaBase table = null;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(ConstraintSQLCommand.GetUniqueKey(database.Info.Version, database.Info.Edition), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
Constraint con = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
if (parentId != (int)reader["ID"])
|
||||
{
|
||||
parentId = (int)reader["ID"];
|
||||
if (reader["ObjectType"].ToString().Trim().Equals("U"))
|
||||
table = database.Tables.Find(parentId);
|
||||
else
|
||||
table = database.TablesTypes.Find(parentId);
|
||||
change = true;
|
||||
}
|
||||
else
|
||||
change = false;
|
||||
|
||||
if (table != null)
|
||||
{
|
||||
if ((lastId != (int)reader["Index_id"]) || (change))
|
||||
{
|
||||
con = new Constraint(table);
|
||||
con.Name = reader["Name"].ToString();
|
||||
con.Owner = (string)reader["Owner"];
|
||||
con.Id = (int)reader["Index_id"];
|
||||
con.Type = Constraint.ConstraintType.Unique;
|
||||
con.Index.Id = (int)reader["Index_id"];
|
||||
con.Index.AllowPageLocks = (bool)reader["allow_page_locks"];
|
||||
con.Index.AllowRowLocks = (bool)reader["allow_row_locks"];
|
||||
con.Index.FillFactor = (byte)reader["fill_factor"];
|
||||
con.Index.IgnoreDupKey = (bool)reader["ignore_dup_key"];
|
||||
con.Index.IsAutoStatistics = (bool)reader["ignore_dup_key"];
|
||||
con.Index.IsDisabled = (bool)reader["is_disabled"];
|
||||
con.Index.IsPadded = (bool)reader["is_padded"];
|
||||
con.Index.IsPrimaryKey = false;
|
||||
con.Index.IsUniqueKey = true;
|
||||
con.Index.Type = (Index.IndexTypeEnum)(byte)reader["type"];
|
||||
con.Index.Name = con.Name;
|
||||
if (database.Options.Ignore.FilterTableFileGroup)
|
||||
con.Index.FileGroup = reader["FileGroup"].ToString();
|
||||
lastId = (int)reader["Index_id"];
|
||||
if (reader["ObjectType"].ToString().Trim().Equals("U"))
|
||||
((Table)table).Constraints.Add(con);
|
||||
else
|
||||
((TableType)table).Constraints.Add(con);
|
||||
}
|
||||
ConstraintColumn ccon = new ConstraintColumn(con);
|
||||
ccon.Name = reader["ColumnName"].ToString();
|
||||
ccon.IsIncluded = (bool)reader["is_included_column"];
|
||||
ccon.Order = (bool)reader["is_descending_key"];
|
||||
ccon.Id = (int)reader["column_id"];
|
||||
ccon.DataTypeId = (int)reader["user_type_id"];
|
||||
con.Columns.Add(ccon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PrimaryKey Functions...
|
||||
private static void FillPrimaryKey(Database database, string connectionString)
|
||||
{
|
||||
int lastId = 0;
|
||||
int parentId = 0;
|
||||
bool change = false;
|
||||
ISchemaBase table = null;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(ConstraintSQLCommand.GetPrimaryKey(database.Info.Version, null), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
Constraint con = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
if (parentId != (int)reader["ID"])
|
||||
{
|
||||
parentId = (int)reader["ID"];
|
||||
if (reader["ObjectType"].ToString().Trim().Equals("U"))
|
||||
table = database.Tables.Find(parentId);
|
||||
else
|
||||
table = database.TablesTypes.Find(parentId);
|
||||
change = true;
|
||||
}
|
||||
else
|
||||
change = false;
|
||||
|
||||
if (table != null)
|
||||
{
|
||||
if ((lastId != (int)reader["Index_id"]) || (change))
|
||||
{
|
||||
con = new Constraint(table);
|
||||
con.Id = (int)reader["Index_id"];
|
||||
con.Name = (string)reader["Name"];
|
||||
con.Owner = (string)reader["Owner"];
|
||||
con.Type = Constraint.ConstraintType.PrimaryKey;
|
||||
con.Index.Id = (int)reader["Index_id"];
|
||||
con.Index.AllowPageLocks = (bool)reader["allow_page_locks"];
|
||||
con.Index.AllowRowLocks = (bool)reader["allow_row_locks"];
|
||||
con.Index.FillFactor = (byte)reader["fill_factor"];
|
||||
con.Index.IgnoreDupKey = (bool)reader["ignore_dup_key"];
|
||||
con.Index.IsAutoStatistics = (bool)reader["ignore_dup_key"];
|
||||
con.Index.IsDisabled = (bool)reader["is_disabled"];
|
||||
con.Index.IsPadded = (bool)reader["is_padded"];
|
||||
con.Index.IsPrimaryKey = true;
|
||||
con.Index.IsUniqueKey = false;
|
||||
con.Index.Type = (Index.IndexTypeEnum)(byte)reader["type"];
|
||||
con.Index.Name = con.Name;
|
||||
if (database.Options.Ignore.FilterTableFileGroup)
|
||||
con.Index.FileGroup = reader["FileGroup"].ToString();
|
||||
lastId = (int)reader["Index_id"];
|
||||
if (reader["ObjectType"].ToString().Trim().Equals("U"))
|
||||
((Table)table).Constraints.Add(con);
|
||||
else
|
||||
((TableType)table).Constraints.Add(con);
|
||||
}
|
||||
ConstraintColumn ccon = new ConstraintColumn(con);
|
||||
ccon.Name = (string)reader["ColumnName"];
|
||||
ccon.IsIncluded = (bool)reader["is_included_column"];
|
||||
ccon.Order = (bool)reader["is_descending_key"];
|
||||
ccon.KeyOrder = (byte)reader["key_ordinal"];
|
||||
ccon.Id = (int)reader["column_id"];
|
||||
ccon.DataTypeId = (int)reader["user_type_id"];
|
||||
con.Columns.Add(ccon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
if (database.Options.Ignore.FilterConstraintPK)
|
||||
FillPrimaryKey(database, connectionString);
|
||||
if (database.Options.Ignore.FilterConstraintFK)
|
||||
FillForeignKey(database, connectionString);
|
||||
if (database.Options.Ignore.FilterConstraintUK)
|
||||
FillUniqueKey(database, connectionString);
|
||||
if (database.Options.Ignore.FilterConstraintCheck)
|
||||
FillCheck(database, connectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateDDLTriggers
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateDDLTriggers(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetDDLTriggers");
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
if (database.Options.Ignore.FilterDDLTriggers)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Trigger trigger = new Trigger(database);
|
||||
trigger.Text = reader["Text"].ToString();
|
||||
trigger.Name = reader["Name"].ToString();
|
||||
trigger.InsteadOf = (bool)reader["is_instead_of_trigger"];
|
||||
trigger.IsDisabled = (bool)reader["is_disabled"];
|
||||
trigger.IsDDLTrigger = true;
|
||||
trigger.NotForReplication = (bool)reader["is_not_for_replication"];
|
||||
trigger.Owner = "";
|
||||
database.DDLTriggers.Add(trigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using OpenDBDiff.Schema.Misc;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Options;
|
||||
#if DEBUG
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateDatabase
|
||||
{
|
||||
private string connectioString;
|
||||
private SqlOption objectFilter;
|
||||
|
||||
public bool UseDefaultVersionOnVersionParseError { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor de la clase.
|
||||
/// </summary>
|
||||
/// <param name="connectioString">Connection string de la base</param>
|
||||
public GenerateDatabase(string connectioString, SqlOption filter)
|
||||
{
|
||||
this.connectioString = connectioString;
|
||||
this.objectFilter = filter;
|
||||
}
|
||||
|
||||
public DatabaseInfo Get(Database database)
|
||||
{
|
||||
DatabaseInfo item = new DatabaseInfo();
|
||||
using (SqlConnection conn = new SqlConnection(connectioString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(DatabaseSQLCommand.GetVersion(database), conn))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
item.Server = conn.DataSource;
|
||||
item.Database = conn.Database;
|
||||
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
string versionValue = reader["Version"] as string;
|
||||
try
|
||||
{
|
||||
// used to use the decimal as well when Azure was 10.25
|
||||
var version = new Version(versionValue);
|
||||
item.VersionNumber = float.Parse(String.Format("{0}.{1}", version.Major, version.Minor), CultureInfo.InvariantCulture);
|
||||
|
||||
if (reader.FieldCount > 1 && !reader.IsDBNull(1))
|
||||
{
|
||||
int edition;
|
||||
if (int.TryParse(reader[1].ToString(), out edition)
|
||||
&& Enum.IsDefined(typeof(DatabaseInfo.SQLServerEdition), edition))
|
||||
{
|
||||
item.SetEdition((DatabaseInfo.SQLServerEdition)edition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception notAGoodIdeaToCatchAllErrors)
|
||||
{
|
||||
var exception = new SchemaException(
|
||||
String.Format("Error parsing ProductVersion. ({0})", versionValue ?? "[null]")
|
||||
, notAGoodIdeaToCatchAllErrors);
|
||||
|
||||
if (!UseDefaultVersionOnVersionParseError)
|
||||
{
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (SqlCommand command = new SqlCommand(DatabaseSQLCommand.Get(item.Version, item.Edition, database), conn))
|
||||
{
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
item.Collation = reader["Collation"].ToString();
|
||||
item.HasFullTextEnabled = ((int)reader["IsFulltextEnabled"]) == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateDefaults
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateDefaults(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetDefaults");
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
if (database.Options.Ignore.FilterRules)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Default item = new Default(database);
|
||||
item.Id = (int)reader["object_id"];
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.Owner = reader["Owner"].ToString();
|
||||
item.Value = reader["Definition"].ToString();
|
||||
database.Defaults.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.Errors;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateExtendedProperties
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateExtendedProperties(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetExtendedProperties");
|
||||
}
|
||||
|
||||
private static string GetTypeDescription(string type)
|
||||
{
|
||||
if (type.Equals("PC")) return "PROCEDURE";
|
||||
if (type.Equals("P")) return "PROCEDURE";
|
||||
if (type.Equals("V")) return "VIEW";
|
||||
if (type.Equals("U")) return "TABLE";
|
||||
if (type.Equals("TR")) return "TRIGGER";
|
||||
if (type.Equals("TA")) return "TRIGGER";
|
||||
if (type.Equals("FS")) return "FUNCTION";
|
||||
if (type.Equals("FN")) return "FUNCTION";
|
||||
if (type.Equals("IF")) return "FUNCTION";
|
||||
if (type.Equals("TF")) return "FUNCTION";
|
||||
return "";
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString, List<MessageLog> messages)
|
||||
{
|
||||
ISQLServerSchemaBase parent;
|
||||
try
|
||||
{
|
||||
if (database.Options.Ignore.FilterExtendedProperties)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
ExtendedProperty item = new ExtendedProperty(null);
|
||||
if (((byte)reader["Class"]) == 5)
|
||||
{
|
||||
item.Level0type = "ASSEMBLY";
|
||||
item.Level0name = reader["AssemblyName"].ToString();
|
||||
}
|
||||
if (((byte)reader["Class"]) == 1)
|
||||
{
|
||||
string ObjectType = GetTypeDescription(reader["type"].ToString().Trim());
|
||||
item.Level0type = "SCHEMA";
|
||||
item.Level0name = reader["Owner"].ToString();
|
||||
if (!ObjectType.Equals("TRIGGER"))
|
||||
{
|
||||
item.Level1name = reader["ObjectName"].ToString();
|
||||
item.Level1type = ObjectType;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Level1type = "TABLE";
|
||||
item.Level1name = reader["ParentName"].ToString();
|
||||
item.Level2name = reader["ObjectName"].ToString();
|
||||
item.Level2type = ObjectType;
|
||||
}
|
||||
}
|
||||
if (((byte)reader["Class"]) == 6)
|
||||
{
|
||||
item.Level0type = "SCHEMA";
|
||||
item.Level0name = reader["OwnerType"].ToString();
|
||||
item.Level1name = reader["TypeName"].ToString();
|
||||
item.Level1type = "TYPE";
|
||||
}
|
||||
if (((byte)reader["Class"]) == 7)
|
||||
{
|
||||
item.Level0type = "SCHEMA";
|
||||
item.Level0name = reader["Owner"].ToString();
|
||||
item.Level1type = "TABLE";
|
||||
item.Level1name = reader["ObjectName"].ToString();
|
||||
item.Level2type = reader["class_desc"].ToString();
|
||||
item.Level2name = reader["IndexName"].ToString();
|
||||
}
|
||||
item.Value = reader["Value"].ToString();
|
||||
item.Name = reader["Name"].ToString();
|
||||
parent = ((ISQLServerSchemaBase)database.Find(item.FullName));
|
||||
if (parent != null)
|
||||
{
|
||||
item.Parent = (ISchemaBase)parent;
|
||||
parent.ExtendedProperties.Add(item);
|
||||
}
|
||||
else
|
||||
messages.Add(new MessageLog(item.FullName + " not found in extended properties.", "", MessageLog.LogType.Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateFileGroups
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateFileGroups(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQLFile(FileGroup filegroup)
|
||||
{
|
||||
string query = SQLQueries.SQLQueryFactory.Get("GetDatabaseFile");
|
||||
|
||||
return query.Replace("{ID}", filegroup.Id.ToString());
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetFileGroups");
|
||||
}
|
||||
|
||||
private static void FillFiles(FileGroup filegroup, string connectionString)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQLFile(filegroup), conn))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
FileGroupFile item = new FileGroupFile(filegroup);
|
||||
item.Id = (int)reader["file_id"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.Owner = "";
|
||||
item.Growth = (int)reader["growth"];
|
||||
item.IsPercentGrowth = (bool)reader["is_percent_growth"];
|
||||
item.IsSparse = (bool)reader["is_sparse"];
|
||||
item.MaxSize = (int)reader["max_size"];
|
||||
item.PhysicalName = reader["physical_name"].ToString();
|
||||
item.Size = (int)reader["size"];
|
||||
item.Type = (byte)reader["type"];
|
||||
filegroup.Files.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (database.Options.Ignore.FilterTableFileGroup)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
FileGroup item = new FileGroup(database);
|
||||
item.Id = (int)reader["ID"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.Owner = "";
|
||||
item.IsDefaultFileGroup = (bool)reader["is_default"];
|
||||
item.IsReadOnly = (bool)reader["is_read_only"];
|
||||
item.IsFileStream = reader["type"].Equals("FD");
|
||||
FillFiles(item, connectionString);
|
||||
database.FileGroups.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateFullText
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateFullText(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetFullTextCatalogs");
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
if (database.Options.Ignore.FilterFullText)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
FullText item = new FullText(database);
|
||||
item.Id = (int)reader["fulltext_catalog_id"];
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.Owner = reader["Owner"].ToString();
|
||||
item.IsAccentSensity = (bool)reader["is_accent_sensitivity_on"];
|
||||
item.IsDefault = (bool)reader["is_default"];
|
||||
if (!reader.IsDBNull(reader.GetOrdinal("path")))
|
||||
item.Path = reader["path"].ToString().Substring(0, reader["path"].ToString().Length - item.Name.Length);
|
||||
if (!reader.IsDBNull(reader.GetOrdinal("FileGroupName")))
|
||||
item.FileGroupName = reader["FileGroupName"].ToString();
|
||||
database.FullText.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateFullTextIndex
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateFullTextIndex(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
//not supported in azure yet
|
||||
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10) return;
|
||||
|
||||
int parentId = 0;
|
||||
bool change = false;
|
||||
Table parent = null;
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading FullText Index...", Constants.READING_INDEXES));
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(FullTextIndexSQLCommand.Get(database.Info.Version), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
FullTextIndex item = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
root.RaiseOnReadingOne(reader["Name"]);
|
||||
if (parentId != (int)reader["object_id"])
|
||||
{
|
||||
parentId = (int)reader["object_id"];
|
||||
parent = database.Tables.Find(parentId);
|
||||
change = true;
|
||||
}
|
||||
else
|
||||
change = false;
|
||||
if (change)
|
||||
{
|
||||
item = new FullTextIndex(parent);
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.Owner = parent.Owner;
|
||||
item.FullText = reader["FullTextCatalogName"].ToString();
|
||||
item.Index = reader["IndexName"].ToString();
|
||||
item.IsDisabled = !(bool)reader["is_enabled"];
|
||||
item.ChangeTrackingState = reader["ChangeTracking"].ToString();
|
||||
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
|
||||
item.FileGroup = reader["FileGroupName"].ToString();
|
||||
((Table)parent).FullTextIndex.Add(item);
|
||||
}
|
||||
FullTextIndexColumn ccon = new FullTextIndexColumn();
|
||||
ccon.ColumnName = reader["ColumnName"].ToString();
|
||||
ccon.Language = reader["LanguageName"].ToString();
|
||||
item.Columns.Add(ccon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateFunctions
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateFunctions(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQLParameters()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetParameters");
|
||||
}
|
||||
|
||||
private static void FillParameters(Database database, string connectionString)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQLParameters(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var objectName = reader["ObjectName"].ToString();
|
||||
|
||||
if (database.CLRFunctions.Contains(objectName))
|
||||
{
|
||||
Parameter param = new Parameter();
|
||||
param.Name = reader["Name"].ToString();
|
||||
param.Type = reader["TypeName"].ToString();
|
||||
param.Size = (short)reader["max_length"];
|
||||
param.Scale = (byte)reader["scale"];
|
||||
param.Precision = (byte)reader["precision"];
|
||||
param.Output = (bool)reader["is_output"];
|
||||
if (param.Type.Equals("nchar") || param.Type.Equals("nvarchar"))
|
||||
{
|
||||
if (param.Size != -1)
|
||||
param.Size = param.Size / 2;
|
||||
}
|
||||
database.CLRFunctions[objectName].Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
int lastViewId = 0;
|
||||
if ((database.Options.Ignore.FilterFunction) || (database.Options.Ignore.FilterCLRFunction))
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading functions...", Constants.READING_FUNCTIONS));
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(FunctionSQLCommand.Get(database.Info.Version, database.Info.Edition), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
Function itemF = null;
|
||||
CLRFunction itemC = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
root.RaiseOnReadingOne(reader["name"]);
|
||||
if ((!reader["type"].ToString().Trim().Equals("FS")) && (database.Options.Ignore.FilterFunction))
|
||||
{
|
||||
if (lastViewId != (int)reader["object_id"])
|
||||
{
|
||||
itemF = new Function(database);
|
||||
itemF.Id = (int)reader["object_id"];
|
||||
itemF.Name = reader["name"].ToString();
|
||||
itemF.Owner = reader["owner"].ToString();
|
||||
itemF.IsSchemaBinding = reader["IsSchemaBound"].ToString().Equals("1");
|
||||
database.Functions.Add(itemF);
|
||||
lastViewId = itemF.Id;
|
||||
}
|
||||
if (itemF.IsSchemaBinding)
|
||||
{
|
||||
if (!reader.IsDBNull(reader.GetOrdinal("referenced_major_id")))
|
||||
database.Dependencies.Add(database, (int)reader["referenced_major_id"], itemF);
|
||||
if (!String.IsNullOrEmpty(reader["TableName"].ToString()))
|
||||
itemF.DependenciesIn.Add(reader["TableName"].ToString());
|
||||
if (!String.IsNullOrEmpty(reader["DependOut"].ToString()))
|
||||
itemF.DependenciesOut.Add(reader["DependOut"].ToString());
|
||||
}
|
||||
}
|
||||
if ((reader["type"].ToString().Trim().Equals("FS")) && (database.Options.Ignore.FilterCLRFunction))
|
||||
{
|
||||
itemC = new CLRFunction(database);
|
||||
if (lastViewId != (int)reader["object_id"])
|
||||
{
|
||||
itemC.Id = (int)reader["object_id"];
|
||||
itemC.Name = reader["name"].ToString();
|
||||
itemC.Owner = reader["owner"].ToString();
|
||||
itemC.IsAssembly = true;
|
||||
itemC.AssemblyId = (int)reader["assembly_id"];
|
||||
itemC.AssemblyName = reader["assembly_name"].ToString();
|
||||
itemC.AssemblyClass = reader["assembly_class"].ToString();
|
||||
itemC.AssemblyExecuteAs = reader["ExecuteAs"].ToString();
|
||||
itemC.AssemblyMethod = reader["assembly_method"].ToString();
|
||||
itemC.ReturnType.Type = reader["ReturnType"].ToString();
|
||||
itemC.ReturnType.Size = (short)reader["max_length"];
|
||||
itemC.ReturnType.Scale = (byte)reader["Scale"];
|
||||
itemC.ReturnType.Precision = (byte)reader["precision"];
|
||||
if (itemC.ReturnType.Type.Equals("nchar") || itemC.ReturnType.Type.Equals("nvarchar"))
|
||||
{
|
||||
if (itemC.ReturnType.Size != -1)
|
||||
itemC.ReturnType.Size = itemC.ReturnType.Size / 2;
|
||||
}
|
||||
database.CLRFunctions.Add(itemC);
|
||||
lastViewId = itemC.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (database.CLRFunctions.Any())
|
||||
FillParameters(database, connectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
OpenDBDiff.Schema.SQLServer.Generates/Generates/GenerateIndex.cs
Normal file
105
OpenDBDiff.Schema.SQLServer.Generates/Generates/GenerateIndex.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateIndex
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateIndex(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
int indexid = 0;
|
||||
int parentId = 0;
|
||||
bool change = false;
|
||||
string type;
|
||||
ISchemaBase parent = null;
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading Index...", Constants.READING_INDEXES));
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(IndexSQLCommand.Get(database.Info.Version, database.Info.Edition), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
Index item = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
root.RaiseOnReadingOne(reader["Name"]);
|
||||
type = reader["ObjectType"].ToString().Trim();
|
||||
if (parentId != (int)reader["object_id"])
|
||||
{
|
||||
parentId = (int)reader["object_id"];
|
||||
if (type.Equals("V"))
|
||||
parent = database.Views.Find(parentId);
|
||||
else
|
||||
parent = database.Tables.Find(parentId);
|
||||
change = true;
|
||||
}
|
||||
else
|
||||
change = false;
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
if (indexid != (int)reader["index_id"] || change)
|
||||
{
|
||||
item = new Index(parent);
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.Owner = parent.Owner;
|
||||
item.Type = (Index.IndexTypeEnum)(byte)reader["type"];
|
||||
item.Id = (int)reader["index_id"];
|
||||
item.IgnoreDupKey = (bool)reader["ignore_dup_key"];
|
||||
item.IsAutoStatistics = (bool)reader["NoAutomaticRecomputation"];
|
||||
item.IsDisabled = (bool)reader["is_disabled"];
|
||||
item.IsPrimaryKey = (bool)reader["is_primary_key"];
|
||||
item.IsUniqueKey = (bool)reader["is_unique"];
|
||||
if (database.Options.Ignore.FilterIndexRowLock)
|
||||
{
|
||||
item.AllowPageLocks = (bool)reader["allow_page_locks"];
|
||||
item.AllowRowLocks = (bool)reader["allow_row_locks"];
|
||||
}
|
||||
if (database.Options.Ignore.FilterIndexFillFactor)
|
||||
{
|
||||
item.FillFactor = (byte)reader["fill_factor"];
|
||||
item.IsPadded = (bool)reader["is_padded"];
|
||||
}
|
||||
if ((database.Options.Ignore.FilterTableFileGroup) && (item.Type != Index.IndexTypeEnum.XML))
|
||||
item.FileGroup = reader["FileGroup"].ToString();
|
||||
|
||||
if ((database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008) && (database.Options.Ignore.FilterIndexFilter))
|
||||
{
|
||||
item.FilterDefintion = reader["FilterDefinition"].ToString();
|
||||
}
|
||||
indexid = (int)reader["index_id"];
|
||||
if (type.Equals("V"))
|
||||
((View)parent).Indexes.Add(item);
|
||||
else
|
||||
((Table)parent).Indexes.Add(item);
|
||||
}
|
||||
IndexColumn ccon = new IndexColumn(item.Parent);
|
||||
ccon.Name = reader["ColumnName"].ToString();
|
||||
ccon.IsIncluded = (bool)reader["is_included_column"];
|
||||
ccon.Order = (bool)reader["is_descending_key"];
|
||||
ccon.Id = (int)reader["column_id"];
|
||||
ccon.KeyOrder = (byte)reader["key_ordinal"];
|
||||
ccon.DataTypeId = (int)reader["user_type_id"];
|
||||
if ((!ccon.IsIncluded) || (ccon.IsIncluded && database.Options.Ignore.FilterIndexIncludeColumns))
|
||||
item.Columns.Add(ccon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Text;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GeneratePartitionFunctions
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GeneratePartitionFunctions(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetPartitionFunctions");
|
||||
}
|
||||
|
||||
private static string ToHex(byte[] stream)
|
||||
{
|
||||
StringBuilder sHex = new StringBuilder(2 * stream.Length);
|
||||
for (int i = 0; i < stream.Length; i++)
|
||||
sHex.AppendFormat("{0:X2} ", stream[i]);
|
||||
return "0x" + sHex.ToString().Replace(" ", String.Empty);
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectioString)
|
||||
{
|
||||
int lastObjectId = 0;
|
||||
PartitionFunction item = null;
|
||||
if (database.Options.Ignore.FilterPartitionFunction)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectioString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
if (lastObjectId != (int)reader["function_id"])
|
||||
{
|
||||
lastObjectId = (int)reader["function_id"];
|
||||
item = new PartitionFunction(database);
|
||||
item.Id = (int)reader["function_id"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.IsBoundaryRight = (bool)reader["IsRight"];
|
||||
item.Precision = (byte)reader["precision"];
|
||||
item.Scale = (byte)reader["scale"];
|
||||
item.Size = (short)reader["max_length"];
|
||||
item.Type = reader["TypeName"].ToString();
|
||||
database.PartitionFunctions.Add(item);
|
||||
}
|
||||
|
||||
switch (item.Type) {
|
||||
case "binary":
|
||||
case "varbinary":
|
||||
item.Values.Add(ToHex((byte[])reader["value"]));
|
||||
break;
|
||||
case "date":
|
||||
item.Values.Add(String.Format("'{0:yyyy/MM/dd}'", (DateTime)reader["value"]));
|
||||
break;
|
||||
case "smalldatetime":
|
||||
case "datetime":
|
||||
item.Values.Add(String.Format("'{0:yyyy/MM/dd HH:mm:ss.fff}'", (DateTime)reader["value"]));
|
||||
break;
|
||||
default:
|
||||
item.Values.Add(reader["value"].ToString());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GeneratePartitionScheme
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GeneratePartitionScheme(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetPartitionSchemes");
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectioString)
|
||||
{
|
||||
int lastObjectId = 0;
|
||||
PartitionScheme item = null;
|
||||
if (database.Options.Ignore.FilterPartitionScheme)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectioString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
if (lastObjectId != (int)reader["ID"])
|
||||
{
|
||||
lastObjectId = (int)reader["ID"];
|
||||
item = new PartitionScheme(database);
|
||||
item.Id = (int)reader["ID"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.PartitionFunction = reader["FunctionName"].ToString();
|
||||
database.PartitionSchemes.Add(item);
|
||||
}
|
||||
item.FileGroups.Add(reader["FileGroupName"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateRules
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateRules(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetRules");
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
if (database.Options.Ignore.FilterRules)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Rule item = new Rule(database);
|
||||
item.Id = (int)reader["object_id"];
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.Owner = reader["Owner"].ToString();
|
||||
item.Text = reader["Definition"].ToString();
|
||||
database.Rules.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateSchemas
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateSchemas(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetSchemas");
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectioString)
|
||||
{
|
||||
if (database.Options.Ignore.FilterSchema)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectioString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Model.Schema item = new Model.Schema(database);
|
||||
item.Id = (int)reader["schema_id"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.Owner = reader["owner"].ToString();
|
||||
database.Schemas.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateStoredProcedures
|
||||
{
|
||||
private static int NameIndex = -1;
|
||||
private static int object_idIndex = -1;
|
||||
private static int ownerIndex = -1;
|
||||
private static int typeIndex = -1;
|
||||
|
||||
private Generate root;
|
||||
|
||||
public GenerateStoredProcedures(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static void InitIndex(SqlDataReader reader)
|
||||
{
|
||||
if (NameIndex == -1)
|
||||
{
|
||||
object_idIndex = reader.GetOrdinal("object_id");
|
||||
NameIndex = reader.GetOrdinal("Name");
|
||||
ownerIndex = reader.GetOrdinal("owner");
|
||||
typeIndex = reader.GetOrdinal("type");
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetSQLParameters()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetParameters");
|
||||
}
|
||||
|
||||
private static string GetSQL(DatabaseInfo.SQLServerVersion version)
|
||||
{
|
||||
if (version == DatabaseInfo.SQLServerVersion.SQLServerAzure10)
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetProcedures", DatabaseInfo.SQLServerVersion.SQLServerAzure10);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetProcedures");
|
||||
}
|
||||
}
|
||||
|
||||
private static void FillParameters(Database database, string connectionString)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQLParameters(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var objectName = reader["ObjectName"].ToString();
|
||||
|
||||
if (database.CLRProcedures.Contains(objectName))
|
||||
{
|
||||
Parameter param = new Parameter();
|
||||
param.Name = reader["Name"].ToString();
|
||||
param.Type = reader["TypeName"].ToString();
|
||||
param.Size = (short)reader["max_length"];
|
||||
param.Scale = (byte)reader["scale"];
|
||||
param.Precision = (byte)reader["precision"];
|
||||
param.Output = (bool)reader["is_output"];
|
||||
if (param.Type.Equals("nchar") || param.Type.Equals("nvarchar"))
|
||||
{
|
||||
if (param.Size != -1)
|
||||
param.Size = param.Size / 2;
|
||||
}
|
||||
database.CLRProcedures[objectName].Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
if ((database.Options.Ignore.FilterStoredProcedure) || (database.Options.Ignore.FilterCLRStoredProcedure))
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading stored procedures...", Constants.READING_PROCEDURES));
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(database.Info.Version), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
InitIndex(reader);
|
||||
root.RaiseOnReadingOne(reader[NameIndex]);
|
||||
|
||||
var objectType = reader[typeIndex].ToString().Trim();
|
||||
switch (objectType)
|
||||
{
|
||||
case "P":
|
||||
if (database.Options.Ignore.FilterStoredProcedure)
|
||||
{
|
||||
StoredProcedure item = new StoredProcedure(database);
|
||||
item.Id = (int)reader[object_idIndex];
|
||||
item.Name = (string)reader[NameIndex];
|
||||
item.Owner = (string)reader[ownerIndex];
|
||||
database.Procedures.Add(item);
|
||||
}
|
||||
break;
|
||||
|
||||
case "PC":
|
||||
if (database.Options.Ignore.FilterCLRStoredProcedure)
|
||||
{
|
||||
CLRStoredProcedure item = new CLRStoredProcedure(database);
|
||||
item.Id = (int)reader[object_idIndex];
|
||||
item.Name = reader[NameIndex].ToString();
|
||||
item.Owner = reader[ownerIndex].ToString();
|
||||
item.IsAssembly = true;
|
||||
item.AssemblyId = (int)reader["assembly_id"];
|
||||
item.AssemblyName = reader["assembly_name"].ToString();
|
||||
item.AssemblyClass = reader["assembly_class"].ToString();
|
||||
item.AssemblyExecuteAs = reader["ExecuteAs"].ToString();
|
||||
item.AssemblyMethod = reader["assembly_method"].ToString();
|
||||
database.CLRProcedures.Add(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (database.CLRProcedures.Any())
|
||||
FillParameters(database, connectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateSynonyms
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateSynonyms(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetSynonyms");
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
if (database.Options.Ignore.FilterSynonyms)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Synonym item = new Synonym(database);
|
||||
item.Id = (int)reader["object_id"];
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.Owner = reader["Owner"].ToString();
|
||||
item.Value = reader["base_object_name"].ToString();
|
||||
database.Synonyms.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
using OpenDBDiff.Schema.Errors;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Constraint = OpenDBDiff.Schema.SQLServer.Generates.Model.Constraint;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateTables
|
||||
{
|
||||
private int colIDIndex = -1;
|
||||
private int colNameIndex = -1;
|
||||
private int colFormulaIndex = -1;
|
||||
private int colIsPersistedIndex = -1;
|
||||
private int colIsComputedIndex = -1;
|
||||
private int colNullableIndex = -1;
|
||||
private int colXmlSchemaIndex = -1;
|
||||
private int colIs_xml_documentIndex = -1;
|
||||
private int colPrecisionIndex = -1;
|
||||
private int colScaleIndex = -1;
|
||||
private int colDataUserTypeIdIndex = -1;
|
||||
private int colIsUserDefinedTypeIndex = -1;
|
||||
private int colSizeIndex = -1;
|
||||
private int colHasIndexIndex = -1;
|
||||
private int colHasComputedFormulaIndex = -1;
|
||||
private int colIsRowGuidIndex = -1;
|
||||
private int colTypeIndex = -1;
|
||||
private int colOwnerType = -1;
|
||||
private int colis_sparseIndex = -1;
|
||||
private int colIs_FileStream = -1;
|
||||
private int colDefaultIdIndex = -1;
|
||||
private int colDefaultNameIndex = -1;
|
||||
private int colDefaultDefinitionIndex = -1;
|
||||
private int colrule_object_idIndex = -1;
|
||||
private int colIsIdentityReplIndex = -1;
|
||||
private int colCollationIndex = -1;
|
||||
private int colIsIdentityIndex = -1;
|
||||
private int colIdentSeedIndex = -1;
|
||||
private int colIdentIncrementIndex = -1;
|
||||
private int TableIdIndex = -1;
|
||||
private int TableNameIndex = -1;
|
||||
private int TableOwnerIndex = -1;
|
||||
private int TableHasChangeTracking = -1;
|
||||
private int TableHasChangeTrackingTrackColumn = -1;
|
||||
private int TableLockEscalation = -1;
|
||||
private int Text_In_Row_limitIndex = -1;
|
||||
private int HasClusteredIndexIndex = -1;
|
||||
private int large_value_types_out_of_rowIndex = -1;
|
||||
private int HasVarDecimalIndex = -1;
|
||||
private int FileGroupIndex = -1;
|
||||
private int FileGroupTextIndex = -1;
|
||||
private int FileGroupStreamIndex = -1;
|
||||
|
||||
private Generate root;
|
||||
|
||||
public GenerateTables(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private void InitTableIndex(Database database, IDataRecord reader)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException("reader");
|
||||
if (TableIdIndex == -1)
|
||||
{
|
||||
TableIdIndex = reader.GetOrdinal("TableId");
|
||||
TableNameIndex = reader.GetOrdinal("TableName");
|
||||
TableOwnerIndex = reader.GetOrdinal("TableOwner");
|
||||
Text_In_Row_limitIndex = reader.GetOrdinal("Text_In_Row_limit");
|
||||
HasClusteredIndexIndex = reader.GetOrdinal("HasClusteredIndex");
|
||||
large_value_types_out_of_rowIndex = reader.GetOrdinal("large_value_types_out_of_row");
|
||||
HasVarDecimalIndex = reader.GetOrdinal("HasVarDecimal");
|
||||
FileGroupIndex = reader.GetOrdinal("FileGroup");
|
||||
FileGroupTextIndex = reader.GetOrdinal("FileGroupText");
|
||||
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
|
||||
{
|
||||
FileGroupStreamIndex = reader.GetOrdinal("FileGroupStream");
|
||||
TableHasChangeTracking = reader.GetOrdinal("HasChangeTracking");
|
||||
TableHasChangeTrackingTrackColumn = reader.GetOrdinal("HasChangeTrackingTrackColumn");
|
||||
TableLockEscalation = reader.GetOrdinal("lock_escalation_desc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitColIndex(Database database, IDataRecord reader)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException("reader");
|
||||
if (colNameIndex == -1)
|
||||
{
|
||||
colIDIndex = reader.GetOrdinal("ID");
|
||||
colNameIndex = reader.GetOrdinal("Name");
|
||||
colFormulaIndex = reader.GetOrdinal("Formula");
|
||||
colIsPersistedIndex = reader.GetOrdinal("FormulaPersisted");
|
||||
colIsComputedIndex = reader.GetOrdinal("IsComputed");
|
||||
colNullableIndex = reader.GetOrdinal("IsNullable");
|
||||
colOwnerType = reader.GetOrdinal("OwnerType");
|
||||
colXmlSchemaIndex = reader.GetOrdinal("XmlSchema");
|
||||
colIs_xml_documentIndex = reader.GetOrdinal("Is_xml_document");
|
||||
colPrecisionIndex = reader.GetOrdinal("Precision");
|
||||
colScaleIndex = reader.GetOrdinal("Scale");
|
||||
colDataUserTypeIdIndex = reader.GetOrdinal("user_type_id");
|
||||
colIsUserDefinedTypeIndex = reader.GetOrdinal("is_user_defined");
|
||||
colSizeIndex = reader.GetOrdinal("Size");
|
||||
colHasIndexIndex = reader.GetOrdinal("HasIndex");
|
||||
colHasComputedFormulaIndex = reader.GetOrdinal("HasComputedFormula");
|
||||
colIsRowGuidIndex = reader.GetOrdinal("IsRowGuid");
|
||||
colTypeIndex = reader.GetOrdinal("Type");
|
||||
colDefaultIdIndex = reader.GetOrdinal("DefaultId");
|
||||
colDefaultNameIndex = reader.GetOrdinal("DefaultName");
|
||||
colDefaultDefinitionIndex = reader.GetOrdinal("DefaultDefinition");
|
||||
colrule_object_idIndex = reader.GetOrdinal("rule_object_id");
|
||||
colIsIdentityReplIndex = reader.GetOrdinal("IsIdentityRepl");
|
||||
colCollationIndex = reader.GetOrdinal("Collation");
|
||||
colIsIdentityIndex = reader.GetOrdinal("IsIdentity");
|
||||
colIdentSeedIndex = reader.GetOrdinal("IdentSeed");
|
||||
colIdentIncrementIndex = reader.GetOrdinal("IdentIncrement");
|
||||
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
|
||||
{
|
||||
colis_sparseIndex = reader.GetOrdinal("is_sparse");
|
||||
colIs_FileStream = reader.GetOrdinal("is_filestream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FillColumn<T>(ITable<T> table, SqlDataReader reader) where T : ISchemaBase
|
||||
{
|
||||
Database database = (Database)table.Parent;
|
||||
|
||||
InitColIndex(database, reader);
|
||||
Column col = new Column((ISchemaBase)table);
|
||||
col.Id = (int)reader[colIDIndex];
|
||||
if (database.Options.Ignore.FilterColumnOrder)
|
||||
col.Position = table.Columns.Count + 1;
|
||||
|
||||
if (database.Options.Ignore.FilterColumnCollation)
|
||||
col.Collation = (string)reader[colCollationIndex];
|
||||
|
||||
if (database.Options.Ignore.FilterColumnIdentity)
|
||||
{
|
||||
col.IsIdentity = (bool)reader[colIsIdentityIndex];
|
||||
if ((col.IsIdentity) || (col.IsIdentityForReplication))
|
||||
{
|
||||
if (!reader.IsDBNull(colIdentSeedIndex))
|
||||
col.IdentitySeed = (long)(decimal)reader[colIdentSeedIndex];
|
||||
else
|
||||
col.IdentitySeed = 1;
|
||||
|
||||
if (!reader.IsDBNull(colIdentIncrementIndex))
|
||||
col.IdentityIncrement = (int)(decimal)reader[colIdentIncrementIndex];
|
||||
else
|
||||
col.IdentityIncrement = 1;
|
||||
}
|
||||
if (database.Options.Ignore.FilterNotForReplication)
|
||||
col.IsIdentityForReplication = ((int)reader[colIsIdentityReplIndex] == 1);
|
||||
}
|
||||
col.Name = (string)reader[colNameIndex];
|
||||
col.Owner = table.Owner;
|
||||
col.ComputedFormula = (string)reader[colFormulaIndex];
|
||||
col.IsPersisted = (bool)reader[colIsPersistedIndex];
|
||||
col.IsComputed = (bool)reader[colIsComputedIndex];
|
||||
col.IsNullable = (bool)reader[colNullableIndex];
|
||||
col.XmlSchema = reader[colXmlSchemaIndex].ToString();
|
||||
col.IsXmlDocument = (bool)reader[colIs_xml_documentIndex];
|
||||
col.Precision = (byte)reader[colPrecisionIndex];
|
||||
col.Scale = (byte)reader[colScaleIndex];
|
||||
col.DataUserTypeId = (int)reader[colDataUserTypeIdIndex];
|
||||
col.IsUserDefinedType = (bool)reader[colIsUserDefinedTypeIndex];
|
||||
if (!String.IsNullOrEmpty(reader[colSizeIndex].ToString()))
|
||||
col.Size = (short)reader[colSizeIndex];
|
||||
col.HasIndexDependencies = ((int)reader[colHasIndexIndex] == 1);
|
||||
col.HasComputedDependencies = ((int)reader[colHasComputedFormulaIndex] == 1);
|
||||
col.IsRowGuid = (bool)reader[colIsRowGuidIndex];
|
||||
if (col.IsUserDefinedType)
|
||||
col.Type = "[" + (string)reader[colOwnerType] + "].[" + (string)reader[colTypeIndex] + "]";
|
||||
else
|
||||
col.Type = (string)reader[colTypeIndex];
|
||||
if (((Database)table.Parent).Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
|
||||
{
|
||||
col.IsSparse = (bool)reader[colis_sparseIndex];
|
||||
col.IsFileStream = (bool)reader[colIs_FileStream];
|
||||
}
|
||||
if ((int)reader[colDefaultIdIndex] != 0)
|
||||
{
|
||||
col.DefaultConstraint = new ColumnConstraint(col)
|
||||
{
|
||||
Id = (int)reader[colDefaultIdIndex],
|
||||
Owner = table.Owner,
|
||||
Name = (string)reader[colDefaultNameIndex],
|
||||
Type = Constraint.ConstraintType.Default,
|
||||
Definition = (string)reader[colDefaultDefinitionIndex]
|
||||
};
|
||||
}
|
||||
if ((int)reader[colrule_object_idIndex] != 0)
|
||||
col.Rule = ((Database)table.Parent).Rules.Find((int)reader[colrule_object_idIndex]);
|
||||
table.Columns.Add(col);
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString, List<MessageLog> messages)
|
||||
{
|
||||
try
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading tables...", Constants.READING_TABLES));
|
||||
FillTables(database, connectionString);
|
||||
if (database.Tables.Any() || database.TablesTypes.Any())
|
||||
{
|
||||
if (database.Options.Ignore.FilterConstraint)
|
||||
(new GenerateConstraint(root)).Fill(database, connectionString);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
|
||||
}
|
||||
}
|
||||
|
||||
private void FillTables(Database database, string connectionString)
|
||||
{
|
||||
int textInRow;
|
||||
Boolean largeValues;
|
||||
Boolean varDecimal;
|
||||
int lastObjectId = 0;
|
||||
bool isTable = true;
|
||||
ISchemaBase item = null;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(TableSQLCommand.GetTableDetail(database.Info.Version, database.Info.Edition), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
InitTableIndex(database, reader);
|
||||
root.RaiseOnReadingOne(reader[TableNameIndex]);
|
||||
if (lastObjectId != (int)reader[TableIdIndex])
|
||||
{
|
||||
lastObjectId = (int)reader[TableIdIndex];
|
||||
isTable = reader["ObjectType"].ToString().Trim().Equals("U");
|
||||
if (isTable)
|
||||
{
|
||||
item = new Table(database);
|
||||
item.Id = (int)reader[TableIdIndex];
|
||||
item.Name = (string)reader[TableNameIndex];
|
||||
item.Owner = (string)reader[TableOwnerIndex];
|
||||
((Table)item).HasClusteredIndex = (int)reader[HasClusteredIndexIndex] == 1;
|
||||
textInRow = (int)reader[Text_In_Row_limitIndex];
|
||||
largeValues = (Boolean)reader[large_value_types_out_of_rowIndex];
|
||||
varDecimal = ((int)reader[HasVarDecimalIndex]) == 1;
|
||||
if (database.Options.Ignore.FilterTableFileGroup)
|
||||
{
|
||||
((Table)item).FileGroup = (string)reader[FileGroupIndex];
|
||||
((Table)item).FileGroupText = (string)reader[FileGroupTextIndex];
|
||||
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
|
||||
{
|
||||
if (database.Options.Ignore.FilterTableChangeTracking)
|
||||
{
|
||||
((Table)item).FileGroupStream = (string)reader[FileGroupStreamIndex];
|
||||
((Table)item).HasChangeTracking = ((int)reader[TableHasChangeTracking]) == 1;
|
||||
((Table)item).HasChangeTrackingTrackColumn = ((int)reader[TableHasChangeTrackingTrackColumn]) == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (database.Options.Ignore.FilterTableOption)
|
||||
{
|
||||
if (textInRow > 0) ((Table)item).Options.Add(new TableOption("TextInRow", textInRow.ToString(CultureInfo.InvariantCulture), item));
|
||||
if (largeValues) ((Table)item).Options.Add(new TableOption("LargeValues", "1", item));
|
||||
if (varDecimal) ((Table)item).Options.Add(new TableOption("VarDecimal", "1", item));
|
||||
}
|
||||
if ((database.Options.Ignore.FilterTableLockEscalation) && (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008))
|
||||
((Table)item).Options.Add(new TableOption("LockEscalation", (string)reader[TableLockEscalation], item));
|
||||
else
|
||||
((Table)item).Options.Add(new TableOption("LockEscalation", "TABLE", item));
|
||||
database.Tables.Add((Table)item);
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new TableType(database)
|
||||
{
|
||||
Id = (int)reader[TableIdIndex],
|
||||
Name = (string)reader[TableNameIndex],
|
||||
Owner = (string)reader[TableOwnerIndex]
|
||||
};
|
||||
database.TablesTypes.Add((TableType)item);
|
||||
}
|
||||
}
|
||||
if (isTable)
|
||||
{
|
||||
if (database.Options.Ignore.FilterTable)
|
||||
FillColumn((ITable<Table>)item, reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (database.Options.Ignore.FilterUserDataType)
|
||||
FillColumn((ITable<TableType>)item, reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//tables.ToSQL();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Text.RegularExpressions;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Options;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateTextObjects
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateTextObjects(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL(SqlOption options)
|
||||
{
|
||||
var filterQuery = SQLQueries.SQLQueryFactory.Get("GetTextObjectsQuery");
|
||||
string filter = "";
|
||||
if (options.Ignore.FilterStoredProcedure)
|
||||
filter += "O.type = 'P' OR ";
|
||||
if (options.Ignore.FilterView)
|
||||
filter += "O.type = 'V' OR ";
|
||||
if (options.Ignore.FilterTrigger)
|
||||
filter += "O.type = 'TR' OR ";
|
||||
if (options.Ignore.FilterFunction)
|
||||
filter += "O.type IN ('IF','FN','TF') OR ";
|
||||
filter = filter.Substring(0, filter.Length - 4);
|
||||
return filterQuery.Replace("{FILTER}", filter);
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
ICode code = null;
|
||||
try
|
||||
{
|
||||
if ((database.Options.Ignore.FilterStoredProcedure) || (database.Options.Ignore.FilterView) || (database.Options.Ignore.FilterFunction) || (database.Options.Ignore.FilterTrigger))
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading Text Objects...", Constants.READING_TEXTOBJECTS));
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(database.Options), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
code = null;
|
||||
root.RaiseOnReadingOne(reader["name"]);
|
||||
string type = reader["Type"].ToString().Trim();
|
||||
string name = reader["name"].ToString();
|
||||
string definition = reader["Text"].ToString();
|
||||
int id = (int)reader["object_id"];
|
||||
if (type.Equals("V"))
|
||||
code = (ICode)database.Views.Find(id);
|
||||
|
||||
if (type.Equals("TR"))
|
||||
code = (ICode)database.Find(id);
|
||||
|
||||
if (type.Equals("P"))
|
||||
{
|
||||
var procedure = database.Procedures.Find(id);
|
||||
if (procedure != null)
|
||||
((ICode)procedure).Text = GetObjectDefinition(type, name, definition);
|
||||
}
|
||||
|
||||
if (type.Equals("IF") || type.Equals("FN") || type.Equals("TF"))
|
||||
code = (ICode)database.Functions.Find(id);
|
||||
|
||||
if (code != null)
|
||||
code.Text = reader["Text"].ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetObjectDefinition(string type, string name, string definition)
|
||||
{
|
||||
string rv = definition;
|
||||
|
||||
string sqlDelimiters = @"(\r|\n|\s)+?";
|
||||
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline;
|
||||
Regex re = new Regex(@"CREATE" + sqlDelimiters + @"PROC(EDURE)?" + sqlDelimiters + @"(\w+\.|\[\w+\]\.)?\[?(?<spname>\w+)\]?" + sqlDelimiters, options);
|
||||
switch (type)
|
||||
{
|
||||
case "P":
|
||||
Match match = re.Match(definition);
|
||||
if (match != null && match.Success)
|
||||
{
|
||||
// Try to replace the name saved in the definition when the object was created by the one used for the object in sys.object
|
||||
string oldName = match.Groups["spname"].Value;
|
||||
//if (String.IsNullOrEmpty(oldName)) System.Diagnostics.Debugger.Break();
|
||||
if (String.Compare(oldName, name) != 0)
|
||||
{
|
||||
rv = rv.Replace(oldName, name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//TODO : Add the logic used for other objects than procedures
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.Errors;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Options;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateTriggers
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateTriggers(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQL(DatabaseInfo.SQLServerVersion version, SqlOption options)
|
||||
{
|
||||
if (version == DatabaseInfo.SQLServerVersion.SQLServerAzure10)
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetTriggers", version);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetTriggers");
|
||||
}
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString, List<MessageLog> messages)
|
||||
{
|
||||
int parentId = 0;
|
||||
ISchemaBase parent = null;
|
||||
string type;
|
||||
try
|
||||
{
|
||||
if (database.Options.Ignore.FilterTrigger)
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading Triggers...", Constants.READING_TRIGGERS));
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQL(database.Info.Version, database.Options), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
root.RaiseOnReadingOne(reader["Name"]);
|
||||
type = reader["ObjectType"].ToString().Trim();
|
||||
if (parentId != (int)reader["parent_id"])
|
||||
{
|
||||
parentId = (int)reader["parent_id"];
|
||||
if (type.Equals("V"))
|
||||
parent = database.Views.Find(parentId);
|
||||
else
|
||||
parent = database.Tables.Find(parentId);
|
||||
}
|
||||
if (reader["type"].Equals("TR"))
|
||||
{
|
||||
Trigger item = new Trigger(parent);
|
||||
item.Id = (int)reader["object_id"];
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.InsteadOf = (bool)reader["is_instead_of_trigger"];
|
||||
item.IsDisabled = (bool)reader["is_disabled"];
|
||||
item.IsDDLTrigger = false;
|
||||
item.Owner = reader["Owner"].ToString();
|
||||
if (database.Options.Ignore.FilterNotForReplication)
|
||||
item.NotForReplication = (bool)reader["is_not_for_replication"];
|
||||
if (type.Equals("V"))
|
||||
((View)parent).Triggers.Add(item);
|
||||
else
|
||||
((Table)parent).Triggers.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLRTrigger item = new CLRTrigger(parent);
|
||||
item.Id = (int)reader["object_id"];
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.IsDelete = (bool)reader["IsDelete"];
|
||||
item.IsUpdate = (bool)reader["IsUpdate"];
|
||||
item.IsInsert = (bool)reader["IsInsert"];
|
||||
item.Owner = reader["Owner"].ToString();
|
||||
item.IsAssembly = true;
|
||||
item.AssemblyId = (int)reader["assembly_id"];
|
||||
item.AssemblyName = reader["assembly_name"].ToString();
|
||||
item.AssemblyClass = reader["assembly_class"].ToString();
|
||||
item.AssemblyExecuteAs = reader["ExecuteAs"].ToString();
|
||||
item.AssemblyMethod = reader["assembly_method"].ToString();
|
||||
if (type.Equals("V"))
|
||||
((View)parent).CLRTriggers.Add(item);
|
||||
else
|
||||
((Table)parent).CLRTriggers.Add(item);
|
||||
/*if (!database.Options.Ignore.FilterIgnoreNotForReplication)
|
||||
trigger.NotForReplication = (bool)reader["is_not_for_replication"];*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.Errors;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateUserDataTypes
|
||||
{
|
||||
private readonly Generate root;
|
||||
|
||||
public GenerateUserDataTypes(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQLColumnsDependencies()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetSQLColumnsDependencies");
|
||||
}
|
||||
|
||||
private static void FillColumnsDependencies(SchemaList<UserDataType, Database> types, string connectionString)
|
||||
{
|
||||
if (types == null) throw new ArgumentNullException("types");
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQLColumnsDependencies(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
types[reader["TypeName"].ToString()].Dependencies.Add(new ObjectDependency(reader["TableName"].ToString(), reader["ColumnName"].ToString(), ConvertType.GetObjectType(reader["Type"].ToString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString, List<MessageLog> messages)
|
||||
{
|
||||
//not supported in azure yet http://msdn.microsoft.com/en-us/library/ee336233.aspx
|
||||
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10) return;
|
||||
|
||||
try
|
||||
{
|
||||
if (database.Options.Ignore.FilterUserDataType)
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading UDT...", Constants.READING_UDT));
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(UserDataTypeCommand.Get(database.Info.Version, database.Info.Edition), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
root.RaiseOnReadingOne(reader["Name"]);
|
||||
UserDataType item = new UserDataType(database);
|
||||
item.Id = (int)reader["tid"];
|
||||
item.AllowNull = (bool)reader["is_nullable"];
|
||||
item.Size = (short)reader["max_length"];
|
||||
item.Name = reader["Name"].ToString();
|
||||
item.Owner = reader["owner"].ToString();
|
||||
item.Precision = int.Parse(reader["precision"].ToString());
|
||||
item.Scale = int.Parse(reader["scale"].ToString());
|
||||
if (!String.IsNullOrEmpty(reader["defaultname"].ToString()))
|
||||
{
|
||||
item.Default.Name = reader["defaultname"].ToString();
|
||||
item.Default.Owner = reader["defaultowner"].ToString();
|
||||
}
|
||||
if (!String.IsNullOrEmpty(reader["rulename"].ToString()))
|
||||
{
|
||||
item.Rule.Name = reader["rulename"].ToString();
|
||||
item.Rule.Owner = reader["ruleowner"].ToString();
|
||||
}
|
||||
item.Type = reader["basetypename"].ToString();
|
||||
item.IsAssembly = (bool)reader["is_assembly_type"];
|
||||
item.AssemblyId = (int)reader["assembly_id"];
|
||||
item.AssemblyName = reader["assembly_name"].ToString();
|
||||
item.AssemblyClass = reader["assembly_class"].ToString();
|
||||
database.UserTypes.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (database.Options.Ignore.FilterTable)
|
||||
FillColumnsDependencies(database.UserTypes, connectionString);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateUsers
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateUsers(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectioString)
|
||||
{
|
||||
string type;
|
||||
if ((database.Options.Ignore.FilterUsers) || (database.Options.Ignore.FilterRoles))
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectioString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(UserSQLCommand.Get(database.Info.Version, database.Info.Edition), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
type = reader["type"].ToString();
|
||||
if (database.Options.Ignore.FilterUsers && (type.Equals("S") || type.Equals("U")))
|
||||
{
|
||||
User item = new User(database);
|
||||
item.Id = (int)reader["principal_id"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.Login = reader["Login"].ToString();
|
||||
item.Owner = reader["default_schema_name"].ToString();
|
||||
database.Users.Add(item);
|
||||
}
|
||||
if (database.Options.Ignore.FilterRoles && (type.Equals("A") || type.Equals("R")))
|
||||
{
|
||||
Role item = new Role(database);
|
||||
item.Id = (int)reader["principal_id"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.Owner = reader["default_schema_name"].ToString();
|
||||
item.Password = "";
|
||||
item.IsSystem = (Boolean)reader["is_fixed_role"];
|
||||
if (type.Equals("A"))
|
||||
item.Type = Role.RoleTypeEnum.ApplicationRole;
|
||||
else
|
||||
item.Type = Role.RoleTypeEnum.DatabaseRole;
|
||||
database.Roles.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using OpenDBDiff.Schema.Errors;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateViews
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateViews(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString, List<MessageLog> messages)
|
||||
{
|
||||
try
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading views...", Constants.READING_VIEWS));
|
||||
if (database.Options.Ignore.FilterView)
|
||||
{
|
||||
FillView(database, connectionString);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
messages.Add(new MessageLog(ex.Message, ex.StackTrace, MessageLog.LogType.Error));
|
||||
}
|
||||
}
|
||||
|
||||
private void FillView(Database database, string connectionString)
|
||||
{
|
||||
int lastViewId = 0;
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(ViewSQLCommand.GetView(database.Info.Version, database.Info.Edition), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
View item = null;
|
||||
while (reader.Read())
|
||||
{
|
||||
root.RaiseOnReadingOne(reader["name"]);
|
||||
if (lastViewId != (int)reader["object_id"])
|
||||
{
|
||||
item = new View(database);
|
||||
item.Id = (int)reader["object_id"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.Owner = reader["owner"].ToString();
|
||||
item.IsSchemaBinding = reader["IsSchemaBound"].ToString().Equals("1");
|
||||
database.Views.Add(item);
|
||||
lastViewId = item.Id;
|
||||
}
|
||||
if (item.IsSchemaBinding)
|
||||
{
|
||||
if (!reader.IsDBNull(reader.GetOrdinal("referenced_major_id")))
|
||||
database.Dependencies.Add(database, (int)reader["referenced_major_id"], item);
|
||||
if (!String.IsNullOrEmpty(reader["TableName"].ToString()))
|
||||
item.DependenciesIn.Add(reader["TableName"].ToString());
|
||||
if (!String.IsNullOrEmpty(reader["DependOut"].ToString()))
|
||||
item.DependenciesOut.Add(reader["DependOut"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Data.SqlClient;
|
||||
using System.Text;
|
||||
using OpenDBDiff.Schema.Events;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Generates.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates
|
||||
{
|
||||
public class GenerateXMLSchemas
|
||||
{
|
||||
private Generate root;
|
||||
|
||||
public GenerateXMLSchemas(Generate root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private static string GetSQLColumnsDependencies()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetXMLSchemaCollections");
|
||||
}
|
||||
|
||||
private static string GetSQLXMLSchema()
|
||||
{
|
||||
return SQLQueries.SQLQueryFactory.Get("GetSQLXMLSchema");
|
||||
}
|
||||
|
||||
private static void FillColumnsDependencies(SchemaList<XMLSchema, Database> items, string connectionString)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQLColumnsDependencies(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
items[reader["XMLName"].ToString()].Dependencies.Add(new ObjectDependency(reader["TableName"].ToString(), reader["ColumnName"].ToString(), ConvertType.GetObjectType(reader["Type"].ToString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Fill(Database database, string connectionString)
|
||||
{
|
||||
//TODO XML_SCHEMA_NAMESPACE function not supported in Azure, is there a workaround?
|
||||
//not supported in azure yet
|
||||
if (database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10) return;
|
||||
|
||||
|
||||
if (database.Options.Ignore.FilterXMLSchema)
|
||||
{
|
||||
root.RaiseOnReading(new ProgressEventArgs("Reading XML Schema...", Constants.READING_XMLSCHEMAS));
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand(GetSQLXMLSchema(), conn))
|
||||
{
|
||||
conn.Open();
|
||||
command.CommandTimeout = 0;
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
root.RaiseOnReadingOne(reader["name"]);
|
||||
XMLSchema item = new XMLSchema(database);
|
||||
item.Id = (int)reader["ID"];
|
||||
item.Name = reader["name"].ToString();
|
||||
item.Owner = reader["owner"].ToString();
|
||||
item.Text = reader["Text"].ToString();
|
||||
database.XmlSchemas.Add(item);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (database.Options.Ignore.FilterTable)
|
||||
FillColumnsDependencies(database.XmlSchemas, connectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal static class ConstraintSQLCommand
|
||||
{
|
||||
public static string GetUniqueKey(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
return GetUniqueKey2005();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServerAzure10:
|
||||
return GetUniqueKeyAzure();
|
||||
|
||||
default:
|
||||
if (edition == DatabaseInfo.SQLServerEdition.Azure)
|
||||
return GetUniqueKeyAzure();
|
||||
else
|
||||
return GetUniqueKey2008();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetCheck(DatabaseInfo.SQLServerVersion version)
|
||||
{
|
||||
if (version == DatabaseInfo.SQLServerVersion.SQLServer2005) return GetCheck2005();
|
||||
//Fall back to highest compatible version
|
||||
return GetCheck2008();
|
||||
}
|
||||
|
||||
public static string GetPrimaryKey(DatabaseInfo.SQLServerVersion version, Table table)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2000:
|
||||
return GetPrimaryKey2000(table);
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
return GetPrimaryKey2005();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServerAzure10:
|
||||
return GetPrimaryKeyAzure();
|
||||
|
||||
default:
|
||||
return GetPrimaryKey2008();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetUniqueKeyAzure()
|
||||
{
|
||||
//File Groups not supported in Azure
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT O.type as ObjectType, S.Name as Owner, I.object_Id AS id,'' as FileGroup, C.user_type_id, C.column_id, I.Index_id, C.Name AS ColumnName, I.Name, I.type, I.fill_factor, I.is_padded, I.allow_row_locks, I.allow_page_locks, I.ignore_dup_key, I.is_disabled, IC.is_descending_key, IC.is_included_column ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects O ON O.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = O.schema_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
//sql.Append("LEFT JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("WHERE is_unique_constraint = 1 AND O.type <> 'TF' ORDER BY I.object_id,I.Name");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetUniqueKey2008()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT O.type as ObjectType, S.Name as Owner, I.object_Id AS id,dsidx.Name as FileGroup, C.user_type_id, C.column_id, I.Index_id, C.Name AS ColumnName, I.Name, I.type, I.fill_factor, I.is_padded, I.allow_row_locks, I.allow_page_locks, I.ignore_dup_key, I.is_disabled, IC.is_descending_key, IC.is_included_column ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects O ON O.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = O.schema_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
sql.Append("LEFT JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("WHERE is_unique_constraint = 1 AND O.type <> 'TF' ORDER BY I.object_id,I.Name");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetUniqueKey2005()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT O.type as ObjectType, S.Name as Owner, I.object_Id AS id,dsidx.Name as FileGroup, C.user_type_id, C.column_id, I.Index_id, C.Name AS ColumnName, I.Name, I.type, I.fill_factor, I.is_padded, I.allow_row_locks, I.allow_page_locks, I.ignore_dup_key, I.is_disabled, IC.is_descending_key, IC.is_included_column ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects O ON O.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = O.schema_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
sql.Append("LEFT JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("WHERE is_unique_constraint = 1 AND O.type <> 'TF' ORDER BY I.object_id,I.Name");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetCheck2008()
|
||||
{
|
||||
string sql;
|
||||
sql = "SELECT ";
|
||||
sql += "CC.parent_object_id, ";
|
||||
sql += "O.type as ObjectType, ";
|
||||
sql += "CC.object_id AS ID, ";
|
||||
sql += "CC.parent_column_id, ";
|
||||
sql += "CC.name, ";
|
||||
sql += "CC.type, ";
|
||||
sql += "CC.definition, ";
|
||||
sql += "CC.is_disabled, ";
|
||||
sql += "CC.is_not_trusted AS WithCheck, ";
|
||||
sql += "CC.is_not_for_replication, ";
|
||||
sql += "0, ";
|
||||
sql += "schema_name(CC.schema_id) AS Owner ";
|
||||
sql += "FROM sys.check_constraints CC ";
|
||||
sql += "INNER JOIN sys.objects O ON O.object_id = CC.parent_object_id ";
|
||||
sql += "ORDER BY CC.parent_object_id,CC.name";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string GetCheck2005()
|
||||
{
|
||||
string sql;
|
||||
sql = "SELECT ";
|
||||
sql += "CC.parent_object_id, ";
|
||||
sql += "O.Type as ObjectType, ";
|
||||
sql += "CC.object_id AS ID, ";
|
||||
sql += "CC.parent_column_id, ";
|
||||
sql += "CC.name, ";
|
||||
sql += "CC.type, ";
|
||||
sql += "CC.definition, ";
|
||||
sql += "CC.is_disabled, ";
|
||||
sql += "CC.is_not_trusted AS WithCheck, ";
|
||||
sql += "CC.is_not_for_replication, ";
|
||||
sql += "0, ";
|
||||
sql += "schema_name(CC.schema_id) AS Owner ";
|
||||
sql += "FROM sys.check_constraints CC ";
|
||||
sql += "INNER JOIN sys.objects O ON O.object_id = CC.parent_object_id ";
|
||||
sql += "ORDER BY CC.parent_object_id,CC.name";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string GetPrimaryKeyAzure()
|
||||
{
|
||||
//File Groups not supported in Azure
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT O.type as ObjectType, S.Name as Owner, IC.key_ordinal, C.user_type_id, I.object_id AS ID, '' AS FileGroup, C.column_id, I.Index_id, C.Name AS ColumnName, I.Name, I.type, I.fill_factor, I.is_padded, I.allow_row_locks, I.allow_page_locks, I.ignore_dup_key, I.is_disabled, IC.is_descending_key, IC.is_included_column, CONVERT(bit,INDEXPROPERTY(I.object_id,I.name,'IsAutoStatistics')) AS IsAutoStatistics ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects O ON O.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = O.schema_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
//sql.Append("LEFT JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("WHERE is_primary_key = 1 AND O.type <> 'TF' ORDER BY I.object_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetPrimaryKey2008()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT O.type as ObjectType, S.Name as Owner, IC.key_ordinal, C.user_type_id, I.object_id AS ID, dsidx.Name AS FileGroup, C.column_id, I.Index_id, C.Name AS ColumnName, I.Name, I.type, I.fill_factor, I.is_padded, I.allow_row_locks, I.allow_page_locks, I.ignore_dup_key, I.is_disabled, IC.is_descending_key, IC.is_included_column, CONVERT(bit,INDEXPROPERTY(I.object_id,I.name,'IsAutoStatistics')) AS IsAutoStatistics ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects O ON O.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = O.schema_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
sql.Append("LEFT JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("WHERE is_primary_key = 1 AND O.type <> 'TF' ORDER BY I.object_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetPrimaryKey2005()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT O.type as ObjectType, S.Name as Owner, IC.key_ordinal, C.user_type_id, I.object_id AS ID, dsidx.Name AS FileGroup, C.column_id, I.Index_id, C.Name AS ColumnName, I.Name, I.type, I.fill_factor, I.is_padded, I.allow_row_locks, I.allow_page_locks, I.ignore_dup_key, I.is_disabled, IC.is_descending_key, IC.is_included_column, CONVERT(bit,INDEXPROPERTY(I.object_id,I.name,'IsAutoStatistics')) AS IsAutoStatistics ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects O ON O.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = O.schema_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
sql.Append("INNER JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("WHERE is_primary_key = 1 AND O.type <> 'TF' ORDER BY I.object_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetPrimaryKey2000(Table table)
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT CONVERT(tinyint,CASE WHEN SI.indid = 0 THEN 0 WHEN SI.indid = 1 THEN 1 WHEN SI.indid > 1 THEN 2 END) AS Type,f.groupname AS FileGroup,CONVERT(int,SI.indid) AS Index_id, CONVERT(int,SI.indid) AS ID, SI.name, SC.colid, SC.Name AS ColumnName, CONVERT(bit,0) AS is_included_column, SIK.keyno AS key_ordinal, CONVERT(bit,INDEXPROPERTY(SI.id,SI.name,'IsPadIndex')) AS is_padded, CONVERT(bit,INDEXPROPERTY(SI.id,SI.name,'IsRowLockDisallowed')) AS allow_row_locks, CONVERT(bit,INDEXPROPERTY(SI.id,SI.name,'IsPageLockDisallowed')) AS allow_page_locks, CONVERT(bit,INDEXPROPERTY(SI.id,SI.name,'IsAutoStatistics')) AS IsAutoStatistics, CONVERT(tinyint,INDEXPROPERTY(SI.id,SI.name,'IndexFillFactor')) AS fill_factor, INDEXKEY_PROPERTY(SI.id, SI.indid,SC.colid,'IsDescending') AS is_descending_key, CONVERT(bit,0) AS is_disabled, CONVERT(bit,0) AS is_included_column ");
|
||||
sql.Append("FROM sysindexes SI INNER JOIN sysindexkeys SIK ON SI.indid = SIK.indid AND SIK.id = SI.ID ");
|
||||
sql.Append("INNER JOIN syscolumns SC ON SC.colid = SIK.colid AND SC.id = SI.ID ");
|
||||
sql.Append("inner join sysfilegroups f on f.groupid = SI.groupid ");
|
||||
sql.Append("WHERE (SI.status & 0x800) = 0x800 AND SI.id = " + table.Id.ToString() + " ORDER BY SIK.keyno");
|
||||
return sql.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal class DatabaseSQLCommand
|
||||
{
|
||||
public static string GetVersion(Database databaseSchema)
|
||||
{
|
||||
string sql;
|
||||
sql = "SELECT SERVERPROPERTY('productversion') AS Version, SERVERPROPERTY('EngineEdition') AS Edition";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public static string Get(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition, Database databaseSchema)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
return Get2005(databaseSchema);
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008:
|
||||
return Get2008(databaseSchema);
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008R2:
|
||||
return Get2008R2(databaseSchema);
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServerAzure10:
|
||||
return GetAzure(databaseSchema);
|
||||
|
||||
default:
|
||||
if (edition == DatabaseInfo.SQLServerEdition.Azure)
|
||||
return GetAzure(databaseSchema);
|
||||
else
|
||||
return Get2008R2(databaseSchema);
|
||||
}
|
||||
}
|
||||
|
||||
private static string Get2005(Database databaseSchema)
|
||||
{
|
||||
string sql;
|
||||
sql = "SELECT DATABASEPROPERTYEX('" + databaseSchema.Name + "','IsFulltextEnabled') AS IsFullTextEnabled, DATABASEPROPERTYEX('" + databaseSchema.Name + "','Collation') AS Collation";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string Get2008(Database databaseSchema)
|
||||
{
|
||||
string sql;
|
||||
sql = "SELECT DATABASEPROPERTYEX('" + databaseSchema.Name + "','IsFulltextEnabled') AS IsFullTextEnabled, DATABASEPROPERTYEX('" + databaseSchema.Name + "','Collation') AS Collation";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string Get2008R2(Database databaseSchema)
|
||||
{
|
||||
string sql;
|
||||
sql = "SELECT DATABASEPROPERTYEX('" + databaseSchema.Name + "','IsFulltextEnabled') AS IsFullTextEnabled, DATABASEPROPERTYEX('" + databaseSchema.Name + "','Collation') AS Collation";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string GetAzure(Database databaseSchema)
|
||||
{
|
||||
string sql;
|
||||
//DATABASEPROPERTYEX('IsFullTextEnabled') is deprecated http://technet.microsoft.com/en-us/library/cc646010(SQL.110).aspx
|
||||
sql = "SELECT 0 AS IsFullTextEnabled, DATABASEPROPERTYEX('" + databaseSchema.Name + "','Collation') AS Collation";
|
||||
return sql;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal static class FullTextIndexSQLCommand
|
||||
{
|
||||
public static string Get(DatabaseInfo.SQLServerVersion version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
return Get2005();
|
||||
|
||||
default:
|
||||
return Get2008();
|
||||
}
|
||||
}
|
||||
|
||||
private static string Get2005()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT ");
|
||||
sql.Append("FI.object_id, ");
|
||||
sql.Append("T.Name AS TableName, ");
|
||||
sql.Append("FC.name AS FullTextCatalogName, ");
|
||||
sql.Append("I.name AS IndexName, ");
|
||||
sql.Append("FI.is_enabled, ");
|
||||
sql.Append("'['+ S.name + '].['+ T.name + '].[' + FC.name + ']' AS Name, ");
|
||||
sql.Append("C.name as ColumnName, ");
|
||||
sql.Append("FI.change_tracking_state_desc AS ChangeTracking, ");
|
||||
sql.Append("FL.name AS LanguageName ");
|
||||
sql.Append("FROM sys.fulltext_indexes FI ");
|
||||
sql.Append("INNER JOIN sys.fulltext_catalogs FC ON FC.fulltext_catalog_id = FI.fulltext_catalog_id ");
|
||||
sql.Append("INNER JOIN sys.indexes I ON I.index_id = FI.unique_index_id and I.object_id = FI.object_id ");
|
||||
sql.Append("INNER JOIN sys.tables T ON T.object_id = FI.object_id ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = T.schema_id ");
|
||||
sql.Append("INNER JOIN sys.fulltext_index_columns FIC ON FIC.object_id = FI.object_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.object_id = FIC.object_id AND C.column_id = FIC.column_id ");
|
||||
sql.Append("INNER JOIN sys.fulltext_languages FL ON FL.lcid = FIC.language_id ");
|
||||
sql.Append("ORDER BY OBJECT_NAME(FI.object_id), I.name ");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string Get2008()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT ");
|
||||
sql.Append("FI.object_id, ");
|
||||
sql.Append("T.Name AS TableName, ");
|
||||
sql.Append("FC.name AS FullTextCatalogName, ");
|
||||
sql.Append("I.name AS IndexName, ");
|
||||
sql.Append("FI.is_enabled, ");
|
||||
sql.Append("'['+ S.name + '].['+ T.name + '].[' + FC.name + ']' AS Name, ");
|
||||
sql.Append("C.name as ColumnName, ");
|
||||
sql.Append("FL.name AS LanguageName,");
|
||||
sql.Append("DS.name AS FileGroupName, ");
|
||||
sql.Append("FI.change_tracking_state_desc AS ChangeTracking ");
|
||||
sql.Append("FROM sys.fulltext_indexes FI ");
|
||||
sql.Append("INNER JOIN sys.fulltext_catalogs FC ON FC.fulltext_catalog_id = FI.fulltext_catalog_id ");
|
||||
sql.Append("INNER JOIN sys.indexes I ON I.index_id = FI.unique_index_id and I.object_id = FI.object_id ");
|
||||
sql.Append("INNER JOIN sys.tables T ON T.object_id = FI.object_id ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = T.schema_id ");
|
||||
sql.Append("INNER JOIN sys.fulltext_index_columns FIC ON FIC.object_id = FI.object_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.object_id = FIC.object_id AND C.column_id = FIC.column_id ");
|
||||
sql.Append("INNER JOIN sys.data_spaces DS ON DS.data_space_id = FI.data_space_id ");
|
||||
sql.Append("INNER JOIN sys.fulltext_languages FL ON FL.lcid = FIC.language_id ");
|
||||
sql.Append("ORDER BY OBJECT_NAME(FI.object_id), I.name ");
|
||||
return sql.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal static class FunctionSQLCommand
|
||||
{
|
||||
public static string Get(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
return Get2005();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008:
|
||||
return Get2008();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServerAzure10:
|
||||
return GetAzure();
|
||||
|
||||
default:
|
||||
if (edition == DatabaseInfo.SQLServerEdition.Azure)
|
||||
return GetAzure();
|
||||
else
|
||||
return Get2008();
|
||||
}
|
||||
}
|
||||
|
||||
private static string Get2005()
|
||||
{
|
||||
string sql = "";
|
||||
sql += "select distinct ";
|
||||
sql += "T.name AS ReturnType, PP.max_length, PP.precision, PP.Scale, ";
|
||||
sql += "ISNULL(CONVERT(varchar,AM.execute_as_principal_id),'CALLER') as ExecuteAs, ";
|
||||
sql += "P.type, ";
|
||||
sql += "AF.name AS assembly_name, ";
|
||||
sql += "AM.assembly_class, ";
|
||||
sql += "AM.assembly_id, ";
|
||||
sql += "AM.assembly_method, ";
|
||||
sql += "ISNULL('[' + S3.Name + '].[' + object_name(D2.object_id) + ']','') AS DependOut, '[' + S2.Name + '].[' + object_name(D.referenced_major_id) + ']' AS TableName, D.referenced_major_id, OBJECTPROPERTY (P.object_id,'IsSchemaBound') AS IsSchemaBound, P.object_id, S.name as owner, P.name as name from sys.objects P ";
|
||||
sql += "INNER JOIN sys.schemas S ON S.schema_id = P.schema_id ";
|
||||
sql += "LEFT JOIN sys.sql_dependencies D ON P.object_id = D.object_id ";
|
||||
sql += "LEFT JOIN sys.objects O ON O.object_id = D.referenced_major_id ";
|
||||
sql += "LEFT JOIN sys.schemas S2 ON S2.schema_id = O.schema_id ";
|
||||
sql += "LEFT JOIN sys.sql_dependencies D2 ON P.object_id = D2.referenced_major_id ";
|
||||
sql += "LEFT JOIN sys.objects O2 ON O2.object_id = D2.object_id ";
|
||||
sql += "LEFT JOIN sys.schemas S3 ON S3.schema_id = O2.schema_id ";
|
||||
sql += "LEFT JOIN sys.assembly_modules AM ON AM.object_id = P.object_id ";
|
||||
sql += "LEFT JOIN sys.assemblies AF ON AF.assembly_id = AM.assembly_id ";
|
||||
sql += "LEFT JOIN sys.parameters PP ON PP.object_id = AM.object_id AND PP.parameter_id = 0 and PP.is_output = 1 ";
|
||||
sql += "LEFT JOIN sys.types T ON T.system_type_id = PP.system_type_id ";
|
||||
sql += "WHERE P.type IN ('IF','FN','TF','FS') ORDER BY P.object_id";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string Get2008()
|
||||
{
|
||||
var sql = new StringBuilder();
|
||||
sql.AppendLine("SELECT DISTINCT ");
|
||||
sql.AppendLine("T.name AS ReturnType, PP.max_length, PP.precision, PP.Scale, ");
|
||||
sql.AppendLine("ISNULL(CONVERT(varchar,AM.execute_as_principal_id),'CALLER') as ExecuteAs, ");
|
||||
sql.AppendLine("P.type, ");
|
||||
sql.AppendLine("AF.name AS assembly_name, ");
|
||||
sql.AppendLine("AM.assembly_class, ");
|
||||
sql.AppendLine("AM.assembly_id, ");
|
||||
sql.AppendLine("AM.assembly_method, ");
|
||||
sql.AppendLine("ISNULL('[' + S3.Name + '].[' + object_name(D2.object_id) + ']','') AS DependOut, '[' + S2.Name + '].[' + object_name(D.referenced_major_id) + ']' AS TableName, D.referenced_major_id, OBJECTPROPERTY (P.object_id,'IsSchemaBound') AS IsSchemaBound, P.object_id, S.name as owner, P.name as name from sys.objects P ");
|
||||
sql.AppendLine("INNER JOIN sys.schemas S ON S.schema_id = P.schema_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.sql_dependencies D ON P.object_id = D.object_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.objects O ON O.object_id = D.referenced_major_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.schemas S2 ON S2.schema_id = O.schema_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.sql_dependencies D2 ON P.object_id = D2.referenced_major_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.objects O2 ON O2.object_id = D2.object_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.schemas S3 ON S3.schema_id = O2.schema_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.assembly_modules AM ON AM.object_id = P.object_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.assemblies AF ON AF.assembly_id = AM.assembly_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.parameters PP ON PP.object_id = AM.object_id AND PP.parameter_id = 0 and PP.is_output = 1 ");
|
||||
sql.AppendLine("LEFT JOIN sys.types T ON T.system_type_id = PP.system_type_id ");
|
||||
sql.AppendLine("WHERE P.type IN ('IF','FN','TF','FS') ORDER BY P.object_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetAzure()
|
||||
{
|
||||
var sql = new StringBuilder();
|
||||
sql.AppendLine("SELECT DISTINCT ");
|
||||
sql.AppendLine("T.name AS ReturnType, PP.max_length, PP.precision, PP.Scale, ");
|
||||
sql.AppendLine("ISNULL(CONVERT(varchar,AM.execute_as_principal_id),'CALLER') as ExecuteAs, ");
|
||||
sql.AppendLine("P.type, ");
|
||||
sql.AppendLine("AF.name AS assembly_name, ");
|
||||
sql.AppendLine("AM.assembly_class, ");
|
||||
sql.AppendLine("AM.assembly_id, ");
|
||||
sql.AppendLine("AM.assembly_method, ");
|
||||
sql.AppendLine("ISNULL('[' + S3.Name + '].[' + object_name(D2.referencing_id) + ']','') AS DependOut, ");
|
||||
sql.AppendLine("'[' + S2.Name + '].[' + object_name(D.referenced_id) + ']' AS TableName, D.referenced_id AS referenced_major_id, OBJECTPROPERTY (P.object_id,'IsSchemaBound') AS IsSchemaBound, P.object_id, S.name as owner, P.name as name from sys.objects P ");
|
||||
sql.AppendLine("INNER JOIN sys.schemas S ON S.schema_id = P.schema_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.sql_expression_dependencies D ON P.object_id = D.referencing_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.objects O ON O.object_id = D.referenced_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.schemas S2 ON S2.schema_id = O.schema_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.sql_expression_dependencies D2 ON P.object_id = D2.referenced_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.objects O2 ON O2.object_id = D2.referencing_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.schemas S3 ON S3.schema_id = O2.schema_id ");
|
||||
sql.AppendLine("CROSS JOIN (SELECT null as object_id, null as execute_as_principal_id, null as assembly_class, null as assembly_id, null as assembly_method) AS AM ");
|
||||
sql.AppendLine("CROSS JOIN (SELECT null AS name) AS AF");
|
||||
sql.AppendLine("LEFT JOIN sys.parameters PP ON PP.object_id = AM.object_id AND PP.parameter_id = 0 and PP.is_output = 1 ");
|
||||
sql.AppendLine("LEFT JOIN sys.types T ON T.system_type_id = PP.system_type_id ");
|
||||
sql.AppendLine("WHERE P.type IN ('IF','FN','TF','FS') ORDER BY P.object_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal static class IndexSQLCommand
|
||||
{
|
||||
public static string Get(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
return Get2005();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008:
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008R2:
|
||||
return Get2008();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServerAzure10:
|
||||
return GetAzure();
|
||||
|
||||
default:
|
||||
if (edition == DatabaseInfo.SQLServerEdition.Azure)
|
||||
return GetAzure();
|
||||
else
|
||||
return Get2008();
|
||||
}
|
||||
}
|
||||
|
||||
private static string Get2005()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT OO.type AS ObjectType, IC.key_ordinal, C.user_type_id, I.object_id, dsidx.Name as FileGroup, C.column_id,C.Name AS ColumnName, I.Name, I.index_id, I.type, is_unique, ignore_dup_key, is_primary_key, is_unique_constraint, fill_factor, is_padded, is_disabled, allow_row_locks, allow_page_locks, IC.is_descending_key, IC.is_included_column, ISNULL(ST.no_recompute,0) AS NoAutomaticRecomputation ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects OO ON OO.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
sql.Append("LEFT JOIN sys.stats AS ST ON ST.stats_id = I.index_id AND ST.object_id = I.object_id ");
|
||||
sql.Append("WHERE I.type IN (1,2,3) ");
|
||||
sql.Append("AND is_unique_constraint = 0 AND is_primary_key = 0 "); //AND I.object_id = " + table.Id.ToString(CultureInfo.InvariantCulture) + " ");
|
||||
sql.Append("AND objectproperty(I.object_id, 'IsMSShipped') <> 1 ");
|
||||
sql.Append("ORDER BY I.object_id, I.Name, IC.column_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string Get2008()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT ISNULL(I.filter_definition,'') AS FilterDefinition, OO.type AS ObjectType, IC.key_ordinal, C.user_type_id, I.object_id, dsidx.Name as FileGroup, C.column_id,C.Name AS ColumnName, I.Name, I.index_id, I.type, is_unique, ignore_dup_key, is_primary_key, is_unique_constraint, fill_factor, is_padded, is_disabled, allow_row_locks, allow_page_locks, IC.is_descending_key, IC.is_included_column, ISNULL(ST.no_recompute,0) AS NoAutomaticRecomputation ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects OO ON OO.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
sql.Append("LEFT JOIN sys.stats AS ST ON ST.stats_id = I.index_id AND ST.object_id = I.object_id ");
|
||||
sql.Append("WHERE I.type IN (1,2,3) ");
|
||||
sql.Append("AND is_unique_constraint = 0 AND is_primary_key = 0 "); //AND I.object_id = " + table.Id.ToString(CultureInfo.InvariantCulture) + " ");
|
||||
sql.Append("AND objectproperty(I.object_id, 'IsMSShipped') <> 1 ");
|
||||
sql.Append("ORDER BY I.object_id, I.Name, IC.column_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetAzure()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("SELECT ISNULL(I.filter_definition,'') AS FilterDefinition, OO.type AS ObjectType, IC.key_ordinal, C.user_type_id, I.object_id, '' as FileGroup, C.column_id,C.Name AS ColumnName, I.Name, I.index_id, I.type, is_unique, ignore_dup_key, is_primary_key, is_unique_constraint, fill_factor, is_padded, is_disabled, allow_row_locks, allow_page_locks, IC.is_descending_key, IC.is_included_column, ISNULL(ST.no_recompute,0) AS NoAutomaticRecomputation ");
|
||||
sql.Append("FROM sys.indexes I ");
|
||||
sql.Append("INNER JOIN sys.objects OO ON OO.object_id = I.object_id ");
|
||||
sql.Append("INNER JOIN sys.index_columns IC ON IC.index_id = I.index_id AND IC.object_id = I.object_id ");
|
||||
//sql.Append("INNER JOIN sys.data_spaces AS dsidx ON dsidx.data_space_id = I.data_space_id ");
|
||||
sql.Append("INNER JOIN sys.columns C ON C.column_id = IC.column_id AND IC.object_id = C.object_id ");
|
||||
sql.Append("LEFT JOIN sys.stats AS ST ON ST.stats_id = I.index_id AND ST.object_id = I.object_id ");
|
||||
sql.Append("WHERE I.type IN (1,2,3) ");
|
||||
sql.Append("AND is_unique_constraint = 0 AND is_primary_key = 0 "); //AND I.object_id = " + table.Id.ToString(CultureInfo.InvariantCulture) + " ");
|
||||
sql.Append("AND objectproperty(I.object_id, 'IsMSShipped') <> 1 ");
|
||||
sql.Append("ORDER BY I.object_id, I.Name, IC.column_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal static class TableSQLCommand
|
||||
{
|
||||
#region Table Count
|
||||
|
||||
public static string GetTableCount(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2000:
|
||||
return GetTableCount2000();
|
||||
|
||||
default:
|
||||
return GetTableCount2005();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetTableCount2000()
|
||||
{
|
||||
return "SELECT Count(*) FROM sysobjects SO WHERE type = 'U'";
|
||||
}
|
||||
|
||||
private static string GetTableCount2005()
|
||||
{
|
||||
return "SELECT Count(*) from sys.tables";
|
||||
}
|
||||
|
||||
#endregion Table Count
|
||||
|
||||
#region Table Detail
|
||||
|
||||
public static string GetTableDetail(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2000:
|
||||
return GetTableDetail2000();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
return GetTableDetail2005();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008:
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008R2:
|
||||
return GetTableDetail2008();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServerAzure10:
|
||||
return GetTableDetailAzure();
|
||||
|
||||
default:
|
||||
if (edition == DatabaseInfo.SQLServerEdition.Azure)
|
||||
return GetTableDetailAzure();
|
||||
else
|
||||
return GetTableDetail2008();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetTableDetailAzure()
|
||||
{
|
||||
var sql = new StringBuilder();
|
||||
sql.AppendLine("SELECT DISTINCT 0 AS HasChangeTrackingTrackColumn, 0 AS HasChangeTracking, TTT.lock_escalation_desc, T.type AS ObjectType, C.Name, C.is_filestream, C.is_sparse, S4.Name as OwnerType,C.user_type_id, C.Column_Id AS ID, C.max_length AS Size, C.Precision, C.Scale, ISNULL(C.Collation_Name,'') as Collation, C.Is_nullable AS IsNullable, C.Is_RowGuidcol AS IsRowGuid, C.Is_Computed AS IsComputed, C.Is_Identity AS IsIdentity, COLUMNPROPERTY(T.object_id,C.name,'IsIdNotForRepl') AS IsIdentityRepl,IDENT_SEED('[' + S1.name + '].[' + T.Name + ']') AS IdentSeed, IDENT_INCR('[' + S1.name + '].[' + T.Name + ']') AS IdentIncrement, ISNULL(CC.Definition,'') AS Formula, ISNULL(CC.Is_Persisted,0) AS FormulaPersisted, ");
|
||||
sql.AppendLine("CASE WHEN ISNULL(DEP.referencing_minor_id,0) = 0 THEN 0 ELSE 1 END AS HasComputedFormula, CASE WHEN ISNULL(IC.column_id,0) = 0 THEN 0 ELSE 1 END AS HasIndex, TY.Name AS Type, '[' + S3.Name + '].' + XSC.Name AS XMLSchema, C.Is_xml_document, TY.is_user_defined, ");
|
||||
sql.AppendLine("ISNULL(TT.Name,T.Name) AS TableName, T.object_id AS TableId,S1.name AS TableOwner,Text_In_Row_limit, large_value_types_out_of_row,ISNULL(objectproperty(T.object_id, N'TableHasVarDecimalStorageFormat'),0) AS HasVarDecimal,OBJECTPROPERTY(T.OBJECT_ID,'TableHasClustIndex') AS HasClusteredIndex, ");
|
||||
sql.AppendLine(" '' AS FileGroup, '' AS FileGroupText, '' AS FileGroupStream,ISNULL(DC.object_id,0) AS DefaultId, DC.name AS DefaultName, DC.definition AS DefaultDefinition, C.rule_object_id, C.default_object_id ");
|
||||
sql.AppendLine("FROM sys.columns C ");
|
||||
sql.AppendLine("INNER JOIN sys.objects T ON T.object_id = C.object_id ");
|
||||
sql.AppendLine("INNER JOIN sys.types TY ON TY.user_type_id = C.user_type_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.indexes IDX ON IDX.object_id = T.object_id and IDX.index_id < 2 ");
|
||||
//sql.Append("LEFT JOIN sys.data_spaces AS DSIDX ON DSIDX.data_space_id = IDX.data_space_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.table_types TT ON TT.type_table_object_id = C.object_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.tables TTT ON TTT.object_id = C.object_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.schemas S1 ON (S1.schema_id = TTT.schema_id and T.type = 'U') OR (S1.schema_id = TT.schema_id and T.type = 'TT')");
|
||||
sql.AppendLine("LEFT JOIN sys.xml_schema_collections XSC ON XSC.xml_collection_id = C.xml_collection_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.schemas S3 ON S3.schema_id = XSC.schema_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.schemas S4 ON S4.schema_id = TY.schema_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.computed_columns CC ON CC.column_id = C.column_Id AND C.object_id = CC.object_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.sql_expression_dependencies DEP ON DEP.referenced_id = C.object_id AND DEP.referenced_minor_id = C.column_Id AND DEP.referencing_id = C.object_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.index_columns IC ON IC.object_id = T.object_id AND IC.column_Id = C.column_Id ");
|
||||
//sql.Append("LEFT JOIN sys.data_spaces AS lob ON lob.data_space_id = TTT.lob_data_space_id ");
|
||||
//sql.Append("LEFT JOIN sys.data_spaces AS filestr ON filestr.data_space_id = TTT.filestream_data_space_id ");
|
||||
sql.AppendLine("LEFT JOIN sys.default_constraints DC ON DC.parent_object_id = T.object_id AND parent_column_id = C.Column_Id ");
|
||||
//sql.Append("LEFT JOIN sys.change_tracking_tables CTT ON CTT.object_id = T.object_id ");
|
||||
sql.AppendLine("WHERE T.type IN ('U','TT') ");
|
||||
sql.AppendLine("ORDER BY ISNULL(TT.Name,T.Name),T.object_id,C.column_id");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetTableDetail2008()
|
||||
{
|
||||
string sql = "";
|
||||
sql += "SELECT DISTINCT (CASE WHEN ISNULL(CTT.is_track_columns_updated_on,0) <> 0 THEN is_track_columns_updated_on ELSE 0 END) AS HasChangeTrackingTrackColumn, (CASE WHEN ISNULL(CTT.object_id,0) <> 0 THEN 1 ELSE 0 END) AS HasChangeTracking, TTT.lock_escalation_desc, T.type AS ObjectType, C.Name, C.is_filestream, C.is_sparse, S4.Name as OwnerType,C.user_type_id, C.Column_Id AS ID, C.max_length AS Size, C.Precision, C.Scale, ISNULL(C.Collation_Name,'') as Collation, C.Is_nullable AS IsNullable, C.Is_RowGuidcol AS IsRowGuid, C.Is_Computed AS IsComputed, C.Is_Identity AS IsIdentity, COLUMNPROPERTY(T.object_id,C.name,'IsIdNotForRepl') AS IsIdentityRepl,IDENT_SEED('[' + S1.name + '].[' + T.Name + ']') AS IdentSeed, IDENT_INCR('[' + S1.name + '].[' + T.Name + ']') AS IdentIncrement, ISNULL(CC.Definition,'') AS Formula, ISNULL(CC.Is_Persisted,0) AS FormulaPersisted, CASE WHEN ISNULL(DEP.column_id,0) = 0 THEN 0 ELSE 1 END AS HasComputedFormula, CASE WHEN ISNULL(IC.column_id,0) = 0 THEN 0 ELSE 1 END AS HasIndex, TY.Name AS Type, '[' + S3.Name + '].' + XSC.Name AS XMLSchema, C.Is_xml_document, TY.is_user_defined, ISNULL(TT.Name,T.Name) AS TableName, T.object_id AS TableId,S1.name AS TableOwner,Text_In_Row_limit, large_value_types_out_of_row,ISNULL(objectproperty(T.object_id, N'TableHasVarDecimalStorageFormat'),0) AS HasVarDecimal,OBJECTPROPERTY(T.OBJECT_ID,'TableHasClustIndex') AS HasClusteredIndex,DSIDX.Name AS FileGroup,ISNULL(lob.Name,'') AS FileGroupText, ISNULL(filestr.Name,'') AS FileGroupStream,ISNULL(DC.object_id,0) AS DefaultId, DC.name AS DefaultName, DC.definition AS DefaultDefinition, C.rule_object_id, C.default_object_id ";
|
||||
sql += "FROM sys.columns C ";
|
||||
sql += "INNER JOIN sys.objects T ON T.object_id = C.object_id ";
|
||||
sql += "INNER JOIN sys.types TY ON TY.user_type_id = C.user_type_id ";
|
||||
sql += "LEFT JOIN sys.indexes IDX ON IDX.object_id = T.object_id and IDX.index_id < 2 ";
|
||||
sql += "LEFT JOIN sys.data_spaces AS DSIDX ON DSIDX.data_space_id = IDX.data_space_id ";
|
||||
sql += "LEFT JOIN sys.table_types TT ON TT.type_table_object_id = C.object_id ";
|
||||
sql += "LEFT JOIN sys.tables TTT ON TTT.object_id = C.object_id ";
|
||||
sql += "LEFT JOIN sys.schemas S1 ON (S1.schema_id = TTT.schema_id and T.type = 'U') OR (S1.schema_id = TT.schema_id and T.type = 'TT')";
|
||||
sql += "LEFT JOIN sys.xml_schema_collections XSC ON XSC.xml_collection_id = C.xml_collection_id ";
|
||||
sql += "LEFT JOIN sys.schemas S3 ON S3.schema_id = XSC.schema_id ";
|
||||
sql += "LEFT JOIN sys.schemas S4 ON S4.schema_id = TY.schema_id ";
|
||||
sql += "LEFT JOIN sys.computed_columns CC ON CC.column_id = C.column_Id AND C.object_id = CC.object_id ";
|
||||
sql += "LEFT JOIN sys.sql_dependencies DEP ON DEP.referenced_major_id = C.object_id AND DEP.referenced_minor_id = C.column_Id AND DEP.object_id = C.object_id ";
|
||||
sql += "LEFT JOIN sys.index_columns IC ON IC.object_id = T.object_id AND IC.column_Id = C.column_Id ";
|
||||
sql += "LEFT JOIN sys.data_spaces AS lob ON lob.data_space_id = TTT.lob_data_space_id ";
|
||||
sql += "LEFT JOIN sys.data_spaces AS filestr ON filestr.data_space_id = TTT.filestream_data_space_id ";
|
||||
sql += "LEFT JOIN sys.default_constraints DC ON DC.parent_object_id = T.object_id AND parent_column_id = C.Column_Id ";
|
||||
sql += "LEFT JOIN sys.change_tracking_tables CTT ON CTT.object_id = T.object_id ";
|
||||
sql += "WHERE T.type IN ('U','TT') ";
|
||||
sql += "ORDER BY ISNULL(TT.Name,T.Name),T.object_id,C.column_id";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string GetTableDetail2005()
|
||||
{
|
||||
string sql = "";
|
||||
sql += "SELECT DISTINCT T.type AS ObjectType, C.Name, S4.Name as OwnerType,";
|
||||
sql += "C.user_type_id, C.Column_Id AS ID, C.max_length AS Size, C.Precision, C.Scale, ISNULL(C.Collation_Name,'') as Collation, C.Is_nullable AS IsNullable, C.Is_RowGuidcol AS IsRowGuid, C.Is_Computed AS IsComputed, C.Is_Identity AS IsIdentity, COLUMNPROPERTY(T.object_id,C.name,'IsIdNotForRepl') AS IsIdentityRepl,IDENT_SEED('[' + S1.name + '].[' + T.Name + ']') AS IdentSeed, IDENT_INCR('[' + S1.name + '].[' + T.Name + ']') AS IdentIncrement, ISNULL(CC.Definition,'') AS Formula, ISNULL(CC.Is_Persisted,0) AS FormulaPersisted, CASE WHEN ISNULL(DEP.column_id,0) = 0 THEN 0 ELSE 1 END AS HasComputedFormula, CASE WHEN ISNULL(IC.column_id,0) = 0 THEN 0 ELSE 1 END AS HasIndex, TY.Name AS Type, '[' + S3.Name + '].' + XSC.Name AS XMLSchema, C.Is_xml_document, TY.is_user_defined, ";
|
||||
sql += "T.Name AS TableName, T.object_id AS TableId,S1.name AS TableOwner,Text_In_Row_limit, large_value_types_out_of_row,ISNULL(objectproperty(T.object_id, N'TableHasVarDecimalStorageFormat'),0) AS HasVarDecimal,OBJECTPROPERTY(T.OBJECT_ID,'TableHasClustIndex') AS HasClusteredIndex,DSIDX.Name AS FileGroup,ISNULL(LOB.Name,'') AS FileGroupText, ";
|
||||
sql += "ISNULL(DC.object_id,0) AS DefaultId, DC.name AS DefaultName, DC.definition AS DefaultDefinition, C.rule_object_id, C.default_object_id ";
|
||||
sql += "FROM sys.columns C ";
|
||||
sql += "INNER JOIN sys.tables T ON T.object_id = C.object_id ";
|
||||
sql += "INNER JOIN sys.types TY ON TY.user_type_id = C.user_type_id ";
|
||||
sql += "INNER JOIN sys.schemas S1 ON S1.schema_id = T.schema_id ";
|
||||
sql += "INNER JOIN sys.indexes IDX ON IDX.object_id = T.object_id and IDX.index_id < 2 ";
|
||||
sql += "INNER JOIN sys.data_spaces AS DSIDX ON DSIDX.data_space_id = IDX.data_space_id ";
|
||||
sql += "LEFT JOIN sys.xml_schema_collections XSC ON XSC.xml_collection_id = C.xml_collection_id ";
|
||||
sql += "LEFT JOIN sys.schemas S3 ON S3.schema_id = XSC.schema_id ";
|
||||
sql += "LEFT JOIN sys.schemas S4 ON S4.schema_id = TY.schema_id ";
|
||||
sql += "LEFT JOIN sys.computed_columns CC ON CC.column_id = C.column_Id AND C.object_id = CC.object_id ";
|
||||
sql += "LEFT JOIN sys.sql_dependencies DEP ON DEP.referenced_major_id = C.object_id AND DEP.referenced_minor_id = C.column_Id AND DEP.object_id = C.object_id ";
|
||||
sql += "LEFT JOIN sys.index_columns IC ON IC.object_id = T.object_id AND IC.column_Id = C.column_Id ";
|
||||
sql += "LEFT JOIN sys.data_spaces AS LOB ON LOB.data_space_id = T.lob_data_space_id ";
|
||||
sql += "LEFT JOIN sys.default_constraints DC ON DC.parent_object_id = T.object_id AND parent_column_id = C.Column_Id ";
|
||||
sql += "ORDER BY T.Name,T.object_id,C.column_id";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string GetTableDetail2000()
|
||||
{
|
||||
string sql = "";
|
||||
sql += "SELECT SO.name, ";
|
||||
sql += "SO.id as object_id, ";
|
||||
sql += "SU.name as Owner, ";
|
||||
sql += "OBJECTPROPERTY(SO.ID,'TableTextInRowLimit') AS Text_In_Row_limit,";
|
||||
sql += "0 AS HasVarDecimal, ";
|
||||
sql += "CONVERT(bit,0) AS large_value_types_out_of_row, ";
|
||||
sql += "F.groupname AS FileGroup, ";
|
||||
sql += "ISNULL(F2.groupname,'') AS FileGroupText, ";
|
||||
sql += "OBJECTPROPERTY(SO.ID,'TableHasClustIndex') AS HasClusteredIndex ";
|
||||
sql += "FROM sysobjects SO ";
|
||||
sql += "inner join sysindexes I ON I.id = SO.id and I.indid < 2 ";
|
||||
sql += "inner join sysfilegroups f on f.groupid = i.groupid ";
|
||||
sql += "left join sysindexes I2 ON I2.id = SO.id and I2.indid = 255 ";
|
||||
sql += "left join sysfilegroups f2 on f2.groupid = i2.groupid ";
|
||||
sql += "INNER JOIN sysusers SU ON SU.uid = SO.uid WHERE type = 'U' ORDER BY SO.name";
|
||||
return sql;
|
||||
}
|
||||
|
||||
#endregion Table Detail
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal static class UserDataTypeCommand
|
||||
{
|
||||
public static string Get(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2000:
|
||||
return Get2000();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
return Get2005();
|
||||
|
||||
default:
|
||||
return Get2008();
|
||||
}
|
||||
}
|
||||
|
||||
public static string Get2008()
|
||||
{
|
||||
string sql = "SELECT ISNULL(AF.name,'') AS assembly_name, ISNULL(AT.assembly_id,0) AS assembly_id, ISNULL(assembly_class,'') AS assembly_class, T.max_length, S2.name as defaultowner, O2.name as defaultname, S1.name as ruleowner, O.name as rulename, ISNULL(T2.Name,'') AS basetypename, S.Name AS Owner, T.Name, T.is_assembly_type, T.user_type_id AS tid, T.is_nullable, T.precision, T.scale ";
|
||||
sql += "FROM sys.types T ";
|
||||
sql += "INNER JOIN sys.schemas S ON S.schema_id = T.schema_id ";
|
||||
sql += "LEFT JOIN sys.types T2 ON T2.user_type_id = T.system_type_id ";
|
||||
sql += "LEFT JOIN sys.objects O ON O.type = 'R' and O.object_id = T.rule_object_id ";
|
||||
sql += "LEFT JOIN sys.schemas S1 ON S1.schema_id = O.schema_id ";
|
||||
sql += "LEFT JOIN sys.objects O2 ON O2.type = 'D' and O2.object_id = T.default_object_id ";
|
||||
sql += "LEFT JOIN sys.schemas S2 ON S2.schema_id = O2.schema_id ";
|
||||
sql += "LEFT JOIN sys.assembly_types AT ON AT.user_type_id = T.user_type_id AND T.is_assembly_type = 1 ";
|
||||
sql += "LEFT JOIN sys.assemblies AF ON AF.assembly_id = AT.assembly_id ";
|
||||
sql += "WHERE T.is_user_defined = 1 AND T.is_table_type = 0 ORDER BY T.Name";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public static string Get2005()
|
||||
{
|
||||
string sql = "select ISNULL(AF.name,'') AS assembly_name, ISNULL(AT.assembly_id,0) AS assembly_id, ISNULL(assembly_class,'') AS assembly_class, T.max_length, S2.name as defaultowner, O2.name as defaultname, S1.name as ruleowner, O.name as rulename, ISNULL(T2.Name,'') AS basetypename, S.Name AS Owner, T.Name, T.is_assembly_type, T.user_type_id AS tid, T.is_nullable, T.precision, T.scale from sys.types T ";
|
||||
sql += "INNER JOIN sys.schemas S ON S.schema_id = T.schema_id ";
|
||||
sql += "LEFT JOIN sys.types T2 ON T2.user_type_id = T.system_type_id ";
|
||||
sql += "LEFT JOIN sys.objects O ON O.type = 'R' and O.object_id = T.rule_object_id ";
|
||||
sql += "LEFT JOIN sys.schemas S1 ON S1.schema_id = O.schema_id ";
|
||||
sql += "LEFT JOIN sys.objects O2 ON O2.type = 'D' and O2.object_id = T.default_object_id ";
|
||||
sql += "LEFT JOIN sys.schemas S2 ON S2.schema_id = O2.schema_id ";
|
||||
sql += "LEFT JOIN sys.assembly_types AT ON AT.user_type_id = T.user_type_id AND T.is_assembly_type = 1 ";
|
||||
sql += "LEFT JOIN sys.assemblies AF ON AF.assembly_id = AT.assembly_id ";
|
||||
sql += "WHERE T.is_user_defined = 1 ORDER BY T.Name";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public static string Get2000()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal static class UserSQLCommand
|
||||
{
|
||||
public static string Get(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2000:
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008:
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008R2:
|
||||
return Get2008();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServerAzure10:
|
||||
return GetAzure();
|
||||
|
||||
default:
|
||||
if (edition == DatabaseInfo.SQLServerEdition.Azure)
|
||||
return GetAzure();
|
||||
else
|
||||
return Get2008();
|
||||
}
|
||||
}
|
||||
|
||||
private static string Get2008()
|
||||
{
|
||||
var sql = new StringBuilder();
|
||||
sql.AppendLine("SELECT is_fixed_role, type, ISNULL(suser_sname(sid),'') AS Login,Name,principal_id, ISNULL(default_schema_name,'') AS default_schema_name ");
|
||||
sql.AppendLine("FROM sys.database_principals ");
|
||||
sql.AppendLine("WHERE type IN ('S','U','A','R') ");
|
||||
sql.AppendLine("ORDER BY Name");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
private static string GetAzure()
|
||||
{
|
||||
var sql = new StringBuilder();
|
||||
//to get LoginName in Azure (asside for the current login) you would have to link to master and query sys.sysusers or sys.sql_users
|
||||
//the CASE test below will at least get you the Current login
|
||||
sql.AppendLine("SELECT is_fixed_role, type, CASE WHEN suser_sid()=sid THEN suser_sname() ELSE '' END AS Login,Name,principal_id, ISNULL(default_schema_name,'') AS default_schema_name ");
|
||||
sql.AppendLine("FROM sys.database_principals ");
|
||||
sql.AppendLine("WHERE type IN ('S','U','A','R') ");
|
||||
sql.AppendLine("ORDER BY Name");
|
||||
return sql.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.SQLCommands
|
||||
{
|
||||
internal static class ViewSQLCommand
|
||||
{
|
||||
#region View
|
||||
|
||||
public static string GetView(DatabaseInfo.SQLServerVersion version, DatabaseInfo.SQLServerEdition edition)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2000:
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2005:
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008:
|
||||
case DatabaseInfo.SQLServerVersion.SQLServer2008R2:
|
||||
return GetViewSql2008();
|
||||
|
||||
case DatabaseInfo.SQLServerVersion.SQLServerAzure10:
|
||||
return GetViewSqlAzure();
|
||||
|
||||
default:
|
||||
if (edition == DatabaseInfo.SQLServerEdition.Azure)
|
||||
return GetViewSqlAzure();
|
||||
else
|
||||
return GetViewSql2008();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetViewSql2008()
|
||||
{
|
||||
string sql = "";
|
||||
sql += "select distinct ISNULL('[' + S3.Name + '].[' + object_name(D2.object_id) + ']','') AS DependOut, '[' + S2.Name + '].[' + object_name(D.referenced_major_id) + ']' AS TableName, D.referenced_major_id, OBJECTPROPERTY (P.object_id,'IsSchemaBound') AS IsSchemaBound, P.object_id, S.name as owner, P.name as name from sys.views P ";
|
||||
sql += "INNER JOIN sys.schemas S ON S.schema_id = P.schema_id ";
|
||||
sql += "LEFT JOIN sys.sql_dependencies D ON P.object_id = D.object_id ";
|
||||
sql += "LEFT JOIN sys.objects O ON O.object_id = D.referenced_major_id ";
|
||||
sql += "LEFT JOIN sys.schemas S2 ON S2.schema_id = O.schema_id ";
|
||||
sql += "LEFT JOIN sys.sql_dependencies D2 ON P.object_id = D2.referenced_major_id ";
|
||||
sql += "LEFT JOIN sys.objects O2 ON O2.object_id = D2.object_id ";
|
||||
sql += "LEFT JOIN sys.schemas S3 ON S3.schema_id = O2.schema_id ";
|
||||
sql += "ORDER BY P.object_id";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string GetViewSqlAzure()
|
||||
{
|
||||
var sql = new StringBuilder();
|
||||
//Avoid using sql_dependencies. Use sys.sql_expression_dependencies instead. http://msdn.microsoft.com/en-us/library/ms174402.aspx
|
||||
sql.Append("SELECT DISTINCT ISNULL('[' + S3.Name + '].[' + object_name(D2.referencing_id) + ']','') AS DependOut, ");
|
||||
sql.Append("'[' + S2.Name + '].[' + object_name(D.referenced_id) + ']' AS TableName, ");
|
||||
sql.Append("D.referenced_id AS referenced_major_id, OBJECTPROPERTY (P.object_id,'IsSchemaBound') AS IsSchemaBound, ");
|
||||
sql.Append("P.object_id, S.name as owner, P.name as name ");
|
||||
sql.Append("FROM sys.views P ");
|
||||
sql.Append("INNER JOIN sys.schemas S ON S.schema_id = P.schema_id ");
|
||||
sql.Append("LEFT JOIN sys.sql_expression_dependencies D ON P.object_id = D.referencing_id ");
|
||||
sql.Append("LEFT JOIN sys.objects O ON O.object_id = D.referenced_id ");
|
||||
sql.Append("LEFT JOIN sys.schemas S2 ON S2.schema_id = O.schema_id ");
|
||||
sql.Append("LEFT JOIN sys.sql_expression_dependencies D2 ON P.object_id = D2.referenced_id ");
|
||||
sql.Append("LEFT JOIN sys.objects O2 ON O2.object_id = D2.referencing_id ");
|
||||
sql.Append("LEFT JOIN sys.schemas S3 ON S3.schema_id = O2.schema_id ");
|
||||
sql.Append("ORDER BY P.object_id ");
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
#endregion View
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// This class implements a fast conversion from a byte array to an hex string.
|
||||
/// </summary>
|
||||
public class ByteToHexEncoder
|
||||
{
|
||||
private static readonly uint[] _lookup32 = CreateLookup32();
|
||||
|
||||
private static uint[] CreateLookup32()
|
||||
{
|
||||
var result = new uint[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
var s = i.ToString("X2");
|
||||
result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string ByteArrayToHex(byte[] bytes)
|
||||
{
|
||||
var result = new char[2 + bytes.Length * 2];
|
||||
|
||||
result[0] = '0';
|
||||
result[1] = 'x';
|
||||
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
var val = _lookup32[bytes[i]];
|
||||
result[2 * i + 2] = (char)val;
|
||||
result[2 * i + 3] = (char)(val >> 16);
|
||||
}
|
||||
|
||||
return new string(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.Util
|
||||
{
|
||||
internal class Constants
|
||||
{
|
||||
public const int READING_RULES = 0;
|
||||
public const int READING_TABLES = 1;
|
||||
public const int READING_CONSTRAINTS = 2;
|
||||
public const int READING_UDT = 3;
|
||||
public const int READING_XMLSCHEMAS = 4;
|
||||
public const int READING_SCHEMAS = 5;
|
||||
public const int READING_USER = 6;
|
||||
public const int READING_PARTITIONFUNCTION = 7;
|
||||
public const int READING_PARTITIONSCHEME = 8;
|
||||
public const int READING_FILEGROUPS = 9;
|
||||
public const int READING_DLLTRIGGERS = 10;
|
||||
public const int READING_SYNONYMS = 11;
|
||||
public const int READING_ASSEMBLIES = 12;
|
||||
public const int READING_PROCEDURES = 13;
|
||||
public const int READING_VIEWS = 14;
|
||||
public const int READING_FUNCTIONS = 15;
|
||||
public const int READING_INDEXES = 16;
|
||||
public const int READING_TRIGGERS = 17;
|
||||
public const int READING_TEXTOBJECTS = 18;
|
||||
public const int READING_EXTENDED_PROPERTIES = 19;
|
||||
public const int READING_MAX = 20;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Generates.Util
|
||||
{
|
||||
internal static class ConvertType
|
||||
{
|
||||
public static ObjectType GetObjectType(string type)
|
||||
{
|
||||
if (type.Trim().Equals("V")) return ObjectType.View;
|
||||
if (type.Trim().Equals("U")) return ObjectType.Table;
|
||||
if (type.Trim().Equals("FN")) return ObjectType.Function;
|
||||
if (type.Trim().Equals("TF")) return ObjectType.Function;
|
||||
if (type.Trim().Equals("IF")) return ObjectType.Function;
|
||||
if (type.Trim().Equals("P")) return ObjectType.StoredProcedure;
|
||||
if (type.Trim().Equals("TR")) return ObjectType.Trigger;
|
||||
return ObjectType.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
126
OpenDBDiff.Schema.SQLServer.Generates/Model/Assembly.cs
Normal file
126
OpenDBDiff.Schema.SQLServer.Generates/Model/Assembly.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class Assembly : Code
|
||||
{
|
||||
public Assembly(ISchemaBase parent)
|
||||
: base(parent, ObjectType.Assembly, ScriptAction.AddAssembly, ScriptAction.DropAssembly)
|
||||
{
|
||||
Files = new SchemaList<AssemblyFile, Assembly>(this);
|
||||
}
|
||||
|
||||
public override ISchemaBase Clone(ISchemaBase parent)
|
||||
{
|
||||
Assembly item = new Assembly(parent)
|
||||
{
|
||||
Id = this.Id,
|
||||
Name = this.Name,
|
||||
Owner = this.Owner,
|
||||
Visible = this.Visible,
|
||||
Text = this.Text,
|
||||
PermissionSet = this.PermissionSet,
|
||||
CLRName = this.CLRName,
|
||||
Guid = this.Guid,
|
||||
Files = this.Files
|
||||
};
|
||||
this.DependenciesOut.ForEach(dep => item.DependenciesOut.Add(dep));
|
||||
this.ExtendedProperties.ForEach(ep => item.ExtendedProperties.Add(ep));
|
||||
return item;
|
||||
}
|
||||
|
||||
public SchemaList<AssemblyFile, Assembly> Files { get; set; }
|
||||
|
||||
public override string FullName
|
||||
{
|
||||
get { return "[" + Name + "]"; }
|
||||
}
|
||||
|
||||
public string CLRName { get; set; }
|
||||
|
||||
public bool Visible { get; set; }
|
||||
|
||||
public string PermissionSet { get; set; }
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
string access = PermissionSet;
|
||||
if (PermissionSet.Equals("UNSAFE_ACCESS")) access = "UNSAFE";
|
||||
if (PermissionSet.Equals("SAFE_ACCESS")) access = "SAFE";
|
||||
string toSql = "CREATE ASSEMBLY ";
|
||||
toSql += FullName + "\r\n";
|
||||
toSql += "AUTHORIZATION " + Owner + "\r\n";
|
||||
toSql += "FROM " + Text + "\r\n";
|
||||
toSql += "WITH PERMISSION_SET = " + access + "\r\n";
|
||||
toSql += "GO\r\n";
|
||||
toSql += Files.ToSql();
|
||||
toSql += this.ExtendedProperties.ToSql();
|
||||
return toSql;
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "DROP ASSEMBLY " + FullName + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return ToSql();
|
||||
}
|
||||
|
||||
private string ToSQLAlter()
|
||||
{
|
||||
string access = PermissionSet;
|
||||
if (PermissionSet.Equals("UNSAFE_ACCESS")) access = "UNSAFE";
|
||||
if (PermissionSet.Equals("SAFE_ACCESS")) access = "SAFE";
|
||||
return "ALTER ASSEMBLY " + FullName + " WITH PERMISSION_SET = " + access + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
private string ToSQLAlterOwner()
|
||||
{
|
||||
return "ALTER AUTHORIZATION ON ASSEMBLY::" + FullName + " TO " + Owner + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
|
||||
if (this.Status == ObjectStatus.Drop)
|
||||
{
|
||||
list.AddRange(RebuildDependencies());
|
||||
list.Add(Drop());
|
||||
}
|
||||
if (this.Status == ObjectStatus.Create)
|
||||
list.Add(Create());
|
||||
if (this.HasState(ObjectStatus.Rebuild))
|
||||
list.AddRange(Rebuild());
|
||||
if (this.HasState(ObjectStatus.ChangeOwner))
|
||||
list.Add(ToSQLAlterOwner(), 0, ScriptAction.AlterAssembly);
|
||||
if (this.HasState(ObjectStatus.PermissionSet))
|
||||
list.Add(ToSQLAlter(), 0, ScriptAction.AlterAssembly);
|
||||
if (this.HasState(ObjectStatus.Alter))
|
||||
list.AddRange(Files.ToSqlDiff());
|
||||
list.AddRange(this.ExtendedProperties.ToSqlDiff());
|
||||
return list;
|
||||
}
|
||||
|
||||
public bool Compare(Assembly obj)
|
||||
{
|
||||
if (obj == null) throw new ArgumentNullException("obj");
|
||||
if (!this.CLRName.Equals(obj.CLRName)) return false;
|
||||
if (!this.PermissionSet.Equals(obj.PermissionSet)) return false;
|
||||
if (!this.Owner.Equals(obj.Owner)) return false;
|
||||
if (!this.Text.Equals(obj.Text)) return false;
|
||||
if (this.Files.Count != obj.Files.Count) return false;
|
||||
for (int j = 0; j < this.Files.Count; j++)
|
||||
if (!this.Files[j].Content.Equals(obj.Files[j].Content)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override Boolean IsCodeType
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
67
OpenDBDiff.Schema.SQLServer.Generates/Model/AssemblyFile.cs
Normal file
67
OpenDBDiff.Schema.SQLServer.Generates/Model/AssemblyFile.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class AssemblyFile : SQLServerSchemaBase
|
||||
{
|
||||
public AssemblyFile(ISchemaBase parent, AssemblyFile assemblyFile, ObjectStatus status)
|
||||
: base(parent, ObjectType.AssemblyFile)
|
||||
{
|
||||
this.Name = assemblyFile.Name;
|
||||
this.Content = assemblyFile.Content;
|
||||
this.Status = status;
|
||||
}
|
||||
|
||||
public AssemblyFile(ISchemaBase parent, string name, string content)
|
||||
: base(parent, ObjectType.AssemblyFile)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Content = content;
|
||||
}
|
||||
|
||||
public override string FullName
|
||||
{
|
||||
get { return "[" + Name + "]"; }
|
||||
}
|
||||
|
||||
public string Content { get; set; }
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
string sql = "ALTER ASSEMBLY ";
|
||||
sql += this.Parent.FullName + "\r\n";
|
||||
sql += "ADD FILE FROM " + this.Content + "\r\n";
|
||||
sql += "AS N'" + this.Name + "'\r\n";
|
||||
return sql + "GO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
return ToSqlAdd();
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
string sql = "ALTER ASSEMBLY ";
|
||||
sql += this.Parent.FullName + "\r\n";
|
||||
sql += "DROP FILE N'" + this.Name + "'\r\n";
|
||||
return sql + "GO\r\n";
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList listDiff = new SQLScriptList();
|
||||
|
||||
if (this.Status == ObjectStatus.Drop)
|
||||
listDiff.Add(ToSqlDrop(), 0, ScriptAction.DropAssemblyFile);
|
||||
if (this.Status == ObjectStatus.Create)
|
||||
listDiff.Add(ToSqlAdd(), 0, ScriptAction.AddAssemblyFile);
|
||||
if (this.HasState(ObjectStatus.Alter))
|
||||
{
|
||||
listDiff.Add(ToSqlDrop(), 0, ScriptAction.DropAssemblyFile);
|
||||
listDiff.Add(ToSqlAdd(), 0, ScriptAction.AddAssemblyFile);
|
||||
}
|
||||
return listDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
OpenDBDiff.Schema.SQLServer.Generates/Model/CLRCode.cs
Normal file
30
OpenDBDiff.Schema.SQLServer.Generates/Model/CLRCode.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public abstract class CLRCode : Code
|
||||
{
|
||||
public CLRCode(ISchemaBase parent, ObjectType type, ScriptAction addAction, ScriptAction dropAction)
|
||||
: base(parent, type, addAction, dropAction)
|
||||
{
|
||||
}
|
||||
|
||||
public string AssemblyMethod { get; set; }
|
||||
|
||||
public string AssemblyExecuteAs { get; set; }
|
||||
|
||||
public string AssemblyName { get; set; }
|
||||
|
||||
public Boolean IsAssembly { get; set; }
|
||||
|
||||
public string AssemblyClass { get; set; }
|
||||
|
||||
public int AssemblyId { get; set; }
|
||||
|
||||
public override Boolean IsCodeType
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
56
OpenDBDiff.Schema.SQLServer.Generates/Model/CLRFunction.cs
Normal file
56
OpenDBDiff.Schema.SQLServer.Generates/Model/CLRFunction.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class CLRFunction : CLRCode
|
||||
{
|
||||
public CLRFunction(ISchemaBase parent)
|
||||
: base(parent, ObjectType.CLRFunction, ScriptAction.AddFunction, ScriptAction.DropFunction)
|
||||
{
|
||||
Parameters = new List<Parameter>();
|
||||
ReturnType = new Parameter();
|
||||
}
|
||||
|
||||
public List<Parameter> Parameters { get; set; }
|
||||
|
||||
public Parameter ReturnType { get; private set; }
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
string sql = "CREATE FUNCTION " + FullName + "";
|
||||
string param = "";
|
||||
Parameters.ForEach(item => param += item.ToSql() + ",");
|
||||
if (!String.IsNullOrEmpty(param))
|
||||
{
|
||||
param = param.Substring(0, param.Length - 1);
|
||||
sql += " (" + param + ")\r\n";
|
||||
}
|
||||
else
|
||||
sql += "()\r\n";
|
||||
sql += "RETURNS " + ReturnType.ToSql() + " ";
|
||||
sql += "WITH EXECUTE AS " + AssemblyExecuteAs + "\r\n";
|
||||
sql += "AS\r\n";
|
||||
sql += "EXTERNAL NAME [" + AssemblyName + "].[" + AssemblyClass + "].[" + AssemblyMethod + "]\r\n";
|
||||
sql += "GO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
|
||||
if (this.HasState(ObjectStatus.Drop))
|
||||
list.Add(Drop());
|
||||
if (this.HasState(ObjectStatus.Create))
|
||||
list.Add(Create());
|
||||
if (this.Status == ObjectStatus.Alter)
|
||||
{
|
||||
list.AddRange(Rebuild());
|
||||
}
|
||||
list.AddRange(this.ExtendedProperties.ToSqlDiff());
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class CLRStoredProcedure : CLRCode
|
||||
{
|
||||
public CLRStoredProcedure(ISchemaBase parent)
|
||||
: base(parent, ObjectType.CLRStoredProcedure, ScriptAction.AddStoredProcedure, ScriptAction.DropStoredProcedure)
|
||||
{
|
||||
Parameters = new List<Parameter>();
|
||||
}
|
||||
|
||||
public List<Parameter> Parameters { get; set; }
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
string sql = "CREATE PROCEDURE " + FullName + "\r\n";
|
||||
string param = "";
|
||||
Parameters.ForEach(item => param += "\t" + item.ToSql() + ",\r\n");
|
||||
if (!String.IsNullOrEmpty(param)) param = param.Substring(0, param.Length - 3) + "\r\n";
|
||||
sql += param;
|
||||
sql += "WITH EXECUTE AS " + AssemblyExecuteAs + "\r\n";
|
||||
sql += "AS\r\n";
|
||||
sql += "EXTERNAL NAME [" + AssemblyName + "].[" + AssemblyClass + "].[" + AssemblyMethod + "]\r\n";
|
||||
sql += "GO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
|
||||
if (this.HasState(ObjectStatus.Drop))
|
||||
list.Add(Drop());
|
||||
if (this.HasState(ObjectStatus.Create))
|
||||
list.Add(Create());
|
||||
if (this.Status == ObjectStatus.Alter)
|
||||
{
|
||||
list.AddRange(Rebuild());
|
||||
}
|
||||
list.AddRange(this.ExtendedProperties.ToSqlDiff());
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
48
OpenDBDiff.Schema.SQLServer.Generates/Model/CLRTrigger.cs
Normal file
48
OpenDBDiff.Schema.SQLServer.Generates/Model/CLRTrigger.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class CLRTrigger : CLRCode
|
||||
{
|
||||
public CLRTrigger(ISchemaBase parent)
|
||||
: base(parent, ObjectType.CLRTrigger, ScriptAction.AddTrigger, ScriptAction.DropTrigger)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
string sql = "CREATE TRIGGER " + FullName + " ON " + Parent.FullName;
|
||||
sql += " AFTER ";
|
||||
if (IsInsert) sql += "INSERT,";
|
||||
if (IsUpdate) sql += "UPDATE,";
|
||||
if (IsDelete) sql += "DELETE,";
|
||||
sql = sql.Substring(0, sql.Length - 1) + " ";
|
||||
sql += "AS\r\n";
|
||||
sql += "EXTERNAL NAME [" + AssemblyName + "].[" + AssemblyClass + "].[" + AssemblyMethod + "]\r\n";
|
||||
sql += "GO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public bool IsUpdate { get; set; }
|
||||
|
||||
public bool IsInsert { get; set; }
|
||||
|
||||
public bool IsDelete { get; set; }
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
|
||||
if (this.HasState(ObjectStatus.Drop))
|
||||
list.Add(Drop());
|
||||
if (this.HasState(ObjectStatus.Create))
|
||||
list.Add(Create());
|
||||
if (this.Status == ObjectStatus.Alter)
|
||||
{
|
||||
list.AddRange(Rebuild());
|
||||
}
|
||||
list.AddRange(this.ExtendedProperties.ToSqlDiff());
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
256
OpenDBDiff.Schema.SQLServer.Generates/Model/Code.cs
Normal file
256
OpenDBDiff.Schema.SQLServer.Generates/Model/Code.cs
Normal file
@@ -0,0 +1,256 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model.Util;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.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));
|
||||
}
|
||||
}
|
||||
}
|
||||
641
OpenDBDiff.Schema.SQLServer.Generates/Model/Column.cs
Normal file
641
OpenDBDiff.Schema.SQLServer.Generates/Model/Column.cs
Normal file
@@ -0,0 +1,641 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Xml.Serialization;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class Column : SQLServerSchemaBase, IComparable<Column>
|
||||
{
|
||||
public Column(ISchemaBase parent)
|
||||
: base(parent, ObjectType.Column)
|
||||
{
|
||||
ComputedFormula = "";
|
||||
Collation = "";
|
||||
this.Default = new Default(this);
|
||||
this.Rule = new Rule(this);
|
||||
this.DefaultConstraint = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clona el objeto Column en una nueva instancia.
|
||||
/// </summary>
|
||||
public new Column Clone(ISchemaBase parent)
|
||||
{
|
||||
Column col;
|
||||
if (parent == null)
|
||||
col = new Column(this.Parent);
|
||||
else
|
||||
col = new Column(parent);
|
||||
col.ComputedFormula = this.ComputedFormula;
|
||||
col.DataUserTypeId = this.DataUserTypeId;
|
||||
col.Id = this.Id;
|
||||
col.Guid = this.Guid;
|
||||
col.Owner = this.Owner;
|
||||
col.IdentityIncrement = this.IdentityIncrement;
|
||||
col.IdentitySeed = this.IdentitySeed;
|
||||
col.IsIdentity = this.IsIdentity;
|
||||
col.IsIdentityForReplication = this.IsIdentityForReplication;
|
||||
col.IsComputed = this.IsComputed;
|
||||
col.IsRowGuid = this.IsRowGuid;
|
||||
col.IsPersisted = this.IsPersisted;
|
||||
col.IsFileStream = this.IsFileStream;
|
||||
col.IsSparse = this.IsSparse;
|
||||
col.IsXmlDocument = this.IsXmlDocument;
|
||||
col.IsUserDefinedType = this.IsUserDefinedType;
|
||||
col.HasComputedDependencies = this.HasComputedDependencies;
|
||||
col.HasIndexDependencies = this.HasIndexDependencies;
|
||||
col.Name = this.Name;
|
||||
col.IsNullable = this.IsNullable;
|
||||
col.Position = this.Position;
|
||||
col.Precision = this.Precision;
|
||||
col.Scale = this.Scale;
|
||||
col.Collation = this.Collation;
|
||||
col.Size = this.Size;
|
||||
col.Status = this.Status;
|
||||
col.Type = this.Type;
|
||||
col.XmlSchema = this.XmlSchema;
|
||||
col.Default = this.Default.Clone(this);
|
||||
col.Rule = this.Rule.Clone(this);
|
||||
if (this.DefaultConstraint != null)
|
||||
col.DefaultConstraint = this.DefaultConstraint.Clone(this);
|
||||
return col;
|
||||
}
|
||||
|
||||
public ColumnConstraint DefaultConstraint { get; set; }
|
||||
|
||||
public Rule Rule { get; set; }
|
||||
|
||||
public Default Default { get; set; }
|
||||
|
||||
public Boolean IsFileStream { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is XML document.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is XML document; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean IsXmlDocument { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the XML schema.
|
||||
/// </summary>
|
||||
/// <value>The XML schema.</value>
|
||||
public string XmlSchema { get; set; }
|
||||
|
||||
public Boolean IsSparse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is user defined type.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is user defined type; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean IsUserDefinedType { get; set; }
|
||||
|
||||
public int DataUserTypeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the column position.
|
||||
/// </summary>
|
||||
/// <value>The position.</value>
|
||||
public int Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scale (only in numeric or decimal datatypes).
|
||||
/// </summary>
|
||||
/// <value>The scale.</value>
|
||||
public int Scale { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the precision (only in numeric or decimal datatypes).
|
||||
/// </summary>
|
||||
/// <value>The precision.</value>
|
||||
public int Precision { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collation (only in text datatypes).
|
||||
/// </summary>
|
||||
/// <value>The collation.</value>
|
||||
public string Collation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Column"/> is nullable.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if nullable; otherwise, <c>false</c>.</value>
|
||||
public Boolean IsNullable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size.
|
||||
/// </summary>
|
||||
/// <value>The size.</value>
|
||||
public int Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is persisted (only in Computed columns).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is persisted; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean IsPersisted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance has index dependencies.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance has index dependencies; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean HasIndexDependencies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance has computed dependencies.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance has computed dependencies; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean HasComputedDependencies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance has to rebuild only constraint.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance has to rebuild only constraint; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean HasToRebuildOnlyConstraint
|
||||
{
|
||||
get
|
||||
{
|
||||
return (HasIndexDependencies && !HasComputedDependencies && !IsComputed);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance has to rebuild.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance has to rebuild; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean HasToRebuild(int newPosition, string newType, bool isFileStream)
|
||||
{
|
||||
if (newType.Equals("text") && (!this.IsText)) return true;
|
||||
if (newType.Equals("ntext") && (!this.IsText)) return true;
|
||||
if (newType.Equals("image") && (!this.IsBinary)) return true;
|
||||
if (isFileStream != this.IsFileStream) return true;
|
||||
return ((Position != newPosition) || HasComputedDependencies || HasIndexDependencies || IsComputed || Type.ToLower().Equals("timestamp"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the computed formula (only in Computed columns).
|
||||
/// </summary>
|
||||
/// <value>The computed formula.</value>
|
||||
public string ComputedFormula { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is computed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is computed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean IsComputed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this column is BLOB.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this column is BLOB; otherwise, <c>false</c>.</value>
|
||||
public Boolean IsBLOB
|
||||
{
|
||||
get
|
||||
{
|
||||
return Type.Equals("varchar(MAX)") || Type.Equals("nvarchar(MAX)") || Type.Equals("varbinary(MAX)") || Type.Equals("text") || Type.Equals("image") || Type.Equals("ntext") || Type.Equals("xml");
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Type.Equals("varchar(MAX)") || Type.Equals("nvarchar(MAX)") || Type.Equals("ntext") || Type.Equals("text") || Type.Equals("nvarchar") || Type.Equals("varchar") || Type.Equals("xml") || Type.Equals("char") || Type.Equals("nchar");
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean IsBinary
|
||||
{
|
||||
get
|
||||
{
|
||||
return Type.Equals("varbinary") || Type.Equals("varbinary(MAX)") || Type.Equals("image") || Type.Equals("binary");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this field is identity for replication.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this field is identity for replication; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean IsIdentityForReplication { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this field is identity.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this field is identity; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean IsIdentity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the identity increment (only if the field is Identity).
|
||||
/// </summary>
|
||||
/// <value>The identity increment.</value>
|
||||
public int IdentityIncrement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the identity seed (only if the field is Identity).
|
||||
/// </summary>
|
||||
/// <value>The identity seed.</value>
|
||||
public long IdentitySeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indica si el campo es Row Guid
|
||||
/// </summary>
|
||||
public Boolean IsRowGuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nombre completo del objeto, incluyendo el owner.
|
||||
/// </summary>
|
||||
public override string FullName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Parent.FullName + ".[" + Name + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convierte el schema de la tabla en XML.
|
||||
/// </summary>
|
||||
public string ToXML()
|
||||
{
|
||||
/*string xml = "";
|
||||
xml += "<COLUMN name=\"" + Name + "\" HasIndexDependencies=\"" + (hasIndexDependencies ? "1" : "0") + "\" HasComputedDependencies=\"" + (hasComputedDependencies ? "1" : "0") + "\" IsRowGuid=\"" + (isRowGuid ? "1" : "0") + "\" IsComputed=\"" + (isComputed ? "1" : "0") + "\" computedFormula=\"" + computedFormula + "\">\n";
|
||||
xml += "<TYPE>" + type + "</TYPE>";
|
||||
xml += "<ORIGINALTYPE>" + OriginalType + "</ORIGINALTYPE>";
|
||||
xml += "<SIZE>" + size.ToString() + "</SIZE>";
|
||||
xml += "<NULLABLE>" + (nullable ? "1":"0") + "</NULLABLE>";
|
||||
xml += "<PREC>" + precision.ToString() + "</PREC>";
|
||||
xml += "<SCALE>" + scale.ToString() + "</SCALE>";
|
||||
if (this.identity)
|
||||
xml += "<IDENTITY seed=\"" + identitySeed.ToString() + "\",increment=\"" + identityIncrement.ToString() + "\"/>";
|
||||
if (this.identityForReplication)
|
||||
xml += "<IDENTITYNOTFORREPLICATION seed=\"" + identitySeed.ToString() + "\",increment=\"" + identityIncrement.ToString() + "\"/>";
|
||||
xml += constraints.ToXML();
|
||||
xml += "</COLUMN>\n";
|
||||
return xml;*/
|
||||
XmlSerializer serial = new XmlSerializer(this.GetType());
|
||||
return serial.ToString();
|
||||
}
|
||||
|
||||
public Boolean HasToForceValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.HasState(ObjectStatus.Update)) || ((!this.IsNullable) && (this.Status == ObjectStatus.Create));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default force value.
|
||||
/// </summary>
|
||||
/// <value>The default force value.</value>
|
||||
public string DefaultForceValue
|
||||
{
|
||||
get
|
||||
{
|
||||
string tl = this.Type;
|
||||
if (this.IsUserDefinedType)
|
||||
tl = ((Database)this.Parent.Parent).UserTypes[Type].Type.ToLower();
|
||||
|
||||
if ((((Database)Parent.Parent).Options.Defaults.UseDefaultValueIfExists) && (this.DefaultConstraint != null))
|
||||
{
|
||||
return this.DefaultConstraint.Definition;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tl.Equals("time")) return ((Database)Parent.Parent).Options.Defaults.DefaultTime;
|
||||
if (tl.Equals("int") || tl.Equals("bit") || tl.Equals("smallint") || tl.Equals("bigint") || tl.Equals("tinyint")) return ((Database)Parent.Parent).Options.Defaults.DefaultIntegerValue;
|
||||
if (tl.Equals("text") || tl.Equals("char") || tl.Equals("varchar") || tl.Equals("varchar(max)")) return ((Database)Parent.Parent).Options.Defaults.DefaultTextValue;
|
||||
if (tl.Equals("ntext") || tl.Equals("nchar") || tl.Equals("nvarchar") || tl.Equals("nvarchar(max)")) return ((Database)Parent.Parent).Options.Defaults.DefaultNTextValue;
|
||||
if (tl.Equals("date") || tl.Equals("datetimeoffset") || tl.Equals("datetime2") || tl.Equals("datetime") || tl.Equals("smalldatetime")) return ((Database)Parent.Parent).Options.Defaults.DefaultDateValue;
|
||||
if (tl.Equals("numeric") || tl.Equals("decimal") || tl.Equals("float") || tl.Equals("money") || tl.Equals("smallmoney") || tl.Equals("real")) return ((Database)Parent.Parent).Options.Defaults.DefaultRealValue;
|
||||
if (tl.Equals("sql_variant")) return ((Database)Parent.Parent).Options.Defaults.DefaultVariantValue;
|
||||
if (tl.Equals("uniqueidentifier")) return ((Database)Parent.Parent).Options.Defaults.DefaultUniqueValue;
|
||||
if (tl.Equals("image") || tl.Equals("binary") || tl.Equals("varbinary")) return ((Database)Parent.Parent).Options.Defaults.DefaultBlobValue;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Toes the SQL drop.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
string sql = "ALTER TABLE " + Parent.FullName + " DROP COLUMN [" + Name + "]\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toes the SQL add.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return "ALTER TABLE " + Parent.FullName + " ADD " + ToSql(false) + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
return ToSql(true);
|
||||
}
|
||||
|
||||
public string ToSQLRedefine(string type, int size, string xmlSchema)
|
||||
{
|
||||
string originalType = "";
|
||||
int originalSize = 0;
|
||||
string originalXMLSchema = "";
|
||||
|
||||
string sql;
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
originalType = this.Type;
|
||||
this.Type = type;
|
||||
}
|
||||
if (size != 0)
|
||||
{
|
||||
originalSize = this.Size;
|
||||
this.Size = size;
|
||||
}
|
||||
if (xmlSchema != null)
|
||||
{
|
||||
originalXMLSchema = this.XmlSchema;
|
||||
this.XmlSchema = xmlSchema;
|
||||
|
||||
}
|
||||
sql = this.ToSql(false);
|
||||
|
||||
if (type != null)
|
||||
this.Type = originalType;
|
||||
if (size != 0)
|
||||
this.Size = originalSize;
|
||||
if (xmlSchema != null)
|
||||
this.XmlSchema = originalXMLSchema;
|
||||
return sql;
|
||||
}
|
||||
/// <summary>
|
||||
/// Devuelve el schema de la columna en formato SQL.
|
||||
/// </summary>
|
||||
public string ToSql(Boolean sqlConstraint)
|
||||
{
|
||||
string sql = "";
|
||||
sql += "[" + Name + "] ";
|
||||
if (!IsComputed)
|
||||
{
|
||||
if (this.IsUserDefinedType)
|
||||
sql += Type;
|
||||
else
|
||||
sql += "[" + Type + "]";
|
||||
if (Type.Equals("binary") || Type.Equals("varbinary") || Type.Equals("varchar") || Type.Equals("char") || Type.Equals("nchar") || Type.Equals("nvarchar"))
|
||||
{
|
||||
if (Size == -1)
|
||||
sql += " (max)";
|
||||
else
|
||||
{
|
||||
if (Type.Equals("nchar") || Type.Equals("nvarchar"))
|
||||
sql += " (" + (Size / 2).ToString(CultureInfo.InvariantCulture) + ")";
|
||||
else
|
||||
sql += " (" + Size.ToString(CultureInfo.InvariantCulture) + ")";
|
||||
}
|
||||
}
|
||||
if (Type.Equals("xml"))
|
||||
{
|
||||
if (!String.IsNullOrEmpty(XmlSchema))
|
||||
{
|
||||
if (IsXmlDocument)
|
||||
sql += "(DOCUMENT " + XmlSchema + ")";
|
||||
else
|
||||
sql += "(CONTENT " + XmlSchema + ")";
|
||||
}
|
||||
}
|
||||
if (Type.Equals("numeric") || Type.Equals("decimal")) sql += " (" + Precision.ToString(CultureInfo.InvariantCulture) + "," + Scale.ToString(CultureInfo.InvariantCulture) + ")";
|
||||
if (((Database)Parent.Parent).Info.Version >= DatabaseInfo.SQLServerVersion.SQLServer2008)
|
||||
{
|
||||
if (Type.Equals("datetime2") || Type.Equals("datetimeoffset") || Type.Equals("time")) sql += "(" + Scale.ToString(CultureInfo.InvariantCulture) + ")";
|
||||
}
|
||||
if ((!String.IsNullOrEmpty(Collation)) && (!IsUserDefinedType)) sql += " COLLATE " + Collation;
|
||||
if (IsIdentity) sql += " IDENTITY (" + IdentitySeed.ToString(CultureInfo.InvariantCulture) + "," + IdentityIncrement.ToString(CultureInfo.InvariantCulture) + ")";
|
||||
if (IsIdentityForReplication) sql += " NOT FOR REPLICATION";
|
||||
if (IsSparse) sql += " SPARSE";
|
||||
if (IsFileStream) sql += " FILESTREAM";
|
||||
if (IsNullable)
|
||||
sql += " NULL";
|
||||
else
|
||||
sql += " NOT NULL";
|
||||
if (IsRowGuid) sql += " ROWGUIDCOL";
|
||||
}
|
||||
else
|
||||
{
|
||||
sql += "AS " + ComputedFormula;
|
||||
if (IsPersisted) sql += " PERSISTED";
|
||||
}
|
||||
if ((sqlConstraint) && (DefaultConstraint != null))
|
||||
{
|
||||
if (DefaultConstraint.Status != ObjectStatus.Drop)
|
||||
sql += " " + DefaultConstraint.ToSql().Replace("\t", "").Trim();
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
public SQLScriptList RebuildDependencies()
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
list.AddRange(RebuildConstraint());
|
||||
list.AddRange(RebuildIndex());
|
||||
list.AddRange(RebuildFullTextIndex());
|
||||
return list;
|
||||
}
|
||||
|
||||
private SQLScriptList RebuildFullTextIndex()
|
||||
{
|
||||
return RebuildFullTextIndex(null);
|
||||
}
|
||||
|
||||
private SQLScriptList RebuildFullTextIndex(string index)
|
||||
{
|
||||
bool it;
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
((Table)Parent).FullTextIndex.ForEach(item =>
|
||||
{
|
||||
if (index == null)
|
||||
it = item.Columns.Exists(col => { return col.ColumnName.Equals(this.Name); });
|
||||
else
|
||||
it = item.Index.Equals(index);
|
||||
if (it)
|
||||
{
|
||||
if (item.Status != ObjectStatus.Create) list.Add(item.Drop());
|
||||
if (item.Status != ObjectStatus.Drop) list.Add(item.Create());
|
||||
}
|
||||
}
|
||||
);
|
||||
return list;
|
||||
}
|
||||
|
||||
private SQLScriptList RebuildConstraint()
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
((Table)Parent).Constraints.ForEach(item =>
|
||||
{
|
||||
ConstraintColumn ic = item.Columns.Find(this.Id);
|
||||
if (ic != null)
|
||||
{
|
||||
if (item.Status != ObjectStatus.Create) list.Add(item.Drop());
|
||||
if (item.Status != ObjectStatus.Drop) list.Add(item.Create());
|
||||
list.AddRange(RebuildFullTextIndex(item.Name));
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
private SQLScriptList RebuildIndex()
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (HasIndexDependencies)
|
||||
{
|
||||
((Table)Parent).Indexes.ForEach(item =>
|
||||
{
|
||||
IndexColumn ic = item.Columns.Find(this.Id);
|
||||
if (ic != null)
|
||||
{
|
||||
if (item.Status != ObjectStatus.Create) list.Add(item.Drop());
|
||||
if (item.Status != ObjectStatus.Drop) list.Add(item.Create());
|
||||
list.AddRange(RebuildFullTextIndex(item.Name));
|
||||
}
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public SQLScriptList RebuildConstraint(Boolean Check)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (DefaultConstraint != null)
|
||||
{
|
||||
if ((!Check) || (DefaultConstraint.CanCreate)) list.Add(DefaultConstraint.Create());
|
||||
list.Add(DefaultConstraint.Drop());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public SQLScriptList RebuildSchemaBindingDependencies()
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
List<ISchemaBase> items = ((Database)this.Parent.Parent).Dependencies.Find(this.Parent.Id, this.Id, 0);
|
||||
items.ForEach(item =>
|
||||
{
|
||||
if ((item.ObjectType == ObjectType.Function) || (item.ObjectType == ObjectType.View))
|
||||
{
|
||||
if (item.Status != ObjectStatus.Create)
|
||||
list.Add(item.Drop());
|
||||
if (item.Status != ObjectStatus.Drop)
|
||||
list.Add(item.Create());
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public SQLScriptList Alter(ScriptAction typeStatus)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
string sql = "ALTER TABLE " + Parent.FullName + " ALTER COLUMN " + this.ToSql(false) + "\r\nGO\r\n";
|
||||
list.Add(sql, 0, typeStatus);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara solo las propiedades de dos campos relacionadas con los Identity. Si existen
|
||||
/// diferencias, devuelve falso, caso contrario, true.
|
||||
/// </summary>
|
||||
public static Boolean CompareIdentity(Column origin, Column destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.IsIdentity != destination.IsIdentity) return false;
|
||||
if (origin.IsIdentityForReplication != destination.IsIdentityForReplication) return false;
|
||||
if (origin.IdentityIncrement != destination.IdentityIncrement) return false;
|
||||
if (origin.IdentitySeed != destination.IdentitySeed) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Boolean CompareRule(Column origin, Column destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if ((origin.Rule.Name != null) && (destination.Rule.Name == null)) return false;
|
||||
if ((origin.Rule.Name == null) && (destination.Rule.Name != null)) return false;
|
||||
if (origin.Rule.Name != null)
|
||||
if (!origin.Rule.Name.Equals(destination.Rule.Name)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara dos campos y devuelve true si son iguales, caso contrario, devuelve false.
|
||||
/// </summary>
|
||||
public static Boolean Compare(Column origin, Column destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (!origin.ComputedFormula.Equals(destination.ComputedFormula)) return false;
|
||||
if (origin.IsComputed != destination.IsComputed) return false;
|
||||
//if (origin.Position != destination.Position) return false;
|
||||
if (!origin.IsComputed)
|
||||
{
|
||||
if (origin.IsXmlDocument != destination.IsXmlDocument) return false;
|
||||
if ((origin.XmlSchema == null) && (destination.XmlSchema != null)) return false;
|
||||
if (origin.XmlSchema != null)
|
||||
if (!origin.XmlSchema.Equals(destination.XmlSchema)) return false;
|
||||
if (origin.IsNullable != destination.IsNullable) return false;
|
||||
if (origin.IsFileStream != destination.IsFileStream) return false;
|
||||
if (origin.IsSparse != destination.IsSparse) return false;
|
||||
if (!origin.Collation.Equals(destination.Collation)) return false;
|
||||
if (!origin.Type.Equals(destination.Type, StringComparison.CurrentCultureIgnoreCase)) return false;
|
||||
//Si el tipo de campo es custom, no compara size del campo.
|
||||
if (!origin.IsUserDefinedType)
|
||||
{
|
||||
if (origin.Precision != destination.Precision) return false;
|
||||
if (origin.Scale != destination.Scale) return false;
|
||||
//Si el tamaño de un campo Text cambia, entonces por la opcion TextInRowLimit.
|
||||
if ((origin.Size != destination.Size) && (origin.Type.Equals(destination.Type, StringComparison.CurrentCultureIgnoreCase)) && (!origin.Type.Equals("text", StringComparison.CurrentCultureIgnoreCase))) return false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (origin.IsPersisted != destination.IsPersisted) return false;
|
||||
}
|
||||
if (!CompareIdentity(origin, destination)) return false;
|
||||
return CompareRule(origin, destination);
|
||||
}
|
||||
|
||||
public int CompareTo(Column other)
|
||||
{
|
||||
return this.Id.CompareTo(other.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
171
OpenDBDiff.Schema.SQLServer.Generates/Model/ColumnConstraint.cs
Normal file
171
OpenDBDiff.Schema.SQLServer.Generates/Model/ColumnConstraint.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// Clase de constraints de Columnas (Default Constraint y Check Constraint)
|
||||
/// </summary>
|
||||
public class ColumnConstraint : SQLServerSchemaBase
|
||||
{
|
||||
public ColumnConstraint(Column parent)
|
||||
: base(parent, ObjectType.Constraint)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clona el objeto ColumnConstraint en una nueva instancia.
|
||||
/// </summary>
|
||||
public ColumnConstraint Clone(Column parent)
|
||||
{
|
||||
ColumnConstraint ccons = new ColumnConstraint(parent);
|
||||
ccons.Name = this.Name;
|
||||
ccons.Type = this.Type;
|
||||
ccons.Definition = this.Definition;
|
||||
ccons.Status = this.Status;
|
||||
ccons.Disabled = this.Disabled;
|
||||
ccons.Owner = this.Owner;
|
||||
return ccons;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indica si la constraint esta deshabilitada.
|
||||
/// </summary>
|
||||
public Boolean Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indica si la constraint va a ser usada en replicacion.
|
||||
/// </summary>
|
||||
public Boolean NotForReplication { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [with no check].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [with no check]; otherwise, <c>false</c>.</value>
|
||||
public Boolean WithNoCheck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valor de la constraint.
|
||||
/// </summary>
|
||||
public string Definition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indica el tipo de constraint (Default o Check constraint).
|
||||
/// </summary>
|
||||
public Constraint.ConstraintType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Convierte el schema de la constraint en XML.
|
||||
/// </summary>
|
||||
public string ToXML()
|
||||
{
|
||||
string xml = "";
|
||||
if (this.Type == Constraint.ConstraintType.Default)
|
||||
{
|
||||
xml += "<COLUMNCONSTRAINT name=\"" + Name + "\" type=\"DF\" value=\"" + Definition + "\"/>\n";
|
||||
}
|
||||
if (this.Type == Constraint.ConstraintType.Check)
|
||||
{
|
||||
xml += "<COLUMNCONSTRAINT name=\"" + Name + "\" type=\"C\" value=\"" + Definition + "\" notForReplication=\"" + (NotForReplication ? "1" : "0") + "\"/>\n";
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara dos campos y devuelve true si son iguales, caso contrario, devuelve false.
|
||||
/// </summary>
|
||||
public static Boolean Compare(ColumnConstraint origin, ColumnConstraint destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.NotForReplication != destination.NotForReplication) return false;
|
||||
if (origin.Disabled != destination.Disabled) return false;
|
||||
if ((!origin.Definition.Equals(destination.Definition)) && (!origin.Definition.Equals("(" + destination.Definition + ")"))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override SQLScript Create()
|
||||
{
|
||||
ScriptAction action = ScriptAction.AddConstraint;
|
||||
if (!GetWasInsertInDiffList(action))
|
||||
{
|
||||
SetWasInsertInDiffList(action);
|
||||
return new SQLScript(this.ToSqlAdd(), 0, action);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public override SQLScript Drop()
|
||||
{
|
||||
ScriptAction action = ScriptAction.DropConstraint;
|
||||
if (!GetWasInsertInDiffList(action))
|
||||
{
|
||||
SetWasInsertInDiffList(action);
|
||||
return new SQLScript(this.ToSqlDrop(), 0, action);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public Boolean CanCreate
|
||||
{
|
||||
get
|
||||
{
|
||||
ObjectStatus tableStatus = this.Parent.Parent.Status;
|
||||
ObjectStatus columnStatus = this.Parent.Status;
|
||||
return ((columnStatus != ObjectStatus.Drop) && (((tableStatus == ObjectStatus.Alter) || (tableStatus == ObjectStatus.Original) || (tableStatus == ObjectStatus.RebuildDependencies)) && (this.Status == ObjectStatus.Original)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve el schema de la constraint en formato SQL.
|
||||
/// </summary>
|
||||
public override string ToSql()
|
||||
{
|
||||
string sql = "";
|
||||
if (this.Type == Constraint.ConstraintType.Default)
|
||||
sql = " CONSTRAINT [" + Name + "] DEFAULT " + Definition;
|
||||
return sql;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toes the SQL add.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
if (this.Type == Constraint.ConstraintType.Default)
|
||||
return "ALTER TABLE " + ((Table)Parent.Parent).FullName + " ADD" + ToSql() + " FOR [" + Parent.Name + "]\r\nGO\r\n";
|
||||
if (this.Type == Constraint.ConstraintType.Check)
|
||||
return "ALTER TABLE " + ((Table)Parent.Parent).FullName + " ADD" + ToSql() + "\r\nGO\r\n";
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toes the SQL drop.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "ALTER TABLE " + ((Table)Parent.Parent).FullName + " DROP CONSTRAINT [" + Name + "]\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<OpenDBDiff.Schema.Model.ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (this.HasState(ObjectStatus.Drop))
|
||||
list.Add(Drop());
|
||||
if (this.HasState(ObjectStatus.Create))
|
||||
list.Add(Create());
|
||||
|
||||
if (this.Status == ObjectStatus.Alter)
|
||||
{
|
||||
list.Add(Drop());
|
||||
list.Add(Create());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
114
OpenDBDiff.Schema.SQLServer.Generates/Model/Columns.cs
Normal file
114
OpenDBDiff.Schema.SQLServer.Generates/Model/Columns.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class Columns<T> : SchemaList<Column, T> where T : ISchemaBase
|
||||
{
|
||||
public Columns(T parent) : base(parent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clona el objeto Columns en una nueva instancia.
|
||||
/// </summary>
|
||||
public new Columns<T> Clone(T parentObject)
|
||||
{
|
||||
Columns<T> columns = new Columns<T>(parentObject);
|
||||
for (int index = 0; index < this.Count; index++)
|
||||
{
|
||||
columns.Add(this[index].Clone(parentObject));
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
return string.Join
|
||||
(
|
||||
",\r\n",
|
||||
this
|
||||
.Where(c => !c.HasState(ObjectStatus.Drop))
|
||||
.Select(c => "\t" + c.ToSql(true))
|
||||
);
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
string sqlDrop = "";
|
||||
string sqlAdd = "";
|
||||
string sqlCons = "";
|
||||
string sqlBinds = "";
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (Parent.Status != ObjectStatus.Rebuild)
|
||||
{
|
||||
this.ForEach(item =>
|
||||
{
|
||||
bool isIncluded = schemas.Count == 0;
|
||||
if (!isIncluded)
|
||||
{
|
||||
foreach (var selectedSchema in schemas)
|
||||
{
|
||||
if (selectedSchema.Id == item.Id)
|
||||
{
|
||||
isIncluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isIncluded)
|
||||
{
|
||||
if (item.HasState(ObjectStatus.Drop))
|
||||
{
|
||||
if (item.DefaultConstraint != null)
|
||||
list.Add(item.DefaultConstraint.Drop());
|
||||
/*Si la columna formula debe ser eliminada y ya fue efectuada la operacion en otro momento, no
|
||||
* se borra nuevamente*/
|
||||
if (!item.GetWasInsertInDiffList(ScriptAction.AlterColumnFormula))
|
||||
sqlDrop += "[" + item.Name + "],";
|
||||
}
|
||||
if (item.HasState(ObjectStatus.Create))
|
||||
sqlAdd += "\r\n" + item.ToSql(true) + ",";
|
||||
if ((item.HasState(ObjectStatus.Alter) || (item.HasState(ObjectStatus.RebuildDependencies))))
|
||||
{
|
||||
if ((!item.Parent.HasState(ObjectStatus.RebuildDependencies) || (!item.Parent.HasState(ObjectStatus.Rebuild))))
|
||||
list.AddRange(item.RebuildSchemaBindingDependencies());
|
||||
list.AddRange(item.RebuildConstraint(false));
|
||||
list.AddRange(item.RebuildDependencies());
|
||||
list.AddRange(item.Alter(ScriptAction.AlterTable));
|
||||
}
|
||||
if (item.HasState(ObjectStatus.Update))
|
||||
list.Add("UPDATE " + Parent.FullName + " SET [" + item.Name + "] = " + item.DefaultForceValue + " WHERE [" + item.Name + "] IS NULL\r\nGO\r\n", 0, ScriptAction.UpdateTable);
|
||||
if (item.HasState(ObjectStatus.Bind))
|
||||
{
|
||||
if (item.Rule.Id != 0)
|
||||
sqlBinds += item.Rule.ToSQLAddBind();
|
||||
if (item.Rule.Id == 0)
|
||||
sqlBinds += item.Rule.ToSQLAddUnBind();
|
||||
}
|
||||
if (item.DefaultConstraint != null)
|
||||
list.AddRange(item.DefaultConstraint.ToSqlDiff(schemas));
|
||||
}
|
||||
});
|
||||
if (!String.IsNullOrEmpty(sqlDrop))
|
||||
sqlDrop = "ALTER TABLE " + Parent.FullName + " DROP COLUMN " + sqlDrop.Substring(0, sqlDrop.Length - 1) + "\r\nGO\r\n";
|
||||
if (!String.IsNullOrEmpty(sqlAdd))
|
||||
sqlAdd = "ALTER TABLE " + Parent.FullName + " ADD " + sqlAdd.Substring(0, sqlAdd.Length - 1) + "\r\nGO\r\n";
|
||||
|
||||
if (!String.IsNullOrEmpty(sqlDrop + sqlAdd + sqlCons + sqlBinds))
|
||||
list.Add(sqlDrop + sqlAdd + sqlBinds, 0, ScriptAction.AlterTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ForEach(item =>
|
||||
{
|
||||
if (item.Status != ObjectStatus.Original)
|
||||
item.RootParent.ActionMessage[item.Parent.FullName].Add(item);
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
359
OpenDBDiff.Schema.SQLServer.Generates/Model/Constraint.cs
Normal file
359
OpenDBDiff.Schema.SQLServer.Generates/Model/Constraint.cs
Normal file
@@ -0,0 +1,359 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class Constraint : SQLServerSchemaBase
|
||||
{
|
||||
public enum ConstraintType
|
||||
{
|
||||
None = 0,
|
||||
PrimaryKey = 1,
|
||||
ForeignKey = 2,
|
||||
Default = 3,
|
||||
Unique = 4,
|
||||
Check = 5
|
||||
}
|
||||
|
||||
public Constraint(ISchemaBase parent)
|
||||
: base(parent, ObjectType.Constraint)
|
||||
{
|
||||
this.Columns = new ConstraintColumns(this);
|
||||
this.Index = new Index(parent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clona el objeto Column en una nueva instancia.
|
||||
/// </summary>
|
||||
public override ISchemaBase Clone(ISchemaBase parent)
|
||||
{
|
||||
Constraint col = new Constraint(parent);
|
||||
col.Id = this.Id;
|
||||
col.Name = this.Name;
|
||||
col.NotForReplication = this.NotForReplication;
|
||||
col.RelationalTableFullName = this.RelationalTableFullName;
|
||||
col.Status = this.Status;
|
||||
col.Type = this.Type;
|
||||
col.WithNoCheck = this.WithNoCheck;
|
||||
col.OnDeleteCascade = this.OnDeleteCascade;
|
||||
col.OnUpdateCascade = this.OnUpdateCascade;
|
||||
col.Owner = this.Owner;
|
||||
col.Columns = this.Columns.Clone();
|
||||
col.Index = (Index)this.Index.Clone(parent);
|
||||
col.IsDisabled = this.IsDisabled;
|
||||
col.Definition = this.Definition;
|
||||
col.Guid = this.Guid;
|
||||
return col;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Informacion sobre le indice asociado al Constraint.
|
||||
/// </summary>
|
||||
public Index Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Coleccion de columnas de la constraint.
|
||||
/// </summary>
|
||||
public ConstraintColumns Columns { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indica si la constraint tiene asociada un indice Clustered.
|
||||
/// </summary>
|
||||
public Boolean HasClusteredIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Index != null)
|
||||
return (Index.Type == Index.IndexTypeEnum.Clustered);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this constraint is disabled.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this constraint is disabled; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean IsDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the on delete cascade (only for FK).
|
||||
/// </summary>
|
||||
/// <value>The on delete cascade.</value>
|
||||
public int OnDeleteCascade { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the on update cascade (only for FK).
|
||||
/// </summary>
|
||||
/// <value>The on update cascade.</value>
|
||||
public int OnUpdateCascade { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Valor de la constraint (se usa para los Check Constraint).
|
||||
/// </summary>
|
||||
public string Definition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indica si la constraint va a ser usada en replicacion.
|
||||
/// </summary>
|
||||
public Boolean NotForReplication { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [with no check].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [with no check]; otherwise, <c>false</c>.</value>
|
||||
public Boolean WithNoCheck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indica el tipo de constraint (PrimaryKey, ForeignKey, Unique o Default).
|
||||
/// </summary>
|
||||
public ConstraintType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID de la tabla relacionada a la que hace referencia (solo aplica a FK)
|
||||
/// </summary>
|
||||
public int RelationalTableId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nombre de la tabla relacionada a la que hace referencia (solo aplica a FK)
|
||||
/// </summary>
|
||||
public string RelationalTableFullName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Compara dos campos y devuelve true si son iguales, caso contrario, devuelve false.
|
||||
/// </summary>
|
||||
public static Boolean Compare(Constraint origin, Constraint destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.NotForReplication != destination.NotForReplication) return false;
|
||||
if ((origin.RelationalTableFullName == null) && (destination.RelationalTableFullName != null)) return false;
|
||||
if (origin.RelationalTableFullName != null)
|
||||
if (!origin.RelationalTableFullName.Equals(destination.RelationalTableFullName, StringComparison.CurrentCultureIgnoreCase)) return false;
|
||||
if ((origin.Definition == null) && (destination.Definition != null)) return false;
|
||||
if (origin.Definition != null)
|
||||
if ((!origin.Definition.Equals(destination.Definition)) && (!origin.Definition.Equals("(" + destination.Definition + ")"))) return false;
|
||||
/*Solo si la constraint esta habilitada, se chequea el is_trusted*/
|
||||
if (!destination.IsDisabled)
|
||||
if (origin.WithNoCheck != destination.WithNoCheck) return false;
|
||||
if (origin.OnUpdateCascade != destination.OnUpdateCascade) return false;
|
||||
if (origin.OnDeleteCascade != destination.OnDeleteCascade) return false;
|
||||
if (!ConstraintColumns.Compare(origin.Columns, destination.Columns)) return false;
|
||||
if ((origin.Index != null) && (destination.Index != null))
|
||||
return Index.Compare(origin.Index, destination.Index);
|
||||
return true;
|
||||
}
|
||||
|
||||
private string ToSQLGeneric(ConstraintType consType)
|
||||
{
|
||||
Database database = null;
|
||||
ISchemaBase current = this;
|
||||
while (database == null && current.Parent != null)
|
||||
{
|
||||
database = current.Parent as Database;
|
||||
current = current.Parent;
|
||||
}
|
||||
var isAzure10 = database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10;
|
||||
string typeConstraint = "";
|
||||
StringBuilder sql = new StringBuilder();
|
||||
if (Index.Type == Index.IndexTypeEnum.Clustered) typeConstraint = "CLUSTERED";
|
||||
if (Index.Type == Index.IndexTypeEnum.Nonclustered) typeConstraint = "NONCLUSTERED";
|
||||
if (Index.Type == Index.IndexTypeEnum.XML) typeConstraint = "XML";
|
||||
if (Index.Type == Index.IndexTypeEnum.Heap) typeConstraint = "HEAP";
|
||||
if (Parent.ObjectType != ObjectType.TableType)
|
||||
sql.Append("CONSTRAINT [" + Name + "] ");
|
||||
else
|
||||
sql.Append("\t");
|
||||
if (consType == ConstraintType.PrimaryKey)
|
||||
sql.Append("PRIMARY KEY " + typeConstraint + "\r\n\t(\r\n");
|
||||
else
|
||||
sql.Append("UNIQUE " + typeConstraint + "\r\n\t(\r\n");
|
||||
|
||||
this.Columns.Sort();
|
||||
|
||||
for (int j = 0; j < this.Columns.Count; j++)
|
||||
{
|
||||
sql.Append("\t\t[" + this.Columns[j].Name + "]");
|
||||
if (this.Columns[j].Order) sql.Append(" DESC"); else sql.Append(" ASC");
|
||||
if (j != this.Columns.Count - 1) sql.Append(",");
|
||||
sql.Append("\r\n");
|
||||
}
|
||||
sql.Append("\t)");
|
||||
sql.Append(" WITH (");
|
||||
if (Parent.ObjectType == ObjectType.TableType)
|
||||
if (Index.IgnoreDupKey) sql.Append("IGNORE_DUP_KEY = ON"); else sql.Append("IGNORE_DUP_KEY = OFF");
|
||||
else
|
||||
{
|
||||
if (!isAzure10)
|
||||
{
|
||||
if (Index.IsPadded) sql.Append("PAD_INDEX = ON, "); else sql.Append("PAD_INDEX = OFF, ");
|
||||
}
|
||||
if (Index.IsAutoStatistics) sql.Append("STATISTICS_NORECOMPUTE = ON"); else sql.Append("STATISTICS_NORECOMPUTE = OFF");
|
||||
if (Index.IgnoreDupKey) sql.Append(", IGNORE_DUP_KEY = ON"); else sql.Append(", IGNORE_DUP_KEY = OFF");
|
||||
if (!isAzure10)
|
||||
{
|
||||
if (Index.AllowRowLocks) sql.Append(", ALLOW_ROW_LOCKS = ON"); else sql.Append(", ALLOW_ROW_LOCKS = OFF");
|
||||
if (Index.AllowPageLocks) sql.Append(", ALLOW_PAGE_LOCKS = ON"); else sql.Append(", ALLOW_PAGE_LOCKS = OFF");
|
||||
if (Index.FillFactor != 0) sql.Append(", FILLFACTOR = " + Index.FillFactor.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
sql.Append(")");
|
||||
if (!isAzure10)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Index.FileGroup)) sql.Append(" ON [" + Index.FileGroup + "]");
|
||||
}
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve el schema de la tabla en formato SQL.
|
||||
/// </summary>
|
||||
public override string ToSql()
|
||||
{
|
||||
if (this.Type == ConstraintType.PrimaryKey)
|
||||
{
|
||||
return ToSQLGeneric(ConstraintType.PrimaryKey);
|
||||
}
|
||||
if (this.Type == ConstraintType.ForeignKey)
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
StringBuilder sqlReference = new StringBuilder();
|
||||
int indexc = 0;
|
||||
|
||||
this.Columns.Sort();
|
||||
sql.Append("CONSTRAINT [" + Name + "] FOREIGN KEY\r\n\t(\r\n");
|
||||
foreach (ConstraintColumn column in this.Columns)
|
||||
{
|
||||
sql.Append("\t\t[" + column.Name + "]");
|
||||
sqlReference.Append("\t\t[" + column.ColumnRelationalName + "]");
|
||||
if (indexc != this.Columns.Count - 1)
|
||||
{
|
||||
sql.Append(",");
|
||||
sqlReference.Append(",");
|
||||
}
|
||||
sql.Append("\r\n");
|
||||
sqlReference.Append("\r\n");
|
||||
indexc++;
|
||||
}
|
||||
sql.Append("\t)\r\n");
|
||||
sql.Append("\tREFERENCES " + this.RelationalTableFullName + "\r\n\t(\r\n");
|
||||
sql.Append(sqlReference + "\t)");
|
||||
if (OnUpdateCascade == 1) sql.Append(" ON UPDATE CASCADE");
|
||||
if (OnDeleteCascade == 1) sql.Append(" ON DELETE CASCADE");
|
||||
if (OnUpdateCascade == 2) sql.Append(" ON UPDATE SET NULL");
|
||||
if (OnDeleteCascade == 2) sql.Append(" ON DELETE SET NULL");
|
||||
if (OnUpdateCascade == 3) sql.Append(" ON UPDATE SET DEFAULT");
|
||||
if (OnDeleteCascade == 3) sql.Append(" ON DELETE SET DEFAULT");
|
||||
sql.Append((NotForReplication ? " NOT FOR REPLICATION" : ""));
|
||||
return sql.ToString();
|
||||
}
|
||||
if (this.Type == ConstraintType.Unique)
|
||||
{
|
||||
return ToSQLGeneric(ConstraintType.Unique);
|
||||
}
|
||||
if (this.Type == ConstraintType.Check)
|
||||
{
|
||||
string sqlcheck = "";
|
||||
if (Parent.ObjectType != ObjectType.TableType)
|
||||
sqlcheck = "CONSTRAINT [" + Name + "] ";
|
||||
|
||||
return sqlcheck + "CHECK " + (NotForReplication ? "NOT FOR REPLICATION" : "") + " (" + Definition + ")";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return "ALTER TABLE " + Parent.FullName + (WithNoCheck ? " WITH NOCHECK" : "") + " ADD " + ToSql() + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return ToSqlDrop(null);
|
||||
}
|
||||
|
||||
public override SQLScript Create()
|
||||
{
|
||||
ScriptAction action = ScriptAction.AddConstraint;
|
||||
if (this.Type == ConstraintType.ForeignKey)
|
||||
action = ScriptAction.AddConstraintFK;
|
||||
if (this.Type == ConstraintType.PrimaryKey)
|
||||
action = ScriptAction.AddConstraintPK;
|
||||
if (!GetWasInsertInDiffList(action))
|
||||
{
|
||||
SetWasInsertInDiffList(action);
|
||||
return new SQLScript(this.ToSqlAdd(), ((Table)Parent).DependenciesCount, action);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public override SQLScript Drop()
|
||||
{
|
||||
ScriptAction action = ScriptAction.DropConstraint;
|
||||
if (this.Type == ConstraintType.ForeignKey)
|
||||
action = ScriptAction.DropConstraintFK;
|
||||
if (this.Type == ConstraintType.PrimaryKey)
|
||||
action = ScriptAction.DropConstraintPK;
|
||||
if (!GetWasInsertInDiffList(action))
|
||||
{
|
||||
SetWasInsertInDiffList(action);
|
||||
return new SQLScript(this.ToSqlDrop(), ((Table)Parent).DependenciesCount, action);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public string ToSqlDrop(string FileGroupName)
|
||||
{
|
||||
string sql = "ALTER TABLE " + ((Table)Parent).FullName + " DROP CONSTRAINT [" + Name + "]";
|
||||
if (!String.IsNullOrEmpty(FileGroupName)) sql += " WITH (MOVE TO [" + FileGroupName + "])";
|
||||
sql += "\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public string ToSQLEnabledDisabled()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
if (this.IsDisabled)
|
||||
return "ALTER TABLE " + Parent.FullName + " NOCHECK CONSTRAINT [" + Name + "]\r\nGO\r\n";
|
||||
else
|
||||
{
|
||||
return "ALTER TABLE " + Parent.FullName + " CHECK CONSTRAINT [" + Name + "]\r\nGO\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (this.Status != ObjectStatus.Original)
|
||||
RootParent.ActionMessage[Parent.FullName].Add(this);
|
||||
|
||||
if (this.HasState(ObjectStatus.Drop))
|
||||
{
|
||||
if (this.Parent.Status != ObjectStatus.Rebuild)
|
||||
list.Add(Drop());
|
||||
}
|
||||
if (this.HasState(ObjectStatus.Create))
|
||||
list.Add(Create());
|
||||
if (this.HasState(ObjectStatus.Alter))
|
||||
{
|
||||
list.Add(Drop());
|
||||
list.Add(Create());
|
||||
}
|
||||
if (this.HasState(ObjectStatus.Disabled))
|
||||
{
|
||||
list.Add(this.ToSQLEnabledDisabled(), ((Table)Parent).DependenciesCount, ScriptAction.AlterConstraint);
|
||||
}
|
||||
/*if (this.Status == StatusEnum.ObjectStatusType.ChangeFileGroup)
|
||||
{
|
||||
list.Add(this.ToSQLDrop(this.Index.FileGroup), ((Table)Parent).DependenciesCount, actionDrop);
|
||||
list.Add(this.ToSQLAdd(), ((Table)Parent).DependenciesCount, actionAdd);
|
||||
}*/
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class ConstraintColumn : SQLServerSchemaBase, IComparable<ConstraintColumn>
|
||||
{
|
||||
public ConstraintColumn(Constraint parentObject)
|
||||
: base(parentObject, ObjectType.ConstraintColumn)
|
||||
{
|
||||
}
|
||||
|
||||
public ConstraintColumn Clone()
|
||||
{
|
||||
ConstraintColumn ccol = new ConstraintColumn((Constraint)this.Parent);
|
||||
ccol.ColumnRelationalName = this.ColumnRelationalName;
|
||||
ccol.ColumnRelationalId = this.ColumnRelationalId;
|
||||
ccol.Name = this.Name;
|
||||
ccol.IsIncluded = this.IsIncluded;
|
||||
ccol.Order = this.Order;
|
||||
ccol.KeyOrder = this.KeyOrder;
|
||||
ccol.Id = this.Id;
|
||||
ccol.DataTypeId = this.DataTypeId;
|
||||
ccol.ColumnRelationalDataTypeId = this.ColumnRelationalDataTypeId;
|
||||
return ccol;
|
||||
}
|
||||
|
||||
public int DataTypeId { get; set; }
|
||||
|
||||
public int ColumnRelationalDataTypeId { get; set; }
|
||||
|
||||
public int ColumnRelationalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the column key order in the index.
|
||||
/// </summary>
|
||||
/// <value>The key order.</value>
|
||||
public int KeyOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this column is included in the index leaf page.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this column is included; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public Boolean IsIncluded { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Orden de la columna (Ascendente o Descendente). Se usa solo en Primary Keys.
|
||||
/// </summary>
|
||||
public Boolean Order { get; set; }
|
||||
|
||||
public string ColumnRelationalName { get; set; }
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public static Boolean Compare(ConstraintColumn origin, ConstraintColumn destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if ((origin.ColumnRelationalName == null) && (destination.ColumnRelationalName != null)) return false;
|
||||
if (origin.ColumnRelationalName != null)
|
||||
{
|
||||
if (!origin.ColumnRelationalName.Equals(destination.ColumnRelationalName, StringComparison.CurrentCultureIgnoreCase)) return false;
|
||||
}
|
||||
if (origin.IsIncluded != destination.IsIncluded) return false;
|
||||
if (origin.Order != destination.Order) return false;
|
||||
if (origin.KeyOrder != destination.KeyOrder) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int CompareTo(ConstraintColumn other)
|
||||
{
|
||||
return this.ColumnRelationalId.CompareTo(other.ColumnRelationalId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class ConstraintColumns : SchemaList<ConstraintColumn, Constraint>
|
||||
{
|
||||
public ConstraintColumns(Constraint parent)
|
||||
: base(parent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clona el objeto ColumnConstraints en una nueva instancia.
|
||||
/// </summary>
|
||||
public ConstraintColumns Clone()
|
||||
{
|
||||
ConstraintColumns columns = new ConstraintColumns(this.Parent);
|
||||
for (int index = 0; index < this.Count; index++)
|
||||
{
|
||||
columns.Add(this[index].Clone());
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara dos campos y devuelve true si son iguales, caso contrario, devuelve false.
|
||||
/// </summary>
|
||||
public static Boolean Compare(ConstraintColumns origin, ConstraintColumns destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.Count != destination.Count) return false;
|
||||
for (int j = 0; j < origin.Count; j++)
|
||||
{
|
||||
ConstraintColumn item = destination[origin[j].FullName];
|
||||
if (item == null)
|
||||
return false;
|
||||
else
|
||||
if (!ConstraintColumn.Compare(origin[j], item)) return false;
|
||||
}
|
||||
for (int j = 0; j < destination.Count; j++)
|
||||
{
|
||||
ConstraintColumn item = origin[destination[j].FullName];
|
||||
if (item == null)
|
||||
return false;
|
||||
else
|
||||
if (!ConstraintColumn.Compare(destination[j], item)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
446
OpenDBDiff.Schema.SQLServer.Generates/Model/Database.cs
Normal file
446
OpenDBDiff.Schema.SQLServer.Generates/Model/Database.cs
Normal file
@@ -0,0 +1,446 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using OpenDBDiff.Schema.Attributes;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Options;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class Database : SQLServerSchemaBase, IDatabase
|
||||
{
|
||||
private readonly List<DatabaseChangeStatus> _changesOptions;
|
||||
|
||||
public Database() : base(null, ObjectType.Database)
|
||||
{
|
||||
AllObjects = new SearchSchemaBase();
|
||||
_changesOptions = new List<DatabaseChangeStatus>();
|
||||
Dependencies = new Dependencies();
|
||||
TablesTypes = new SchemaList<TableType, Database>(this, AllObjects);
|
||||
UserTypes = new SchemaList<UserDataType, Database>(this, AllObjects);
|
||||
XmlSchemas = new SchemaList<XMLSchema, Database>(this, AllObjects);
|
||||
Schemas = new SchemaList<Schema, Database>(this, AllObjects);
|
||||
Procedures = new SchemaList<StoredProcedure, Database>(this, AllObjects);
|
||||
CLRProcedures = new SchemaList<CLRStoredProcedure, Database>(this, AllObjects);
|
||||
CLRFunctions = new SchemaList<CLRFunction, Database>(this, AllObjects);
|
||||
FileGroups = new SchemaList<FileGroup, Database>(this);
|
||||
Rules = new SchemaList<Rule, Database>(this, AllObjects);
|
||||
DDLTriggers = new SchemaList<Trigger, Database>(this, AllObjects);
|
||||
Synonyms = new SchemaList<Synonym, Database>(this, AllObjects);
|
||||
Assemblies = new SchemaList<Assembly, Database>(this, AllObjects);
|
||||
Views = new SchemaList<View, Database>(this, AllObjects);
|
||||
Users = new SchemaList<User, Database>(this, AllObjects);
|
||||
FullText = new SchemaList<FullText, Database>(this, AllObjects);
|
||||
Functions = new SchemaList<Function, Database>(this, AllObjects);
|
||||
PartitionFunctions = new SchemaList<PartitionFunction, Database>(this, AllObjects);
|
||||
PartitionSchemes = new SchemaList<PartitionScheme, Database>(this, AllObjects);
|
||||
Roles = new SchemaList<Role, Database>(this);
|
||||
Tables = new SchemaList<Table, Database>(this, AllObjects);
|
||||
Defaults = new SchemaList<Default, Database>(this, AllObjects);
|
||||
ActionMessage = new SqlAction(this);
|
||||
}
|
||||
|
||||
internal SearchSchemaBase AllObjects { get; private set; }
|
||||
|
||||
[SchemaNode("Full Text Catalog", "FullText")]
|
||||
public SchemaList<FullText, Database> FullText { get; private set; }
|
||||
|
||||
[SchemaNode("Table Type", "Table")]
|
||||
public SchemaList<TableType, Database> TablesTypes { get; private set; }
|
||||
|
||||
[SchemaNode("Partition Scheme", "PartitionScheme")]
|
||||
public SchemaList<PartitionScheme, Database> PartitionSchemes { get; private set; }
|
||||
|
||||
[SchemaNode("Partition Functions", "PartitionFunction")]
|
||||
public SchemaList<PartitionFunction, Database> PartitionFunctions { get; private set; }
|
||||
|
||||
[SchemaNode("Defaults")]
|
||||
public SchemaList<Default, Database> Defaults { get; private set; }
|
||||
|
||||
[SchemaNode("Roles", "Rol")]
|
||||
public SchemaList<Role, Database> Roles { get; private set; }
|
||||
|
||||
[SchemaNode("Functions", "Function", true)]
|
||||
public SchemaList<Function, Database> Functions { get; private set; }
|
||||
|
||||
[SchemaNode("Users", "User")]
|
||||
public SchemaList<User, Database> Users { get; private set; }
|
||||
|
||||
[SchemaNode("Views", "View", true)]
|
||||
public SchemaList<View, Database> Views { get; private set; }
|
||||
|
||||
[SchemaNode("Assemblies", "Assembly")]
|
||||
public SchemaList<Assembly, Database> Assemblies { get; private set; }
|
||||
|
||||
[SchemaNode("Synonyms", "Assembly")] // We don't have an icon for synonyms at the moment.
|
||||
public SchemaList<Synonym, Database> Synonyms { get; private set; }
|
||||
|
||||
[SchemaNode("DLL Triggers")]
|
||||
public SchemaList<Trigger, Database> DDLTriggers { get; private set; }
|
||||
|
||||
[SchemaNode("File Groups")]
|
||||
public SchemaList<FileGroup, Database> FileGroups { get; private set; }
|
||||
|
||||
[SchemaNode("Rules")]
|
||||
public SchemaList<Rule, Database> Rules { get; private set; }
|
||||
|
||||
[SchemaNode("Stored Procedures", "Procedure", true)]
|
||||
public SchemaList<StoredProcedure, Database> Procedures { get; private set; }
|
||||
|
||||
[SchemaNode("CLR Stored Procedures", "CLRProcedure", true)]
|
||||
public SchemaList<CLRStoredProcedure, Database> CLRProcedures { get; private set; }
|
||||
|
||||
[SchemaNode("CLR Functions", "CLRFunction", true)]
|
||||
public SchemaList<CLRFunction, Database> CLRFunctions { get; private set; }
|
||||
|
||||
[SchemaNode("Schemas", "Schema")]
|
||||
public SchemaList<Schema, Database> Schemas { get; private set; }
|
||||
|
||||
[SchemaNode("XML Schemas", "XMLSchema")]
|
||||
public SchemaList<XMLSchema, Database> XmlSchemas { get; private set; }
|
||||
|
||||
[SchemaNode("Tables", "Table", true)]
|
||||
public SchemaList<Table, Database> Tables { get; private set; }
|
||||
|
||||
[SchemaNode("User Types", "UDT")]
|
||||
public SchemaList<UserDataType, Database> UserTypes { get; private set; }
|
||||
|
||||
public SqlOption Options { get; set; }
|
||||
IOption IDatabase.Options { get { return Options; } }
|
||||
|
||||
public DatabaseInfo Info { get; set; }
|
||||
|
||||
public DatabaseInfo SourceInfo
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Coleccion de dependencias de constraints.
|
||||
/// </summary>
|
||||
internal Dependencies Dependencies { get; set; }
|
||||
|
||||
private List<DatabaseChangeStatus> ChangesOptions
|
||||
{
|
||||
get { return _changesOptions; }
|
||||
}
|
||||
|
||||
#region IDatabase Members
|
||||
|
||||
public override ISchemaBase Clone(ISchemaBase parent)
|
||||
{
|
||||
//Get a list of all of the objects that are SchemaLists, so that we can clone them all.
|
||||
var item = new Database() { AllObjects = this.AllObjects };
|
||||
|
||||
var explicitProperties = (from properties in this.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)
|
||||
where properties.PropertyType.GetInterface(typeof(ISchemaList<Code, Database>).Name) != null
|
||||
select properties).ToList();
|
||||
|
||||
foreach (var property in explicitProperties)
|
||||
{
|
||||
object value = property.GetValue(this, null);
|
||||
|
||||
//Clone the value
|
||||
value = value.GetType().GetMethod("Clone").Invoke(value, new object[] { this });
|
||||
|
||||
//Set the value to the cloned object
|
||||
property.SetValue(item, value, null);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public SqlAction ActionMessage { get; private set; }
|
||||
|
||||
public Boolean IsCaseSensitive
|
||||
{
|
||||
get
|
||||
{
|
||||
bool isCS = false;
|
||||
if (!String.IsNullOrEmpty(Info.Collation))
|
||||
isCS = Info.Collation.IndexOf("_CS_") != -1;
|
||||
|
||||
if (Options.Comparison.CaseSensityType == SqlOptionComparison.CaseSensityOptions.Automatic)
|
||||
return isCS;
|
||||
if (Options.Comparison.CaseSensityType == SqlOptionComparison.CaseSensityOptions.CaseSensity)
|
||||
return true;
|
||||
if (Options.Comparison.CaseSensityType == SqlOptionComparison.CaseSensityOptions.CaseInsensity)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
string sql = "";
|
||||
sql += FileGroups.ToSql();
|
||||
sql += Schemas.ToSql();
|
||||
sql += XmlSchemas.ToSql();
|
||||
sql += Rules.ToSql();
|
||||
sql += UserTypes.ToSql();
|
||||
sql += Assemblies.ToSql();
|
||||
sql += Tables.ToSql();
|
||||
sql += Functions.ToSql();
|
||||
sql += Procedures.ToSql();
|
||||
sql += CLRProcedures.ToSql();
|
||||
sql += CLRFunctions.ToSql();
|
||||
sql += DDLTriggers.ToSql();
|
||||
sql += Synonyms.ToSql();
|
||||
sql += Views.ToSql();
|
||||
sql += Users.ToSql();
|
||||
sql += PartitionFunctions.ToSql();
|
||||
sql += FullText.ToSql();
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
var isAzure10 = this.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10;
|
||||
|
||||
var listDiff = new SQLScriptList();
|
||||
|
||||
var header = $@"/*
|
||||
|
||||
OpenDBDiff {System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()}
|
||||
https://github.com/OpenDBDiff/OpenDBDiff
|
||||
|
||||
Script created by {Environment.UserDomainName}\{Environment.UserName} on {DateTime.Now.ToShortDateString()} at {DateTime.Now.ToLongTimeString()}.
|
||||
|
||||
Created on: {Environment.MachineName}
|
||||
Source: {SourceInfo?.Database ?? "Unknown"} on {SourceInfo?.Server ?? "Unknown"}
|
||||
Destination: {Info?.Database ?? "Unknown"} on {Info?.Server ?? "Unknown"}
|
||||
|
||||
### This script performs actions to change the Destination schema to the Source schema. ###
|
||||
|
||||
*/
|
||||
|
||||
";
|
||||
|
||||
listDiff.Add(new SQLScript(header, 0, ScriptAction.None));
|
||||
|
||||
if (!isAzure10)
|
||||
{
|
||||
listDiff.Add("USE [" + Name + "]\r\nGO\r\n\r\n", 0, ScriptAction.UseDatabase);
|
||||
listDiff.AddRange(Assemblies.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(UserTypes.ToSqlDiff(schemas));
|
||||
}
|
||||
listDiff.AddRange(TablesTypes.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Tables.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Rules.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Schemas.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(XmlSchemas.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Procedures.ToSqlDiff(schemas));
|
||||
if (!isAzure10)
|
||||
{
|
||||
listDiff.AddRange(CLRProcedures.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(CLRFunctions.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(FileGroups.ToSqlDiff(schemas));
|
||||
}
|
||||
listDiff.AddRange(DDLTriggers.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Synonyms.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Views.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Users.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Functions.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(Roles.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(PartitionFunctions.ToSqlDiff(schemas));
|
||||
listDiff.AddRange(PartitionSchemes.ToSqlDiff(schemas));
|
||||
if (!isAzure10)
|
||||
{
|
||||
listDiff.AddRange(FullText.ToSqlDiff(schemas));
|
||||
}
|
||||
return listDiff;
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public ISchemaBase Find(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
string full = AllObjects.GetFullName(id);
|
||||
return Find(full);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ISchemaBase Find(String _FullName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var typeVal = AllObjects.GetType(_FullName);
|
||||
if (!typeVal.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ObjectType type = typeVal.Value;
|
||||
|
||||
|
||||
string parentName = "";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ObjectType.Table:
|
||||
return Tables[_FullName];
|
||||
case ObjectType.StoredProcedure:
|
||||
return Procedures[_FullName];
|
||||
case ObjectType.Function:
|
||||
return Functions[_FullName];
|
||||
case ObjectType.View:
|
||||
return Views[_FullName];
|
||||
case ObjectType.Assembly:
|
||||
return Assemblies[_FullName];
|
||||
case ObjectType.UserDataType:
|
||||
return UserTypes[_FullName];
|
||||
case ObjectType.TableType:
|
||||
return TablesTypes[_FullName];
|
||||
case ObjectType.XMLSchema:
|
||||
return XmlSchemas[_FullName];
|
||||
case ObjectType.CLRStoredProcedure:
|
||||
return CLRProcedures[_FullName];
|
||||
case ObjectType.CLRFunction:
|
||||
return CLRFunctions[_FullName];
|
||||
case ObjectType.Synonym:
|
||||
return Synonyms[_FullName];
|
||||
case ObjectType.FullText:
|
||||
return FullText[_FullName];
|
||||
case ObjectType.Rule:
|
||||
return Rules[_FullName];
|
||||
case ObjectType.PartitionFunction:
|
||||
return PartitionFunctions[_FullName];
|
||||
case ObjectType.PartitionScheme:
|
||||
return PartitionSchemes[_FullName];
|
||||
case ObjectType.Role:
|
||||
return Roles[_FullName];
|
||||
case ObjectType.Schema:
|
||||
return Schemas[_FullName];
|
||||
case ObjectType.Constraint:
|
||||
parentName = AllObjects.GetParentName(_FullName);
|
||||
return Tables[parentName].Constraints[_FullName];
|
||||
case ObjectType.Index:
|
||||
parentName = AllObjects.GetParentName(_FullName);
|
||||
|
||||
var typeName = AllObjects.GetType(parentName);
|
||||
if (!typeName.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
type = typeName.Value;
|
||||
if (type == ObjectType.Table)
|
||||
return Tables[parentName].Indexes[_FullName];
|
||||
return Views[parentName].Indexes[_FullName];
|
||||
case ObjectType.Trigger:
|
||||
parentName = AllObjects.GetParentName(_FullName);
|
||||
var typeNameB = AllObjects.GetType(parentName);
|
||||
if (!typeNameB.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
type = typeNameB.Value;
|
||||
if (type == ObjectType.Table)
|
||||
return Tables[parentName].Triggers[_FullName];
|
||||
return Views[parentName].Triggers[_FullName];
|
||||
case ObjectType.CLRTrigger:
|
||||
parentName = AllObjects.GetParentName(_FullName);
|
||||
var typeNameC = AllObjects.GetType(parentName);
|
||||
if (!typeNameC.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
type = typeNameC.Value;
|
||||
if (type == ObjectType.Table)
|
||||
return Tables[parentName].CLRTriggers[_FullName];
|
||||
return Views[parentName].CLRTriggers[_FullName];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*private SQLScriptList CleanScripts(SQLScriptList listDiff)
|
||||
{
|
||||
SQLScriptList alters = listDiff.FindAlter();
|
||||
for (int j = 0; j < alters.Count; j++)
|
||||
{
|
||||
//alters[j].
|
||||
}
|
||||
return null;
|
||||
}*/
|
||||
|
||||
public void BuildDependency()
|
||||
{
|
||||
ISchemaBase schema;
|
||||
var indexes = new List<Index>();
|
||||
var constraints = new List<Constraint>();
|
||||
|
||||
Tables.ForEach(item => indexes.AddRange(item.Indexes));
|
||||
Views.ForEach(item => indexes.AddRange(item.Indexes));
|
||||
Tables.ForEach(item => constraints.AddRange(item.Constraints));
|
||||
|
||||
foreach (Index index in indexes)
|
||||
{
|
||||
schema = index.Parent;
|
||||
foreach (IndexColumn icolumn in index.Columns)
|
||||
{
|
||||
Dependencies.Add(this, schema.Id, icolumn.Id, schema.Id, icolumn.DataTypeId, index);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Constraint con in constraints)
|
||||
{
|
||||
schema = con.Parent;
|
||||
if (con.Type != Constraint.ConstraintType.Check)
|
||||
{
|
||||
foreach (ConstraintColumn ccolumn in con.Columns)
|
||||
{
|
||||
Dependencies.Add(this, schema.Id, ccolumn.Id, schema.Id, ccolumn.DataTypeId, con);
|
||||
if (con.Type == Constraint.ConstraintType.ForeignKey)
|
||||
{
|
||||
Dependencies.Add(this, con.RelationalTableId, ccolumn.ColumnRelationalId, schema.Id,
|
||||
ccolumn.ColumnRelationalDataTypeId, con);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (
|
||||
((Table)schema).FullTextIndex.Exists(
|
||||
item => { return item.Index.Equals(con.Name); }))
|
||||
{
|
||||
Dependencies.Add(this, schema.Id, 0, schema.Id, 0, con);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Dependencies.Add(this, schema.Id, 0, schema.Id, 0, con);
|
||||
}
|
||||
}
|
||||
|
||||
#region Nested type: DatabaseChangeStatus
|
||||
|
||||
private enum DatabaseChangeStatus
|
||||
{
|
||||
AlterChangeTracking = 1,
|
||||
AlterCollation = 2
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
94
OpenDBDiff.Schema.SQLServer.Generates/Model/DatabaseInfo.cs
Normal file
94
OpenDBDiff.Schema.SQLServer.Generates/Model/DatabaseInfo.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class DatabaseInfo
|
||||
{
|
||||
public enum SQLServerVersion
|
||||
{
|
||||
SQLServer2000,
|
||||
SQLServer2005,
|
||||
SQLServer2008,
|
||||
SQLServer2008R2,
|
||||
|
||||
// Azure will be reporting v11 instead of v10.25 soon...
|
||||
// http://social.msdn.microsoft.com/Forums/en-US/ssdsgetstarted/thread/ad7aae98-26ac-4979-848d-517a86c3fa5c/
|
||||
SQLServerAzure10, /*Azure*/
|
||||
|
||||
SQLServer2012,
|
||||
SQLServer2014,
|
||||
SQLServer2016,
|
||||
SQLServer2017,
|
||||
}
|
||||
|
||||
public enum SQLServerEdition
|
||||
{
|
||||
Personal = 1,
|
||||
Standard = 2,
|
||||
Enterprise = 3,
|
||||
Express = 4,
|
||||
Azure = 5
|
||||
}
|
||||
|
||||
private float versionNumber;
|
||||
|
||||
public DatabaseInfo()
|
||||
{
|
||||
Version = SQLServerVersion.SQLServer2005;
|
||||
}
|
||||
|
||||
public string Server { get; set; }
|
||||
|
||||
public string Database { get; set; }
|
||||
|
||||
public SQLServerVersion Version { get; private set; }
|
||||
|
||||
public SQLServerEdition Edition { get; private set; }
|
||||
|
||||
public string Collation { get; set; }
|
||||
|
||||
public bool HasFullTextEnabled { get; set; }
|
||||
|
||||
public string ChangeTrackingPeriodUnitsDesc { get; set; }
|
||||
|
||||
public int ChangeTrackingPeriodUnits { get; set; }
|
||||
|
||||
public int ChangeTrackingRetentionPeriod { get; set; }
|
||||
|
||||
public bool IsChangeTrackingAutoCleanup { get; set; }
|
||||
|
||||
public bool HasChangeTracking { get; set; }
|
||||
|
||||
public float VersionNumber
|
||||
{
|
||||
get { return versionNumber; }
|
||||
set
|
||||
{
|
||||
versionNumber = value;
|
||||
|
||||
SQLServerVersion version = this.Version;
|
||||
|
||||
// https://buildnumbers.wordpress.com/sqlserver/
|
||||
if (versionNumber >= 8) version = SQLServerVersion.SQLServer2000;
|
||||
if (versionNumber >= 9) version = SQLServerVersion.SQLServer2005;
|
||||
if (versionNumber >= 10) version = SQLServerVersion.SQLServer2008;
|
||||
if (versionNumber >= 10.25) version = SQLServerVersion.SQLServerAzure10;
|
||||
if (versionNumber >= 10.5) version = SQLServerVersion.SQLServer2008R2;
|
||||
if (versionNumber >= 11.0) version = SQLServerVersion.SQLServer2012;
|
||||
if (versionNumber >= 12.0) version = SQLServerVersion.SQLServer2014;
|
||||
if (versionNumber >= 13.0) version = SQLServerVersion.SQLServer2016;
|
||||
if (versionNumber >= 14.0) version = SQLServerVersion.SQLServer2017;
|
||||
|
||||
this.Version = version;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEdition(SQLServerEdition edition)
|
||||
{
|
||||
this.Edition = edition;
|
||||
|
||||
if (edition == SQLServerEdition.Azure)
|
||||
{
|
||||
this.Version = SQLServerVersion.SQLServerAzure10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
76
OpenDBDiff.Schema.SQLServer.Generates/Model/Default.cs
Normal file
76
OpenDBDiff.Schema.SQLServer.Generates/Model/Default.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class Default : SQLServerSchemaBase
|
||||
{
|
||||
public Default(ISchemaBase parent)
|
||||
: base(parent, ObjectType.Default)
|
||||
{
|
||||
}
|
||||
|
||||
public new Default Clone(ISchemaBase parent)
|
||||
{
|
||||
Default item = new Default(parent);
|
||||
item.Id = this.Id;
|
||||
item.Name = this.Name;
|
||||
item.Owner = this.Owner;
|
||||
item.Value = this.Value;
|
||||
return item;
|
||||
}
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public string ToSQLAddBind()
|
||||
{
|
||||
string sql = "";
|
||||
sql += "EXEC sp_bindefault N'" + Name + "', N'" + this.Parent.Name + "'\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public string ToSQLAddUnBind()
|
||||
{
|
||||
string sql = "";
|
||||
sql += "EXEC sp_unbindefault @objname=N'" + this.Parent.Name + "'\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return ToSql();
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "DROP DEFAULT " + FullName + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve el schema de diferencias del Schema en formato SQL.
|
||||
/// </summary>
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList listDiff = new SQLScriptList();
|
||||
|
||||
if (this.Status == ObjectStatus.Drop)
|
||||
{
|
||||
listDiff.Add(ToSqlDrop(), 0, ScriptAction.DropRule);
|
||||
}
|
||||
if (this.Status == ObjectStatus.Create)
|
||||
{
|
||||
listDiff.Add(ToSql(), 0, ScriptAction.AddRule);
|
||||
}
|
||||
if (this.Status == ObjectStatus.Alter)
|
||||
{
|
||||
listDiff.Add(ToSqlDrop(), 0, ScriptAction.DropRule);
|
||||
listDiff.Add(ToSql(), 0, ScriptAction.AddRule);
|
||||
}
|
||||
return listDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
151
OpenDBDiff.Schema.SQLServer.Generates/Model/Dependencies.cs
Normal file
151
OpenDBDiff.Schema.SQLServer.Generates/Model/Dependencies.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
internal class Dependencies : List<Dependency>
|
||||
{
|
||||
public Database Database { get; private set; }
|
||||
|
||||
public void Add(Database database, int tableId, int columnId, int ownerTableId, int typeId, ISchemaBase constraint)
|
||||
{
|
||||
Dependency dependency = new Dependency();
|
||||
dependency.SubObjectId = columnId;
|
||||
dependency.ObjectId = tableId;
|
||||
dependency.OwnerTableId = ownerTableId;
|
||||
|
||||
dependency.FullName = constraint.FullName;
|
||||
dependency.Type = constraint.ObjectType;
|
||||
dependency.DataTypeId = typeId;
|
||||
this.Database = database;
|
||||
base.Add(dependency);
|
||||
}
|
||||
|
||||
public void Add(Database database, int objectId, ISchemaBase objectSchema)
|
||||
{
|
||||
Dependency dependency = new Dependency();
|
||||
dependency.ObjectId = objectId;
|
||||
dependency.FullName = objectSchema.FullName;
|
||||
dependency.Type = objectSchema.ObjectType;
|
||||
this.Database = database;
|
||||
base.Add(dependency);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve todos las constraints dependientes de una tabla.
|
||||
/// </summary>
|
||||
public List<ISchemaBase> FindNotOwner(int tableId, ObjectType type)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<ISchemaBase> cons = new List<ISchemaBase>();
|
||||
this.ForEach(dependency =>
|
||||
{
|
||||
if (dependency.Type == type)
|
||||
{
|
||||
ISchemaBase item = (ISchemaBase)Database.Find(dependency.FullName);
|
||||
if (dependency.Type == ObjectType.Constraint)
|
||||
{
|
||||
if ((dependency.ObjectId == tableId) && (((Constraint)item).Type == Constraint.ConstraintType.ForeignKey))
|
||||
cons.Add(item);
|
||||
}
|
||||
else
|
||||
if (dependency.ObjectId == tableId)
|
||||
cons.Add(item);
|
||||
}
|
||||
|
||||
});
|
||||
return cons;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve todos las constraints dependientes de una tabla.
|
||||
/// </summary>
|
||||
/*public void Set(int tableId, Constraint constraint)
|
||||
{
|
||||
this.ForEach(item =>
|
||||
{
|
||||
if (item.Type == ObjectType.Constraint)
|
||||
if ((item.ObjectId == tableId) && (item.ObjectSchema.Name.Equals(constraint.Name)))
|
||||
item.ObjectSchema = constraint;
|
||||
});
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve todos las constraints dependientes de una tabla.
|
||||
/// </summary>
|
||||
public List<ISchemaBase> Find(int tableId)
|
||||
{
|
||||
return Find(tableId, 0, 0);
|
||||
}
|
||||
|
||||
public int DependenciesCount(int objectId, ObjectType type)
|
||||
{
|
||||
Dictionary<int, bool> depencyTracker = new Dictionary<int, bool>();
|
||||
return DependenciesCount(objectId, type, depencyTracker);
|
||||
}
|
||||
|
||||
private int DependenciesCount(int tableId, ObjectType type, Dictionary<int, bool> depencyTracker)
|
||||
{
|
||||
int count = 0;
|
||||
bool putItem = false;
|
||||
int relationalTableId;
|
||||
List<ISchemaBase> constraints = this.FindNotOwner(tableId, type);
|
||||
for (int index = 0; index < constraints.Count; index++)
|
||||
{
|
||||
ISchemaBase cons = constraints[index];
|
||||
if (cons.ObjectType == type)
|
||||
{
|
||||
if (type == ObjectType.Constraint)
|
||||
{
|
||||
relationalTableId = ((Constraint)cons).RelationalTableId;
|
||||
putItem = (relationalTableId == tableId);
|
||||
}
|
||||
}
|
||||
if (putItem)
|
||||
{
|
||||
if (!depencyTracker.ContainsKey(tableId))
|
||||
{
|
||||
depencyTracker.Add(tableId, true);
|
||||
count += 1 + DependenciesCount(cons.Parent.Id, type, depencyTracker);
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve todos las constraints dependientes de una tabla y una columna.
|
||||
/// </summary>
|
||||
public List<ISchemaBase> Find(int tableId, int columnId, int dataTypeId)
|
||||
{
|
||||
List<string> cons = new List<string>();
|
||||
List<ISchemaBase> real = new List<ISchemaBase>();
|
||||
|
||||
cons = (from depends in this
|
||||
where (depends.Type == ObjectType.Constraint || depends.Type == ObjectType.Index) &&
|
||||
((depends.DataTypeId == dataTypeId || dataTypeId == 0) && (depends.SubObjectId == columnId || columnId == 0) && (depends.ObjectId == tableId))
|
||||
select depends.FullName)
|
||||
.Concat(from depends in this
|
||||
where (depends.Type == ObjectType.View || depends.Type == ObjectType.Function) &&
|
||||
(depends.ObjectId == tableId)
|
||||
select depends.FullName).ToList();
|
||||
|
||||
cons.ForEach(item =>
|
||||
{
|
||||
ISchemaBase schema = Database.Find(item);
|
||||
if (schema != null) real.Add(schema);
|
||||
}
|
||||
);
|
||||
return real;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
OpenDBDiff.Schema.SQLServer.Generates/Model/Dependency.cs
Normal file
23
OpenDBDiff.Schema.SQLServer.Generates/Model/Dependency.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
internal class Dependency
|
||||
{
|
||||
public string FullName { get; set; }
|
||||
|
||||
public int DataTypeId { get; set; }
|
||||
|
||||
public ObjectType Type { get; set; }
|
||||
|
||||
public int SubObjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID de la tabla a la que hace referencia la constraint.
|
||||
/// </summary>
|
||||
public int ObjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID de la tabla a la que pertenece la constraint.
|
||||
/// </summary>
|
||||
public int OwnerTableId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class ExtendedProperty : SQLServerSchemaBase, ISchemaBase
|
||||
{
|
||||
public ExtendedProperty(ISchemaBase parent)
|
||||
: base(parent, ObjectType.ExtendedProperty)
|
||||
{
|
||||
}
|
||||
|
||||
public override string FullName
|
||||
{
|
||||
get
|
||||
{
|
||||
string normal = "[" + Level0name + "]" + (String.IsNullOrEmpty(Level1name) ? "" : ".[" + Level1name + "]") + (String.IsNullOrEmpty(Level2name) ? "" : ".[" + Level2name + "]");
|
||||
if ((String.IsNullOrEmpty(Level1type)) || (String.IsNullOrEmpty(Level2type)))
|
||||
return normal;
|
||||
if (!Level2type.Equals("TRIGGER"))
|
||||
return normal;
|
||||
else
|
||||
return "[" + Level0name + "].[" + Level2name + "]";
|
||||
}
|
||||
}
|
||||
|
||||
public string Level2name { get; set; }
|
||||
|
||||
public string Level2type { get; set; }
|
||||
|
||||
public string Level1name { get; set; }
|
||||
|
||||
public string Level1type { get; set; }
|
||||
|
||||
public string Level0name { get; set; }
|
||||
|
||||
public string Level0type { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public override SQLScript Create()
|
||||
{
|
||||
ScriptAction action = ScriptAction.AddExtendedProperty;
|
||||
return new SQLScript(this.ToSqlAdd(), 0, action);
|
||||
}
|
||||
|
||||
public override SQLScript Drop()
|
||||
{
|
||||
ScriptAction action = ScriptAction.DropExtendedProperty;
|
||||
return new SQLScript(this.ToSqlDrop(), 0, action);
|
||||
}
|
||||
|
||||
public override ObjectStatus Status { get; set; }
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
string sql = "EXEC sys.sp_addextendedproperty @name=N'" + Name + "', @value=N'" + Value + "' ,";
|
||||
sql += "@level0type=N'" + Level0type + "',@level0name=N'" + Level0name + "'";
|
||||
if (!String.IsNullOrEmpty(Level1name))
|
||||
sql += ", @level1type=N'" + Level1type + "',@level1name=N'" + Level1name + "'";
|
||||
if (!String.IsNullOrEmpty(Level2name))
|
||||
sql += ", @level2type=N'" + Level2type + "',@level2name=N'" + Level2name + "'";
|
||||
|
||||
return sql + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
string sql = "EXEC sys.sp_dropextendedproperty @name=N'" + Name + "', @value=N'" + Value + "' ,";
|
||||
sql += "@level0type=N'" + Level0type + "',@level0name=N'" + Level0name + "'";
|
||||
if (!String.IsNullOrEmpty(Level1name))
|
||||
sql += ", @level1type=N'" + Level1type + "',@level1name=N'" + Level1name + "'";
|
||||
|
||||
if (!String.IsNullOrEmpty(Level2name))
|
||||
sql += ", @level2type=N'" + Level2type + "',@level2name=N'" + Level2name + "'";
|
||||
return sql + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
return ToSqlAdd();
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (this.Parent.Status != ObjectStatus.Create)
|
||||
{
|
||||
if (this.Status == ObjectStatus.Create)
|
||||
list.Add(this.Create());
|
||||
if (this.Status == ObjectStatus.Drop)
|
||||
list.Add(this.Drop());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
106
OpenDBDiff.Schema.SQLServer.Generates/Model/FileGroup.cs
Normal file
106
OpenDBDiff.Schema.SQLServer.Generates/Model/FileGroup.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class FileGroup : SQLServerSchemaBase
|
||||
{
|
||||
public FileGroup(ISchemaBase parent)
|
||||
: base(parent, ObjectType.FileGroup)
|
||||
{
|
||||
Files = new FileGroupFiles(this);
|
||||
}
|
||||
|
||||
public override ISchemaBase Clone(ISchemaBase parent)
|
||||
{
|
||||
FileGroup file = new FileGroup(parent);
|
||||
file.IsDefaultFileGroup = this.IsDefaultFileGroup;
|
||||
file.IsReadOnly = this.IsReadOnly;
|
||||
file.Name = this.Name;
|
||||
file.Id = this.Id;
|
||||
file.Files = this.Files.Clone(file);
|
||||
file.Guid = this.Guid;
|
||||
file.IsFileStream = this.IsFileStream;
|
||||
return file;
|
||||
}
|
||||
|
||||
public FileGroupFiles Files { get; set; }
|
||||
|
||||
public Boolean IsFileStream { get; set; }
|
||||
|
||||
public Boolean IsDefaultFileGroup { get; set; }
|
||||
|
||||
public Boolean IsReadOnly { get; set; }
|
||||
|
||||
public static Boolean Compare(FileGroup origin, FileGroup destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.IsReadOnly != destination.IsReadOnly) return false;
|
||||
if (origin.IsDefaultFileGroup != destination.IsDefaultFileGroup) return false;
|
||||
if (origin.IsFileStream != destination.IsFileStream) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private string ToSQL(string action)
|
||||
{
|
||||
string sql = "ALTER DATABASE [" + Parent.Name + "] " + action + " ";
|
||||
sql += "FILEGROUP [" + Name + "]";
|
||||
if (action.Equals("MODIFY"))
|
||||
{
|
||||
if (IsDefaultFileGroup) sql += " DEFAULT";
|
||||
}
|
||||
else
|
||||
if (IsFileStream) sql += " CONTAINS FILESTREAM";
|
||||
if (IsReadOnly) sql += " READONLY";
|
||||
sql += "\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
string sql = ToSQL("ADD");
|
||||
foreach (FileGroupFile file in this.Files)
|
||||
sql += file.ToSql();
|
||||
if (IsDefaultFileGroup)
|
||||
sql += ToSQL("MODIFY");
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
string sql = ToSQL("ADD");
|
||||
foreach (FileGroupFile file in this.Files)
|
||||
sql += file.ToSqlAdd();
|
||||
if (IsDefaultFileGroup)
|
||||
sql += ToSQL("MODIFY");
|
||||
return sql;
|
||||
}
|
||||
|
||||
public string ToSQLAlter()
|
||||
{
|
||||
return ToSQL("MODIFY");
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
string sql = "";
|
||||
sql = Files.ToSQLDrop();
|
||||
return sql + "ALTER DATABASE [" + Parent.Name + "] REMOVE FILEGROUP [" + Name + "]\r\nGO\r\n\r\n";
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList listDiff = new SQLScriptList();
|
||||
|
||||
if (this.Status == ObjectStatus.Drop)
|
||||
listDiff.Add(this.ToSqlDrop(), 1, ScriptAction.DropFileGroup);
|
||||
if (this.Status == ObjectStatus.Create)
|
||||
listDiff.Add(this.ToSqlAdd(), 1, ScriptAction.AddFileGroup);
|
||||
if (this.Status == ObjectStatus.Alter)
|
||||
listDiff.Add(this.ToSQLAlter(), 1, ScriptAction.AlterFileGroup);
|
||||
|
||||
return listDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
111
OpenDBDiff.Schema.SQLServer.Generates/Model/FileGroupFile.cs
Normal file
111
OpenDBDiff.Schema.SQLServer.Generates/Model/FileGroupFile.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class FileGroupFile : SQLServerSchemaBase
|
||||
{
|
||||
public FileGroupFile(ISchemaBase parent)
|
||||
: base(parent, ObjectType.File)
|
||||
{
|
||||
}
|
||||
|
||||
public override ISchemaBase Clone(ISchemaBase parent)
|
||||
{
|
||||
FileGroupFile file = new FileGroupFile(parent);
|
||||
file.Growth = this.Growth;
|
||||
file.Id = this.Id;
|
||||
file.IsPercentGrowth = this.IsPercentGrowth;
|
||||
file.IsSparse = this.IsSparse;
|
||||
file.MaxSize = this.MaxSize;
|
||||
file.Name = this.Name;
|
||||
file.PhysicalName = this.PhysicalName;
|
||||
file.Size = this.Size;
|
||||
file.Type = this.Type;
|
||||
return file;
|
||||
}
|
||||
|
||||
public int Size { get; set; }
|
||||
|
||||
public Boolean IsSparse { get; set; }
|
||||
|
||||
public Boolean IsPercentGrowth { get; set; }
|
||||
|
||||
private string TypeGrowth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Growth == 0)
|
||||
return "";
|
||||
else
|
||||
if (IsPercentGrowth)
|
||||
return "%";
|
||||
else
|
||||
return "KB";
|
||||
}
|
||||
}
|
||||
|
||||
public int Growth { get; set; }
|
||||
|
||||
public int MaxSize { get; set; }
|
||||
|
||||
public string PhysicalName { get; set; }
|
||||
|
||||
public int Type { get; set; }
|
||||
|
||||
private string GetNameNewFileGroup(string path)
|
||||
{
|
||||
string result = "";
|
||||
string[] flies = path.Split('\\');
|
||||
for (int index = 0; index < flies.Length - 1; index++)
|
||||
if (!String.IsNullOrEmpty(flies[index]))
|
||||
result += flies[index] + "\\";
|
||||
result += Parent.Parent.Name + "_" + Name + "_DB.ndf";
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara dos triggers y devuelve true si son iguales, caso contrario, devuelve false.
|
||||
/// </summary>
|
||||
public static Boolean Compare(FileGroupFile origin, FileGroupFile destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.Growth != destination.Growth) return false;
|
||||
if (origin.IsPercentGrowth != destination.IsPercentGrowth) return false;
|
||||
if (origin.IsSparse != destination.IsSparse) return false;
|
||||
if (origin.MaxSize != destination.MaxSize) return false;
|
||||
if (!origin.PhysicalName.Equals(destination.PhysicalName)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
if (Type != 2)
|
||||
return "ALTER DATABASE " + Parent.Parent.FullName + "\r\nADD" + ((Type != 1) ? "" : " LOG") + " FILE ( NAME = N'" + Name + "', FILENAME = N'" + PhysicalName + "' , SIZE = " + Size * 1000 + "KB , FILEGROWTH = " + Growth * 1000 + TypeGrowth + ") TO FILEGROUP " + Parent.FullName + "\r\nGO\r\n";
|
||||
else
|
||||
return "ALTER DATABASE " + Parent.Parent.FullName + "\r\nADD" + ((Type != 1) ? "" : " LOG") + " FILE ( NAME = N'" + Name + "', FILENAME = N'" + PhysicalName + "') TO FILEGROUP " + Parent.FullName + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
if (Type != 2)
|
||||
return "ALTER DATABASE " + Parent.Parent.FullName + "\r\nADD" + ((Type != 1) ? "" : " LOG") + " FILE ( NAME = N'" + Name + "', FILENAME = N'" + GetNameNewFileGroup(PhysicalName) + "' , SIZE = " + Size * 1000 + "KB , FILEGROWTH = " + Growth * 1000 + TypeGrowth + ") TO FILEGROUP " + Parent.FullName + "\r\nGO\r\n";
|
||||
else
|
||||
return "ALTER DATABASE " + Parent.Parent.FullName + "\r\nADD" + ((Type != 1) ? "" : " LOG") + " FILE ( NAME = N'" + Name + "', FILENAME = N'" + GetNameNewFileGroup(PhysicalName) + "') TO FILEGROUP " + Parent.FullName + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public string ToSQLAlter()
|
||||
{
|
||||
if (Type != 2)
|
||||
return "ALTER DATABASE " + Parent.Parent.FullName + " MODIFY FILE ( NAME = N'" + Name + "', FILENAME = N'" + PhysicalName + "' , SIZE = " + Size * 1000 + "KB , FILEGROWTH = " + Growth * 1000 + TypeGrowth + ")";
|
||||
else
|
||||
return "ALTER DATABASE " + Parent.Parent.FullName + " MODIFY FILE ( NAME = N'" + Name + "', FILENAME = N'" + PhysicalName + "')";
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "ALTER DATABASE " + Parent.Parent.FullName + " REMOVE FILE " + this.FullName + "\r\nGO\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
104
OpenDBDiff.Schema.SQLServer.Generates/Model/FileGroupFiles.cs
Normal file
104
OpenDBDiff.Schema.SQLServer.Generates/Model/FileGroupFiles.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class FileGroupFiles : List<FileGroupFile>
|
||||
{
|
||||
private Hashtable hash = new Hashtable();
|
||||
|
||||
/// <summary>
|
||||
/// Constructor de la clase.
|
||||
/// </summary>
|
||||
/// <param name="parent">
|
||||
/// Objeto Database padre.
|
||||
/// </param>
|
||||
public FileGroupFiles(FileGroup parent)
|
||||
{
|
||||
this.Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clona el objeto FileGroups en una nueva instancia.
|
||||
/// </summary>
|
||||
public FileGroupFiles Clone(FileGroup parentObject)
|
||||
{
|
||||
FileGroupFiles columns = new FileGroupFiles(parentObject);
|
||||
for (int index = 0; index < this.Count; index++)
|
||||
{
|
||||
columns.Add((FileGroupFile)this[index].Clone(parentObject));
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indica si el nombre del FileGroup existe en la coleccion de tablas del objeto.
|
||||
/// </summary>
|
||||
/// <param name="table">
|
||||
/// Nombre de la tabla a buscar.
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public Boolean Find(string table)
|
||||
{
|
||||
return hash.ContainsKey(table);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Agrega un objeto columna a la coleccion de columnas.
|
||||
/// </summary>
|
||||
public new void Add(FileGroupFile file)
|
||||
{
|
||||
if (file != null)
|
||||
{
|
||||
hash.Add(file.FullName, file);
|
||||
base.Add(file);
|
||||
}
|
||||
else
|
||||
throw new ArgumentNullException("file");
|
||||
}
|
||||
|
||||
public FileGroupFile this[string name]
|
||||
{
|
||||
get { return (FileGroupFile)hash[name]; }
|
||||
set
|
||||
{
|
||||
hash[name] = value;
|
||||
for (int index = 0; index < base.Count; index++)
|
||||
{
|
||||
if (((FileGroupFile)base[index]).Name.Equals(name))
|
||||
{
|
||||
base[index] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devuelve la tabla perteneciente a la coleccion de campos.
|
||||
/// </summary>
|
||||
public FileGroup Parent { get; private set; }
|
||||
|
||||
public string ToSQL()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
for (int index = 0; index < this.Count; index++)
|
||||
{
|
||||
sql.Append(this[index].ToSql());
|
||||
}
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
public string ToSQLDrop()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
for (int index = 0; index < this.Count; index++)
|
||||
{
|
||||
sql.Append(this[index].ToSqlDrop());
|
||||
}
|
||||
return sql.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
131
OpenDBDiff.Schema.SQLServer.Generates/Model/FullText.cs
Normal file
131
OpenDBDiff.Schema.SQLServer.Generates/Model/FullText.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class FullText : SQLServerSchemaBase
|
||||
{
|
||||
public FullText(ISchemaBase parent)
|
||||
: base(parent, ObjectType.FullText)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override string FullName
|
||||
{
|
||||
get { return "[" + Name + "]"; }
|
||||
}
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public Boolean IsDefault { get; set; }
|
||||
|
||||
public Boolean IsAccentSensity { get; set; }
|
||||
|
||||
public string FileGroupName { get; set; }
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
Database database = (Database)this.Parent;
|
||||
|
||||
string sql = "CREATE FULLTEXT CATALOG " + FullName + " ";
|
||||
if (!IsAccentSensity)
|
||||
sql += "WITH ACCENT_SENSITIVITY = OFF\r\n";
|
||||
else
|
||||
sql += "WITH ACCENT_SENSITIVITY = ON\r\n";
|
||||
if (!String.IsNullOrEmpty(this.Path))
|
||||
{
|
||||
if (!database.Options.Ignore.FilterFullTextPath)
|
||||
sql += "--";
|
||||
sql += "IN PATH N'" + Path + "'\r\n";
|
||||
}
|
||||
if (IsDefault)
|
||||
sql += "AS DEFAULT\r\n";
|
||||
sql += "AUTHORIZATION [" + Owner + "]\r\n";
|
||||
return sql + "GO\r\n";
|
||||
}
|
||||
|
||||
private string ToSqlAlterDefault()
|
||||
{
|
||||
if (IsDefault)
|
||||
{
|
||||
string sql = "ALTER FULLTEXT CATALOG " + FullName + "\r\n";
|
||||
sql += "AS DEFAULT";
|
||||
sql += "\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
else return "";
|
||||
|
||||
}
|
||||
|
||||
private string ToSqlAlterOwner()
|
||||
{
|
||||
string sql = "ALTER AUTHORIZATION ON FULLTEXT CATALOG::" + FullName + "\r\n";
|
||||
sql += "TO [" + Owner + "]\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
private string ToSqlAlter()
|
||||
{
|
||||
string sql = "ALTER FULLTEXT CATALOG " + FullName + "\r\n";
|
||||
sql += "REBUILD WITH ACCENT_SENSITIVITY = ";
|
||||
if (IsAccentSensity) sql += "ON"; else sql += "OFF";
|
||||
sql += "\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "DROP FULLTEXT CATALOG " + FullName + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return ToSql();
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList listDiff = new SQLScriptList();
|
||||
|
||||
if (this.Status == ObjectStatus.Drop)
|
||||
{
|
||||
listDiff.Add(ToSqlDrop(), 0, ScriptAction.DropFullText);
|
||||
}
|
||||
if (this.Status == ObjectStatus.Create)
|
||||
{
|
||||
listDiff.Add(ToSql(), 0, ScriptAction.AddFullText);
|
||||
}
|
||||
if (this.HasState(ObjectStatus.Alter))
|
||||
{
|
||||
listDiff.Add(ToSqlAlter(), 0, ScriptAction.AddFullText);
|
||||
}
|
||||
if (this.HasState(ObjectStatus.Disabled))
|
||||
{
|
||||
listDiff.Add(ToSqlAlterDefault(), 0, ScriptAction.AddFullText);
|
||||
}
|
||||
if (this.HasState(ObjectStatus.ChangeOwner))
|
||||
{
|
||||
listDiff.Add(ToSqlAlterOwner(), 0, ScriptAction.AddFullText);
|
||||
}
|
||||
return listDiff;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara dos Synonyms y devuelve true si son iguales, caso contrario, devuelve false.
|
||||
/// </summary>
|
||||
public Boolean Compare(FullText destination)
|
||||
{
|
||||
Database database = (Database)this.Parent;
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (!this.IsAccentSensity.Equals(destination.IsAccentSensity)) return false;
|
||||
if (!this.IsDefault.Equals(destination.IsDefault)) return false;
|
||||
if ((!String.IsNullOrEmpty(this.FileGroupName)) && (!String.IsNullOrEmpty(destination.FileGroupName)))
|
||||
if (!this.FileGroupName.Equals(destination.FileGroupName)) return false;
|
||||
if (database.Options.Ignore.FilterFullTextPath)
|
||||
if ((!String.IsNullOrEmpty(this.Path)) && (!String.IsNullOrEmpty(destination.Path)))
|
||||
return this.Path.Equals(destination.Path, StringComparison.CurrentCultureIgnoreCase);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
159
OpenDBDiff.Schema.SQLServer.Generates/Model/FullTextIndex.cs
Normal file
159
OpenDBDiff.Schema.SQLServer.Generates/Model/FullTextIndex.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class FullTextIndex : SQLServerSchemaBase
|
||||
{
|
||||
public FullTextIndex(ISchemaBase parent)
|
||||
: base(parent, ObjectType.FullTextIndex)
|
||||
{
|
||||
Columns = new List<FullTextIndexColumn>();
|
||||
}
|
||||
|
||||
public override ISchemaBase Clone(ISchemaBase parent)
|
||||
{
|
||||
FullTextIndex index = new FullTextIndex(parent);
|
||||
index.ChangeTrackingState = this.ChangeTrackingState;
|
||||
index.FullText = this.FullText;
|
||||
index.Name = this.Name;
|
||||
index.FileGroup = this.FileGroup;
|
||||
index.Id = this.Id;
|
||||
index.Index = this.Index;
|
||||
index.IsDisabled = this.IsDisabled;
|
||||
index.Status = this.Status;
|
||||
index.Owner = this.Owner;
|
||||
index.Columns = this.Columns;
|
||||
this.ExtendedProperties.ForEach(item => index.ExtendedProperties.Add(item));
|
||||
return index;
|
||||
}
|
||||
|
||||
public string FileGroup { get; set; }
|
||||
|
||||
public Boolean IsDisabled { get; set; }
|
||||
|
||||
public string Index { get; set; }
|
||||
|
||||
public string FullText { get; set; }
|
||||
|
||||
public string ChangeTrackingState { get; set; }
|
||||
|
||||
public override string FullName
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public List<FullTextIndexColumn> Columns { get; set; }
|
||||
|
||||
public override SQLScript Create()
|
||||
{
|
||||
ScriptAction action = ScriptAction.AddFullTextIndex;
|
||||
if (!GetWasInsertInDiffList(action))
|
||||
{
|
||||
SetWasInsertInDiffList(action);
|
||||
return new SQLScript(this.ToSqlAdd(), Parent.DependenciesCount, action);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public override SQLScript Drop()
|
||||
{
|
||||
ScriptAction action = ScriptAction.DropFullTextIndex;
|
||||
if (!GetWasInsertInDiffList(action))
|
||||
{
|
||||
SetWasInsertInDiffList(action);
|
||||
return new SQLScript(this.ToSqlDrop(), Parent.DependenciesCount, action);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
string sql = "CREATE FULLTEXT INDEX ON " + Parent.FullName + "( ";
|
||||
Columns.ForEach(item => { sql += "[" + item.ColumnName + "] LANGUAGE [" + item.Language + "],"; });
|
||||
sql = sql.Substring(0, sql.Length - 1);
|
||||
sql += ")\r\n";
|
||||
if (((Database)this.RootParent).Info.Version == DatabaseInfo.SQLServerVersion.SQLServer2008)
|
||||
{
|
||||
sql += "KEY INDEX " + Index + " ON ([" + FullText + "]";
|
||||
sql += ", FILEGROUP [" + FileGroup + "]";
|
||||
sql += ") WITH (CHANGE_TRACKING " + ChangeTrackingState + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
sql += "KEY INDEX " + Index + " ON [" + FullText + "]";
|
||||
sql += " WITH CHANGE_TRACKING " + ChangeTrackingState;
|
||||
}
|
||||
sql += "\r\nGO\r\n";
|
||||
if (!this.IsDisabled)
|
||||
sql += "ALTER FULLTEXT INDEX ON " + Parent.FullName + " ENABLE\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public string ToSqlEnabled()
|
||||
{
|
||||
if (this.IsDisabled)
|
||||
return "ALTER FULLTEXT INDEX ON " + Parent.FullName + " DISABLE\r\nGO\r\n";
|
||||
else
|
||||
return "ALTER FULLTEXT INDEX ON " + Parent.FullName + " ENABLE\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "DROP FULLTEXT INDEX ON " + Parent.FullName + "\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
return ToSqlAdd();
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (this.Status != ObjectStatus.Original)
|
||||
RootParent.ActionMessage[Parent.FullName].Add(this);
|
||||
|
||||
if (this.HasState(ObjectStatus.Drop))
|
||||
list.Add(Drop());
|
||||
if (this.HasState(ObjectStatus.Create))
|
||||
list.Add(Create());
|
||||
if (this.HasState(ObjectStatus.Alter))
|
||||
{
|
||||
list.Add(Drop());
|
||||
list.Add(Create());
|
||||
}
|
||||
if (this.Status == ObjectStatus.Disabled)
|
||||
{
|
||||
list.Add(this.ToSqlEnabled(), Parent.DependenciesCount, ScriptAction.AlterFullTextIndex);
|
||||
}
|
||||
/*if (this.Status == StatusEnum.ObjectStatusType.ChangeFileGroup)
|
||||
{
|
||||
listDiff.Add(this.ToSQLDrop(this.FileGroup), ((Table)Parent).DependenciesCount, StatusEnum.ScripActionType.DropIndex);
|
||||
listDiff.Add(this.ToSQLAdd(), ((Table)Parent).DependenciesCount, StatusEnum.ScripActionType.AddIndex);
|
||||
}*/
|
||||
list.AddRange(this.ExtendedProperties.ToSqlDiff());
|
||||
return list;
|
||||
}
|
||||
|
||||
public Boolean Compare(FullTextIndex destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (!this.ChangeTrackingState.Equals(destination.ChangeTrackingState)) return false;
|
||||
if (!this.FullText.Equals(destination.FullText)) return false;
|
||||
if (!this.Index.Equals(destination.Index)) return false;
|
||||
if (this.IsDisabled != destination.IsDisabled) return false;
|
||||
if (this.Columns.Count != destination.Columns.Count) return false;
|
||||
if (this.Columns.Exists(item => { return !destination.Columns.Exists(item2 => item2.ColumnName.Equals(item.ColumnName)); })) return false;
|
||||
if (destination.Columns.Exists(item => { return !this.Columns.Exists(item2 => item2.ColumnName.Equals(item.ColumnName)); })) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class FullTextIndexColumn
|
||||
{
|
||||
public string Language { get; set; }
|
||||
|
||||
public string ColumnName { get; set; }
|
||||
}
|
||||
}
|
||||
80
OpenDBDiff.Schema.SQLServer.Generates/Model/Function.cs
Normal file
80
OpenDBDiff.Schema.SQLServer.Generates/Model/Function.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
using OpenDBDiff.Schema.SQLServer.Generates.Model.Util;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class Function : Code
|
||||
{
|
||||
public Function(ISchemaBase parent)
|
||||
: base(parent, ObjectType.Function, ScriptAction.AddFunction, ScriptAction.DropFunction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clona el objeto en una nueva instancia.
|
||||
/// </summary>
|
||||
public override ISchemaBase Clone(ISchemaBase parent)
|
||||
{
|
||||
Function item = new Function(parent);
|
||||
item.Text = this.Text;
|
||||
item.Status = this.Status;
|
||||
item.Name = this.Name;
|
||||
item.Id = this.Id;
|
||||
item.Owner = this.Owner;
|
||||
item.Guid = this.Guid;
|
||||
item.IsSchemaBinding = this.IsSchemaBinding;
|
||||
this.DependenciesIn.ForEach(dep => item.DependenciesIn.Add(dep));
|
||||
this.DependenciesOut.ForEach(dep => item.DependenciesOut.Add(dep));
|
||||
return item;
|
||||
}
|
||||
|
||||
public override Boolean IsCodeType
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public string ToSQLAlter()
|
||||
{
|
||||
return ToSQLAlter(false);
|
||||
}
|
||||
|
||||
public string ToSQLAlter(Boolean quitSchemaBinding)
|
||||
{
|
||||
return FormatCode.FormatAlter("FUNCTION", ToSql(), this, quitSchemaBinding);
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (this.Status != ObjectStatus.Original)
|
||||
RootParent.ActionMessage.Add(this);
|
||||
|
||||
if (this.HasState(ObjectStatus.Drop))
|
||||
list.Add(Drop());
|
||||
if (this.HasState(ObjectStatus.Create))
|
||||
list.Add(Create());
|
||||
if (this.HasState(ObjectStatus.Alter))
|
||||
{
|
||||
if (this.HasState(ObjectStatus.RebuildDependencies))
|
||||
list.AddRange(RebuildDependencies());
|
||||
|
||||
if (!this.GetWasInsertInDiffList(ScriptAction.DropFunction))
|
||||
{
|
||||
if (this.HasState(ObjectStatus.Rebuild))
|
||||
{
|
||||
list.Add(Drop());
|
||||
list.Add(Create());
|
||||
}
|
||||
if (this.HasState(ObjectStatus.AlterBody))
|
||||
{
|
||||
int iCount = DependenciesCount;
|
||||
list.Add(ToSQLAlter(), iCount, ScriptAction.AlterFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
OpenDBDiff.Schema.SQLServer.Generates/Model/ITableType.cs
Normal file
13
OpenDBDiff.Schema.SQLServer.Generates/Model/ITableType.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public interface ITable<T> where T : ISchemaBase
|
||||
{
|
||||
Columns<T> Columns { get; }
|
||||
SchemaList<Constraint, T> Constraints { get; }
|
||||
SchemaList<Index, T> Indexes { get; }
|
||||
ISchemaBase Parent { get; set; }
|
||||
string Owner { get; set; }
|
||||
}
|
||||
}
|
||||
300
OpenDBDiff.Schema.SQLServer.Generates/Model/Index.cs
Normal file
300
OpenDBDiff.Schema.SQLServer.Generates/Model/Index.cs
Normal file
@@ -0,0 +1,300 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class Index : SQLServerSchemaBase
|
||||
{
|
||||
public enum IndexTypeEnum
|
||||
{
|
||||
Heap = 0,
|
||||
Clustered = 1,
|
||||
Nonclustered = 2,
|
||||
XML = 3,
|
||||
GEO = 4
|
||||
}
|
||||
|
||||
public Index(ISchemaBase parent)
|
||||
: base(parent, ObjectType.Index)
|
||||
{
|
||||
FilterDefintion = "";
|
||||
Columns = new IndexColumns(parent);
|
||||
}
|
||||
|
||||
public override ISchemaBase Clone(ISchemaBase parent)
|
||||
{
|
||||
Index index = new Index(parent)
|
||||
{
|
||||
AllowPageLocks = this.AllowPageLocks,
|
||||
AllowRowLocks = this.AllowRowLocks,
|
||||
Columns = this.Columns.Clone(),
|
||||
FillFactor = this.FillFactor,
|
||||
FileGroup = this.FileGroup,
|
||||
Id = this.Id,
|
||||
IgnoreDupKey = this.IgnoreDupKey,
|
||||
IsAutoStatistics = this.IsAutoStatistics,
|
||||
IsDisabled = this.IsDisabled,
|
||||
IsPadded = this.IsPadded,
|
||||
IsPrimaryKey = this.IsPrimaryKey,
|
||||
IsUniqueKey = this.IsUniqueKey,
|
||||
Name = this.Name,
|
||||
SortInTempDb = this.SortInTempDb,
|
||||
Status = this.Status,
|
||||
Type = this.Type,
|
||||
Owner = this.Owner,
|
||||
FilterDefintion = this.FilterDefintion
|
||||
};
|
||||
ExtendedProperties.ForEach(item => index.ExtendedProperties.Add(item));
|
||||
return index;
|
||||
}
|
||||
|
||||
public string FileGroup { get; set; }
|
||||
|
||||
public Boolean SortInTempDb { get; set; }
|
||||
|
||||
public string FilterDefintion { get; set; }
|
||||
|
||||
public IndexColumns Columns { get; set; }
|
||||
|
||||
public Boolean IsAutoStatistics { get; set; }
|
||||
|
||||
public Boolean IsUniqueKey { get; set; }
|
||||
|
||||
public Boolean IsPrimaryKey { get; set; }
|
||||
|
||||
public IndexTypeEnum Type { get; set; }
|
||||
|
||||
public short FillFactor { get; set; }
|
||||
|
||||
public Boolean IsDisabled { get; set; }
|
||||
|
||||
public Boolean IsPadded { get; set; }
|
||||
|
||||
public Boolean IgnoreDupKey { get; set; }
|
||||
|
||||
public Boolean AllowPageLocks { get; set; }
|
||||
|
||||
public Boolean AllowRowLocks { get; set; }
|
||||
|
||||
public override string FullName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Parent.FullName + ".[" + Name + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara dos indices y devuelve true si son iguales, caso contrario, devuelve false.
|
||||
/// </summary>
|
||||
public static Boolean Compare(Index origin, Index destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.AllowPageLocks != destination.AllowPageLocks) return false;
|
||||
if (origin.AllowRowLocks != destination.AllowRowLocks) return false;
|
||||
if (origin.FillFactor != destination.FillFactor) return false;
|
||||
if (origin.IgnoreDupKey != destination.IgnoreDupKey) return false;
|
||||
if (origin.IsAutoStatistics != destination.IsAutoStatistics) return false;
|
||||
if (origin.IsDisabled != destination.IsDisabled) return false;
|
||||
if (origin.IsPadded != destination.IsPadded) return false;
|
||||
if (origin.IsPrimaryKey != destination.IsPrimaryKey) return false;
|
||||
if (origin.IsUniqueKey != destination.IsUniqueKey) return false;
|
||||
if (origin.Type != destination.Type) return false;
|
||||
if (origin.SortInTempDb != destination.SortInTempDb) return false;
|
||||
if (!origin.FilterDefintion.Equals(destination.FilterDefintion)) return false;
|
||||
if (!IndexColumns.Compare(origin.Columns, destination.Columns)) return false;
|
||||
return CompareFileGroup(origin, destination);
|
||||
}
|
||||
|
||||
public static Boolean CompareExceptIsDisabled(Index origin, Index destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.AllowPageLocks != destination.AllowPageLocks) return false;
|
||||
if (origin.AllowRowLocks != destination.AllowRowLocks) return false;
|
||||
if (origin.FillFactor != destination.FillFactor) return false;
|
||||
if (origin.IgnoreDupKey != destination.IgnoreDupKey) return false;
|
||||
if (origin.IsAutoStatistics != destination.IsAutoStatistics) return false;
|
||||
if (origin.IsPadded != destination.IsPadded) return false;
|
||||
if (origin.IsPrimaryKey != destination.IsPrimaryKey) return false;
|
||||
if (origin.IsUniqueKey != destination.IsUniqueKey) return false;
|
||||
if (origin.Type != destination.Type) return false;
|
||||
if (origin.SortInTempDb != destination.SortInTempDb) return false;
|
||||
if (!origin.FilterDefintion.Equals(destination.FilterDefintion)) return false;
|
||||
if (!IndexColumns.Compare(origin.Columns, destination.Columns)) return false;
|
||||
//return true;
|
||||
return CompareFileGroup(origin, destination);
|
||||
}
|
||||
|
||||
private static Boolean CompareFileGroup(Index origin, Index destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.FileGroup != null)
|
||||
{
|
||||
if (!origin.FileGroup.Equals(destination.FileGroup)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
Database database = null;
|
||||
ISchemaBase current = this;
|
||||
while (database == null && current.Parent != null)
|
||||
{
|
||||
database = current.Parent as Database;
|
||||
current = current.Parent;
|
||||
}
|
||||
var isAzure10 = database.Info.Version == DatabaseInfo.SQLServerVersion.SQLServerAzure10;
|
||||
|
||||
StringBuilder sql = new StringBuilder();
|
||||
string includes = "";
|
||||
if ((Type == IndexTypeEnum.Clustered) && (IsUniqueKey)) sql.Append("CREATE UNIQUE CLUSTERED ");
|
||||
if ((Type == IndexTypeEnum.Clustered) && (!IsUniqueKey)) sql.Append("CREATE CLUSTERED ");
|
||||
if ((Type == IndexTypeEnum.Nonclustered) && (IsUniqueKey)) sql.Append("CREATE UNIQUE NONCLUSTERED ");
|
||||
if ((Type == IndexTypeEnum.Nonclustered) && (!IsUniqueKey)) sql.Append("CREATE NONCLUSTERED ");
|
||||
if (Type == IndexTypeEnum.XML) sql.Append("CREATE PRIMARY XML ");
|
||||
sql.Append("INDEX [" + Name + "] ON " + Parent.FullName + "\r\n(\r\n");
|
||||
/*Ordena la coleccion de campos del Indice en funcion de la propieda IsIncluded*/
|
||||
Columns.Sort();
|
||||
for (int j = 0; j < Columns.Count; j++)
|
||||
{
|
||||
if (!Columns[j].IsIncluded)
|
||||
{
|
||||
sql.Append("\t[" + Columns[j].Name + "]");
|
||||
if (Type != IndexTypeEnum.XML)
|
||||
{
|
||||
if (Columns[j].Order) sql.Append(" DESC"); else sql.Append(" ASC");
|
||||
}
|
||||
if (j < Columns.Count - 1) sql.Append(",");
|
||||
sql.Append("\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (String.IsNullOrEmpty(includes)) includes = ") INCLUDE (";
|
||||
includes += "[" + Columns[j].Name + "],";
|
||||
}
|
||||
}
|
||||
if (!String.IsNullOrEmpty(includes)) includes = includes.Substring(0, includes.Length - 1);
|
||||
sql.Append(includes);
|
||||
sql.Append(")");
|
||||
if (!String.IsNullOrEmpty(FilterDefintion)) sql.Append("\r\n WHERE " + FilterDefintion + "\r\n");
|
||||
sql.Append(" WITH (");
|
||||
if (Parent.ObjectType == ObjectType.TableType)
|
||||
{
|
||||
if ((IgnoreDupKey) && (IsUniqueKey)) sql.Append("IGNORE_DUP_KEY = ON "); else sql.Append("IGNORE_DUP_KEY = OFF ");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isAzure10)
|
||||
{
|
||||
if (IsPadded) sql.Append("PAD_INDEX = ON, "); else sql.Append("PAD_INDEX = OFF, ");
|
||||
}
|
||||
|
||||
if (IsAutoStatistics) sql.Append("STATISTICS_NORECOMPUTE = ON"); else sql.Append("STATISTICS_NORECOMPUTE = OFF");
|
||||
if (Type != IndexTypeEnum.XML)
|
||||
if ((IgnoreDupKey) && (IsUniqueKey)) sql.Append("IGNORE_DUP_KEY = ON, "); else sql.Append(", IGNORE_DUP_KEY = OFF");
|
||||
|
||||
if (!isAzure10)
|
||||
{
|
||||
if (AllowRowLocks) sql.Append(", ALLOW_ROW_LOCKS = ON"); else sql.Append(", ALLOW_ROW_LOCKS = OFF");
|
||||
if (AllowPageLocks) sql.Append(", ALLOW_PAGE_LOCKS = ON"); else sql.Append(", ALLOW_PAGE_LOCKS = OFF");
|
||||
if (FillFactor != 0) sql.Append(", FILLFACTOR = " + FillFactor.ToString());
|
||||
}
|
||||
}
|
||||
sql.Append(")");
|
||||
if (!isAzure10)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(FileGroup)) sql.Append(" ON [" + FileGroup + "]");
|
||||
}
|
||||
sql.Append("\r\nGO\r\n");
|
||||
if (IsDisabled)
|
||||
sql.Append("ALTER INDEX [" + Name + "] ON " + ((Table)Parent).FullName + " DISABLE\r\nGO\r\n");
|
||||
|
||||
sql.Append(ExtendedProperties.ToSql());
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return ToSql();
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return ToSqlDrop(null);
|
||||
}
|
||||
|
||||
private string ToSqlDrop(string FileGroupName)
|
||||
{
|
||||
string sql = "DROP INDEX [" + Name + "] ON " + Parent.FullName;
|
||||
if (!String.IsNullOrEmpty(FileGroupName)) sql += " WITH (MOVE TO [" + FileGroupName + "])";
|
||||
sql += "\r\nGO\r\n";
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override SQLScript Create()
|
||||
{
|
||||
ScriptAction action = ScriptAction.AddIndex;
|
||||
if (!GetWasInsertInDiffList(action))
|
||||
{
|
||||
SetWasInsertInDiffList(action);
|
||||
return new SQLScript(ToSqlAdd(), Parent.DependenciesCount, action);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override SQLScript Drop()
|
||||
{
|
||||
ScriptAction action = ScriptAction.DropIndex;
|
||||
if (!GetWasInsertInDiffList(action))
|
||||
{
|
||||
SetWasInsertInDiffList(action);
|
||||
return new SQLScript(ToSqlDrop(), Parent.DependenciesCount, action);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private string ToSqlEnabled()
|
||||
{
|
||||
if (IsDisabled)
|
||||
return "ALTER INDEX [" + Name + "] ON " + Parent.FullName + " DISABLE\r\nGO\r\n";
|
||||
return "ALTER INDEX [" + Name + "] ON " + Parent.FullName + " REBUILD\r\nGO\r\n";
|
||||
}
|
||||
|
||||
public override SQLScriptList ToSqlDiff(System.Collections.Generic.ICollection<ISchemaBase> schemas)
|
||||
{
|
||||
SQLScriptList list = new SQLScriptList();
|
||||
if (Status != ObjectStatus.Original)
|
||||
{
|
||||
var actionMessage = RootParent.ActionMessage[Parent.FullName];
|
||||
if (actionMessage != null)
|
||||
actionMessage.Add(this);
|
||||
}
|
||||
|
||||
if (HasState(ObjectStatus.Drop))
|
||||
list.Add(Drop());
|
||||
if (HasState(ObjectStatus.Create))
|
||||
list.Add(Create());
|
||||
if (HasState(ObjectStatus.Alter))
|
||||
{
|
||||
list.Add(Drop());
|
||||
list.Add(Create());
|
||||
}
|
||||
if (Status == ObjectStatus.Disabled)
|
||||
{
|
||||
list.Add(ToSqlEnabled(), Parent.DependenciesCount, ScriptAction.AlterIndex);
|
||||
}
|
||||
/*if (this.Status == StatusEnum.ObjectStatusType.ChangeFileGroup)
|
||||
{
|
||||
listDiff.Add(this.ToSQLDrop(this.FileGroup), ((Table)Parent).DependenciesCount, StatusEnum.ScripActionType.DropIndex);
|
||||
listDiff.Add(this.ToSQLAdd(), ((Table)Parent).DependenciesCount, StatusEnum.ScripActionType.AddIndex);
|
||||
}*/
|
||||
list.AddRange(ExtendedProperties.ToSqlDiff());
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
72
OpenDBDiff.Schema.SQLServer.Generates/Model/IndexColumn.cs
Normal file
72
OpenDBDiff.Schema.SQLServer.Generates/Model/IndexColumn.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class IndexColumn : SQLServerSchemaBase, IComparable<IndexColumn>
|
||||
{
|
||||
public IndexColumn(ISchemaBase parentObject)
|
||||
: base(parentObject, ObjectType.IndexColumn)
|
||||
{
|
||||
}
|
||||
|
||||
public new IndexColumn Clone(ISchemaBase parent)
|
||||
{
|
||||
IndexColumn column = new IndexColumn(parent);
|
||||
column.Id = this.Id;
|
||||
column.IsIncluded = this.IsIncluded;
|
||||
column.Name = this.Name;
|
||||
column.Order = this.Order;
|
||||
column.Status = this.Status;
|
||||
column.KeyOrder = this.KeyOrder;
|
||||
column.DataTypeId = this.DataTypeId;
|
||||
return column;
|
||||
}
|
||||
|
||||
public int DataTypeId { get; set; }
|
||||
|
||||
public int KeyOrder { get; set; }
|
||||
|
||||
public Boolean IsIncluded { get; set; }
|
||||
|
||||
public Boolean Order { get; set; }
|
||||
|
||||
public static Boolean Compare(IndexColumn origin, IndexColumn destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.IsIncluded != destination.IsIncluded) return false;
|
||||
if (origin.Order != destination.Order) return false;
|
||||
if (origin.KeyOrder != destination.KeyOrder) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToSqlDrop()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public override string ToSqlAdd()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public override string ToSql()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public int CompareTo(IndexColumn other)
|
||||
{
|
||||
/*if (other.Name.Equals(this.Name))
|
||||
{*/
|
||||
if (other.IsIncluded == this.IsIncluded)
|
||||
return this.KeyOrder.CompareTo(other.KeyOrder);
|
||||
else
|
||||
return other.IsIncluded.CompareTo(this.IsIncluded);
|
||||
/*}
|
||||
else
|
||||
return this.Name.CompareTo(other.Name);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
53
OpenDBDiff.Schema.SQLServer.Generates/Model/IndexColumns.cs
Normal file
53
OpenDBDiff.Schema.SQLServer.Generates/Model/IndexColumns.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class IndexColumns : SchemaList<IndexColumn, ISchemaBase>
|
||||
{
|
||||
public IndexColumns(ISchemaBase parent)
|
||||
: base(parent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clona el objeto ColumnConstraints en una nueva instancia.
|
||||
/// </summary>
|
||||
public IndexColumns Clone()
|
||||
{
|
||||
IndexColumns columns = new IndexColumns(Parent);
|
||||
for (int index = 0; index < this.Count; index++)
|
||||
{
|
||||
columns.Add(this[index].Clone(Parent));
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compara dos campos y devuelve true si son iguales, caso contrario, devuelve false.
|
||||
/// </summary>
|
||||
public static Boolean Compare(IndexColumns origin, IndexColumns destination)
|
||||
{
|
||||
if (destination == null) throw new ArgumentNullException("destination");
|
||||
if (origin == null) throw new ArgumentNullException("origin");
|
||||
if (origin.Count != destination.Count) return false;
|
||||
for (int j = 0; j < origin.Count; j++)
|
||||
{
|
||||
IndexColumn item = destination[origin[j].FullName];
|
||||
if (item == null)
|
||||
return false;
|
||||
else
|
||||
if (!IndexColumn.Compare(origin[j], item)) return false;
|
||||
}
|
||||
for (int j = 0; j < destination.Count; j++)
|
||||
{
|
||||
IndexColumn item = origin[destination[j].FullName];
|
||||
if (item == null)
|
||||
return false;
|
||||
else
|
||||
if (!IndexColumn.Compare(destination[j], item)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public interface ICode : ISchemaBase
|
||||
{
|
||||
SQLScriptList Rebuild();
|
||||
List<string> DependenciesIn { get; set; }
|
||||
List<string> DependenciesOut { get; set; }
|
||||
bool IsSchemaBinding { get; set; }
|
||||
string Text { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using OpenDBDiff.Schema.Model;
|
||||
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public interface ISQLServerSchemaBase
|
||||
{
|
||||
SchemaList<ExtendedProperty, ISchemaBase> ExtendedProperties { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace OpenDBDiff.Schema.SQLServer.Generates.Model
|
||||
{
|
||||
public class ObjectDependency
|
||||
{
|
||||
public ObjectDependency(string name, string Column, ObjectType type)
|
||||
{
|
||||
this.Name = name;
|
||||
this.ColumnName = Column;
|
||||
this.Type = type;
|
||||
}
|
||||
|
||||
public ObjectDependency(string name, string Column)
|
||||
{
|
||||
this.Name = name;
|
||||
this.ColumnName = Column;
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string ColumnName { get; set; }
|
||||
|
||||
public ObjectType Type { get; set; }
|
||||
|
||||
public bool IsCodeType
|
||||
{
|
||||
get { return ((Type == ObjectType.StoredProcedure) || (Type == ObjectType.Trigger) || (Type == ObjectType.View) || (Type == ObjectType.Function)); }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user