From c1909eccf557054cebb7c77db12fcc2c8878db40 Mon Sep 17 00:00:00 2001 From: sitereactor Date: Fri, 19 Oct 2012 13:20:57 -0200 Subject: [PATCH] Refactoring database creation, adding sql syntax provider to account for differences in syntax between sql, ce and mysql. Adding MySql unit test. --- src/Umbraco.Core/Models/Rdbms/AppDto.cs | 2 +- .../Models/Rdbms/ContentTypeDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs | 2 +- .../Models/Rdbms/DataTypePreValueDto.cs | 4 +- .../Models/Rdbms/DictionaryDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/DocumentDto.cs | 4 +- src/Umbraco.Core/Models/Rdbms/LanguageDto.cs | 4 +- .../Models/Rdbms/LanguageTextDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/LogDto.cs | 4 +- .../Models/Rdbms/MacroPropertyDto.cs | 2 +- .../Models/Rdbms/MacroPropertyTypeDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/MemberDto.cs | 6 +- src/Umbraco.Core/Models/Rdbms/NodeDto.cs | 22 +- .../Models/Rdbms/PreviewXmlDto.cs | 2 +- .../Models/Rdbms/PropertyDataDto.cs | 4 +- .../Models/Rdbms/PropertyTypeDto.cs | 4 +- src/Umbraco.Core/Models/Rdbms/RelationDto.cs | 2 +- .../Models/Rdbms/RelationTypeDto.cs | 2 +- .../Models/Rdbms/StylesheetDto.cs | 4 +- .../Models/Rdbms/StylesheetPropertyDto.cs | 4 +- src/Umbraco.Core/Models/Rdbms/TagDto.cs | 4 +- src/Umbraco.Core/Models/Rdbms/TaskDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/TemplateDto.cs | 4 +- src/Umbraco.Core/Models/Rdbms/User2AppDto.cs | 2 +- .../Models/Rdbms/User2NodeNotifyDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/UserDto.cs | 8 +- src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs | 4 +- .../AttributeExtensions.cs | 148 ---------- .../DatabaseAnnotations/DatabaseTypes.cs | 18 +- .../DatabaseAnnotations/IndexTypes.cs | 4 +- .../Persistence/PetaPocoExtensions.cs | 204 +++---------- .../Persistence/SqlSyntax/DbTypes.cs | 30 ++ .../ModelDefinitions/ColumnDefinition.cs | 28 ++ .../ModelDefinitions/DefinitionFactory.cs | 112 +++++++ .../ModelDefinitions/ForeignKeyDefinition.cs | 10 + .../ModelDefinitions/IndexDefinition.cs | 12 + .../ModelDefinitions/TableDefinition.cs | 33 +++ .../SqlSyntax/MySqlSyntaxProvider.cs | 54 ++++ .../SqlSyntax/SqlCeSyntaxProvider.cs | 68 +++++ .../SqlSyntax/SqlServerSyntaxProvider.cs | 35 +++ .../SqlSyntax/SqlSyntaxProviderBase.cs | 277 ++++++++++++++++++ .../Persistence/SqlSyntax/SyntaxConfig.cs | 23 ++ src/Umbraco.Core/Umbraco.Core.csproj | 12 +- .../Persistence/DatabaseExtensionsTest.cs | 3 + .../Persistence/MySqlDatabaseCreationTest.cs | 42 +++ .../TestHelpers/BaseDatabaseTest.cs | 4 + src/Umbraco.Tests/Umbraco.Tests.csproj | 5 + 47 files changed, 844 insertions(+), 384 deletions(-) delete mode 100644 src/Umbraco.Core/Persistence/DatabaseAnnotations/AttributeExtensions.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/DbTypes.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/ColumnDefinition.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/DefinitionFactory.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/ForeignKeyDefinition.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/IndexDefinition.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/TableDefinition.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SyntaxConfig.cs create mode 100644 src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs diff --git a/src/Umbraco.Core/Models/Rdbms/AppDto.cs b/src/Umbraco.Core/Models/Rdbms/AppDto.cs index 31a3b3fe12..7ce8658c1b 100644 --- a/src/Umbraco.Core/Models/Rdbms/AppDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/AppDto.cs @@ -10,7 +10,7 @@ namespace Umbraco.Core.Models.Rdbms { [Column("appAlias")] [PrimaryKeyColumn(AutoIncrement = false, Clustered = true)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] public string AppAlias { get; set; } [Column("appIcon")] diff --git a/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs index cd254a18ed..af5e554172 100644 --- a/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ContentTypeDto.cs @@ -32,7 +32,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("description")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 1500)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 1500)] public string Description { get; set; } [Column("isContainer")] diff --git a/src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs index 8e619b45fa..db077cec1c 100644 --- a/src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DataTypeDto.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Models.Rdbms public Guid ControlId { get; set; } [Column("dbType")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)]//NOTE Is set to [varchar] (50) in Sql Server script + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)]//NOTE Is set to [varchar] (50) in Sql Server script public string DbType { get; set; } [ResultColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/DataTypePreValueDto.cs b/src/Umbraco.Core/Models/Rdbms/DataTypePreValueDto.cs index b84a15c454..3efc216004 100644 --- a/src/Umbraco.Core/Models/Rdbms/DataTypePreValueDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DataTypePreValueDto.cs @@ -18,7 +18,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("value")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 2500)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 2500)] public string Value { get; set; } [Column("sortorder")] @@ -26,7 +26,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("alias")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] public string Alias { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/DictionaryDto.cs b/src/Umbraco.Core/Models/Rdbms/DictionaryDto.cs index 3411fa95df..95fdb3746e 100644 --- a/src/Umbraco.Core/Models/Rdbms/DictionaryDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DictionaryDto.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Models.Rdbms public Guid Parent { get; set; } [Column("key")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 1000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 1000)] public string Key { get; set; } [ResultColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs b/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs index d4a2dadd8b..502c3eaba2 100644 --- a/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/DocumentDto.cs @@ -26,7 +26,7 @@ namespace Umbraco.Core.Models.Rdbms public Guid VersionId { get; set; } [Column("text")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 255)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 255)] public string Text { get; set; } [Column("releaseDate")] @@ -48,7 +48,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("alias")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 255)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 255)] public string Alias { get; set; } [Column("newest")] diff --git a/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs b/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs index 293cd1b826..578732dc64 100644 --- a/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs @@ -15,12 +15,12 @@ namespace Umbraco.Core.Models.Rdbms [Column("languageISOCode")] [Index(IndexTypes.UniqueNonClustered)] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 10)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 10)] public string IsoCode { get; set; } [Column("languageCultureName")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 100)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 100)] public string CultureName { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/LanguageTextDto.cs b/src/Umbraco.Core/Models/Rdbms/LanguageTextDto.cs index dc8863440d..778c8ab0c6 100644 --- a/src/Umbraco.Core/Models/Rdbms/LanguageTextDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/LanguageTextDto.cs @@ -21,7 +21,7 @@ namespace Umbraco.Core.Models.Rdbms public Guid UniqueId { get; set; } [Column("value")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 1000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 1000)] public string Value { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/LogDto.cs b/src/Umbraco.Core/Models/Rdbms/LogDto.cs index 21f957425a..8b786bc4f2 100644 --- a/src/Umbraco.Core/Models/Rdbms/LogDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/LogDto.cs @@ -25,12 +25,12 @@ namespace Umbraco.Core.Models.Rdbms public DateTime Datestamp { get; set; } [Column("logHeader")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] public string Header { get; set; } [Column("logComment")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 4000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 4000)] public string Comment { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/MacroPropertyDto.cs b/src/Umbraco.Core/Models/Rdbms/MacroPropertyDto.cs index 837402df4b..32309c4983 100644 --- a/src/Umbraco.Core/Models/Rdbms/MacroPropertyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MacroPropertyDto.cs @@ -29,7 +29,7 @@ namespace Umbraco.Core.Models.Rdbms public byte SortOrder { get; set; } [Column("macroPropertyAlias")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] public string Alias { get; set; } [Column("macroPropertyName")] diff --git a/src/Umbraco.Core/Models/Rdbms/MacroPropertyTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/MacroPropertyTypeDto.cs index 84b2ce2158..c9a35801d9 100644 --- a/src/Umbraco.Core/Models/Rdbms/MacroPropertyTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MacroPropertyTypeDto.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Models.Rdbms public short Id { get; set; } [Column("macroPropertyTypeAlias")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] [NullSetting(NullSetting = NullSettings.Null)] public string Alias { get; set; } diff --git a/src/Umbraco.Core/Models/Rdbms/MemberDto.cs b/src/Umbraco.Core/Models/Rdbms/MemberDto.cs index 8d246cfcad..83d94cea80 100644 --- a/src/Umbraco.Core/Models/Rdbms/MemberDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/MemberDto.cs @@ -15,17 +15,17 @@ namespace Umbraco.Core.Models.Rdbms public int NodeId { get; set; } [Column("Email")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 1000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 1000)] [Constraint(Default = "''")] public string Email { get; set; } [Column("LoginName")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 1000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 1000)] [Constraint(Default = "''")] public string LoginName { get; set; } [Column("Password")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 1000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 1000)] [Constraint(Default = "''")] public string Password { get; set; } } diff --git a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs index 78cab99f35..ddb697cd6c 100644 --- a/src/Umbraco.Core/Models/Rdbms/NodeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/NodeDto.cs @@ -11,55 +11,55 @@ namespace Umbraco.Core.Models.Rdbms { [Column("id")] [PrimaryKeyColumn(Name = "PK_structure")] - [DatabaseType(DatabaseTypes.Integer)] + //[DatabaseType(DatabaseTypes.Integer)] public int NodeId { get; set; } [Column("trashed")] - [DatabaseType(DatabaseTypes.Bool)] + //[DatabaseType(DatabaseTypes.Bool)] [Constraint(Default = "0")] public bool Trashed { get; set; } [Column("parentID")] - [DatabaseType(DatabaseTypes.Integer)] + //[DatabaseType(DatabaseTypes.Integer)] [ForeignKey(typeof(NodeDto))] [IndexAttribute(IndexTypes.NonClustered, Name = "IX_umbracoNodeParentId")] public int ParentId { get; set; } [Column("nodeUser")] - [DatabaseType(DatabaseTypes.Integer)] + //[DatabaseType(DatabaseTypes.Integer)] [NullSetting(NullSetting = NullSettings.Null)] public int? UserId { get; set; } [Column("level")] - [DatabaseType(DatabaseTypes.SmallInteger)] + //[DatabaseType(DatabaseTypes.SmallInteger)] public short Level { get; set; } [Column("path")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 150)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 150)] public string Path { get; set; } [Column("sortOrder")] - [DatabaseType(DatabaseTypes.Integer)] + //[DatabaseType(DatabaseTypes.Integer)] public int SortOrder { get; set; } [Column("uniqueID")] - [DatabaseType(DatabaseTypes.UniqueIdentifier)] + //[DatabaseType(DatabaseTypes.UniqueIdentifier)] [NullSetting(NullSetting = NullSettings.Null)] public Guid? UniqueId { get; set; } [Column("text")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 255)] + //[DatabaseType(DatabaseTypes.Nvarchar, Length = 255)] [NullSetting(NullSetting = NullSettings.Null)] public string Text { get; set; } [Column("nodeObjectType")] - [DatabaseType(DatabaseTypes.UniqueIdentifier)] + //[DatabaseType(DatabaseTypes.UniqueIdentifier)] [NullSetting(NullSetting = NullSettings.Null)] [IndexAttribute(IndexTypes.NonClustered, Name = "IX_umbracoNodeObjectType")] public Guid? NodeObjectType { get; set; } [Column("createDate")] - [DatabaseType(DatabaseTypes.DateTime)] + //[DatabaseType(DatabaseTypes.DateTime)] [Constraint(Default = "getdate()")] public DateTime CreateDate { get; set; } } diff --git a/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs b/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs index 85ae2e38ac..7f6d70624c 100644 --- a/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Models.Rdbms public DateTime Timestamp { get; set; } [Column("xml")] - [DatabaseType(DatabaseTypes.Ntext)] + [DatabaseType(DatabaseTypes.NTEXT)] public string Xml { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs index ab9fff4fb7..8d15d59c94 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs @@ -39,12 +39,12 @@ namespace Umbraco.Core.Models.Rdbms [Column("dataNvarchar")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 500)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 500)] public string VarChar { get; set; } [Column("dataNtext")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Ntext)] + [DatabaseType(DatabaseTypes.NTEXT)] public string Text { get; set; } [ResultColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs index 29f2472ca3..206baf2cda 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyTypeDto.cs @@ -34,7 +34,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("helpText")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 1000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 1000)] public string HelpText { get; set; } [Column("sortOrder")] @@ -51,7 +51,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("Description")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 2000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 2000)] public string Description { get; set; } [ResultColumn] diff --git a/src/Umbraco.Core/Models/Rdbms/RelationDto.cs b/src/Umbraco.Core/Models/Rdbms/RelationDto.cs index ad7a8738c4..b1917d7ab4 100644 --- a/src/Umbraco.Core/Models/Rdbms/RelationDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/RelationDto.cs @@ -30,7 +30,7 @@ namespace Umbraco.Core.Models.Rdbms public DateTime Datetime { get; set; } [Column("comment")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 1000)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 1000)] public string Comment { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs index 545f2b25a9..93c7b0a96e 100644 --- a/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs @@ -27,7 +27,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("alias")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 100)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 100)] public string Alias { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/StylesheetDto.cs b/src/Umbraco.Core/Models/Rdbms/StylesheetDto.cs index 24004d326e..49b75dedad 100644 --- a/src/Umbraco.Core/Models/Rdbms/StylesheetDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/StylesheetDto.cs @@ -14,11 +14,11 @@ namespace Umbraco.Core.Models.Rdbms public int NodeId { get; set; } [Column("filename")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 100)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 100)] public string Filename { get; set; } [Column("content")] - [DatabaseType(DatabaseTypes.Ntext)] + [DatabaseType(DatabaseTypes.NTEXT)] [NullSetting(NullSetting = NullSettings.Null)] public string Content { get; set; } } diff --git a/src/Umbraco.Core/Models/Rdbms/StylesheetPropertyDto.cs b/src/Umbraco.Core/Models/Rdbms/StylesheetPropertyDto.cs index 7e6dd51317..d4e1481f02 100644 --- a/src/Umbraco.Core/Models/Rdbms/StylesheetPropertyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/StylesheetPropertyDto.cs @@ -18,12 +18,12 @@ namespace Umbraco.Core.Models.Rdbms [Column("stylesheetPropertyAlias")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] public string Alias { get; set; } [Column("stylesheetPropertyValue")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 400)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 400)] public string Value { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/TagDto.cs b/src/Umbraco.Core/Models/Rdbms/TagDto.cs index 1a27d006ee..2a51efd78b 100644 --- a/src/Umbraco.Core/Models/Rdbms/TagDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TagDto.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("tag")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 200)]//NOTE Is set to [varchar] (200) in Sql Server script + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 200)]//NOTE Is set to [varchar] (200) in Sql Server script public string Tag { get; set; } [Column("ParentId")] @@ -23,7 +23,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("group")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 100)]//NOTE Is set to [varchar] (100) in Sql Server script + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 100)]//NOTE Is set to [varchar] (100) in Sql Server script public string Group { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/TaskDto.cs b/src/Umbraco.Core/Models/Rdbms/TaskDto.cs index b0cfdc5a3b..2fa75d8cf2 100644 --- a/src/Umbraco.Core/Models/Rdbms/TaskDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TaskDto.cs @@ -39,7 +39,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("Comment")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 500)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 500)] public string Comment { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/TemplateDto.cs b/src/Umbraco.Core/Models/Rdbms/TemplateDto.cs index 952cbde168..fdf8f08196 100644 --- a/src/Umbraco.Core/Models/Rdbms/TemplateDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TemplateDto.cs @@ -23,12 +23,12 @@ namespace Umbraco.Core.Models.Rdbms public int? Master { get; set; } [Column("alias")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 100)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 100)] [NullSetting(NullSetting = NullSettings.Null)] public string Alias { get; set; } [Column("design")] - [DatabaseType(DatabaseTypes.Ntext)] + [DatabaseType(DatabaseTypes.NTEXT)] public string Design { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs b/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs index 3f68acf909..1650b22c35 100644 --- a/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Models.Rdbms public int UserId { get; set; } [Column("app")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] public string AppAlias { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs b/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs index dd22b82e2d..81203fad6f 100644 --- a/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs @@ -18,7 +18,7 @@ namespace Umbraco.Core.Models.Rdbms public int NodeId { get; set; } [Column("action")] - [DatabaseType(DatabaseTypes.Nchar, Length = 1)] + [DatabaseType(DatabaseTypes.NCHAR, Length = 1)] public string Action { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/UserDto.cs b/src/Umbraco.Core/Models/Rdbms/UserDto.cs index 3138823376..d29ddf1a64 100644 --- a/src/Umbraco.Core/Models/Rdbms/UserDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/UserDto.cs @@ -35,12 +35,12 @@ namespace Umbraco.Core.Models.Rdbms public string UserName { get; set; } [Column("userLogin")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 125)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 125)] [Index(IndexTypes.NonClustered)] public string Login { get; set; } [Column("userPassword")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 125)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 125)] public string Password { get; set; } [Column("userEmail")] @@ -48,12 +48,12 @@ namespace Umbraco.Core.Models.Rdbms [Column("userDefaultPermissions")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] public string DefaultPermissions { get; set; } [Column("userLanguage")] [NullSetting(NullSetting = NullSettings.Null)] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 10)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 10)] public string UserLanguage { get; set; } [Column("defaultToLiveEditing")] diff --git a/src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs index 644fbc78d9..60bb09b019 100644 --- a/src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/UserTypeDto.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Models.Rdbms public short Id { get; set; } [Column("userTypeAlias")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] [NullSetting(NullSetting = NullSettings.Null)] public string Alias { get; set; } @@ -21,7 +21,7 @@ namespace Umbraco.Core.Models.Rdbms public string Name { get; set; } [Column("userTypeDefaultPermissions")] - [DatabaseType(DatabaseTypes.Nvarchar, Length = 50)] + [DatabaseType(DatabaseTypes.NVARCHAR, Length = 50)] [NullSetting(NullSetting = NullSettings.Null)] public string DefaultPermissions { get; set; } } diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/AttributeExtensions.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/AttributeExtensions.cs deleted file mode 100644 index eaf07358fa..0000000000 --- a/src/Umbraco.Core/Persistence/DatabaseAnnotations/AttributeExtensions.cs +++ /dev/null @@ -1,148 +0,0 @@ -namespace Umbraco.Core.Persistence.DatabaseAnnotations -{ - internal static class AttributeExtensions - { - public static string ToSqlSyntax(this NullSettings settings) - { - return settings == NullSettings.Null ? "NULL" : "NOT NULL"; - } - - public static string ToSqlSyntax(this NullSettingAttribute attribute) - { - return attribute.NullSetting.ToSqlSyntax(); - } - - public static string ToSqlSyntax(this DatabaseTypes databaseTypes, int length) - { - string syntax = string.Empty; - switch (databaseTypes) - { - 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.TinyInteger: - syntax = "[tinyint]"; - break; - case DatabaseTypes.Integer: - syntax = "[int]"; - break; - case DatabaseTypes.Nchar: - syntax = "[nchar]"; - if (length > 0) - syntax += string.Format(" ({0})", length); - break; - case DatabaseTypes.Nvarchar: - syntax = "[nvarchar]"; - if (length > 0) - syntax += string.Format(" ({0})", length); - break; - } - return syntax; - } - - public static string ToSqlSyntax(this DatabaseTypeAttribute attribute) - { - return attribute.DatabaseType.ToSqlSyntax(attribute.Length); - } - - 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"; - - if (DatabaseFactory.Current.DatabaseProvider == DatabaseProviders.SqlServerCE) - clustered = string.Empty; - - string syntax = string.IsNullOrEmpty(attribute.OnColumns) - ? string.Format("ALTER TABLE [{0}] ADD CONSTRAINT [{1}] PRIMARY KEY {2} ([{3}])", - tableName, constraintName, clustered, propertyName) - : string.Format("ALTER TABLE [{0}] ADD CONSTRAINT [{1}] PRIMARY KEY {2} ({3})", - tableName, constraintName, clustered, attribute.OnColumns); - - return syntax; - } - - public static string ToSqlSyntax(this ConstraintAttribute attribute, string tableName, string propertyName) - { - if (!string.IsNullOrEmpty(attribute.Name)) - return string.Format("CONSTRAINT [{0}] DEFAULT ({1})", attribute.Name, attribute.Default); - - 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.IsNullOrEmpty(attribute.Name) - ? string.Format("FK_{0}_{1}", tableName, referencedTableName) - : attribute.Name; - - string referencedColumn = string.IsNullOrEmpty(attribute.Column) - ? primaryKeyAttribute.Value - : attribute.Column; - string syntax = - string.Format( - "ALTER TABLE [{0}] ADD CONSTRAINT [{1}] FOREIGN KEY ([{2}]) REFERENCES [{3}] ([{4}])", - tableName, constraintName, propertyName, referencedTableName, referencedColumn); - - 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 = "UNIQUE NONCLUSTERED"; - break; - } - string name = string.IsNullOrEmpty(attribute.Name) ? string.Format("IX_{0}_{1}", tableName, propertyName) : attribute.Name; - - string syntax = string.IsNullOrEmpty(attribute.ForColumns) - ? string.Format("CREATE {0} INDEX [{1}] ON [{2}] ([{3}])", indexType, name, tableName, - propertyName) - : string.Format("CREATE {0} INDEX [{1}] ON [{2}] ({3})", indexType, name, tableName, - attribute.ForColumns); - return syntax; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypes.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypes.cs index 7ed52d8713..be8608081d 100644 --- a/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypes.cs +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/DatabaseTypes.cs @@ -2,14 +2,14 @@ { public enum DatabaseTypes { - Integer, - SmallInteger, - TinyInteger, - UniqueIdentifier, - DateTime, - Ntext, - Nvarchar, - Bool, - Nchar + INTEGER, + SMALLINTEGER, + TINYINTEGER, + UNIQUEIDENTIFIER, + DATETIME, + NTEXT, + NVARCHAR, + BOOL, + NCHAR } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexTypes.cs b/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexTypes.cs index 21d718065d..165c617d3a 100644 --- a/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexTypes.cs +++ b/src/Umbraco.Core/Persistence/DatabaseAnnotations/IndexTypes.cs @@ -4,8 +4,6 @@ { Clustered, NonClustered, - UniqueNonClustered, - PrimaryXml, - Spartial + UniqueNonClustered } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index c18b936fa4..dd28156ed5 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -1,9 +1,7 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.Migrations.Initial; +using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions; namespace Umbraco.Core.Persistence { @@ -25,179 +23,49 @@ namespace Umbraco.Core.Persistence public static void CreateTable(this Database db, bool overwrite, Type modelType) { - var tableNameAttribute = modelType.FirstAttribute(); + var tableDefinition = DefinitionFactory.GetTableDefinition(modelType); + var tableName = tableDefinition.TableName; - var objProperties = modelType.GetProperties().ToList(); - string tableName = tableNameAttribute.Value; + string createSql = SyntaxConfig.SqlSyntaxProvider.ToCreateTableStatement(tableDefinition); + string createPrimaryKeySql = SyntaxConfig.SqlSyntaxProvider.ToCreatePrimaryKeyStatement(tableDefinition); + var foreignSql = SyntaxConfig.SqlSyntaxProvider.ToCreateForeignKeyStatements(tableDefinition); + var indexSql = SyntaxConfig.SqlSyntaxProvider.ToCreateIndexStatements(tableDefinition); - var sql = Sql.Builder.Append(string.Format("CREATE TABLE {0} (", tableName)); - var primaryKeyConstraints = new List(); - var foreignKeyConstraints = new List(); - var indexes = new List(); - - var sb = new StringBuilder(); - - foreach (var propertyInfo in objProperties) +#if DEBUG + Console.WriteLine(createSql); + Console.WriteLine(createPrimaryKeySql); + foreach (var sql in foreignSql) { - //If current property is a ResultColumn then skip it - var resultColumnAttribute = propertyInfo.FirstAttribute(); - if(resultColumnAttribute != null) - { - continue; - } - - //Assumes ExplicitColumn attribute and thus having a ColumnAttribute with the name of the column - var columnAttribute = propertyInfo.FirstAttribute(); - if(columnAttribute == null) continue; - - sb.AppendFormat("[{0}]", columnAttribute.Name); - - var databaseTypeAttribute = propertyInfo.FirstAttribute(); - if (databaseTypeAttribute != null) - { - sb.AppendFormat(" {0}", databaseTypeAttribute.ToSqlSyntax()); - } - else - { - //Convetion - Use property's Type to set/find db type - //TODO Improve :) - if(propertyInfo.PropertyType == typeof(string)) - { - sb.AppendFormat(" [nvarchar] (255)"); - } - else if (propertyInfo.PropertyType == typeof(int)) - { - sb.AppendFormat(" [int]"); - } - else if (propertyInfo.PropertyType == typeof(int?)) - { - sb.AppendFormat(" [int]"); - } - else if (propertyInfo.PropertyType == typeof(long)) - { - sb.AppendFormat(" [bigint]"); - } - else if (propertyInfo.PropertyType == typeof(bool)) - { - sb.AppendFormat(" [bit]"); - } - else if (propertyInfo.PropertyType == typeof(bool?)) - { - sb.AppendFormat(" [bit]"); - } - else if (propertyInfo.PropertyType == typeof(byte)) - { - sb.AppendFormat(DatabaseFactory.Current.DatabaseProvider == DatabaseProviders.SqlServer - ? " [tinyint]" - : " [int]"); - } - else if (propertyInfo.PropertyType == typeof(short)) - { - sb.AppendFormat(DatabaseFactory.Current.DatabaseProvider == DatabaseProviders.SqlServer - ? " [smallint]" - : " [int]"); - } - else if (propertyInfo.PropertyType == typeof(DateTime)) - { - sb.AppendFormat(" [datetime]"); - } - else if (propertyInfo.PropertyType == typeof(DateTime?)) - { - sb.AppendFormat(" [datetime]"); - } - else if (propertyInfo.PropertyType == typeof(Guid)) - { - sb.AppendFormat(" [uniqueidentifier]"); - } - else if (propertyInfo.PropertyType == typeof(Guid?)) - { - sb.AppendFormat(" [uniqueidentifier]"); - } - } - - var nullSettingAttribute = propertyInfo.FirstAttribute(); - if(nullSettingAttribute != null) - { - sb.AppendFormat(" {0}", nullSettingAttribute.ToSqlSyntax()); - } - else - { - //Convention - Use "NOT NULL" if nothing is specified - sb.AppendFormat(" {0}", NullSettings.NotNull.ToSqlSyntax()); - } - - var primaryKeyColumnAttribute = propertyInfo.FirstAttribute(); - if(primaryKeyColumnAttribute != null) - { - sb.Append(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)); - - sb.Append(", "); - - //Look for foreign keys - var foreignKeyAttributes = propertyInfo.MultipleAttribute(); - if (foreignKeyAttributes != null) - { - foreignKeyConstraints.AddRange( - foreignKeyAttributes.Select( - attribute => new Sql(attribute.ToSqlSyntax(tableName, columnAttribute.Name)))); - } - - //Look for indexes - var indexAttribute = propertyInfo.FirstAttribute(); - if(indexAttribute != null) - { - indexes.Add(new Sql(indexAttribute.ToSqlSyntax(tableName, columnAttribute.Name))); - } + Console.WriteLine(sql); } - - sql.Append(sb.ToString().TrimEnd(", ".ToCharArray())); - sql.Append(")");//End + foreach (var sql in indexSql) + { + Console.WriteLine(sql); + } +#endif var tableExist = db.TableExist(tableName); - if(overwrite && tableExist) + if (overwrite && tableExist) { db.DropTable(tableName); } - if(!tableExist) + 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); - } - } + int created = db.Execute(new Sql(createSql)); -#if DEBUG - Console.WriteLine(sql.SQL); - foreach (var constraint in primaryKeyConstraints) - { - Console.WriteLine(constraint.SQL); + if(!string.IsNullOrEmpty(createPrimaryKeySql)) + db.Execute(new Sql(createPrimaryKeySql)); + + foreach (var sql in foreignSql) + { + int createdFk = db.Execute(new Sql(sql)); + } + foreach (var sql in indexSql) + { + int createdIndex = db.Execute(new Sql(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) @@ -217,17 +85,13 @@ namespace Umbraco.Core.Persistence public static void DropTable(this Database db, string tableName) { - var sql = new Sql(string.Format("DROP TABLE {0}", tableName)); + var sql = new Sql(string.Format("DROP TABLE {0}", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(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; + return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName); } public static void Initialize(this Database db) diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/DbTypes.cs b/src/Umbraco.Core/Persistence/SqlSyntax/DbTypes.cs new file mode 100644 index 0000000000..18f8c71493 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/DbTypes.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Data; + +namespace Umbraco.Core.Persistence.SqlSyntax +{ + internal class DbTypes + where TSyntax : ISqlSyntaxProvider + { + public DbType DbType; + public string TextDefinition; + public bool ShouldQuoteValue; + public Dictionary ColumnTypeMap = new Dictionary(); + public Dictionary ColumnDbTypeMap = new Dictionary(); + + public void Set(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; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/ColumnDefinition.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/ColumnDefinition.cs new file mode 100644 index 0000000000..344b88ae17 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/ColumnDefinition.cs @@ -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); } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/DefinitionFactory.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/DefinitionFactory.cs new file mode 100644 index 0000000000..42acad43ea --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/DefinitionFactory.cs @@ -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(); + 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(); + if (resultColumnAttribute != null) continue; + + //Assumes ExplicitColumn attribute and thus having a ColumnAttribute with the name of the column + var columnAttribute = propertyInfo.FirstAttribute(); + 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(); + 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(); + if (nullSettingAttribute != null) + { + columnDefinition.IsNullable = nullSettingAttribute.NullSetting == NullSettings.Null; + } + + //Look for Primary Key for the current column + var primaryKeyColumnAttribute = propertyInfo.FirstAttribute(); + 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(); + 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(); + if (foreignKeyAttributes != null) + { + foreach (var foreignKeyAttribute in foreignKeyAttributes) + { + var referencedTable = foreignKeyAttribute.Type.FirstAttribute(); + var referencedPrimaryKey = foreignKeyAttribute.Type.FirstAttribute(); + + 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(); + 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; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/ForeignKeyDefinition.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/ForeignKeyDefinition.cs new file mode 100644 index 0000000000..06ce016134 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/ForeignKeyDefinition.cs @@ -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; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/IndexDefinition.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/IndexDefinition.cs new file mode 100644 index 0000000000..835a97e746 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/IndexDefinition.cs @@ -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; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/TableDefinition.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/TableDefinition.cs new file mode 100644 index 0000000000..5148b87b4a --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ModelDefinitions/TableDefinition.cs @@ -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(); + ForeignKeyDefinitions = new List(); + IndexDefinitions = new List(); + } + + 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 ColumnDefinitions { get; set; } + public List ForeignKeyDefinitions { get; set; } + public List IndexDefinitions { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs new file mode 100644 index 0000000000..c7061ab043 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -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 + { + 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("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " + + "WHERE TABLE_NAME = @TableName AND " + + "TABLE_SCHEMA = @TableSchema", new { TableName = tableName, TableSchema = db.Connection.Database }); + + return result > 0; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs new file mode 100644 index 0000000000..551d0c0632 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs @@ -0,0 +1,68 @@ +using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions; + +namespace Umbraco.Core.Persistence.SqlSyntax +{ + internal class SqlCeSyntaxProvider : SqlSyntaxProviderBase + { + 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("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName", + new { TableName = tableName }); + + return result > 0; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs new file mode 100644 index 0000000000..f560d68164 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -0,0 +1,35 @@ +using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions; + +namespace Umbraco.Core.Persistence.SqlSyntax +{ + internal class SqlServerSyntaxProvider : SqlSyntaxProviderBase + { + 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("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TableName", + new { TableName = tableName }); + + return result > 0; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs new file mode 100644 index 0000000000..556fde56fb --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -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 ToCreateForeignKeyStatements(TableDefinition tableDefinition); + List 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 : 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 DbTypeMap = new DbTypes(); + protected void InitColumnTypeMap() + { + DbTypeMap.Set(DbType.String, StringColumnDefinition); + DbTypeMap.Set(DbType.StringFixedLength, StringColumnDefinition); + DbTypeMap.Set(DbType.StringFixedLength, StringColumnDefinition); + DbTypeMap.Set(DbType.String, StringColumnDefinition); + DbTypeMap.Set(DbType.Boolean, BoolColumnDefinition); + DbTypeMap.Set(DbType.Boolean, BoolColumnDefinition); + DbTypeMap.Set(DbType.Guid, GuidColumnDefinition); + DbTypeMap.Set(DbType.Guid, GuidColumnDefinition); + DbTypeMap.Set(DbType.DateTime, DateTimeColumnDefinition); + DbTypeMap.Set(DbType.DateTime, DateTimeColumnDefinition); + DbTypeMap.Set(DbType.Time, TimeColumnDefinition); + DbTypeMap.Set(DbType.Time, TimeColumnDefinition); + DbTypeMap.Set(DbType.Time, TimeColumnDefinition); + DbTypeMap.Set(DbType.Time, TimeColumnDefinition); + + DbTypeMap.Set(DbType.Byte, IntColumnDefinition); + DbTypeMap.Set(DbType.Byte, IntColumnDefinition); + DbTypeMap.Set(DbType.SByte, IntColumnDefinition); + DbTypeMap.Set(DbType.SByte, IntColumnDefinition); + DbTypeMap.Set(DbType.Int16, IntColumnDefinition); + DbTypeMap.Set(DbType.Int16, IntColumnDefinition); + DbTypeMap.Set(DbType.UInt16, IntColumnDefinition); + DbTypeMap.Set(DbType.UInt16, IntColumnDefinition); + DbTypeMap.Set(DbType.Int32, IntColumnDefinition); + DbTypeMap.Set(DbType.Int32, IntColumnDefinition); + DbTypeMap.Set(DbType.UInt32, IntColumnDefinition); + DbTypeMap.Set(DbType.UInt32, IntColumnDefinition); + + DbTypeMap.Set(DbType.Int64, LongColumnDefinition); + DbTypeMap.Set(DbType.Int64, LongColumnDefinition); + DbTypeMap.Set(DbType.UInt64, LongColumnDefinition); + DbTypeMap.Set(DbType.UInt64, LongColumnDefinition); + + DbTypeMap.Set(DbType.Single, RealColumnDefinition); + DbTypeMap.Set(DbType.Single, RealColumnDefinition); + DbTypeMap.Set(DbType.Double, RealColumnDefinition); + DbTypeMap.Set(DbType.Double, RealColumnDefinition); + + DbTypeMap.Set(DbType.Decimal, DecimalColumnDefinition); + DbTypeMap.Set(DbType.Decimal, DecimalColumnDefinition); + + DbTypeMap.Set(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 ToCreateForeignKeyStatements(TableDefinition table) + { + var foreignKeys = new List(); + + 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 ToCreateIndexStatements(TableDefinition table) + { + var indexes = new List(); + + 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]; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SyntaxConfig.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SyntaxConfig.cs new file mode 100644 index 0000000000..932939d492 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SyntaxConfig.cs @@ -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; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 285fe765c4..b7952a6ff9 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -104,7 +104,6 @@ - @@ -172,6 +171,17 @@ + + + + + + + + + + + diff --git a/src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs b/src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs index 3b6993fb57..b3c3df86ae 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseExtensionsTest.cs @@ -5,6 +5,7 @@ using System.IO; using NUnit.Framework; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Persistence @@ -37,6 +38,8 @@ namespace Umbraco.Tests.Persistence var engine = new SqlCeEngine(settings.ConnectionString); engine.CreateDatabase(); + SyntaxConfig.SqlSyntaxProvider = SqlCeSyntaxProvider.Instance; + //Create the umbraco database //DatabaseFactory.Current.Database.Initialize(); } diff --git a/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs b/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs new file mode 100644 index 0000000000..e8847e276e --- /dev/null +++ b/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs @@ -0,0 +1,42 @@ +using NUnit.Framework; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; + +namespace Umbraco.Tests.Persistence +{ + [TestFixture] + public class MySqlDatabaseCreationTest : BaseDatabaseTest + { + #region Overrides of BaseDatabaseTest + + public override string ConnectionString + { + get { return "Server = 192.168.1.5; Database = testDb; Uid = umbraco; Pwd = umbraco"; } + } + + public override string ProviderName + { + get { return "MySql.Data.MySqlClient"; } + } + + public override ISqlSyntaxProvider SyntaxProvider + { + get { return MySqlSyntaxProvider.Instance; } + } + + #endregion + + [Test] + public void Can_Assert_Created_Database() + { + bool umbracoNodeTable = Database.TableExist("umbracoNode"); + bool umbracoUserTable = Database.TableExist("umbracoUser"); + bool cmsTagsTable = Database.TableExist("cmsTags"); + + Assert.That(umbracoNodeTable, Is.True); + Assert.That(umbracoUserTable, Is.True); + Assert.That(cmsTagsTable, Is.True); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs index e76cf4a48d..b370ee4508 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs @@ -3,6 +3,7 @@ using System.Data.SqlServerCe; using System.IO; using NUnit.Framework; using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Tests.TestHelpers { @@ -38,6 +39,8 @@ namespace Umbraco.Tests.TestHelpers engine.CreateDatabase(); } + SyntaxConfig.SqlSyntaxProvider = SyntaxProvider; + //Create the umbraco database _database = new Database(ConnectionString, ProviderName); _database.Initialize(); @@ -45,6 +48,7 @@ namespace Umbraco.Tests.TestHelpers public abstract string ConnectionString { get; } public abstract string ProviderName { get; } + public abstract ISqlSyntaxProvider SyntaxProvider { get; } protected Database Database { diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 96e49144eb..d31dcafd55 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -52,6 +52,10 @@ ..\packages\log4net.2.0.0\lib\net40-full\log4net.dll + + False + ..\..\lib\MySql.Data.dll + ..\packages\NUnit.2.6.0.12054\lib\nunit.framework.dll @@ -92,6 +96,7 @@ +