Code from freedom friday project extending petapoco with a bunch of annotations used to decorate strongly typed models for table creation
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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<TableNameAttribute>();
|
||||
var primaryKeyAttribute = attribute.Type.FirstAttribute<PrimaryKeyAttribute>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.DatabaseAnnotations
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ConstraintAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Overrides the default naming of a property constraint:
|
||||
/// DF_tableName_propertyName
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Default { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Umbraco.Core.Persistence.DatabaseAnnotations
|
||||
{
|
||||
public enum DatabaseTypes
|
||||
{
|
||||
Integer,
|
||||
SmallInteger,
|
||||
UniqueIdentifier,
|
||||
DateTime,
|
||||
Ntext,
|
||||
Nvarchar,
|
||||
Bool
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Umbraco.Core.Persistence.DatabaseAnnotations
|
||||
{
|
||||
public enum IndexTypes
|
||||
{
|
||||
Clustered,
|
||||
Nonclustered,
|
||||
UniqueNonclustered,
|
||||
PrimaryXml,
|
||||
Spartial
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.DatabaseAnnotations
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class NullSettingAttribute : Attribute
|
||||
{
|
||||
public NullSettings NullSetting { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Umbraco.Core.Persistence.DatabaseAnnotations
|
||||
{
|
||||
public enum NullSettings
|
||||
{
|
||||
Null,
|
||||
NotNull
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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<DatabaseFactory> lazy = new Lazy<DatabaseFactory>(() => new DatabaseFactory());
|
||||
|
||||
public static DatabaseFactory Current { get { return lazy.Value; } }
|
||||
|
||||
158
src/Umbraco.Core/Persistence/PetaPocoExtensions.cs
Normal file
158
src/Umbraco.Core/Persistence/PetaPocoExtensions.cs
Normal file
@@ -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<T>(this Database db)
|
||||
where T : new()
|
||||
{
|
||||
var tableType = typeof(T);
|
||||
CreateTable(db, false, tableType);
|
||||
}
|
||||
|
||||
public static void CreateTable<T>(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<TableNameAttribute>();
|
||||
|
||||
var objProperties = modelType.GetProperties().ToList();
|
||||
string tableName = tableNameAttribute.Value;
|
||||
|
||||
var sql = Sql.Builder.Append(string.Format("CREATE TABLE {0} (", tableName));
|
||||
var primaryKeyConstraints = new List<Sql>();
|
||||
var foreignKeyConstraints = new List<Sql>();
|
||||
var indexes = new List<Sql>();
|
||||
|
||||
var last = objProperties.Last();
|
||||
foreach (var propertyInfo in objProperties)
|
||||
{
|
||||
var columnAttribute = propertyInfo.FirstAttribute<ColumnAttribute>();
|
||||
if(columnAttribute == null) continue;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendFormat("[{0}]", columnAttribute.Name);
|
||||
|
||||
var databaseTypeAttribute = propertyInfo.FirstAttribute<DatabaseTypeAttribute>();
|
||||
if (databaseTypeAttribute != null)
|
||||
sb.AppendFormat(" {0}", databaseTypeAttribute.ToSqlSyntax());
|
||||
|
||||
var nullSettingAttribute = propertyInfo.FirstAttribute<NullSettingAttribute>();
|
||||
if(nullSettingAttribute != null)
|
||||
sb.AppendFormat(" {0}", nullSettingAttribute.ToSqlSyntax());
|
||||
|
||||
var primaryKeyColumnAttribute = propertyInfo.FirstAttribute<PrimaryKeyColumnAttribute>();
|
||||
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<ConstraintAttribute>();
|
||||
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<ForeignKeyAttribute>();
|
||||
if (foreignKeyAttribute != null)
|
||||
{
|
||||
foreignKeyConstraints.Add(new Sql(foreignKeyAttribute.ToSqlSyntax(tableName, columnAttribute.Name)));
|
||||
}
|
||||
|
||||
//Look for indexes
|
||||
var indexAttribute = propertyInfo.FirstAttribute<IndexAttribute>();
|
||||
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<T>(this Database db)
|
||||
where T : new()
|
||||
{
|
||||
Type type = typeof (T);
|
||||
var tableNameAttribute = type.FirstAttribute<TableNameAttribute>();
|
||||
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<long>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @tableName",
|
||||
new {tableName = tableName});
|
||||
|
||||
return scalar > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,8 +205,7 @@ namespace Umbraco.Core
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Determines whether the specified actual type is type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
@@ -219,27 +218,26 @@ namespace Umbraco.Core
|
||||
return TypeHelper.IsTypeAssignableFrom<T>(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<TAttribute>(this Type type)
|
||||
{
|
||||
return type.FirstAttribute<TAttribute>(true);
|
||||
}
|
||||
|
||||
//internal static string GetCacheKeyFromParameters(IEnumerable<ParameterInfo> 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<TAttribute>(this Type type, bool inherit)
|
||||
{
|
||||
var attrs = type.GetCustomAttributes(typeof(TAttribute), inherit);
|
||||
return (TAttribute)(attrs.Length > 0 ? attrs[0] : null);
|
||||
}
|
||||
|
||||
public static TAttribute FirstAttribute<TAttribute>(this PropertyInfo propertyInfo)
|
||||
{
|
||||
return propertyInfo.FirstAttribute<TAttribute>(true);
|
||||
}
|
||||
|
||||
public static TAttribute FirstAttribute<TAttribute>(this PropertyInfo propertyInfo, bool inherit)
|
||||
{
|
||||
var attrs = propertyInfo.GetCustomAttributes(typeof(TAttribute), inherit);
|
||||
return (TAttribute)(attrs.Length > 0 ? attrs[0] : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,17 @@
|
||||
<Compile Include="Persistence\Caching\IRepositoryCacheProvider.cs" />
|
||||
<Compile Include="Persistence\Caching\NullCacheProvider.cs" />
|
||||
<Compile Include="Persistence\Caching\RuntimeCacheProvider.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\AttributeExtensions.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\ConstraintAttribute.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\DatabaseTypeAttribute.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\DatabaseTypes.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\ForeignKeyAttribute.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\IndexAttribute.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\IndexTypes.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\NullSettingAttribute.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\NullSettings.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\PrimaryKeyColumnAttribute.cs" />
|
||||
<Compile Include="Persistence\DatabaseAnnotations\ReferencesAttribute.cs" />
|
||||
<Compile Include="Persistence\DatabaseFactory.cs" />
|
||||
<Compile Include="Persistence\Factories\ContentFactory.cs" />
|
||||
<Compile Include="Persistence\Factories\ContentTypeFactory.cs" />
|
||||
@@ -119,6 +130,7 @@
|
||||
<Compile Include="Persistence\Factories\RelationFactory.cs" />
|
||||
<Compile Include="Persistence\Factories\RelationTypeFactory.cs" />
|
||||
<Compile Include="Persistence\Mappers\ModelDtoMapper.cs" />
|
||||
<Compile Include="Persistence\PetaPocoExtensions.cs" />
|
||||
<Compile Include="Persistence\Querying\ExpressionHelper.cs" />
|
||||
<Compile Include="Persistence\Querying\IQuery.cs" />
|
||||
<Compile Include="Persistence\Querying\Query.cs" />
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<connectionStrings>
|
||||
<add name="umbracoDbDSN" connectionString="server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco" providerName="System.Data.SqlClient"/>
|
||||
</connectionStrings>
|
||||
|
||||
<FileSystemProviders>
|
||||
<Provider alias="media" type="Umbraco.Core.IO.PhysicalFileSystem, Umbraco.Core">
|
||||
<Parameters>
|
||||
|
||||
32
src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs
Normal file
32
src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs
Normal file
@@ -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<NodeDto>();
|
||||
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@
|
||||
<Compile Include="LibraryTests.cs" />
|
||||
<Compile Include="Models\ContentTests.cs" />
|
||||
<Compile Include="Models\StylesheetTests.cs" />
|
||||
<Compile Include="Persistence\DatabaseExtensionsTest.cs" />
|
||||
<Compile Include="Persistence\DatabaseFactoryTests.cs" />
|
||||
<Compile Include="Persistence\RepositoryResolverTests.cs" />
|
||||
<Compile Include="Resolvers\ActionsResolverTests.cs" />
|
||||
|
||||
Reference in New Issue
Block a user