From 9e7eb2ad7582473f9d46c18ef9803bbc818bc75d Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 17 Jan 2019 12:07:31 +0100 Subject: [PATCH] Remove MySQL support --- build/NuSpecs/UmbracoCms.Core.nuspec | 1 - build/NuSpecs/tools/Web.config.install.xdt | 9 - build/NuSpecs/tools/install.core.ps1 | 1 - .../Constants-DatabaseProviders.cs | 1 - .../Alter/Table/AlterTableBuilder.cs | 58 +- .../Create/Table/CreateTableBuilder.cs | 45 +- .../Expressions/DeleteConstraintExpression.cs | 16 +- .../Expressions/DeleteForeignKeyExpression.cs | 19 +- .../Expressions/InsertDataExpression.cs | 3 - .../Expressions/RenameColumnExpression.cs | 30 +- .../Migrations/Install/DatabaseBuilder.cs | 43 +- .../Install/DatabaseSchemaCreator.cs | 1036 ++++++++--------- .../Install/DatabaseSchemaResult.cs | 9 - .../Migrations/MigrationBase_Extra.cs | 2 - .../UpdateUniqueIndexOnPropertyData.cs | 20 +- .../V_7_6_0/AddIndexToCmsMemberLoginName.cs | 4 +- .../V_7_6_0/ReduceLoginNameColumnsSize.cs | 4 +- .../V_7_7_0/AddIndexToDictionaryKeyColumn.cs | 4 +- .../Upgrade/V_7_7_0/AddUserGroupTables.cs | 27 +- .../V_7_7_0/ReduceDictionaryKeyColumnsSize.cs | 4 +- .../Upgrade/V_8_0_0/RefactorXmlColumns.cs | 39 +- .../Upgrade/V_8_0_0/VariantsMigration.cs | 7 +- .../Persistence/Constants-DbProviderNames.cs | 1 - .../DefinitionFactory.cs | 6 - .../Persistence/DbConnectionExtensions.cs | 13 - .../NPocoDatabaseExtensions-Bulk.cs | 4 - .../Persistence/NPocoDatabaseExtensions.cs | 28 +- .../NPocoDatabaseTypeExtensions.cs | 5 - .../Persistence/NPocoSqlExtensions.cs | 11 - .../Implement/ContentRepositoryBase.cs | 202 ---- .../Repositories/Implement/UserRepository.cs | 2 +- .../SqlSyntax/ISqlSyntaxProvider.cs | 1 - .../SqlSyntax/MySqlSyntaxProvider.cs | 402 ------- .../SqlSyntax/SqlSyntaxProviderBase.cs | 7 +- .../SqlSyntax/SqlSyntaxProviderExtensions.cs | 2 +- .../Persistence/UmbracoDatabase.cs | 10 +- .../Persistence/UmbracoDatabaseFactory.cs | 2 - src/Umbraco.Core/Umbraco.Core.csproj | 2 - src/Umbraco.Tests/App.config | 2 - .../Migrations/SqlScripts/MySqlTotal-480.sql | 822 ------------- .../SqlScripts/SqlResources.Designer.cs | 27 +- .../Migrations/SqlScripts/SqlResources.resx | 5 +- .../Persistence/Querying/ExpressionTests.cs | 36 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 1 - .../installer/steps/database.controller.js | 3 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 1 - src/Umbraco.Web.UI/web.Template.config | 8 - src/Umbraco.Web/Install/InstallHelper.cs | 2 - .../Install/Models/DatabaseType.cs | 1 - 49 files changed, 600 insertions(+), 2388 deletions(-) delete mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs delete mode 100644 src/Umbraco.Tests/Migrations/SqlScripts/MySqlTotal-480.sql diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index dd565aa1d4..8826705157 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -28,7 +28,6 @@ - diff --git a/build/NuSpecs/tools/Web.config.install.xdt b/build/NuSpecs/tools/Web.config.install.xdt index fa3ab86ba2..e3ba6b27df 100644 --- a/build/NuSpecs/tools/Web.config.install.xdt +++ b/build/NuSpecs/tools/Web.config.install.xdt @@ -38,10 +38,6 @@ - - - - @@ -49,11 +45,6 @@ - - - - - diff --git a/build/NuSpecs/tools/install.core.ps1 b/build/NuSpecs/tools/install.core.ps1 index 0a658266a1..9b609a498e 100644 --- a/build/NuSpecs/tools/install.core.ps1 +++ b/build/NuSpecs/tools/install.core.ps1 @@ -73,7 +73,6 @@ if ($project) { if(Test-Path $umbracoBinFolder\Microsoft.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Helpers.dll -Force -Confirm:$false } if(Test-Path $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll -Force -Confirm:$false } if(Test-Path $umbracoBinFolder\MiniProfiler.dll) { Remove-Item $umbracoBinFolder\MiniProfiler.dll -Force -Confirm:$false } - if(Test-Path $umbracoBinFolder\MySql.Data.dll) { Remove-Item $umbracoBinFolder\MySql.Data.dll -Force -Confirm:$false } if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false } if(Test-Path $umbracoBinFolder\Owin.dll) { Remove-Item $umbracoBinFolder\Owin.dll -Force -Confirm:$false } if(Test-Path $umbracoBinFolder\Semver.dll) { Remove-Item $umbracoBinFolder\Semver.dll -Force -Confirm:$false } diff --git a/src/Umbraco.Core/Constants-DatabaseProviders.cs b/src/Umbraco.Core/Constants-DatabaseProviders.cs index c1430eb82d..e93e524bbc 100644 --- a/src/Umbraco.Core/Constants-DatabaseProviders.cs +++ b/src/Umbraco.Core/Constants-DatabaseProviders.cs @@ -6,7 +6,6 @@ { public const string SqlCe = "System.Data.SqlServerCe.4.0"; public const string SqlServer = "System.Data.SqlClient"; - public const string MySql = "MySql.Data.MySqlClient"; } } } diff --git a/src/Umbraco.Core/Migrations/Expressions/Alter/Table/AlterTableBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Alter/Table/AlterTableBuilder.cs index eee9826a85..d5abe67af7 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Alter/Table/AlterTableBuilder.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Alter/Table/AlterTableBuilder.cs @@ -1,9 +1,7 @@ using System.Data; -using NPoco; using Umbraco.Core.Migrations.Expressions.Alter.Expressions; using Umbraco.Core.Migrations.Expressions.Common.Expressions; using Umbraco.Core.Migrations.Expressions.Create.Expressions; -using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -43,11 +41,11 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table if (CurrentColumn.ModificationType == ModificationType.Alter) { var dc = new AlterDefaultConstraintExpression(_context) - { - TableName = Expression.TableName, - ColumnName = CurrentColumn.Name, - DefaultValue = value - }; + { + TableName = Expression.TableName, + ColumnName = CurrentColumn.Name, + DefaultValue = value + }; Expression.Expressions.Add(dc); } @@ -78,9 +76,9 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table }); index.Index.Columns.Add(new IndexColumnDefinition - { - Name = CurrentColumn.Name - }); + { + Name = CurrentColumn.Name + }); Expression.Expressions.Add(index); @@ -91,19 +89,15 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table { CurrentColumn.IsPrimaryKey = true; - // see notes in CreateTableBuilder - if (Expression.DatabaseType.IsMySql() == false) + var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey) { - var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey) - { - Constraint = + Constraint = { TableName = Expression.TableName, Columns = new[] { CurrentColumn.Name } } - }; - Expression.Expressions.Add(expression); - } + }; + Expression.Expressions.Add(expression); return this; } @@ -113,20 +107,16 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table CurrentColumn.IsPrimaryKey = true; CurrentColumn.PrimaryKeyName = primaryKeyName; - // see notes in CreateTableBuilder - if (Expression.DatabaseType.IsMySql() == false) + var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey) { - var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey) - { - Constraint = + Constraint = { ConstraintName = primaryKeyName, TableName = Expression.TableName, Columns = new[] { CurrentColumn.Name } } - }; - Expression.Expressions.Add(expression); - } + }; + Expression.Expressions.Add(expression); return this; } @@ -155,14 +145,14 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table var index = new CreateIndexExpression(_context, new IndexDefinition { Name = indexName, - TableName = Expression.TableName, + TableName = Expression.TableName, IndexType = IndexTypes.UniqueNonClustered }); index.Index.Columns.Add(new IndexColumnDefinition - { - Name = CurrentColumn.Name - }); + { + Name = CurrentColumn.Name + }); Expression.Expressions.Add(index); @@ -241,10 +231,10 @@ namespace Umbraco.Core.Migrations.Expressions.Alter.Table { var column = new ColumnDefinition { Name = name, ModificationType = ModificationType.Create }; var createColumn = new CreateColumnExpression(_context) - { - Column = column, - TableName = Expression.TableName - }; + { + Column = column, + TableName = Expression.TableName + }; CurrentColumn = column; diff --git a/src/Umbraco.Core/Migrations/Expressions/Create/Table/CreateTableBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Create/Table/CreateTableBuilder.cs index f765a58169..a87abb2c84 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Create/Table/CreateTableBuilder.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Create/Table/CreateTableBuilder.cs @@ -94,25 +94,15 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Table { CurrentColumn.IsPrimaryKey = true; - //For MySQL, the PK will be created WITH the create table expression, however for - // SQL Server, the PK get's created in a different Alter table expression afterwords. - // MySQL will choke if the same constraint is again added afterword - // TODO: This is a super hack, I'd rather not add another property like 'CreatesPkInCreateTableDefinition' to check - // for this, but I don't see another way around. MySQL doesn't support checking for a constraint before creating - // it... except in a very strange way but it doesn't actually provider error feedback if it doesn't work so we cannot use - // it. For now, this is what I'm doing - if (Expression.DatabaseType.IsMySql() == false) + var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey) { - var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey) - { - Constraint = + Constraint = { TableName = CurrentColumn.TableName, Columns = new[] { CurrentColumn.Name } } - }; - Expression.Expressions.Add(expression); - } + }; + Expression.Expressions.Add(expression); return this; } @@ -123,27 +113,16 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Table CurrentColumn.IsPrimaryKey = true; CurrentColumn.PrimaryKeyName = primaryKeyName; - //For MySQL, the PK will be created WITH the create table expression, however for - // SQL Server, the PK get's created in a different Alter table expression afterwords. - // MySQL will choke if the same constraint is again added afterword - // TODO: This is a super hack, I'd rather not add another property like 'CreatesPkInCreateTableDefinition' to check - // for this, but I don't see another way around. MySQL doesn't support checking for a constraint before creating - // it... except in a very strange way but it doesn't actually provider error feedback if it doesn't work so we cannot use - // it. For now, this is what I'm doing - - if (Expression.DatabaseType.IsMySql() == false) + var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey) { - var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey) - { - Constraint = + Constraint = { ConstraintName = primaryKeyName, TableName = CurrentColumn.TableName, Columns = new[] { CurrentColumn.Name } } - }; - Expression.Expressions.Add(expression); - } + }; + Expression.Expressions.Add(expression); return this; } @@ -177,14 +156,14 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Table { Name = indexName, SchemaName = Expression.SchemaName, - TableName = Expression.TableName, + TableName = Expression.TableName, IndexType = IndexTypes.UniqueNonClustered }); index.Index.Columns.Add(new IndexColumnDefinition - { - Name = CurrentColumn.Name - }); + { + Name = CurrentColumn.Name + }); Expression.Expressions.Add(index); diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteConstraintExpression.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteConstraintExpression.cs index 25777c5541..c5d986b8d2 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteConstraintExpression.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteConstraintExpression.cs @@ -1,6 +1,4 @@ -using NPoco; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions { @@ -16,19 +14,9 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions protected override string GetSql() { - return DatabaseType.IsMySql() - ? GetMySql() - : string.Format(SqlSyntax.DeleteConstraint, + return string.Format(SqlSyntax.DeleteConstraint, SqlSyntax.GetQuotedTableName(Constraint.TableName), SqlSyntax.GetQuotedName(Constraint.ConstraintName)); } - - private string GetMySql() - { - return string.Format(SqlSyntax.DeleteConstraint, - SqlSyntax.GetQuotedTableName(Constraint.TableName), - Constraint.IsPrimaryKeyConstraint ? "PRIMARY KEY" : "FOREIGN KEY", - ""); - } } } diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteForeignKeyExpression.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteForeignKeyExpression.cs index 037b5eac89..73688233b6 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteForeignKeyExpression.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteForeignKeyExpression.cs @@ -1,7 +1,5 @@ using System; using System.Linq; -using NPoco; -using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions @@ -20,10 +18,7 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions { if (ForeignKey.ForeignTable == null) throw new ArgumentNullException("Table name not specified, ensure you have appended the OnTable extension. Format should be Delete.ForeignKey(KeyName).OnTable(TableName)"); - - if (DatabaseType.IsMySql()) - return GetMySql(); - + if (string.IsNullOrEmpty(ForeignKey.Name)) { ForeignKey.Name = $"FK_{ForeignKey.ForeignTable}_{ForeignKey.PrimaryTable}_{ForeignKey.PrimaryColumns.First()}"; @@ -33,17 +28,5 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions SqlSyntax.GetQuotedTableName(ForeignKey.ForeignTable), SqlSyntax.GetQuotedName(ForeignKey.Name)); } - - private string GetMySql() - { - // MySql naming "convention" for foreignkeys, which aren't explicitly named - if (string.IsNullOrEmpty(ForeignKey.Name)) - ForeignKey.Name = $"{ForeignKey.ForeignTable.ToLower()}_ibfk_1"; - - return string.Format(SqlSyntax.DeleteConstraint, - SqlSyntax.GetQuotedTableName(ForeignKey.ForeignTable), - "FOREIGN KEY", - SqlSyntax.GetQuotedName(ForeignKey.Name)); - } } } diff --git a/src/Umbraco.Core/Migrations/Expressions/Insert/Expressions/InsertDataExpression.cs b/src/Umbraco.Core/Migrations/Expressions/Insert/Expressions/InsertDataExpression.cs index 7efe457402..75768faad8 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Insert/Expressions/InsertDataExpression.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Insert/Expressions/InsertDataExpression.cs @@ -1,8 +1,5 @@ using System.Collections.Generic; using System.Text; -using System.Linq; -using NPoco; -using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Migrations.Expressions.Insert.Expressions diff --git a/src/Umbraco.Core/Migrations/Expressions/Rename/Expressions/RenameColumnExpression.cs b/src/Umbraco.Core/Migrations/Expressions/Rename/Expressions/RenameColumnExpression.cs index 0f73c06f15..3ab5fd27b9 100644 --- a/src/Umbraco.Core/Migrations/Expressions/Rename/Expressions/RenameColumnExpression.cs +++ b/src/Umbraco.Core/Migrations/Expressions/Rename/Expressions/RenameColumnExpression.cs @@ -1,7 +1,4 @@ -using NPoco; -using Umbraco.Core.Persistence; - -namespace Umbraco.Core.Migrations.Expressions.Rename.Expressions +namespace Umbraco.Core.Migrations.Expressions.Rename.Expressions { public class RenameColumnExpression : MigrationExpressionBase { @@ -18,33 +15,8 @@ namespace Umbraco.Core.Migrations.Expressions.Rename.Expressions /// protected override string GetSql() - { - return DatabaseType.IsMySql() - ? GetMySql() - : GetBaseSql(); - } - - private string GetBaseSql() { return SqlSyntax.FormatColumnRename(TableName, OldName, NewName); } - - private string GetMySql() - { - var columnDefinitionSql = $@" -SELECT CONCAT( - CAST(COLUMN_TYPE AS CHAR), - IF(ISNULL(CHARACTER_SET_NAME), '', CONCAT(' CHARACTER SET ', CHARACTER_SET_NAME)), - IF(ISNULL(COLLATION_NAME), '', CONCAT(' COLLATE ', COLLATION_NAME)), - ' ', - IF(IS_NULLABLE = 'NO', 'NOT NULL ', ''), - IF(IS_NULLABLE = 'NO' AND COLUMN_DEFAULT IS NULL, '', CONCAT('DEFAULT ', QUOTE(COLUMN_DEFAULT), ' ')), - UPPER(extra)) -FROM INFORMATION_SCHEMA.COLUMNS -WHERE TABLE_NAME = '{TableName}' AND COLUMN_NAME = '{OldName}'"; - - var columnDefinition = Database.ExecuteScalar(columnDefinitionSql); - return GetBaseSql() + " " + columnDefinition; - } } } diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs index e2c34c31cb..4104ce947c 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs @@ -11,7 +11,6 @@ using Umbraco.Core.Logging; using Umbraco.Core.Migrations.Upgrade; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Scoping; using Umbraco.Core.Services; @@ -151,13 +150,10 @@ namespace Umbraco.Core.Migrations.Install /// Configures a connection string that has been entered manually. /// /// A connection string. - /// Has to be either SQL Server or MySql + /// Has to be SQL Server public void ConfigureDatabaseConnection(string connectionString) { - var provider = DbConnectionExtensions.DetectProviderNameFromConnectionString(connectionString); - var providerName = provider.ToString().ToLower().Contains("mysql") - ? Constants.DbProviderNames.MySql - : Constants.DbProviderNames.SqlServer; + const string providerName = Constants.DbProviderNames.SqlServer; SaveConnectionString(connectionString, providerName, _logger); _databaseFactory.Configure(connectionString, providerName); @@ -170,7 +166,7 @@ namespace Umbraco.Core.Migrations.Install /// The name of the database. /// The user name. /// The user password. - /// The name the provider (Sql, Sql Azure, Sql Ce, MySql). + /// The name of the provider (Sql, Sql Azure, Sql Ce). public void ConfigureDatabaseConnection(string server, string databaseName, string user, string password, string databaseProvider) { var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out var providerName); @@ -186,22 +182,15 @@ namespace Umbraco.Core.Migrations.Install /// The name of the database. /// The user name. /// The user password. - /// The name the provider (Sql, Sql Azure, Sql Ce, MySql). + /// The name of the provider (Sql, Sql Azure, Sql Ce). /// /// A connection string. public static string GetDatabaseConnectionString(string server, string databaseName, string user, string password, string databaseProvider, out string providerName) { providerName = Constants.DbProviderNames.SqlServer; - var test = databaseProvider.ToLower(); - if (test.Contains("mysql")) - { - providerName = Constants.DbProviderNames.MySql; - return $"Server={server}; Database={databaseName};Uid={user};Pwd={password}"; - } - if (test.Contains("azure")) - { + var provider = databaseProvider.ToLower(); + if (provider.InvariantContains("azure")) return GetAzureConnectionString(server, databaseName, user, password); - } return $"server={server};database={databaseName};user id={user};password={password}"; } @@ -433,10 +422,9 @@ namespace Umbraco.Core.Migrations.Install _logger.Info("Database configuration status: Started"); var database = scope.Database; + + var message = string.Empty; - // If MySQL, we're going to ensure that database calls are maintaining proper casing as to remove the necessity for checks - // for case insensitive queries. In an ideal situation (which is what we're striving for), all calls would be case sensitive. - var message = database.DatabaseType.IsMySql() ? ResultMessageForMySql : ""; var schemaResult = ValidateSchema(); var hasInstalledVersion = schemaResult.DetermineHasInstalledVersion(); //var installedSchemaVersion = schemaResult.DetermineInstalledVersion(); @@ -494,14 +482,12 @@ namespace Umbraco.Core.Migrations.Install } _logger.Info("Database upgrade started"); - - var message = _scopeProvider.SqlContext.DatabaseType.IsMySql() ? ResultMessageForMySql : ""; - + // upgrade var upgrader = new UmbracoUpgrader(); upgrader.Execute(_scopeProvider, _migrationBuilder, _keyValueService, _logger, _postMigrations); - message = message + "

Upgrade completed!

"; + var message = "

Upgrade completed!

"; //now that everything is done, we need to determine the version of SQL server that is executing @@ -515,15 +501,6 @@ namespace Umbraco.Core.Migrations.Install } } - private const string ResultMessageForMySql = "

 

Congratulations, the database step ran successfully!

" + - "

Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.

" + - "

However, your hosting provider may not support this option. Umbraco does not currently support MySQL installs that do not support case insensitive queries

" + - "

Make sure to check with your hosting provider if they support case insensitive queries as well.

" + - "

They can check this by looking for the following setting in the my.ini file in their MySQL installation directory:

" + - "
lower_case_table_names=1

" + - "

For more technical information on case sensitivity in MySQL, have a look at " + - "the documentation on the subject

"; - private Attempt CheckReadyForInstall() { if (_databaseFactory.Configured == false) diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs index f9f3e5da30..bfb4d3071f 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs @@ -1,524 +1,512 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NPoco; -using Umbraco.Core.Events; -using Umbraco.Core.Logging; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.DatabaseModelDefinitions; -using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.SqlSyntax; - -namespace Umbraco.Core.Migrations.Install -{ - /// - /// Creates the initial database schema during install. - /// - public class DatabaseSchemaCreator - { - private readonly IUmbracoDatabase _database; - private readonly ILogger _logger; - - public DatabaseSchemaCreator(IUmbracoDatabase database, ILogger logger) - { - _database = database; - _logger = logger; - } - - private ISqlSyntaxProvider SqlSyntax => _database.SqlContext.SqlSyntax; - - // all tables, in order - internal static readonly List OrderedTables = new List - { - typeof (UserDto), - typeof (NodeDto), - typeof (ContentTypeDto), - typeof (TemplateDto), - typeof (ContentDto), - typeof (ContentVersionDto), - typeof (MediaVersionDto), - typeof (DocumentDto), - typeof (ContentTypeTemplateDto), - typeof (DataTypeDto), - typeof (DictionaryDto), - typeof (LanguageDto), - typeof (LanguageTextDto), - typeof (DomainDto), - typeof (LogDto), - typeof (MacroDto), - typeof (MacroPropertyDto), - typeof (MemberTypeDto), - typeof (MemberDto), - typeof (Member2MemberGroupDto), - typeof (ContentXmlDto), - typeof (PreviewXmlDto), - typeof (PropertyTypeGroupDto), - typeof (PropertyTypeDto), - typeof (PropertyDataDto), - typeof (RelationTypeDto), - typeof (RelationDto), - typeof (TagDto), - typeof (TagRelationshipDto), - typeof (ContentType2ContentTypeDto), - typeof (ContentTypeAllowedContentTypeDto), - typeof (User2NodeNotifyDto), - typeof (ServerRegistrationDto), - typeof (AccessDto), - typeof (AccessRuleDto), - typeof (CacheInstructionDto), - typeof (ExternalLoginDto), - typeof (RedirectUrlDto), - typeof (LockDto), - typeof (UserGroupDto), - typeof (User2UserGroupDto), - typeof (UserGroup2NodePermissionDto), - typeof (UserGroup2AppDto), - typeof (UserStartNodeDto), - typeof (ContentNuDto), - typeof (DocumentVersionDto), - typeof (KeyValueDto), - typeof (UserLoginDto), - typeof (ConsentDto), - typeof (AuditEntryDto), - typeof (ContentVersionCultureVariationDto), - typeof (DocumentCultureVariationDto), - typeof (ContentScheduleDto) - }; - - /// - /// Drops all Umbraco tables in the db. - /// - internal void UninstallDatabaseSchema() - { - _logger.Info("Start UninstallDatabaseSchema"); - - foreach (var table in OrderedTables.AsEnumerable().Reverse()) - { - var tableNameAttribute = table.FirstAttribute(); - var tableName = tableNameAttribute == null ? table.Name : tableNameAttribute.Value; - - _logger.Info("Uninstall {TableName}", tableName); - - try - { - if (TableExists(tableName)) - DropTable(tableName); - } - catch (Exception ex) - { - //swallow this for now, not sure how best to handle this with diff databases... though this is internal - // and only used for unit tests. If this fails its because the table doesn't exist... generally! - _logger.Error(ex, "Could not drop table {TableName}", tableName); - } - } - } - - /// - /// Initializes the database by creating the umbraco db schema. - /// - /// This needs to execute as part of a transaction. - public void InitializeDatabaseSchema() - { - if (!_database.InTransaction) - throw new InvalidOperationException("Database is not in a transaction."); - - var e = new DatabaseCreationEventArgs(); - FireBeforeCreation(e); - - if (e.Cancel == false) - { - var dataCreation = new DatabaseDataCreator(_database, _logger); - foreach (var table in OrderedTables) - CreateTable(false, table, dataCreation); - } - - FireAfterCreation(e); - } - - /// - /// Validates the schema of the current database. - /// - internal DatabaseSchemaResult ValidateSchema() - { - var result = new DatabaseSchemaResult(SqlSyntax); - - result.IndexDefinitions.AddRange(SqlSyntax.GetDefinedIndexes(_database) - .Select(x => new DbIndexDefinition(x))); - - result.TableDefinitions.AddRange(OrderedTables - .Select(x => DefinitionFactory.GetTableDefinition(x, SqlSyntax))); - - ValidateDbTables(result); - ValidateDbColumns(result); - ValidateDbIndexes(result); - ValidateDbConstraints(result); - - return result; - } - - /// - /// This validates the Primary/Foreign keys in the database - /// - /// - /// - /// This does not validate any database constraints that are not PKs or FKs because Umbraco does not create a database with non PK/FK contraints. - /// Any unique "constraints" in the database are done with unique indexes. - /// - private void ValidateDbConstraints(DatabaseSchemaResult result) - { - //MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks. - //TODO: At a later point we do other checks for MySql, but ideally it should be necessary to do special checks for different providers. - // ALso note that to get the constraints for MySql we have to open a connection which we currently have not. - if (SqlSyntax is MySqlSyntaxProvider) - return; - - //Check constraints in configured database against constraints in schema - var constraintsInDatabase = SqlSyntax.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList(); - var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("FK_")).Select(x => x.Item3).ToList(); - var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("PK_")).Select(x => x.Item3).ToList(); - - var unknownConstraintsInDatabase = - constraintsInDatabase.Where( - x => - x.Item3.InvariantStartsWith("FK_") == false && x.Item3.InvariantStartsWith("PK_") == false && - x.Item3.InvariantStartsWith("IX_") == false).Select(x => x.Item3).ToList(); - var foreignKeysInSchema = result.TableDefinitions.SelectMany(x => x.ForeignKeys.Select(y => y.Name)).ToList(); - var primaryKeysInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => y.PrimaryKeyName)) - .Where(x => x.IsNullOrWhiteSpace() == false).ToList(); - - //Add valid and invalid foreign key differences to the result object - // We'll need to do invariant contains with case insensitivity because foreign key, primary key, and even index naming w/ MySQL is not standardized - // In theory you could have: FK_ or fk_ ...or really any standard that your development department (or developer) chooses to use. - foreach (var unknown in unknownConstraintsInDatabase) - { - if (foreignKeysInSchema.InvariantContains(unknown) || primaryKeysInSchema.InvariantContains(unknown)) - { - result.ValidConstraints.Add(unknown); - } - else - { - result.Errors.Add(new Tuple("Unknown", unknown)); - } - } - - //Foreign keys: - - var validForeignKeyDifferences = foreignKeysInDatabase.Intersect(foreignKeysInSchema, StringComparer.InvariantCultureIgnoreCase); - foreach (var foreignKey in validForeignKeyDifferences) - { - result.ValidConstraints.Add(foreignKey); - } - var invalidForeignKeyDifferences = - foreignKeysInDatabase.Except(foreignKeysInSchema, StringComparer.InvariantCultureIgnoreCase) - .Union(foreignKeysInSchema.Except(foreignKeysInDatabase, StringComparer.InvariantCultureIgnoreCase)); - foreach (var foreignKey in invalidForeignKeyDifferences) - { - result.Errors.Add(new Tuple("Constraint", foreignKey)); - } - - - //Primary keys: - - //Add valid and invalid primary key differences to the result object - var validPrimaryKeyDifferences = primaryKeysInDatabase.Intersect(primaryKeysInSchema, StringComparer.InvariantCultureIgnoreCase); - foreach (var primaryKey in validPrimaryKeyDifferences) - { - result.ValidConstraints.Add(primaryKey); - } - var invalidPrimaryKeyDifferences = - primaryKeysInDatabase.Except(primaryKeysInSchema, StringComparer.InvariantCultureIgnoreCase) - .Union(primaryKeysInSchema.Except(primaryKeysInDatabase, StringComparer.InvariantCultureIgnoreCase)); - foreach (var primaryKey in invalidPrimaryKeyDifferences) - { - result.Errors.Add(new Tuple("Constraint", primaryKey)); - } - - } - - private void ValidateDbColumns(DatabaseSchemaResult result) - { - //Check columns in configured database against columns in schema - var columnsInDatabase = SqlSyntax.GetColumnsInSchema(_database); - var columnsPerTableInDatabase = columnsInDatabase.Select(x => string.Concat(x.TableName, ",", x.ColumnName)).ToList(); - var columnsPerTableInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => string.Concat(y.TableName, ",", y.Name))).ToList(); - //Add valid and invalid column differences to the result object - var validColumnDifferences = columnsPerTableInDatabase.Intersect(columnsPerTableInSchema, StringComparer.InvariantCultureIgnoreCase); - foreach (var column in validColumnDifferences) - { - result.ValidColumns.Add(column); - } - - var invalidColumnDifferences = - columnsPerTableInDatabase.Except(columnsPerTableInSchema, StringComparer.InvariantCultureIgnoreCase) - .Union(columnsPerTableInSchema.Except(columnsPerTableInDatabase, StringComparer.InvariantCultureIgnoreCase)); - foreach (var column in invalidColumnDifferences) - { - result.Errors.Add(new Tuple("Column", column)); - } - } - - private void ValidateDbTables(DatabaseSchemaResult result) - { - //Check tables in configured database against tables in schema - var tablesInDatabase = SqlSyntax.GetTablesInSchema(_database).ToList(); - var tablesInSchema = result.TableDefinitions.Select(x => x.Name).ToList(); - //Add valid and invalid table differences to the result object - var validTableDifferences = tablesInDatabase.Intersect(tablesInSchema, StringComparer.InvariantCultureIgnoreCase); - foreach (var tableName in validTableDifferences) - { - result.ValidTables.Add(tableName); - } - - var invalidTableDifferences = - tablesInDatabase.Except(tablesInSchema, StringComparer.InvariantCultureIgnoreCase) - .Union(tablesInSchema.Except(tablesInDatabase, StringComparer.InvariantCultureIgnoreCase)); - foreach (var tableName in invalidTableDifferences) - { - result.Errors.Add(new Tuple("Table", tableName)); - } - } - - private void ValidateDbIndexes(DatabaseSchemaResult result) - { - //These are just column indexes NOT constraints or Keys - //var colIndexesInDatabase = result.DbIndexDefinitions.Where(x => x.IndexName.InvariantStartsWith("IX_")).Select(x => x.IndexName).ToList(); - var colIndexesInDatabase = result.IndexDefinitions.Select(x => x.IndexName).ToList(); - var indexesInSchema = result.TableDefinitions.SelectMany(x => x.Indexes.Select(y => y.Name)).ToList(); - - //Add valid and invalid index differences to the result object - var validColIndexDifferences = colIndexesInDatabase.Intersect(indexesInSchema, StringComparer.InvariantCultureIgnoreCase); - foreach (var index in validColIndexDifferences) - { - result.ValidIndexes.Add(index); - } - - var invalidColIndexDifferences = - colIndexesInDatabase.Except(indexesInSchema, StringComparer.InvariantCultureIgnoreCase) - .Union(indexesInSchema.Except(colIndexesInDatabase, StringComparer.InvariantCultureIgnoreCase)); - foreach (var index in invalidColIndexDifferences) - { - result.Errors.Add(new Tuple("Index", index)); - } - } - - #region Events - - /// - /// The save event handler - /// - internal delegate void DatabaseEventHandler(DatabaseCreationEventArgs e); - - /// - /// Occurs when [before save]. - /// - internal static event DatabaseEventHandler BeforeCreation; - /// - /// Raises the event. - /// - /// The instance containing the event data. - internal virtual void FireBeforeCreation(DatabaseCreationEventArgs e) - { - BeforeCreation?.Invoke(e); - } - - /// - /// Occurs when [after save]. - /// - internal static event DatabaseEventHandler AfterCreation; - /// - /// Raises the event. - /// - /// The instance containing the event data. - internal virtual void FireAfterCreation(DatabaseCreationEventArgs e) - { - AfterCreation?.Invoke(e); - } - - #endregion - - #region Utilities - - /// - /// Returns whether a table with the specified exists in the database. - /// - /// The name of the table. - /// true if the table exists; otherwise false. - /// - /// - /// if (schemaHelper.TableExist("MyTable")) - /// { - /// // do something when the table exists - /// } - /// - /// - public bool TableExists(string tableName) - { - return SqlSyntax.DoesTableExist(_database, tableName); - } - - /// - /// Returns whether the table for the specified exists in the database. - /// - /// The type representing the DTO/table. - /// true if the table exists; otherwise false. - /// - /// - /// if (schemaHelper.TableExist<MyDto>) - /// { - /// // do something when the table exists - /// } - /// - /// - /// - /// If has been decorated with an , the name from that - /// attribute will be used for the table name. If the attribute is not present, the name - /// will be used instead. - /// - public bool TableExists() { - var table = DefinitionFactory.GetTableDefinition(typeof(T), SqlSyntax); - return table != null && TableExists(table.Name); } - - /// - /// Creates a new table in the database based on the type of . - /// - /// The type representing the DTO/table. - /// Whether the table should be overwritten if it already exists. - /// - /// If has been decorated with an , the name from that - /// attribute will be used for the table name. If the attribute is not present, the name - /// will be used instead. - /// - /// If a table with the same name already exists, the parameter will determine - /// whether the table is overwritten. If true, the table will be overwritten, whereas this method will - /// not do anything if the parameter is false. - /// - internal void CreateTable(bool overwrite = false) - where T : new() - { - var tableType = typeof(T); - CreateTable(overwrite, tableType, new DatabaseDataCreator(_database, _logger)); - } - - /// - /// Creates a new table in the database for the specified . - /// - /// Whether the table should be overwritten if it already exists. - /// The the representing the table. - /// - /// - /// If has been decorated with an , the name from - /// that attribute will be used for the table name. If the attribute is not present, the name - /// will be used instead. - /// - /// If a table with the same name already exists, the parameter will determine - /// whether the table is overwritten. If true, the table will be overwritten, whereas this method will - /// not do anything if the parameter is false. - /// - /// This need to execute as part of a transaction. - /// - internal void CreateTable(bool overwrite, Type modelType, DatabaseDataCreator dataCreation) - { - if (!_database.InTransaction) - throw new InvalidOperationException("Database is not in a transaction."); - - var tableDefinition = DefinitionFactory.GetTableDefinition(modelType, SqlSyntax); - var tableName = tableDefinition.Name; - - var createSql = SqlSyntax.Format(tableDefinition); - var createPrimaryKeySql = SqlSyntax.FormatPrimaryKey(tableDefinition); - var foreignSql = SqlSyntax.Format(tableDefinition.ForeignKeys); - var indexSql = SqlSyntax.Format(tableDefinition.Indexes); - - var tableExist = TableExists(tableName); - if (overwrite && tableExist) - { - _logger.Info("Table '{TableName}' already exists, but will be recreated", tableName); - - DropTable(tableName); - tableExist = false; - } - - if (tableExist) - { - // The table exists and was not recreated/overwritten. - _logger.Info("Table '{TableName}' already exists - no changes were made", tableName); - return; - } - - //Execute the Create Table sql - var created = _database.Execute(new Sql(createSql)); - _logger.Info("Create Table '{TableName}' ({Created}): \n {Sql}", tableName, created, createSql); - - //If any statements exists for the primary key execute them here - if (string.IsNullOrEmpty(createPrimaryKeySql) == false) - { - var createdPk = _database.Execute(new Sql(createPrimaryKeySql)); - _logger.Info("Create Primary Key ({CreatedPk}):\n {Sql}", createdPk, createPrimaryKeySql); - } - - //Turn on identity insert if db provider is not mysql - if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) - _database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} ON ")); - - //Call the NewTable-event to trigger the insert of base/default data - //OnNewTable(tableName, _db, e, _logger); - - dataCreation.InitializeBaseData(tableName); - - //Turn off identity insert if db provider is not mysql - if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) - _database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} OFF;")); - - //Special case for MySql - if (SqlSyntax is MySqlSyntaxProvider && tableName.Equals("umbracoUser")) - { - _database.Update("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "admin" }); - } - - //Loop through index statements and execute sql - foreach (var sql in indexSql) - { - var createdIndex = _database.Execute(new Sql(sql)); - _logger.Info("Create Index ({CreatedIndex}):\n {Sql}", createdIndex, sql); - } - - //Loop through foreignkey statements and execute sql - foreach (var sql in foreignSql) - { - var createdFk = _database.Execute(new Sql(sql)); - _logger.Info("Create Foreign Key ({CreatedFk}):\n {Sql}", createdFk, sql); - } - - if (overwrite) - { - _logger.Info("Table '{TableName}' was recreated", tableName); - } - else - { - _logger.Info("New table '{TableName}' was created", tableName); - } - } - - /// - /// Drops the table for the specified . - /// - /// The type representing the DTO/table. - /// - /// - /// schemaHelper.DropTable<MyDto>); - /// - /// - /// - /// If has been decorated with an , the name from that - /// attribute will be used for the table name. If the attribute is not present, the name - /// will be used instead. - /// - public void DropTable(string tableName) - { - var sql = new Sql(string.Format(SqlSyntax.DropTable, SqlSyntax.GetQuotedTableName(tableName))); - _database.Execute(sql); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using NPoco; +using Umbraco.Core.Events; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.Dtos; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Migrations.Install +{ + /// + /// Creates the initial database schema during install. + /// + public class DatabaseSchemaCreator + { + private readonly IUmbracoDatabase _database; + private readonly ILogger _logger; + + public DatabaseSchemaCreator(IUmbracoDatabase database, ILogger logger) + { + _database = database; + _logger = logger; + } + + private ISqlSyntaxProvider SqlSyntax => _database.SqlContext.SqlSyntax; + + // all tables, in order + internal static readonly List OrderedTables = new List + { + typeof (UserDto), + typeof (NodeDto), + typeof (ContentTypeDto), + typeof (TemplateDto), + typeof (ContentDto), + typeof (ContentVersionDto), + typeof (MediaVersionDto), + typeof (DocumentDto), + typeof (ContentTypeTemplateDto), + typeof (DataTypeDto), + typeof (DictionaryDto), + typeof (LanguageDto), + typeof (LanguageTextDto), + typeof (DomainDto), + typeof (LogDto), + typeof (MacroDto), + typeof (MacroPropertyDto), + typeof (MemberTypeDto), + typeof (MemberDto), + typeof (Member2MemberGroupDto), + typeof (ContentXmlDto), + typeof (PreviewXmlDto), + typeof (PropertyTypeGroupDto), + typeof (PropertyTypeDto), + typeof (PropertyDataDto), + typeof (RelationTypeDto), + typeof (RelationDto), + typeof (TagDto), + typeof (TagRelationshipDto), + typeof (ContentType2ContentTypeDto), + typeof (ContentTypeAllowedContentTypeDto), + typeof (User2NodeNotifyDto), + typeof (ServerRegistrationDto), + typeof (AccessDto), + typeof (AccessRuleDto), + typeof (CacheInstructionDto), + typeof (ExternalLoginDto), + typeof (RedirectUrlDto), + typeof (LockDto), + typeof (UserGroupDto), + typeof (User2UserGroupDto), + typeof (UserGroup2NodePermissionDto), + typeof (UserGroup2AppDto), + typeof (UserStartNodeDto), + typeof (ContentNuDto), + typeof (DocumentVersionDto), + typeof (KeyValueDto), + typeof (UserLoginDto), + typeof (ConsentDto), + typeof (AuditEntryDto), + typeof (ContentVersionCultureVariationDto), + typeof (DocumentCultureVariationDto), + typeof (ContentScheduleDto) + }; + + /// + /// Drops all Umbraco tables in the db. + /// + internal void UninstallDatabaseSchema() + { + _logger.Info("Start UninstallDatabaseSchema"); + + foreach (var table in OrderedTables.AsEnumerable().Reverse()) + { + var tableNameAttribute = table.FirstAttribute(); + var tableName = tableNameAttribute == null ? table.Name : tableNameAttribute.Value; + + _logger.Info("Uninstall {TableName}", tableName); + + try + { + if (TableExists(tableName)) + DropTable(tableName); + } + catch (Exception ex) + { + //swallow this for now, not sure how best to handle this with diff databases... though this is internal + // and only used for unit tests. If this fails its because the table doesn't exist... generally! + _logger.Error(ex, "Could not drop table {TableName}", tableName); + } + } + } + + /// + /// Initializes the database by creating the umbraco db schema. + /// + /// This needs to execute as part of a transaction. + public void InitializeDatabaseSchema() + { + if (!_database.InTransaction) + throw new InvalidOperationException("Database is not in a transaction."); + + var e = new DatabaseCreationEventArgs(); + FireBeforeCreation(e); + + if (e.Cancel == false) + { + var dataCreation = new DatabaseDataCreator(_database, _logger); + foreach (var table in OrderedTables) + CreateTable(false, table, dataCreation); + } + + FireAfterCreation(e); + } + + /// + /// Validates the schema of the current database. + /// + internal DatabaseSchemaResult ValidateSchema() + { + var result = new DatabaseSchemaResult(SqlSyntax); + + result.IndexDefinitions.AddRange(SqlSyntax.GetDefinedIndexes(_database) + .Select(x => new DbIndexDefinition(x))); + + result.TableDefinitions.AddRange(OrderedTables + .Select(x => DefinitionFactory.GetTableDefinition(x, SqlSyntax))); + + ValidateDbTables(result); + ValidateDbColumns(result); + ValidateDbIndexes(result); + ValidateDbConstraints(result); + + return result; + } + + /// + /// This validates the Primary/Foreign keys in the database + /// + /// + /// + /// This does not validate any database constraints that are not PKs or FKs because Umbraco does not create a database with non PK/FK contraints. + /// Any unique "constraints" in the database are done with unique indexes. + /// + private void ValidateDbConstraints(DatabaseSchemaResult result) + { + //Check constraints in configured database against constraints in schema + var constraintsInDatabase = SqlSyntax.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList(); + var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("FK_")).Select(x => x.Item3).ToList(); + var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("PK_")).Select(x => x.Item3).ToList(); + + var unknownConstraintsInDatabase = + constraintsInDatabase.Where( + x => + x.Item3.InvariantStartsWith("FK_") == false && x.Item3.InvariantStartsWith("PK_") == false && + x.Item3.InvariantStartsWith("IX_") == false).Select(x => x.Item3).ToList(); + var foreignKeysInSchema = result.TableDefinitions.SelectMany(x => x.ForeignKeys.Select(y => y.Name)).ToList(); + var primaryKeysInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => y.PrimaryKeyName)) + .Where(x => x.IsNullOrWhiteSpace() == false).ToList(); + + // Add valid and invalid foreign key differences to the result object + // We'll need to do invariant contains with case insensitivity because foreign key, primary key is not standardized + // In theory you could have: FK_ or fk_ ...or really any standard that your development department (or developer) chooses to use. + foreach (var unknown in unknownConstraintsInDatabase) + { + if (foreignKeysInSchema.InvariantContains(unknown) || primaryKeysInSchema.InvariantContains(unknown)) + { + result.ValidConstraints.Add(unknown); + } + else + { + result.Errors.Add(new Tuple("Unknown", unknown)); + } + } + + //Foreign keys: + + var validForeignKeyDifferences = foreignKeysInDatabase.Intersect(foreignKeysInSchema, StringComparer.InvariantCultureIgnoreCase); + foreach (var foreignKey in validForeignKeyDifferences) + { + result.ValidConstraints.Add(foreignKey); + } + var invalidForeignKeyDifferences = + foreignKeysInDatabase.Except(foreignKeysInSchema, StringComparer.InvariantCultureIgnoreCase) + .Union(foreignKeysInSchema.Except(foreignKeysInDatabase, StringComparer.InvariantCultureIgnoreCase)); + foreach (var foreignKey in invalidForeignKeyDifferences) + { + result.Errors.Add(new Tuple("Constraint", foreignKey)); + } + + + //Primary keys: + + //Add valid and invalid primary key differences to the result object + var validPrimaryKeyDifferences = primaryKeysInDatabase.Intersect(primaryKeysInSchema, StringComparer.InvariantCultureIgnoreCase); + foreach (var primaryKey in validPrimaryKeyDifferences) + { + result.ValidConstraints.Add(primaryKey); + } + var invalidPrimaryKeyDifferences = + primaryKeysInDatabase.Except(primaryKeysInSchema, StringComparer.InvariantCultureIgnoreCase) + .Union(primaryKeysInSchema.Except(primaryKeysInDatabase, StringComparer.InvariantCultureIgnoreCase)); + foreach (var primaryKey in invalidPrimaryKeyDifferences) + { + result.Errors.Add(new Tuple("Constraint", primaryKey)); + } + + } + + private void ValidateDbColumns(DatabaseSchemaResult result) + { + //Check columns in configured database against columns in schema + var columnsInDatabase = SqlSyntax.GetColumnsInSchema(_database); + var columnsPerTableInDatabase = columnsInDatabase.Select(x => string.Concat(x.TableName, ",", x.ColumnName)).ToList(); + var columnsPerTableInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => string.Concat(y.TableName, ",", y.Name))).ToList(); + //Add valid and invalid column differences to the result object + var validColumnDifferences = columnsPerTableInDatabase.Intersect(columnsPerTableInSchema, StringComparer.InvariantCultureIgnoreCase); + foreach (var column in validColumnDifferences) + { + result.ValidColumns.Add(column); + } + + var invalidColumnDifferences = + columnsPerTableInDatabase.Except(columnsPerTableInSchema, StringComparer.InvariantCultureIgnoreCase) + .Union(columnsPerTableInSchema.Except(columnsPerTableInDatabase, StringComparer.InvariantCultureIgnoreCase)); + foreach (var column in invalidColumnDifferences) + { + result.Errors.Add(new Tuple("Column", column)); + } + } + + private void ValidateDbTables(DatabaseSchemaResult result) + { + //Check tables in configured database against tables in schema + var tablesInDatabase = SqlSyntax.GetTablesInSchema(_database).ToList(); + var tablesInSchema = result.TableDefinitions.Select(x => x.Name).ToList(); + //Add valid and invalid table differences to the result object + var validTableDifferences = tablesInDatabase.Intersect(tablesInSchema, StringComparer.InvariantCultureIgnoreCase); + foreach (var tableName in validTableDifferences) + { + result.ValidTables.Add(tableName); + } + + var invalidTableDifferences = + tablesInDatabase.Except(tablesInSchema, StringComparer.InvariantCultureIgnoreCase) + .Union(tablesInSchema.Except(tablesInDatabase, StringComparer.InvariantCultureIgnoreCase)); + foreach (var tableName in invalidTableDifferences) + { + result.Errors.Add(new Tuple("Table", tableName)); + } + } + + private void ValidateDbIndexes(DatabaseSchemaResult result) + { + //These are just column indexes NOT constraints or Keys + //var colIndexesInDatabase = result.DbIndexDefinitions.Where(x => x.IndexName.InvariantStartsWith("IX_")).Select(x => x.IndexName).ToList(); + var colIndexesInDatabase = result.IndexDefinitions.Select(x => x.IndexName).ToList(); + var indexesInSchema = result.TableDefinitions.SelectMany(x => x.Indexes.Select(y => y.Name)).ToList(); + + //Add valid and invalid index differences to the result object + var validColIndexDifferences = colIndexesInDatabase.Intersect(indexesInSchema, StringComparer.InvariantCultureIgnoreCase); + foreach (var index in validColIndexDifferences) + { + result.ValidIndexes.Add(index); + } + + var invalidColIndexDifferences = + colIndexesInDatabase.Except(indexesInSchema, StringComparer.InvariantCultureIgnoreCase) + .Union(indexesInSchema.Except(colIndexesInDatabase, StringComparer.InvariantCultureIgnoreCase)); + foreach (var index in invalidColIndexDifferences) + { + result.Errors.Add(new Tuple("Index", index)); + } + } + + #region Events + + /// + /// The save event handler + /// + internal delegate void DatabaseEventHandler(DatabaseCreationEventArgs e); + + /// + /// Occurs when [before save]. + /// + internal static event DatabaseEventHandler BeforeCreation; + /// + /// Raises the event. + /// + /// The instance containing the event data. + internal virtual void FireBeforeCreation(DatabaseCreationEventArgs e) + { + BeforeCreation?.Invoke(e); + } + + /// + /// Occurs when [after save]. + /// + internal static event DatabaseEventHandler AfterCreation; + /// + /// Raises the event. + /// + /// The instance containing the event data. + internal virtual void FireAfterCreation(DatabaseCreationEventArgs e) + { + AfterCreation?.Invoke(e); + } + + #endregion + + #region Utilities + + /// + /// Returns whether a table with the specified exists in the database. + /// + /// The name of the table. + /// true if the table exists; otherwise false. + /// + /// + /// if (schemaHelper.TableExist("MyTable")) + /// { + /// // do something when the table exists + /// } + /// + /// + public bool TableExists(string tableName) + { + return SqlSyntax.DoesTableExist(_database, tableName); + } + + /// + /// Returns whether the table for the specified exists in the database. + /// + /// The type representing the DTO/table. + /// true if the table exists; otherwise false. + /// + /// + /// if (schemaHelper.TableExist<MyDto>) + /// { + /// // do something when the table exists + /// } + /// + /// + /// + /// If has been decorated with an , the name from that + /// attribute will be used for the table name. If the attribute is not present, the name + /// will be used instead. + /// + public bool TableExists() + { + var table = DefinitionFactory.GetTableDefinition(typeof(T), SqlSyntax); + return table != null && TableExists(table.Name); + } + + /// + /// Creates a new table in the database based on the type of . + /// + /// The type representing the DTO/table. + /// Whether the table should be overwritten if it already exists. + /// + /// If has been decorated with an , the name from that + /// attribute will be used for the table name. If the attribute is not present, the name + /// will be used instead. + /// + /// If a table with the same name already exists, the parameter will determine + /// whether the table is overwritten. If true, the table will be overwritten, whereas this method will + /// not do anything if the parameter is false. + /// + internal void CreateTable(bool overwrite = false) + where T : new() + { + var tableType = typeof(T); + CreateTable(overwrite, tableType, new DatabaseDataCreator(_database, _logger)); + } + + /// + /// Creates a new table in the database for the specified . + /// + /// Whether the table should be overwritten if it already exists. + /// The the representing the table. + /// + /// + /// If has been decorated with an , the name from + /// that attribute will be used for the table name. If the attribute is not present, the name + /// will be used instead. + /// + /// If a table with the same name already exists, the parameter will determine + /// whether the table is overwritten. If true, the table will be overwritten, whereas this method will + /// not do anything if the parameter is false. + /// + /// This need to execute as part of a transaction. + /// + internal void CreateTable(bool overwrite, Type modelType, DatabaseDataCreator dataCreation) + { + if (!_database.InTransaction) + throw new InvalidOperationException("Database is not in a transaction."); + + var tableDefinition = DefinitionFactory.GetTableDefinition(modelType, SqlSyntax); + var tableName = tableDefinition.Name; + + var createSql = SqlSyntax.Format(tableDefinition); + var createPrimaryKeySql = SqlSyntax.FormatPrimaryKey(tableDefinition); + var foreignSql = SqlSyntax.Format(tableDefinition.ForeignKeys); + var indexSql = SqlSyntax.Format(tableDefinition.Indexes); + + var tableExist = TableExists(tableName); + if (overwrite && tableExist) + { + _logger.Info("Table '{TableName}' already exists, but will be recreated", tableName); + + DropTable(tableName); + tableExist = false; + } + + if (tableExist) + { + // The table exists and was not recreated/overwritten. + _logger.Info("Table '{TableName}' already exists - no changes were made", tableName); + return; + } + + //Execute the Create Table sql + var created = _database.Execute(new Sql(createSql)); + _logger.Info("Create Table '{TableName}' ({Created}): \n {Sql}", tableName, created, createSql); + + //If any statements exists for the primary key execute them here + if (string.IsNullOrEmpty(createPrimaryKeySql) == false) + { + var createdPk = _database.Execute(new Sql(createPrimaryKeySql)); + _logger.Info("Create Primary Key ({CreatedPk}):\n {Sql}", createdPk, createPrimaryKeySql); + } + + if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) + _database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} ON ")); + + //Call the NewTable-event to trigger the insert of base/default data + //OnNewTable(tableName, _db, e, _logger); + + dataCreation.InitializeBaseData(tableName); + + if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) + _database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} OFF;")); + + //Loop through index statements and execute sql + foreach (var sql in indexSql) + { + var createdIndex = _database.Execute(new Sql(sql)); + _logger.Info("Create Index ({CreatedIndex}):\n {Sql}", createdIndex, sql); + } + + //Loop through foreignkey statements and execute sql + foreach (var sql in foreignSql) + { + var createdFk = _database.Execute(new Sql(sql)); + _logger.Info("Create Foreign Key ({CreatedFk}):\n {Sql}", createdFk, sql); + } + + if (overwrite) + { + _logger.Info("Table '{TableName}' was recreated", tableName); + } + else + { + _logger.Info("New table '{TableName}' was created", tableName); + } + } + + /// + /// Drops the table for the specified . + /// + /// The type representing the DTO/table. + /// + /// + /// schemaHelper.DropTable<MyDto>); + /// + /// + /// + /// If has been decorated with an , the name from that + /// attribute will be used for the table name. If the attribute is not present, the name + /// will be used instead. + /// + public void DropTable(string tableName) + { + var sql = new Sql(string.Format(SqlSyntax.DropTable, SqlSyntax.GetQuotedTableName(tableName))); + _database.Execute(sql); + } + + #endregion + } +} diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseSchemaResult.cs b/src/Umbraco.Core/Migrations/Install/DatabaseSchemaResult.cs index 4c68addebc..6c28bacd63 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseSchemaResult.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseSchemaResult.cs @@ -12,12 +12,8 @@ namespace Umbraco.Core.Migrations.Install /// internal class DatabaseSchemaResult { - private readonly bool _isMySql; - public DatabaseSchemaResult(ISqlSyntaxProvider sqlSyntax) { - _isMySql = sqlSyntax is MySqlSyntaxProvider; - Errors = new List>(); TableDefinitions = new List(); ValidTables = new List(); @@ -102,11 +98,6 @@ namespace Umbraco.Core.Migrations.Install sb.AppendLine(" "); } - if (_isMySql) - { - sb.AppendLine("Please note that the constraints could not be validated because the current data provider is MySql."); - } - return sb.ToString(); } } diff --git a/src/Umbraco.Core/Migrations/MigrationBase_Extra.cs b/src/Umbraco.Core/Migrations/MigrationBase_Extra.cs index 9e13badacf..6d936e8407 100644 --- a/src/Umbraco.Core/Migrations/MigrationBase_Extra.cs +++ b/src/Umbraco.Core/Migrations/MigrationBase_Extra.cs @@ -98,14 +98,12 @@ namespace Umbraco.Core.Migrations protected bool ColumnExists(string tableName, string columnName) { - // that's ok even on MySql var columns = SqlSyntax.GetColumnsInSchema(Context.Database).Distinct().ToArray(); return columns.Any(x => x.TableName.InvariantEquals(tableName) && x.ColumnName.InvariantEquals(columnName)); } protected string ColumnType(string tableName, string columnName) { - // that's ok even on MySql var columns = SqlSyntax.GetColumnsInSchema(Context.Database).Distinct().ToArray(); var column = columns.FirstOrDefault(x => x.TableName.InvariantEquals(tableName) && x.ColumnName.InvariantEquals(columnName)); return column?.DataType; diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/UpdateUniqueIndexOnPropertyData.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/UpdateUniqueIndexOnPropertyData.cs index 73f03e96c6..8c688cfd28 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/UpdateUniqueIndexOnPropertyData.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/UpdateUniqueIndexOnPropertyData.cs @@ -27,25 +27,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_5_0 if (found != null) { - //Check for MySQL - if (DatabaseType.IsMySql()) - { - //Use the special double nested sub query for MySQL since that is the only - //way delete sub queries works - var delPropQry = SqlSyntax.GetDeleteSubquery( - "cmsPropertyData", - "id", - Sql("SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL"), - WhereInType.NotIn); - Database.Execute(delPropQry.SQL); - } - else - { - //NOTE: Even though the above will work for MSSQL, we are not going to execute the - // nested delete sub query logic since it will be slower and there could be a ton of property - // data here so needs to be as fast as possible. - Database.Execute("DELETE FROM cmsPropertyData WHERE id NOT IN (SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL)"); - } + Database.Execute("DELETE FROM cmsPropertyData WHERE id NOT IN (SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL)"); //we need to re create this index Delete.Index("IX_cmsPropertyData_1").OnTable("cmsPropertyData").Do(); diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToCmsMemberLoginName.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToCmsMemberLoginName.cs index 05abc5ec83..a223d76a07 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToCmsMemberLoginName.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToCmsMemberLoginName.cs @@ -16,9 +16,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0 //Now we need to check if we can actually d6 this because we won't be able to if there's data in there that is too long //http://issues.umbraco.org/issue/U4-9758 - var colLen = SqlSyntax is MySqlSyntaxProvider - ? database.ExecuteScalar("select max(LENGTH(LoginName)) from cmsMember") - : database.ExecuteScalar("select max(datalength(LoginName)) from cmsMember"); + var colLen = database.ExecuteScalar("select max(datalength(LoginName)) from cmsMember"); if (colLen < 900 == false && colLen != null) { diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/ReduceLoginNameColumnsSize.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/ReduceLoginNameColumnsSize.cs index 30ee91300d..1af21617f3 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/ReduceLoginNameColumnsSize.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/ReduceLoginNameColumnsSize.cs @@ -17,9 +17,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0 var database = Database; var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database); - var colLen = (SqlSyntax is MySqlSyntaxProvider) - ? database.ExecuteScalar("select max(LENGTH(LoginName)) from cmsMember") - : database.ExecuteScalar("select max(datalength(LoginName)) from cmsMember"); + var colLen = database.ExecuteScalar("select max(datalength(LoginName)) from cmsMember"); if (colLen < 900 == false) return; diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddIndexToDictionaryKeyColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddIndexToDictionaryKeyColumn.cs index 700702204c..b366c7dab9 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddIndexToDictionaryKeyColumn.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddIndexToDictionaryKeyColumn.cs @@ -13,9 +13,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0 { var database = Database; //Now we need to check if we can actually do this because we won't be able to if there's data in there that is too long - var colLen = (SqlSyntax is MySqlSyntaxProvider) - ? database.ExecuteScalar(string.Format("select max(LENGTH({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key"))) - : database.ExecuteScalar(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key"))); + var colLen = database.ExecuteScalar(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key"))); if (colLen < 900 == false && colLen != null) { diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserGroupTables.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserGroupTables.cs index 35df178672..f5fdd8df2b 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserGroupTables.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserGroupTables.cs @@ -4,7 +4,6 @@ using System.Data; using System.Linq; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.SqlSyntax; using ColumnInfo = Umbraco.Core.Persistence.SqlSyntax.ColumnInfo; namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0 @@ -19,9 +18,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0 //For some of the migration data inserts we require to use a special MSSQL collate expression since //some databases may have a custom collation specified and if that is the case, when we compare strings //in dynamic SQL it will try to compare strings in different collations and this will yield errors. - _collateSyntax = SqlSyntax is MySqlSyntaxProvider || SqlSyntax is SqlCeSyntaxProvider - ? string.Empty - : "COLLATE DATABASE_DEFAULT"; + _collateSyntax = "COLLATE DATABASE_DEFAULT"; } public override void Migrate() @@ -340,24 +337,16 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0 if (tables.InvariantContains("umbracoUserType") && tables.InvariantContains("umbracoUser")) { - if (DatabaseType.IsMySql()) + //Delete the FK if it exists before dropping the column + if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_umbracoUser_umbracoUserType_id"))) { - //In MySql, this will drop the FK according to it's special naming rules - Delete.ForeignKey().FromTable("umbracoUser").ForeignColumn("userType").ToTable("umbracoUserType").PrimaryColumn("id"); + Delete.ForeignKey("FK_umbracoUser_umbracoUserType_id").OnTable("umbracoUser").Do(); } - else - { - //Delete the FK if it exists before dropping the column - if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_umbracoUser_umbracoUserType_id"))) - { - Delete.ForeignKey("FK_umbracoUser_umbracoUserType_id").OnTable("umbracoUser").Do(); - } - //This is the super old constraint name of the FK for user type so check this one too - if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_user_userType"))) - { - Delete.ForeignKey("FK_user_userType").OnTable("umbracoUser").Do(); - } + //This is the super old constraint name of the FK for user type so check this one too + if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_user_userType"))) + { + Delete.ForeignKey("FK_user_userType").OnTable("umbracoUser").Do(); } Delete.Column("userType").FromTable("umbracoUser").Do(); diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/ReduceDictionaryKeyColumnsSize.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/ReduceDictionaryKeyColumnsSize.cs index 9f84320620..17dd3064eb 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/ReduceDictionaryKeyColumnsSize.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/ReduceDictionaryKeyColumnsSize.cs @@ -16,9 +16,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0 var database = Database; var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database); - var colLen = SqlSyntax is MySqlSyntaxProvider - ? database.ExecuteScalar(string.Format("select max(LENGTH({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key"))) - : database.ExecuteScalar(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key"))); + var colLen = database.ExecuteScalar(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key"))); if (colLen < 900 == false) return; diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs index db8f95bf71..c683940f60 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs @@ -20,36 +20,25 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 Alter.Table("cmsPreviewXml").AddColumn("Rv").AsInt64().NotNullable().WithDefaultValue(0).Do(); // remove the any PK_ and the FK_ to cmsContentVersion.VersionId - if (DatabaseType.IsMySql()) + var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray(); + var dups = new List(); + foreach (var c in constraints.Where(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("PK_"))) + { + var keyName = c.Item3.ToLowerInvariant(); + if (dups.Contains(keyName)) + { + Logger.Warn("Duplicate constraint '{Constraint}'", c.Item3); + continue; + } + dups.Add(keyName); + Delete.PrimaryKey(c.Item3).FromTable(c.Item1).Do(); + } + foreach (var c in constraints.Where(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("FK_cmsPreviewXml_cmsContentVersion"))) { - Delete.PrimaryKey("PK_cmsPreviewXml").FromTable("cmsPreviewXml").Do(); - Delete.ForeignKey().FromTable("cmsPreviewXml").ForeignColumn("VersionId") .ToTable("cmsContentVersion").PrimaryColumn("VersionId") .Do(); } - else - { - var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray(); - var dups = new List(); - foreach (var c in constraints.Where(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("PK_"))) - { - var keyName = c.Item3.ToLowerInvariant(); - if (dups.Contains(keyName)) - { - Logger.Warn("Duplicate constraint '{Constraint}'", c.Item3); - continue; - } - dups.Add(keyName); - Delete.PrimaryKey(c.Item3).FromTable(c.Item1).Do(); - } - foreach (var c in constraints.Where(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("FK_cmsPreviewXml_cmsContentVersion"))) - { - Delete.ForeignKey().FromTable("cmsPreviewXml").ForeignColumn("VersionId") - .ToTable("cmsContentVersion").PrimaryColumn("VersionId") - .Do(); - } - } if (ColumnExists("cmsPreviewXml", "Timestamp")) Delete.Column("Timestamp").FromTable("cmsPreviewXml").Do(); diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/VariantsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/VariantsMigration.cs index 9e223e7beb..d484f7c6ba 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/VariantsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/VariantsMigration.cs @@ -1,10 +1,8 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Umbraco.Core.Migrations.Install; using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Dtos; namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 @@ -17,7 +15,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 // notes // do NOT use Rename.Column as it's borked on SQLCE - use ReplaceColumn instead - // not sure it all runs on MySql, needs to test public override void Migrate() { @@ -195,9 +192,7 @@ JOIN {SqlSyntax.GetQuotedTableName(PreTables.Document)} doc ON doc.nodeId=cver.n FROM {SqlSyntax.GetQuotedTableName(PreTables.Document)} doc JOIN {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} cver ON doc.nodeId=cver.nodeId AND doc.versionId=cver.versionId WHERE doc.newest=1 AND doc.published=1"); - var getIdentity = Database.SqlContext.DatabaseType.IsMySql() - ? "LAST_INSERT_ID()" - : "@@@@IDENTITY"; + var getIdentity = "@@@@IDENTITY"; foreach (var t in temp3) { Database.Execute($@"INSERT INTO {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} (nodeId, versionId, versionDate, userId, {SqlSyntax.GetQuotedColumnName("current")}, text) diff --git a/src/Umbraco.Core/Persistence/Constants-DbProviderNames.cs b/src/Umbraco.Core/Persistence/Constants-DbProviderNames.cs index b79269d80e..8e81a5acf8 100644 --- a/src/Umbraco.Core/Persistence/Constants-DbProviderNames.cs +++ b/src/Umbraco.Core/Persistence/Constants-DbProviderNames.cs @@ -6,7 +6,6 @@ namespace Umbraco.Core public static class DbProviderNames { public const string SqlServer = "System.Data.SqlClient"; - public const string MySql = "MySql.Data.MySqlClient"; public const string SqlCe = "System.Data.SqlServerCe.4.0"; } } diff --git a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs index 5a0e44a281..e2d3ac97ae 100644 --- a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs +++ b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs @@ -109,12 +109,6 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions var constraintAttribute = propertyInfo.FirstAttribute(); if (constraintAttribute != null) { - //Special case for MySQL as it can't have multiple default DateTime values, which - //is what the umbracoServer table definition is trying to create - if (sqlSyntax is MySqlSyntaxProvider && definition.TableName == "umbracoServer" && - definition.TableName.ToLowerInvariant() == "lastNotifiedDate".ToLowerInvariant()) - return definition; - definition.ConstraintName = constraintAttribute.Name ?? string.Empty; definition.DefaultValue = constraintAttribute.Default ?? string.Empty; } diff --git a/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs b/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs index 8f501c0aaa..20586cb6f4 100644 --- a/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs +++ b/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs @@ -4,7 +4,6 @@ using System.Data.Common; using System.Data.SqlClient; using System.Data.SqlServerCe; using System.Linq; -using MySql.Data.MySqlClient; using StackExchange.Profiling.Data; using Umbraco.Core.Composing; using Umbraco.Core.Logging; @@ -19,12 +18,6 @@ namespace Umbraco.Core.Persistence var builder = new DbConnectionStringBuilder { ConnectionString = connectionString }; var allKeys = builder.Keys.Cast(); - var mySql = new[] { "Server", "Database", "Uid", "Pwd" }; - if (mySql.All(x => allKeys.InvariantContains(x))) - { - return Constants.DbProviderNames.MySql; - } - if (allKeys.InvariantContains("Data Source") //this dictionary is case insensitive && builder["Data source"].ToString().InvariantContains(".sdf")) @@ -38,7 +31,6 @@ namespace Umbraco.Core.Persistence public static bool IsConnectionAvailable(string connectionString, string providerName) { if (providerName != Constants.DbProviderNames.SqlCe - && providerName != Constants.DbProviderNames.MySql && providerName != Constants.DbProviderNames.SqlServer) throw new NotSupportedException($"Provider \"{providerName}\" is not supported."); @@ -108,11 +100,6 @@ namespace Umbraco.Core.Persistence var builder = new SqlCeConnectionStringBuilder(connection.ConnectionString); return $"DataSource: {builder.DataSource}"; } - case MySqlConnection _: - { - var builder = new MySqlConnectionStringBuilder(connection.ConnectionString); - return $"Server: {builder.Server}, Database: {builder.Database}"; - } } } catch (Exception ex) diff --git a/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions-Bulk.cs b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions-Bulk.cs index 77b412ef2b..2757ee131d 100644 --- a/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions-Bulk.cs +++ b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions-Bulk.cs @@ -71,10 +71,6 @@ namespace Umbraco.Core.Persistence ? BulkInsertRecordsSqlServer(database, pocoData, recordsA) : BulkInsertRecordsWithCommands(database, recordsA); } - - if (database.DatabaseType.IsMySql()) - return BulkInsertRecordsWithCommands(database, recordsA); - throw new NotSupportedException(); } diff --git a/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs index b81e68e567..0548e63290 100644 --- a/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs +++ b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs @@ -32,30 +32,6 @@ namespace Umbraco.Core.Persistence // // works in READ COMMITED, TSQL & SQLCE lock the constraint even if it does not exist, so INSERT is OK // - // proper way to do it with MySQL - // IF EXISTS (SELECT ... FROM table WHERE ... FOR UPDATE) - // BEGIN - // UPDATE table SET ... WHERE ... - // END - // ELSE - // BEGIN - // INSERT INTO table (...) VALUES (...) - // END - // - // MySQL locks the constraint ONLY if it exists, so INSERT may fail... - // in theory, happens in READ COMMITTED but not REPEATABLE READ - // http://www.percona.com/blog/2012/08/28/differences-between-read-committed-and-repeatable-read-transaction-isolation-levels/ - // but according to - // http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html - // it won't work for exact index value (only ranges) so really... - // - // MySQL should do - // INSERT INTO table (...) VALUES (...) ON DUPLICATE KEY UPDATE ... - // - // also the lock is released when the transaction is committed - // not sure if that can have unexpected consequences on our code? - // - // so... for the time being, let's do with that somewhat crazy solution below... // todo: use the proper database syntax, not this kludge /// @@ -66,7 +42,7 @@ namespace Umbraco.Core.Persistence /// The action that executed, either an insert or an update. If an insert occurred and a PK value got generated, the poco object /// passed in will contain the updated value. /// - /// We cannot rely on database-specific options such as MySql ON DUPLICATE KEY UPDATE or MSSQL MERGE WHEN MATCHED because SQLCE + /// We cannot rely on database-specific options because SQLCE /// does not support any of them. Ideally this should be achieved with proper transaction isolation levels but that would mean revisiting /// isolation levels globally. We want to keep it simple for the time being and manage it manually. /// We handle it by trying to update, then insert, etc. until something works, or we get bored. @@ -89,7 +65,7 @@ namespace Umbraco.Core.Persistence /// The action that executed, either an insert or an update. If an insert occurred and a PK value got generated, the poco object /// passed in will contain the updated value. /// - /// We cannot rely on database-specific options such as MySql ON DUPLICATE KEY UPDATE or MSSQL MERGE WHEN MATCHED because SQLCE + /// We cannot rely on database-specific options because SQLCE /// does not support any of them. Ideally this should be achieved with proper transaction isolation levels but that would mean revisiting /// isolation levels globally. We want to keep it simple for the time being and manage it manually. /// We handle it by trying to update, then insert, etc. until something works, or we get bored. diff --git a/src/Umbraco.Core/Persistence/NPocoDatabaseTypeExtensions.cs b/src/Umbraco.Core/Persistence/NPocoDatabaseTypeExtensions.cs index bd44c095fa..70909e2874 100644 --- a/src/Umbraco.Core/Persistence/NPocoDatabaseTypeExtensions.cs +++ b/src/Umbraco.Core/Persistence/NPocoDatabaseTypeExtensions.cs @@ -4,11 +4,6 @@ namespace Umbraco.Core.Persistence { internal static class NPocoDatabaseTypeExtensions { - public static bool IsMySql(this DatabaseType databaseType) - { - return databaseType is NPoco.DatabaseTypes.MySqlDatabaseType; - } - public static bool IsSqlServer(this DatabaseType databaseType) { // note that because SqlServerDatabaseType is the base class for diff --git a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs index 7aa8b707be..a7e1606b9d 100644 --- a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs +++ b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs @@ -1063,17 +1063,6 @@ namespace Umbraco.Core.Persistence /// The Sql statement. public static Sql ForUpdate(this Sql sql) { - // MySql wants "FOR UPDATE" at the end, and T-Sql wants "WITH (UPDLOCK)" in the FROM statement, - // and we want to implement it in the least expensive way, so parsing the entire string here is - // a no, so we use reflection to work on the Sql expression before it is built. - // TODO propose a clean way to do that type of thing in NPoco - - if (sql.SqlContext.DatabaseType.IsMySql()) - { - sql.Append("FOR UPDATE"); - return sql; - } - // go find the first FROM clause, and append the lock hint Sql s = sql; var updated = false; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs index bd7943ff1d..125a86622f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs @@ -744,208 +744,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement /// /// protected abstract Sql GetBaseQuery(QueryType queryType); - - /* - internal class DocumentDefinitionCollection : KeyedCollection - { - private readonly bool _includeAllVersions; - - /// - /// Constructor specifying if all versions should be allowed, in that case the key for the collection becomes the versionId (GUID) - /// - /// - public DocumentDefinitionCollection(bool includeAllVersions = false) - { - _includeAllVersions = includeAllVersions; - } - - protected override ValueType GetKeyForItem(DocumentDefinition item) - { - return _includeAllVersions ? (ValueType)item.Version : item.Id; - } - - /// - /// if this key already exists if it does then we need to check - /// if the existing item is 'older' than the new item and if that is the case we'll replace the older one - /// - /// - /// - public bool AddOrUpdate(DocumentDefinition item) - { - //if we are including all versions then just add, we aren't checking for latest - if (_includeAllVersions) - { - Add(item); - return true; - } - - if (Dictionary == null) - { - Add(item); - return true; - } - - var key = GetKeyForItem(item); - if (TryGetValue(key, out DocumentDefinition found)) - { - //it already exists and it's older so we need to replace it - if (item.VersionId <= found.VersionId) return false; - - var currIndex = Items.IndexOf(found); - if (currIndex == -1) - throw new IndexOutOfRangeException("Could not find the item in the list: " + found.Version); - - //replace the current one with the newer one - SetItem(currIndex, item); - return true; - } - - Add(item); - return true; - } - - public bool TryGetValue(ValueType key, out DocumentDefinition val) - { - if (Dictionary != null) - return Dictionary.TryGetValue(key, out val); - - val = null; - return false; - } - } - - /// - /// Implements a Guid comparer that respect the Sql engine ordering. - /// - /// - /// MySql sorts Guids as strings, but MSSQL sorts guids based on a weird byte sections order - /// This comparer compares Guids using the corresponding Sql syntax method, ie the method of the underlying Sql engine. - /// see http://stackoverflow.com/questions/7810602/sql-server-guid-sort-algorithm-why - /// see https://blogs.msdn.microsoft.com/sqlprogrammability/2006/11/06/how-are-guids-compared-in-sql-server-2005/ - /// - private class DocumentDefinitionComparer : IComparer - { - private readonly bool _mySql; - - public DocumentDefinitionComparer(ISqlSyntaxProvider sqlSyntax) - { - _mySql = sqlSyntax is MySqlSyntaxProvider; - } - - public int Compare(Guid x, Guid y) - { - // MySql sorts Guids as string (ie normal, same as .NET) whereas MSSQL - // sorts them on a weird byte sections order - return _mySql ? x.CompareTo(y) : new SqlGuid(x).CompareTo(new SqlGuid(y)); - } - } - - internal class DocumentDefinition - { - /// - /// Initializes a new instance of the class. - /// - public DocumentDefinition(DocumentDto dto, IContentTypeComposition composition) - { - DocumentDto = dto; - ContentVersionDto = dto.ContentVersionDto; - Composition = composition; - } - - public DocumentDefinition(ContentVersionDto dto, IContentTypeComposition composition) - { - ContentVersionDto = dto; - Composition = composition; - } - - public DocumentDto DocumentDto { get; } - public ContentVersionDto ContentVersionDto { get; } - - public int Id => ContentVersionDto.NodeId; - - public Guid Version => DocumentDto?.VersionId ?? ContentVersionDto.VersionId; - - // This is used to determien which version is the most recent - public int VersionId => ContentVersionDto.Id; - - public DateTime VersionDate => ContentVersionDto.VersionDate; - - public DateTime CreateDate => ContentVersionDto.ContentDto.NodeDto.CreateDate; - - public IContentTypeComposition Composition { get; set; } - } - - // Represents a query that may contain paging information. - internal class PagingSqlQuery - { - // the original query sql - public Sql QuerySql { get; } - - public PagingSqlQuery(Sql querySql) - { - QuerySql = querySql; - } - - protected PagingSqlQuery(Sql querySql, int pageSize) - : this(querySql) - { - HasPaging = pageSize > 0; - } - - // whether the paging query is actually paging - public bool HasPaging { get; } - - // the paging sql - public virtual Sql BuildPagedQuery(string columns) - { - throw new InvalidOperationException("This query has no paging information."); - } - } - - /// - /// Represents a query that may contain paging information. - /// - /// - internal class PagingSqlQuery : PagingSqlQuery // fixme what's here? - { - private readonly Database _db; - private readonly long _pageIndex; - private readonly int _pageSize; - - // fixme - don't capture a db instance here! - // instead, should have an extension method, so one can do - // sql = db.BuildPageQuery(pagingQuery, columns) - public PagingSqlQuery(Database db, Sql querySql, long pageIndex, int pageSize) - : base(querySql, pageSize) - { - _db = db; - _pageIndex = pageIndex; - _pageSize = pageSize; - } - - /// - /// Creates a paged query based on the original query and subtitutes the selectColumns specified - /// - /// - /// - // build a page query - public override Sql BuildPagedQuery(string columns) - { - if (HasPaging == false) - throw new InvalidOperationException("This query has no paging information."); - - // substitutes the original "SELECT ..." with "SELECT {columns}" ie only - // select the specified columns - fixme why? - var sql = $"SELECT {columns} {QuerySql.SQL.Substring(QuerySql.SQL.IndexOf("FROM", StringComparison.Ordinal))}"; - - // and then build the page query - var args = QuerySql.Arguments; - _db.BuildPageQueries(_pageIndex * _pageSize, _pageSize, sql, ref args, out string unused, out string sqlPage); - return new Sql(sqlPage, args); - } - } - */ - #endregion #region Utilities diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/UserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/UserRepository.cs index 17fe79a55b..01609e6a46 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/UserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/UserRepository.cs @@ -300,7 +300,7 @@ ORDER BY colName"; // NPoco cannot fetch 2+ references at a time // plus it creates a combinatorial explosion // better use extra queries - // unfortunately, SqlCe and MySql don't support multiple result sets + // unfortunately, SqlCe doesn't support multiple result sets private void PerformGetReferencedDtos(List dtos) { if (dtos.Count == 0) return; diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs index 98c57644aa..c352e312ac 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs @@ -72,7 +72,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax bool SupportsClustered(); bool SupportsIdentityInsert(); - bool? SupportsCaseInsensitiveQueries(IDatabase db); string ConvertIntegerToOrderableString { get; } string ConvertDateToOrderableString { get; } diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs deleted file mode 100644 index 5cf9fa3af8..0000000000 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ /dev/null @@ -1,402 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NPoco; -using Umbraco.Core.Logging; -using Umbraco.Core.Persistence.DatabaseAnnotations; -using Umbraco.Core.Persistence.DatabaseModelDefinitions; - -namespace Umbraco.Core.Persistence.SqlSyntax -{ - /// - /// Represents an SqlSyntaxProvider for MySql - /// - public class MySqlSyntaxProvider : SqlSyntaxProviderBase - { - private readonly ILogger _logger; - - public MySqlSyntaxProvider(ILogger logger) - { - _logger = logger; - - AutoIncrementDefinition = "AUTO_INCREMENT"; - IntColumnDefinition = "int(11)"; - BoolColumnDefinition = "tinyint(1)"; - DateTimeColumnDefinition = "TIMESTAMP"; - TimeColumnDefinition = "time"; - DecimalColumnDefinition = "decimal(38,6)"; - GuidColumnDefinition = "char(36)"; - - DefaultValueFormat = "DEFAULT {0}"; - - InitColumnTypeMap(); - } - - public override IEnumerable GetTablesInSchema(IDatabase db) - { - List list; - try - { - //needs to be open to read the schema name - db.OpenSharedConnection(); - - var items = - db.Fetch( - "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = @TableSchema", - new { TableSchema = db.Connection.Database }); - list = items.Select(x => x.TABLE_NAME).Cast().ToList(); - } - finally - { - db.CloseSharedConnection(); - } - return list; - } - - public override IEnumerable GetColumnsInSchema(IDatabase db) - { - List list; - try - { - //needs to be open to read the schema name - db.OpenSharedConnection(); - - var items = - db.Fetch( - "SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @TableSchema", - new { TableSchema = db.Connection.Database }); - list = - items.Select( - item => - new ColumnInfo(item.TABLE_NAME, item.COLUMN_NAME, int.Parse(item.ORDINAL_POSITION.ToString()), item.COLUMN_DEFAULT ?? "", - item.IS_NULLABLE, item.DATA_TYPE)).ToList(); - } - finally - { - db.CloseSharedConnection(); - } - return list; - } - - /// - public override IEnumerable> GetConstraintsPerTable(IDatabase db) - { - List> list; - try - { - //needs to be open to read the schema name - db.OpenSharedConnection(); - - //Does not include indexes and constraints are named differently - var items = - db.Fetch( - "SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = @TableSchema", - new { TableSchema = db.Connection.Database }); - list = items.Select(item => new Tuple(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList(); - } - finally - { - db.CloseSharedConnection(); - } - return list; - } - - /// - public override IEnumerable> GetConstraintsPerColumn(IDatabase db) - { - List> list; - try - { - //needs to be open to read the schema name - db.OpenSharedConnection(); - - //Does not include indexes and constraints are named differently - var items = - db.Fetch( - "SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = @TableSchema", - new { TableSchema = db.Connection.Database }); - list = - items.Select( - item => - new Tuple(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)) - .ToList(); - } - finally - { - db.CloseSharedConnection(); - } - return list; - } - - /// - public override IEnumerable> GetDefinedIndexes(IDatabase db) - { - List> list; - try - { - //needs to be open to read the schema name - db.OpenSharedConnection(); - - var indexes = - db.Fetch(@"SELECT DISTINCT - TABLE_NAME, INDEX_NAME, COLUMN_NAME, CASE NON_UNIQUE WHEN 1 THEN 0 ELSE 1 END AS `UNIQUE` -FROM INFORMATION_SCHEMA.STATISTICS -WHERE TABLE_SCHEMA = @TableSchema -AND INDEX_NAME <> COLUMN_NAME AND INDEX_NAME <> 'PRIMARY' -ORDER BY TABLE_NAME, INDEX_NAME", - new { TableSchema = db.Connection.Database }); - list = - indexes.Select( - item => - new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE == 1)) - .ToList(); - } - finally - { - db.CloseSharedConnection(); - } - return list; - } - - public override bool DoesTableExist(IDatabase db, string tableName) - { - long result; - try - { - //needs to be open to read the schema name - db.OpenSharedConnection(); - - result = - db.ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " + - "WHERE TABLE_NAME = @TableName AND " + - "TABLE_SCHEMA = @TableSchema", - new { TableName = tableName, TableSchema = db.Connection.Database }); - - } - finally - { - db.CloseSharedConnection(); - } - - return result > 0; - } - - public override Sql SelectTop(Sql sql, int top) - { - return new Sql(sql.SqlContext, string.Concat(sql.SQL, " LIMIT ", top), sql.Arguments); - } - - public override bool SupportsClustered() - { - return true; - } - - public override bool SupportsIdentityInsert() - { - return false; - } - - /// - /// This is used ONLY if we need to format datetime without using SQL parameters (i.e. during migrations) - /// - /// - /// - /// - /// - /// MySQL has a DateTime standard that is unambiguous and works on all servers: - /// YYYYMMDDHHMMSS - /// - public override string FormatDateTime(DateTime date, bool includeTime = true) - { - return includeTime ? date.ToString("yyyyMMddHHmmss") : date.ToString("yyyyMMdd"); - } - - 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 GetSpecialDbType(SpecialDbTypes dbTypes) - { - if (dbTypes == SpecialDbTypes.NCHAR) - { - return "CHAR"; - } - else if (dbTypes == SpecialDbTypes.NTEXT) - return "LONGTEXT"; - - return "NVARCHAR"; - } - - public override string Format(TableDefinition table) - { - string primaryKey = string.Empty; - var columnDefinition = table.Columns.FirstOrDefault(x => x.IsPrimaryKey); - if (columnDefinition != null) - { - string columns = string.IsNullOrEmpty(columnDefinition.PrimaryKeyColumns) - ? GetQuotedColumnName(columnDefinition.Name) - : string.Join(", ", columnDefinition.PrimaryKeyColumns - .Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) - .Select(GetQuotedColumnName)); - - primaryKey = string.Format(", \nPRIMARY KEY {0} ({1})", columnDefinition.IsIndexed ? "CLUSTERED" : "NONCLUSTERED", columns); - } - - var statement = string.Format(CreateTable, GetQuotedTableName(table.Name), Format(table.Columns), primaryKey); - - return statement; - } - - public override string Format(IndexDefinition index) - { - string name = string.IsNullOrEmpty(index.Name) - ? string.Format("IX_{0}_{1}", index.TableName, index.ColumnName) - : index.Name; - - string columns = index.Columns.Any() - ? string.Join(",", index.Columns.Select(x => GetQuotedColumnName(x.Name))) - : GetQuotedColumnName(index.ColumnName); - - return string.Format(CreateIndex, - GetQuotedName(name), - GetQuotedTableName(index.TableName), - columns); - } - - public override string Format(ForeignKeyDefinition foreignKey) - { - return string.Format(CreateForeignKeyConstraint, - GetQuotedTableName(foreignKey.ForeignTable), - GetQuotedColumnName(foreignKey.ForeignColumns.First()), - GetQuotedTableName(foreignKey.PrimaryTable), - GetQuotedColumnName(foreignKey.PrimaryColumns.First()), - FormatCascade("DELETE", foreignKey.OnDelete), - FormatCascade("UPDATE", foreignKey.OnUpdate)); - } - - public override string FormatPrimaryKey(TableDefinition table) - { - return string.Empty; - } - - protected override string FormatConstraint(ColumnDefinition column) - { - return string.Empty; - } - - protected override string FormatIdentity(ColumnDefinition column) - { - return column.IsIdentity ? AutoIncrementDefinition : string.Empty; - } - - protected override string FormatDefaultValue(ColumnDefinition column) - { - if (column.DefaultValue == null) - return string.Empty; - - //hack - probably not needed with latest changes - if (column.DefaultValue.ToString().ToLower().Equals("getdate()".ToLower())) - column.DefaultValue = SystemMethods.CurrentDateTime; - - // see if this is for a system method - if (column.DefaultValue is SystemMethods) - { - string method = FormatSystemMethods((SystemMethods)column.DefaultValue); - if (string.IsNullOrEmpty(method)) - return string.Empty; - - return string.Format(DefaultValueFormat, method); - } - - //needs quote - return string.Format(DefaultValueFormat, string.Format("'{0}'", column.DefaultValue)); - } - - protected override string FormatPrimaryKey(ColumnDefinition column) - { - return string.Empty; - } - - protected override string FormatSystemMethods(SystemMethods systemMethod) - { - switch (systemMethod) - { - case SystemMethods.NewGuid: - return null; // NOT SUPPORTED! - case SystemMethods.CurrentDateTime: - return "CURRENT_TIMESTAMP"; - } - - return null; - } - - public override string DeleteDefaultConstraint - { - get - { - return "ALTER TABLE {0} ALTER COLUMN {1} DROP DEFAULT"; - } - } - - public override string AlterColumn { get { return "ALTER TABLE {0} MODIFY COLUMN {1}"; } } - - //CREATE TABLE {0} ({1}) ENGINE = INNODB versus CREATE TABLE {0} ({1}) ENGINE = MYISAM ? - public override string CreateTable { get { return "CREATE TABLE {0} ({1}{2})"; } } - - public override string CreateIndex { get { return "CREATE INDEX {0} ON {1} ({2})"; } } - - public override string CreateForeignKeyConstraint { get { return "ALTER TABLE {0} ADD FOREIGN KEY ({1}) REFERENCES {2} ({3}){4}{5}"; } } - - public override string DeleteConstraint { get { return "ALTER TABLE {0} DROP {1} {2}"; } } - - public override string DropIndex { get { return "DROP INDEX {0} ON {1}"; } } - - public override string RenameColumn { get { return "ALTER TABLE {0} CHANGE {1} {2}"; } } - public override string ConvertIntegerToOrderableString { get { return "LPAD(FORMAT({0}, 0), 8, '0')"; } } - public override string ConvertDateToOrderableString { get { return "DATE_FORMAT({0}, '%Y%m%d')"; } } - public override string ConvertDecimalToOrderableString { get { return "LPAD(FORMAT({0}, 9), 20, '0')"; } } - - public override bool? SupportsCaseInsensitiveQueries(IDatabase db) - { - bool? supportsCaseInsensitiveQueries = null; - - try - { - db.OpenSharedConnection(); - // Need 4 @ signs as it is regarded as a parameter, @@ escapes it once, @@@@ escapes it twice - var lowerCaseTableNames = db.Fetch("SELECT @@@@Global.lower_case_table_names"); - - if (lowerCaseTableNames.Any()) - supportsCaseInsensitiveQueries = lowerCaseTableNames.First() == 1; - } - catch (Exception ex) - { - _logger.Error(ex, "Error querying for lower_case support"); - } - finally - { - db.CloseSharedConnection(); - } - - // Could return null, which means testing failed, - // add message to check with their hosting provider - return supportsCaseInsensitiveQueries; - } - - public override string EscapeString(string val) - { - return NPocoDatabaseExtensions.EscapeAtSymbols(MySql.Data.MySqlClient.MySqlHelper.EscapeString(val)); - } - } -} diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index afab5b19f9..9dec7de451 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -200,12 +200,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax return "NVARCHAR"; } - - public virtual bool? SupportsCaseInsensitiveQueries(IDatabase db) - { - return true; - } - + public virtual IEnumerable GetTablesInSchema(IDatabase db) { return new List(); diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderExtensions.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderExtensions.cs index 02f1370b83..f7cf480830 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderExtensions.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderExtensions.cs @@ -27,7 +27,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax /// /// This is used to generate a delete query that uses a sub-query to select the data, it is required because there's a very particular syntax that - /// needs to be used to work for all servers: MySql, SQLCE and MSSQL + /// needs to be used to work for all servers: SQLCE and MSSQL /// /// /// diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs index fdf8061c8e..936fd3de49 100644 --- a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs +++ b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs @@ -167,15 +167,7 @@ namespace Umbraco.Core.Persistence #if DEBUG_DATABASES // determines the database connection SPID for debugging - if (DatabaseType.IsMySql()) - { - using (var command = connection.CreateCommand()) - { - command.CommandText = "SELECT CONNECTION_ID()"; - _spid = Convert.ToInt32(command.ExecuteScalar()); - } - } - else if (DatabaseType.IsSqlServer()) + if (DatabaseType.IsSqlServer()) { using (var command = connection.CreateCommand()) { diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs b/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs index 9ed52ca148..40af951d18 100644 --- a/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs +++ b/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs @@ -246,8 +246,6 @@ namespace Umbraco.Core.Persistence { switch (providerName) { - case Constants.DbProviderNames.MySql: - return new MySqlSyntaxProvider(_logger); case Constants.DbProviderNames.SqlCe: return new SqlCeSyntaxProvider(); case Constants.DbProviderNames.SqlServer: diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 94f422e027..fee23994b6 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -69,7 +69,6 @@ 4.0.0 - @@ -1249,7 +1248,6 @@ - diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 73f9656f56..fdb18c598d 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -74,8 +74,6 @@ - - diff --git a/src/Umbraco.Tests/Migrations/SqlScripts/MySqlTotal-480.sql b/src/Umbraco.Tests/Migrations/SqlScripts/MySqlTotal-480.sql deleted file mode 100644 index 0967f116b0..0000000000 --- a/src/Umbraco.Tests/Migrations/SqlScripts/MySqlTotal-480.sql +++ /dev/null @@ -1,822 +0,0 @@ -/******************************************************************************************* - - - - - - - - Umbraco database installation script for MySQL - -IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT - - Database version: 4.8.0.4 - - Please increment this version number if ANY change is made to this script, - so compatibility with scripts for other database systems can be verified easily. - The first 3 digits depict the Umbraco version, the last digit is the database version. - (e.g. version 4.0.0.3 means "Umbraco version 4.0.0, database version 3") - - Check-in policy: only commit this script if - * you ran the Umbraco installer completely; - * you ran it on the targetted database system; - * you ran the Boost and Nitro installation; - * you were able to browse the Boost site; - * you were able to open the Umbraco administration panel; - * you have documented the code change in this script; - * you have incremented the version number in this script. - -IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT - - - - - - - -********************************************************************************************/ - -CREATE TABLE umbracoRelation -( -id int NOT NULL AUTO_INCREMENT PRIMARY KEY, -parentId int NOT NULL, -childId int NOT NULL, -relType int NOT NULL, -datetime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -comment nvarchar (1000) NOT NULL -) - -; -CREATE TABLE cmsDocument -( -nodeId int NOT NULL, -published bit NOT NULL, -documentUser int NOT NULL, -versionId CHAR(36) NOT NULL PRIMARY KEY, -text nvarchar (255) NOT NULL, -releaseDate datetime NULL, -expireDate datetime NULL, -updateDate TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -templateId int NULL, -alias nvarchar (255) NULL , -newest bit NOT NULL DEFAULT 0 -) - -; -CREATE TABLE umbracoLog -( -id int NOT NULL AUTO_INCREMENT PRIMARY KEY, -userId int NOT NULL, -NodeId int NOT NULL, -Datestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -logHeader nvarchar (50) NOT NULL, -logComment nvarchar (4000) NULL -) - -; -CREATE TABLE umbracoUserGroup -( -id smallint NOT NULL AUTO_INCREMENT PRIMARY KEY, -userGroupName nvarchar (255) NOT NULL -) - -; - -/* TABLE IS NEVER USED, REMOVED FOR 4.1 - -CREATE TABLE umbracoUser2userGroup -( -user int NOT NULL, -userGroup smallint NOT NULL -) -; -ALTER TABLE umbracoUser2userGroup ADD CONSTRAINT PK_user2userGroup PRIMARY KEY CLUSTERED (user, userGroup) -; - -*/ - -CREATE TABLE umbracoApp -( -sortOrder tinyint NOT NULL DEFAULT 0, -appAlias nvarchar (50) PRIMARY KEY NOT NULL, -appIcon nvarchar (255) NOT NULL, -appName nvarchar (255) NOT NULL, -appInitWithTreeAlias nvarchar (255) NULL -) - -; -CREATE TABLE cmsPropertyData -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -contentNodeId int NOT NULL, -versionId CHAR(36) NULL, -propertytypeid int NOT NULL, -dataInt int NULL, -dataDate datetime NULL, -dataNvarchar nvarchar (500) NULL, -dataNtext LONGTEXT NULL -) -; -CREATE INDEX IX_cmsPropertyData_1 ON cmsPropertyData (contentNodeId) -; -CREATE INDEX IX_cmsPropertyData_2 ON cmsPropertyData (versionId) -; -CREATE INDEX IX_cmsPropertyData_3 ON cmsPropertyData (propertytypeid) -; -CREATE TABLE cmsContent -( -pk int NOT NULL PRIMARY KEY AUTO_INCREMENT, -nodeId int NOT NULL, -contentType int NOT NULL -) - -; -CREATE TABLE cmsContentType -( -pk int NOT NULL PRIMARY KEY AUTO_INCREMENT, -nodeId int NOT NULL, -alias nvarchar (255) NULL, -icon nvarchar (255) NULL -) - -; -CREATE TABLE cmsMacroPropertyType -( -id smallint NOT NULL PRIMARY KEY AUTO_INCREMENT, -macroPropertyTypeAlias nvarchar (50) NULL, -macroPropertyTypeRenderAssembly nvarchar (255) NULL, -macroPropertyTypeRenderType nvarchar (255) NULL, -macroPropertyTypeBaseType nvarchar (255) NULL -) -; - -/* TABLE IS NEVER USED, REMOVED FOR 4.1 - -CREATE TABLE umbracoStylesheetProperty -( -id smallint NOT NULL PRIMARY KEY AUTO_INCREMENT, -stylesheetPropertyEditor bit NOT NULL DEFAULT 0, -stylesheet tinyint NOT NULL, -stylesheetPropertyAlias nvarchar (50) NULL, -stylesheetPropertyName nvarchar (255) NULL, -stylesheetPropertyValue nvarchar (400) NULL -) -; - -*/ - -CREATE TABLE cmsTab -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -contenttypeNodeId int NOT NULL, -text nvarchar (255) NOT NULL, -sortorder int NOT NULL -) - -; -CREATE TABLE cmsTemplate -( -pk int NOT NULL PRIMARY KEY AUTO_INCREMENT, -nodeId int NOT NULL, -master int NULL, -alias nvarchar (100) NULL, -design LONGTEXT NOT NULL -) - -; -CREATE TABLE umbracoUser2app -( -user int NOT NULL, -app nvarchar (50) NOT NULL -) - -; -ALTER TABLE umbracoUser2app ADD CONSTRAINT PK_user2app PRIMARY KEY CLUSTERED (user, app) -; -CREATE TABLE umbracoUserType -( -id smallint NOT NULL PRIMARY KEY AUTO_INCREMENT, -userTypeAlias nvarchar (50) NULL, -userTypeName nvarchar (255) NOT NULL, -userTypeDefaultPermissions nvarchar (50) NULL -) - -; -CREATE TABLE umbracoUser -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -userDisabled bit NOT NULL DEFAULT 0, -userNoConsole bit NOT NULL DEFAULT 0, -userType smallint NOT NULL, -startStructureID int NOT NULL, -startMediaID int NULL, -userName nvarchar (255) NOT NULL, -userLogin nvarchar (125) NOT NULL, -userPassword nvarchar (125) NOT NULL, -userEmail nvarchar (255) NOT NULL, -userDefaultPermissions nvarchar (50) NULL, -userLanguage nvarchar (10) NULL , -defaultToLiveEditing bit NOT NULL DEFAULT 0 -) - -; -CREATE TABLE cmsDocumentType -( -contentTypeNodeId int NOT NULL, -templateNodeId int NOT NULL, -IsDefault bit NOT NULL DEFAULT 0 -) - -; -ALTER TABLE cmsDocumentType ADD CONSTRAINT PK_cmsDocumentType PRIMARY KEY CLUSTERED (contentTypeNodeId, templateNodeId) -; -CREATE TABLE cmsMemberType -( -pk int NOT NULL PRIMARY KEY AUTO_INCREMENT, -NodeId int NOT NULL, -propertytypeId int NOT NULL, -memberCanEdit bit NOT NULL DEFAULT 0, -viewOnProfile bit NOT NULL DEFAULT 0 -) - -; -CREATE TABLE cmsMember -( -nodeId int NOT NULL, -Email nvarchar (1000) NOT NULL DEFAULT '', -LoginName nvarchar (1000) NOT NULL DEFAULT '', -Password nvarchar (1000) NOT NULL DEFAULT '' -) - -; -CREATE TABLE umbracoNode -( -id int NOT NULL PRIMARY KEY, -trashed bit NOT NULL DEFAULT 0, -parentID int NOT NULL, -nodeUser int NULL, -level smallint NOT NULL, -path nvarchar (150) NOT NULL, -sortOrder int NOT NULL, -uniqueID CHAR(36) NULL, -text nvarchar (255) NULL, -nodeObjectType CHAR(36) NULL, -createDate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -) - -; -CREATE INDEX IX_umbracoNodeParentId ON umbracoNode (parentID) -; -CREATE INDEX IX_umbracoNodeObjectType ON umbracoNode (nodeObjectType) -; -CREATE TABLE cmsPropertyType -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -dataTypeId int NOT NULL, -contentTypeId int NOT NULL, -tabId int NULL, -Alias nvarchar (255) NOT NULL, -Name nvarchar (255) NULL, -helpText nvarchar (1000) NULL, -sortOrder int NOT NULL DEFAULT 0, -mandatory bit NOT NULL DEFAULT 0, -validationRegExp nvarchar (255) NULL, -Description nvarchar (2000) NULL -) - -; -CREATE TABLE cmsMacroProperty -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -macroPropertyHidden bit NOT NULL DEFAULT 0, -macroPropertyType smallint NOT NULL, -macro int NOT NULL, -macroPropertySortOrder tinyint NOT NULL DEFAULT 0, -macroPropertyAlias nvarchar (50) NOT NULL, -macroPropertyName nvarchar (255) NOT NULL -) - -; -CREATE TABLE cmsMacro -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -macroUseInEditor bit NOT NULL DEFAULT 0, -macroRefreshRate int NOT NULL DEFAULT 0, -macroAlias nvarchar (255) NOT NULL, -macroName nvarchar (255) NULL, -macroScriptType nvarchar (255) NULL, -macroScriptAssembly nvarchar (255) NULL, -macroXSLT nvarchar (255) NULL, -macroCacheByPage bit NOT NULL DEFAULT 1, -macroCachePersonalized bit NOT NULL DEFAULT 0, -macroDontRender bit NOT NULL DEFAULT 0 -) - -; -CREATE TABLE cmsContentVersion -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -ContentId int NOT NULL, -VersionId CHAR(36) NOT NULL, -VersionDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP -) - -; -CREATE TABLE umbracoAppTree -( -treeSilent bit NOT NULL DEFAULT 0, -treeInitialize bit NOT NULL DEFAULT 1, -treeSortOrder tinyint NOT NULL, -appAlias nvarchar (50) NOT NULL, -treeAlias nvarchar (150) NOT NULL, -treeTitle nvarchar (255) NOT NULL, -treeIconClosed nvarchar (255) NOT NULL, -treeIconOpen nvarchar (255) NOT NULL, -treeHandlerAssembly nvarchar (255) NOT NULL, -treeHandlerType nvarchar (255) NOT NULL, -action nvarchar (300) NULL -) - -; -ALTER TABLE umbracoAppTree ADD CONSTRAINT PK_umbracoAppTree PRIMARY KEY CLUSTERED (appAlias, treeAlias) -; -CREATE TABLE cmsContentTypeAllowedContentType -( -Id int NOT NULL, -AllowedId int NOT NULL -) - -; -ALTER TABLE cmsContentTypeAllowedContentType ADD CONSTRAINT PK_cmsContentTypeAllowedContentType PRIMARY KEY CLUSTERED (Id, AllowedId) -; -CREATE TABLE cmsContentXml -( -nodeId int NOT NULL PRIMARY KEY, -xml LONGTEXT NOT NULL -) - -; -CREATE TABLE cmsDataType -( -pk int NOT NULL PRIMARY KEY AUTO_INCREMENT PRIMARY KEY, -nodeId int NOT NULL, -controlId CHAR(36) NOT NULL, -dbType varchar (50) NOT NULL -) - -; -CREATE TABLE cmsDataTypePreValues -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -datatypeNodeId int NOT NULL, -value NVARCHAR(2500) NULL, -sortorder int NOT NULL, -alias nvarchar (50) NULL -) - -; -CREATE TABLE cmsDictionary -( -pk int NOT NULL PRIMARY KEY AUTO_INCREMENT, -id CHAR(36) NOT NULL, -parent CHAR(36) NOT NULL, -`key` nvarchar (1000) NOT NULL -) - -; -CREATE TABLE cmsLanguageText -( -pk int NOT NULL PRIMARY KEY AUTO_INCREMENT, -languageId int NOT NULL, -UniqueId CHAR(36) NOT NULL, -value nvarchar (1000) NOT NULL -) - -; -CREATE TABLE cmsMember2MemberGroup -( -Member int NOT NULL, -MemberGroup int NOT NULL -) - -; -ALTER TABLE cmsMember2MemberGroup ADD CONSTRAINT PK_cmsMember2MemberGroup PRIMARY KEY CLUSTERED (Member, MemberGroup) -; -CREATE TABLE cmsStylesheet -( -nodeId int NOT NULL, -filename nvarchar (100) NOT NULL, -content LONGTEXT NULL -) - -; -CREATE TABLE cmsStylesheetProperty -( -nodeId int NOT NULL, -stylesheetPropertyEditor bit NULL, -stylesheetPropertyAlias nvarchar (50) NULL, -stylesheetPropertyValue nvarchar (400) NULL -) - -; -CREATE TABLE umbracoDomains -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -domainDefaultLanguage int NULL, -domainRootStructureID int NULL, -domainName nvarchar (255) NOT NULL -) - -; -CREATE TABLE umbracoLanguage -( -id smallint NOT NULL PRIMARY KEY AUTO_INCREMENT, -languageISOCode nvarchar (10) NULL, -languageCultureName nvarchar (100) NULL -) - -; -CREATE TABLE umbracoRelationType -( -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -`dual` bit NOT NULL, -parentObjectType CHAR(36) NOT NULL, -childObjectType CHAR(36) NOT NULL, -name nvarchar (255) NOT NULL, -alias nvarchar (100) NULL -) -; - -/* TABLE IS NEVER USED, REMOVED FOR 4.1 - -CREATE TABLE umbracoStylesheet -( -nodeId int NOT NULL PRIMARY KEY, -filename nvarchar (100) NOT NULL, -content LONGTEXT NULL -) -; - -*/ - -CREATE TABLE umbracoUser2NodeNotify -( -userId int NOT NULL, -nodeId int NOT NULL, -action char (1) NOT NULL -) - -; -ALTER TABLE umbracoUser2NodeNotify ADD CONSTRAINT PK_umbracoUser2NodeNotify PRIMARY KEY CLUSTERED (userId, nodeId, action) -; -CREATE TABLE umbracoUser2NodePermission -( -userId int NOT NULL, -nodeId int NOT NULL, -permission char (1) NOT NULL -) - -; -ALTER TABLE umbracoUser2NodePermission ADD CONSTRAINT PK_umbracoUser2NodePermission PRIMARY KEY CLUSTERED (userId, nodeId, permission) -; -INSERT INTO umbracoNode (id, trashed, parentID, nodeUser, level, path, sortOrder, uniqueID, text, nodeObjectType, createDate) VALUES - (-92, 0, -1, 0, 11, '-1,-92', 37, 'f0bc4bfb-b499-40d6-ba86-058885a5178c', 'Label', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'), - (-90, 0, -1, 0, 11, '-1,-90', 35, '84c6b441-31df-4ffe-b67e-67d5bc3ae65a', 'Upload', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'), - (-89, 0, -1, 0, 11, '-1,-89', 34, 'c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3', 'Textarea', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'), - (-88, 0, -1, 0, 11, '-1,-88', 33, '0cc0eba1-9960-42c9-bf9b-60e150b429ae', 'Textstring', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'), - (-87, 0, -1, 0, 11, '-1,-87', 32, 'ca90c950-0aff-4e72-b976-a30b1ac57dad', 'Richtext editor', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'), - (-51, 0, -1, 0, 11, '-1,-51', 4, '2e6d3631-066e-44b8-aec4-96f09099b2b5', 'Numeric', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'), - (-49, 0, -1, 0, 11, '-1,-49', 2, '92897bc6-a5f3-4ffe-ae27-f2e7e33dda49', 'True/false', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'), - (-43, 0, -1, 0, 1, '-1,-43', 2, 'fbaf13a8-4036-41f2-93a3-974f678c312a', 'Checkbox list', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:11:04.367'), - (-42, 0, -1, 0, 1, '-1,-42', 2, '0b6a45e7-44ba-430d-9da5-4e46060b9e03', 'Dropdow', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:59.000'), - (-41, 0, -1, 0, 1, '-1,-41', 2, '5046194e-4237-453c-a547-15db3a07c4e1', 'Date Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:54.303'), - (-40, 0, -1, 0, 1, '-1,-40', 2, 'bb5f57c9-ce2b-4bb9-b697-4caca783a805', 'Radiobox', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:49.253'), - (-39, 0, -1, 0, 1, '-1,-39', 2, 'f38f0ac7-1d27-439c-9f3f-089cd8825a53', 'Dropdown multiple', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:44.480'), - (-38, 0, -1, 0, 1, '-1,-38', 2, 'fd9f1447-6c61-4a7c-9595-5aa39147d318', 'Folder Browser', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:37.020'), - (-37, 0, -1, 0, 1, '-1,-37', 2, '0225af17-b302-49cb-9176-b9f35cab9c17', 'Approved Color', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:30.580'), - (-36, 0, -1, 0, 1, '-1,-36', 2, 'e4d66c0f-b935-4200-81f0-025f7256b89a', 'Date Picker with time', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/10/15 14:10:23.007'), - (-20, 0, -1, 0, 0, '-1,-20', 0, '0F582A79-1E41-4CF0-BFA0-76340651891A', 'Recycle Bin', '01BB7FF2-24DC-4C0C-95A2-C24EF72BBAC8', '2004/09/30 14:01:49.920'), - (-1, 0, -1, 0, 0, '-1', 0, '916724a5-173d-4619-b97e-b9de133dd6f5', 'SYSTEM DATA: umbraco master root', 'ea7d8624-4cfe-4578-a871-24aa946bf34d', '2004/09/30 14:01:49.920'), - (1031, 0, -1, 1, 1, '-1,1031', 2, 'f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d', 'Folder', '4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e', '2004/12/01 00:13:40.743'), - (1032, 0, -1, 1, 1, '-1,1032', 2, 'cc07b313-0843-4aa8-bbda-871c8da728c8', 'Image', '4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e', '2004/12/01 00:13:43.737'), - (1033, 0, -1, 1, 1, '-1,1033', 2, '4c52d8ab-54e6-40cd-999c-7a5f24903e4d', 'File', '4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e', '2004/12/01 00:13:46.210'), - (1034, 0, -1, 0, 1, '-1,1034', 2, 'a6857c73-d6e9-480c-b6e6-f15f6ad11125', 'Content Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:29.203'), - (1035, 0, -1, 0, 1, '-1,1035', 2, '93929b9a-93a2-4e2a-b239-d99334440a59', 'Media Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:36.143'), - (1036, 0, -1, 0, 1, '-1,1036', 2, '2b24165f-9782-4aa3-b459-1de4a4d21f60', 'Member Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:40.260'), - (1038, 0, -1, 0, 1, '-1,1038', 2, '1251c96c-185c-4e9b-93f4-b48205573cbd', 'Simple Editor', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'), - (1039, 0, -1, 0, 1, '-1,1039', 2, '06f349a9-c949-4b6a-8660-59c10451af42', 'Ultimate Picker', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'), - (1040, 0, -1, 0, 1, '-1,1040', 2, '21e798da-e06e-4eda-a511-ed257f78d4fa', 'Related Links', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'), - (1041, 0, -1, 0, 1, '-1,1041', 2, 'b6b73142-b9c1-4bf8-a16d-e1c23320b549', 'Tags', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'), - (1042, 0, -1, 0, 1, '-1,1042', 2, '0a452bd5-83f9-4bc3-8403-1286e13fb77e', 'Macro Container', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250'), - (1043, 0, -1, 0, 1, '-1,1042', 2, '1df9f033-e6d4-451f-b8d2-e0cbc50a836f', 'Image Cropper', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2006/01/03 13:07:55.250') -; - -INSERT INTO cmsContentType (pk, nodeId, alias, icon) VALUES - (532, 1031, 'Folder', 'folder.gif'), - (533, 1032, 'Image', 'mediaPhoto.gif'), - (534, 1033, 'File', 'mediaMulti.gif') -; -INSERT INTO umbracoUserType (id, userTypeAlias, userTypeName, userTypeDefaultPermissions) VALUES - (1, 'admin', 'Administrators', 'CADMOSKTPIURZ5:'), - (2, 'writer', 'Writer', 'CAH:'), - (3, 'editor', 'Editors', 'CADMOSKTPUZ5:'), - (4, 'translator', 'Translator', 'A') -; -INSERT INTO umbracoUser (id, userDisabled, userNoConsole, userType, startStructureID, startMediaID, userName, userLogin, userPassword, userEmail, userDefaultPermissions, userLanguage) VALUES (0, 0, 0, 1, -1, -1, 'Administrator', 'admin', 'default', '', NULL, 'en') -; -UPDATE umbracoUser SET id=0 WHERE id=1 AND userLogin='admin' -; -INSERT INTO umbracoApp (appAlias, sortOrder, appIcon, appName, appInitWithTreeAlias) VALUES - ('content', 0, '.traycontent', 'Indhold', 'content'), - ('developer', 7, '.traydeveloper', 'Developer', NULL), - ('media', 1, '.traymedia', 'Mediearkiv', NULL), - ('member', 8, '.traymember', 'Medlemmer', NULL), - ('settings', 6, '.traysettings', 'Indstillinger', NULL), - ('users', 5, '.trayusers', 'Brugere', NULL) -; -INSERT INTO umbracoUser2app (user, app) VALUES - (0, 'content'), - (0, 'developer'), - (0, 'media'), - (0, 'member'), - (0, 'settings'), - (0, 'users') -; -INSERT INTO umbracoAppTree (appAlias, treeAlias, treeSilent, treeInitialize, treeSortOrder, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) VALUES - ('content', 'content', 1, 1, 0, 'Indhold', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadContent'), - ('developer', 'cacheBrowser', 0, 1, 0, 'CacheBrowser', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadCache'), - ('developer', 'CacheItem', 0, 0, 0, 'Cachebrowser', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadCacheItem'), - ('developer', 'datatype', 0, 1, 1, 'Datatyper', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadDataTypes'), - ('developer', 'macros', 0, 1, 2, 'Macros', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMacros'), - ('developer', 'xslt', 0, 1, 5, 'XSLT Files', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadXslt'), - - ('developer', 'packagerPackages', 0, 0, 1, 'Packager Packages', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadPackages'), - - ('media', 'media', 0, 1, 0, 'Medier', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMedia'), - ('member', 'member', 0, 1, 0, 'Medlemmer', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMembers'), - ('member', 'memberGroups', 0, 1, 1, 'MemberGroups', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMemberGroups'), - ('member', 'memberTypes', 0, 1, 2, 'Medlemstyper', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMemberTypes'), - ('settings', 'languages', 0, 1, 4, 'Languages', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadLanguages'), - ('settings', 'mediaTypes', 0, 1, 5, 'Medietyper', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMediaTypes'), - ('settings', 'documentTypes', 0, 1, 6, 'Dokumenttyper', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadNodeTypes'), - ('settings', 'stylesheetProperty', 0, 0, 0, 'Stylesheet Property', '', '', 'umbraco', 'loadStylesheetProperty'), - ('settings', 'stylesheets', 0, 1, 0, 'Stylesheets', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadStylesheets'), - ('settings', 'templates', 0, 1, 1, 'Templates', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadTemplates'), - ('users', 'users', 0, 1, 0, 'Brugere', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadUsers') -; - -INSERT INTO umbracoAppTree (appAlias, treeAlias, treeSilent, treeInitialize, treeSortOrder, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType, action) VALUES - ('settings', 'dictionary', 0, 1, 3, 'Dictionary', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadDictionary','openDictionary()') -; - -INSERT INTO cmsMacroPropertyType (id, macroPropertyTypeAlias, macroPropertyTypeRenderAssembly, macroPropertyTypeRenderType, macroPropertyTypeBaseType) VALUES - (3, 'mediaCurrent', 'umbraco.macroRenderings', 'media', 'Int32'), - (4, 'contentSubs', 'umbraco.macroRenderings', 'content', 'Int32'), - (5, 'contentRandom', 'umbraco.macroRenderings', 'content', 'Int32'), - (6, 'contentPicker', 'umbraco.macroRenderings', 'content', 'Int32'), - (13, 'number', 'umbraco.macroRenderings', 'numeric', 'Int32'), - (14, 'bool', 'umbraco.macroRenderings', 'yesNo', 'Boolean'), - (16, 'text', 'umbraco.macroRenderings', 'text', 'String'), - (17, 'contentTree', 'umbraco.macroRenderings', 'content', 'Int32'), - (18, 'contentType', 'umbraco.macroRenderings', 'contentTypeSingle', 'Int32'), - (19, 'contentTypeMultiple', 'umbraco.macroRenderings', 'contentTypeMultiple', 'Int32'), - (20, 'contentAll', 'umbraco.macroRenderings', 'content', 'Int32'), - (21, 'tabPicker', 'umbraco.macroRenderings', 'tabPicker', 'String'), - (22, 'tabPickerMultiple', 'umbraco.macroRenderings', 'tabPickerMultiple', 'String'), - (23, 'propertyTypePicker', 'umbraco.macroRenderings', 'propertyTypePicker', 'String'), - (24, 'propertyTypePickerMultiple', 'umbraco.macroRenderings', 'propertyTypePickerMultiple', 'String'), - (25, 'textMultiLine', 'umbraco.macroRenderings', 'textMultiple', 'String') -; -INSERT INTO cmsTab (id, contenttypeNodeId, text, sortorder) VALUES - (3, 1032, 'Image', 1), - (4, 1033, 'File', 1), - (5, 1031, 'Contents', 1) -; -INSERT INTO cmsPropertyType (id, dataTypeId, contentTypeId, tabId, Alias, Name, helpText, sortOrder, mandatory, validationRegExp, Description) VALUES - (6, -90, 1032, 3, 'umbracoFile', 'Upload image', NULL, 0, 0, NULL, NULL), - (7, -92, 1032, 3, 'umbracoWidth', 'Width', NULL, 0, 0, NULL, NULL), - (8, -92, 1032, 3, 'umbracoHeight', 'Height', NULL, 0, 0, NULL, NULL), - (9, -92, 1032, 3, 'umbracoBytes', 'Size', NULL, 0, 0, NULL, NULL), - (10, -92, 1032, 3, 'umbracoExtension', 'Type', NULL, 0, 0, NULL, NULL), - (24, -90, 1033, 4, 'umbracoFile', 'Upload file', NULL, 0, 0, NULL, NULL), - (25, -92, 1033, 4, 'umbracoExtension', 'Type', NULL, 0, 0, NULL, NULL), - (26, -92, 1033, 4, 'umbracoBytes', 'Size', NULL, 0, 0, NULL, NULL), - (27, -38, 1031, 5, 'contents', 'Contents:', NULL, 0, 0, NULL, NULL) -; -INSERT INTO umbracoLanguage (id, languageISOCode, languageCultureName) VALUES (1, 'en-US', 'en-US') -; -INSERT INTO cmsContentTypeAllowedContentType (Id, AllowedId) VALUES (1031, 1031),(1031, 1032),(1031, 1033) -; -INSERT INTO cmsDataType (pk, nodeId, controlId, dbType) VALUES - (4, -49, '38b352c1-e9f8-4fd8-9324-9a2eab06d97a', 'Integer'), - (6, -51, '1413afcb-d19a-4173-8e9a-68288d2a73b8', 'Integer'), - (8, -87, '5E9B75AE-FACE-41c8-B47E-5F4B0FD82F83', 'Ntext'), - (9, -88, 'ec15c1e5-9d90-422a-aa52-4f7622c63bea', 'Nvarchar'), - (10, -89, '67db8357-ef57-493e-91ac-936d305e0f2a', 'Ntext'), - (11, -90, '5032a6e6-69e3-491d-bb28-cd31cd11086c', 'Nvarchar'), - (12, -91, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Nvarchar'), - (13, -92, '6c738306-4c17-4d88-b9bd-6546f3771597', 'Nvarchar'), - (14, -36, 'b6fb1622-afa5-4bbf-a3cc-d9672a442222', 'Date'), - (15, -37, 'f8d60f68-ec59-4974-b43b-c46eb5677985', 'Nvarchar'), - (16, -38, 'cccd4ae9-f399-4ed2-8038-2e88d19e810c', 'Nvarchar'), - (17, -39, '928639ed-9c73-4028-920c-1e55dbb68783', 'Nvarchar'), - (18, -40, 'a52c7c1c-c330-476e-8605-d63d3b84b6a6', 'Nvarchar'), - (19, -41, '23e93522-3200-44e2-9f29-e61a6fcbb79a', 'Date'), - (20, -42, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Integer'), - (21, -43, 'b4471851-82b6-4c75-afa4-39fa9c6a75e9', 'Nvarchar'), - (22, -44, 'a3776494-0574-4d93-b7de-efdfdec6f2d1', 'Ntext'), - (23, -128, 'a52c7c1c-c330-476e-8605-d63d3b84b6a6', 'Nvarchar'), - (24, -129, '928639ed-9c73-4028-920c-1e55dbb68783', 'Nvarchar'), - (25, -130, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Nvarchar'), - (26, -131, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Nvarchar'), - (27, -132, 'a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6', 'Nvarchar'), - (28, -133, '6c738306-4c17-4d88-b9bd-6546f3771597', 'Ntext'), - (29, -134, '928639ed-9c73-4028-920c-1e55dbb68783', 'Nvarchar'), - (30, -50, 'aaf99bb2-dbbe-444d-a296-185076bf0484', 'Date'), - (31, 1034, '158aa029-24ed-4948-939e-c3da209e5fba', 'Integer'), - (32, 1035, 'ead69342-f06d-4253-83ac-28000225583b', 'Integer'), - (33, 1036, '39f533e4-0551-4505-a64b-e0425c5ce775', 'Integer'), - (35, 1038, '60b7dabf-99cd-41eb-b8e9-4d2e669bbde9', 'Ntext'), - (36, 1039, 'cdbf0b5d-5cb2-445f-bc12-fcaaec07cf2c', 'Ntext'), - (37, 1040, '71b8ad1a-8dc2-425c-b6b8-faa158075e63', 'Ntext'), - (38, 1041, '4023e540-92f5-11dd-ad8b-0800200c9a66', 'Ntext'), - (39, 1042, '474FCFF8-9D2D-11DE-ABC6-AD7A56D89593', 'Ntext'), - (40, 1043, '7A2D436C-34C2-410F-898F-4A23B3D79F54', 'Ntext') -; -ALTER TABLE umbracoAppTree ADD FOREIGN KEY (appAlias) REFERENCES umbracoApp (appAlias) -; -ALTER TABLE cmsPropertyData ADD FOREIGN KEY (contentNodeId) REFERENCES umbracoNode (id) -; - -/* TABLE IS NEVER USED, REMOVED FOR 4.1 - -ALTER TABLE umbracoUser2userGroup ADD FOREIGN KEY (user) REFERENCES umbracoUser (id) -; -ALTER TABLE umbracoUser2userGroup ADD FOREIGN KEY (userGroup) REFERENCES umbracoUserGroup (id) -; - -*/ - -ALTER TABLE cmsDocument ADD FOREIGN KEY (nodeId) REFERENCES umbracoNode (id) -; -ALTER TABLE cmsMacroProperty ADD FOREIGN KEY (macroPropertyType) REFERENCES cmsMacroPropertyType (id) -; -ALTER TABLE umbracoUser ADD FOREIGN KEY (userType) REFERENCES umbracoUserType (id) -; -ALTER TABLE cmsTemplate ADD FOREIGN KEY (nodeId) REFERENCES umbracoNode (id) -; -ALTER TABLE cmsContentType ADD FOREIGN KEY (nodeId) REFERENCES umbracoNode (id) -; -ALTER TABLE umbracoNode ADD FOREIGN KEY (parentID) REFERENCES umbracoNode (id) -; -ALTER TABLE cmsPropertyType ADD FOREIGN KEY (tabId) REFERENCES cmsTab (id) -; -ALTER TABLE cmsContent ADD FOREIGN KEY (nodeId) REFERENCES umbracoNode (id) -; -ALTER TABLE umbracoUser2app ADD FOREIGN KEY (app) REFERENCES umbracoApp (appAlias) -; - -/* TABLE IS NEVER USED, REMOVED FOR 4.1 - -ALTER TABLE umbracoUser2userGroup ADD FOREIGN KEY (user) REFERENCES umbracoUser (id) -; - -*/ - -CREATE TABLE cmsTask -( -closed bit NOT NULL DEFAULT 0, -id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -taskTypeId tinyint NOT NULL, -nodeId int NOT NULL, -parentUserId int NOT NULL, -userId int NOT NULL, -DateTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -Comment nvarchar (500) NULL -) -; -CREATE TABLE cmsTaskType -( -id tinyint NOT NULL PRIMARY KEY AUTO_INCREMENT, -alias nvarchar (255) NOT NULL -) -; -insert into cmsTaskType (alias) values ('toTranslate') -; -insert into umbracoRelationType (`dual`, parentObjectType, childObjectType, name, alias) values (1, 'c66ba18e-eaf3-4cff-8a22-41b16d66a972', 'c66ba18e-eaf3-4cff-8a22-41b16d66a972', 'Relate Document On Copy','relateDocumentOnCopy') -; -ALTER TABLE cmsMacro ADD macroPython nvarchar(255) -; -INSERT INTO umbracoAppTree(treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) VALUES(0, 1, 4, 'developer', 'python', 'Python Files', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadPython') -; -INSERT INTO umbracoAppTree(treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) VALUES(0, 1, 2, 'settings', 'scripts', 'Scripts', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadScripts') -; -alter TABLE cmsContentType add thumbnail nvarchar(255) NOT NULL DEFAULT 'folder.png' -; -alter TABLE cmsContentType add description nvarchar(1500) NULL -; -alter TABLE cmsContentType add masterContentType int NULL -; -insert into cmsDataTypePreValues (id, dataTypeNodeId, value, sortorder, alias) values -(3,-87,',code,undo,redo,cut,copy,mcepasteword,stylepicker,bold,italic,bullist,numlist,outdent,indent,mcelink,unlink,mceinsertanchor,mceimage,umbracomacro,mceinserttable,mcecharmap,|1|1,2,3,|0|500,400|1049,|true|', 0, ''), -(4,1041,'default', 0, 'group') -; - -UPDATE umbracoUserType SET userTypeDefaultPermissions = CONCAT(userTypeDefaultPermissions, 'F') WHERE INSTR(userTypeDefaultPermissions,'A') >= 1 -AND INSTR(userTypeDefaultPermissions,'F') < 1 -; - -UPDATE umbracoUserType SET userTypeDefaultPermissions = CONCAT(userTypeDefaultPermissions, 'H') WHERE userTypeAlias = 'writer' -AND INSTR(userTypeDefaultPermissions,'F') < 1 -; - -INSERT IGNORE INTO umbracoUser2NodePermission (userID, nodeId, permission) -SELECT userID, nodeId, 'F' FROM umbracoUser2NodePermission WHERE permission='A' -; - -INSERT IGNORE INTO umbracoUser2NodePermission (userID, nodeId, permission) -SELECT DISTINCT userID, nodeId, 'H' FROM umbracoUser2NodePermission WHERE userId IN -(SELECT umbracoUser.id FROM umbracoUserType INNER JOIN umbracoUser ON umbracoUserType.id = umbracoUser.userType WHERE (umbracoUserType.userTypeAlias = 'writer')) -; - -INSERT IGNORE INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) -VALUES (0, 0, 0, 'content', 'contentRecycleBin', 'RecycleBin', 'folder.gif', 'folder_o.gif', 'umbraco', 'cms.presentation.Trees.ContentRecycleBin') -; - -INSERT IGNORE INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) -VALUES (0, 1, 1, 'users', 'userTypes', 'User Types', 'folder.gif', 'folder_o.gif', 'umbraco', 'cms.presentation.Trees.UserTypes') -; - -INSERT IGNORE INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) -VALUES (0, 1, 2, 'users', 'userPermissions', 'User Permissions', 'folder.gif', 'folder_o.gif', 'umbraco', 'cms.presentation.Trees.UserPermissions') -; - -CREATE TABLE cmsTagRelationship -( - nodeId int NOT NULL, - tagId int NOT NULL -); - -ALTER TABLE cmsTagRelationship ADD CONSTRAINT PK_user2app PRIMARY KEY CLUSTERED (nodeId, tagId); - -CREATE TABLE cmsTags( - id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, - tag VARCHAR(200) NULL, - parentId INT NULL, - `group` VARCHAR(100) NULL -); - -ALTER TABLE cmsTagRelationship ADD CONSTRAINT umbracoNode_cmsTagRelationship FOREIGN KEY(nodeId) -REFERENCES umbracoNode (id) -ON DELETE CASCADE; - -ALTER TABLE cmsTagRelationship ADD CONSTRAINT cmsTags_cmsTagRelationship FOREIGN KEY(tagId) -REFERENCES cmsTags (id) -ON DELETE CASCADE; - -/* TRANSLATION RELATED SQL */ -INSERT INTO umbracoApp (appAlias, sortOrder, appIcon, appName, appInitWithTreeAlias) -VALUES ('translation', 5, '.traytranslation', 'Translation', NULL) -; -INSERT INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) -VALUES (0, 1, 1, 'translation','openTasks', 'Tasks assigned to you', '.sprTreeFolder', '.sprTreeFolder_o', 'umbraco', 'loadOpenTasks') -; -INSERT INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) -VALUES (0, 1, 2, 'translation','yourTasks', 'Tasks created by you', '.sprTreeFolder', '.sprTreeFolder_o', 'umbraco', 'loadYourTasks') -; - -ALTER TABLE umbraconode MODIFY COLUMN id INTEGER NOT NULL AUTO_INCREMENT; /* fix for MySQL bug 36411 */ - -/* remove auto increment so we can insert identity */ -ALTER TABLE umbraconode MODIFY COLUMN id INTEGER NOT NULL; -/* INSERT NEW MEDIA RECYCLE BIN NODE */ -INSERT INTO umbracoNode (id, trashed, parentID, nodeUser, level, path, sortOrder, uniqueID, text, nodeObjectType, createDate) -VALUES (-21, 0, -1, 0, 0, '-1,-21', 0, 'BF7C7CBC-952F-4518-97A2-69E9C7B33842', 'Recycle Bin', 'CF3D8E34-1C1C-41e9-AE56-878B57B32113', '2009/08/28 00:28:28.920') -; -/* re-add auto increment */ -ALTER TABLE umbraconode MODIFY COLUMN id INTEGER NOT NULL AUTO_INCREMENT; -/* Add the mediaRecycleBin tree type */ -INSERT IGNORE INTO umbracoAppTree (treeSilent, treeInitialize, treeSortOrder, appAlias, treeAlias, treeTitle, treeIconClosed, treeIconOpen, treeHandlerAssembly, treeHandlerType) -VALUES (0, 0, 0, 'media', 'mediaRecycleBin', 'RecycleBin', 'folder.gif', 'folder_o.gif', 'umbraco', 'cms.presentation.Trees.MediaRecycleBin') -; - -CREATE TABLE cmsPreviewXml( - nodeId int NOT NULL, - versionId CHAR(36) NOT NULL, - timestamp datetime NOT NULL, - xml LONGTEXT NOT NULL) -; -ALTER TABLE cmsPreviewXml ADD CONSTRAINT PK_cmsContentPreviewXml PRIMARY KEY CLUSTERED (nodeId, versionId) -; - - -/* Create missing indexes and primary keys */ -CREATE INDEX IX_Icon ON cmsContentType(nodeId, icon) -; - -/* CHANGE:Allan Stegelmann Laustsen */ -/* Create Custom Index to speed up tree loading */ -CREATE INDEX IX_contentid_versiondate ON cmscontentversion(CONTENTID, VERSIONDATE) -; -/* CHANGE:End */ - diff --git a/src/Umbraco.Tests/Migrations/SqlScripts/SqlResources.Designer.cs b/src/Umbraco.Tests/Migrations/SqlScripts/SqlResources.Designer.cs index eb7bba5593..7a7cee0ce3 100644 --- a/src/Umbraco.Tests/Migrations/SqlScripts/SqlResources.Designer.cs +++ b/src/Umbraco.Tests/Migrations/SqlScripts/SqlResources.Designer.cs @@ -19,7 +19,7 @@ namespace Umbraco.Tests.Migrations.SqlScripts { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class SqlResources { @@ -60,31 +60,6 @@ namespace Umbraco.Tests.Migrations.SqlScripts { } } - /// - /// Looks up a localized string similar to /******************************************************************************************* - /// - /// - /// - /// - /// - /// - /// - /// Umbraco database installation script for MySQL - /// - ///IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT - /// - /// Database version: 4.8.0.4 - /// - /// Please increment this version number if ANY change is made to this script, - /// so compatibility with scripts for other database systems can be verified easily. - /// The first 3 digits depict the Umbraco version, t [rest of string was truncated]";. - /// - internal static string MySqlTotal_480 { - get { - return ResourceManager.GetString("MySqlTotal_480", resourceCulture); - } - } - /// /// Looks up a localized string similar to CREATE TABLE [umbracoUserType] ( /// [id] int NOT NULL IDENTITY (5,1) diff --git a/src/Umbraco.Tests/Migrations/SqlScripts/SqlResources.resx b/src/Umbraco.Tests/Migrations/SqlScripts/SqlResources.resx index d379adbe64..20ba6d0e8e 100644 --- a/src/Umbraco.Tests/Migrations/SqlScripts/SqlResources.resx +++ b/src/Umbraco.Tests/Migrations/SqlScripts/SqlResources.resx @@ -118,9 +118,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - mysqltotal-480.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 - sqlcetotal-480.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 @@ -130,4 +127,4 @@ sqlservertotal-480.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 - \ No newline at end of file + diff --git a/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs b/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs index 70d70d4a31..8f56c8f246 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/ExpressionTests.cs @@ -160,41 +160,7 @@ namespace Umbraco.Tests.Persistence.Querying Assert.AreEqual("upper([umbracoUser].[userLogin]) = upper(@0)", result); Assert.AreEqual("hello@world.com", modelToSqlExpressionHelper.GetSqlParameters()[0]); } - - [Test] - public void Model_Expression_Value_Does_Not_Get_Double_Escaped() - { - //mysql escapes backslashes, so we'll test with that - var sqlSyntax = new MySqlSyntaxProvider(Mock.Of()); - var sqlContext = new SqlContext(sqlSyntax, DatabaseType.MySQL, SqlContext.PocoDataFactory); - - Expression> predicate = user => user.Username.Equals("mydomain\\myuser"); - var modelToSqlExpressionHelper = new ModelToSqlExpressionVisitor(sqlContext.SqlSyntax, Mappers); - var result = modelToSqlExpressionHelper.Visit(predicate); - - Debug.Print("Model to Sql ExpressionHelper: \n" + result); - - Assert.AreEqual("upper(`umbracoUser`.`userLogin`) = upper(@0)", result); - Assert.AreEqual("mydomain\\myuser", modelToSqlExpressionHelper.GetSqlParameters()[0]); - } - - [Test] - public void Poco_Expression_Value_Does_Not_Get_Double_Escaped() - { - //mysql escapes backslashes, so we'll test with that - var sqlSyntax = new MySqlSyntaxProvider(Mock.Of()); - var sqlContext = new SqlContext(sqlSyntax, DatabaseType.MySQL, SqlContext.PocoDataFactory); - - Expression> predicate = user => user.Login.StartsWith("mydomain\\myuser"); - var modelToSqlExpressionHelper = new PocoToSqlExpressionVisitor(sqlContext, null); - var result = modelToSqlExpressionHelper.Visit(predicate); - - Debug.Print("Poco to Sql ExpressionHelper: \n" + result); - - Assert.AreEqual("upper(`umbracoUser`.`userLogin`) LIKE upper(@0)", result); - Assert.AreEqual("mydomain\\myuser%", modelToSqlExpressionHelper.GetSqlParameters()[0]); - } - + [Test] public void Sql_Replace_Mapped() { diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index de1fc18249..fa914380f3 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -559,7 +559,6 @@ Designer Always - diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js b/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js index 98002ae1aa..e83c5114fc 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js @@ -6,8 +6,7 @@ angular.module("umbraco.install").controller("Umbraco.Installer.DataBaseControll $scope.dbs = [ { name: 'Microsoft SQL Server Compact (SQL CE)', id: 0}, { name: 'Microsoft SQL Server', id: 1}, - { name: 'Microsoft SQL Azure', id: 3 }, - { name: 'MySQL', id: 2 }, + { name: 'Microsoft SQL Azure', id: 3 }, { name: 'Custom connection string', id: -1} ]; diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 778ab188cd..363c475fa2 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -104,7 +104,6 @@ - 8.0.0-alpha.33 diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index 68fee030a0..2371282a14 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -71,8 +71,6 @@ - - @@ -150,12 +148,6 @@ - - - - - - diff --git a/src/Umbraco.Web/Install/InstallHelper.cs b/src/Umbraco.Web/Install/InstallHelper.cs index 36fb384655..f9519ebe8a 100644 --- a/src/Umbraco.Web/Install/InstallHelper.cs +++ b/src/Umbraco.Web/Install/InstallHelper.cs @@ -100,8 +100,6 @@ namespace Umbraco.Web.Install var syntax = sqlContext.SqlSyntax; if (syntax is SqlCeSyntaxProvider) dbProvider = "SqlServerCE"; - else if (syntax is MySqlSyntaxProvider) - dbProvider = "MySql"; else if (syntax is SqlServerSyntaxProvider) dbProvider = (syntax as SqlServerSyntaxProvider).ServerVersion.IsAzure ? "SqlAzure" : "SqlServer"; diff --git a/src/Umbraco.Web/Install/Models/DatabaseType.cs b/src/Umbraco.Web/Install/Models/DatabaseType.cs index 3f7379eca5..a8b98a7de5 100644 --- a/src/Umbraco.Web/Install/Models/DatabaseType.cs +++ b/src/Umbraco.Web/Install/Models/DatabaseType.cs @@ -4,7 +4,6 @@ { SqlCe, SqlServer, - MySql, SqlAzure, Custom }