diff --git a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs index 2d7bc6dd63..4ad49bc367 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentDto.cs @@ -1,4 +1,5 @@ using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { @@ -8,12 +9,21 @@ namespace Umbraco.Core.Models.Rdbms internal class ContentDto { [Column("pk")] + [PrimaryKeyColumn] + [DatabaseType(DatabaseTypes.Integer)] + [NullSetting(NullSetting = NullSettings.Null)] public int PrimaryKey { get; set; } [Column("nodeId")] + [ForeignKey(typeof(NodeDto))] + [DatabaseType(DatabaseTypes.Integer)] + [NullSetting(NullSetting = NullSettings.Null)] + [Index(IndexTypes.UniqueNonclustered, Name = "IX_cmsContent")] public int NodeId { get; set; } [Column("contentType")] + [DatabaseType(DatabaseTypes.Integer)] + [NullSetting(NullSetting = NullSettings.Null)] public int ContentType { get; set; } [ResultColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs index b90f09b7eb..c3f30a640d 100644 --- a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs @@ -1,5 +1,6 @@ using System; using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Models.Rdbms { @@ -9,36 +10,64 @@ namespace Umbraco.Core.Models.Rdbms internal class NodeDto { [Column("id")] + [PrimaryKeyColumn(Name = "PK_structure")] + [DatabaseType(DatabaseTypes.Integer)] + [NullSetting(NullSetting = NullSettings.NotNull)] public int NodeId { get; set; } [Column("trashed")] + [DatabaseType(DatabaseTypes.Bool)] + [NullSetting(NullSetting = NullSettings.NotNull)] + [Constraint(Default = "0")] public bool Trashed { get; set; } [Column("parentID")] + [DatabaseType(DatabaseTypes.Integer)] + [NullSetting(NullSetting = NullSettings.NotNull)] + [ForeignKey(typeof(NodeDto))] + [IndexAttribute(IndexTypes.Nonclustered, Name = "IX_umbracoNodeParentId")] public int ParentId { get; set; } [Column("nodeUser")] + [DatabaseType(DatabaseTypes.Integer)] + [NullSetting(NullSetting = NullSettings.Null)] public int? UserId { get; set; } [Column("level")] + [DatabaseType(DatabaseTypes.SmallInteger)] + [NullSetting(NullSetting = NullSettings.NotNull)] public short Level { get; set; } [Column("path")] + [DatabaseType(DatabaseTypes.Nvarchar, Length = 150)] + [NullSetting(NullSetting = NullSettings.NotNull)] public string Path { get; set; } [Column("sortOrder")] + [DatabaseType(DatabaseTypes.Integer)] + [NullSetting(NullSetting = NullSettings.NotNull)] public int SortOrder { get; set; } [Column("uniqueID")] + [DatabaseType(DatabaseTypes.UniqueIdentifier)] + [NullSetting(NullSetting = NullSettings.Null)] public Guid? UniqueId { get; set; } [Column("text")] + [DatabaseType(DatabaseTypes.Nvarchar, Length = 255)] + [NullSetting(NullSetting = NullSettings.Null)] public string Text { get; set; } [Column("nodeObjectType")] + [DatabaseType(DatabaseTypes.UniqueIdentifier)] + [NullSetting(NullSetting = NullSettings.Null)] + [IndexAttribute(IndexTypes.Nonclustered, Name = "IX_umbracoNodeObjectType")] public Guid? NodeObjectType { get; set; } [Column("createDate")] + [DatabaseType(DatabaseTypes.DateTime)] + [NullSetting(NullSetting = NullSettings.NotNull)] + [Constraint(Default = "getdate()")] public DateTime CreateDate { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/AttributeExtensions.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/AttributeExtensions.cs new file mode 100644 index 0000000000..7e662a28f4 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/AttributeExtensions.cs @@ -0,0 +1,111 @@ +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + public static class AttributeExtensions + { + public static string ToSqlSyntax(this NullSettingAttribute attribute) + { + return attribute.NullSetting == NullSettings.Null ? "NULL" : "NOT NULL"; + } + + public static string ToSqlSyntax(this DatabaseTypeAttribute attribute) + { + string syntax = string.Empty; + switch (attribute.DatabaseType) + { + case DatabaseTypes.Bool: + syntax = "[bit]"; + break; + case DatabaseTypes.Ntext: + syntax = "[ntext]"; + break; + case DatabaseTypes.DateTime: + syntax = "[datetime]"; + break; + case DatabaseTypes.UniqueIdentifier: + syntax = "[uniqueidentifier]"; + break; + case DatabaseTypes.SmallInteger: + syntax = "[smallint]"; + break; + case DatabaseTypes.Integer: + syntax = "[int]"; + break; + case DatabaseTypes.Nvarchar: + syntax = "[nvarchar]"; + if (attribute.Length > 0) + syntax += string.Format(" ({0})", attribute.Length); + break; + } + return syntax; + } + + public static string ToSqlSyntax(this PrimaryKeyColumnAttribute attribute) + { + string syntax = string.Empty; + + if (attribute.AutoIncrement) + syntax = "IDENTITY(1, 1)"; + + return syntax; + } + + public static string ToSqlSyntax(this PrimaryKeyColumnAttribute attribute, string tableName, string propertyName) + { + string constraintName = string.IsNullOrEmpty(attribute.Name) ? string.Format("PK_{0}", tableName) : attribute.Name; + string clustered = attribute.Clustered ? "CLUSTERED" : "NONCLUSTERED"; + string syntax = string.Format("ALTER TABLE [{0}] ADD CONSTRAINT [{1}] PRIMARY KEY {2} ([{3}])", tableName, + constraintName, clustered, propertyName); + + return syntax; + } + + public static string ToSqlSyntax(this ConstraintAttribute attribute, string tableName, string propertyName) + { + if (!string.IsNullOrEmpty(attribute.Name)) + return attribute.Name; + + return string.Format("CONSTRAINT [DF_{0}_{1}] DEFAULT ({2})", tableName, propertyName, attribute.Default); + } + + public static string ToSqlSyntax(this ForeignKeyAttribute attribute, string tableName, string propertyName) + { + var tableNameAttribute = attribute.Type.FirstAttribute(); + var primaryKeyAttribute = attribute.Type.FirstAttribute(); + var referencedTableName = tableNameAttribute.Value; + + string constraintName = string.Format("FK_{0}_{1}", tableName, referencedTableName); + string syntax = + string.Format( + "ALTER TABLE [{0}] ADD CONSTRAINT [{1}] FOREIGN KEY ([{2}]) REFERENCES [{3}] ([{4}])", + tableName, constraintName, propertyName, referencedTableName, primaryKeyAttribute.Value); + return syntax; + } + + public static string ToSqlSyntax(this IndexAttribute attribute, string tableName, string propertyName) + { + string indexType = string.Empty; + + switch (attribute.IndexType) + { + case IndexTypes.Clustered: + indexType = "CLUSTERED"; + break; + case IndexTypes.Nonclustered: + indexType = "NONCLUSTERED"; + break; + case IndexTypes.PrimaryXml: + indexType = "PRIMARYXML"; + break; + case IndexTypes.Spartial: + indexType = "SPARTIAL"; + break; + case IndexTypes.UniqueNonclustered: + indexType = "UNIQUENONCLUSTERED"; + break; + } + string name = string.IsNullOrEmpty(attribute.Name) ? string.Format("IX_{0}_{1}", tableName, propertyName) : attribute.Name; + string syntax = string.Format("CREATE {0} INDEX [{1}] ON [{2}] ([{3}])", indexType, name, tableName, propertyName); + return syntax; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/ConstraintAttribute.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/ConstraintAttribute.cs new file mode 100644 index 0000000000..f8a7ff7268 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/ConstraintAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + [AttributeUsage(AttributeTargets.Property)] + public class ConstraintAttribute : Attribute + { + /// + /// Overrides the default naming of a property constraint: + /// DF_tableName_propertyName + /// + public string Name { get; set; } + + public string Default { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypeAttribute.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypeAttribute.cs new file mode 100644 index 0000000000..1c012b3853 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypeAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + [AttributeUsage(AttributeTargets.Property)] + public class DatabaseTypeAttribute : Attribute + { + public DatabaseTypeAttribute(DatabaseTypes databaseType) + { + DatabaseType = databaseType; + } + + public DatabaseTypes DatabaseType { get; private set; } + public int Length { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypes.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypes.cs new file mode 100644 index 0000000000..8e7a9b580b --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypes.cs @@ -0,0 +1,13 @@ +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + public enum DatabaseTypes + { + Integer, + SmallInteger, + UniqueIdentifier, + DateTime, + Ntext, + Nvarchar, + Bool + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/ForeignKeyAttribute.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/ForeignKeyAttribute.cs new file mode 100644 index 0000000000..5796826016 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/ForeignKeyAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + [AttributeUsage(AttributeTargets.Property)] + public class ForeignKeyAttribute : ReferencesAttribute + { + public ForeignKeyAttribute(Type type) : base(type) + { + } + + public string OnDelete { get; set; } + public string OnUpdate { get; set; } + + //Default naming: FK_thisTableName_refTableName + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexAttribute.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexAttribute.cs new file mode 100644 index 0000000000..a094c84e36 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + [AttributeUsage(AttributeTargets.Property)] + public class IndexAttribute : Attribute + { + public IndexAttribute(IndexTypes indexType) + { + IndexType = indexType; + } + + //public Type Type { get; set; } + public string Name { get; set; }//Overrides default naming of indexes: IX_tableName + public IndexTypes IndexType { get; private set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexTypes.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexTypes.cs new file mode 100644 index 0000000000..97f3680aa7 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexTypes.cs @@ -0,0 +1,11 @@ +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + public enum IndexTypes + { + Clustered, + Nonclustered, + UniqueNonclustered, + PrimaryXml, + Spartial + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/NullSettingAttribute.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/NullSettingAttribute.cs new file mode 100644 index 0000000000..1c4da8a2a4 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/NullSettingAttribute.cs @@ -0,0 +1,10 @@ +using System; + +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + [AttributeUsage(AttributeTargets.Property)] + public class NullSettingAttribute : Attribute + { + public NullSettings NullSetting { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/NullSettings.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/NullSettings.cs new file mode 100644 index 0000000000..fab2835776 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/NullSettings.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + public enum NullSettings + { + Null, + NotNull + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/PrimaryKeyColumnAttribute.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/PrimaryKeyColumnAttribute.cs new file mode 100644 index 0000000000..20e56b84c3 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/PrimaryKeyColumnAttribute.cs @@ -0,0 +1,18 @@ +using System; + +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + [AttributeUsage(AttributeTargets.Property)] + public class PrimaryKeyColumnAttribute : Attribute + { + public PrimaryKeyColumnAttribute() + { + Clustered = true; + AutoIncrement = true; + } + + public bool Clustered { get; set; }//Defaults to true + public bool AutoIncrement { get; set; }//Default to true + public string Name { get; set; }//Overrides the default naming of a PrimaryKey constraint: PK_tableName + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/ReferencesAttribute.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/ReferencesAttribute.cs new file mode 100644 index 0000000000..b99a3f8ba1 --- /dev/null +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/ReferencesAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Umbraco.Core.Persistence.DatabaseAnnotations +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)] + public class ReferencesAttribute : Attribute + { + public ReferencesAttribute(Type type) + { + Type = type; + } + + public Type Type { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseFactory.cs b/src/Umbraco.Core/Persistence/DatabaseFactory.cs index 6ce5bd6ac4..aafe03a635 100644 --- a/src/Umbraco.Core/Persistence/DatabaseFactory.cs +++ b/src/Umbraco.Core/Persistence/DatabaseFactory.cs @@ -12,7 +12,7 @@ namespace Umbraco.Core.Persistence { #region Singleton - private static readonly Database _database = new Database(GlobalSettings.DbDsn); + private static readonly Database _database = new Database("umbracoDbDSN"); private static readonly Lazy lazy = new Lazy(() => new DatabaseFactory()); public static DatabaseFactory Current { get { return lazy.Value; } } diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs new file mode 100644 index 0000000000..2ad6b16c14 --- /dev/null +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Umbraco.Core.Persistence.DatabaseAnnotations; + +namespace Umbraco.Core.Persistence +{ + public static class PetaPocoExtensions + { + public static void CreateTable(this Database db) + where T : new() + { + var tableType = typeof(T); + CreateTable(db, false, tableType); + } + + public static void CreateTable(this Database db, bool overwrite) + where T : new() + { + var tableType = typeof(T); + CreateTable(db, overwrite, tableType); + } + + public static void CreateTable(this Database db, bool overwrite, Type modelType) + { + var tableNameAttribute = modelType.FirstAttribute(); + + var objProperties = modelType.GetProperties().ToList(); + string tableName = tableNameAttribute.Value; + + var sql = Sql.Builder.Append(string.Format("CREATE TABLE {0} (", tableName)); + var primaryKeyConstraints = new List(); + var foreignKeyConstraints = new List(); + var indexes = new List(); + + var last = objProperties.Last(); + foreach (var propertyInfo in objProperties) + { + var columnAttribute = propertyInfo.FirstAttribute(); + if(columnAttribute == null) continue; + + var sb = new StringBuilder(); + sb.AppendFormat("[{0}]", columnAttribute.Name); + + var databaseTypeAttribute = propertyInfo.FirstAttribute(); + if (databaseTypeAttribute != null) + sb.AppendFormat(" {0}", databaseTypeAttribute.ToSqlSyntax()); + + var nullSettingAttribute = propertyInfo.FirstAttribute(); + if(nullSettingAttribute != null) + sb.AppendFormat(" {0}", nullSettingAttribute.ToSqlSyntax()); + + var primaryKeyColumnAttribute = propertyInfo.FirstAttribute(); + if(primaryKeyColumnAttribute != null) + { + sb.AppendFormat(" {0}", primaryKeyColumnAttribute.ToSqlSyntax()); + //Add to list of primary key constraints + primaryKeyConstraints.Add(new Sql(primaryKeyColumnAttribute.ToSqlSyntax(tableName, columnAttribute.Name))); + } + + var constraintAttribute = propertyInfo.FirstAttribute(); + if(constraintAttribute != null) + sb.AppendFormat(" {0}", constraintAttribute.ToSqlSyntax(tableName, columnAttribute.Name)); + + if (propertyInfo != last) + sb.Append(", "); + + sql.Append(sb.ToString()); + + //Look for foreign keys + var foreignKeyAttribute = propertyInfo.FirstAttribute(); + if (foreignKeyAttribute != null) + { + foreignKeyConstraints.Add(new Sql(foreignKeyAttribute.ToSqlSyntax(tableName, columnAttribute.Name))); + } + + //Look for indexes + var indexAttribute = propertyInfo.FirstAttribute(); + if(indexAttribute != null) + { + indexes.Add(new Sql(indexAttribute.ToSqlSyntax(tableName, columnAttribute.Name))); + } + } + + sql.Append(")");//End + + var tableExist = db.TableExist(tableName); + if(overwrite && tableExist) + { + db.DropTable(tableName); + } + + if(!tableExist) + { + int created = db.Execute(sql); + foreach (var constraint in primaryKeyConstraints) + { + db.Execute(constraint); + } + foreach (var constraint in foreignKeyConstraints) + { + db.Execute(constraint); + } + foreach (var index in indexes) + { + db.Execute(index); + } + } + +#if DEBUG + Console.WriteLine(sql.SQL); + foreach (var constraint in primaryKeyConstraints) + { + Console.WriteLine(constraint.SQL); + } + foreach (var constraint in foreignKeyConstraints) + { + Console.WriteLine(constraint.SQL); + } + foreach (var index in indexes) + { + Console.WriteLine(index.SQL); + } +#endif + } + + public static void DropTable(this Database db) + where T : new() + { + Type type = typeof (T); + var tableNameAttribute = type.FirstAttribute(); + if (tableNameAttribute == null) + throw new Exception( + string.Format( + "The Type '{0}' does not contain a TableNameAttribute, which is used to find the name of the table to drop. The operation could not be completed.", + type.Name)); + + string tableName = tableNameAttribute.Value; + DropTable(db, tableName); + } + + public static void DropTable(this Database db, string tableName) + { + var sql = new Sql(string.Format("DROP TABLE {0}", tableName)); + db.Execute(sql); + } + + public static bool TableExist(this Database db, string tableName) + { + var scalar = + db.ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tableName", + new {tableName = tableName}); + + return scalar > 0; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/TypeExtensions.cs b/src/Umbraco.Core/TypeExtensions.cs index 47d573dccf..9e2af0225a 100644 --- a/src/Umbraco.Core/TypeExtensions.cs +++ b/src/Umbraco.Core/TypeExtensions.cs @@ -205,8 +205,7 @@ namespace Umbraco.Core } - - /// + /// /// Determines whether the specified actual type is type. /// /// @@ -219,27 +218,26 @@ namespace Umbraco.Core return TypeHelper.IsTypeAssignableFrom(actualType); } - //internal static string GetCacheKeyFromParameters(this MemberInfo info) - //{ - // var methodInfo = info as MethodInfo; - // if (methodInfo != null) - // return GetCacheKeyFromParameters(methodInfo.GetParameters()); - // return string.Empty; - //} + public static TAttribute FirstAttribute(this Type type) + { + return type.FirstAttribute(true); + } - //internal static string GetCacheKeyFromParameters(IEnumerable parameters) - //{ - // var sb = new StringBuilder(); - // sb.Append("("); - // foreach (var parameter in parameters) - // { - // sb.Append(parameter.ParameterType); - // sb.Append(" "); - // sb.Append(parameter.Name); - // sb.Append(","); - // } - // sb.Append(")"); - // return sb.ToString(); - //} + public static TAttribute FirstAttribute(this Type type, bool inherit) + { + var attrs = type.GetCustomAttributes(typeof(TAttribute), inherit); + return (TAttribute)(attrs.Length > 0 ? attrs[0] : null); + } + + public static TAttribute FirstAttribute(this PropertyInfo propertyInfo) + { + return propertyInfo.FirstAttribute(true); + } + + public static TAttribute FirstAttribute(this PropertyInfo propertyInfo, bool inherit) + { + var attrs = propertyInfo.GetCustomAttributes(typeof(TAttribute), inherit); + return (TAttribute)(attrs.Length > 0 ? attrs[0] : null); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 098013e774..104d140919 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -104,6 +104,17 @@ + + + + + + + + + + + @@ -119,6 +130,7 @@ + diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index b9a1f1b86c..cbb4866fb0 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -7,6 +7,10 @@ + + + + diff --git a/src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs b/src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs new file mode 100644 index 0000000000..01432d9085 --- /dev/null +++ b/src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs @@ -0,0 +1,32 @@ +using System; +using System.Configuration; +using NUnit.Framework; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence; +using Umbraco.Tests.TestHelpers; + +namespace Umbraco.Tests.Persistence +{ + [TestFixture] + public class DatabaseExtensionsTest + { + [SetUp] + public virtual void Initialize() + { + AppDomain.CurrentDomain.SetData("DataDirectory", TestHelper.CurrentAssemblyDirectory); + } + + [Test] + public void Can_Create_umbracoNode_Table() + { + var factory = DatabaseFactory.Current; + + using(Transaction transaction = factory.Database.GetTransaction()) + { + factory.Database.CreateTable(); + + transaction.Complete(); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 2441e5815e..e3343c4b29 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -67,6 +67,7 @@ +