From 3f4e817b56cdc083fd5554376c7d3f600d9c9546 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 22 Sep 2010 14:17:45 -0700 Subject: [PATCH] Manage default SQL values conversion in Datq Migrations --HG-- branch : dev --- .../DataMigration/SchemaBuilderTests.cs | 6 +-- .../DataMigrations/UsersDataMigration.cs | 12 +++--- .../Generator/SchemaCommandGenerator.cs | 30 ++++++++------- .../DefaultDataMigrationInterpreter.cs | 38 ++++++++++++++++++- .../Data/Migration/Schema/ColumnCommand.cs | 4 +- .../Migration/Schema/CreateColumnCommand.cs | 2 +- 6 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/Orchard.Tests/DataMigration/SchemaBuilderTests.cs b/src/Orchard.Tests/DataMigration/SchemaBuilderTests.cs index 59f493f52..fdbc736fc 100644 --- a/src/Orchard.Tests/DataMigration/SchemaBuilderTests.cs +++ b/src/Orchard.Tests/DataMigration/SchemaBuilderTests.cs @@ -96,7 +96,7 @@ namespace Orchard.Tests.DataMigration { .Column("Lastname", DbType.String, column => column.WithLength(100).NotNull()) .Column("SN", DbType.AnsiString, column => column.WithLength(40).Unique()) .Column("Salary", DbType.Decimal, column => column.WithPrecision(9).WithScale(2)) - .Column("Gender", DbType.Decimal, column => column.WithDefault("''")) + .Column("Gender", DbType.Decimal, column => column.WithDefault("")) ); } @@ -109,7 +109,7 @@ namespace Orchard.Tests.DataMigration { .Column("Lastname", DbType.String, column => column.WithLength(100).NotNull()) .Column("SN", DbType.AnsiString, column => column.WithLength(40).Unique()) .Column("Salary", DbType.Decimal, column => column.WithPrecision(9).WithScale(2)) - .Column("Gender", DbType.Decimal, column => column.WithDefault("''")) + .Column("Gender", DbType.Decimal, column => column.WithDefault("")) ); _schemaBuilder @@ -133,7 +133,7 @@ namespace Orchard.Tests.DataMigration { .AlterTable("User", table => table .AddColumn("Age", DbType.Int32)) .AlterTable("User", table => table - .AlterColumn("Lastname", column => column.WithDefault("'John'"))) + .AlterColumn("Lastname", column => column.WithDefault("John"))) .AlterTable("User", table => table .DropColumn("Firstname") ); diff --git a/src/Orchard.Web/Modules/Orchard.Users/DataMigrations/UsersDataMigration.cs b/src/Orchard.Web/Modules/Orchard.Users/DataMigrations/UsersDataMigration.cs index 95b725ffb..7bec8138d 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/DataMigrations/UsersDataMigration.cs +++ b/src/Orchard.Web/Modules/Orchard.Users/DataMigrations/UsersDataMigration.cs @@ -23,17 +23,17 @@ namespace Orchard.Users.DataMigrations { // Adds registration fields to previous versions SchemaBuilder - .AlterTable("UserPartRecord", table => table.AddColumn("RegistrationStatus", c => c.WithDefault("'Approved'"))) - .AlterTable("UserPartRecord", table => table.AddColumn("EmailStatus", c => c.WithDefault("'Approved'"))) + .AlterTable("UserPartRecord", table => table.AddColumn("RegistrationStatus", c => c.WithDefault("Approved"))) + .AlterTable("UserPartRecord", table => table.AddColumn("EmailStatus", c => c.WithDefault("Approved"))) .AlterTable("UserPartRecord", table => table.AddColumn("EmailChallengeToken")); // Site Settings record SchemaBuilder.CreateTable("RegistrationSettingsPartRecord", table => table .ContentPartRecord() - .Column("UsersCanRegister", c => c.WithDefault("'0'")) - .Column("UsersMustValidateEmail", c => c.WithDefault("'0'")) - .Column("UsersAreModerated", c => c.WithDefault("'0'")) - .Column("NotifyModeration", c => c.WithDefault("'0'")) + .Column("UsersCanRegister", c => c.WithDefault(false)) + .Column("UsersMustValidateEmail", c => c.WithDefault(false)) + .Column("UsersAreModerated", c => c.WithDefault(false)) + .Column("NotifyModeration", c => c.WithDefault(false)) ); return 2; diff --git a/src/Orchard/Data/Migration/Generator/SchemaCommandGenerator.cs b/src/Orchard/Data/Migration/Generator/SchemaCommandGenerator.cs index b51bf48ea..aad54fca0 100644 --- a/src/Orchard/Data/Migration/Generator/SchemaCommandGenerator.cs +++ b/src/Orchard/Data/Migration/Generator/SchemaCommandGenerator.cs @@ -94,12 +94,14 @@ namespace Orchard.Data.Migration.Generator { var command = new CreateTableCommand(tableName); foreach (var column in table.ColumnIterator) { - var table1 = table; - var column1 = column; - var sqlType = column1.GetSqlTypeCode(mapping); + // create copies for local variables to be evaluated at the time the loop is called, and not lately when the la;bda is executed + var tableCopy = table; + var columnCopy = column; + + var sqlType = columnCopy.GetSqlTypeCode(mapping); command.Column(column.Name, sqlType.DbType, action => { - if (table1.PrimaryKey.Columns.Any(c => c.Name == column1.Name)) { + if (tableCopy.PrimaryKey.Columns.Any(c => c.Name == columnCopy.Name)) { action.PrimaryKey(); if ( !isContentPart ) { @@ -108,26 +110,26 @@ namespace Orchard.Data.Migration.Generator { } - if ( column1.IsLengthDefined() + if ( columnCopy.IsLengthDefined() && new DbType[] { DbType.StringFixedLength, DbType.String, DbType.AnsiString, DbType.AnsiStringFixedLength }.Contains(sqlType.DbType) - && column1.Length != Column.DefaultLength) { - action.WithLength(column1.Length); + && columnCopy.Length != Column.DefaultLength) { + action.WithLength(columnCopy.Length); } - if (column1.IsPrecisionDefined()) { - action.WithPrecision((byte) column1.Precision); - action.WithScale((byte) column1.Scale); + if (columnCopy.IsPrecisionDefined()) { + action.WithPrecision((byte) columnCopy.Precision); + action.WithScale((byte) columnCopy.Scale); } - if (column1.IsNullable) { + if (columnCopy.IsNullable) { action.Nullable(); } - if ( column1.IsUnique ) { + if ( columnCopy.IsUnique ) { action.Unique(); } - if(column1.DefaultValue != null) { - action.WithDefault(column1.DefaultValue); + if(columnCopy.DefaultValue != null) { + action.WithDefault(columnCopy.DefaultValue); } }); } diff --git a/src/Orchard/Data/Migration/Interpreters/DefaultDataMigrationInterpreter.cs b/src/Orchard/Data/Migration/Interpreters/DefaultDataMigrationInterpreter.cs index 6377aa25f..148c22dbd 100644 --- a/src/Orchard/Data/Migration/Interpreters/DefaultDataMigrationInterpreter.cs +++ b/src/Orchard/Data/Migration/Interpreters/DefaultDataMigrationInterpreter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Globalization; using System.Linq; using System.Text; using NHibernate; @@ -200,7 +201,7 @@ namespace Orchard.Data.Migration.Interpreters { // [default value] if (!string.IsNullOrEmpty(command.Default)) { - builder.Append(" set default ").Append(command.Default).Append(Space); + builder.Append(" set default ").Append(ConvertToSqlValue(command.Default)).Append(Space); } _sqlStatements.Add(builder.ToString()); } @@ -304,7 +305,7 @@ namespace Orchard.Data.Migration.Interpreters { // [default value] if (!string.IsNullOrEmpty(command.Default)) { - builder.Append(" default ").Append(command.Default).Append(Space); + builder.Append(" default ").Append(ConvertToSqlValue(command.Default)).Append(Space); } // nullable @@ -352,5 +353,38 @@ namespace Orchard.Data.Migration.Interpreters { return false; } + + private static string ConvertToSqlValue(object value) { + if ( value == null ) { + return "null"; + } + + TypeCode typeCode = Type.GetTypeCode(value.GetType()); + switch (typeCode) { + case TypeCode.Empty: + case TypeCode.Object: + case TypeCode.DBNull: + case TypeCode.String: + case TypeCode.Char: + return String.Concat("'", Convert.ToString(value).Replace("'", "''"), "'"); + case TypeCode.Boolean: + return (bool) value ? "1" : "0"; + case TypeCode.SByte: + case TypeCode.Int16: + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return Convert.ToString(value, CultureInfo.InvariantCulture); + case TypeCode.DateTime: + return String.Concat("'", Convert.ToString(value, CultureInfo.InvariantCulture), "'"); + } + + return "null"; + } } } diff --git a/src/Orchard/Data/Migration/Schema/ColumnCommand.cs b/src/Orchard/Data/Migration/Schema/ColumnCommand.cs index d172229e0..33613336b 100644 --- a/src/Orchard/Data/Migration/Schema/ColumnCommand.cs +++ b/src/Orchard/Data/Migration/Schema/ColumnCommand.cs @@ -17,7 +17,7 @@ namespace Orchard.Data.Migration.Schema { public DbType DbType { get; private set; } - public string Default { get; private set; } + public object Default { get; private set; } public int? Length { get; private set; } @@ -26,7 +26,7 @@ namespace Orchard.Data.Migration.Schema { return this; } - public ColumnCommand WithDefault(string @default) { + public ColumnCommand WithDefault(object @default) { Default = @default; return this; } diff --git a/src/Orchard/Data/Migration/Schema/CreateColumnCommand.cs b/src/Orchard/Data/Migration/Schema/CreateColumnCommand.cs index b672312a1..59eecaac5 100644 --- a/src/Orchard/Data/Migration/Schema/CreateColumnCommand.cs +++ b/src/Orchard/Data/Migration/Schema/CreateColumnCommand.cs @@ -73,7 +73,7 @@ namespace Orchard.Data.Migration.Schema { return this; } - public new CreateColumnCommand WithDefault(string @default) { + public new CreateColumnCommand WithDefault(object @default) { base.WithDefault(@default); return this; }