You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
8.6 KiB
216 lines
8.6 KiB
using OpenDBDiff.Abstractions.Schema;
|
|
using OpenDBDiff.Abstractions.Schema.Model;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace OpenDBDiff.SqlServer.Schema.Model
|
|
{
|
|
public class PartitionFunction : SQLServerSchemaBase
|
|
{
|
|
private const int IS_STRING = 0;
|
|
private const int IS_UNIQUE = 1;
|
|
private const int IS_DATE = 2;
|
|
private const int IS_NUMERIC = 3;
|
|
|
|
public PartitionFunction(ISchemaBase parent)
|
|
: base(parent, ObjectType.PartitionFunction)
|
|
{
|
|
Values = new List<string>();
|
|
}
|
|
|
|
public new PartitionFunction Clone(ISchemaBase parent)
|
|
{
|
|
PartitionFunction item = new PartitionFunction(parent);
|
|
item.Id = this.Id;
|
|
item.IsBoundaryRight = this.IsBoundaryRight;
|
|
item.Name = this.Name;
|
|
item.Precision = this.Precision;
|
|
item.Scale = this.Scale;
|
|
item.Size = this.Size;
|
|
item.Type = this.Type;
|
|
this.Values.ForEach(value => { item.Values.Add(value); });
|
|
return item;
|
|
}
|
|
|
|
public List<string> Values { get; set; }
|
|
|
|
public PartitionFunction Old { get; set; }
|
|
|
|
public int Precision { get; set; }
|
|
|
|
public int Scale { get; set; }
|
|
|
|
public int Size { get; set; }
|
|
|
|
public bool IsBoundaryRight { get; set; }
|
|
|
|
public string Type { get; set; }
|
|
|
|
private int ValueItem(string typeName)
|
|
{
|
|
if ((typeName.Equals("nchar") || typeName.Equals("nvarchar") || typeName.Equals("varchar") || typeName.Equals("char")))
|
|
return IS_STRING;
|
|
if (typeName.Equals("uniqueidentifier"))
|
|
return IS_UNIQUE;
|
|
if (typeName.Equals("datetime") || typeName.Equals("smalldatetime") || typeName.Equals("datetime2") || typeName.Equals("time") || typeName.Equals("datetimeoffset"))
|
|
return IS_DATE;
|
|
if (typeName.Equals("numeric") || typeName.Equals("decimal") || typeName.Equals("float") || typeName.Equals("real") || typeName.Equals("money") || typeName.Equals("smallmoney"))
|
|
return IS_NUMERIC;
|
|
|
|
return IS_NUMERIC;
|
|
}
|
|
|
|
public override string ToSql()
|
|
{
|
|
string sqltype = Type;
|
|
|
|
if (Type.Equals("binary") || Type.Equals("varbinary") || Type.Equals("varchar") || Type.Equals("char") || Type.Equals("nchar") || Type.Equals("nvarchar"))
|
|
{
|
|
if (Type.Equals("nchar") || Type.Equals("nvarchar"))
|
|
sqltype += " (" + (Size / 2).ToString(CultureInfo.InvariantCulture) + ")";
|
|
else
|
|
sqltype += " (" + Size.ToString(CultureInfo.InvariantCulture) + ")";
|
|
}
|
|
if (Type.Equals("numeric") || Type.Equals("decimal")) sqltype += " (" + Precision.ToString(CultureInfo.InvariantCulture) + "," + Scale.ToString(CultureInfo.InvariantCulture) + ")";
|
|
if (((Database)Parent).Info.Version >= DatabaseInfo.SQLServerVersion.SQLServer2008)
|
|
{
|
|
if (Type.Equals("datetime2") || Type.Equals("datetimeoffset") || Type.Equals("time")) sqltype += "(" + Scale.ToString(CultureInfo.InvariantCulture) + ")";
|
|
}
|
|
|
|
string sql = "CREATE PARTITION FUNCTION [" + Name + "](" + sqltype + ") AS RANGE\r\n ";
|
|
if (IsBoundaryRight)
|
|
sql += "RIGHT";
|
|
else
|
|
sql += "LEFT";
|
|
sql += " FOR VALUES (";
|
|
|
|
string sqlvalues = "";
|
|
int valueType = ValueItem(Type);
|
|
|
|
if (valueType == IS_STRING)
|
|
Values.ForEach(item => { sqlvalues += "N'" + item + "',"; });
|
|
else
|
|
if (valueType == IS_DATE)
|
|
Values.ForEach(item => { sqlvalues += "'" + DateTime.Parse(item).ToString("yyyyMMdd HH:mm:ss.fff") + "',"; });
|
|
else
|
|
if (valueType == IS_UNIQUE)
|
|
Values.ForEach(item => { sqlvalues += "'{" + item + "}',"; });
|
|
else
|
|
if (valueType == IS_NUMERIC)
|
|
Values.ForEach(item => { sqlvalues += item.Replace(",", ".") + ","; });
|
|
else
|
|
Values.ForEach(item => { sqlvalues += item + ","; });
|
|
sql += sqlvalues.Substring(0, sqlvalues.Length - 1) + ")";
|
|
|
|
return sql + "\r\nGO\r\n";
|
|
}
|
|
|
|
public override string ToSqlDrop()
|
|
{
|
|
return "DROP PARTITION FUNCTION [" + Name + "]\r\nGO\r\n";
|
|
}
|
|
|
|
public override string ToSqlAdd()
|
|
{
|
|
return ToSql();
|
|
}
|
|
|
|
public string ToSqlAlter()
|
|
{
|
|
StringBuilder sqlFinal = new StringBuilder();
|
|
string sql = "ALTER PARTITION FUNCTION [" + Name + "]()\r\n";
|
|
string sqlmergue = "";
|
|
string sqsplit = "";
|
|
IEnumerable<string> items = Old.Values.Except<string>(this.Values);
|
|
int valueType = ValueItem(Type);
|
|
foreach (var item in items)
|
|
{
|
|
sqlmergue = "MERGE RANGE (";
|
|
if (valueType == IS_STRING)
|
|
sqlmergue += "N'" + item + "'";
|
|
else
|
|
if (valueType == IS_DATE)
|
|
sqlmergue += "'" + DateTime.Parse(item).ToString("yyyyMMdd HH:mm:ss.fff") + "'";
|
|
else
|
|
if (valueType == IS_UNIQUE)
|
|
sqlmergue += "'{" + item + "}'";
|
|
else
|
|
if (valueType == IS_NUMERIC)
|
|
sqlmergue += item.Replace(",", ".");
|
|
else
|
|
sqlmergue += item;
|
|
sqlFinal.Append(sql + sqlmergue + ")\r\nGO\r\n");
|
|
}
|
|
IEnumerable<string> items2 = this.Values.Except<string>(this.Old.Values);
|
|
foreach (var item in items2)
|
|
{
|
|
sqsplit = "SPLIT RANGE (";
|
|
if (valueType == IS_STRING)
|
|
sqsplit += "N'" + item + "'";
|
|
else
|
|
if (valueType == IS_DATE)
|
|
sqsplit += "'" + DateTime.Parse(item).ToString("yyyyMMdd HH:mm:ss.fff") + "'";
|
|
else
|
|
if (valueType == IS_UNIQUE)
|
|
sqsplit += "'{" + item + "}'";
|
|
else
|
|
if (valueType == IS_NUMERIC)
|
|
sqsplit += item.Replace(",", ".");
|
|
else
|
|
sqsplit += item;
|
|
sqlFinal.Append(sql + sqsplit + ")\r\nGO\r\n");
|
|
}
|
|
return sqlFinal.ToString();
|
|
}
|
|
|
|
/// <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.DropPartitionFunction);
|
|
}
|
|
if (this.Status == ObjectStatus.Rebuild)
|
|
{
|
|
listDiff.Add(ToSqlDrop() + ToSqlAdd(), 0, ScriptAction.AlterPartitionFunction);
|
|
}
|
|
if (this.Status == ObjectStatus.Alter)
|
|
listDiff.Add(ToSqlAlter(), 0, ScriptAction.AlterPartitionFunction);
|
|
|
|
if (this.Status == ObjectStatus.Create)
|
|
{
|
|
listDiff.Add(ToSqlAdd(), 0, ScriptAction.AddPartitionFunction);
|
|
}
|
|
return listDiff;
|
|
}
|
|
|
|
public static Boolean Compare(PartitionFunction origin, PartitionFunction destination)
|
|
{
|
|
if (destination == null) throw new ArgumentNullException("destination");
|
|
if (origin == null) throw new ArgumentNullException("origin");
|
|
if (!origin.Type.Equals(destination.Type)) return false;
|
|
if (origin.Size != destination.Size) return false;
|
|
if (origin.Precision != destination.Precision) return false;
|
|
if (origin.Scale != destination.Scale) return false;
|
|
if (origin.IsBoundaryRight != destination.IsBoundaryRight) return false;
|
|
return true;
|
|
}
|
|
|
|
public static Boolean CompareValues(PartitionFunction origin, PartitionFunction destination)
|
|
{
|
|
if (destination == null) throw new ArgumentNullException("destination");
|
|
if (origin == null) throw new ArgumentNullException("origin");
|
|
if (origin.Values.Count != destination.Values.Count) return false;
|
|
if (origin.Values.Except(destination.Values).ToList().Count != 0) return false;
|
|
return true;
|
|
}
|
|
}
|
|
}
|