diff --git a/src/Umbraco.Core/Persistence/Migrations/IMigration.cs b/src/Umbraco.Core/Persistence/Migrations/IMigration.cs
new file mode 100644
index 0000000000..2769400e44
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/IMigration.cs
@@ -0,0 +1,11 @@
+namespace Umbraco.Core.Persistence.Migrations
+{
+ ///
+ /// Marker interface for database migrations
+ ///
+ public interface IMigration
+ {
+ void Up();
+ void Down();
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationAttribute.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationAttribute.cs
new file mode 100644
index 0000000000..70484942fc
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/MigrationAttribute.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Umbraco.Core.Persistence.Migrations
+{
+ ///
+ /// Represents the Migration attribute, which is used to mark classes as
+ /// database migrations with Up/Down methods for pushing changes UP or pulling them DOWN.
+ ///
+ [AttributeUsage(AttributeTargets.Class)]
+ public class MigrationAttribute : Attribute
+ {
+ public MigrationAttribute(string targetVersion, int sortOrder)
+ {
+ TargetVersion = new Version(targetVersion);
+ SortOrder = sortOrder;
+ }
+
+ ///
+ /// Gets or sets the target version of this migration.
+ ///
+ public Version TargetVersion { get; private set; }
+
+ ///
+ /// Gets or sets the sort order, which is the order this migration will be run in.
+ ///
+ public int SortOrder { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs
new file mode 100644
index 0000000000..88103e7d2d
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs
@@ -0,0 +1,65 @@
+using Umbraco.Core.Persistence.Migrations.Syntax.Alter;
+using Umbraco.Core.Persistence.Migrations.Syntax.Create;
+using Umbraco.Core.Persistence.Migrations.Syntax.Delete;
+using Umbraco.Core.Persistence.Migrations.Syntax.Insert;
+using Umbraco.Core.Persistence.Migrations.Syntax.Rename;
+using Umbraco.Core.Persistence.Migrations.Syntax.Schema;
+using Umbraco.Core.Persistence.Migrations.Syntax.Update;
+
+namespace Umbraco.Core.Persistence.Migrations
+{
+ public abstract class MigrationBase : IMigration
+ {
+ internal IMigrationContext _context;
+
+ public abstract void Up();
+ public abstract void Down();
+
+ public virtual void GetUpExpressions(IMigrationContext context)
+ {
+ _context = context;
+ Up();
+ }
+
+ public virtual void GetDownExpressions(IMigrationContext context)
+ {
+ _context = context;
+ Down();
+ }
+
+ public IAlterSyntaxBuilder Alter
+ {
+ get { return new AlterSyntaxBuilder(_context); }
+ }
+
+ public ICreateBuilder Create
+ {
+ get { return new CreateBuilder(_context); }
+ }
+
+ public IDeleteBuilder Delete
+ {
+ get { return new DeleteBuilder(_context); }
+ }
+
+ public IInsertBuilder Insert
+ {
+ get { return new InsertBuilder(_context); }
+ }
+
+ public IRenameBuilder Rename
+ {
+ get { return new RenameBuilder(_context); }
+ }
+
+ public ISchemaBuilder Schema
+ {
+ get { return new SchemaBuilder(_context); }
+ }
+
+ public IUpdateBuilder Update
+ {
+ get { return new UpdateBuilder(_context); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs
new file mode 100644
index 0000000000..8fac51a11b
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Umbraco.Core.Persistence.Migrations
+{
+ internal class MigrationContext : IMigrationContext
+ {
+ public MigrationContext()
+ {
+ Expressions = new Collection();
+ }
+
+ public virtual ICollection Expressions { get; set; }
+ }
+
+ public interface IMigrationContext
+ {
+ ICollection Expressions { get; set; }
+ }
+
+ ///
+ /// Marker interface for migration expressions
+ ///
+ public interface IMigrationExpression
+ {}
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Model/ColumnDefinition.cs b/src/Umbraco.Core/Persistence/Migrations/Model/ColumnDefinition.cs
new file mode 100644
index 0000000000..c41aebf0ab
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Model/ColumnDefinition.cs
@@ -0,0 +1,29 @@
+using System.Data;
+
+namespace Umbraco.Core.Persistence.Migrations.Model
+{
+ public class ColumnDefinition
+ {
+ public virtual string Name { get; set; }
+ public virtual DbType? Type { get; set; }
+ public virtual int Size { get; set; }
+ public virtual int Precision { get; set; }
+ public virtual string CustomType { get; set; }
+ public virtual object DefaultValue { get; set; }
+ public virtual bool IsForeignKey { get; set; }
+ public virtual bool IsIdentity { get; set; }
+ public virtual bool IsIndexed { get; set; }
+ public virtual bool IsPrimaryKey { get; set; }
+ public virtual string PrimaryKeyName { get; set; }
+ public virtual bool IsNullable { get; set; }
+ public virtual bool IsUnique { get; set; }
+ public virtual string TableName { get; set; }
+ public virtual ColumnModificationType ModificationType { get; set; }
+ }
+
+ public enum ColumnModificationType
+ {
+ Create,
+ Alter
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Model/ForeignKeyDefinition.cs b/src/Umbraco.Core/Persistence/Migrations/Model/ForeignKeyDefinition.cs
new file mode 100644
index 0000000000..b688f230d5
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Model/ForeignKeyDefinition.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using System.Data;
+
+namespace Umbraco.Core.Persistence.Migrations.Model
+{
+ public class ForeignKeyDefinition
+ {
+ public ForeignKeyDefinition()
+ {
+ ForeignColumns = new List();
+ PrimaryColumns = new List();
+ }
+
+ public virtual string Name { get; set; }
+ public virtual string ForeignTable { get; set; }
+ public virtual string ForeignTableSchema { get; set; }
+ public virtual string PrimaryTable { get; set; }
+ public virtual string PrimaryTableSchema { get; set; }
+ public virtual Rule OnDelete { get; set; }
+ public virtual Rule OnUpdate { get; set; }
+ public virtual ICollection ForeignColumns { get; set; }
+ public virtual ICollection PrimaryColumns { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Model/IndexColumnDefinition.cs b/src/Umbraco.Core/Persistence/Migrations/Model/IndexColumnDefinition.cs
new file mode 100644
index 0000000000..1f30bf3381
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Model/IndexColumnDefinition.cs
@@ -0,0 +1,14 @@
+namespace Umbraco.Core.Persistence.Migrations.Model
+{
+ public class IndexColumnDefinition
+ {
+ public virtual string Name { get; set; }
+ public virtual Direction Direction { get; set; }
+ }
+
+ public enum Direction
+ {
+ Ascending = 0,
+ Descending = 1
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Model/IndexDefinition.cs b/src/Umbraco.Core/Persistence/Migrations/Model/IndexDefinition.cs
new file mode 100644
index 0000000000..0ba9c5f9ca
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Model/IndexDefinition.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Core.Persistence.Migrations.Model
+{
+ public class IndexDefinition
+ {
+ public IndexDefinition()
+ {
+ Columns = new List();
+ }
+
+ public virtual string Name { get; set; }
+ public virtual string SchemaName { get; set; }
+ public virtual string TableName { get; set; }
+ public virtual bool IsUnique { get; set; }
+ public bool IsClustered { get; set; }
+ public virtual ICollection Columns { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Model/SystemMethods.cs b/src/Umbraco.Core/Persistence/Migrations/Model/SystemMethods.cs
new file mode 100644
index 0000000000..2bd0591494
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Model/SystemMethods.cs
@@ -0,0 +1,10 @@
+namespace Umbraco.Core.Persistence.Migrations.Model
+{
+ public enum SystemMethods
+ {
+ NewGuid,
+ NewSequentialId,
+ CurrentDateTime,
+ CurrentUTCDateTime
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Model/TableDefinition.cs b/src/Umbraco.Core/Persistence/Migrations/Model/TableDefinition.cs
new file mode 100644
index 0000000000..a305875b7c
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Model/TableDefinition.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Core.Persistence.Migrations.Model
+{
+ public class TableDefinition
+ {
+ public TableDefinition()
+ {
+ Columns = new List();
+ ForeignKeys = new List();
+ Indexes = new List();
+ }
+
+ public virtual string Name { get; set; }
+ public virtual string SchemaName { get; set; }
+ public virtual ICollection Columns { get; set; }
+ public virtual ICollection ForeignKeys { get; set; }
+ public virtual ICollection Indexes { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/AlterSyntaxBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/AlterSyntaxBuilder.cs
new file mode 100644
index 0000000000..44b3c8c828
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/AlterSyntaxBuilder.cs
@@ -0,0 +1,30 @@
+using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column;
+using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions;
+using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter
+{
+ public class AlterSyntaxBuilder : IAlterSyntaxBuilder
+ {
+ private readonly IMigrationContext _context;
+
+ public AlterSyntaxBuilder(IMigrationContext context)
+ {
+ _context = context;
+ }
+
+ public IAlterTableSyntax Table(string tableName)
+ {
+ var expression = new AlterTableExpression { TableName = tableName };
+ //_context.Expressions.Add(expression);
+ return new AlterTableSyntaxBuilder(expression, _context);
+ }
+
+ public IAlterColumnSyntax Column(string columnName)
+ {
+ var expression = new AlterColumnExpression { Column = { Name = columnName } };
+ //_context.Expressions.Add(expression);
+ return new AlterColumnSyntaxBuilder(expression, _context);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/AlterColumnSyntaxBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/AlterColumnSyntaxBuilder.cs
new file mode 100644
index 0000000000..b0ef9144f8
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/AlterColumnSyntaxBuilder.cs
@@ -0,0 +1,229 @@
+using System.Data;
+using Umbraco.Core.Persistence.Migrations.Model;
+using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions;
+using Umbraco.Core.Persistence.Migrations.Syntax.Expressions;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column
+{
+ public class AlterColumnSyntaxBuilder : ExpressionBuilder,
+ IAlterColumnSyntax,
+ IAlterColumnOptionForeignKeyCascadeSyntax
+ {
+ private readonly IMigrationContext _context;
+
+ public AlterColumnSyntaxBuilder(AlterColumnExpression expression, IMigrationContext context)
+ : base(expression)
+ {
+ _context = context;
+ }
+
+ public ForeignKeyDefinition CurrentForeignKey { get; set; }
+
+ public override ColumnDefinition GetColumnForType()
+ {
+ return Expression.Column;
+ }
+
+ public IAlterColumnOptionSyntax WithDefaultValue(object value)
+ {
+ var dc = new AlterDefaultConstraintExpression
+ {
+ TableName = Expression.TableName,
+ SchemaName = Expression.SchemaName,
+ ColumnName = Expression.Column.Name,
+ DefaultValue = value
+ };
+
+ _context.Expressions.Add(dc);
+
+ Expression.Column.DefaultValue = value;
+
+ return this;
+ }
+
+ public IAlterColumnOptionSyntax Identity()
+ {
+ Expression.Column.IsIdentity = true;
+ return this;
+ }
+
+ public IAlterColumnOptionSyntax Indexed()
+ {
+ return Indexed(null);
+ }
+
+ public IAlterColumnOptionSyntax Indexed(string indexName)
+ {
+ Expression.Column.IsIndexed = true;
+
+ var index = new CreateIndexExpression
+ {
+ Index = new IndexDefinition
+ {
+ Name = indexName,
+ SchemaName = Expression.SchemaName,
+ TableName = Expression.TableName
+ }
+ };
+
+ index.Index.Columns.Add(new IndexColumnDefinition
+ {
+ Name = Expression.Column.Name
+ });
+
+ _context.Expressions.Add(index);
+
+ return this;
+ }
+
+ public IAlterColumnOptionSyntax PrimaryKey()
+ {
+ Expression.Column.IsPrimaryKey = true;
+ return this;
+ }
+
+ public IAlterColumnOptionSyntax PrimaryKey(string primaryKeyName)
+ {
+ Expression.Column.IsPrimaryKey = true;
+ Expression.Column.PrimaryKeyName = primaryKeyName;
+ return this;
+ }
+
+ public IAlterColumnOptionSyntax Nullable()
+ {
+ Expression.Column.IsNullable = true;
+ return this;
+ }
+
+ public IAlterColumnOptionSyntax NotNullable()
+ {
+ Expression.Column.IsNullable = false;
+ return this;
+ }
+
+ public IAlterColumnOptionSyntax Unique()
+ {
+ return Unique(null);
+ }
+
+ public IAlterColumnOptionSyntax Unique(string indexName)
+ {
+ Expression.Column.IsUnique = true;
+
+ var index = new CreateIndexExpression
+ {
+ Index = new IndexDefinition
+ {
+ Name = indexName,
+ SchemaName = Expression.SchemaName,
+ TableName = Expression.TableName,
+ IsUnique = true
+ }
+ };
+
+ index.Index.Columns.Add(new IndexColumnDefinition
+ {
+ Name = Expression.Column.Name
+ });
+
+ _context.Expressions.Add(index);
+
+ return this;
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax ForeignKey(string primaryTableName, string primaryColumnName)
+ {
+ return ForeignKey(null, null, primaryTableName, primaryColumnName);
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax ForeignKey(string foreignKeyName, string primaryTableName,
+ string primaryColumnName)
+ {
+ return ForeignKey(foreignKeyName, null, primaryTableName, primaryColumnName);
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax ForeignKey(string foreignKeyName, string primaryTableSchema,
+ string primaryTableName, string primaryColumnName)
+ {
+ Expression.Column.IsForeignKey = true;
+
+ var fk = new CreateForeignKeyExpression
+ {
+ ForeignKey = new ForeignKeyDefinition
+ {
+ Name = foreignKeyName,
+ PrimaryTable = primaryTableName,
+ PrimaryTableSchema = primaryTableSchema,
+ ForeignTable = Expression.TableName,
+ ForeignTableSchema = Expression.SchemaName
+ }
+ };
+
+ fk.ForeignKey.PrimaryColumns.Add(primaryColumnName);
+ fk.ForeignKey.ForeignColumns.Add(Expression.Column.Name);
+
+ _context.Expressions.Add(fk);
+ CurrentForeignKey = fk.ForeignKey;
+ return this;
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax ForeignKey()
+ {
+ Expression.Column.IsForeignKey = true;
+ return this;
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax ReferencedBy(string foreignTableName, string foreignColumnName)
+ {
+ return ReferencedBy(null, null, foreignTableName, foreignColumnName);
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax ReferencedBy(string foreignKeyName, string foreignTableName,
+ string foreignColumnName)
+ {
+ return ReferencedBy(foreignKeyName, null, foreignTableName, foreignColumnName);
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax ReferencedBy(string foreignKeyName, string foreignTableSchema,
+ string foreignTableName, string foreignColumnName)
+ {
+ var fk = new CreateForeignKeyExpression
+ {
+ ForeignKey = new ForeignKeyDefinition
+ {
+ Name = foreignKeyName,
+ PrimaryTable = Expression.TableName,
+ PrimaryTableSchema = Expression.SchemaName,
+ ForeignTable = foreignTableName,
+ ForeignTableSchema = foreignTableSchema
+ }
+ };
+
+ fk.ForeignKey.PrimaryColumns.Add(Expression.Column.Name);
+ fk.ForeignKey.ForeignColumns.Add(foreignColumnName);
+
+ _context.Expressions.Add(fk);
+ CurrentForeignKey = fk.ForeignKey;
+ return this;
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax OnDelete(Rule rule)
+ {
+ CurrentForeignKey.OnDelete = rule;
+ return this;
+ }
+
+ public IAlterColumnOptionForeignKeyCascadeSyntax OnUpdate(Rule rule)
+ {
+ CurrentForeignKey.OnUpdate = rule;
+ return this;
+ }
+
+ public IAlterColumnOptionSyntax OnDeleteOrUpdate(Rule rule)
+ {
+ OnDelete(rule);
+ OnUpdate(rule);
+ return this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnOptionForeignKeyCascadeSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnOptionForeignKeyCascadeSyntax.cs
new file mode 100644
index 0000000000..c6c3aae29e
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnOptionForeignKeyCascadeSyntax.cs
@@ -0,0 +1,9 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column
+{
+ public interface IAlterColumnOptionForeignKeyCascadeSyntax :
+ IAlterColumnOptionSyntax,
+ IForeignKeyCascadeSyntax
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnOptionSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnOptionSyntax.cs
new file mode 100644
index 0000000000..2dd4578f1d
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnOptionSyntax.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column
+{
+ public interface IAlterColumnOptionSyntax : IColumnOptionSyntax
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnSyntax.cs
new file mode 100644
index 0000000000..846b4857f2
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/IAlterColumnSyntax.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column
+{
+ public interface IAlterColumnSyntax : IFluentSyntax
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs
new file mode 100644
index 0000000000..32eaf9da71
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs
@@ -0,0 +1,22 @@
+using Umbraco.Core.Persistence.Migrations.Model;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions
+{
+ public class AlterColumnExpression : IMigrationExpression
+ {
+ public AlterColumnExpression()
+ {
+ Column = new ColumnDefinition() { ModificationType = ColumnModificationType.Alter };
+ }
+
+ public virtual string SchemaName { get; set; }
+ public virtual string TableName { get; set; }
+ public virtual ColumnDefinition Column { get; set; }
+
+ public override string ToString()
+ {
+ //TODO Implement usage of the SqlSyntax provider here to generate the sql statement for this expression.
+ return TableName + " " + Column.Name + " " + Column.Type ?? Column.CustomType;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterTableExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterTableExpression.cs
new file mode 100644
index 0000000000..bcff2fbc25
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterTableExpression.cs
@@ -0,0 +1,17 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions
+{
+ public class AlterTableExpression : IMigrationExpression
+ {
+ public AlterTableExpression()
+ {
+ }
+
+ public virtual string SchemaName { get; set; }
+ public virtual string TableName { get; set; }
+
+ public override string ToString()
+ {
+ return base.ToString() + TableName;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/IAlterSyntaxBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/IAlterSyntaxBuilder.cs
new file mode 100644
index 0000000000..479c2eadce
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/IAlterSyntaxBuilder.cs
@@ -0,0 +1,11 @@
+using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column;
+using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter
+{
+ public interface IAlterSyntaxBuilder : IFluentSyntax
+ {
+ IAlterTableSyntax Table(string tableName);
+ IAlterColumnSyntax Column(string columnName);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/AlterTableSyntaxBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/AlterTableSyntaxBuilder.cs
new file mode 100644
index 0000000000..79d5ba3630
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/AlterTableSyntaxBuilder.cs
@@ -0,0 +1,265 @@
+using System.Data;
+using Umbraco.Core.Persistence.Migrations.Model;
+using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions;
+using Umbraco.Core.Persistence.Migrations.Syntax.Expressions;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
+{
+ public class AlterTableSyntaxBuilder : ExpressionBuilder,
+ IAlterTableColumnSyntax,
+ IAlterTableColumnOptionForeignKeyCascadeSyntax
+ {
+ private readonly IMigrationContext _context;
+
+ public AlterTableSyntaxBuilder(AlterTableExpression expression, IMigrationContext context)
+ : base(expression)
+ {
+ _context = context;
+ }
+
+ public ColumnDefinition CurrentColumn { get; set; }
+
+ public ForeignKeyDefinition CurrentForeignKey { get; set; }
+
+ public override ColumnDefinition GetColumnForType()
+ {
+ return CurrentColumn;
+ }
+
+ public IAlterTableColumnOptionSyntax WithDefaultValue(object value)
+ {
+ if (CurrentColumn.ModificationType == ColumnModificationType.Alter)
+ {
+ var dc = new AlterDefaultConstraintExpression
+ {
+ TableName = Expression.TableName,
+ SchemaName = Expression.SchemaName,
+ ColumnName = CurrentColumn.Name,
+ DefaultValue = value
+ };
+
+ _context.Expressions.Add(dc);
+ }
+
+ CurrentColumn.DefaultValue = value;
+ return this;
+ }
+
+ public IAlterTableColumnOptionSyntax Identity()
+ {
+ CurrentColumn.IsIdentity = true;
+ return this;
+ }
+
+ public IAlterTableColumnOptionSyntax Indexed()
+ {
+ return Indexed(null);
+ }
+
+ public IAlterTableColumnOptionSyntax Indexed(string indexName)
+ {
+ CurrentColumn.IsIndexed = true;
+
+ var index = new CreateIndexExpression
+ {
+ Index = new IndexDefinition
+ {
+ Name = indexName,
+ SchemaName = Expression.SchemaName,
+ TableName = Expression.TableName
+ }
+ };
+
+ index.Index.Columns.Add(new IndexColumnDefinition
+ {
+ Name = CurrentColumn.Name
+ });
+
+ _context.Expressions.Add(index);
+
+ return this;
+ }
+
+ public IAlterTableColumnOptionSyntax PrimaryKey()
+ {
+ CurrentColumn.IsPrimaryKey = true;
+ return this;
+ }
+
+ public IAlterTableColumnOptionSyntax PrimaryKey(string primaryKeyName)
+ {
+ CurrentColumn.IsPrimaryKey = true;
+ CurrentColumn.PrimaryKeyName = primaryKeyName;
+ return this;
+ }
+
+ public IAlterTableColumnOptionSyntax Nullable()
+ {
+ CurrentColumn.IsNullable = true;
+ return this;
+ }
+
+ public IAlterTableColumnOptionSyntax NotNullable()
+ {
+ CurrentColumn.IsNullable = false;
+ return this;
+ }
+
+ public IAlterTableColumnOptionSyntax Unique()
+ {
+ return Unique(null);
+ }
+
+ public IAlterTableColumnOptionSyntax Unique(string indexName)
+ {
+ CurrentColumn.IsUnique = true;
+
+ var index = new CreateIndexExpression
+ {
+ Index = new IndexDefinition
+ {
+ Name = indexName,
+ SchemaName = Expression.SchemaName,
+ TableName = Expression.TableName,
+ IsUnique = true
+ }
+ };
+
+ index.Index.Columns.Add(new IndexColumnDefinition
+ {
+ Name = CurrentColumn.Name
+ });
+
+ _context.Expressions.Add(index);
+
+ return this;
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax ForeignKey(string primaryTableName, string primaryColumnName)
+ {
+ return ForeignKey(null, null, primaryTableName, primaryColumnName);
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax ForeignKey(string foreignKeyName, string primaryTableName,
+ string primaryColumnName)
+ {
+ return ForeignKey(foreignKeyName, null, primaryTableName, primaryColumnName);
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax ForeignKey(string foreignKeyName, string primaryTableSchema,
+ string primaryTableName, string primaryColumnName)
+ {
+ CurrentColumn.IsForeignKey = true;
+
+ var fk = new CreateForeignKeyExpression
+ {
+ ForeignKey = new ForeignKeyDefinition
+ {
+ Name = foreignKeyName,
+ PrimaryTable = primaryTableName,
+ PrimaryTableSchema = primaryTableSchema,
+ ForeignTable = Expression.TableName,
+ ForeignTableSchema = Expression.SchemaName
+ }
+ };
+
+ fk.ForeignKey.PrimaryColumns.Add(primaryColumnName);
+ fk.ForeignKey.ForeignColumns.Add(CurrentColumn.Name);
+
+ _context.Expressions.Add(fk);
+ CurrentForeignKey = fk.ForeignKey;
+ return this;
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax ForeignKey()
+ {
+ CurrentColumn.IsForeignKey = true;
+ return this;
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax ReferencedBy(string foreignTableName, string foreignColumnName)
+ {
+ return ReferencedBy(null, null, foreignTableName, foreignColumnName);
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax ReferencedBy(string foreignKeyName, string foreignTableName,
+ string foreignColumnName)
+ {
+ return ReferencedBy(foreignKeyName, null, foreignTableName, foreignColumnName);
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax ReferencedBy(string foreignKeyName, string foreignTableSchema,
+ string foreignTableName, string foreignColumnName)
+ {
+ var fk = new CreateForeignKeyExpression
+ {
+ ForeignKey = new ForeignKeyDefinition
+ {
+ Name = foreignKeyName,
+ PrimaryTable = Expression.TableName,
+ PrimaryTableSchema = Expression.SchemaName,
+ ForeignTable = foreignTableName,
+ ForeignTableSchema = foreignTableSchema
+ }
+ };
+
+ fk.ForeignKey.PrimaryColumns.Add(CurrentColumn.Name);
+ fk.ForeignKey.ForeignColumns.Add(foreignColumnName);
+
+ _context.Expressions.Add(fk);
+ CurrentForeignKey = fk.ForeignKey;
+ return this;
+ }
+
+ public IAlterTableColumnSyntax AddColumn(string name)
+ {
+ var column = new ColumnDefinition { Name = name, ModificationType = ColumnModificationType.Create };
+ var createColumn = new CreateColumnExpression
+ {
+ Column = column,
+ SchemaName = Expression.SchemaName,
+ TableName = Expression.TableName
+ };
+
+ CurrentColumn = column;
+
+ _context.Expressions.Add(createColumn);
+ return this;
+ }
+
+ public IAlterTableColumnSyntax AlterColumn(string name)
+ {
+ var column = new ColumnDefinition { Name = name, ModificationType = ColumnModificationType.Alter };
+ var alterColumn = new AlterColumnExpression
+ {
+ Column = column,
+ SchemaName = Expression.SchemaName,
+ TableName = Expression.TableName
+ };
+
+ CurrentColumn = column;
+
+ _context.Expressions.Add(alterColumn);
+ return this;
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax OnDelete(Rule rule)
+ {
+ CurrentForeignKey.OnDelete = rule;
+ return this;
+ }
+
+ public IAlterTableColumnOptionForeignKeyCascadeSyntax OnUpdate(Rule rule)
+ {
+ CurrentForeignKey.OnUpdate = rule;
+ return this;
+ }
+
+ public IAlterTableColumnOptionSyntax OnDeleteOrUpdate(Rule rule)
+ {
+ OnDelete(rule);
+ OnUpdate(rule);
+ return this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnOptionForeignKeyCascadeSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnOptionForeignKeyCascadeSyntax.cs
new file mode 100644
index 0000000000..e9035c195c
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnOptionForeignKeyCascadeSyntax.cs
@@ -0,0 +1,9 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
+{
+ public interface IAlterTableColumnOptionForeignKeyCascadeSyntax :
+ IAlterTableColumnOptionSyntax,
+ IForeignKeyCascadeSyntax
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnOptionSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnOptionSyntax.cs
new file mode 100644
index 0000000000..956f9ee999
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnOptionSyntax.cs
@@ -0,0 +1,9 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
+{
+ public interface IAlterTableColumnOptionSyntax :
+ IColumnOptionSyntax,
+ IAlterTableSyntax
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnSyntax.cs
new file mode 100644
index 0000000000..44dc72de6c
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableColumnSyntax.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
+{
+ public interface IAlterTableColumnSyntax : IColumnTypeSyntax
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableSyntax.cs
new file mode 100644
index 0000000000..d761c80565
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/IAlterTableSyntax.cs
@@ -0,0 +1,8 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
+{
+ public interface IAlterTableSyntax : IFluentSyntax
+ {
+ IAlterTableColumnSyntax AddColumn(string name);
+ IAlterTableColumnSyntax AlterColumn(string name);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/CreateBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/CreateBuilder.cs
new file mode 100644
index 0000000000..af1a2284c0
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/CreateBuilder.cs
@@ -0,0 +1,12 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Create
+{
+ public class CreateBuilder : ICreateBuilder
+ {
+ private readonly IMigrationContext _context;
+
+ public CreateBuilder(IMigrationContext context)
+ {
+ _context = context;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/ICreateBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/ICreateBuilder.cs
new file mode 100644
index 0000000000..1a7e451f0b
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/ICreateBuilder.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Create
+{
+ public interface ICreateBuilder
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs
new file mode 100644
index 0000000000..8013869854
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs
@@ -0,0 +1,12 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete
+{
+ public class DeleteBuilder : IDeleteBuilder
+ {
+ private readonly IMigrationContext _context;
+
+ public DeleteBuilder(IMigrationContext context)
+ {
+ _context = context;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/IDeleteBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/IDeleteBuilder.cs
new file mode 100644
index 0000000000..2989156022
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/IDeleteBuilder.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete
+{
+ public interface IDeleteBuilder
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/ExpressionBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/ExpressionBuilder.cs
new file mode 100644
index 0000000000..28be42d739
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/ExpressionBuilder.cs
@@ -0,0 +1,181 @@
+using System.Data;
+using Umbraco.Core.Persistence.Migrations.Model;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax
+{
+ public abstract class ExpressionBuilder : ExpressionBuilderBase
+ where ExpressionT : IMigrationExpression
+ where NextT : IFluentSyntax
+ {
+ protected ExpressionBuilder(ExpressionT expression)
+ : base(expression)
+ {
+ }
+
+ public abstract ColumnDefinition GetColumnForType();
+
+ private ColumnDefinition Column
+ {
+ get { return GetColumnForType(); }
+ }
+
+ public NextT AsAnsiString()
+ {
+ Column.Type = DbType.AnsiString;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsAnsiString(int size)
+ {
+ Column.Type = DbType.AnsiString;
+ Column.Size = size;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsBinary()
+ {
+ Column.Type = DbType.Binary;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsBinary(int size)
+ {
+ Column.Type = DbType.Binary;
+ Column.Size = size;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsBoolean()
+ {
+ Column.Type = DbType.Boolean;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsByte()
+ {
+ Column.Type = DbType.Byte;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsCurrency()
+ {
+ Column.Type = DbType.Currency;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsDate()
+ {
+ Column.Type = DbType.Date;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsDateTime()
+ {
+ Column.Type = DbType.DateTime;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsDecimal()
+ {
+ Column.Type = DbType.Decimal;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsDecimal(int size, int precision)
+ {
+ Column.Type = DbType.Decimal;
+ Column.Size = size;
+ Column.Precision = precision;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsDouble()
+ {
+ Column.Type = DbType.Double;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsFixedLengthString(int size)
+ {
+ Column.Type = DbType.StringFixedLength;
+ Column.Size = size;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsFixedLengthAnsiString(int size)
+ {
+ Column.Type = DbType.AnsiStringFixedLength;
+ Column.Size = size;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsFloat()
+ {
+ Column.Type = DbType.Single;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsGuid()
+ {
+ Column.Type = DbType.Guid;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsInt16()
+ {
+ Column.Type = DbType.Int16;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsInt32()
+ {
+ Column.Type = DbType.Int32;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsInt64()
+ {
+ Column.Type = DbType.Int64;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsString()
+ {
+ Column.Type = DbType.String;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsString(int size)
+ {
+ Column.Type = DbType.String;
+ Column.Size = size;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsTime()
+ {
+ Column.Type = DbType.Time;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsXml()
+ {
+ Column.Type = DbType.Xml;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsXml(int size)
+ {
+ Column.Type = DbType.Xml;
+ Column.Size = size;
+ return (NextT)(object)this;
+ }
+
+ public NextT AsCustom(string customType)
+ {
+ Column.Type = null;
+ Column.CustomType = customType;
+ return (NextT)(object)this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/ExpressionBuilderBase.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/ExpressionBuilderBase.cs
new file mode 100644
index 0000000000..da75ab8541
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/ExpressionBuilderBase.cs
@@ -0,0 +1,13 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax
+{
+ public abstract class ExpressionBuilderBase
+ where T : IMigrationExpression
+ {
+ public T Expression { get; private set; }
+
+ protected ExpressionBuilderBase(T expression)
+ {
+ Expression = expression;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/AlterDefaultConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/AlterDefaultConstraintExpression.cs
new file mode 100644
index 0000000000..d50df9b0fe
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/AlterDefaultConstraintExpression.cs
@@ -0,0 +1,20 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
+{
+ public class AlterDefaultConstraintExpression : IMigrationExpression
+ {
+ public virtual string SchemaName { get; set; }
+ public virtual string TableName { get; set; }
+ public virtual string ColumnName { get; set; }
+ public virtual object DefaultValue { get; set; }
+
+ public override string ToString()
+ {
+ return base.ToString() +
+ string.Format("{0}.{1} {2} {3}",
+ SchemaName,
+ TableName,
+ ColumnName,
+ DefaultValue);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs
new file mode 100644
index 0000000000..592eac3e85
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs
@@ -0,0 +1,27 @@
+using System;
+using Umbraco.Core.Persistence.Migrations.Model;
+using Umbraco.Core.Persistence.SqlSyntax;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
+{
+ public class CreateColumnExpression : IMigrationExpression
+ {
+ public CreateColumnExpression()
+ {
+ Column = new ColumnDefinition { ModificationType = ColumnModificationType.Create };
+ }
+
+ public virtual string SchemaName { get; set; }
+ public virtual string TableName { get; set; }
+ public virtual ColumnDefinition Column { get; set; }
+
+ public override string ToString()
+ {
+
+ var output = String.Format(SyntaxConfig.SqlSyntaxProvider.AddColumn,
+ SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName),
+ SyntaxConfig.SqlSyntaxProvider.Format(Column));
+ return output;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs
new file mode 100644
index 0000000000..08ca98befa
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs
@@ -0,0 +1,26 @@
+using System.Linq;
+using Umbraco.Core.Persistence.Migrations.Model;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
+{
+ public class CreateForeignKeyExpression : IMigrationExpression
+ {
+ public CreateForeignKeyExpression()
+ {
+ ForeignKey = new ForeignKeyDefinition();
+ }
+
+ public virtual ForeignKeyDefinition ForeignKey { get; set; }
+
+ public override string ToString()
+ {
+ return base.ToString() +
+ string.Format("{0} {1}({2}) {3}({4})",
+ ForeignKey.Name,
+ ForeignKey.ForeignTable,
+ string.Join(", ", ForeignKey.ForeignColumns.ToArray()),
+ ForeignKey.PrimaryTable,
+ string.Join(", ", ForeignKey.PrimaryColumns.ToArray()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs
new file mode 100644
index 0000000000..854acd7e3d
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs
@@ -0,0 +1,20 @@
+using System.Linq;
+using Umbraco.Core.Persistence.Migrations.Model;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
+{
+ public class CreateIndexExpression : IMigrationExpression
+ {
+ public CreateIndexExpression()
+ {
+ Index = new IndexDefinition();
+ }
+
+ public virtual IndexDefinition Index { get; set; }
+
+ public override string ToString()
+ {
+ return base.ToString() + Index.TableName + " (" + string.Join(", ", Index.Columns.Select(x => x.Name).ToArray()) + ")";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/IColumnOptionSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/IColumnOptionSyntax.cs
new file mode 100644
index 0000000000..e18a68eda7
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/IColumnOptionSyntax.cs
@@ -0,0 +1,28 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax
+{
+ public interface IColumnOptionSyntax : IFluentSyntax
+ where TNext : IFluentSyntax
+ where TNextFk : IFluentSyntax
+ {
+ TNext WithDefaultValue(object value);
+ TNext Identity();
+ TNext Indexed();
+ TNext Indexed(string indexName);
+
+ TNext PrimaryKey();
+ TNext PrimaryKey(string primaryKeyName);
+ TNext Nullable();
+ TNext NotNullable();
+ TNext Unique();
+ TNext Unique(string indexName);
+
+ TNextFk ForeignKey(string primaryTableName, string primaryColumnName);
+ TNextFk ForeignKey(string foreignKeyName, string primaryTableName, string primaryColumnName);
+ TNextFk ForeignKey(string foreignKeyName, string primaryTableSchema, string primaryTableName, string primaryColumnName);
+ TNextFk ForeignKey();
+
+ TNextFk ReferencedBy(string foreignTableName, string foreignColumnName);
+ TNextFk ReferencedBy(string foreignKeyName, string foreignTableName, string foreignColumnName);
+ TNextFk ReferencedBy(string foreignKeyName, string foreignTableSchema, string foreignTableName, string foreignColumnName);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/IColumnTypeSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/IColumnTypeSyntax.cs
new file mode 100644
index 0000000000..406e6962bb
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/IColumnTypeSyntax.cs
@@ -0,0 +1,32 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax
+{
+ public interface IColumnTypeSyntax : IFluentSyntax
+ where TNext : IFluentSyntax
+ {
+ TNext AsAnsiString();
+ TNext AsAnsiString(int size);
+ TNext AsBinary();
+ TNext AsBinary(int size);
+ TNext AsBoolean();
+ TNext AsByte();
+ TNext AsCurrency();
+ TNext AsDate();
+ TNext AsDateTime();
+ TNext AsDecimal();
+ TNext AsDecimal(int size, int precision);
+ TNext AsDouble();
+ TNext AsGuid();
+ TNext AsFixedLengthString(int size);
+ TNext AsFixedLengthAnsiString(int size);
+ TNext AsFloat();
+ TNext AsInt16();
+ TNext AsInt32();
+ TNext AsInt64();
+ TNext AsString();
+ TNext AsString(int size);
+ TNext AsTime();
+ TNext AsXml();
+ TNext AsXml(int size);
+ TNext AsCustom(string customType);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/IFluentSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/IFluentSyntax.cs
new file mode 100644
index 0000000000..f6d1f67f2b
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/IFluentSyntax.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax
+{
+ public interface IFluentSyntax
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/IForeignKeyCascadeSyntax.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/IForeignKeyCascadeSyntax.cs
new file mode 100644
index 0000000000..eb75ef7c3d
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/IForeignKeyCascadeSyntax.cs
@@ -0,0 +1,13 @@
+using System.Data;
+
+namespace Umbraco.Core.Persistence.Migrations.Syntax
+{
+ public interface IForeignKeyCascadeSyntax : IFluentSyntax
+ where TNext : IFluentSyntax
+ where TNextFk : IFluentSyntax
+ {
+ TNextFk OnDelete(Rule rule);
+ TNextFk OnUpdate(Rule rule);
+ TNext OnDeleteOrUpdate(Rule rule);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/IInsertBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/IInsertBuilder.cs
new file mode 100644
index 0000000000..7a8eeeb8ba
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/IInsertBuilder.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Insert
+{
+ public interface IInsertBuilder
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/InsertBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/InsertBuilder.cs
new file mode 100644
index 0000000000..12f046e56b
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/InsertBuilder.cs
@@ -0,0 +1,12 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Insert
+{
+ public class InsertBuilder : IInsertBuilder
+ {
+ private readonly IMigrationContext _context;
+
+ public InsertBuilder(IMigrationContext context)
+ {
+ _context = context;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/IRenameBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/IRenameBuilder.cs
new file mode 100644
index 0000000000..6a54c32863
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/IRenameBuilder.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename
+{
+ public interface IRenameBuilder
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/RenameBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/RenameBuilder.cs
new file mode 100644
index 0000000000..4e04f87554
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/RenameBuilder.cs
@@ -0,0 +1,12 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename
+{
+ public class RenameBuilder : IRenameBuilder
+ {
+ private readonly IMigrationContext _context;
+
+ public RenameBuilder(IMigrationContext context)
+ {
+ _context = context;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Schema/ISchemaBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Schema/ISchemaBuilder.cs
new file mode 100644
index 0000000000..b22c92ed07
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Schema/ISchemaBuilder.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Schema
+{
+ public interface ISchemaBuilder
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Schema/SchemaBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Schema/SchemaBuilder.cs
new file mode 100644
index 0000000000..327102d520
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Schema/SchemaBuilder.cs
@@ -0,0 +1,12 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Schema
+{
+ public class SchemaBuilder : ISchemaBuilder
+ {
+ private readonly IMigrationContext _context;
+
+ public SchemaBuilder(IMigrationContext context)
+ {
+ _context = context;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/IUpdateBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/IUpdateBuilder.cs
new file mode 100644
index 0000000000..fce9bfe18f
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/IUpdateBuilder.cs
@@ -0,0 +1,7 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Update
+{
+ public interface IUpdateBuilder
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/UpdateBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/UpdateBuilder.cs
new file mode 100644
index 0000000000..5866a3b8b9
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/UpdateBuilder.cs
@@ -0,0 +1,12 @@
+namespace Umbraco.Core.Persistence.Migrations.Syntax.Update
+{
+ public class UpdateBuilder : IUpdateBuilder
+ {
+ private readonly IMigrationContext _context;
+
+ public UpdateBuilder(IMigrationContext context)
+ {
+ _context = context;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
index c5e117459f..6431b43347 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
@@ -26,5 +26,24 @@ namespace Umbraco.Core.Persistence.SqlSyntax
string GetSpecialDbType(SpecialDbTypes dbTypes);
string GetConstraintDefinition(ColumnDefinition column, string tableName);
List ToAlterIdentitySeedStatements(TableDefinition table);
+ string CreateTable { get; }
+ string DropTable { get; }
+ string AddColumn { get; }
+ string DropColumn { get; }
+ string AlterColumn { get; }
+ string RenameColumn { get; }
+ string RenameTable { get; }
+ string CreateSchema { get; }
+ string AlterSchema { get; }
+ string DropSchema { get; }
+ string CreateIndex { get; }
+ string DropIndex { get; }
+ string InsertData { get; }
+ string UpdateData { get; }
+ string DeleteData { get; }
+ string CreateConstraint { get; }
+ string DeleteConstraint { get; }
+ string CreateForeignKeyConstraint { get; }
+ string Format(Migrations.Model.ColumnDefinition column);
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs
index 2beec2bd1d..d9914f2e86 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs
@@ -1,7 +1,9 @@
using System.Collections.Generic;
using System.Text;
using Umbraco.Core.Persistence.DatabaseAnnotations;
-using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions;
+using Umbraco.Core.Persistence.Migrations.Model;
+using ColumnDefinition = Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions.ColumnDefinition;
+using TableDefinition = Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions.TableDefinition;
namespace Umbraco.Core.Persistence.SqlSyntax
{
@@ -166,5 +168,33 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return result > 0;
}
+
+ protected override string FormatIdentity(Migrations.Model.ColumnDefinition column)
+ {
+ return column.IsIdentity ? AutoIncrementDefinition : string.Empty;
+ }
+
+ protected override string FormatSystemMethods(SystemMethods systemMethod)
+ {
+ switch (systemMethod)
+ {
+ case SystemMethods.NewGuid:
+ return "NEWID()";
+ case SystemMethods.NewSequentialId:
+ return "NEWSEQUENTIALID()";
+ case SystemMethods.CurrentDateTime:
+ return "GETDATE()";
+ case SystemMethods.CurrentUTCDateTime:
+ return "GETUTCDATE()";
+ }
+
+ return null;
+ }
+
+ public override string AlterColumn { get { return "ALTER TABLE {0} MODIFY COLUMN {1}"; } }
+
+ public override string DeleteConstraint { get { return "ALTER TABLE {0} DROP {1}{2}"; } }
+
+ public override string CreateTable { get { return "CREATE TABLE {0} ({1}) ENGINE = INNODB"; } }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
index 8a644ddd43..07fdd0a790 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
@@ -1,4 +1,5 @@
-using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions;
+using Umbraco.Core.Persistence.Migrations.Model;
+using ColumnDefinition = Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions.ColumnDefinition;
namespace Umbraco.Core.Persistence.SqlSyntax
{
@@ -75,5 +76,34 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return result > 0;
}
+
+ protected override string FormatIdentity(Migrations.Model.ColumnDefinition column)
+ {
+ return column.IsIdentity ? GetIdentityString(column) : string.Empty;
+ }
+
+ private static string GetIdentityString(Migrations.Model.ColumnDefinition column)
+ {
+ return "IDENTITY(1,1)";
+ }
+
+ protected override string FormatSystemMethods(SystemMethods systemMethod)
+ {
+ switch (systemMethod)
+ {
+ case SystemMethods.NewGuid:
+ return "NEWID()";
+ case SystemMethods.NewSequentialId:
+ return "NEWSEQUENTIALID()";
+ case SystemMethods.CurrentDateTime:
+ return "GETDATE()";
+ case SystemMethods.CurrentUTCDateTime:
+ return "GETUTCDATE()";
+ }
+
+ return null;
+ }
+
+ public override string AddColumn { get { return "ALTER TABLE {0} ADD {1}"; } }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
index ca6a5f1a13..5784fff530 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
@@ -1,4 +1,6 @@
-namespace Umbraco.Core.Persistence.SqlSyntax
+using Umbraco.Core.Persistence.Migrations.Model;
+
+namespace Umbraco.Core.Persistence.SqlSyntax
{
///
/// Static class that provides simple access to the Sql Server SqlSyntax Providers singleton
@@ -40,5 +42,34 @@
return result > 0;
}
+
+ protected override string FormatIdentity(Migrations.Model.ColumnDefinition column)
+ {
+ return column.IsIdentity ? GetIdentityString(column) : string.Empty;
+ }
+
+ private static string GetIdentityString(Migrations.Model.ColumnDefinition column)
+ {
+ return "IDENTITY(1,1)";
+ }
+
+ protected override string FormatSystemMethods(SystemMethods systemMethod)
+ {
+ switch (systemMethod)
+ {
+ case SystemMethods.NewGuid:
+ return "NEWID()";
+ case SystemMethods.NewSequentialId:
+ return "NEWSEQUENTIALID()";
+ case SystemMethods.CurrentDateTime:
+ return "GETDATE()";
+ case SystemMethods.CurrentUTCDateTime:
+ return "GETUTCDATE()";
+ }
+
+ return null;
+ }
+
+ public override string AddColumn { get { return "ALTER TABLE {0} ADD {1}"; } }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
index ec0337d293..da129c7aca 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
@@ -4,7 +4,9 @@ using System.Data;
using System.Linq;
using System.Text;
using Umbraco.Core.Persistence.DatabaseAnnotations;
-using Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions;
+using Umbraco.Core.Persistence.Migrations.Model;
+using ColumnDefinition = Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions.ColumnDefinition;
+using TableDefinition = Umbraco.Core.Persistence.SqlSyntax.ModelDefinitions.TableDefinition;
namespace Umbraco.Core.Persistence.SqlSyntax
{
@@ -18,6 +20,19 @@ namespace Umbraco.Core.Persistence.SqlSyntax
internal abstract class SqlSyntaxProviderBase : ISqlSyntaxProvider
where TSyntax : ISqlSyntaxProvider
{
+ protected SqlSyntaxProviderBase()
+ {
+ ClauseOrder = new List>
+ {
+ FormatString,
+ FormatType,
+ FormatNullable,
+ FormatDefaultValue,
+ FormatPrimaryKey,
+ FormatIdentity
+ };
+ }
+
public string StringLengthNonUnicodeColumnDefinitionFormat = "VARCHAR({0})";
public string StringLengthUnicodeColumnDefinitionFormat = "NVARCHAR({0})";
@@ -39,6 +54,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public string DateTimeColumnDefinition = "DATETIME";
public string TimeColumnDefinition = "DATETIME";
+ protected IList> ClauseOrder { get; set; }
+
protected DbTypes DbTypeMap = new DbTypes();
protected void InitColumnTypeMap()
{
@@ -317,5 +334,96 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return DbTypeMap.ColumnDbTypeMap[valueType];
}
+
+ public virtual string Format(Migrations.Model.ColumnDefinition column)
+ {
+ var clauses = new List();
+
+ foreach (var action in ClauseOrder)
+ {
+ string clause = action(column);
+ if (!string.IsNullOrEmpty(clause))
+ clauses.Add(clause);
+ }
+
+ return string.Join(" ", clauses.ToArray());
+ }
+
+ public virtual string FormatString(Migrations.Model.ColumnDefinition column)
+ {
+ return GetQuotedColumnName(column.Name);
+ }
+
+ protected virtual string FormatType(Migrations.Model.ColumnDefinition column)
+ {
+ if (!column.Type.HasValue)
+ return column.CustomType;
+
+ var dbType = DbTypeMap.ColumnDbTypeMap.First(x => x.Value == column.Type.Value).Key;
+ var definition = DbTypeMap.ColumnDbTypeMap.First(x => x.Key == dbType).Value;
+
+ string dbTypeDefinition = column.Size != default(int)
+ ? string.Format("{0}({1})", definition, column.Size)
+ : definition.ToString();
+ //NOTE Percision is left out
+ return dbTypeDefinition;
+ }
+
+ protected virtual string FormatNullable(Migrations.Model.ColumnDefinition column)
+ {
+ return !column.IsNullable ? "NOT NULL" : string.Empty;
+ }
+
+ protected virtual string FormatDefaultValue(Migrations.Model.ColumnDefinition column)
+ {
+ if (column.DefaultValue == null)
+ return string.Empty;
+
+ // 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 "DEFAULT " + method;
+ }
+
+ return "DEFAULT " + GetQuotedValue(column.DefaultValue.ToString());
+ }
+
+ protected virtual string FormatPrimaryKey(Migrations.Model.ColumnDefinition column)
+ {
+ return string.Empty;
+ }
+
+ protected abstract string FormatSystemMethods(SystemMethods systemMethod);
+
+ protected abstract string FormatIdentity(Migrations.Model.ColumnDefinition column);
+
+ public virtual string CreateTable { get { return "CREATE TABLE {0} ({1})"; } }
+ public virtual string DropTable { get { return "DROP TABLE {0}"; } }
+
+ public virtual string AddColumn { get { return "ALTER TABLE {0} ADD COLUMN {1}"; } }
+ public virtual string DropColumn { get { return "ALTER TABLE {0} DROP COLUMN {1}"; } }
+ public virtual string AlterColumn { get { return "ALTER TABLE {0} ALTER COLUMN {1}"; } }
+ public virtual string RenameColumn { get { return "ALTER TABLE {0} RENAME COLUMN {1} TO {2}"; } }
+
+ public virtual string RenameTable { get { return "RENAME TABLE {0} TO {1}"; } }
+
+ public virtual string CreateSchema { get { return "CREATE SCHEMA {0}"; } }
+ public virtual string AlterSchema { get { return "ALTER SCHEMA {0} TRANSFER {1}.{2}"; } }
+ public virtual string DropSchema { get { return "DROP SCHEMA {0}"; } }
+
+ public virtual string CreateIndex { get { return "CREATE {0}{1}INDEX {2} ON {3} ({4})"; } }
+ public virtual string DropIndex { get { return "DROP INDEX {0}"; } }
+
+ public virtual string InsertData { get { return "INSERT INTO {0} ({1}) VALUES ({2})"; } }
+ public virtual string UpdateData { get { return "UPDATE {0} SET {1} WHERE {2}"; } }
+ public virtual string DeleteData { get { return "DELETE FROM {0} WHERE {1}"; } }
+
+ public virtual string CreateConstraint { get { return "ALTER TABLE {0} ADD CONSTRAINT {1} {2} ({3})"; } }
+ public virtual string DeleteConstraint { get { return "ALTER TABLE {0} DROP CONSTRAINT {1}"; } }
+ public virtual string CreateForeignKeyConstraint { get { return "ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}){5}{6}"; } }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index e5fe961a5a..1e4474c7ba 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -190,8 +190,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -488,7 +533,9 @@
umbraco.interfaces
-
+
+
+