Refactored data migration to correct SQL Server bugs

- Added explicit Identity column specification
- Defined string lengths explicitly on needed columns

--HG--
branch : dev
This commit is contained in:
Sebastien Ros 2010-07-08 15:18:13 -07:00
parent 199c462d4d
commit 7abd8ac71c
15 changed files with 65 additions and 39 deletions

View File

@ -212,7 +212,7 @@ namespace Orchard.Tests.DataMigration {
public int Create() {
SchemaBuilder.CreateTable("UserRecord", table =>
table.Column("Id", DbType.Int32, column =>
column.PrimaryKey()));
column.PrimaryKey().Identity()));
return 1;
}

View File

@ -47,7 +47,6 @@ namespace Orchard.Tests.DataMigration {
_schemaBuilder
.CreateTable("User", table => table
.ContentPartRecord()
.Column("Id", DbType.Int32, column => column.PrimaryKey())
.Column("Firstname", DbType.String, column => column.WithLength(255))
.Column("Lastname", DbType.String, column => column.WithPrecision(0).WithScale(1)))
.CreateTable("Address", table => table
@ -75,7 +74,7 @@ namespace Orchard.Tests.DataMigration {
_schemaBuilder
.CreateTable("User", table => table
.Column("Id", DbType.Int32, column => column.PrimaryKey())
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
.Column("Firstname", DbType.String, column => column.WithLength(255))
.Column("Lastname", DbType.String, column => column.WithLength(100).NotNull())
.Column("SN", DbType.AnsiString, column => column.WithLength(40).Unique())
@ -119,7 +118,7 @@ namespace Orchard.Tests.DataMigration {
_schemaBuilder
.CreateTable("User", table => table
.Column("Id", DbType.Int32, column => column.PrimaryKey())
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
.Column("Firstname", DbType.String, column => column.WithLength(255))
.Column("Lastname", DbType.String, column => column.WithPrecision(0).WithScale(1)))
.CreateTable("Address", table => table

View File

@ -8,7 +8,7 @@ namespace Orchard.Core.Common.DataMigrations {
//CREATE TABLE Common_BodyRecord (Id INTEGER not null, Text TEXT, Format TEXT, ContentItemRecord_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("BodyRecord", table => table
.ContentPartVersionRecord()
.Column<string>("Text")
.Column<string>("Text", column => column.WithLength(10000))
.Column<string>("Format")
);
@ -33,9 +33,9 @@ namespace Orchard.Core.Common.DataMigrations {
//CREATE TABLE Common_RoutableRecord (Id INTEGER not null, Title TEXT, Slug TEXT, Path TEXT, ContentItemRecord_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("RoutableRecord", table => table
.ContentPartVersionRecord()
.Column<string>("Title")
.Column<string>("Title", column => column.WithLength(1024))
.Column<string>("Slug")
.Column<string>("Path")
.Column<string>("Path", column => column.WithLength(2048))
);
return 0010;

View File

@ -7,7 +7,7 @@ namespace Orchard.Core.Scheduling.DataMigrations {
public int Create() {
//CREATE TABLE Scheduling_ScheduledTaskRecord (Id integer, TaskType TEXT, ScheduledUtc DATETIME, ContentItemVersionRecord_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ScheduledTaskRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("TaskType")
.Column<DateTime>("ScheduledUtc")
.Column<int>("ContentItemVersionRecord_id")

View File

@ -6,13 +6,13 @@ namespace Orchard.Core.Settings.DataMigrations {
public int Create() {
//CREATE TABLE Settings_ContentFieldDefinitionRecord (Id integer, Name TEXT, primary key (Id));
SchemaBuilder.CreateTable("ContentFieldDefinitionRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
);
//CREATE TABLE Settings_ContentPartDefinitionRecord (Id integer, Name TEXT, Hidden INTEGER, Settings TEXT, primary key (Id));
SchemaBuilder.CreateTable("ContentPartDefinitionRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
.Column<bool>("Hidden")
.Column<string>("Settings")
@ -20,7 +20,7 @@ namespace Orchard.Core.Settings.DataMigrations {
//CREATE TABLE Settings_ContentPartFieldDefinitionRecord (Id integer, Name TEXT, Settings TEXT, ContentFieldDefinitionRecord_id INTEGER, INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ContentPartFieldDefinitionRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
.Column<string>("Settings")
.Column<int>("ContentFieldDefinitionRecord_id")
@ -29,7 +29,7 @@ namespace Orchard.Core.Settings.DataMigrations {
//CREATE TABLE Settings_ContentTypeDefinitionRecord (Id integer, Name TEXT, DisplayName TEXT, Hidden INTEGER, Settings TEXT, primary key (Id));
SchemaBuilder.CreateTable("ContentTypeDefinitionRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
.Column<string>("DisplayName")
.Column<bool>("Hidden")
@ -38,7 +38,7 @@ namespace Orchard.Core.Settings.DataMigrations {
//CREATE TABLE Settings_ContentTypePartDefinitionRecord (Id integer, Settings TEXT, ContentPartDefinitionRecord_id INTEGER, ContentTypeDefinitionRecord_Id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ContentTypePartDefinitionRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Settings")
.Column<int>("ContentPartDefinitionRecord_id")
.Column<int>("ContentTypeDefinitionRecord_Id")
@ -46,19 +46,19 @@ namespace Orchard.Core.Settings.DataMigrations {
//CREATE TABLE Settings_ShellDescriptorRecord (Id integer, SerialNumber INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ShellDescriptorRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<int>("SerialNumber")
);
//CREATE TABLE Settings_ShellFeatureRecord (Id integer, Name TEXT, ShellDescriptorRecord_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ShellFeatureRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
.Column<int>("ShellDescriptorRecord_id"));
//CREATE TABLE Settings_ShellFeatureStateRecord (Id integer, Name TEXT, InstallState TEXT, EnableState TEXT, ShellStateRecord_Id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ShellFeatureStateRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
.Column<string>("InstallState")
.Column<string>("EnableState")
@ -67,7 +67,7 @@ namespace Orchard.Core.Settings.DataMigrations {
//CREATE TABLE Settings_ShellParameterRecord (Id integer, Component TEXT, Name TEXT, Value TEXT, ShellDescriptorRecord_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ShellParameterRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Component")
.Column<string>("Name")
.Column<string>("Value")
@ -76,7 +76,7 @@ namespace Orchard.Core.Settings.DataMigrations {
//CREATE TABLE Settings_ShellStateRecord (Id integer, primary key (Id));
SchemaBuilder.CreateTable("ShellStateRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
);

View File

@ -6,7 +6,7 @@ namespace Orchard.Blogs.DataMigrations {
public int Create() {
//CREATE TABLE Orchard_Blogs_BlogArchiveRecord (Id integer, Year INTEGER, Month INTEGER, PostCount INTEGER, Blog_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("BlogArchiveRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<int>("Year")
.Column<int>("Month")
.Column<int>("PostCount")
@ -15,7 +15,7 @@ namespace Orchard.Blogs.DataMigrations {
//CREATE TABLE Orchard_Blogs_BlogRecord (Id INTEGER not null, Description TEXT, PostCount INTEGER, primary key (Id));
SchemaBuilder.CreateTable("BlogRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.ContentPartRecord()
.Column<string>("Description")
.Column<int>("PostCount")
);

View File

@ -7,7 +7,7 @@ namespace Orchard.Comments.DataMigrations {
public int Create() {
//CREATE TABLE Orchard_Comments_ClosedCommentsRecord (Id integer, ContentItemId INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ClosedCommentsRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<int>("ContentItemId")
);
@ -20,7 +20,7 @@ namespace Orchard.Comments.DataMigrations {
.Column<string>("Email")
.Column<string>("Status")
.Column<DateTime>("CommentDateUtc")
.Column<string>("CommentText")
.Column<string>("CommentText", column => column.WithLength(10000))
.Column<int>("CommentedOn")
.Column<int>("CommentedOnContainer")
);

View File

@ -6,7 +6,7 @@ namespace Orchard.Roles.DataMigrations {
public int Create() {
//CREATE TABLE Orchard_Roles_PermissionRecord (Id integer, Name TEXT, ModuleName TEXT, Description TEXT, primary key (Id));
SchemaBuilder.CreateTable("PermissionRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
.Column<string>("ModuleName")
.Column<string>("Description")
@ -14,13 +14,13 @@ namespace Orchard.Roles.DataMigrations {
//CREATE TABLE Orchard_Roles_RoleRecord (Id integer, Name TEXT, primary key (Id));
SchemaBuilder.CreateTable("RoleRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
);
//CREATE TABLE Orchard_Roles_RolesPermissionsRecord (Id integer, Role_id INTEGER, Permission_id INTEGER, RoleRecord_Id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("RolesPermissionsRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<int>("Role_id")
.Column<int>("Permission_id")
.Column<int>("RoleRecord_Id")
@ -28,7 +28,7 @@ namespace Orchard.Roles.DataMigrations {
//CREATE TABLE Orchard_Roles_UserRolesRecord (Id integer, UserId INTEGER, Role_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("UserRolesRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<int>("UserId")
.Column<int>("Role_id")
);

View File

@ -9,6 +9,7 @@ using Orchard.Core.Common.Settings;
using Orchard.Core.Navigation.Models;
using Orchard.Core.Settings.Models;
using Orchard.Data;
using Orchard.Data.Migration.Generator;
using Orchard.Data.Migration.Interpreters;
using Orchard.Data.Providers;
using Orchard.Data.Migration.Schema;
@ -89,6 +90,7 @@ namespace Orchard.Setup.Services {
context.EnabledFeatures = hardcoded;
}
var shellSettings = new ShellSettings(_shellSettings);
if (string.IsNullOrEmpty(shellSettings.DataProvider)) {
@ -110,7 +112,7 @@ namespace Orchard.Setup.Services {
var schemaBuilder = new SchemaBuilder(environment.Resolve<IDataMigrationInterpreter>() );
schemaBuilder.CreateTable("Orchard_Framework_DataMigrationRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("DataMigrationClass")
.Column<int>("Version"));

View File

@ -6,13 +6,13 @@ namespace Orchard.Tags.DataMigrations {
public int Create() {
//CREATE TABLE Orchard_Tags_Tag (Id integer, TagName TEXT, primary key (Id));
SchemaBuilder.CreateTable("Tag", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("TagName")
);
//CREATE TABLE Orchard_Tags_TagsContentItems (Id integer, TagId INTEGER, ContentItemId INTEGER, primary key (Id));
SchemaBuilder.CreateTable("TagsContentItems", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<int>("TagId")
.Column<int>("ContentItemId")
);

View File

@ -6,14 +6,14 @@ namespace Orchard.ContentManagement.DataMigrations {
public int Create() {
//CREATE TABLE Orchard_Framework_ContentItemRecord (Id integer, Data TEXT, ContentType_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ContentItemRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Data")
.Column<int>("ContentType_id")
);
//CREATE TABLE Orchard_Framework_ContentItemVersionRecord (Id integer, Number INTEGER, Published INTEGER, Latest INTEGER, Data TEXT, ContentItemRecord_id INTEGER, primary key (Id));
SchemaBuilder.CreateTable("ContentItemVersionRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<int>("Number")
.Column<bool>("Published")
.Column<bool>("Latest")
@ -23,13 +23,13 @@ namespace Orchard.ContentManagement.DataMigrations {
//CREATE TABLE Orchard_Framework_ContentTypeRecord (Id integer, Name TEXT, primary key (Id));
SchemaBuilder.CreateTable("ContentTypeRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Name")
);
//CREATE TABLE Orchard_Framework_CultureRecord (Id integer, Culture TEXT, primary key (Id));
SchemaBuilder.CreateTable("CultureRecord", table => table
.Column<int>("Id", column => column.PrimaryKey())
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("Culture")
);

View File

@ -20,6 +20,9 @@ namespace Orchard.Data.Migration.Generator {
_sessionFactoryHolder = sessionFactoryHolder;
}
/// <summary>
/// Generates SchemaCommand instances in order to create the schema for a specific feature
/// </summary>
public IEnumerable<SchemaCommand> GetCreateFeatureCommands(string feature, bool drop) {
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
@ -31,7 +34,7 @@ namespace Orchard.Data.Migration.Generator {
Dialect.GetDialect(configuration.Properties);
var mapping = configuration.BuildMapping();
// get the tables using reflection
// get the table mappings using reflection
var tablesField = typeof(Configuration).GetField("tables", BindingFlags.Instance | BindingFlags.NonPublic);
var tables = ((IDictionary<string, Table>) tablesField.GetValue(configuration)).Values;
@ -56,7 +59,7 @@ namespace Orchard.Data.Migration.Generator {
command.Column(column.Name, sqlType.DbType,
action => {
if (table1.PrimaryKey.Columns.Any(c => c.Name == column1.Name)) {
action.PrimaryKey();
action.PrimaryKey().Identity();
}
if (column1.IsLengthDefined()) {
@ -85,12 +88,18 @@ namespace Orchard.Data.Migration.Generator {
}
}
/// <summary>
/// Automatically updates a db to a functionning schema
/// </summary>
public void UpdateDatabase() {
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
var configuration = _dataServicesProviderFactory.CreateProvider(parameters).BuildConfiguration(parameters);
new SchemaUpdate(configuration).Execute(false, true);
}
/// <summary>
/// Automatically creates a db with a functionning schema
/// </summary>
public void CreateDatabase() {
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
var configuration = _dataServicesProviderFactory.CreateProvider(parameters).BuildConfiguration(parameters);

View File

@ -280,8 +280,14 @@ namespace Orchard.Data.Migration.Interpreters {
// name
builder.Append(_dialect.QuoteForColumnName(command.ColumnName)).Append(Space);
// type
builder.Append(GetTypeName(command.DbType, command.Length, command.Precision, command.Scale));
if (!command.IsIdentity || _dialect.HasDataTypeInIdentityColumn ) {
builder.Append(GetTypeName(command.DbType, command.Length, command.Precision, command.Scale));
}
// append identity if handled
if ( command.IsIdentity && _dialect.SupportsIdentityColumns ) {
builder.Append(Space).Append(_dialect.IdentityColumnString);
}
// [default value]
if ( !string.IsNullOrEmpty(command.Default) ) {
@ -299,6 +305,7 @@ namespace Orchard.Data.Migration.Interpreters {
if ( command.IsUnique && _dialect.SupportsUnique ) {
builder.Append(" unique");
}
}
private void RunPendingStatements() {

View File

@ -13,12 +13,20 @@ namespace Orchard.Data.Migration.Schema {
public bool IsPrimaryKey { get; protected set; }
public bool IsIdentity { get; protected set; }
public CreateColumnCommand PrimaryKey() {
IsPrimaryKey = true;
IsUnique = false;
return this;
}
public CreateColumnCommand Identity() {
IsIdentity = true;
IsUnique = false;
return this;
}
public CreateColumnCommand WithPrecision(byte precision) {
Precision = precision;
return this;
@ -42,6 +50,7 @@ namespace Orchard.Data.Migration.Schema {
public CreateColumnCommand Unique() {
IsUnique = true;
IsPrimaryKey = false;
IsIdentity = false;
return this;
}

View File

@ -27,7 +27,7 @@ namespace Orchard.Data.Migration.Schema {
/// Defines a primary column as for content parts
/// </summary>
public CreateTableCommand ContentPartRecord() {
Column<int>("Id", column => column.PrimaryKey());
Column<int>("Id", column => column.PrimaryKey().NotNull());
return this;
}
@ -36,7 +36,7 @@ namespace Orchard.Data.Migration.Schema {
/// Defines a primary column as for versionnable content parts
/// </summary>
public CreateTableCommand ContentPartVersionRecord() {
Column<int>("Id", column => column.PrimaryKey());
Column<int>("Id", column => column.PrimaryKey().NotNull());
Column<int>("ContentItemRecord_id");
return this;
}