From f48fb5c499ce75a9f4e8985ef96116e6755674d0 Mon Sep 17 00:00:00 2001 From: Brian Powell Date: Tue, 3 Dec 2013 15:44:34 -0500 Subject: [PATCH] Fix MySQL migrations. --- .../Migrations/Syntax/Delete/DeleteBuilder.cs | 24 +++++++-------- .../Expressions/DeleteConstraintExpression.cs | 29 ++++++++++++++++++- .../Expressions/DeleteForeignKeyExpression.cs | 4 +-- .../AlterTagRelationsTable.cs | 14 ++++----- .../SqlSyntax/MySqlSyntaxProvider.cs | 24 +++++++-------- 5 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs index 03ceaa6a4e..4865182134 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs @@ -27,7 +27,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete public IDeleteColumnFromTableSyntax Column(string columnName) { - var expression = _databaseProviders == null + var expression = _databaseProviders == null ? new DeleteColumnExpression { ColumnNames = { columnName } } : new DeleteColumnExpression(_context.CurrentDatabaseProvider, _databaseProviders) { ColumnNames = { columnName } }; _context.Expressions.Add(expression); @@ -36,7 +36,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete public IDeleteForeignKeyFromTableSyntax ForeignKey() { - var expression = _databaseProviders == null + var expression = _databaseProviders == null ? new DeleteForeignKeyExpression() : new DeleteForeignKeyExpression(_context.CurrentDatabaseProvider, _databaseProviders); _context.Expressions.Add(expression); @@ -45,7 +45,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete public IDeleteForeignKeyOnTableSyntax ForeignKey(string foreignKeyName) { - var expression = _databaseProviders == null + var expression = _databaseProviders == null ? new DeleteForeignKeyExpression { ForeignKey = { Name = foreignKeyName } } : new DeleteForeignKeyExpression(_context.CurrentDatabaseProvider, _databaseProviders) { ForeignKey = { Name = foreignKeyName } }; _context.Expressions.Add(expression); @@ -68,17 +68,17 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete public IDeleteIndexForTableSyntax Index(string indexName) { - var expression = new DeleteIndexExpression {Index = {Name = indexName}}; + var expression = new DeleteIndexExpression { Index = { Name = indexName } }; _context.Expressions.Add(expression); return new DeleteIndexBuilder(expression); } public IDeleteConstraintOnTableSyntax PrimaryKey(string primaryKeyName) { - var expression = new DeleteConstraintExpression(ConstraintType.PrimaryKey) - { - Constraint = { ConstraintName = primaryKeyName } - }; + var expression = new DeleteConstraintExpression(_context.CurrentDatabaseProvider, _databaseProviders, ConstraintType.PrimaryKey) + { + Constraint = { ConstraintName = primaryKeyName } + }; _context.Expressions.Add(expression); return new DeleteConstraintBuilder(expression); } @@ -86,16 +86,16 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete public IDeleteConstraintOnTableSyntax UniqueConstraint(string constraintName) { var expression = new DeleteConstraintExpression(ConstraintType.Unique) - { - Constraint = { ConstraintName = constraintName } - }; + { + Constraint = { ConstraintName = constraintName } + }; _context.Expressions.Add(expression); return new DeleteConstraintBuilder(expression); } public IDeleteDefaultConstraintOnTableSyntax DefaultConstraint() { - var expression = _databaseProviders == null + var expression = _databaseProviders == null ? new DeleteDefaultConstraintExpression() : new DeleteDefaultConstraintExpression(_context.CurrentDatabaseProvider, _databaseProviders); _context.Expressions.Add(expression); diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs index 1f20f6bbb9..39f250532d 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs @@ -10,13 +10,40 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions Constraint = new ConstraintDefinition(type); } + public DeleteConstraintExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders, ConstraintType type) + : base(current, databaseProviders) + { + Constraint = new ConstraintDefinition(type); + } + public ConstraintDefinition Constraint { get; private set; } public override string ToString() { - return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, + // Test for MySQL primary key situation. + if (CurrentDatabaseProvider == DatabaseProviders.MySql) + { + if (Constraint.IsPrimaryKeyConstraint) + { + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName), + "PRIMARY KEY", + ""); + } + else + { + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName), + "FOREIGN KEY", + ""); + } + } + else + { + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName), SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName)); + } } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs index df79f7c8f7..75eb5d1d1f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs @@ -27,7 +27,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.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(CurrentDatabaseProvider == DatabaseProviders.MySql) + if (CurrentDatabaseProvider == DatabaseProviders.MySql) { //MySql naming "convention" for foreignkeys, which aren't explicitly named if (string.IsNullOrEmpty(ForeignKey.Name)) @@ -35,7 +35,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable), - "FOREIGN KEY ", + "FOREIGN KEY", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name)); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs index 7b23e22504..4a549c7af3 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs @@ -26,11 +26,11 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven //create a new col which we will make a foreign key, but first needs to be populated with data. Alter.Table("cmsTagRelationship").AddColumn("propertyTypeId").AsInt32().Nullable(); + //drop the foreign key on umbracoNode. Must drop foreign key first before primary key can be removed in MySql. + Delete.ForeignKey("FK_cmsTagRelationship_umbracoNode_id").OnTable("cmsTagRelationship"); + //we need to drop the primary key Delete.PrimaryKey("PK_cmsTagRelationship").FromTable("cmsTagRelationship"); - - //drop the foreign key on umbracoNode - Delete.ForeignKey("FK_cmsTagRelationship_umbracoNode_id").OnTable("cmsTagRelationship"); } private void Upgrade() @@ -57,9 +57,9 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven var propertyTypes = propertyTypeIdRef.Where(x => x.NodeId == tr.NodeId).ToArray(); if (propertyTypes.Length == 0) { - LogHelper.Warn("There was no cmsContent reference for cmsTagRelationship for nodeId " + LogHelper.Warn("There was no cmsContent reference for cmsTagRelationship for nodeId " + tr.NodeId + - ". The new tag system only supports tags with references to content in the cmsContent and cmsPropertyType tables. This row will be deleted: " + ". The new tag system only supports tags with references to content in the cmsContent and cmsPropertyType tables. This row will be deleted: " + string.Format("nodeId: {0}, tagId: {1}", tr.NodeId, tr.TagId)); Delete.FromTable("cmsTagRelationship").Row(new { nodeId = tr.NodeId, tagId = tr.TagId }); } @@ -92,7 +92,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven Alter.Table("cmsTagRelationship").AlterColumn("propertyTypeId").AsInt32().NotNullable(); //we need to re-add the new primary key on all 3 columns - Create.PrimaryKey("PK_cmsTagRelationship").OnTable("cmsTagRelationship").Columns(new[] {"nodeId", "propertyTypeId", "tagId"}); + Create.PrimaryKey("PK_cmsTagRelationship").OnTable("cmsTagRelationship").Columns(new[] { "nodeId", "propertyTypeId", "tagId" }); //now we need to add a foreign key to the propertyTypeId column and change it's constraints Create.ForeignKey("FK_cmsTagRelationship_cmsPropertyType") @@ -102,7 +102,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven .PrimaryColumn("id") .OnDelete(Rule.None) .OnUpdate(Rule.None); - + //now we need to add a foreign key to the nodeId column to cmsContent (intead of the original umbracoNode) Create.ForeignKey("FK_cmsTagRelationship_cmsContent") .FromTable("cmsTagRelationship") diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index 52ea11e572..8f466e3829 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax TimeColumnDefinition = "time"; DecimalColumnDefinition = "decimal(38,6)"; GuidColumnDefinition = "char(36)"; - + InitColumnTypeMap(); DefaultValueFormat = "DEFAULT '{0}'"; @@ -48,7 +48,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax var items = db.Fetch( "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = @TableSchema", - new {TableSchema = db.Connection.Database}); + new { TableSchema = db.Connection.Database }); list = items.Select(x => x.TABLE_NAME).Cast().ToList(); } finally @@ -67,7 +67,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax 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}); + new { TableSchema = db.Connection.Database }); list = items.Select( item => @@ -90,7 +90,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax var items = db.Fetch( "SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = @TableSchema", - new {TableSchema = db.Connection.Database}); + new { TableSchema = db.Connection.Database }); list = items.Select(item => new Tuple(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList(); } finally @@ -109,7 +109,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax 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}); + new { TableSchema = db.Connection.Database }); list = items.Select( item => @@ -133,7 +133,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax db.ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " + "WHERE TABLE_NAME = @TableName AND " + "TABLE_SCHEMA = @TableSchema", - new {TableName = tableName, TableSchema = db.Connection.Database}); + new { TableName = tableName, TableSchema = db.Connection.Database }); } finally @@ -213,7 +213,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax return string.Format(CreateIndex, GetQuotedName(name), - GetQuotedTableName(index.TableName), + GetQuotedTableName(index.TableName), columns); } @@ -290,7 +290,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax { get { - throw new NotSupportedException("Default constraints are not supported in MySql"); + return "ALTER TABLE {0} ALTER COLUMN {1} DROP DEFAULT"; } } @@ -303,7 +303,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax 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 DeleteConstraint { get { return "ALTER TABLE {0} DROP {1} {2}"; } } public override string DropIndex { get { return "DROP INDEX {0} ON {1}"; } } @@ -318,11 +318,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax 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()) + + if (lowerCaseTableNames.Any()) supportsCaseInsensitiveQueries = lowerCaseTableNames.First() == 1; } - catch(Exception ex) + catch (Exception ex) { Logging.LogHelper.Error("Error querying for lower_case support", ex); }