Refactoring database creation, adding sql syntax provider to account for differences in syntax between sql, ce and mysql.
Adding MySql unit test.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
internal class DbTypes<TSyntax>
|
||||
where TSyntax : ISqlSyntaxProvider
|
||||
{
|
||||
public DbType DbType;
|
||||
public string TextDefinition;
|
||||
public bool ShouldQuoteValue;
|
||||
public Dictionary<Type, string> ColumnTypeMap = new Dictionary<Type, string>();
|
||||
public Dictionary<Type, DbType> ColumnDbTypeMap = new Dictionary<Type, DbType>();
|
||||
|
||||
public void Set<T>(DbType dbType, string fieldDefinition)
|
||||
{
|
||||
DbType = dbType;
|
||||
TextDefinition = fieldDefinition;
|
||||
ShouldQuoteValue = fieldDefinition != "INTEGER"
|
||||
&& fieldDefinition != "BIGINT"
|
||||
&& fieldDefinition != "DOUBLE"
|
||||
&& fieldDefinition != "DECIMAL"
|
||||
&& fieldDefinition != "BOOL";
|
||||
|
||||
ColumnTypeMap[typeof(T)] = fieldDefinition;
|
||||
ColumnDbTypeMap[typeof(T)] = dbType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions
|
||||
{
|
||||
public class ColumnDefinition
|
||||
{
|
||||
public string ColumnName { get; set; }
|
||||
|
||||
public Type PropertyType { get; set; }
|
||||
public string DbType { get; set; }
|
||||
public int? DbTypeLength { get; set; }
|
||||
|
||||
public bool IsNullable { get; set; }
|
||||
|
||||
public bool IsPrimaryKey { get; set; }
|
||||
public bool IsPrimaryKeyIdentityColumn { get; set; }
|
||||
public bool IsPrimaryKeyClustered { get; set; }
|
||||
public string PrimaryKeyName { get; set; }
|
||||
public string PrimaryKeyColumns { get; set; }
|
||||
|
||||
public string ConstraintName { get; set; }
|
||||
public string ConstraintDefaultValue { get; set; }
|
||||
public bool HasConstraint
|
||||
{
|
||||
get { return !string.IsNullOrEmpty(ConstraintName) || !string.IsNullOrEmpty(ConstraintDefaultValue); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions
|
||||
{
|
||||
public static class DefinitionFactory
|
||||
{
|
||||
public static TableDefinition GetTableDefinition(Type modelType)
|
||||
{
|
||||
var tableNameAttribute = modelType.FirstAttribute<TableNameAttribute>();
|
||||
string tableName = tableNameAttribute.Value;
|
||||
|
||||
var tableDefinition = new TableDefinition { TableName = tableName };
|
||||
var objProperties = modelType.GetProperties().ToList();
|
||||
foreach (var propertyInfo in objProperties)
|
||||
{
|
||||
//If current property is a ResultColumn then skip it
|
||||
var resultColumnAttribute = propertyInfo.FirstAttribute<ResultColumnAttribute>();
|
||||
if (resultColumnAttribute != null) continue;
|
||||
|
||||
//Assumes ExplicitColumn attribute and thus having a ColumnAttribute with the name of the column
|
||||
var columnAttribute = propertyInfo.FirstAttribute<ColumnAttribute>();
|
||||
if (columnAttribute == null) continue;
|
||||
|
||||
//Creates a column definition and adds it to the collection on the table definition
|
||||
var columnDefinition = new ColumnDefinition
|
||||
{
|
||||
ColumnName = columnAttribute.Name,
|
||||
PropertyType = propertyInfo.PropertyType
|
||||
};
|
||||
|
||||
//Look for specific DbType attributed a column
|
||||
var databaseTypeAttribute = propertyInfo.FirstAttribute<DatabaseTypeAttribute>();
|
||||
if (databaseTypeAttribute != null)
|
||||
{
|
||||
columnDefinition.DbType = databaseTypeAttribute.DatabaseType.ToString();
|
||||
if (databaseTypeAttribute.Length > 0)
|
||||
columnDefinition.DbTypeLength = databaseTypeAttribute.Length;
|
||||
}
|
||||
|
||||
//Look for specific Null setting attributed a column
|
||||
var nullSettingAttribute = propertyInfo.FirstAttribute<NullSettingAttribute>();
|
||||
if (nullSettingAttribute != null)
|
||||
{
|
||||
columnDefinition.IsNullable = nullSettingAttribute.NullSetting == NullSettings.Null;
|
||||
}
|
||||
|
||||
//Look for Primary Key for the current column
|
||||
var primaryKeyColumnAttribute = propertyInfo.FirstAttribute<PrimaryKeyColumnAttribute>();
|
||||
if (primaryKeyColumnAttribute != null)
|
||||
{
|
||||
columnDefinition.IsPrimaryKey = true;
|
||||
columnDefinition.IsPrimaryKeyIdentityColumn = primaryKeyColumnAttribute.AutoIncrement;
|
||||
columnDefinition.IsPrimaryKeyClustered = primaryKeyColumnAttribute.Clustered;
|
||||
columnDefinition.PrimaryKeyName = primaryKeyColumnAttribute.Name ?? string.Empty;
|
||||
columnDefinition.PrimaryKeyColumns = primaryKeyColumnAttribute.OnColumns ?? string.Empty;
|
||||
}
|
||||
|
||||
//Look for Constraint for the current column
|
||||
var constraintAttribute = propertyInfo.FirstAttribute<ConstraintAttribute>();
|
||||
if (constraintAttribute != null)
|
||||
{
|
||||
columnDefinition.ConstraintName = constraintAttribute.Name ?? string.Empty;
|
||||
columnDefinition.ConstraintDefaultValue = constraintAttribute.Default ?? string.Empty;
|
||||
}
|
||||
|
||||
tableDefinition.ColumnDefinitions.Add(columnDefinition);
|
||||
|
||||
//Creates a foreignkey definition and adds it to the collection on the table definition
|
||||
var foreignKeyAttributes = propertyInfo.MultipleAttribute<ForeignKeyAttribute>();
|
||||
if (foreignKeyAttributes != null)
|
||||
{
|
||||
foreach (var foreignKeyAttribute in foreignKeyAttributes)
|
||||
{
|
||||
var referencedTable = foreignKeyAttribute.Type.FirstAttribute<TableNameAttribute>();
|
||||
var referencedPrimaryKey = foreignKeyAttribute.Type.FirstAttribute<PrimaryKeyAttribute>();
|
||||
|
||||
string referencedColumn = string.IsNullOrEmpty(foreignKeyAttribute.Column)
|
||||
? referencedPrimaryKey.Value
|
||||
: foreignKeyAttribute.Column;
|
||||
|
||||
var foreignKeyDefinition = new ForeignKeyDefinition
|
||||
{
|
||||
ColumnName = columnAttribute.Name,
|
||||
ConstraintName = foreignKeyAttribute.Name,
|
||||
ReferencedColumnName = referencedColumn,
|
||||
ReferencedTableName = referencedTable.Value
|
||||
};
|
||||
tableDefinition.ForeignKeyDefinitions.Add(foreignKeyDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
//Creates an index definition and adds it to the collection on the table definition
|
||||
var indexAttribute = propertyInfo.FirstAttribute<IndexAttribute>();
|
||||
if (indexAttribute != null)
|
||||
{
|
||||
var indexDefinition = new IndexDefinition
|
||||
{
|
||||
ColumnNames = indexAttribute.ForColumns,
|
||||
IndexName = indexAttribute.Name,
|
||||
IndexType = indexAttribute.IndexType,
|
||||
IndexForColumn = columnAttribute.Name
|
||||
};
|
||||
tableDefinition.IndexDefinitions.Add(indexDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
return tableDefinition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions
|
||||
{
|
||||
public class ForeignKeyDefinition
|
||||
{
|
||||
public string ConstraintName { get; set; }
|
||||
public string ColumnName { get; set; }
|
||||
public string ReferencedTableName { get; set; }
|
||||
public string ReferencedColumnName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions
|
||||
{
|
||||
public class IndexDefinition
|
||||
{
|
||||
public string IndexName { get; set; }
|
||||
public IndexTypes IndexType { get; set; }
|
||||
public string ColumnNames { get; set; }
|
||||
public string IndexForColumn { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions
|
||||
{
|
||||
public class TableDefinition
|
||||
{
|
||||
public TableDefinition()
|
||||
{
|
||||
ColumnDefinitions = new List<ColumnDefinition>();
|
||||
ForeignKeyDefinitions = new List<ForeignKeyDefinition>();
|
||||
IndexDefinitions = new List<IndexDefinition>();
|
||||
}
|
||||
|
||||
public string TableName { get; set; }
|
||||
public bool IsPrimaryKeyClustered
|
||||
{
|
||||
get { return ColumnDefinitions.Any(x => x.IsPrimaryKeyClustered); }
|
||||
}
|
||||
public string PrimaryKeyName
|
||||
{
|
||||
get { return ColumnDefinitions.First(x => x.IsPrimaryKey).PrimaryKeyName ?? string.Empty; }
|
||||
}
|
||||
public string PrimaryKeyColumns
|
||||
{
|
||||
get { return ColumnDefinitions.First(x => x.IsPrimaryKey).PrimaryKeyColumns ?? string.Empty; }
|
||||
}
|
||||
|
||||
public List<ColumnDefinition> ColumnDefinitions { get; set; }
|
||||
public List<ForeignKeyDefinition> ForeignKeyDefinitions { get; set; }
|
||||
public List<IndexDefinition> IndexDefinitions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
internal static class MySqlSyntax
|
||||
{
|
||||
public static ISqlSyntaxProvider Provider { get { return MySqlSyntaxProvider.Instance; } }
|
||||
}
|
||||
|
||||
internal class MySqlSyntaxProvider : SqlSyntaxProviderBase<MySqlSyntaxProvider>
|
||||
{
|
||||
public static MySqlSyntaxProvider Instance = new MySqlSyntaxProvider();
|
||||
|
||||
private MySqlSyntaxProvider()
|
||||
{
|
||||
AutoIncrementDefinition = "AUTO_INCREMENT";
|
||||
IntColumnDefinition = "int(11)";
|
||||
BoolColumnDefinition = "tinyint(1)";
|
||||
TimeColumnDefinition = "time";
|
||||
DecimalColumnDefinition = "decimal(38,6)";
|
||||
GuidColumnDefinition = "char(32)";
|
||||
DefaultStringLength = 255;
|
||||
|
||||
InitColumnTypeMap();
|
||||
|
||||
DefaultValueFormat = " DEFAULT '{0}'";
|
||||
}
|
||||
|
||||
public override string GetQuotedTableName(string tableName)
|
||||
{
|
||||
return string.Format("`{0}`", tableName);
|
||||
}
|
||||
|
||||
public override string GetQuotedColumnName(string columnName)
|
||||
{
|
||||
return string.Format("`{0}`", columnName);
|
||||
}
|
||||
|
||||
public override string GetQuotedName(string name)
|
||||
{
|
||||
return string.Format("`{0}`", name);
|
||||
}
|
||||
|
||||
public override bool DoesTableExist(Database db, string tableName)
|
||||
{
|
||||
var result =
|
||||
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " +
|
||||
"WHERE TABLE_NAME = @TableName AND " +
|
||||
"TABLE_SCHEMA = @TableSchema", new { TableName = tableName, TableSchema = db.Connection.Database });
|
||||
|
||||
return result > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
internal class SqlCeSyntaxProvider : SqlSyntaxProviderBase<SqlCeSyntaxProvider>
|
||||
{
|
||||
public static SqlCeSyntaxProvider Instance = new SqlCeSyntaxProvider();
|
||||
|
||||
private SqlCeSyntaxProvider()
|
||||
{
|
||||
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
|
||||
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
|
||||
|
||||
AutoIncrementDefinition = "IDENTITY(1,1)";
|
||||
StringColumnDefinition = "NVARCHAR(255)";
|
||||
GuidColumnDefinition = "UniqueIdentifier";
|
||||
RealColumnDefinition = "FLOAT";
|
||||
BoolColumnDefinition = "BIT";
|
||||
DecimalColumnDefinition = "DECIMAL(38,6)";
|
||||
TimeColumnDefinition = "TIME"; //SQLSERVER 2008+
|
||||
BlobColumnDefinition = "VARBINARY(MAX)";
|
||||
|
||||
InitColumnTypeMap();
|
||||
}
|
||||
|
||||
public override string GetQuotedTableName(string tableName)
|
||||
{
|
||||
return string.Format("[{0}]", tableName);
|
||||
}
|
||||
|
||||
public override string GetQuotedColumnName(string columnName)
|
||||
{
|
||||
return string.Format("[{0}]", columnName);
|
||||
}
|
||||
|
||||
public override string GetQuotedName(string name)
|
||||
{
|
||||
return string.Format("[{0}]", name);
|
||||
}
|
||||
|
||||
public override string GetPrimaryKeyStatement(ColumnDefinition column, string tableName)
|
||||
{
|
||||
string constraintName = string.IsNullOrEmpty(column.PrimaryKeyName)
|
||||
? string.Format("PK_{0}", tableName)
|
||||
: column.PrimaryKeyName;
|
||||
|
||||
string columns = string.IsNullOrEmpty(column.PrimaryKeyColumns)
|
||||
? GetQuotedColumnName(column.ColumnName)
|
||||
: column.PrimaryKeyColumns;
|
||||
|
||||
string sql = string.Format("ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY ({2}); \n",
|
||||
GetQuotedTableName(tableName),
|
||||
GetQuotedName(constraintName),
|
||||
columns);
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
public override bool DoesTableExist(Database db, string tableName)
|
||||
{
|
||||
var result =
|
||||
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName",
|
||||
new { TableName = tableName });
|
||||
|
||||
return result > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
internal class SqlServerSyntaxProvider : SqlSyntaxProviderBase<SqlServerSyntaxProvider>
|
||||
{
|
||||
public static SqlServerSyntaxProvider Instance = new SqlServerSyntaxProvider();
|
||||
|
||||
private SqlServerSyntaxProvider()
|
||||
{
|
||||
StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat;
|
||||
StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength);
|
||||
|
||||
AutoIncrementDefinition = "IDENTITY(1,1)";
|
||||
StringColumnDefinition = "VARCHAR(8000)";
|
||||
GuidColumnDefinition = "UniqueIdentifier";
|
||||
RealColumnDefinition = "FLOAT";
|
||||
BoolColumnDefinition = "BIT";
|
||||
DecimalColumnDefinition = "DECIMAL(38,6)";
|
||||
TimeColumnDefinition = "TIME"; //SQLSERVER 2008+
|
||||
BlobColumnDefinition = "VARBINARY(MAX)";
|
||||
|
||||
InitColumnTypeMap();
|
||||
}
|
||||
|
||||
public override bool DoesTableExist(Database db, string tableName)
|
||||
{
|
||||
var result =
|
||||
db.ExecuteScalar<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName",
|
||||
new { TableName = tableName });
|
||||
|
||||
return result > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
public interface ISqlSyntaxProvider
|
||||
{
|
||||
string GetQuotedTableName(string tableName);
|
||||
string GetQuotedColumnName(string columnName);
|
||||
string GetQuotedName(string name);
|
||||
bool DoesTableExist(Database db, string tableName);
|
||||
string ToCreateTableStatement(TableDefinition tableDefinition);
|
||||
List<string> ToCreateForeignKeyStatements(TableDefinition tableDefinition);
|
||||
List<string> ToCreateIndexStatements(TableDefinition tableDefinition);
|
||||
DbType GetColumnDbType(Type valueType);
|
||||
string GetIndexType(IndexTypes indexTypes);
|
||||
string GetColumnDefinition(ColumnDefinition column, string tableName);
|
||||
string GetPrimaryKeyStatement(ColumnDefinition column, string tableName);
|
||||
string ToCreatePrimaryKeyStatement(TableDefinition table);
|
||||
}
|
||||
|
||||
internal abstract class SqlSyntaxProviderBase<TSyntax> : ISqlSyntaxProvider
|
||||
where TSyntax : ISqlSyntaxProvider
|
||||
{
|
||||
public string StringLengthNonUnicodeColumnDefinitionFormat = "VARCHAR({0})";
|
||||
public string StringLengthUnicodeColumnDefinitionFormat = "NVARCHAR({0})";
|
||||
|
||||
public string DefaultValueFormat = " DEFAULT ({0})";
|
||||
public int DefaultStringLength = 255;
|
||||
|
||||
//Set by Constructor
|
||||
public string StringColumnDefinition;
|
||||
public string StringLengthColumnDefinitionFormat;
|
||||
|
||||
public string AutoIncrementDefinition = "AUTOINCREMENT";
|
||||
public string IntColumnDefinition = "INTEGER";
|
||||
public string LongColumnDefinition = "BIGINT";
|
||||
public string GuidColumnDefinition = "GUID";
|
||||
public string BoolColumnDefinition = "BOOL";
|
||||
public string RealColumnDefinition = "DOUBLE";
|
||||
public string DecimalColumnDefinition = "DECIMAL";
|
||||
public string BlobColumnDefinition = "BLOB";
|
||||
public string DateTimeColumnDefinition = "DATETIME";
|
||||
public string TimeColumnDefinition = "DATETIME";
|
||||
|
||||
protected DbTypes<TSyntax> DbTypeMap = new DbTypes<TSyntax>();
|
||||
protected void InitColumnTypeMap()
|
||||
{
|
||||
DbTypeMap.Set<string>(DbType.String, StringColumnDefinition);
|
||||
DbTypeMap.Set<char>(DbType.StringFixedLength, StringColumnDefinition);
|
||||
DbTypeMap.Set<char?>(DbType.StringFixedLength, StringColumnDefinition);
|
||||
DbTypeMap.Set<char[]>(DbType.String, StringColumnDefinition);
|
||||
DbTypeMap.Set<bool>(DbType.Boolean, BoolColumnDefinition);
|
||||
DbTypeMap.Set<bool?>(DbType.Boolean, BoolColumnDefinition);
|
||||
DbTypeMap.Set<Guid>(DbType.Guid, GuidColumnDefinition);
|
||||
DbTypeMap.Set<Guid?>(DbType.Guid, GuidColumnDefinition);
|
||||
DbTypeMap.Set<DateTime>(DbType.DateTime, DateTimeColumnDefinition);
|
||||
DbTypeMap.Set<DateTime?>(DbType.DateTime, DateTimeColumnDefinition);
|
||||
DbTypeMap.Set<TimeSpan>(DbType.Time, TimeColumnDefinition);
|
||||
DbTypeMap.Set<TimeSpan?>(DbType.Time, TimeColumnDefinition);
|
||||
DbTypeMap.Set<DateTimeOffset>(DbType.Time, TimeColumnDefinition);
|
||||
DbTypeMap.Set<DateTimeOffset?>(DbType.Time, TimeColumnDefinition);
|
||||
|
||||
DbTypeMap.Set<byte>(DbType.Byte, IntColumnDefinition);
|
||||
DbTypeMap.Set<byte?>(DbType.Byte, IntColumnDefinition);
|
||||
DbTypeMap.Set<sbyte>(DbType.SByte, IntColumnDefinition);
|
||||
DbTypeMap.Set<sbyte?>(DbType.SByte, IntColumnDefinition);
|
||||
DbTypeMap.Set<short>(DbType.Int16, IntColumnDefinition);
|
||||
DbTypeMap.Set<short?>(DbType.Int16, IntColumnDefinition);
|
||||
DbTypeMap.Set<ushort>(DbType.UInt16, IntColumnDefinition);
|
||||
DbTypeMap.Set<ushort?>(DbType.UInt16, IntColumnDefinition);
|
||||
DbTypeMap.Set<int>(DbType.Int32, IntColumnDefinition);
|
||||
DbTypeMap.Set<int?>(DbType.Int32, IntColumnDefinition);
|
||||
DbTypeMap.Set<uint>(DbType.UInt32, IntColumnDefinition);
|
||||
DbTypeMap.Set<uint?>(DbType.UInt32, IntColumnDefinition);
|
||||
|
||||
DbTypeMap.Set<long>(DbType.Int64, LongColumnDefinition);
|
||||
DbTypeMap.Set<long?>(DbType.Int64, LongColumnDefinition);
|
||||
DbTypeMap.Set<ulong>(DbType.UInt64, LongColumnDefinition);
|
||||
DbTypeMap.Set<ulong?>(DbType.UInt64, LongColumnDefinition);
|
||||
|
||||
DbTypeMap.Set<float>(DbType.Single, RealColumnDefinition);
|
||||
DbTypeMap.Set<float?>(DbType.Single, RealColumnDefinition);
|
||||
DbTypeMap.Set<double>(DbType.Double, RealColumnDefinition);
|
||||
DbTypeMap.Set<double?>(DbType.Double, RealColumnDefinition);
|
||||
|
||||
DbTypeMap.Set<decimal>(DbType.Decimal, DecimalColumnDefinition);
|
||||
DbTypeMap.Set<decimal?>(DbType.Decimal, DecimalColumnDefinition);
|
||||
|
||||
DbTypeMap.Set<byte[]>(DbType.Binary, BlobColumnDefinition);
|
||||
}
|
||||
|
||||
public virtual string GetQuotedTableName(string tableName)
|
||||
{
|
||||
return string.Format("\"{0}\"", tableName);
|
||||
}
|
||||
|
||||
public virtual string GetQuotedColumnName(string columnName)
|
||||
{
|
||||
return string.Format("\"{0}\"", columnName);
|
||||
}
|
||||
|
||||
public virtual string GetQuotedName(string name)
|
||||
{
|
||||
return string.Format("\"{0}\"", name);
|
||||
}
|
||||
|
||||
public virtual string GetIndexType(IndexTypes indexTypes)
|
||||
{
|
||||
string indexType;
|
||||
|
||||
if (indexTypes == IndexTypes.Clustered)
|
||||
{
|
||||
indexType = "CLUSTERED";
|
||||
}
|
||||
else
|
||||
{
|
||||
indexType = indexTypes == IndexTypes.NonClustered
|
||||
? "NONCLUSTERED"
|
||||
: "UNIQUE NONCLUSTERED";
|
||||
}
|
||||
return indexType;
|
||||
}
|
||||
|
||||
public virtual string GetColumnDefinition(ColumnDefinition column, string tableName)
|
||||
{
|
||||
string dbTypeDefinition;
|
||||
if(!string.IsNullOrEmpty(column.DbType))
|
||||
{
|
||||
dbTypeDefinition = column.DbType;//Translate
|
||||
if (column.DbTypeLength.HasValue)
|
||||
dbTypeDefinition = string.Format("{0}({1})", column.DbType, column.DbTypeLength.Value);
|
||||
}
|
||||
else if (column.PropertyType == typeof(string))
|
||||
{
|
||||
dbTypeDefinition = string.Format(StringLengthColumnDefinitionFormat, column.DbTypeLength.GetValueOrDefault(DefaultStringLength));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!DbTypeMap.ColumnTypeMap.TryGetValue(column.PropertyType, out dbTypeDefinition))
|
||||
{
|
||||
dbTypeDefinition = "";
|
||||
}
|
||||
}
|
||||
|
||||
var sql = new StringBuilder();
|
||||
sql.AppendFormat("{0} {1}", GetQuotedColumnName(column.ColumnName), dbTypeDefinition);
|
||||
|
||||
if (column.IsPrimaryKeyIdentityColumn)
|
||||
{
|
||||
sql.Append(" NOT NULL ").Append(AutoIncrementDefinition);
|
||||
}
|
||||
else
|
||||
{
|
||||
sql.Append(column.IsNullable ? " NULL" : " NOT NULL");
|
||||
}
|
||||
|
||||
if(column.HasConstraint)
|
||||
{
|
||||
sql.AppendFormat(" CONSTRAINT {0}",
|
||||
string.IsNullOrEmpty(column.ConstraintName)
|
||||
? GetQuotedName(string.Format("DF_{0}_{1}", tableName, column.ColumnName))
|
||||
: column.ConstraintName);
|
||||
|
||||
sql.AppendFormat(DefaultValueFormat, column.ConstraintDefaultValue);
|
||||
}
|
||||
|
||||
return sql.ToString();
|
||||
}
|
||||
|
||||
public virtual string GetPrimaryKeyStatement(ColumnDefinition column, string tableName)
|
||||
{
|
||||
string constraintName = string.IsNullOrEmpty(column.PrimaryKeyName)
|
||||
? string.Format("PK_{0}", tableName)
|
||||
: column.PrimaryKeyName;
|
||||
|
||||
string columns = string.IsNullOrEmpty(column.PrimaryKeyColumns)
|
||||
? GetQuotedColumnName(column.ColumnName)
|
||||
: column.PrimaryKeyColumns;
|
||||
|
||||
string sql = string.Format("ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY {2} ({3}); \n",
|
||||
GetQuotedTableName(tableName),
|
||||
GetQuotedName(constraintName),
|
||||
column.IsPrimaryKeyClustered ? "CLUSTERED" : "NONCLUSTERED",
|
||||
columns);
|
||||
return sql;
|
||||
}
|
||||
|
||||
public virtual string ToCreateTableStatement(TableDefinition table)
|
||||
{
|
||||
var columns = new StringBuilder();
|
||||
|
||||
foreach (var column in table.ColumnDefinitions)
|
||||
{
|
||||
columns.Append(GetColumnDefinition(column, table.TableName) + ", \n");
|
||||
}
|
||||
|
||||
string sql = string.Format("CREATE TABLE {0} \n(\n {1} \n); \n",
|
||||
table.TableName,
|
||||
columns.ToString().TrimEnd(", \n".ToCharArray()));
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
public virtual string ToCreatePrimaryKeyStatement(TableDefinition table)
|
||||
{
|
||||
var columnDefinition = table.ColumnDefinitions.FirstOrDefault(x => x.IsPrimaryKey);
|
||||
if (columnDefinition == null)
|
||||
return string.Empty;
|
||||
|
||||
var sql = GetPrimaryKeyStatement(columnDefinition, table.TableName);
|
||||
return sql;
|
||||
}
|
||||
|
||||
public virtual List<string> ToCreateForeignKeyStatements(TableDefinition table)
|
||||
{
|
||||
var foreignKeys = new List<string>();
|
||||
|
||||
foreach (var key in table.ForeignKeyDefinitions)
|
||||
{
|
||||
string constraintName = string.IsNullOrEmpty(key.ConstraintName)
|
||||
? string.Format("FK_{0}_{1}_{2}", table.TableName, key.ReferencedTableName, key.ReferencedColumnName)
|
||||
: key.ConstraintName;
|
||||
|
||||
foreignKeys.Add(string.Format("ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}); \n",
|
||||
GetQuotedTableName(table.TableName),
|
||||
GetQuotedName(constraintName),
|
||||
GetQuotedColumnName(key.ColumnName),
|
||||
GetQuotedTableName(key.ReferencedTableName),
|
||||
GetQuotedColumnName(key.ReferencedColumnName)));
|
||||
}
|
||||
|
||||
return foreignKeys;
|
||||
}
|
||||
|
||||
public virtual List<string> ToCreateIndexStatements(TableDefinition table)
|
||||
{
|
||||
var indexes = new List<string>();
|
||||
|
||||
foreach (var index in table.IndexDefinitions)
|
||||
{
|
||||
string name = string.IsNullOrEmpty(index.IndexName)
|
||||
? string.Format("IX_{0}_{1}", table.TableName, index.IndexForColumn)
|
||||
: index.IndexName;
|
||||
|
||||
string columns = string.IsNullOrEmpty(index.ColumnNames)
|
||||
? GetQuotedColumnName(index.IndexForColumn)
|
||||
: index.ColumnNames;
|
||||
|
||||
indexes.Add(string.Format("CREATE {0} INDEX {1} ON {2} ({3}); \n",
|
||||
GetIndexType(index.IndexType),
|
||||
GetQuotedName(name),
|
||||
GetQuotedTableName(table.TableName),
|
||||
columns));
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
public virtual bool DoesTableExist(Database db, string tableName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual DbType GetColumnDbType(Type valueType)
|
||||
{
|
||||
if (valueType.IsEnum)
|
||||
return DbTypeMap.ColumnDbTypeMap[typeof(string)];
|
||||
|
||||
return DbTypeMap.ColumnDbTypeMap[valueType];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
internal static class SyntaxConfig
|
||||
{
|
||||
private static ISqlSyntaxProvider _sqlSyntaxProvider;
|
||||
|
||||
public static ISqlSyntaxProvider SqlSyntaxProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_sqlSyntaxProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException("SqlSyntaxProvider",
|
||||
"You must set the singleton 'Umbraco.Core.Persistence.SqlSyntax.SyntaxConfig' to use an sql syntax provider");
|
||||
}
|
||||
return _sqlSyntaxProvider;
|
||||
}
|
||||
set { _sqlSyntaxProvider = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user