diff --git a/Migrator.net/Migrator.Framework/Column.cs b/Migrator.net/Migrator.Framework/Column.cs
new file mode 100644
index 000000000..8542ecc8b
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Column.cs
@@ -0,0 +1,126 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System.Data;
+
+namespace Migrator.Framework
+{
+ ///
+ /// Represents a table column.
+ ///
+ public class Column : IColumn
+ {
+ private string _name;
+ private DbType _type;
+ private int _size;
+ private ColumnProperty _property;
+ private object _defaultValue;
+
+ public Column(string name)
+ {
+ Name = name;
+ }
+
+ public Column(string name, DbType type)
+ {
+ Name = name;
+ Type = type;
+ }
+
+ public Column(string name, DbType type, int size)
+ {
+ Name = name;
+ Type = type;
+ Size = size;
+ }
+
+ public Column(string name, DbType type, object defaultValue)
+ {
+ Name = name;
+ Type = type;
+ DefaultValue = defaultValue;
+ }
+
+ public Column(string name, DbType type, ColumnProperty property)
+ {
+ Name = name;
+ Type = type;
+ ColumnProperty = property;
+ }
+
+ public Column(string name, DbType type, int size, ColumnProperty property)
+ {
+ Name = name;
+ Type = type;
+ Size = size;
+ ColumnProperty = property;
+ }
+
+ public Column(string name, DbType type, int size, ColumnProperty property, object defaultValue)
+ {
+ Name = name;
+ Type = type;
+ Size = size;
+ ColumnProperty = property;
+ DefaultValue = defaultValue;
+ }
+
+ public Column(string name, DbType type, ColumnProperty property, object defaultValue)
+ {
+ Name = name;
+ Type = type;
+ ColumnProperty = property;
+ DefaultValue = defaultValue;
+ }
+
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+
+ public DbType Type
+ {
+ get { return _type; }
+ set { _type = value; }
+ }
+
+ public int Size
+ {
+ get { return _size; }
+ set { _size = value; }
+ }
+
+ public ColumnProperty ColumnProperty
+ {
+ get { return _property; }
+ set { _property = value; }
+ }
+
+ public object DefaultValue
+ {
+ get { return _defaultValue; }
+ set { _defaultValue = value; }
+ }
+
+ public bool IsIdentity
+ {
+ get { return (ColumnProperty & ColumnProperty.Identity) == ColumnProperty.Identity; }
+ }
+
+ public bool IsPrimaryKey
+ {
+ get { return (ColumnProperty & ColumnProperty.PrimaryKey) == ColumnProperty.PrimaryKey; }
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/ColumnProperty.cs b/Migrator.net/Migrator.Framework/ColumnProperty.cs
new file mode 100644
index 000000000..434f89f13
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/ColumnProperty.cs
@@ -0,0 +1,50 @@
+using System;
+
+namespace Migrator.Framework
+{
+
+ ///
+ /// Represents a table column properties.
+ ///
+ [Flags]
+ public enum ColumnProperty
+ {
+ None = 0,
+ ///
+ /// Null is allowable
+ ///
+ Null = 1,
+ ///
+ /// Null is not allowable
+ ///
+ NotNull = 2,
+ ///
+ /// Identity column, autoinc
+ ///
+ Identity = 4,
+ ///
+ /// Unique Column
+ ///
+ Unique = 8,
+ ///
+ /// Indexed Column
+ ///
+ Indexed = 16,
+ ///
+ /// Unsigned Column
+ ///
+ Unsigned = 32,
+ ///
+ /// Foreign Key
+ ///
+ ForeignKey = Unsigned | Null,
+ ///
+ /// Primary Key
+ ///
+ PrimaryKey = 64 | Unsigned | NotNull,
+ ///
+ /// Primary key. Make the column a PrimaryKey and unsigned
+ ///
+ PrimaryKeyWithIdentity = PrimaryKey | Identity
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/ForeignKeyConstraint.cs b/Migrator.net/Migrator.Framework/ForeignKeyConstraint.cs
new file mode 100644
index 000000000..26d29fbcd
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/ForeignKeyConstraint.cs
@@ -0,0 +1,11 @@
+namespace Migrator.Framework
+{
+ public enum ForeignKeyConstraint
+ {
+ Cascade,
+ SetNull,
+ NoAction,
+ Restrict,
+ SetDefault
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/IColumn.cs b/Migrator.net/Migrator.Framework/IColumn.cs
new file mode 100644
index 000000000..aa2a4d183
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/IColumn.cs
@@ -0,0 +1,34 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System.Data;
+
+namespace Migrator.Framework
+{
+ public interface IColumn
+ {
+ ColumnProperty ColumnProperty { get; set; }
+
+ string Name { get; set; }
+
+ DbType Type { get; set; }
+
+ int Size { get; set; }
+
+ bool IsIdentity { get; }
+
+ bool IsPrimaryKey { get; }
+
+ object DefaultValue { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/ILogger.cs b/Migrator.net/Migrator.Framework/ILogger.cs
new file mode 100644
index 000000000..d6b0cee0e
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/ILogger.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+
+namespace Migrator.Framework
+{
+ public interface ILogger
+ {
+ ///
+ /// Log that we have started a migration
+ ///
+ /// Start list of versions
+ /// Final Version
+ void Started(List currentVersion, long finalVersion);
+
+ ///
+ /// Log that we are migrating up
+ ///
+ /// Version we are migrating to
+ /// Migration name
+ void MigrateUp(long version, string migrationName);
+
+ ///
+ /// Log that we are migrating down
+ ///
+ /// Version we are migrating to
+ /// Migration name
+ void MigrateDown(long version, string migrationName);
+
+ ///
+ /// Inform that a migration corresponding to the number of
+ /// version is untraceable (not found?) and will be ignored.
+ ///
+ /// Version we couldnt find
+ void Skipping(long version);
+
+ ///
+ /// Log that we are rolling back to version
+ ///
+ ///
+ /// version
+ ///
+ void RollingBack(long originalVersion);
+
+ ///
+ /// Log a Sql statement that changes the schema or content of the database as part of a migration
+ ///
+ ///
+ /// SELECT statements should not be logged using this method as they do not alter the data or schema of the
+ /// database.
+ ///
+ /// The Sql statement to log
+ void ApplyingDBChange(string sql);
+
+ ///
+ /// Log that we had an exception on a migration
+ ///
+ /// The version of the migration that caused the exception.
+ /// The name of the migration that caused the exception.
+ /// The exception itself
+ void Exception(long version, string migrationName, Exception ex);
+
+ ///
+ /// Log that we had an exception on a migration
+ ///
+ /// An informative message to show to the user.
+ /// The exception itself
+ void Exception(string message, Exception ex);
+
+ ///
+ /// Log that we have finished a migration
+ ///
+ /// List of versions with which we started
+ /// Final Version
+ void Finished(List currentVersion, long finalVersion);
+
+ ///
+ /// Log a message
+ ///
+ /// The format string ("{0}, blabla {1}").
+ /// Parameters to apply to the format string.
+ void Log(string format, params object[] args);
+
+ ///
+ /// Log a Warning
+ ///
+ /// The format string ("{0}, blabla {1}").
+ /// Parameters to apply to the format string.
+ void Warn(string format, params object[] args);
+
+ ///
+ /// Log a Trace Message
+ ///
+ /// The format string ("{0}, blabla {1}").
+ /// Parameters to apply to the format string.
+ void Trace(string format, params object[] args);
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/IMigration.cs b/Migrator.net/Migrator.Framework/IMigration.cs
new file mode 100644
index 000000000..eb7a77509
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/IMigration.cs
@@ -0,0 +1,39 @@
+namespace Migrator.Framework
+{
+ public interface IMigration
+ {
+ string Name { get; }
+
+ ///
+ /// Represents the database.
+ /// .
+ ///
+ /// Migration.Framework.ITransformationProvider
+ ITransformationProvider Database { get; set; }
+
+ ///
+ /// Defines tranformations to port the database to the current version.
+ ///
+ void Up();
+
+ ///
+ /// This is run after the Up transaction has been committed
+ ///
+ void AfterUp();
+
+ ///
+ /// Defines transformations to revert things done in Up.
+ ///
+ void Down();
+
+ ///
+ /// This is run after the Down transaction has been committed
+ ///
+ void AfterDown();
+
+ ///
+ /// This gets called once on the first migration object.
+ ///
+ void InitializeOnce(string[] args);
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/ITransformationProvider.cs b/Migrator.net/Migrator.Framework/ITransformationProvider.cs
new file mode 100644
index 000000000..46d77199f
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/ITransformationProvider.cs
@@ -0,0 +1,469 @@
+using System;
+using System.Data;
+using System.Collections.Generic;
+
+namespace Migrator.Framework
+{
+ ///
+ /// The main interface to use in Migrations to make changes on a database schema.
+ ///
+ public interface ITransformationProvider : IDisposable
+ {
+
+ ///
+ /// Get this provider or a NoOp provider if you are not running in the context of 'provider'.
+ ///
+ ITransformationProvider this[string provider] { get;}
+
+ ///
+ /// The list of Migrations currently applied to the database.
+ ///
+ List AppliedMigrations { get; }
+
+ ILogger Logger { get; set; }
+
+ ///
+ /// Add a column to an existing table
+ ///
+ /// The name of the table that will get the new column
+ /// The name of the new column
+ /// The data type for the new columnd
+ /// The precision or size of the column
+ /// Properties that can be ORed together
+ /// The default value of the column if no value is given in a query
+ void AddColumn(string table, string column, DbType type, int size, ColumnProperty property, object defaultValue);
+
+ ///
+ /// Add a column to an existing table
+ ///
+ /// The name of the table that will get the new column
+ /// The name of the new column
+ /// The data type for the new columnd
+ void AddColumn(string table, string column, DbType type);
+
+ ///
+ /// Add a column to an existing table
+ ///
+ /// The name of the table that will get the new column
+ /// The name of the new column
+ /// The data type for the new columnd
+ /// The precision or size of the column
+ void AddColumn(string table, string column, DbType type, int size);
+
+ ///
+ /// Add a column to an existing table
+ ///
+ /// The name of the table that will get the new column
+ /// The name of the new column
+ /// The data type for the new columnd
+ /// The precision or size of the column
+ /// Properties that can be ORed together
+ void AddColumn(string table, string column, DbType type, int size, ColumnProperty property);
+
+ ///
+ /// Add a column to an existing table
+ ///
+ /// The name of the table that will get the new column
+ /// The name of the new column
+ /// The data type for the new columnd
+ /// Properties that can be ORed together
+ void AddColumn(string table, string column, DbType type, ColumnProperty property);
+
+ ///
+ /// Add a column to an existing table with the default column size.
+ ///
+ /// The name of the table that will get the new column
+ /// The name of the new column
+ /// The data type for the new columnd
+ /// The default value of the column if no value is given in a query
+ void AddColumn(string table, string column, DbType type, object defaultValue);
+
+ ///
+ /// Add a column to an existing table
+ ///
+ /// The name of the table that will get the new column
+ /// An instance of a Column with the specified properties
+ void AddColumn(string table, Column column);
+
+ ///
+ /// Add a foreign key constraint
+ ///
+ /// The name of the foreign key. e.g. FK_TABLE_REF
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The columns that are the foreign keys (eg. FK_id)
+ /// The table that holds the primary keys (eg. Table.PK_id)
+ /// The columns that are the primary keys (eg. PK_id)
+ void AddForeignKey(string name, string foreignTable, string[] foreignColumns, string primaryTable, string[] primaryColumns);
+
+ ///
+ /// Add a foreign key constraint
+ ///
+ /// The name of the foreign key. e.g. FK_TABLE_REF
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The columns that are the foreign keys (eg. FK_id)
+ /// The table that holds the primary keys (eg. Table.PK_id)
+ /// The columns that are the primary keys (eg. PK_id)
+ /// Constraint parameters
+ void AddForeignKey(string name, string foreignTable, string[] foreignColumns, string primaryTable, string[] primaryColumns, ForeignKeyConstraint constraint);
+
+ ///
+ /// Add a foreign key constraint
+ ///
+ ///
+ /// The name of the foreign key. e.g. FK_TABLE_REF
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The column that is the foreign key (eg. FK_id)
+ /// The table that holds the primary keys (eg. Table.PK_id)
+ /// The column that is the primary key (eg. PK_id)
+ void AddForeignKey(string name, string foreignTable, string foreignColumn, string primaryTable, string primaryColumn);
+
+ ///
+ /// Add a foreign key constraint
+ ///
+ /// The name of the foreign key. e.g. FK_TABLE_REF
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The column that is the foreign key (eg. FK_id)
+ /// The table that holds the primary key (eg. Table.PK_id)
+ /// The column that is the primary key (eg. PK_id)
+ /// Constraint parameters
+ void AddForeignKey(string name, string foreignTable, string foreignColumn, string primaryTable, string primaryColumn, ForeignKeyConstraint constraint);
+
+ ///
+ /// Add a foreign key constraint when you don't care about the name of the constraint.
+ /// Warning: This will prevent you from dropping the constraint since you won't know the name.
+ ///
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The column that is the foreign key (eg. FK_id)
+ /// The table that holds the primary key (eg. Table.PK_id)
+ /// The column that is the primary key (eg. PK_id)
+ void GenerateForeignKey(string foreignTable, string foreignColumn, string primaryTable, string primaryColumn);
+
+ ///
+ /// Add a foreign key constraint when you don't care about the name of the constraint.
+ /// Warning: This will prevent you from dropping the constraint since you won't know the name.
+ ///
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The columns that are the foreign keys (eg. FK_id)
+ /// The table that holds the primary key (eg. Table.PK_id)
+ /// The column that is the primary key (eg. PK_id)
+ void GenerateForeignKey(string foreignTable, string[] foreignColumns, string primaryTable, string[] primaryColumns);
+
+ ///
+ /// Add a foreign key constraint when you don't care about the name of the constraint.
+ /// Warning: This will prevent you from dropping the constraint since you won't know the name.
+ ///
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The columns that are the foreign keys (eg. FK_id)
+ /// The table that holds the primary key (eg. Table.PK_id)
+ /// The columns that are the primary keys (eg. PK_id)
+ /// Constraint parameters
+ void GenerateForeignKey(string foreignTable, string[] foreignColumns, string primaryTable, string[] primaryColumns, ForeignKeyConstraint constraint);
+
+ ///
+ /// Add a foreign key constraint when you don't care about the name of the constraint.
+ /// Warning: This will prevent you from dropping the constraint since you won't know the name.
+ ///
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The columns that are the foreign keys (eg. FK_id)
+ /// The table that holds the primary key (eg. Table.PK_id)
+ /// The column that is the primary key (eg. PK_id)
+ /// Constraint parameters
+ void GenerateForeignKey(string foreignTable, string foreignColumn, string primaryTable, string primaryColumn,
+ ForeignKeyConstraint constraint);
+
+ ///
+ /// Add a foreign key constraint when you don't care about the name of the constraint.
+ /// Warning: This will prevent you from dropping the constraint since you won't know the name.
+ ///
+ /// The current expectations are that there is a column named the same as the foreignTable present in
+ /// the table. This is subject to change because I think it's not a good convention.
+ ///
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The table that holds the primary key (eg. Table.PK_id)
+ void GenerateForeignKey(string foreignTable, string primaryTable);
+
+ ///
+ /// Add a foreign key constraint when you don't care about the name of the constraint.
+ /// Warning: This will prevent you from dropping the constraint since you won't know the name.
+ ///
+ /// The current expectations are that there is a column named the same as the foreignTable present in
+ /// the table. This is subject to change because I think it's not a good convention.
+ ///
+ /// The table that the foreign key will be created in (eg. Table.FK_id)
+ /// The table that holds the primary key (eg. Table.PK_id)
+ ///
+ void GenerateForeignKey(string foreignTable, string primaryTable, ForeignKeyConstraint constraint);
+
+ ///
+ /// Add a primary key to a table
+ ///
+ /// The name of the primary key to add.
+ /// The name of the table that will get the primary key.
+ /// The name of the column or columns that are in the primary key.
+ void AddPrimaryKey(string name, string table, params string[] columns);
+
+ ///
+ /// Add a constraint to a table
+ ///
+ /// The name of the constraint to add.
+ /// The name of the table that will get the constraint
+ /// The name of the column or columns that will get the constraint.
+ void AddUniqueConstraint(string name, string table, params string[] columns);
+
+ ///
+ /// Add a constraint to a table
+ ///
+ /// The name of the constraint to add.
+ /// The name of the table that will get the constraint
+ /// The check constraint definition.
+ void AddCheckConstraint(string name, string table, string checkSql);
+
+ ///
+ /// Add a table
+ ///
+ /// The name of the table to add.
+ /// The columns that are part of the table.
+ void AddTable(string name, params Column[] columns);
+
+ ///
+ /// Add a table
+ ///
+ /// The name of the table to add.
+ /// The name of the database engine to use. (MySQL)
+ /// The columns that are part of the table.
+ void AddTable(string name, string engine, params Column[] columns);
+
+ ///
+ /// Start a transction
+ ///
+ void BeginTransaction();
+
+ ///
+ /// Change the definition of an existing column.
+ ///
+ /// The name of the table that will get the new column
+ /// An instance of a Column with the specified properties and the name of an existing column
+ void ChangeColumn(string table, Column column);
+
+ ///
+ /// Check to see if a column exists
+ ///
+ ///
+ ///
+ ///
+ bool ColumnExists(string table, string column);
+
+ ///
+ /// Commit the running transction
+ ///
+ void Commit();
+
+ ///
+ /// Check to see if a constraint exists
+ ///
+ /// The name of the constraint
+ /// The table that the constraint lives on.
+ ///
+ bool ConstraintExists(string table, string name);
+
+ ///
+ /// Check to see if a primary key constraint exists on the table
+ ///
+ /// The name of the primary key
+ /// The table that the constraint lives on.
+ ///
+ bool PrimaryKeyExists(string table, string name);
+
+ ///
+ /// Execute an arbitrary SQL query
+ ///
+ /// The SQL to execute.
+ ///
+ int ExecuteNonQuery(string sql);
+
+ ///
+ /// Execute an arbitrary SQL query
+ ///
+ /// The SQL to execute.
+ ///
+ IDataReader ExecuteQuery(string sql);
+
+ ///
+ /// Execute an arbitrary SQL query
+ ///
+ /// The SQL to execute.
+ /// A single value that is returned.
+ object ExecuteScalar(string sql);
+
+ ///
+ /// Get the information about the columns in a table
+ ///
+ /// The table name that you want the columns for.
+ ///
+ Column[] GetColumns(string table);
+
+ ///
+ /// Get information about a single column in a table
+ ///
+ /// The table name that you want the columns for.
+ /// The column name for which you want information.
+ ///
+ Column GetColumnByName(string table, string column);
+
+ ///
+ /// Get the names of all of the tables
+ ///
+ /// The names of all the tables.
+ string[] GetTables();
+
+ ///
+ /// Insert data into a table
+ ///
+ /// The table that will get the new data
+ /// The names of the columns
+ /// The values in the same order as the columns
+ ///
+ int Insert(string table, string[] columns, string[] values);
+
+ ///
+ /// Delete data from a table
+ ///
+ /// The table that will have the data deleted
+ /// The names of the columns used in a where clause
+ /// The values in the same order as the columns
+ ///
+ int Delete(string table, string[] columns, string[] values);
+
+ ///
+ /// Delete data from a table
+ ///
+ /// The table that will have the data deleted
+ /// The name of the column used in a where clause
+ /// The value for the where clause
+ ///
+ int Delete(string table, string whereColumn, string whereValue);
+
+ ///
+ /// Marks a Migration version number as having been applied
+ ///
+ /// The version number of the migration that was applied
+ void MigrationApplied(long version);
+
+ ///
+ /// Marks a Migration version number as having been rolled back from the database
+ ///
+ /// The version number of the migration that was removed
+ void MigrationUnApplied(long version);
+
+ ///
+ /// Remove an existing column from a table
+ ///
+ /// The name of the table to remove the column from
+ /// The column to remove
+ void RemoveColumn(string table, string column);
+
+ ///
+ /// Remove an existing foreign key constraint
+ ///
+ /// The table that contains the foreign key.
+ /// The name of the foreign key to remove
+ void RemoveForeignKey(string table, string name);
+
+ ///
+ /// Remove an existing constraint
+ ///
+ /// The table that contains the foreign key.
+ /// The name of the constraint to remove
+ void RemoveConstraint(string table, string name);
+
+ ///
+ /// Remove an existing table
+ ///
+ /// The name of the table
+ void RemoveTable(string tableName);
+
+ ///
+ /// Rename an existing table
+ ///
+ /// The old name of the table
+ /// The new name of the table
+ void RenameTable(string oldName, string newName);
+
+ ///
+ /// Rename an existing table
+ ///
+ /// The name of the table
+ /// The old name of the column
+ /// The new name of the column
+ void RenameColumn(string tableName, string oldColumnName, string newColumnName);
+
+ ///
+ /// Rollback the currently running transaction.
+ ///
+ void Rollback();
+
+ ///
+ /// Get values from a table
+ ///
+ /// The columns to select
+ /// The table to select from
+ /// The where clause to limit the selection
+ ///
+ IDataReader Select(string what, string from, string where);
+
+ ///
+ /// Get values from a table
+ ///
+ /// The columns to select
+ /// The table to select from
+ ///
+ IDataReader Select(string what, string from);
+
+ ///
+ /// Get a single value from a table
+ ///
+ /// The columns to select
+ /// The table to select from
+ ///
+ ///
+ object SelectScalar(string what, string from, string where);
+
+ ///
+ /// Get a single value from a table
+ ///
+ /// The columns to select
+ /// The table to select from
+ ///
+ object SelectScalar(string what, string from);
+
+ ///
+ /// Check if a table already exists
+ ///
+ /// The name of the table that you want to check on.
+ ///
+ bool TableExists(string tableName);
+
+ ///
+ /// Update the values in a table
+ ///
+ /// The name of the table to update
+ /// The names of the columns.
+ /// The values for the columns in the same order as the names.
+ ///
+ int Update(string table, string[] columns, string[] columnValues);
+
+ ///
+ /// Update the values in a table
+ ///
+ /// The name of the table to update
+ /// The names of the columns.
+ /// The values for the columns in the same order as the names.
+ /// A where clause to limit the update
+ ///
+ int Update(string table, string[] columns, string[] values, string where);
+
+ IDbCommand GetCommand();
+
+ void ExecuteSchemaBuilder(SchemaBuilder.SchemaBuilder schemaBuilder);
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/.svn/all-wcprops b/Migrator.net/Migrator.Framework/Loggers/.svn/all-wcprops
new file mode 100644
index 000000000..1d7a4067b
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/.svn/all-wcprops
@@ -0,0 +1,35 @@
+K 25
+svn:wc:ra_dav:version-url
+V 54
+/svn/!svn/ver/120/trunk/src/Migrator.Framework/Loggers
+END
+Logger.cs
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/!svn/ver/120/trunk/src/Migrator.Framework/Loggers/Logger.cs
+END
+ConsoleWriter.cs
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/svn/!svn/ver/73/trunk/src/Migrator.Framework/Loggers/ConsoleWriter.cs
+END
+IAttachableLogger.cs
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/svn/!svn/ver/120/trunk/src/Migrator.Framework/Loggers/IAttachableLogger.cs
+END
+SqlScriptFileLogger.cs
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/svn/!svn/ver/120/trunk/src/Migrator.Framework/Loggers/SqlScriptFileLogger.cs
+END
+ILogWriter.cs
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/!svn/ver/120/trunk/src/Migrator.Framework/Loggers/ILogWriter.cs
+END
diff --git a/Migrator.net/Migrator.Framework/Loggers/.svn/entries b/Migrator.net/Migrator.Framework/Loggers/.svn/entries
new file mode 100644
index 000000000..ebffeac65
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/.svn/entries
@@ -0,0 +1,198 @@
+10
+
+dir
+147
+http://migratordotnet.googlecode.com/svn/trunk/src/Migrator.Framework/Loggers
+http://migratordotnet.googlecode.com/svn
+
+
+
+2008-09-11T21:48:32.631850Z
+120
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8c3eb3c4-eb3a-0410-862c-73fa8ce6028b
+
+Logger.cs
+file
+
+
+
+
+2011-05-23T18:17:16.585003Z
+24718815685110ea98d3f4207a358907
+2008-09-11T21:48:32.631850Z
+120
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4456
+
+ConsoleWriter.cs
+file
+
+
+
+
+2011-05-23T18:17:16.587003Z
+32bbf60aa8f07bbc281ac3be2da2a214
+2008-04-24T03:58:41.677562Z
+43
+dkode8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+838
+
+IAttachableLogger.cs
+file
+
+
+
+
+2011-05-23T18:17:16.587003Z
+e0226db3d0d21f0b59d7593f76835e9f
+2008-09-11T21:48:32.631850Z
+120
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1114
+
+SqlScriptFileLogger.cs
+file
+
+
+
+
+2011-05-23T18:17:16.589003Z
+bb2a95971af988525878e60b8cdb21a7
+2008-09-11T21:48:32.631850Z
+120
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2527
+
+ILogWriter.cs
+file
+
+
+
+
+2011-05-23T18:17:16.590003Z
+53fd3ec26d0d191e9d4ae77530e5d928
+2008-09-11T21:48:32.631850Z
+120
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1088
+
diff --git a/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/ConsoleWriter.cs.svn-base b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/ConsoleWriter.cs.svn-base
new file mode 100644
index 000000000..8c93ec371
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/ConsoleWriter.cs.svn-base
@@ -0,0 +1,28 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System;
+
+namespace Migrator.Framework.Loggers
+{
+ public class ConsoleWriter : ILogWriter
+ {
+ public void Write(string message, params object[] args)
+ {
+ Console.Write(message, args);
+ }
+
+ public void WriteLine(string message, params object[] args)
+ {
+ Console.WriteLine(message, args);
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/IAttachableLogger.cs.svn-base b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/IAttachableLogger.cs.svn-base
new file mode 100644
index 000000000..24b09a352
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/IAttachableLogger.cs.svn-base
@@ -0,0 +1,33 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+namespace Migrator.Framework.Loggers
+{
+ ///
+ /// ILogger interface.
+ /// Implicit in this interface is that the logger will delegate actual
+ /// logging to the (s) that have been attached
+ ///
+ public interface IAttachableLogger: ILogger
+ {
+ ///
+ /// Attach an
+ ///
+ ///
+ void Attach(ILogWriter writer);
+
+ ///
+ /// Detach an
+ ///
+ ///
+ void Detach(ILogWriter writer);
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/ILogWriter.cs.svn-base b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/ILogWriter.cs.svn-base
new file mode 100644
index 000000000..298f53dce
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/ILogWriter.cs.svn-base
@@ -0,0 +1,33 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+namespace Migrator.Framework.Loggers
+{
+ ///
+ /// Handles writing a message to the log medium (i.e. file, console)
+ ///
+ public interface ILogWriter
+ {
+ ///
+ /// Write this message
+ ///
+ ///
+ ///
+ void Write(string message, params object[] args);
+
+ ///
+ /// Write this message, as a line
+ ///
+ ///
+ ///
+ void WriteLine(string message, params object[] args);
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/Logger.cs.svn-base b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/Logger.cs.svn-base
new file mode 100644
index 000000000..4f27b1a7d
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/Logger.cs.svn-base
@@ -0,0 +1,169 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Migrator.Framework.Loggers
+{
+ ///
+ /// Text logger for the migration mediator
+ ///
+ public class Logger : IAttachableLogger
+ {
+ private readonly bool _trace;
+ private readonly List _writers = new List();
+
+ public Logger(bool trace)
+ {
+ _trace = trace;
+ }
+
+ public Logger(bool trace, params ILogWriter[] writers)
+ : this(trace)
+ {
+ _writers.AddRange(writers);
+ }
+
+ public void Attach(ILogWriter writer)
+ {
+ _writers.Add(writer);
+ }
+
+ public void Detach(ILogWriter writer)
+ {
+ _writers.Remove(writer);
+ }
+
+ public void Started(long currentVersion, long finalVersion)
+ {
+ WriteLine("Current version : {0}. Target version : {1}", currentVersion, finalVersion);
+ }
+
+ public void Started(List currentVersions, long finalVersion)
+ {
+ WriteLine("Latest version applied : {0}. Target version : {1}", LatestVersion(currentVersions), finalVersion);
+ }
+
+ public void MigrateUp(long version, string migrationName)
+ {
+ WriteLine("Applying {0}: {1}", version.ToString(), migrationName);
+ }
+
+ public void MigrateDown(long version, string migrationName)
+ {
+ WriteLine("Removing {0}: {1}", version.ToString(), migrationName);
+ }
+
+ public void Skipping(long version)
+ {
+ WriteLine("{0} {1}", version.ToString(), "");
+ }
+
+ public void RollingBack(long originalVersion)
+ {
+ WriteLine("Rolling back to migration {0}", originalVersion);
+ }
+
+ public void ApplyingDBChange(string sql)
+ {
+ Log(sql);
+ }
+
+ public void Exception(long version, string migrationName, Exception ex)
+ {
+ WriteLine("============ Error Detail ============");
+ WriteLine("Error in migration: {0}", version);
+ LogExceptionDetails(ex);
+ WriteLine("======================================");
+ }
+
+ public void Exception(string message, Exception ex)
+ {
+ WriteLine("============ Error Detail ============");
+ WriteLine("Error: {0}", message);
+ LogExceptionDetails(ex);
+ WriteLine("======================================");
+ }
+
+ private void LogExceptionDetails(Exception ex)
+ {
+ WriteLine("{0}", ex.Message);
+ WriteLine("{0}", ex.StackTrace);
+ Exception iex = ex.InnerException;
+ while (iex != null)
+ {
+ WriteLine("Caused by: {0}", iex);
+ WriteLine("{0}", ex.StackTrace);
+ iex = iex.InnerException;
+ }
+ }
+
+ public void Finished(long originalVersion, long currentVersion)
+ {
+ WriteLine("Migrated to version {0}", currentVersion);
+ }
+
+ public void Finished(List originalVersions, long currentVersion)
+ {
+ WriteLine("Migrated to version {0}", currentVersion);
+ }
+
+ public void Log(string format, params object[] args)
+ {
+ WriteLine(format, args);
+ }
+
+ public void Warn(string format, params object[] args)
+ {
+ Write("Warning! : ");
+ WriteLine(format, args);
+ }
+
+ public void Trace(string format, params object[] args)
+ {
+ if (_trace)
+ {
+ Log(format, args);
+ }
+ }
+
+ private void Write(string message, params object[] args)
+ {
+ foreach (ILogWriter writer in _writers)
+ {
+ writer.Write(message, args);
+ }
+ }
+
+ private void WriteLine(string message, params object[] args)
+ {
+ foreach (ILogWriter writer in _writers)
+ {
+ writer.WriteLine(message, args);
+ }
+ }
+
+ public static ILogger ConsoleLogger()
+ {
+ return new Logger(false, new ConsoleWriter());
+ }
+
+ private string LatestVersion(List versions)
+ {
+ if (versions.Count > 0)
+ {
+ return versions[versions.Count - 1].ToString();
+ }
+ return "No migrations applied yet!";
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/SqlScriptFileLogger.cs.svn-base b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/SqlScriptFileLogger.cs.svn-base
new file mode 100644
index 000000000..de70868f4
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/.svn/text-base/SqlScriptFileLogger.cs.svn-base
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Migrator.Framework.Loggers
+{
+ public class SqlScriptFileLogger : ILogger, IDisposable
+ {
+ private readonly ILogger _innerLogger;
+ private TextWriter _streamWriter;
+
+ public SqlScriptFileLogger(ILogger logger, TextWriter streamWriter)
+ {
+ _innerLogger = logger;
+ _streamWriter = streamWriter;
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ if (_streamWriter != null)
+ {
+ _streamWriter.Dispose();
+ _streamWriter = null;
+ }
+ }
+
+ #endregion
+
+ public void Log(string format, params object[] args)
+ {
+ _innerLogger.Log(format, args);
+ }
+
+ public void Warn(string format, params object[] args)
+ {
+ _innerLogger.Warn(format, args);
+ }
+
+ public void Trace(string format, params object[] args)
+ {
+ _innerLogger.Trace(format, args);
+ }
+
+ public void ApplyingDBChange(string sql)
+ {
+ _innerLogger.ApplyingDBChange(sql);
+ _streamWriter.WriteLine(sql);
+ }
+
+ public void Started(List appliedVersions, long finalVersion)
+ {
+ _innerLogger.Started(appliedVersions, finalVersion);
+ }
+
+ public void MigrateUp(long version, string migrationName)
+ {
+ _innerLogger.MigrateUp(version, migrationName);
+ }
+
+ public void MigrateDown(long version, string migrationName)
+ {
+ _innerLogger.MigrateDown(version, migrationName);
+ }
+
+ public void Skipping(long version)
+ {
+ _innerLogger.Skipping(version);
+ }
+
+ public void RollingBack(long originalVersion)
+ {
+ _innerLogger.RollingBack(originalVersion);
+ }
+
+ public void Exception(long version, string migrationName, Exception ex)
+ {
+ _innerLogger.Exception(version, migrationName, ex);
+ }
+
+ public void Exception(string message, Exception ex)
+ {
+ _innerLogger.Exception(message, ex);
+ }
+
+ public void Finished(List appliedVersions, long currentVersion)
+ {
+ _innerLogger.Finished(appliedVersions, currentVersion);
+ _streamWriter.Close();
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/ConsoleWriter.cs b/Migrator.net/Migrator.Framework/Loggers/ConsoleWriter.cs
new file mode 100644
index 000000000..8c93ec371
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/ConsoleWriter.cs
@@ -0,0 +1,28 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System;
+
+namespace Migrator.Framework.Loggers
+{
+ public class ConsoleWriter : ILogWriter
+ {
+ public void Write(string message, params object[] args)
+ {
+ Console.Write(message, args);
+ }
+
+ public void WriteLine(string message, params object[] args)
+ {
+ Console.WriteLine(message, args);
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/IAttachableLogger.cs b/Migrator.net/Migrator.Framework/Loggers/IAttachableLogger.cs
new file mode 100644
index 000000000..24b09a352
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/IAttachableLogger.cs
@@ -0,0 +1,33 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+namespace Migrator.Framework.Loggers
+{
+ ///
+ /// ILogger interface.
+ /// Implicit in this interface is that the logger will delegate actual
+ /// logging to the (s) that have been attached
+ ///
+ public interface IAttachableLogger: ILogger
+ {
+ ///
+ /// Attach an
+ ///
+ ///
+ void Attach(ILogWriter writer);
+
+ ///
+ /// Detach an
+ ///
+ ///
+ void Detach(ILogWriter writer);
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/ILogWriter.cs b/Migrator.net/Migrator.Framework/Loggers/ILogWriter.cs
new file mode 100644
index 000000000..298f53dce
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/ILogWriter.cs
@@ -0,0 +1,33 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+namespace Migrator.Framework.Loggers
+{
+ ///
+ /// Handles writing a message to the log medium (i.e. file, console)
+ ///
+ public interface ILogWriter
+ {
+ ///
+ /// Write this message
+ ///
+ ///
+ ///
+ void Write(string message, params object[] args);
+
+ ///
+ /// Write this message, as a line
+ ///
+ ///
+ ///
+ void WriteLine(string message, params object[] args);
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/Logger.cs b/Migrator.net/Migrator.Framework/Loggers/Logger.cs
new file mode 100644
index 000000000..4f27b1a7d
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/Logger.cs
@@ -0,0 +1,169 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Migrator.Framework.Loggers
+{
+ ///
+ /// Text logger for the migration mediator
+ ///
+ public class Logger : IAttachableLogger
+ {
+ private readonly bool _trace;
+ private readonly List _writers = new List();
+
+ public Logger(bool trace)
+ {
+ _trace = trace;
+ }
+
+ public Logger(bool trace, params ILogWriter[] writers)
+ : this(trace)
+ {
+ _writers.AddRange(writers);
+ }
+
+ public void Attach(ILogWriter writer)
+ {
+ _writers.Add(writer);
+ }
+
+ public void Detach(ILogWriter writer)
+ {
+ _writers.Remove(writer);
+ }
+
+ public void Started(long currentVersion, long finalVersion)
+ {
+ WriteLine("Current version : {0}. Target version : {1}", currentVersion, finalVersion);
+ }
+
+ public void Started(List currentVersions, long finalVersion)
+ {
+ WriteLine("Latest version applied : {0}. Target version : {1}", LatestVersion(currentVersions), finalVersion);
+ }
+
+ public void MigrateUp(long version, string migrationName)
+ {
+ WriteLine("Applying {0}: {1}", version.ToString(), migrationName);
+ }
+
+ public void MigrateDown(long version, string migrationName)
+ {
+ WriteLine("Removing {0}: {1}", version.ToString(), migrationName);
+ }
+
+ public void Skipping(long version)
+ {
+ WriteLine("{0} {1}", version.ToString(), "");
+ }
+
+ public void RollingBack(long originalVersion)
+ {
+ WriteLine("Rolling back to migration {0}", originalVersion);
+ }
+
+ public void ApplyingDBChange(string sql)
+ {
+ Log(sql);
+ }
+
+ public void Exception(long version, string migrationName, Exception ex)
+ {
+ WriteLine("============ Error Detail ============");
+ WriteLine("Error in migration: {0}", version);
+ LogExceptionDetails(ex);
+ WriteLine("======================================");
+ }
+
+ public void Exception(string message, Exception ex)
+ {
+ WriteLine("============ Error Detail ============");
+ WriteLine("Error: {0}", message);
+ LogExceptionDetails(ex);
+ WriteLine("======================================");
+ }
+
+ private void LogExceptionDetails(Exception ex)
+ {
+ WriteLine("{0}", ex.Message);
+ WriteLine("{0}", ex.StackTrace);
+ Exception iex = ex.InnerException;
+ while (iex != null)
+ {
+ WriteLine("Caused by: {0}", iex);
+ WriteLine("{0}", ex.StackTrace);
+ iex = iex.InnerException;
+ }
+ }
+
+ public void Finished(long originalVersion, long currentVersion)
+ {
+ WriteLine("Migrated to version {0}", currentVersion);
+ }
+
+ public void Finished(List originalVersions, long currentVersion)
+ {
+ WriteLine("Migrated to version {0}", currentVersion);
+ }
+
+ public void Log(string format, params object[] args)
+ {
+ WriteLine(format, args);
+ }
+
+ public void Warn(string format, params object[] args)
+ {
+ Write("Warning! : ");
+ WriteLine(format, args);
+ }
+
+ public void Trace(string format, params object[] args)
+ {
+ if (_trace)
+ {
+ Log(format, args);
+ }
+ }
+
+ private void Write(string message, params object[] args)
+ {
+ foreach (ILogWriter writer in _writers)
+ {
+ writer.Write(message, args);
+ }
+ }
+
+ private void WriteLine(string message, params object[] args)
+ {
+ foreach (ILogWriter writer in _writers)
+ {
+ writer.WriteLine(message, args);
+ }
+ }
+
+ public static ILogger ConsoleLogger()
+ {
+ return new Logger(false, new ConsoleWriter());
+ }
+
+ private string LatestVersion(List versions)
+ {
+ if (versions.Count > 0)
+ {
+ return versions[versions.Count - 1].ToString();
+ }
+ return "No migrations applied yet!";
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Loggers/SqlScriptFileLogger.cs b/Migrator.net/Migrator.Framework/Loggers/SqlScriptFileLogger.cs
new file mode 100644
index 000000000..de70868f4
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Loggers/SqlScriptFileLogger.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Migrator.Framework.Loggers
+{
+ public class SqlScriptFileLogger : ILogger, IDisposable
+ {
+ private readonly ILogger _innerLogger;
+ private TextWriter _streamWriter;
+
+ public SqlScriptFileLogger(ILogger logger, TextWriter streamWriter)
+ {
+ _innerLogger = logger;
+ _streamWriter = streamWriter;
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ if (_streamWriter != null)
+ {
+ _streamWriter.Dispose();
+ _streamWriter = null;
+ }
+ }
+
+ #endregion
+
+ public void Log(string format, params object[] args)
+ {
+ _innerLogger.Log(format, args);
+ }
+
+ public void Warn(string format, params object[] args)
+ {
+ _innerLogger.Warn(format, args);
+ }
+
+ public void Trace(string format, params object[] args)
+ {
+ _innerLogger.Trace(format, args);
+ }
+
+ public void ApplyingDBChange(string sql)
+ {
+ _innerLogger.ApplyingDBChange(sql);
+ _streamWriter.WriteLine(sql);
+ }
+
+ public void Started(List appliedVersions, long finalVersion)
+ {
+ _innerLogger.Started(appliedVersions, finalVersion);
+ }
+
+ public void MigrateUp(long version, string migrationName)
+ {
+ _innerLogger.MigrateUp(version, migrationName);
+ }
+
+ public void MigrateDown(long version, string migrationName)
+ {
+ _innerLogger.MigrateDown(version, migrationName);
+ }
+
+ public void Skipping(long version)
+ {
+ _innerLogger.Skipping(version);
+ }
+
+ public void RollingBack(long originalVersion)
+ {
+ _innerLogger.RollingBack(originalVersion);
+ }
+
+ public void Exception(long version, string migrationName, Exception ex)
+ {
+ _innerLogger.Exception(version, migrationName, ex);
+ }
+
+ public void Exception(string message, Exception ex)
+ {
+ _innerLogger.Exception(message, ex);
+ }
+
+ public void Finished(List appliedVersions, long currentVersion)
+ {
+ _innerLogger.Finished(appliedVersions, currentVersion);
+ _streamWriter.Close();
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Migration.cs b/Migrator.net/Migrator.Framework/Migration.cs
new file mode 100644
index 000000000..5150e1cef
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Migration.cs
@@ -0,0 +1,119 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework
+{
+ ///
+ /// A migration is a group of transformation applied to the database schema
+ /// (or sometimes data) to port the database from one version to another.
+ /// The Up() method must apply the modifications (eg.: create a table)
+ /// and the Down() method must revert, or rollback the modifications
+ /// (eg.: delete a table).
+ ///
+ /// Each migration must be decorated with the [Migration(0)] attribute.
+ /// Each migration number (0) must be unique, or else a
+ /// DuplicatedVersionException will be trown.
+ ///
+ ///
+ /// All migrations are executed inside a transaction. If an exception is
+ /// thrown, the transaction will be rolledback and transformations wont be
+ /// applied.
+ ///
+ ///
+ /// It is best to keep a limited number of transformation inside a migration
+ /// so you can easely move from one version of to another with fine grain
+ /// modifications.
+ /// You should give meaningful name to the migration class and prepend the
+ /// migration number to the filename so they keep ordered, eg.:
+ /// 002_CreateTableTest.cs.
+ ///
+ ///
+ /// Use the Database property to apply transformation and the
+ /// Logger property to output informations in the console (or other).
+ /// For more details on transformations see
+ /// ITransformationProvider.
+ ///
+ ///
+ ///
+ /// The following migration creates a new Customer table.
+ /// (File 003_AddCustomerTable.cs)
+ ///
+ /// [Migration(3)]
+ /// public class AddCustomerTable : Migration
+ /// {
+ /// public override void Up()
+ /// {
+ /// Database.AddTable("Customer",
+ /// new Column("Name", typeof(string), 50),
+ /// new Column("Address", typeof(string), 100)
+ /// );
+ /// }
+ /// public override void Down()
+ /// {
+ /// Database.RemoveTable("Customer");
+ /// }
+ /// }
+ ///
+ ///
+ public abstract class Migration : IMigration
+ {
+ private ITransformationProvider _transformationProvider;
+
+ public string Name
+ {
+ get { return StringUtils.ToHumanName(GetType().Name); }
+ }
+
+ ///
+ /// Defines tranformations to port the database to the current version.
+ ///
+ public abstract void Up();
+
+ ///
+ /// This is run after the Up transaction has been committed
+ ///
+ public virtual void AfterUp()
+ {
+ }
+
+ ///
+ /// Defines transformations to revert things done in Up.
+ ///
+ public abstract void Down();
+
+ ///
+ /// This is run after the Down transaction has been committed
+ ///
+ public virtual void AfterDown()
+ {
+ }
+
+ ///
+ /// Represents the database.
+ /// .
+ ///
+ /// Migration.Framework.ITransformationProvider
+ public ITransformationProvider Database
+ {
+ get { return _transformationProvider; }
+ set { _transformationProvider = value; }
+ }
+
+ ///
+ /// This gets called once on the first migration object.
+ ///
+ public virtual void InitializeOnce(string[] args)
+ {
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/MigrationAttribute.cs b/Migrator.net/Migrator.Framework/MigrationAttribute.cs
new file mode 100644
index 000000000..c424dac14
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/MigrationAttribute.cs
@@ -0,0 +1,53 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System;
+
+namespace Migrator.Framework
+{
+ ///
+ /// Describe a migration
+ ///
+ public class MigrationAttribute : Attribute
+ {
+ private long _version;
+ private bool _ignore = false;
+
+ ///
+ /// Describe the migration
+ ///
+ /// The unique version of the migration.
+ public MigrationAttribute(long version)
+ {
+ Version = version;
+ }
+
+ ///
+ /// The version reflected by the migration
+ ///
+ public long Version
+ {
+ get { return _version; }
+ private set { _version = value; }
+ }
+
+ ///
+ /// Set to true to ignore this migration.
+ ///
+ public bool Ignore
+ {
+ get { return _ignore; }
+ set { _ignore = value; }
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/MigrationException.cs b/Migrator.net/Migrator.Framework/MigrationException.cs
new file mode 100644
index 000000000..e88ea4a8c
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/MigrationException.cs
@@ -0,0 +1,30 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System;
+
+namespace Migrator.Framework
+{
+ ///
+ /// Base class for migration errors.
+ ///
+ public class MigrationException : Exception
+ {
+ public MigrationException(string message)
+ : base(message) {}
+
+ public MigrationException(string message, Exception cause)
+ : base(message, cause) {}
+
+ public MigrationException(string migration, int version, Exception innerException)
+ : base(String.Format("Exception in migration {0} (#{1})", migration, version), innerException) {}
+ }
+}
diff --git a/Migrator.net/Migrator.Framework/Migrator.Framework.csproj b/Migrator.net/Migrator.Framework/Migrator.Framework.csproj
new file mode 100644
index 000000000..bf6c4d3eb
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/Migrator.Framework.csproj
@@ -0,0 +1,83 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}
+ Library
+ Migrator.Framework
+ Migrator.Framework
+
+
+ 3.5
+
+
+ true
+ MigratorDotNet.snk
+ v2.0
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/MigratorDotNet.snk b/Migrator.net/Migrator.Framework/MigratorDotNet.snk
new file mode 100644
index 000000000..5032d709b
Binary files /dev/null and b/Migrator.net/Migrator.Framework/MigratorDotNet.snk differ
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/all-wcprops b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/all-wcprops
new file mode 100644
index 000000000..ea94932b1
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/all-wcprops
@@ -0,0 +1,77 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder
+END
+FluentColumn.cs
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/FluentColumn.cs
+END
+IDeleteTableOptions.cs
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/svn/!svn/ver/122/trunk/src/Migrator.Framework/SchemaBuilder/IDeleteTableOptions.cs
+END
+RenameTableExpression.cs
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/RenameTableExpression.cs
+END
+AddTableExpression.cs
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/AddTableExpression.cs
+END
+ISchemaBuilderExpression.cs
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/ISchemaBuilderExpression.cs
+END
+IColumnOptions.cs
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/IColumnOptions.cs
+END
+ForeignKey.cs
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/!svn/ver/122/trunk/src/Migrator.Framework/SchemaBuilder/ForeignKey.cs
+END
+IFluentColumn.cs
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/IFluentColumn.cs
+END
+AddColumnExpression.cs
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/AddColumnExpression.cs
+END
+SchemaBuilder.cs
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/SchemaBuilder.cs
+END
+IForeignKeyOptions.cs
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/svn/!svn/ver/122/trunk/src/Migrator.Framework/SchemaBuilder/IForeignKeyOptions.cs
+END
+DeleteTableExpression.cs
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/svn/!svn/ver/124/trunk/src/Migrator.Framework/SchemaBuilder/DeleteTableExpression.cs
+END
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/entries b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/entries
new file mode 100644
index 000000000..4b47ae201
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/entries
@@ -0,0 +1,436 @@
+10
+
+dir
+147
+http://migratordotnet.googlecode.com/svn/trunk/src/Migrator.Framework/SchemaBuilder
+http://migratordotnet.googlecode.com/svn
+
+
+
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8c3eb3c4-eb3a-0410-862c-73fa8ce6028b
+
+FluentColumn.cs
+file
+
+
+
+
+2011-05-23T18:17:16.661007Z
+530a5a0d558d87b32e4a9681f0066bfb
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1746
+
+IDeleteTableOptions.cs
+file
+
+
+
+
+2011-05-23T18:17:16.662007Z
+ca7d7dcec6bf029e9d68f797d12a0b23
+2008-12-17T03:32:49.850862Z
+122
+dkode8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+748
+
+RenameTableExpression.cs
+file
+
+
+
+
+2011-05-23T18:17:16.663007Z
+09ce9cc03039ba2986e97bf91babb390
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+927
+
+AddTableExpression.cs
+file
+
+
+
+
+2011-05-23T18:17:16.665007Z
+5021cf7ddfeaf239e49f0cc34d912972
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+843
+
+ISchemaBuilderExpression.cs
+file
+
+
+
+
+2011-05-23T18:17:16.665007Z
+5edc417b65a8294e9c701da78a2a0fd0
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+665
+
+IColumnOptions.cs
+file
+
+
+
+
+2011-05-23T18:17:16.666007Z
+725aafda14fca858a75392468e46912d
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+231
+
+ForeignKey.cs
+file
+
+
+
+
+2011-05-23T18:17:16.668007Z
+dfb33fc890b6aaabfcbfbb9a55c8f628
+2008-12-17T03:32:49.850862Z
+122
+dkode8
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1014
+
+IFluentColumn.cs
+file
+
+
+
+
+2011-05-23T18:17:16.670007Z
+0da0bc3bfc129443966847f12f24fec4
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+706
+
+AddColumnExpression.cs
+file
+
+
+
+
+2011-05-23T18:17:16.671007Z
+a28232c3bc6fe16fe65fff83b1327ac3
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1334
+
+SchemaBuilder.cs
+file
+
+
+
+
+2011-05-23T18:17:16.672008Z
+28742d9b060cf61f51534d162246e764
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4441
+
+IForeignKeyOptions.cs
+file
+
+
+
+
+2011-05-23T18:17:16.673008Z
+67796061d9ed8701e6df79e76657ab92
+2008-12-17T03:32:49.850862Z
+122
+dkode8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+689
+
+DeleteTableExpression.cs
+file
+
+
+
+
+2011-05-23T18:17:16.674008Z
+99d55609a1311b914534e6d16d0064b2
+2008-12-22T16:27:00.481752Z
+124
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+857
+
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/prop-base/ForeignKey.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/prop-base/ForeignKey.cs.svn-base
new file mode 100644
index 000000000..316065866
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/prop-base/ForeignKey.cs.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/prop-base/IFluentColumn.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/prop-base/IFluentColumn.cs.svn-base
new file mode 100644
index 000000000..316065866
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/prop-base/IFluentColumn.cs.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/AddColumnExpression.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/AddColumnExpression.cs.svn-base
new file mode 100644
index 000000000..0bcbc9433
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/AddColumnExpression.cs.svn-base
@@ -0,0 +1,40 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class AddColumnExpression : ISchemaBuilderExpression
+ {
+ private IFluentColumn _column;
+ private string _toTable;
+
+
+ public AddColumnExpression(string toTable, IFluentColumn column)
+ {
+ _column = column;
+ _toTable = toTable;
+ }
+ public void Create(ITransformationProvider provider)
+ {
+ provider.AddColumn(_toTable, _column.Name, _column.Type, _column.Size, _column.ColumnProperty, _column.DefaultValue);
+
+ if (_column.ForeignKey != null)
+ {
+ provider.AddForeignKey(
+ "FK_" + _toTable + "_" + _column.Name + "_" + _column.ForeignKey.PrimaryTable + "_" +
+ _column.ForeignKey.PrimaryKey,
+ _toTable, _column.Name, _column.ForeignKey.PrimaryTable, _column.ForeignKey.PrimaryKey, _column.Constraint);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/AddTableExpression.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/AddTableExpression.cs.svn-base
new file mode 100644
index 000000000..1bb3360c5
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/AddTableExpression.cs.svn-base
@@ -0,0 +1,28 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class AddTableExpression : ISchemaBuilderExpression
+ {
+ private string _newTable;
+ public AddTableExpression(string newTable)
+ {
+ _newTable = newTable;
+ }
+ public void Create(ITransformationProvider provider)
+ {
+ provider.AddTable(_newTable);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/DeleteTableExpression.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/DeleteTableExpression.cs.svn-base
new file mode 100644
index 000000000..82666ee5d
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/DeleteTableExpression.cs.svn-base
@@ -0,0 +1,28 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class DeleteTableExpression : ISchemaBuilderExpression
+ {
+ private string _tableName;
+ public DeleteTableExpression(string tableName)
+ {
+ _tableName = tableName;
+ }
+ public void Create(ITransformationProvider provider)
+ {
+ provider.RemoveTable(_tableName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/FluentColumn.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/FluentColumn.cs.svn-base
new file mode 100644
index 000000000..e1cc1ca02
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/FluentColumn.cs.svn-base
@@ -0,0 +1,80 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System.Data;
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class FluentColumn : IFluentColumn
+ {
+ private Column _inner;
+ private ForeignKeyConstraint _constraint;
+ private ForeignKey _fk;
+
+ public FluentColumn(string columnName)
+ {
+ _inner = new Column(columnName);
+ }
+
+ public ColumnProperty ColumnProperty
+ {
+ get { return _inner.ColumnProperty; }
+ set { _inner.ColumnProperty = value; }
+ }
+
+ public string Name
+ {
+ get { return _inner.Name; }
+ set { _inner.Name = value; }
+ }
+
+ public DbType Type
+ {
+ get { return _inner.Type; }
+ set { _inner.Type = value; }
+ }
+
+ public int Size
+ {
+ get { return _inner.Size; }
+ set { _inner.Size = value; }
+ }
+
+ public bool IsIdentity
+ {
+ get { return _inner.IsIdentity; }
+ }
+
+ public bool IsPrimaryKey
+ {
+ get { return _inner.IsPrimaryKey; }
+ }
+
+ public object DefaultValue
+ {
+ get { return _inner.DefaultValue; }
+ set { _inner.DefaultValue = value; }
+ }
+
+ public ForeignKeyConstraint Constraint
+ {
+ get { return _constraint; }
+ set { _constraint = value; }
+ }
+ public ForeignKey ForeignKey
+ {
+ get { return _fk; }
+ set { _fk = value; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/ForeignKey.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/ForeignKey.cs.svn-base
new file mode 100644
index 000000000..095b0948a
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/ForeignKey.cs.svn-base
@@ -0,0 +1,39 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class ForeignKey
+ {
+ private string _primaryTable;
+ private string _primaryKey;
+
+ public ForeignKey(string primaryTable, string primaryKey)
+ {
+ _primaryTable = primaryTable;
+ _primaryKey = primaryKey;
+ }
+
+ public string PrimaryTable
+ {
+ get { return _primaryTable; }
+ set { _primaryTable = value; }
+ }
+
+ public string PrimaryKey
+ {
+ get { return _primaryKey; }
+ set { _primaryKey = value; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IColumnOptions.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IColumnOptions.cs.svn-base
new file mode 100644
index 000000000..8fd8cb32d
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IColumnOptions.cs.svn-base
@@ -0,0 +1,13 @@
+using System.Data;
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface IColumnOptions
+ {
+ SchemaBuilder OfType(DbType dbType);
+
+ SchemaBuilder WithSize(int size);
+
+ IForeignKeyOptions AsForeignKey();
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IDeleteTableOptions.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IDeleteTableOptions.cs.svn-base
new file mode 100644
index 000000000..4d4152519
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IDeleteTableOptions.cs.svn-base
@@ -0,0 +1,24 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface IDeleteTableOptions
+ {
+ SchemaBuilder WithTable(string name);
+
+ SchemaBuilder AddTable(string name);
+
+ IDeleteTableOptions DeleteTable(string name);
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IFluentColumn.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IFluentColumn.cs.svn-base
new file mode 100644
index 000000000..6500ba948
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IFluentColumn.cs.svn-base
@@ -0,0 +1,22 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface IFluentColumn : IColumn
+ {
+ ForeignKeyConstraint Constraint { get; set; }
+
+ ForeignKey ForeignKey { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IForeignKeyOptions.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IForeignKeyOptions.cs.svn-base
new file mode 100644
index 000000000..3cb52cbf1
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/IForeignKeyOptions.cs.svn-base
@@ -0,0 +1,20 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface IForeignKeyOptions
+ {
+ SchemaBuilder ReferencedTo(string primaryKeyTable, string primaryKeyColumn);
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/ISchemaBuilderExpression.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/ISchemaBuilderExpression.cs.svn-base
new file mode 100644
index 000000000..0db89f886
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/ISchemaBuilderExpression.cs.svn-base
@@ -0,0 +1,20 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface ISchemaBuilderExpression
+ {
+ void Create(ITransformationProvider provider);
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/RenameTableExpression.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/RenameTableExpression.cs.svn-base
new file mode 100644
index 000000000..7880618a9
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/RenameTableExpression.cs.svn-base
@@ -0,0 +1,31 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class RenameTableExpression : ISchemaBuilderExpression
+ {
+ private string _oldName;
+ private string _newName;
+
+ public RenameTableExpression(string oldName, string newName)
+ {
+ _oldName = oldName;
+ _newName = newName;
+ }
+ public void Create(ITransformationProvider provider)
+ {
+ provider.RenameTable(_oldName, _newName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/SchemaBuilder.cs.svn-base b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/SchemaBuilder.cs.svn-base
new file mode 100644
index 000000000..a02c4fe6d
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/.svn/text-base/SchemaBuilder.cs.svn-base
@@ -0,0 +1,169 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class SchemaBuilder : IColumnOptions, IForeignKeyOptions, IDeleteTableOptions
+ {
+ private string _currentTable;
+ private IFluentColumn _currentColumn;
+ private IList _exprs;
+
+ public SchemaBuilder()
+ {
+ _exprs = new List();
+ }
+
+ public IEnumerable Expressions
+ {
+ get { return _exprs; }
+ }
+
+ ///
+ /// Adds a Table to be created to the Schema
+ ///
+ /// Table name to be created
+ /// SchemaBuilder for chaining
+ public SchemaBuilder AddTable(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+
+ _exprs.Add(new AddTableExpression(name));
+ _currentTable = name;
+
+ return this;
+ }
+
+ public IDeleteTableOptions DeleteTable(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+ _currentTable = "";
+ _currentColumn = null;
+
+ _exprs.Add(new DeleteTableExpression(name));
+
+ return this;
+ }
+
+ ///
+ /// Reference an existing table.
+ ///
+ /// Table to reference
+ /// SchemaBuilder for chaining
+ public SchemaBuilder RenameTable(string newName)
+ {
+ if (string.IsNullOrEmpty(newName))
+ throw new ArgumentNullException("newName");
+
+ _exprs.Add(new RenameTableExpression(_currentTable, newName));
+ _currentTable = newName;
+
+ return this;
+ }
+
+ ///
+ /// Reference an existing table.
+ ///
+ /// Table to reference
+ /// SchemaBuilder for chaining
+ public SchemaBuilder WithTable(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+
+ _currentTable = name;
+
+ return this;
+ }
+
+ ///
+ /// Adds a Column to be created
+ ///
+ /// Column name to be added
+ /// IColumnOptions to restrict chaining
+ public IColumnOptions AddColumn(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+ if (string.IsNullOrEmpty(_currentTable))
+ throw new ArgumentException("missing referenced table");
+
+ IFluentColumn column = new FluentColumn(name);
+ _currentColumn = column;
+
+ _exprs.Add(new AddColumnExpression(_currentTable, column));
+ return this;
+ }
+
+ public SchemaBuilder OfType(DbType columnType)
+ {
+ _currentColumn.Type = columnType;
+
+ return this;
+ }
+
+ public SchemaBuilder WithProperty(ColumnProperty columnProperty)
+ {
+ _currentColumn.ColumnProperty = columnProperty;
+
+ return this;
+ }
+
+ public SchemaBuilder WithSize(int size)
+ {
+ if (size == 0)
+ throw new ArgumentNullException("size", "Size must be greater than zero");
+
+ _currentColumn.Size = size;
+
+ return this;
+ }
+
+ public SchemaBuilder WithDefaultValue(object defaultValue)
+ {
+ if (defaultValue == null)
+ throw new ArgumentNullException("defaultValue", "DefaultValue cannot be null or empty");
+
+ _currentColumn.DefaultValue = defaultValue;
+
+ return this;
+ }
+
+ public IForeignKeyOptions AsForeignKey()
+ {
+ _currentColumn.ColumnProperty = ColumnProperty.ForeignKey;
+
+ return this;
+ }
+
+ public SchemaBuilder ReferencedTo(string primaryKeyTable, string primaryKeyColumn)
+ {
+ _currentColumn.Constraint = ForeignKeyConstraint.NoAction;
+ _currentColumn.ForeignKey = new ForeignKey(primaryKeyTable, primaryKeyColumn);
+ return this;
+ }
+
+ public SchemaBuilder WithConstraint(ForeignKeyConstraint action)
+ {
+ _currentColumn.Constraint = action;
+
+ return this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/AddColumnExpression.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/AddColumnExpression.cs
new file mode 100644
index 000000000..0bcbc9433
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/AddColumnExpression.cs
@@ -0,0 +1,40 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class AddColumnExpression : ISchemaBuilderExpression
+ {
+ private IFluentColumn _column;
+ private string _toTable;
+
+
+ public AddColumnExpression(string toTable, IFluentColumn column)
+ {
+ _column = column;
+ _toTable = toTable;
+ }
+ public void Create(ITransformationProvider provider)
+ {
+ provider.AddColumn(_toTable, _column.Name, _column.Type, _column.Size, _column.ColumnProperty, _column.DefaultValue);
+
+ if (_column.ForeignKey != null)
+ {
+ provider.AddForeignKey(
+ "FK_" + _toTable + "_" + _column.Name + "_" + _column.ForeignKey.PrimaryTable + "_" +
+ _column.ForeignKey.PrimaryKey,
+ _toTable, _column.Name, _column.ForeignKey.PrimaryTable, _column.ForeignKey.PrimaryKey, _column.Constraint);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/AddTableExpression.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/AddTableExpression.cs
new file mode 100644
index 000000000..1bb3360c5
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/AddTableExpression.cs
@@ -0,0 +1,28 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class AddTableExpression : ISchemaBuilderExpression
+ {
+ private string _newTable;
+ public AddTableExpression(string newTable)
+ {
+ _newTable = newTable;
+ }
+ public void Create(ITransformationProvider provider)
+ {
+ provider.AddTable(_newTable);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/DeleteTableExpression.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/DeleteTableExpression.cs
new file mode 100644
index 000000000..82666ee5d
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/DeleteTableExpression.cs
@@ -0,0 +1,28 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class DeleteTableExpression : ISchemaBuilderExpression
+ {
+ private string _tableName;
+ public DeleteTableExpression(string tableName)
+ {
+ _tableName = tableName;
+ }
+ public void Create(ITransformationProvider provider)
+ {
+ provider.RemoveTable(_tableName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/FluentColumn.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/FluentColumn.cs
new file mode 100644
index 000000000..e1cc1ca02
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/FluentColumn.cs
@@ -0,0 +1,80 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System.Data;
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class FluentColumn : IFluentColumn
+ {
+ private Column _inner;
+ private ForeignKeyConstraint _constraint;
+ private ForeignKey _fk;
+
+ public FluentColumn(string columnName)
+ {
+ _inner = new Column(columnName);
+ }
+
+ public ColumnProperty ColumnProperty
+ {
+ get { return _inner.ColumnProperty; }
+ set { _inner.ColumnProperty = value; }
+ }
+
+ public string Name
+ {
+ get { return _inner.Name; }
+ set { _inner.Name = value; }
+ }
+
+ public DbType Type
+ {
+ get { return _inner.Type; }
+ set { _inner.Type = value; }
+ }
+
+ public int Size
+ {
+ get { return _inner.Size; }
+ set { _inner.Size = value; }
+ }
+
+ public bool IsIdentity
+ {
+ get { return _inner.IsIdentity; }
+ }
+
+ public bool IsPrimaryKey
+ {
+ get { return _inner.IsPrimaryKey; }
+ }
+
+ public object DefaultValue
+ {
+ get { return _inner.DefaultValue; }
+ set { _inner.DefaultValue = value; }
+ }
+
+ public ForeignKeyConstraint Constraint
+ {
+ get { return _constraint; }
+ set { _constraint = value; }
+ }
+ public ForeignKey ForeignKey
+ {
+ get { return _fk; }
+ set { _fk = value; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/ForeignKey.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/ForeignKey.cs
new file mode 100644
index 000000000..095b0948a
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/ForeignKey.cs
@@ -0,0 +1,39 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class ForeignKey
+ {
+ private string _primaryTable;
+ private string _primaryKey;
+
+ public ForeignKey(string primaryTable, string primaryKey)
+ {
+ _primaryTable = primaryTable;
+ _primaryKey = primaryKey;
+ }
+
+ public string PrimaryTable
+ {
+ get { return _primaryTable; }
+ set { _primaryTable = value; }
+ }
+
+ public string PrimaryKey
+ {
+ get { return _primaryKey; }
+ set { _primaryKey = value; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/IColumnOptions.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/IColumnOptions.cs
new file mode 100644
index 000000000..8fd8cb32d
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/IColumnOptions.cs
@@ -0,0 +1,13 @@
+using System.Data;
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface IColumnOptions
+ {
+ SchemaBuilder OfType(DbType dbType);
+
+ SchemaBuilder WithSize(int size);
+
+ IForeignKeyOptions AsForeignKey();
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/IDeleteTableOptions.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/IDeleteTableOptions.cs
new file mode 100644
index 000000000..4d4152519
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/IDeleteTableOptions.cs
@@ -0,0 +1,24 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface IDeleteTableOptions
+ {
+ SchemaBuilder WithTable(string name);
+
+ SchemaBuilder AddTable(string name);
+
+ IDeleteTableOptions DeleteTable(string name);
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/IFluentColumn.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/IFluentColumn.cs
new file mode 100644
index 000000000..6500ba948
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/IFluentColumn.cs
@@ -0,0 +1,22 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface IFluentColumn : IColumn
+ {
+ ForeignKeyConstraint Constraint { get; set; }
+
+ ForeignKey ForeignKey { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/IForeignKeyOptions.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/IForeignKeyOptions.cs
new file mode 100644
index 000000000..3cb52cbf1
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/IForeignKeyOptions.cs
@@ -0,0 +1,20 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface IForeignKeyOptions
+ {
+ SchemaBuilder ReferencedTo(string primaryKeyTable, string primaryKeyColumn);
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/ISchemaBuilderExpression.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/ISchemaBuilderExpression.cs
new file mode 100644
index 000000000..0db89f886
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/ISchemaBuilderExpression.cs
@@ -0,0 +1,20 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public interface ISchemaBuilderExpression
+ {
+ void Create(ITransformationProvider provider);
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/RenameTableExpression.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/RenameTableExpression.cs
new file mode 100644
index 000000000..7880618a9
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/RenameTableExpression.cs
@@ -0,0 +1,31 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class RenameTableExpression : ISchemaBuilderExpression
+ {
+ private string _oldName;
+ private string _newName;
+
+ public RenameTableExpression(string oldName, string newName)
+ {
+ _oldName = oldName;
+ _newName = newName;
+ }
+ public void Create(ITransformationProvider provider)
+ {
+ provider.RenameTable(_oldName, _newName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/SchemaBuilder/SchemaBuilder.cs b/Migrator.net/Migrator.Framework/SchemaBuilder/SchemaBuilder.cs
new file mode 100644
index 000000000..a02c4fe6d
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/SchemaBuilder/SchemaBuilder.cs
@@ -0,0 +1,169 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+
+namespace Migrator.Framework.SchemaBuilder
+{
+ public class SchemaBuilder : IColumnOptions, IForeignKeyOptions, IDeleteTableOptions
+ {
+ private string _currentTable;
+ private IFluentColumn _currentColumn;
+ private IList _exprs;
+
+ public SchemaBuilder()
+ {
+ _exprs = new List();
+ }
+
+ public IEnumerable Expressions
+ {
+ get { return _exprs; }
+ }
+
+ ///
+ /// Adds a Table to be created to the Schema
+ ///
+ /// Table name to be created
+ /// SchemaBuilder for chaining
+ public SchemaBuilder AddTable(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+
+ _exprs.Add(new AddTableExpression(name));
+ _currentTable = name;
+
+ return this;
+ }
+
+ public IDeleteTableOptions DeleteTable(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+ _currentTable = "";
+ _currentColumn = null;
+
+ _exprs.Add(new DeleteTableExpression(name));
+
+ return this;
+ }
+
+ ///
+ /// Reference an existing table.
+ ///
+ /// Table to reference
+ /// SchemaBuilder for chaining
+ public SchemaBuilder RenameTable(string newName)
+ {
+ if (string.IsNullOrEmpty(newName))
+ throw new ArgumentNullException("newName");
+
+ _exprs.Add(new RenameTableExpression(_currentTable, newName));
+ _currentTable = newName;
+
+ return this;
+ }
+
+ ///
+ /// Reference an existing table.
+ ///
+ /// Table to reference
+ /// SchemaBuilder for chaining
+ public SchemaBuilder WithTable(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+
+ _currentTable = name;
+
+ return this;
+ }
+
+ ///
+ /// Adds a Column to be created
+ ///
+ /// Column name to be added
+ /// IColumnOptions to restrict chaining
+ public IColumnOptions AddColumn(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("name");
+ if (string.IsNullOrEmpty(_currentTable))
+ throw new ArgumentException("missing referenced table");
+
+ IFluentColumn column = new FluentColumn(name);
+ _currentColumn = column;
+
+ _exprs.Add(new AddColumnExpression(_currentTable, column));
+ return this;
+ }
+
+ public SchemaBuilder OfType(DbType columnType)
+ {
+ _currentColumn.Type = columnType;
+
+ return this;
+ }
+
+ public SchemaBuilder WithProperty(ColumnProperty columnProperty)
+ {
+ _currentColumn.ColumnProperty = columnProperty;
+
+ return this;
+ }
+
+ public SchemaBuilder WithSize(int size)
+ {
+ if (size == 0)
+ throw new ArgumentNullException("size", "Size must be greater than zero");
+
+ _currentColumn.Size = size;
+
+ return this;
+ }
+
+ public SchemaBuilder WithDefaultValue(object defaultValue)
+ {
+ if (defaultValue == null)
+ throw new ArgumentNullException("defaultValue", "DefaultValue cannot be null or empty");
+
+ _currentColumn.DefaultValue = defaultValue;
+
+ return this;
+ }
+
+ public IForeignKeyOptions AsForeignKey()
+ {
+ _currentColumn.ColumnProperty = ColumnProperty.ForeignKey;
+
+ return this;
+ }
+
+ public SchemaBuilder ReferencedTo(string primaryKeyTable, string primaryKeyColumn)
+ {
+ _currentColumn.Constraint = ForeignKeyConstraint.NoAction;
+ _currentColumn.ForeignKey = new ForeignKey(primaryKeyTable, primaryKeyColumn);
+ return this;
+ }
+
+ public SchemaBuilder WithConstraint(ForeignKeyConstraint action)
+ {
+ _currentColumn.Constraint = action;
+
+ return this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Framework/StringUtils.cs b/Migrator.net/Migrator.Framework/StringUtils.cs
new file mode 100644
index 000000000..4d91d4305
--- /dev/null
+++ b/Migrator.net/Migrator.Framework/StringUtils.cs
@@ -0,0 +1,43 @@
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Migrator.Framework
+{
+ public class StringUtils
+ {
+ ///
+ /// Convert a classname to something more readable.
+ /// ex.: CreateATable => Create a table
+ ///
+ ///
+ ///
+ public static string ToHumanName(string className)
+ {
+ string name = Regex.Replace(className, "([A-Z])", " $1").Substring(1);
+ return name.Substring(0, 1).ToUpper() + name.Substring(1).ToLower();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static string ReplaceOnce(string template, string placeholder, string replacement)
+ {
+ int loc = template.IndexOf(placeholder);
+ if (loc < 0)
+ {
+ return template;
+ }
+ else
+ {
+ return new StringBuilder(template.Substring(0, loc))
+ .Append(replacement)
+ .Append(template.Substring(loc + placeholder.Length))
+ .ToString();
+ }
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Providers/ColumnPropertiesMapper.cs b/Migrator.net/Migrator.Providers/ColumnPropertiesMapper.cs
new file mode 100644
index 000000000..8682a2c29
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/ColumnPropertiesMapper.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections.Generic;
+using Migrator.Framework;
+
+namespace Migrator.Providers
+{
+ ///
+ /// This is basically a just a helper base class
+ /// per-database implementors may want to override ColumnSql
+ ///
+ public class ColumnPropertiesMapper
+ {
+ protected Dialect dialect;
+
+ /// The SQL type
+ protected string type;
+
+ /// The name of the column
+ protected string name;
+
+ ///
+ /// the type of the column
+ ///
+ protected string columnSql;
+
+ ///
+ /// Sql if This column is Indexed
+ ///
+ protected bool indexed = false;
+
+ ///
+ /// Sql if this column has a default value
+ ///
+ protected object defaultVal;
+
+ public ColumnPropertiesMapper(Dialect dialect, string type)
+ {
+ this.dialect = dialect;
+ this.type = type;
+ }
+
+ ///
+ /// The sql for this column, override in database-specific implementation classes
+ ///
+ public virtual string ColumnSql
+ {
+ get { return columnSql; }
+ }
+
+ public string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public object Default
+ {
+ get { return defaultVal; }
+ set { defaultVal = value; }
+ }
+
+ public string QuotedName
+ {
+ get { return dialect.Quote(Name); }
+ }
+
+ public string IndexSql
+ {
+ get
+ {
+ if (dialect.SupportsIndex && indexed)
+ return String.Format("INDEX({0})", dialect.Quote(name));
+ return null;
+ }
+ }
+
+ public void MapColumnProperties(Column column)
+ {
+ Name = column.Name;
+ indexed = PropertySelected(column.ColumnProperty, ColumnProperty.Indexed);
+
+ List vals = new List();
+ vals.Add(dialect.ColumnNameNeedsQuote ? QuotedName : Name);
+
+ vals.Add(type);
+
+ if (! dialect.IdentityNeedsType)
+ AddValueIfSelected(column, ColumnProperty.Identity, vals);
+
+ AddValueIfSelected(column, ColumnProperty.Unsigned, vals);
+ if (! PropertySelected(column.ColumnProperty, ColumnProperty.PrimaryKey) || dialect.NeedsNotNullForIdentity)
+ AddValueIfSelected(column, ColumnProperty.NotNull, vals);
+
+ AddValueIfSelected(column, ColumnProperty.PrimaryKey, vals);
+
+ if (dialect.IdentityNeedsType)
+ AddValueIfSelected(column, ColumnProperty.Identity, vals);
+
+ AddValueIfSelected(column, ColumnProperty.Unique, vals);
+ AddValueIfSelected(column, ColumnProperty.ForeignKey, vals);
+
+ if (column.DefaultValue != null)
+ vals.Add(dialect.Default(column.DefaultValue));
+
+ columnSql = String.Join(" ", vals.ToArray());
+ }
+
+ private void AddValueIfSelected(Column column, ColumnProperty property, ICollection vals)
+ {
+ if (PropertySelected(column.ColumnProperty, property))
+ vals.Add(dialect.SqlForProperty(property));
+ }
+
+ public static bool PropertySelected(ColumnProperty source, ColumnProperty comparison)
+ {
+ return (source & comparison) == comparison;
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Providers/Dialect.cs b/Migrator.net/Migrator.Providers/Dialect.cs
new file mode 100644
index 000000000..11df04dde
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Dialect.cs
@@ -0,0 +1,181 @@
+
+using System;
+using System.Data;
+using System.Collections.Generic;
+using Migrator.Framework;
+
+namespace Migrator.Providers
+{
+ ///
+ /// Defines the implementations specific details for a particular database.
+ ///
+ public abstract class Dialect
+ {
+ private readonly Dictionary propertyMap = new Dictionary();
+ private readonly TypeNames typeNames = new TypeNames();
+
+ protected Dialect()
+ {
+ RegisterProperty(ColumnProperty.Null, "NULL");
+ RegisterProperty(ColumnProperty.NotNull, "NOT NULL");
+ RegisterProperty(ColumnProperty.Unique, "UNIQUE");
+ RegisterProperty(ColumnProperty.PrimaryKey, "PRIMARY KEY");
+ }
+
+ public abstract Type TransformationProvider { get; }
+
+ public ITransformationProvider NewProviderForDialect(string connectionString)
+ {
+ return (ITransformationProvider) Activator.CreateInstance(TransformationProvider, this, connectionString);
+ }
+
+ ///
+ /// Subclasses register a typename for the given type code and maximum
+ /// column length. $l in the type name will be replaced by the column
+ /// length (if appropriate)
+ ///
+ /// The typecode
+ /// Maximum length of database type
+ /// The database type name
+ protected void RegisterColumnType(DbType code, int capacity, string name)
+ {
+ typeNames.Put(code, capacity, name);
+ }
+
+ ///
+ /// Suclasses register a typename for the given type code. $l in the
+ /// typename will be replaced by the column length (if appropriate).
+ ///
+ /// The typecode
+ /// The database type name
+ protected void RegisterColumnType(DbType code, string name)
+ {
+ typeNames.Put(code, name);
+ }
+
+ public ColumnPropertiesMapper GetColumnMapper(Column column)
+ {
+ string type = column.Size > 0 ? GetTypeName(column.Type, column.Size) : GetTypeName(column.Type);
+ if (! IdentityNeedsType && column.IsIdentity)
+ type = String.Empty;
+
+ return new ColumnPropertiesMapper(this, type);
+ }
+
+ ///
+ /// Get the name of the database type associated with the given
+ ///
+ /// The DbType
+ /// The database type name used by ddl.
+ public virtual string GetTypeName(DbType type)
+ {
+ string result = typeNames.Get(type);
+ if (result == null)
+ {
+ throw new Exception(string.Format("No default type mapping for DbType {0}", type));
+ }
+
+ return result;
+ }
+
+ ///
+ /// Get the name of the database type associated with the given
+ ///
+ /// The DbType
+ /// The database type name used by ddl.
+ ///
+ public virtual string GetTypeName(DbType type, int length)
+ {
+ return GetTypeName(type, length, 0, 0);
+ }
+
+ ///
+ /// Get the name of the database type associated with the given
+ ///
+ /// The DbType
+ /// The database type name used by ddl.
+ ///
+ ///
+ ///
+ public virtual string GetTypeName(DbType type, int length, int precision, int scale)
+ {
+ string resultWithLength = typeNames.Get(type, length, precision, scale);
+ if (resultWithLength != null)
+ return resultWithLength;
+
+ return GetTypeName(type);
+ }
+
+ public void RegisterProperty(ColumnProperty property, string sql)
+ {
+ if (! propertyMap.ContainsKey(property))
+ {
+ propertyMap.Add(property, sql);
+ }
+ propertyMap[property] = sql;
+ }
+
+ public string SqlForProperty(ColumnProperty property)
+ {
+ if (propertyMap.ContainsKey(property))
+ {
+ return propertyMap[property];
+ }
+ return String.Empty;
+ }
+
+ public virtual bool ColumnNameNeedsQuote
+ {
+ get { return false; }
+ }
+
+ public virtual bool TableNameNeedsQuote
+ {
+ get { return false; }
+ }
+
+ public virtual bool ConstraintNameNeedsQuote
+ {
+ get { return false; }
+ }
+
+ public virtual bool IdentityNeedsType
+ {
+ get { return true; }
+ }
+
+ public virtual bool NeedsNotNullForIdentity
+ {
+ get { return true; }
+ }
+
+ public virtual bool SupportsIndex
+ {
+ get { return true; }
+ }
+
+ public virtual string Quote(string value)
+ {
+ return String.Format(QuoteTemplate, value);
+ }
+
+ public virtual string QuoteTemplate
+ {
+ get { return "\"{0}\""; }
+ }
+
+ public virtual string Default(object defaultValue)
+ {
+ return String.Format("DEFAULT {0}", defaultValue);
+ }
+
+ public ColumnPropertiesMapper GetAndMapColumnProperties(Column column)
+ {
+ ColumnPropertiesMapper mapper = GetColumnMapper(column);
+ mapper.MapColumnProperties(column);
+ if (column.DefaultValue != null)
+ mapper.Default = column.DefaultValue;
+ return mapper;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Providers/ForeignKeyConstraintMapper.cs b/Migrator.net/Migrator.Providers/ForeignKeyConstraintMapper.cs
new file mode 100644
index 000000000..35c4a8e93
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/ForeignKeyConstraintMapper.cs
@@ -0,0 +1,24 @@
+using Migrator.Framework;
+
+namespace Migrator.Providers
+{
+ public class ForeignKeyConstraintMapper
+ {
+ public string SqlForConstraint(ForeignKeyConstraint constraint)
+ {
+ switch(constraint)
+ {
+ case ForeignKeyConstraint.Cascade:
+ return "CASCADE";
+ case ForeignKeyConstraint.Restrict:
+ return "RESTRICT";
+ case ForeignKeyConstraint.SetDefault:
+ return "SET DEFAULT";
+ case ForeignKeyConstraint.SetNull:
+ return "SET NULL";
+ default:
+ return "NO ACTION";
+ }
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Providers/Impl/.svn/all-wcprops b/Migrator.net/Migrator.Providers/Impl/.svn/all-wcprops
new file mode 100644
index 000000000..2ad37dc87
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Impl/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/svn/!svn/ver/144/trunk/src/Migrator.Providers/Impl
+END
diff --git a/Migrator.net/Migrator.Providers/Impl/.svn/entries b/Migrator.net/Migrator.Providers/Impl/.svn/entries
new file mode 100644
index 000000000..2b80596b8
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Impl/.svn/entries
@@ -0,0 +1,43 @@
+10
+
+dir
+147
+http://migratordotnet.googlecode.com/svn/trunk/src/Migrator.Providers/Impl
+http://migratordotnet.googlecode.com/svn
+
+
+
+2010-03-25T22:27:09.529568Z
+144
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8c3eb3c4-eb3a-0410-862c-73fa8ce6028b
+
+SQLite
+dir
+
+PostgreSQL
+dir
+
+Oracle
+dir
+
+Mysql
+dir
+
+SqlServer
+dir
+
diff --git a/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/all-wcprops b/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/all-wcprops
new file mode 100644
index 000000000..cd10a5fe9
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/svn/!svn/ver/108/trunk/src/Migrator.Providers/Impl/SQLite
+END
+SQLiteTransformationProvider.cs
+K 25
+svn:wc:ra_dav:version-url
+V 90
+/svn/!svn/ver/108/trunk/src/Migrator.Providers/Impl/SQLite/SQLiteTransformationProvider.cs
+END
+SQLiteDialect.cs
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/!svn/ver/87/trunk/src/Migrator.Providers/Impl/SQLite/SQLiteDialect.cs
+END
diff --git a/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/entries b/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/entries
new file mode 100644
index 000000000..bbb0295b3
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+147
+http://migratordotnet.googlecode.com/svn/trunk/src/Migrator.Providers/Impl/SQLite
+http://migratordotnet.googlecode.com/svn
+
+
+
+2008-08-04T22:56:23.283456Z
+108
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8c3eb3c4-eb3a-0410-862c-73fa8ce6028b
+
+SQLiteTransformationProvider.cs
+file
+
+
+
+
+2011-05-23T18:17:16.308987Z
+1a5895030f84893a6051489dcd1958d2
+2008-08-04T22:56:23.283456Z
+108
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8486
+
+SQLiteDialect.cs
+file
+
+
+
+
+2011-05-23T18:17:16.309987Z
+4dc0c91dddefbb5ec3c85037f025f3f3
+2008-06-12T19:25:48.586161Z
+87
+geofflane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1786
+
diff --git a/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/text-base/SQLiteDialect.cs.svn-base b/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/text-base/SQLiteDialect.cs.svn-base
new file mode 100644
index 000000000..0731f79ef
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/text-base/SQLiteDialect.cs.svn-base
@@ -0,0 +1,44 @@
+
+using System;
+using System.Data;
+using Migrator.Framework;
+
+namespace Migrator.Providers.SQLite
+{
+ public class SQLiteDialect : Dialect
+ {
+ public SQLiteDialect()
+ {
+ RegisterColumnType(DbType.Binary, "BLOB");
+ RegisterColumnType(DbType.Byte, "INTEGER");
+ RegisterColumnType(DbType.Int16, "INTEGER");
+ RegisterColumnType(DbType.Int32, "INTEGER");
+ RegisterColumnType(DbType.Int64, "INTEGER");
+ RegisterColumnType(DbType.SByte, "INTEGER");
+ RegisterColumnType(DbType.UInt16, "INTEGER");
+ RegisterColumnType(DbType.UInt32, "INTEGER");
+ RegisterColumnType(DbType.UInt64, "INTEGER");
+ RegisterColumnType(DbType.Currency, "NUMERIC");
+ RegisterColumnType(DbType.Decimal, "NUMERIC");
+ RegisterColumnType(DbType.Double, "NUMERIC");
+ RegisterColumnType(DbType.Single, "NUMERIC");
+ RegisterColumnType(DbType.VarNumeric, "NUMERIC");
+ RegisterColumnType(DbType.String, "TEXT");
+ RegisterColumnType(DbType.AnsiStringFixedLength, "TEXT");
+ RegisterColumnType(DbType.StringFixedLength, "TEXT");
+ RegisterColumnType(DbType.DateTime, "DATETIME");
+ RegisterColumnType(DbType.Time, "DATETIME");
+ RegisterColumnType(DbType.Boolean, "INTEGER");
+ RegisterColumnType(DbType.Guid, "UNIQUEIDENTIFIER");
+
+ RegisterProperty(ColumnProperty.Identity, "AUTOINCREMENT");
+ }
+
+ public override Type TransformationProvider { get { return typeof(SQLiteTransformationProvider); } }
+
+ public override bool NeedsNotNullForIdentity
+ {
+ get { return false; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/text-base/SQLiteTransformationProvider.cs.svn-base b/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/text-base/SQLiteTransformationProvider.cs.svn-base
new file mode 100644
index 000000000..ad6f3cc31
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Impl/SQLite/.svn/text-base/SQLiteTransformationProvider.cs.svn-base
@@ -0,0 +1,232 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using Migrator.Framework;
+using ForeignKeyConstraint=Migrator.Framework.ForeignKeyConstraint;
+#if DOTNET2
+using SqliteConnection=System.Data.SQLite.SQLiteConnection;
+#else
+using Mono.Data.Sqlite;
+#endif
+
+namespace Migrator.Providers.SQLite
+{
+ ///
+ /// Summary description for SQLiteTransformationProvider.
+ ///
+ public class SQLiteTransformationProvider : TransformationProvider
+ {
+ public SQLiteTransformationProvider(Dialect dialect, string connectionString)
+ : base(dialect, connectionString)
+ {
+ _connection = new SqliteConnection(_connectionString);
+ _connection.ConnectionString = _connectionString;
+ _connection.Open();
+ }
+
+ public override void AddForeignKey(string name, string primaryTable, string[] primaryColumns, string refTable,
+ string[] refColumns, ForeignKeyConstraint constraint)
+ {
+ // NOOP Because SQLite doesn't support foreign keys
+ }
+
+ public override void RemoveForeignKey(string name, string table)
+ {
+ // NOOP Because SQLite doesn't support foreign keys
+ }
+
+ public override void RemoveColumn(string table, string column)
+ {
+ if (! (TableExists(table) && ColumnExists(table, column)))
+ return;
+
+ string[] origColDefs = GetColumnDefs(table);
+ List colDefs = new List();
+
+ foreach (string origdef in origColDefs)
+ {
+ if (! ColumnMatch(column, origdef))
+ colDefs.Add(origdef);
+ }
+
+ string[] newColDefs = colDefs.ToArray();
+ string colDefsSql = String.Join(",", newColDefs);
+
+ string[] colNames = ParseSqlForColumnNames(newColDefs);
+ string colNamesSql = String.Join(",", colNames);
+
+ AddTable(table + "_temp", null, colDefsSql);
+ ExecuteQuery(String.Format("INSERT INTO {0}_temp SELECT {1} FROM {0}", table, colNamesSql));
+ RemoveTable(table);
+ ExecuteQuery(String.Format("ALTER TABLE {0}_temp RENAME TO {0}", table));
+ }
+
+ public override void RenameColumn(string tableName, string oldColumnName, string newColumnName)
+ {
+ if (ColumnExists(tableName, newColumnName))
+ throw new MigrationException(String.Format("Table '{0}' has column named '{1}' already", tableName, newColumnName));
+
+ if (ColumnExists(tableName, oldColumnName))
+ {
+ string[] columnDefs = GetColumnDefs(tableName);
+ string columnDef = Array.Find(columnDefs, delegate(string col) { return ColumnMatch(oldColumnName, col); });
+
+ string newColumnDef = columnDef.Replace(oldColumnName, newColumnName);
+
+ AddColumn(tableName, newColumnDef);
+ ExecuteQuery(String.Format("UPDATE {0} SET {1}={2}", tableName, newColumnName, oldColumnName));
+ RemoveColumn(tableName, oldColumnName);
+ }
+ }
+
+ public override void ChangeColumn(string table, Column column)
+ {
+ if (! ColumnExists(table, column.Name))
+ {
+ Logger.Warn("Column {0}.{1} does not exist", table, column.Name);
+ return;
+ }
+
+ string tempColumn = "temp_" + column.Name;
+ RenameColumn(table, column.Name, tempColumn);
+ AddColumn(table, column);
+ ExecuteQuery(String.Format("UPDATE {0} SET {1}={2}", table, column.Name, tempColumn));
+ RemoveColumn(table, tempColumn);
+ }
+
+ public override bool TableExists(string table)
+ {
+ using (IDataReader reader =
+ ExecuteQuery(String.Format("SELECT name FROM sqlite_master WHERE type='table' and name='{0}'",table)))
+ {
+ return reader.Read();
+ }
+ }
+
+ public override bool ConstraintExists(string table, string name)
+ {
+ return false;
+ }
+
+ public override string[] GetTables()
+ {
+ List tables = new List();
+
+ using (IDataReader reader = ExecuteQuery("SELECT name FROM sqlite_master WHERE type='table' AND name <> 'sqlite_sequence' ORDER BY name"))
+ {
+ while (reader.Read())
+ {
+ tables.Add((string) reader[0]);
+ }
+ }
+
+ return tables.ToArray();
+ }
+
+ public override Column[] GetColumns(string table)
+ {
+ List columns = new List();
+ foreach (string columnDef in GetColumnDefs(table))
+ {
+ string name = ExtractNameFromColumnDef(columnDef);
+ // FIXME: Need to get the real type information
+ Column column = new Column(name, DbType.String);
+ bool isNullable = IsNullable(columnDef);
+ column.ColumnProperty |= isNullable ? ColumnProperty.Null : ColumnProperty.NotNull;
+ columns.Add(column);
+ }
+ return columns.ToArray();
+ }
+
+ public string GetSqlDefString(string table)
+ {
+ string sqldef = null;
+ using (IDataReader reader = ExecuteQuery(String.Format("SELECT sql FROM sqlite_master WHERE type='table' AND name='{0}'",table)))
+ {
+ if (reader.Read())
+ {
+ sqldef = (string) reader[0];
+ }
+ }
+ return sqldef;
+ }
+
+ public string[] GetColumnNames(string table)
+ {
+ return ParseSqlForColumnNames(GetSqlDefString(table));
+ }
+
+ public string[] GetColumnDefs(string table)
+ {
+ return ParseSqlColumnDefs(GetSqlDefString(table));
+ }
+
+ ///
+ /// Turn something like 'columnName INTEGER NOT NULL' into just 'columnName'
+ ///
+ public string[] ParseSqlForColumnNames(string sqldef)
+ {
+ string[] parts = ParseSqlColumnDefs(sqldef);
+ return ParseSqlForColumnNames(parts);
+ }
+
+ public string[] ParseSqlForColumnNames(string[] parts)
+ {
+ if (null == parts)
+ return null;
+
+ for (int i = 0; i < parts.Length; i ++)
+ {
+ parts[i] = ExtractNameFromColumnDef(parts[i]);
+ }
+ return parts;
+ }
+
+ ///
+ /// Name is the first value before the space.
+ ///
+ ///
+ ///
+ public string ExtractNameFromColumnDef(string columnDef)
+ {
+ int idx = columnDef.IndexOf(" ");
+ if (idx > 0)
+ {
+ return columnDef.Substring(0, idx);
+ }
+ return null;
+ }
+
+ public bool IsNullable(string columnDef)
+ {
+ return ! columnDef.Contains("NOT NULL");
+ }
+
+ public string[] ParseSqlColumnDefs(string sqldef)
+ {
+ if (String.IsNullOrEmpty(sqldef))
+ {
+ return null;
+ }
+
+ sqldef = sqldef.Replace(Environment.NewLine, " ");
+ int start = sqldef.IndexOf("(");
+ int end = sqldef.IndexOf(")");
+
+ sqldef = sqldef.Substring(0, end);
+ sqldef = sqldef.Substring(start + 1);
+
+ string[] cols = sqldef.Split(new char[]{','});
+ for (int i = 0; i < cols.Length; i ++)
+ {
+ cols[i] = cols[i].Trim();
+ }
+ return cols;
+ }
+
+ public bool ColumnMatch(string column, string columnDef)
+ {
+ return columnDef.StartsWith(column + " ") || columnDef.StartsWith(_dialect.Quote(column));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Providers/Impl/SQLite/SQLiteDialect.cs b/Migrator.net/Migrator.Providers/Impl/SQLite/SQLiteDialect.cs
new file mode 100644
index 000000000..0731f79ef
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Impl/SQLite/SQLiteDialect.cs
@@ -0,0 +1,44 @@
+
+using System;
+using System.Data;
+using Migrator.Framework;
+
+namespace Migrator.Providers.SQLite
+{
+ public class SQLiteDialect : Dialect
+ {
+ public SQLiteDialect()
+ {
+ RegisterColumnType(DbType.Binary, "BLOB");
+ RegisterColumnType(DbType.Byte, "INTEGER");
+ RegisterColumnType(DbType.Int16, "INTEGER");
+ RegisterColumnType(DbType.Int32, "INTEGER");
+ RegisterColumnType(DbType.Int64, "INTEGER");
+ RegisterColumnType(DbType.SByte, "INTEGER");
+ RegisterColumnType(DbType.UInt16, "INTEGER");
+ RegisterColumnType(DbType.UInt32, "INTEGER");
+ RegisterColumnType(DbType.UInt64, "INTEGER");
+ RegisterColumnType(DbType.Currency, "NUMERIC");
+ RegisterColumnType(DbType.Decimal, "NUMERIC");
+ RegisterColumnType(DbType.Double, "NUMERIC");
+ RegisterColumnType(DbType.Single, "NUMERIC");
+ RegisterColumnType(DbType.VarNumeric, "NUMERIC");
+ RegisterColumnType(DbType.String, "TEXT");
+ RegisterColumnType(DbType.AnsiStringFixedLength, "TEXT");
+ RegisterColumnType(DbType.StringFixedLength, "TEXT");
+ RegisterColumnType(DbType.DateTime, "DATETIME");
+ RegisterColumnType(DbType.Time, "DATETIME");
+ RegisterColumnType(DbType.Boolean, "INTEGER");
+ RegisterColumnType(DbType.Guid, "UNIQUEIDENTIFIER");
+
+ RegisterProperty(ColumnProperty.Identity, "AUTOINCREMENT");
+ }
+
+ public override Type TransformationProvider { get { return typeof(SQLiteTransformationProvider); } }
+
+ public override bool NeedsNotNullForIdentity
+ {
+ get { return false; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Providers/Impl/SQLite/SQLiteTransformationProvider.cs b/Migrator.net/Migrator.Providers/Impl/SQLite/SQLiteTransformationProvider.cs
new file mode 100644
index 000000000..d4731d218
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Impl/SQLite/SQLiteTransformationProvider.cs
@@ -0,0 +1,232 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using Migrator.Framework;
+using ForeignKeyConstraint=Migrator.Framework.ForeignKeyConstraint;
+#if DOTNET2
+using SqliteConnection=System.Data.SQLite.SQLiteConnection;
+#else
+using Mono.Data.Sqlite;
+#endif
+
+namespace Migrator.Providers.SQLite
+{
+ ///
+ /// Summary description for SQLiteTransformationProvider.
+ ///
+ public class SQLiteTransformationProvider : TransformationProvider
+ {
+ public SQLiteTransformationProvider(Dialect dialect, string connectionString)
+ : base(dialect, connectionString)
+ {
+ _connection = new SqliteConnection(_connectionString);
+ _connection.ConnectionString = _connectionString;
+ _connection.Open();
+ }
+
+ public override void AddForeignKey(string name, string primaryTable, string[] primaryColumns, string refTable,
+ string[] refColumns, ForeignKeyConstraint constraint)
+ {
+ // NOOP Because SQLite doesn't support foreign keys
+ }
+
+ public override void RemoveForeignKey(string name, string table)
+ {
+ // NOOP Because SQLite doesn't support foreign keys
+ }
+
+ public override void RemoveColumn(string table, string column)
+ {
+ if (! (TableExists(table) && ColumnExists(table, column)))
+ return;
+
+ string[] origColDefs = GetColumnDefs(table);
+ List colDefs = new List();
+
+ foreach (string origdef in origColDefs)
+ {
+ if (! ColumnMatch(column, origdef))
+ colDefs.Add(origdef);
+ }
+
+ string[] newColDefs = colDefs.ToArray();
+ string colDefsSql = String.Join(",", newColDefs);
+
+ string[] colNames = ParseSqlForColumnNames(newColDefs);
+ string colNamesSql = String.Join(",", colNames);
+
+ AddTable(table + "_temp", null, colDefsSql);
+ ExecuteQuery(String.Format("INSERT INTO {0}_temp SELECT {1} FROM {0}", table, colNamesSql));
+ RemoveTable(table);
+ ExecuteQuery(String.Format("ALTER TABLE {0}_temp RENAME TO {0}", table));
+ }
+
+ public override void RenameColumn(string tableName, string oldColumnName, string newColumnName)
+ {
+ if (ColumnExists(tableName, newColumnName))
+ throw new MigrationException(String.Format("Table '{0}' has column named '{1}' already", tableName, newColumnName));
+
+ if (ColumnExists(tableName, oldColumnName))
+ {
+ string[] columnDefs = GetColumnDefs(tableName);
+ string columnDef = Array.Find(columnDefs, delegate(string col) { return ColumnMatch(oldColumnName, col); });
+
+ string newColumnDef = columnDef.Replace(oldColumnName, newColumnName);
+
+ AddColumn(tableName, newColumnDef);
+ ExecuteQuery(String.Format("UPDATE {0} SET {1}={2}", tableName, newColumnName, oldColumnName));
+ RemoveColumn(tableName, oldColumnName);
+ }
+ }
+
+ public override void ChangeColumn(string table, Column column)
+ {
+ if (! ColumnExists(table, column.Name))
+ {
+ Logger.Warn("Column {0}.{1} does not exist", table, column.Name);
+ return;
+ }
+
+ string tempColumn = "temp_" + column.Name;
+ RenameColumn(table, column.Name, tempColumn);
+ AddColumn(table, column);
+ ExecuteQuery(String.Format("UPDATE {0} SET {1}={2}", table, column.Name, tempColumn));
+ RemoveColumn(table, tempColumn);
+ }
+
+ public override bool TableExists(string table)
+ {
+ using (IDataReader reader =
+ ExecuteQuery(String.Format("SELECT name FROM sqlite_master WHERE type='table' and name='{0}'",table)))
+ {
+ return reader.Read();
+ }
+ }
+
+ public override bool ConstraintExists(string table, string name)
+ {
+ return false;
+ }
+
+ public override string[] GetTables()
+ {
+ List tables = new List();
+
+ using (IDataReader reader = ExecuteQuery("SELECT name FROM sqlite_master WHERE type='table' AND name <> 'sqlite_sequence' ORDER BY name"))
+ {
+ while (reader.Read())
+ {
+ tables.Add((string) reader[0]);
+ }
+ }
+
+ return tables.ToArray();
+ }
+
+ public override Column[] GetColumns(string table)
+ {
+ List columns = new List();
+ foreach (string columnDef in GetColumnDefs(table))
+ {
+ string name = ExtractNameFromColumnDef(columnDef);
+ // FIXME: Need to get the real type information
+ Column column = new Column(name, DbType.String);
+ bool isNullable = IsNullable(columnDef);
+ column.ColumnProperty |= isNullable ? ColumnProperty.Null : ColumnProperty.NotNull;
+ columns.Add(column);
+ }
+ return columns.ToArray();
+ }
+
+ public string GetSqlDefString(string table)
+ {
+ string sqldef = null;
+ using (IDataReader reader = ExecuteQuery(String.Format("SELECT sql FROM sqlite_master WHERE type='table' AND name='{0}'",table)))
+ {
+ if (reader.Read())
+ {
+ sqldef = (string) reader[0];
+ }
+ }
+ return sqldef;
+ }
+
+ public string[] GetColumnNames(string table)
+ {
+ return ParseSqlForColumnNames(GetSqlDefString(table));
+ }
+
+ public string[] GetColumnDefs(string table)
+ {
+ return ParseSqlColumnDefs(GetSqlDefString(table));
+ }
+
+ ///
+ /// Turn something like 'columnName INTEGER NOT NULL' into just 'columnName'
+ ///
+ public string[] ParseSqlForColumnNames(string sqldef)
+ {
+ string[] parts = ParseSqlColumnDefs(sqldef);
+ return ParseSqlForColumnNames(parts);
+ }
+
+ public string[] ParseSqlForColumnNames(string[] parts)
+ {
+ if (null == parts)
+ return null;
+
+ for (int i = 0; i < parts.Length; i ++)
+ {
+ parts[i] = ExtractNameFromColumnDef(parts[i]);
+ }
+ return parts;
+ }
+
+ ///
+ /// Name is the first value before the space.
+ ///
+ ///
+ ///
+ public string ExtractNameFromColumnDef(string columnDef)
+ {
+ int idx = columnDef.IndexOf(" ");
+ if (idx > 0)
+ {
+ return columnDef.Substring(0, idx);
+ }
+ return null;
+ }
+
+ public bool IsNullable(string columnDef)
+ {
+ return ! columnDef.Contains("NOT NULL");
+ }
+
+ public string[] ParseSqlColumnDefs(string sqldef)
+ {
+ if (String.IsNullOrEmpty(sqldef))
+ {
+ return null;
+ }
+
+ sqldef = sqldef.Replace(Environment.NewLine, " ");
+ int start = sqldef.IndexOf("(");
+ int end = sqldef.LastIndexOf(")");
+
+ sqldef = sqldef.Substring(0, end);
+ sqldef = sqldef.Substring(start + 1);
+
+ string[] cols = sqldef.Split(new char[]{','});
+ for (int i = 0; i < cols.Length; i ++)
+ {
+ cols[i] = cols[i].Trim();
+ }
+ return cols;
+ }
+
+ public bool ColumnMatch(string column, string columnDef)
+ {
+ return columnDef.StartsWith(column + " ") || columnDef.StartsWith(_dialect.Quote(column));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Providers/Migrator.Providers.csproj b/Migrator.net/Migrator.Providers/Migrator.Providers.csproj
new file mode 100644
index 000000000..b6290d3c2
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/Migrator.Providers.csproj
@@ -0,0 +1,118 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}
+ Library
+ Migrator.Providers
+ Migrator.Providers
+
+
+ 3.5
+
+
+ false
+ true
+ MigratorDotNet.snk
+ v2.0
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ TRACE;DEBUG;DOTNET2
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+ ..\..\NzbDrone.Core\Libraries\System.Data.SQLite.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 2.0 %28x86%29
+ true
+
+
+ False
+ .NET Framework 3.0 %28x86%29
+ false
+
+
+ False
+ .NET Framework 3.5
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}
+ Migrator.Framework
+
+
+
+
+
\ No newline at end of file
diff --git a/Migrator.net/Migrator.Providers/MigratorDotNet.snk b/Migrator.net/Migrator.Providers/MigratorDotNet.snk
new file mode 100644
index 000000000..5032d709b
Binary files /dev/null and b/Migrator.net/Migrator.Providers/MigratorDotNet.snk differ
diff --git a/Migrator.net/Migrator.Providers/NoOpTransformationProvider.cs b/Migrator.net/Migrator.Providers/NoOpTransformationProvider.cs
new file mode 100644
index 000000000..48f666658
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/NoOpTransformationProvider.cs
@@ -0,0 +1,336 @@
+using System.Data;
+using Migrator.Framework;
+using ForeignKeyConstraint=Migrator.Framework.ForeignKeyConstraint;
+using System.Collections.Generic;
+
+namespace Migrator.Providers
+{
+ ///
+ /// No Op (Null Object Pattern) implementation of the ITransformationProvider
+ ///
+ public class NoOpTransformationProvider : ITransformationProvider
+ {
+
+ public static readonly NoOpTransformationProvider Instance = new NoOpTransformationProvider();
+
+ private NoOpTransformationProvider()
+ {
+
+ }
+
+ public virtual ILogger Logger
+ {
+ get { return null; }
+ set { }
+ }
+
+ public Dialect Dialect
+ {
+ get { return null; }
+ }
+
+ public string[] GetTables()
+ {
+ return null;
+ }
+
+ public Column[] GetColumns(string table)
+ {
+ return null;
+ }
+
+ public Column GetColumnByName(string table, string column)
+ {
+ return null;
+ }
+
+ public void RemoveForeignKey(string table, string name)
+ {
+ // No Op
+ }
+
+ public void RemoveConstraint(string table, string name)
+ {
+ // No Op
+ }
+
+ public void AddTable(string name, params Column[] columns)
+ {
+ // No Op
+ }
+
+ public void AddTable(string name, string engine, params Column[] columns)
+ {
+ // No Op
+ }
+
+ public void RemoveTable(string name)
+ {
+ // No Op
+ }
+
+ public void RenameTable(string oldName, string newName)
+ {
+ // No Op
+ }
+
+ public void RenameColumn(string tableName, string oldColumnName, string newColumnName)
+ {
+ // No Op
+ }
+
+ public void AddColumn(string table, string sqlColumn)
+ {
+ // No Op
+ }
+
+ public void RemoveColumn(string table, string column)
+ {
+ // No Op
+ }
+
+ public bool ColumnExists(string table, string column)
+ {
+ return false;
+ }
+
+ public bool TableExists(string table)
+ {
+ return false;
+ }
+
+ public void AddColumn(string table, string column, DbType type, int size, ColumnProperty property, object defaultValue)
+ {
+ // No Op
+ }
+
+ public void AddColumn(string table, string column, DbType type)
+ {
+ // No Op
+ }
+
+ public void AddColumn(string table, string column, DbType type, object defaultValue)
+ {
+ // No Op
+ }
+
+ public void AddColumn(string table, string column, DbType type, int size)
+ {
+ // No Op
+ }
+
+ public void AddColumn(string table, string column, DbType type, ColumnProperty property)
+ {
+ // No Op
+ }
+
+ public void AddColumn(string table, string column, DbType type, int size, ColumnProperty property)
+ {
+ // No Op
+ }
+
+ public void AddPrimaryKey(string name, string table, params string[] columns)
+ {
+ // No Op
+ }
+
+ public void GenerateForeignKey(string primaryTable, string primaryColumn, string refTable, string refColumn)
+ {
+ // No Op
+ }
+
+ public void GenerateForeignKey(string primaryTable, string[] primaryColumns, string refTable, string[] refColumns)
+ {
+ // No Op
+ }
+
+ public void GenerateForeignKey(string primaryTable, string primaryColumn, string refTable, string refColumn, ForeignKeyConstraint constraint)
+ {
+ // No Op
+ }
+
+ public void GenerateForeignKey(string primaryTable, string[] primaryColumns, string refTable,
+ string[] refColumns, ForeignKeyConstraint constraint)
+ {
+ // No Op
+ }
+
+ public void AddForeignKey(string name, string primaryTable, string primaryColumn, string refTable,
+ string refColumn)
+ {
+ // No Op
+ }
+
+ public void AddForeignKey(string name, string primaryTable, string[] primaryColumns, string refTable, string[] refColumns)
+ {
+ // No Op
+ }
+
+ public void AddForeignKey(string name, string primaryTable, string primaryColumn, string refTable, string refColumn, ForeignKeyConstraint constraint)
+ {
+ // No Op
+ }
+
+ public void AddForeignKey(string name, string primaryTable, string[] primaryColumns, string refTable,
+ string[] refColumns, ForeignKeyConstraint constraint)
+ {
+ // No Op
+ }
+
+ public void AddUniqueConstraint(string name, string table, params string[] columns)
+ {
+ // No Op
+ }
+
+ public void AddCheckConstraint(string name, string table, string checkSql)
+ {
+ // No Op
+ }
+
+ public bool ConstraintExists(string table, string name)
+ {
+ return false;
+ }
+
+ public void ChangeColumn(string table, Column column)
+ {
+ // No Op
+ }
+
+
+ public bool PrimaryKeyExists(string table, string name)
+ {
+ return false;
+ }
+
+ public int ExecuteNonQuery(string sql)
+ {
+ return 0;
+ }
+
+ public IDataReader ExecuteQuery(string sql)
+ {
+ return null;
+ }
+
+ public object ExecuteScalar(string sql)
+ {
+ return null;
+ }
+
+ public IDataReader Select(string what, string from)
+ {
+ return null;
+ }
+
+ public IDataReader Select(string what, string from, string where)
+ {
+ return null;
+ }
+
+ public object SelectScalar(string what, string from)
+ {
+ return null;
+ }
+
+ public object SelectScalar(string what, string from, string where)
+ {
+ return null;
+ }
+
+ public int Update(string table, string[] columns, string[] columnValues)
+ {
+ return 0;
+ }
+
+ public int Update(string table, string[] columns, string[] columnValues, string where)
+ {
+ return 0;
+ }
+
+ public int Insert(string table, string[] columns, string[] columnValues)
+ {
+ return 0;
+ }
+
+ public int Delete(string table, string[] columns, string[] columnValues)
+ {
+ return 0;
+ }
+
+ public int Delete(string table, string column, string value)
+ {
+ return 0;
+ }
+
+ public void BeginTransaction()
+ {
+ // No Op
+ }
+
+ public void Rollback()
+ {
+ // No Op
+ }
+
+ public void Commit()
+ {
+ // No Op
+ }
+
+ public ITransformationProvider this[string provider]
+ {
+ get { return this; }
+ }
+
+ public void MigrationApplied(long version)
+ {
+ //no op
+ }
+
+ public void MigrationUnApplied(long version)
+ {
+ //no op
+ }
+
+ public List AppliedMigrations
+ {
+ get { return new List(); }
+ }
+
+ protected void CreateSchemaInfoTable()
+ {
+
+ }
+
+ public void AddColumn(string table, Column column)
+ {
+ // No Op
+ }
+
+ public void GenerateForeignKey(string primaryTable, string refTable)
+ {
+ // No Op
+ }
+
+ public void GenerateForeignKey(string primaryTable, string refTable, ForeignKeyConstraint constraint)
+ {
+ // No Op
+ }
+
+ public IDbCommand GetCommand()
+ {
+ return null;
+ }
+
+ public void ExecuteSchemaBuilder(Migrator.Framework.SchemaBuilder.SchemaBuilder schemaBuilder)
+ {
+ // No Op
+ }
+
+ public void Dispose()
+ {
+ //No Op
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Providers/TransformationProvider.cs b/Migrator.net/Migrator.Providers/TransformationProvider.cs
new file mode 100644
index 000000000..964780746
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/TransformationProvider.cs
@@ -0,0 +1,853 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using Migrator.Framework;
+using Migrator.Framework.SchemaBuilder;
+using ForeignKeyConstraint = Migrator.Framework.ForeignKeyConstraint;
+using Migrator.Framework.Loggers;
+
+namespace Migrator.Providers
+{
+ ///
+ /// Base class for every transformation providers.
+ /// A 'tranformation' is an operation that modifies the database.
+ ///
+ public abstract class TransformationProvider : ITransformationProvider
+ {
+ private ILogger _logger;
+ protected IDbConnection _connection;
+ private IDbTransaction _transaction;
+ private List _appliedMigrations;
+
+ protected readonly string _connectionString;
+ protected Dialect _dialect;
+
+ private readonly ForeignKeyConstraintMapper constraintMapper = new ForeignKeyConstraintMapper();
+
+ protected TransformationProvider(Dialect dialect, string connectionString)
+ {
+ _dialect = dialect;
+ _connectionString = connectionString;
+ _logger = new Logger(false);
+ }
+
+ ///
+ /// Returns the event logger
+ ///
+ public virtual ILogger Logger
+ {
+ get { return _logger; }
+ set { _logger = value; }
+ }
+
+ public Dialect Dialect
+ {
+ get { return _dialect; }
+ }
+
+ public ITransformationProvider this[string provider]
+ {
+ get
+ {
+ if (null != provider && IsThisProvider(provider))
+ return this;
+
+ return NoOpTransformationProvider.Instance;
+ }
+ }
+
+ public bool IsThisProvider(string provider)
+ {
+ // XXX: This might need to be more sophisticated. Currently just a convention
+ return GetType().Name.ToLower().StartsWith(provider.ToLower());
+ }
+
+ public virtual Column[] GetColumns(string table)
+ {
+ List columns = new List();
+ using (
+ IDataReader reader =
+ ExecuteQuery(
+ String.Format("select COLUMN_NAME, IS_NULLABLE from information_schema.columns where table_name = '{0}'", table)))
+ {
+ while (reader.Read())
+ {
+ Column column = new Column(reader.GetString(0), DbType.String);
+ string nullableStr = reader.GetString(1);
+ bool isNullable = nullableStr == "YES";
+ column.ColumnProperty |= isNullable ? ColumnProperty.Null : ColumnProperty.NotNull;
+
+ columns.Add(column);
+ }
+ }
+
+ return columns.ToArray();
+ }
+
+ public virtual Column GetColumnByName(string table, string columnName)
+ {
+ return Array.Find(GetColumns(table),
+ delegate(Column column)
+ {
+ return column.Name == columnName;
+ });
+ }
+
+ public virtual string[] GetTables()
+ {
+ List tables = new List();
+ using (IDataReader reader = ExecuteQuery("SELECT table_name FROM information_schema.tables"))
+ {
+ while (reader.Read())
+ {
+ tables.Add((string)reader[0]);
+ }
+ }
+ return tables.ToArray();
+ }
+
+ public virtual void RemoveForeignKey(string table, string name)
+ {
+ RemoveConstraint(table, name);
+ }
+
+ public virtual void RemoveConstraint(string table, string name)
+ {
+ if (TableExists(table) && ConstraintExists(table, name))
+ {
+ table = _dialect.TableNameNeedsQuote ? _dialect.Quote(table) : table;
+ name = _dialect.ConstraintNameNeedsQuote ? _dialect.Quote(name) : name;
+ ExecuteNonQuery(String.Format("ALTER TABLE {0} DROP CONSTRAINT {1}", table, name));
+ }
+ }
+
+ public virtual void AddTable(string table, string engine, string columns)
+ {
+ table = _dialect.TableNameNeedsQuote ? _dialect.Quote(table) : table;
+ string sqlCreate = String.Format("CREATE TABLE {0} ({1})", table, columns);
+ ExecuteNonQuery(sqlCreate);
+ }
+
+ ///
+ /// Add a new table
+ ///
+ /// Table name
+ /// Columns
+ ///
+ /// Adds the Test table with two columns:
+ ///
+ /// Database.AddTable("Test",
+ /// new Column("Id", typeof(int), ColumnProperty.PrimaryKey),
+ /// new Column("Title", typeof(string), 100)
+ /// );
+ ///
+ ///
+ public virtual void AddTable(string name, params Column[] columns)
+ {
+ // Most databases don't have the concept of a storage engine, so default is to not use it.
+ AddTable(name, null, columns);
+ }
+
+ ///
+ /// Add a new table
+ ///
+ /// Table name
+ /// Columns
+ /// the database storage engine to use
+ ///
+ /// Adds the Test table with two columns:
+ ///
+ /// Database.AddTable("Test", "INNODB",
+ /// new Column("Id", typeof(int), ColumnProperty.PrimaryKey),
+ /// new Column("Title", typeof(string), 100)
+ /// );
+ ///
+ ///
+ public virtual void AddTable(string name, string engine, params Column[] columns)
+ {
+
+ if (TableExists(name))
+ {
+ Logger.Warn("Table {0} already exists", name);
+ return;
+ }
+
+ List pks = GetPrimaryKeys(columns);
+ bool compoundPrimaryKey = pks.Count > 1;
+
+ List columnProviders = new List(columns.Length);
+ foreach (Column column in columns)
+ {
+ // Remove the primary key notation if compound primary key because we'll add it back later
+ if (compoundPrimaryKey && column.IsPrimaryKey)
+ column.ColumnProperty = ColumnProperty.Unsigned | ColumnProperty.NotNull;
+
+ ColumnPropertiesMapper mapper = _dialect.GetAndMapColumnProperties(column);
+ columnProviders.Add(mapper);
+ }
+
+ string columnsAndIndexes = JoinColumnsAndIndexes(columnProviders);
+ AddTable(name, engine, columnsAndIndexes);
+
+ if (compoundPrimaryKey)
+ {
+ AddPrimaryKey(String.Format("PK_{0}", name), name, pks.ToArray());
+ }
+ }
+
+ public List GetPrimaryKeys(IEnumerable columns)
+ {
+ List pks = new List();
+ foreach (Column col in columns)
+ {
+ if (col.IsPrimaryKey)
+ pks.Add(col.Name);
+ }
+ return pks;
+ }
+
+ public virtual void RemoveTable(string name)
+ {
+ if (TableExists(name))
+ ExecuteNonQuery(String.Format("DROP TABLE {0}", name));
+ }
+
+ public virtual void RenameTable(string oldName, string newName)
+ {
+ if (TableExists(newName))
+ throw new MigrationException(String.Format("Table with name '{0}' already exists", newName));
+
+ if (TableExists(oldName))
+ ExecuteNonQuery(String.Format("ALTER TABLE {0} RENAME TO {1}", oldName, newName));
+ }
+
+ public virtual void RenameColumn(string tableName, string oldColumnName, string newColumnName)
+ {
+ if (ColumnExists(tableName, newColumnName))
+ throw new MigrationException(String.Format("Table '{0}' has column named '{1}' already", tableName, newColumnName));
+
+ if (ColumnExists(tableName, oldColumnName))
+ ExecuteNonQuery(String.Format("ALTER TABLE {0} RENAME COLUMN {1} TO {2}", tableName, oldColumnName, newColumnName));
+ }
+
+ public virtual void AddColumn(string table, string sqlColumn)
+ {
+ ExecuteNonQuery(String.Format("ALTER TABLE {0} ADD COLUMN {1}", table, sqlColumn));
+ }
+
+ public virtual void RemoveColumn(string table, string column)
+ {
+ if (ColumnExists(table, column))
+ {
+ ExecuteNonQuery(String.Format("ALTER TABLE {0} DROP COLUMN {1} ", table, column));
+ }
+ }
+
+ public virtual bool ColumnExists(string table, string column)
+ {
+ try
+ {
+ ExecuteNonQuery(String.Format("SELECT {0} FROM {1}", column, table));
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
+ public virtual void ChangeColumn(string table, Column column)
+ {
+ if (!ColumnExists(table, column.Name))
+ {
+ Logger.Warn("Column {0}.{1} does not exist", table, column.Name);
+ return;
+ }
+
+ ColumnPropertiesMapper mapper = _dialect.GetAndMapColumnProperties(column);
+ ChangeColumn(table, mapper.ColumnSql);
+ }
+
+ public virtual void ChangeColumn(string table, string sqlColumn)
+ {
+ ExecuteNonQuery(String.Format("ALTER TABLE {0} ALTER COLUMN {1}", table, sqlColumn));
+ }
+
+ public virtual bool TableExists(string table)
+ {
+ try
+ {
+ ExecuteNonQuery("SELECT COUNT(*) FROM " + table);
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
+ protected virtual string JoinColumnsAndIndexes(IEnumerable columns)
+ {
+ string indexes = JoinIndexes(columns);
+ string columnsAndIndexes = JoinColumns(columns) + (indexes != null ? "," + indexes : String.Empty);
+ return columnsAndIndexes;
+ }
+
+ protected virtual string JoinIndexes(IEnumerable columns)
+ {
+ List indexes = new List();
+ foreach (ColumnPropertiesMapper column in columns)
+ {
+ string indexSql = column.IndexSql;
+ if (indexSql != null)
+ indexes.Add(indexSql);
+ }
+
+ if (indexes.Count == 0)
+ return null;
+
+ return String.Join(", ", indexes.ToArray());
+ }
+
+ protected virtual string JoinColumns(IEnumerable columns)
+ {
+ List columnStrings = new List();
+ foreach (ColumnPropertiesMapper column in columns)
+ columnStrings.Add(column.ColumnSql);
+ return String.Join(", ", columnStrings.ToArray());
+ }
+
+ ///
+ /// Add a new column to an existing table.
+ ///
+ /// Table to which to add the column
+ /// Column name
+ /// Date type of the column
+ /// Max length of the column
+ /// Properties of the column, see ColumnProperty,
+ /// Default value
+ public virtual void AddColumn(string table, string column, DbType type, int size, ColumnProperty property,
+ object defaultValue)
+ {
+ if (ColumnExists(table, column))
+ {
+ Logger.Warn("Column {0}.{1} already exists", table, column);
+ return;
+ }
+
+ ColumnPropertiesMapper mapper =
+ _dialect.GetAndMapColumnProperties(new Column(column, type, size, property, defaultValue));
+
+ AddColumn(table, mapper.ColumnSql);
+ }
+
+ ///
+ ///
+ /// AddColumn(string, string, Type, int, ColumnProperty, object)
+ ///
+ ///
+ public virtual void AddColumn(string table, string column, DbType type)
+ {
+ AddColumn(table, column, type, 0, ColumnProperty.Null, null);
+ }
+
+ ///
+ ///
+ /// AddColumn(string, string, Type, int, ColumnProperty, object)
+ ///
+ ///
+ public virtual void AddColumn(string table, string column, DbType type, int size)
+ {
+ AddColumn(table, column, type, size, ColumnProperty.Null, null);
+ }
+
+ public void AddColumn(string table, string column, DbType type, object defaultValue)
+ {
+ if (ColumnExists(table, column))
+ {
+ Logger.Warn("Column {0}.{1} already exists", table, column);
+ return;
+ }
+
+ ColumnPropertiesMapper mapper =
+ _dialect.GetAndMapColumnProperties(new Column(column, type, defaultValue));
+
+ AddColumn(table, mapper.ColumnSql);
+
+ }
+
+ ///
+ ///
+ /// AddColumn(string, string, Type, int, ColumnProperty, object)
+ ///
+ ///
+ public virtual void AddColumn(string table, string column, DbType type, ColumnProperty property)
+ {
+ AddColumn(table, column, type, 0, property, null);
+ }
+
+ ///
+ ///
+ /// AddColumn(string, string, Type, int, ColumnProperty, object)
+ ///
+ ///
+ public virtual void AddColumn(string table, string column, DbType type, int size, ColumnProperty property)
+ {
+ AddColumn(table, column, type, size, property, null);
+ }
+
+ ///
+ /// Append a primary key to a table.
+ ///
+ /// Constraint name
+ /// Table name
+ /// Primary column names
+ public virtual void AddPrimaryKey(string name, string table, params string[] columns)
+ {
+ if (ConstraintExists(table, name))
+ {
+ Logger.Warn("Primary key {0} already exists", name);
+ return;
+ }
+ ExecuteNonQuery(
+ String.Format("ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY ({2}) ", table, name,
+ String.Join(",", columns)));
+ }
+
+ public virtual void AddUniqueConstraint(string name, string table, params string[] columns)
+ {
+ if (ConstraintExists(table, name))
+ {
+ Logger.Warn("Constraint {0} already exists", name);
+ return;
+ }
+ ExecuteNonQuery(String.Format("ALTER TABLE {0} ADD CONSTRAINT {1} UNIQUE({2}) ", table, name, string.Join(", ", columns)));
+ }
+
+ public virtual void AddCheckConstraint(string name, string table, string checkSql)
+ {
+ if (ConstraintExists(table, name))
+ {
+ Logger.Warn("Constraint {0} already exists", name);
+ return;
+ }
+ ExecuteNonQuery(String.Format("ALTER TABLE {0} ADD CONSTRAINT {1} CHECK ({2}) ", table, name, checkSql));
+ }
+
+ ///
+ /// Guesses the name of the foreign key and add it
+ ///
+ public virtual void GenerateForeignKey(string primaryTable, string primaryColumn, string refTable, string refColumn)
+ {
+ AddForeignKey("FK_" + primaryTable + "_" + refTable, primaryTable, primaryColumn, refTable, refColumn);
+ }
+
+ ///
+ /// Guesses the name of the foreign key and add it
+ ///
+ ///
+ public virtual void GenerateForeignKey(string primaryTable, string[] primaryColumns, string refTable,
+ string[] refColumns)
+ {
+ AddForeignKey("FK_" + primaryTable + "_" + refTable, primaryTable, primaryColumns, refTable, refColumns);
+ }
+
+ ///
+ /// Guesses the name of the foreign key and add it
+ ///
+ public virtual void GenerateForeignKey(string primaryTable, string primaryColumn, string refTable,
+ string refColumn, ForeignKeyConstraint constraint)
+ {
+ AddForeignKey("FK_" + primaryTable + "_" + refTable, primaryTable, primaryColumn, refTable, refColumn,
+ constraint);
+ }
+
+ ///
+ /// Guesses the name of the foreign key and add it
+ ///
+ ///
+ public virtual void GenerateForeignKey(string primaryTable, string[] primaryColumns, string refTable,
+ string[] refColumns, ForeignKeyConstraint constraint)
+ {
+ AddForeignKey("FK_" + primaryTable + "_" + refTable, primaryTable, primaryColumns, refTable, refColumns,
+ constraint);
+ }
+
+ ///
+ /// Append a foreign key (relation) between two tables.
+ /// tables.
+ ///
+ /// Constraint name
+ /// Table name containing the primary key
+ /// Primary key column name
+ /// Foreign table name
+ /// Foreign column name
+ public virtual void AddForeignKey(string name, string primaryTable, string primaryColumn, string refTable,
+ string refColumn)
+ {
+ AddForeignKey(name, primaryTable, new string[] { primaryColumn }, refTable, new string[] { refColumn });
+ }
+
+ ///
+ ///
+ /// AddForeignKey(string, string, string, string, string)
+ ///
+ ///
+ public virtual void AddForeignKey(string name, string primaryTable, string[] primaryColumns, string refTable, string[] refColumns)
+ {
+ AddForeignKey(name, primaryTable, primaryColumns, refTable, refColumns, ForeignKeyConstraint.NoAction);
+ }
+
+ public virtual void AddForeignKey(string name, string primaryTable, string primaryColumn, string refTable, string refColumn, ForeignKeyConstraint constraint)
+ {
+ AddForeignKey(name, primaryTable, new string[] { primaryColumn }, refTable, new string[] { refColumn },
+ constraint);
+ }
+
+ public virtual void AddForeignKey(string name, string primaryTable, string[] primaryColumns, string refTable,
+ string[] refColumns, ForeignKeyConstraint constraint)
+ {
+ if (ConstraintExists(primaryTable, name))
+ {
+ Logger.Warn("Constraint {0} already exists", name);
+ return;
+ }
+
+ string constraintResolved = constraintMapper.SqlForConstraint(constraint);
+ ExecuteNonQuery(
+ String.Format(
+ "ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}) ON UPDATE {5} ON DELETE {6}",
+ primaryTable, name, String.Join(",", primaryColumns),
+ refTable, String.Join(",", refColumns), constraintResolved, constraintResolved));
+ }
+
+ ///
+ /// Determines if a constraint exists.
+ ///
+ /// Constraint name
+ /// Table owning the constraint
+ /// true if the constraint exists.
+ public abstract bool ConstraintExists(string table, string name);
+
+ public virtual bool PrimaryKeyExists(string table, string name)
+ {
+ return ConstraintExists(table, name);
+ }
+
+ public int ExecuteNonQuery(string sql)
+ {
+ Logger.Trace(sql);
+ Logger.ApplyingDBChange(sql);
+ using (IDbCommand cmd = BuildCommand(sql))
+ {
+ try
+ {
+ return cmd.ExecuteNonQuery();
+ }
+ catch (Exception ex)
+ {
+ Logger.Warn(ex.Message);
+ throw;
+ }
+ }
}
+
+ private IDbCommand BuildCommand(string sql)
+ {
+ IDbCommand cmd = _connection.CreateCommand();
+ cmd.CommandText = sql;
+ cmd.CommandType = CommandType.Text;
+ if (_transaction != null)
+ {
+ cmd.Transaction = _transaction;
+ }
+ return cmd;
+ }
+
+ ///
+ /// Execute an SQL query returning results.
+ ///
+ /// The SQL command.
+ /// A data iterator, IDataReader.
+ public IDataReader ExecuteQuery(string sql)
+ {
+ Logger.Trace(sql);
+ using (IDbCommand cmd = BuildCommand(sql))
+ {
+ try
+ {
+ return cmd.ExecuteReader();
+ }
+ catch
+ {
+ Logger.Warn("query failed: {0}", cmd.CommandText);
+ throw;
+ }
+ }
}
+
+ public object ExecuteScalar(string sql)
+ {
+ Logger.Trace(sql);
+ using (IDbCommand cmd = BuildCommand(sql))
+ {
+ try
+ {
+ return cmd.ExecuteScalar();
+ }
+ catch
+ {
+ Logger.Warn("Query failed: {0}", cmd.CommandText);
+ throw;
+ }
+ }
}
+
+ public IDataReader Select(string what, string from)
+ {
+ return Select(what, from, "1=1");
+ }
+
+ public virtual IDataReader Select(string what, string from, string where)
+ {
+ return ExecuteQuery(String.Format("SELECT {0} FROM {1} WHERE {2}", what, from, where));
+ }
+
+ public object SelectScalar(string what, string from)
+ {
+ return SelectScalar(what, from, "1=1");
+ }
+
+ public virtual object SelectScalar(string what, string from, string where)
+ {
+ return ExecuteScalar(String.Format("SELECT {0} FROM {1} WHERE {2}", what, from, where));
+ }
+
+ public virtual int Update(string table, string[] columns, string[] values)
+ {
+ return Update(table, columns, values, null);
+ }
+
+ public virtual int Update(string table, string[] columns, string[] values, string where)
+ {
+ string namesAndValues = JoinColumnsAndValues(columns, values);
+
+ string query = "UPDATE {0} SET {1}";
+ if (!String.IsNullOrEmpty(where))
+ {
+ query += " WHERE " + where;
+ }
+
+ return ExecuteNonQuery(String.Format(query, table, namesAndValues));
+ }
+
+ public virtual int Insert(string table, string[] columns, string[] values)
+ {
+ return ExecuteNonQuery(String.Format("INSERT INTO {0} ({1}) VALUES ({2})", table, String.Join(", ", columns), String.Join(", ", QuoteValues(values))));
+ }
+
+ public virtual int Delete(string table)
+ {
+ return Delete(table, (string[])null, (string[]) null);
+ }
+
+ public virtual int Delete(string table, string[] columns, string[] values)
+ {
+ if (null == columns || null == values)
+ {
+ return ExecuteNonQuery(String.Format("DELETE FROM {0}", table));
+ }
+ else
+ {
+ return ExecuteNonQuery(String.Format("DELETE FROM {0} WHERE ({1})", table, JoinColumnsAndValues(columns, values)));
+ }
+ }
+
+ public virtual int Delete(string table, string wherecolumn, string wherevalue)
+ {
+ return ExecuteNonQuery(String.Format("DELETE FROM {0} WHERE {1} = {2}", table, wherecolumn, QuoteValues(wherevalue)));
+ }
+
+ ///
+ /// Starts a transaction. Called by the migration mediator.
+ ///
+ public void BeginTransaction()
+ {
+ if (_transaction == null && _connection != null)
+ {
+ EnsureHasConnection();
+ _transaction = _connection.BeginTransaction(IsolationLevel.ReadCommitted);
+ }
+ }
+
+ protected void EnsureHasConnection()
+ {
+ if (_connection.State != ConnectionState.Open)
+ {
+ _connection.Open();
+ }
+ }
+
+ ///
+ /// Rollback the current migration. Called by the migration mediator.
+ ///
+ public virtual void Rollback()
+ {
+ if (_transaction != null && _connection != null && _connection.State == ConnectionState.Open)
+ {
+ try
+ {
+ _transaction.Rollback();
+ }
+ finally
+ {
+ _connection.Close();
+ }
+ }
+ _transaction = null;
+ }
+
+ ///
+ /// Commit the current transaction. Called by the migrations mediator.
+ ///
+ public void Commit()
+ {
+ if (_transaction != null && _connection != null && _connection.State == ConnectionState.Open)
+ {
+ try
+ {
+ _transaction.Commit();
+ }
+ finally
+ {
+ _connection.Close();
+ }
+ }
+ _transaction = null;
+ }
+
+ ///
+ /// The list of Migrations currently applied to the database.
+ ///
+ public List AppliedMigrations
+ {
+ get
+ {
+ if(_appliedMigrations == null)
+ {
+ _appliedMigrations = new List();
+ CreateSchemaInfoTable();
+ using(IDataReader reader = Select("version","SchemaInfo")){
+ while(reader.Read()){
+ _appliedMigrations.Add(Convert.ToInt64(reader.GetValue(0)));
+ }
+ }
+ }
+ return _appliedMigrations;
+ }
+ }
+
+ ///
+ /// Marks a Migration version number as having been applied
+ ///
+ /// The version number of the migration that was applied
+ public void MigrationApplied(long version)
+ {
+ CreateSchemaInfoTable();
+ Insert("SchemaInfo",new string[]{"version"},new string[]{version.ToString()});
+ _appliedMigrations.Add(version);
+ }
+
+ ///
+ /// Marks a Migration version number as having been rolled back from the database
+ ///
+ /// The version number of the migration that was removed
+ public void MigrationUnApplied(long version)
+ {
+ CreateSchemaInfoTable();
+ Delete("SchemaInfo", "version", version.ToString());
+ _appliedMigrations.Remove(version);
+ }
+
+ protected void CreateSchemaInfoTable()
+ {
+ EnsureHasConnection();
+ if (!TableExists("SchemaInfo"))
+ {
+ AddTable("SchemaInfo", new Column("Version", DbType.Int64, ColumnProperty.PrimaryKey));
+ }
+ }
+
+ public void AddColumn(string table, Column column)
+ {
+ AddColumn(table, column.Name, column.Type, column.Size, column.ColumnProperty, column.DefaultValue);
+ }
+
+ public void GenerateForeignKey(string primaryTable, string refTable)
+ {
+ GenerateForeignKey(primaryTable, refTable, ForeignKeyConstraint.NoAction);
+ }
+
+ public void GenerateForeignKey(string primaryTable, string refTable, ForeignKeyConstraint constraint)
+ {
+ GenerateForeignKey(primaryTable, refTable + "Id", refTable, "Id", constraint);
+ }
+
+ public IDbCommand GetCommand()
+ {
+ return BuildCommand(null);
+ }
+
+ public void ExecuteSchemaBuilder(SchemaBuilder builder)
+ {
+ foreach (ISchemaBuilderExpression expr in builder.Expressions)
+ expr.Create(this);
+ }
+
+ public virtual string QuoteValues(string values)
+ {
+ return QuoteValues(new string[] {values})[0];
+ }
+
+ public virtual string[] QuoteValues(string[] values)
+ {
+ return Array.ConvertAll(values,
+ delegate(string val) {
+ if (null == val)
+ return "null";
+ else
+ return String.Format("'{0}'", val.Replace("'", "''"));
+ });
+ }
+
+ public string JoinColumnsAndValues(string[] columns, string[] values)
+ {
+ string[] quotedValues = QuoteValues(values);
+ string[] namesAndValues = new string[columns.Length];
+ for (int i = 0; i < columns.Length; i++)
+ {
+ namesAndValues[i] = String.Format("{0}={1}", columns[i], quotedValues[i]);
+ }
+
+ return String.Join(", ", namesAndValues);
+ }
+
+ public void Dispose()
+ {
+ if (_connection != null && _connection.State == ConnectionState.Open)
+ {
+ _connection.Close();
+ }
+ }
+ }
+}
diff --git a/Migrator.net/Migrator.Providers/TypeNames.cs b/Migrator.net/Migrator.Providers/TypeNames.cs
new file mode 100644
index 000000000..60d11603d
--- /dev/null
+++ b/Migrator.net/Migrator.Providers/TypeNames.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using Migrator.Framework;
+
+namespace Migrator.Providers
+{
+ ///
+ /// This class maps a DbType to names.
+ ///
+ ///
+ /// Associations may be marked with a capacity. Calling the Get()
+ /// method with a type and actual size n will return the associated
+ /// name with smallest capacity >= n, if available and an unmarked
+ /// default type otherwise.
+ /// Eg, setting
+ ///
+ /// Names.Put(DbType, "TEXT" );
+ /// Names.Put(DbType, 255, "VARCHAR($l)" );
+ /// Names.Put(DbType, 65534, "LONGVARCHAR($l)" );
+ ///
+ /// will give you back the following:
+ ///
+ /// Names.Get(DbType) // --> "TEXT" (default)
+ /// Names.Get(DbType,100) // --> "VARCHAR(100)" (100 is in [0:255])
+ /// Names.Get(DbType,1000) // --> "LONGVARCHAR(1000)" (100 is in [256:65534])
+ /// Names.Get(DbType,100000) // --> "TEXT" (default)
+ ///
+ /// On the other hand, simply putting
+ ///
+ /// Names.Put(DbType, "VARCHAR($l)" );
+ ///
+ /// would result in
+ ///
+ /// Names.Get(DbType) // --> "VARCHAR($l)" (will cause trouble)
+ /// Names.Get(DbType,100) // --> "VARCHAR(100)"
+ /// Names.Get(DbType,1000) // --> "VARCHAR(1000)"
+ /// Names.Get(DbType,10000) // --> "VARCHAR(10000)"
+ ///
+ ///
+ public class TypeNames
+ {
+ public const string LengthPlaceHolder = "$l";
+ public const string PrecisionPlaceHolder = "$p";
+ public const string ScalePlaceHolder = "$s";
+
+ private readonly Dictionary> weighted =
+ new Dictionary>();
+
+ private readonly Dictionary defaults = new Dictionary();
+
+ ///
+ /// Get default type name for specified type
+ ///
+ /// the type key
+ /// the default type name associated with the specified key
+ public string Get(DbType typecode)
+ {
+ string result;
+ if (!defaults.TryGetValue(typecode, out result))
+ {
+ throw new ArgumentException("Dialect does not support DbType." + typecode, "typecode");
+ }
+ return result;
+ }
+
+ ///
+ /// Get the type name specified type and size
+ ///
+ /// the type key
+ /// the SQL length
+ /// the SQL scale
+ /// the SQL precision
+ ///
+ /// The associated name with smallest capacity >= size if available and the
+ /// default type name otherwise
+ ///
+ public string Get(DbType typecode, int size, int precision, int scale)
+ {
+ SortedList map;
+ weighted.TryGetValue(typecode, out map);
+ if (map != null && map.Count > 0)
+ {
+ foreach (KeyValuePair entry in map)
+ {
+ if (size <= entry.Key)
+ {
+ return Replace(entry.Value, size, precision, scale);
+ }
+ }
+ }
+ //Could not find a specific type for the size, using the default
+ return Replace(Get(typecode), size, precision, scale);
+ }
+
+ private static string Replace(string type, int size, int precision, int scale)
+ {
+ type = StringUtils.ReplaceOnce(type, LengthPlaceHolder, size.ToString());
+ type = StringUtils.ReplaceOnce(type, ScalePlaceHolder, scale.ToString());
+ return StringUtils.ReplaceOnce(type, PrecisionPlaceHolder, precision.ToString());
+ }
+
+ ///
+ /// Set a type name for specified type key and capacity
+ ///
+ /// the type key
+ /// the (maximum) type size/length
+ /// The associated name
+ public void Put(DbType typecode, int capacity, string value)
+ {
+ SortedList map;
+ if (!weighted.TryGetValue(typecode, out map))
+ {
+ // add new ordered map
+ weighted[typecode] = map = new SortedList();
+ }
+ map[capacity] = value;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void Put(DbType typecode, string value)
+ {
+ defaults[typecode] = value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator/BaseMigrate.cs b/Migrator.net/Migrator/BaseMigrate.cs
new file mode 100644
index 000000000..5d1847c48
--- /dev/null
+++ b/Migrator.net/Migrator/BaseMigrate.cs
@@ -0,0 +1,110 @@
+using Migrator.Framework;
+using System.Collections.Generic;
+
+namespace Migrator
+{
+ public abstract class BaseMigrate
+ {
+ protected readonly ITransformationProvider _provider;
+ protected ILogger _logger;
+ protected List _availableMigrations;
+ protected List _original;
+ protected long _current;
+ protected bool _dryrun;
+
+ protected BaseMigrate(List availableMigrations, ITransformationProvider provider, ILogger logger)
+ {
+ _provider = provider;
+ _availableMigrations = availableMigrations;
+ _original = new List (_provider.AppliedMigrations.ToArray()); //clone
+ _logger = logger;
+ }
+
+ public static BaseMigrate GetInstance(List availableMigrations, ITransformationProvider provider, ILogger logger)
+ {
+ return new MigrateAnywhere(availableMigrations, provider, logger);
+ }
+
+ public List AppliedVersions
+ {
+ get { return _original; }
+ }
+
+ public virtual long Current
+ {
+ get { return _current; }
+ protected set { _current = value; }
+ }
+
+ public virtual bool DryRun
+ {
+ get { return _dryrun; }
+ set { _dryrun = value; }
+ }
+
+ public abstract long Previous { get; }
+ public abstract long Next { get; }
+
+ public void Iterate()
+ {
+ Current = Next;
+ }
+
+ public abstract bool Continue(long targetVersion);
+
+ public abstract void Migrate(IMigration migration);
+
+ ///
+ /// Finds the next migration available to be applied. Only returns
+ /// migrations that have NOT already been applied.
+ ///
+ /// The migration number of the next available Migration.
+ protected long NextMigration()
+ {
+ // Start searching at the current index
+ int migrationSearch = _availableMigrations.IndexOf(Current)+1;
+
+ // See if we can find a migration that matches the requirement
+ while(migrationSearch < _availableMigrations.Count
+ && _provider.AppliedMigrations.Contains(_availableMigrations[migrationSearch]))
+ {
+ migrationSearch++;
+ }
+
+ // did we exhaust the list?
+ if(migrationSearch == _availableMigrations.Count){
+ // we're at the last one. Done!
+ return _availableMigrations[migrationSearch-1]+1;
+ }
+ // found one.
+ return _availableMigrations[migrationSearch];
+ }
+
+ ///
+ /// Finds the previous migration that has been applied. Only returns
+ /// migrations that HAVE already been applied.
+ ///
+ /// The most recently applied Migration.
+ protected long PreviousMigration()
+ {
+ // Start searching at the current index
+ int migrationSearch = _availableMigrations.IndexOf(Current)-1;
+
+ // See if we can find a migration that matches the requirement
+ while(migrationSearch > -1
+ && !_provider.AppliedMigrations.Contains(_availableMigrations[migrationSearch]))
+ {
+ migrationSearch--;
+ }
+
+ // did we exhaust the list?
+ if(migrationSearch < 0){
+ // we're at the first one. Done!
+ return 0;
+ }
+
+ // found one.
+ return _availableMigrations[migrationSearch];
+ }
+ }
+}
diff --git a/Migrator.net/Migrator/Compile/ScriptEngine.cs b/Migrator.net/Migrator/Compile/ScriptEngine.cs
new file mode 100644
index 000000000..f9629ba48
--- /dev/null
+++ b/Migrator.net/Migrator/Compile/ScriptEngine.cs
@@ -0,0 +1,118 @@
+using System;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using Migrator.Framework;
+
+namespace Migrator.Compile
+{
+ public class ScriptEngine
+ {
+ public readonly string[] extraReferencedAssemblies;
+
+ private readonly CodeDomProvider _provider;
+ private string _codeType = "csharp";
+
+ public ScriptEngine() : this(null, null)
+ {
+ }
+
+ public ScriptEngine(string[] extraReferencedAssemblies)
+ : this(null, extraReferencedAssemblies)
+ {
+ }
+
+ public ScriptEngine(string codeType, string[] extraReferencedAssemblies)
+ {
+ if (!String.IsNullOrEmpty(codeType))
+ _codeType = codeType;
+ this.extraReferencedAssemblies = extraReferencedAssemblies;
+
+ // There is currently no way to generically create a CodeDomProvider and have it work with .NET 3.5
+ _provider = CodeDomProvider.CreateProvider(_codeType);
+ }
+
+ public Assembly Compile(string directory)
+ {
+ string[] files = GetFilesRecursive(directory);
+ Console.Out.WriteLine("Compiling:");
+ Array.ForEach(files, delegate(String file) { Console.Out.WriteLine(file); });
+
+ return Compile(files);
+ }
+
+ private string[] GetFilesRecursive(string directory)
+ {
+ FileInfo[] files = GetFilesRecursive(new DirectoryInfo(directory));
+ string[] fileNames = new string[files.Length];
+ for (int i = 0; i < files.Length; i ++)
+ {
+ fileNames[i] = files[i].FullName;
+ }
+ return fileNames;
+ }
+
+ private FileInfo[] GetFilesRecursive(DirectoryInfo d)
+ {
+ List files = new List();
+ files.AddRange(d.GetFiles(String.Format("*.{0}", _provider.FileExtension)));
+ DirectoryInfo[] subDirs = d.GetDirectories();
+ if (subDirs.Length > 0)
+ {
+ foreach (DirectoryInfo subDir in subDirs)
+ {
+ files.AddRange(GetFilesRecursive(subDir));
+ }
+ }
+
+ return files.ToArray();
+ }
+
+ public Assembly Compile(params string[] files)
+ {
+ CompilerParameters parms = SetupCompilerParams();
+
+ CompilerResults compileResult = _provider.CompileAssemblyFromFile(parms, files);
+ if (compileResult.Errors.Count != 0)
+ {
+ foreach (CompilerError err in compileResult.Errors)
+ {
+ Console.Error.WriteLine("{0} ({1}:{2}) {3}", err.FileName, err.Line, err.Column, err.ErrorText);
+ }
+ }
+ return compileResult.CompiledAssembly;
+ }
+
+ private CompilerParameters SetupCompilerParams()
+ {
+ string migrationFrameworkPath = FrameworkAssemblyPath();
+ CompilerParameters parms = new CompilerParameters();
+ parms.CompilerOptions = "/t:library";
+ parms.GenerateInMemory = true;
+ parms.IncludeDebugInformation = true;
+ parms.OutputAssembly = Path.Combine(Path.GetDirectoryName(migrationFrameworkPath), "MyMigrations.dll");
+
+ Console.Out.WriteLine("Output assembly: " + parms.OutputAssembly);
+
+ // Add Default referenced assemblies
+ parms.ReferencedAssemblies.Add("mscorlib.dll");
+ parms.ReferencedAssemblies.Add("System.dll");
+ parms.ReferencedAssemblies.Add("System.Data.dll");
+ parms.ReferencedAssemblies.Add(FrameworkAssemblyPath());
+ if (null != extraReferencedAssemblies && extraReferencedAssemblies.Length > 0)
+ {
+ Array.ForEach(extraReferencedAssemblies,
+ delegate(String assemb) { parms.ReferencedAssemblies.Add(assemb); });
+ }
+ return parms;
+ }
+
+ private static string FrameworkAssemblyPath()
+ {
+ string path = typeof (MigrationAttribute).Module.FullyQualifiedName;
+ Console.Out.WriteLine("Framework DLL: " + path);
+ return path;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/Migrator/DuplicatedVersionException.cs b/Migrator.net/Migrator/DuplicatedVersionException.cs
new file mode 100644
index 000000000..511888fee
--- /dev/null
+++ b/Migrator.net/Migrator/DuplicatedVersionException.cs
@@ -0,0 +1,26 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System;
+
+namespace Migrator
+{
+ ///
+ /// Exception thrown when a migration number is not unique.
+ ///
+ public class DuplicatedVersionException : Exception
+ {
+ public DuplicatedVersionException(long version)
+ : base(String.Format("Migration version #{0} is duplicated", version))
+ {
+ }
+ }
+}
diff --git a/Migrator.net/Migrator/IrreversibleMigrationException.cs b/Migrator.net/Migrator/IrreversibleMigrationException.cs
new file mode 100644
index 000000000..06b960763
--- /dev/null
+++ b/Migrator.net/Migrator/IrreversibleMigrationException.cs
@@ -0,0 +1,26 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System;
+
+namespace Migrator
+{
+ ///
+ /// Exception thrown in a migration Down() method
+ /// when changes can't be undone.
+ ///
+ public class IrreversibleMigrationException : Exception
+ {
+ public IrreversibleMigrationException() : base("Irreversible migration")
+ {
+ }
+ }
+}
diff --git a/Migrator.net/Migrator/MigrateAnywhere.cs b/Migrator.net/Migrator/MigrateAnywhere.cs
new file mode 100644
index 000000000..eb1bde01e
--- /dev/null
+++ b/Migrator.net/Migrator/MigrateAnywhere.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using Migrator.Framework;
+
+namespace Migrator
+{
+ ///
+ /// Description of MigrateAnywhere.
+ ///
+ public class MigrateAnywhere : BaseMigrate
+ {
+ private bool _goForward;
+
+ public MigrateAnywhere(List availableMigrations, ITransformationProvider provider, ILogger logger)
+ : base(availableMigrations, provider, logger)
+ {
+ _current = 0;
+ if (provider.AppliedMigrations.Count > 0) {
+ _current = provider.AppliedMigrations[provider.AppliedMigrations.Count - 1];
+ }
+ _goForward = false;
+ }
+
+ public override long Next
+ {
+ get
+ {
+ return _goForward
+ ? NextMigration()
+ : PreviousMigration();
+ }
+ }
+
+ public override long Previous
+ {
+ get
+ {
+ return _goForward
+ ? PreviousMigration()
+ : NextMigration();
+ }
+ }
+
+ public override bool Continue(long version)
+ {
+ // If we're going backwards and our current is less than the target,
+ // reverse direction. Also, start over at zero to make sure we catch
+ // any merged migrations that are less than the current target.
+ if (!_goForward && version >= Current)
+ {
+ _goForward = true;
+ Current = 0;
+ Iterate();
+ }
+
+ // We always finish on going forward. So continue if we're still
+ // going backwards, or if there are no migrations left in the forward direction.
+ return !_goForward || Current <= version;
+ }
+
+ public override void Migrate(IMigration migration)
+ {
+ _provider.BeginTransaction();
+ MigrationAttribute attr = (MigrationAttribute)Attribute.GetCustomAttribute(migration.GetType(), typeof(MigrationAttribute));
+
+ if (_provider.AppliedMigrations.Contains(attr.Version)) {
+ RemoveMigration(migration, attr);
+ } else {
+ ApplyMigration(migration, attr);
+ }
+ }
+
+ private void ApplyMigration(IMigration migration, MigrationAttribute attr)
+ {
+ // we're adding this one
+ _logger.MigrateUp(Current, migration.Name);
+ if(! DryRun)
+ {
+ migration.Up();
+ _provider.MigrationApplied(attr.Version);
+ _provider.Commit();
+ migration.AfterUp();
+ }
+ }
+
+ private void RemoveMigration(IMigration migration, MigrationAttribute attr)
+ {
+ // we're removing this one
+ _logger.MigrateDown(Current, migration.Name);
+ if (! DryRun)
+ {
+ migration.Down();
+ _provider.MigrationUnApplied(attr.Version);
+ _provider.Commit();
+ migration.AfterDown();
+ }
+ }
+ }
+}
diff --git a/Migrator.net/Migrator/MigrateDown.cs b/Migrator.net/Migrator/MigrateDown.cs
new file mode 100644
index 000000000..e69de29bb
diff --git a/Migrator.net/Migrator/MigrateUp.cs b/Migrator.net/Migrator/MigrateUp.cs
new file mode 100644
index 000000000..e69de29bb
diff --git a/Migrator.net/Migrator/MigrationComparer.cs b/Migrator.net/Migrator/MigrationComparer.cs
new file mode 100644
index 000000000..a1f7281f3
--- /dev/null
+++ b/Migrator.net/Migrator/MigrationComparer.cs
@@ -0,0 +1,43 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Migrator.Framework;
+
+namespace Migrator
+{
+ ///
+ /// Comparer of Migration by their version attribute.
+ ///
+ public class MigrationTypeComparer : IComparer
+ {
+ private readonly bool _ascending = true;
+
+ public MigrationTypeComparer(bool ascending)
+ {
+ _ascending = ascending;
+ }
+
+ public int Compare(Type x, Type y)
+ {
+ MigrationAttribute attribOfX = (MigrationAttribute) Attribute.GetCustomAttribute(x, typeof(MigrationAttribute));
+ MigrationAttribute attribOfY = (MigrationAttribute) Attribute.GetCustomAttribute(y, typeof(MigrationAttribute));
+
+ if (_ascending)
+ return attribOfX.Version.CompareTo(attribOfY.Version);
+ else
+ return attribOfY.Version.CompareTo(attribOfX.Version);
+
+
+ }
+ }
+}
diff --git a/Migrator.net/Migrator/MigrationLoader.cs b/Migrator.net/Migrator/MigrationLoader.cs
new file mode 100644
index 000000000..397ed43c7
--- /dev/null
+++ b/Migrator.net/Migrator/MigrationLoader.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Migrator.Framework;
+
+namespace Migrator
+{
+ ///
+ /// Handles inspecting code to find all of the Migrations in assemblies and reading
+ /// other metadata such as the last revision, etc.
+ ///
+ public class MigrationLoader
+ {
+ private readonly ITransformationProvider _provider;
+ private readonly List _migrationsTypes = new List();
+
+ public MigrationLoader(ITransformationProvider provider, Assembly migrationAssembly, bool trace)
+ {
+ _provider = provider;
+ AddMigrations(migrationAssembly);
+
+ if (trace)
+ {
+ provider.Logger.Trace("Loaded migrations:");
+ foreach (Type t in _migrationsTypes)
+ {
+ provider.Logger.Trace("{0} {1}", GetMigrationVersion(t).ToString().PadLeft(5), StringUtils.ToHumanName(t.Name));
+ }
+ }
+ }
+
+ public void AddMigrations(Assembly migrationAssembly)
+ {
+ if (migrationAssembly != null)
+ _migrationsTypes.AddRange(GetMigrationTypes(migrationAssembly));
+ }
+
+ ///
+ /// Returns registered migration types.
+ ///
+ public List MigrationsTypes
+ {
+ get { return _migrationsTypes; }
+ }
+
+ ///
+ /// Returns the last version of the migrations.
+ ///
+ public long LastVersion
+ {
+ get
+ {
+ if (_migrationsTypes.Count == 0)
+ return 0;
+ return GetMigrationVersion(_migrationsTypes[_migrationsTypes.Count - 1]);
+ }
+ }
+
+ ///
+ /// Check for duplicated version in migrations.
+ ///
+ /// CheckForDuplicatedVersion
+ public void CheckForDuplicatedVersion()
+ {
+ List versions = new List();
+ foreach (Type t in _migrationsTypes)
+ {
+ long version = GetMigrationVersion(t);
+
+ if (versions.Contains(version))
+ throw new DuplicatedVersionException(version);
+
+ versions.Add(version);
+ }
+ }
+
+ ///
+ /// Collect migrations in one Assembly.
+ ///
+ /// The Assembly to browse.
+ /// The migrations collection
+ public static List GetMigrationTypes(Assembly asm)
+ {
+ List migrations = new List();
+ foreach (Type t in asm.GetExportedTypes())
+ {
+ MigrationAttribute attrib =
+ (MigrationAttribute) Attribute.GetCustomAttribute(t, typeof (MigrationAttribute));
+
+ if (attrib != null && typeof(IMigration).IsAssignableFrom(t) && !attrib.Ignore)
+ {
+ migrations.Add(t);
+ }
+ }
+
+ migrations.Sort(new MigrationTypeComparer(true));
+ return migrations;
+ }
+
+ ///
+ /// Returns the version of the migration
+ /// MigrationAttribute.
+ ///
+ /// Migration type.
+ /// Version number sepcified in the attribute
+ public static long GetMigrationVersion(Type t)
+ {
+ MigrationAttribute attrib = (MigrationAttribute)
+ Attribute.GetCustomAttribute(t, typeof(MigrationAttribute));
+
+ return attrib.Version;
+ }
+
+ public List GetAvailableMigrations()
+ {
+ //List availableMigrations = new List();
+ _migrationsTypes.Sort(new MigrationTypeComparer(true));
+ return _migrationsTypes.ConvertAll(new Converter(GetMigrationVersion));
+ }
+
+ public IMigration GetMigration(long version)
+ {
+ foreach (Type t in _migrationsTypes)
+ {
+ if (GetMigrationVersion(t) == version)
+ {
+ IMigration migration = (IMigration)Activator.CreateInstance(t);
+ migration.Database = _provider;
+ return migration;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/Migrator.net/Migrator/Migrator.cs b/Migrator.net/Migrator/Migrator.cs
new file mode 100644
index 000000000..c41c204e1
--- /dev/null
+++ b/Migrator.net/Migrator/Migrator.cs
@@ -0,0 +1,177 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Migrator.Framework;
+using Migrator.Framework.Loggers;
+
+namespace Migrator
+{
+ ///
+ /// Migrations mediator.
+ ///
+ public class Migrator
+ {
+ private readonly ITransformationProvider _provider;
+
+ private readonly MigrationLoader _migrationLoader;
+
+ private ILogger _logger = new Logger(false);
+ protected bool _dryrun;
+ private string[] _args;
+
+ public string[] args
+ {
+ get { return _args; }
+ set { _args = value; }
+ }
+
+ public Migrator(string provider, string connectionString, Assembly migrationAssembly)
+ : this(provider, connectionString, migrationAssembly, false)
+ {
+ }
+
+ public Migrator(string provider, string connectionString, Assembly migrationAssembly, bool trace)
+ : this(ProviderFactory.Create(provider, connectionString), migrationAssembly, trace)
+ {
+ }
+
+ public Migrator(string provider, string connectionString, Assembly migrationAssembly, bool trace, ILogger logger)
+ : this(ProviderFactory.Create(provider, connectionString), migrationAssembly, trace, logger)
+ {
+ }
+
+ public Migrator(ITransformationProvider provider, Assembly migrationAssembly, bool trace)
+ : this(provider, migrationAssembly, trace, new Logger(trace, new ConsoleWriter()))
+ {
+ }
+
+ public Migrator(ITransformationProvider provider, Assembly migrationAssembly, bool trace, ILogger logger)
+ {
+ _provider = provider;
+ Logger = logger;
+
+ _migrationLoader = new MigrationLoader(provider, migrationAssembly, trace);
+ _migrationLoader.CheckForDuplicatedVersion();
+ }
+
+
+ ///
+ /// Returns registered migration types.
+ ///
+ public List MigrationsTypes
+ {
+ get { return _migrationLoader.MigrationsTypes; }
+ }
+
+ ///
+ /// Run all migrations up to the latest. Make no changes to database if
+ /// dryrun is true.
+ ///
+ public void MigrateToLastVersion()
+ {
+ MigrateTo(_migrationLoader.LastVersion);
+ }
+
+ ///
+ /// Returns the current migrations applied to the database.
+ ///
+ public List AppliedMigrations
+ {
+ get { return _provider.AppliedMigrations; }
+ }
+
+ ///
+ /// Get or set the event logger.
+ ///
+ public ILogger Logger
+ {
+ get { return _logger; }
+ set
+ {
+ _logger = value;
+ _provider.Logger = value;
+ }
+ }
+
+ public virtual bool DryRun
+ {
+ get { return _dryrun; }
+ set { _dryrun = value; }
+ }
+
+ ///
+ /// Migrate the database to a specific version.
+ /// Runs all migration between the actual version and the
+ /// specified version.
+ /// If version is greater then the current version,
+ /// the Up() method will be invoked.
+ /// If version lower then the current version,
+ /// the Down() method of previous migration will be invoked.
+ /// If dryrun is set, don't write any changes to the database.
+ ///
+ /// The version that must became the current one
+ public void MigrateTo(long version)
+ {
+
+ if (_migrationLoader.MigrationsTypes.Count == 0)
+ {
+ _logger.Warn("No public classes with the Migration attribute were found.");
+ return;
+ }
+
+ bool firstRun = true;
+ BaseMigrate migrate = BaseMigrate.GetInstance(_migrationLoader.GetAvailableMigrations(), _provider, _logger);
+ migrate.DryRun = DryRun;
+ Logger.Started(migrate.AppliedVersions, version);
+
+ while (migrate.Continue(version))
+ {
+ IMigration migration = _migrationLoader.GetMigration(migrate.Current);
+ if (null == migration)
+ {
+ _logger.Skipping(migrate.Current);
+ migrate.Iterate();
+ continue;
+ }
+
+ try
+ {
+ if (firstRun)
+ {
+ migration.InitializeOnce(_args);
+ firstRun = false;
+ }
+
+ migrate.Migrate(migration);
+ }
+ catch (Exception ex)
+ {
+ Logger.Exception(migrate.Current, migration.Name, ex);
+
+ // Oho! error! We rollback changes.
+ Logger.RollingBack(migrate.Previous);
+ _provider.Rollback();
+
+ throw;
+ }
+
+ migrate.Iterate();
+ }
+
+ Logger.Finished(migrate.AppliedVersions, version);
+ }
+ }
+}
diff --git a/Migrator.net/Migrator/Migrator.csproj b/Migrator.net/Migrator/Migrator.csproj
new file mode 100644
index 000000000..c2915327f
--- /dev/null
+++ b/Migrator.net/Migrator/Migrator.csproj
@@ -0,0 +1,76 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}
+ Library
+ Properties
+ Migrator
+ Migrator
+
+
+ 3.5
+
+
+ true
+ MigratorDotNet.snk
+ v2.0
+
+
+ true
+ full
+ false
+ bin\Migrator\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Migrator\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+ AssemblyInfo.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}
+ Migrator.Framework
+
+
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}
+ Migrator.Providers
+
+
+
+
\ No newline at end of file
diff --git a/Migrator.net/Migrator/MigratorDotNet.snk b/Migrator.net/Migrator/MigratorDotNet.snk
new file mode 100644
index 000000000..5032d709b
Binary files /dev/null and b/Migrator.net/Migrator/MigratorDotNet.snk differ
diff --git a/Migrator.net/Migrator/ProviderFactory.cs b/Migrator.net/Migrator/ProviderFactory.cs
new file mode 100644
index 000000000..c9f45f9d8
--- /dev/null
+++ b/Migrator.net/Migrator/ProviderFactory.cs
@@ -0,0 +1,75 @@
+#region License
+
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Migrator.Framework;
+using Migrator.Providers;
+
+namespace Migrator
+{
+ ///
+ /// Handles loading Provider implementations
+ ///
+ public class ProviderFactory
+ {
+ private static readonly Assembly providerAssembly;
+ private static readonly Dictionary dialects = new Dictionary();
+ static ProviderFactory()
+ {
+
+ //string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
+ //string fullPath = Path.Combine(directory, "Migrator.Providers.dll");
+ //if (fullPath.StartsWith("file:\\"))
+ // fullPath = fullPath.Substring(6);
+ //else if (fullPath.StartsWith("file:"))
+ // fullPath = fullPath.Substring(5);
+ providerAssembly = Assembly.GetAssembly(typeof(TransformationProvider));
+ //providerAssembly = Assembly.LoadFrom("Migrator.Providers.dll");
+ LoadDialects();
+ }
+
+ public static ITransformationProvider Create(string providerName, string connectionString)
+ {
+ object dialectInstance = DialectForProvider(providerName);
+ MethodInfo mi = dialectInstance.GetType().GetMethod("NewProviderForDialect", new Type[] {typeof (String)});
+ return (ITransformationProvider)mi.Invoke(dialectInstance, new object[] { connectionString });
+ }
+
+ public static object DialectForProvider(string providerName)
+ {
+ if (String.IsNullOrEmpty(providerName))
+ return null;
+
+ foreach (string key in dialects.Keys)
+ {
+ if (0 < key.IndexOf(providerName, StringComparison.InvariantCultureIgnoreCase))
+ return dialects[key];
+ }
+ return null;
+ }
+
+ public static void LoadDialects()
+ {
+ Type dialectType = providerAssembly.GetType("Migrator.Providers.Dialect");
+ foreach (Type t in providerAssembly.GetTypes())
+ {
+ if (t.IsSubclassOf(dialectType))
+ {
+ dialects.Add(t.FullName, Activator.CreateInstance(t, null));
+ }
+ }
+ }
+ }
+}
diff --git a/Migrator.net/Migrator/Tools/SchemaDumper.cs b/Migrator.net/Migrator/Tools/SchemaDumper.cs
new file mode 100644
index 000000000..ee6195d41
--- /dev/null
+++ b/Migrator.net/Migrator/Tools/SchemaDumper.cs
@@ -0,0 +1,70 @@
+#region License
+//The contents of this file are subject to the Mozilla Public License
+//Version 1.1 (the "License"); you may not use this file except in
+//compliance with the License. You may obtain a copy of the License at
+//http://www.mozilla.org/MPL/
+//Software distributed under the License is distributed on an "AS IS"
+//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+//License for the specific language governing rights and limitations
+//under the License.
+#endregion
+
+using System.IO;
+using Migrator.Framework;
+
+namespace Migrator.Tools
+{
+ public class SchemaDumper
+ {
+ private readonly ITransformationProvider _provider;
+
+ public SchemaDumper(string provider, string connectionString)
+ {
+ _provider = ProviderFactory.Create(provider, connectionString);
+ }
+
+ public string Dump()
+ {
+ StringWriter writer = new StringWriter();
+
+ writer.WriteLine("using Migrator;\n");
+ writer.WriteLine("[Migration(1)]");
+ writer.WriteLine("public class SchemaDump : Migration");
+ writer.WriteLine("{");
+ writer.WriteLine("\tpublic override void Up()");
+ writer.WriteLine("\t{");
+
+ foreach (string table in _provider.GetTables())
+ {
+ writer.WriteLine("\t\tDatabase.AddTable(\"{0}\",", table);
+ foreach (Column column in _provider.GetColumns(table))
+ {
+ writer.WriteLine("\t\t\tnew Column(\"{0}\", typeof({1})),", column.Name, column.Type);
+ }
+ writer.WriteLine("\t\t);");
+ }
+
+ writer.WriteLine("\t}\n");
+ writer.WriteLine("\tpublic override void Down()");
+ writer.WriteLine("\t{");
+
+ foreach (string table in _provider.GetTables())
+ {
+ writer.WriteLine("\t\tDatabase.RemoveTable(\"{0}\");", table);
+ }
+
+ writer.WriteLine("\t}");
+ writer.WriteLine("}");
+
+ return writer.ToString();
+ }
+
+ public void DumpTo(string file)
+ {
+ using (StreamWriter writer = new StreamWriter(file))
+ {
+ writer.Write(Dump());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Migrator.net/config/AssemblyInfo.cs b/Migrator.net/config/AssemblyInfo.cs
new file mode 100644
index 000000000..1f0e5aa7a
--- /dev/null
+++ b/Migrator.net/config/AssemblyInfo.cs
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Migrator")]
+[assembly: AssemblyDescription("Database migration for .NET")]
+[assembly: AssemblyProduct("Migrator")]
+[assembly: AssemblyCopyright("Copyright © 2006")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a5f0077a-d124-449a-a684-453576551f43")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.9.1.*")]
diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
index 2a5407133..64bf6f0b3 100644
--- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
+++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
@@ -59,18 +59,6 @@
..\packages\Unity.2.0\lib\20\Microsoft.Practices.Unity.Interception.Configuration.dll
-
- False
- ..\packages\MigratorDotNet.0.9.0.28138\lib\Net40\Migrator.dll
-
-
- False
- ..\packages\MigratorDotNet.0.9.0.28138\lib\Net40\Migrator.Framework.dll
-
-
- False
- ..\packages\MigratorDotNet.0.9.0.28138\lib\Net40\Migrator.Providers.dll
-
..\packages\Moq.4.0.10827\lib\NET40\Moq.dll
@@ -130,6 +118,18 @@
+
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}
+ Migrator.Framework
+
+
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}
+ Migrator.Providers
+
+
+ {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}
+ Migrator
+
{FF5EE3B6-913B-47CE-9CEB-11C51B4E1205}
NzbDrone.Core
diff --git a/NzbDrone.Core.Test/RepositoryProviderTest.cs b/NzbDrone.Core.Test/RepositoryProviderTest.cs
index f2bd21428..0374b7cbd 100644
--- a/NzbDrone.Core.Test/RepositoryProviderTest.cs
+++ b/NzbDrone.Core.Test/RepositoryProviderTest.cs
@@ -6,6 +6,7 @@ using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
using Migrator.Framework;
+using Migrator.Providers.SQLite;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Repository;
@@ -86,11 +87,12 @@ namespace NzbDrone.Core.Test
string connectionString = "Data Source=" + Guid.NewGuid() + ".db;Version=3;New=True";
var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
var repo = new SimpleRepository(dbProvider, SimpleRepositoryOptions.RunMigrations);
+ var sqliteDatabase = new SQLiteTransformationProvider(new SQLiteDialect(), connectionString);
repo.Add(new TestRepoType(){Value = "Dummy"});
var repositoryProvider = new RepositoryProvider();
- var columns = repositoryProvider.GetColumnsFromDatabase(connectionString, "TestRepoTypes");
+ var columns = repositoryProvider.GetColumnsFromDatabase(sqliteDatabase, "TestRepoTypes");
Assert.Count(3, columns);
@@ -102,13 +104,14 @@ namespace NzbDrone.Core.Test
{
string connectionString = "Data Source=" + Guid.NewGuid() + ".db;Version=3;New=True";
var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
+ var sqliteDatabase = new SQLiteTransformationProvider(new SQLiteDialect(), connectionString);
var repo = new SimpleRepository(dbProvider, SimpleRepositoryOptions.RunMigrations);
repo.Add(new TestRepoType(){Value = "Dummy"});
var repositoryProvider = new RepositoryProvider();
var typeSchema = repositoryProvider.GetSchemaFromType(typeof(TestRepoType2));
- var columns = repositoryProvider.GetColumnsFromDatabase(connectionString, "TestRepoTypes");
+ var columns = repositoryProvider.GetColumnsFromDatabase(sqliteDatabase, "TestRepoTypes");
var deletedColumns = repositoryProvider.GetDeletedColumns(typeSchema, columns);
@@ -125,12 +128,13 @@ namespace NzbDrone.Core.Test
string connectionString = "Data Source=" + Guid.NewGuid() + ".db;Version=3;New=True";
var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
var repo = new SimpleRepository(dbProvider, SimpleRepositoryOptions.RunMigrations);
+ var sqliteDatabase = new SQLiteTransformationProvider(new SQLiteDialect(), connectionString);
repo.Add(new TestRepoType2() { Value = "dummy" });
var repositoryProvider = new RepositoryProvider();
var typeSchema = repositoryProvider.GetSchemaFromType(typeof(TestRepoType));
- var columns = repositoryProvider.GetColumnsFromDatabase(connectionString, "TestRepoType2s");
+ var columns = repositoryProvider.GetColumnsFromDatabase(sqliteDatabase, "TestRepoType2s");
var deletedColumns = repositoryProvider.GetNewColumns(typeSchema, columns);
diff --git a/NzbDrone.Core/Datastore/Migrations.cs b/NzbDrone.Core/Datastore/Migrations.cs
index a3e27791a..09e361954 100644
--- a/NzbDrone.Core/Datastore/Migrations.cs
+++ b/NzbDrone.Core/Datastore/Migrations.cs
@@ -6,6 +6,7 @@ using System.Reflection;
using System.Text;
using Migrator.Framework;
using NLog;
+using NzbDrone.Core.Repository;
using SubSonic.Extensions;
using SubSonic.Schema;
@@ -43,16 +44,19 @@ namespace NzbDrone.Core.Datastore
foreach (var repoType in repoTypes)
{
var typeSchema = provider.GetSchemaFromType(repoType);
- var dbColumns = provider.GetColumnsFromDatabase(Connection.MainConnectionString, typeSchema.Name);
- var deletedColumns = provider.GetDeletedColumns(typeSchema, dbColumns);
-
- foreach (var deletedColumn in deletedColumns)
+ if (transformationProvider.TableExists(typeSchema.Name))
{
- Logger.Info("Removing column '{0}' from '{1}'", deletedColumn.Name, repoType.Name);
- transformationProvider.RemoveColumn(typeSchema.Name, deletedColumn.Name);
- }
+ var dbColumns = provider.GetColumnsFromDatabase(transformationProvider, typeSchema.Name);
+ var deletedColumns = provider.GetDeletedColumns(typeSchema, dbColumns);
+
+ foreach (var deletedColumn in deletedColumns)
+ {
+ Logger.Info("Removing column '{0}' from '{1}'", deletedColumn.Name, repoType.Name);
+ transformationProvider.RemoveColumn(typeSchema.Name, deletedColumn.Name);
+ }
+ }
}
}
@@ -65,14 +69,17 @@ namespace NzbDrone.Core.Datastore
foreach (var repoType in repoTypes)
{
var typeSchema = provider.GetSchemaFromType(repoType);
- var dbColumns = provider.GetColumnsFromDatabase(Connection.MainConnectionString, typeSchema.Name);
+ if (transformationProvider.TableExists(typeSchema.Name))
+ {
+ var dbColumns = provider.GetColumnsFromDatabase(transformationProvider, typeSchema.Name);
- var newColumns = provider.GetNewColumns(typeSchema, dbColumns);
+ var newColumns = provider.GetNewColumns(typeSchema, dbColumns);
- foreach (var newColumn in newColumns)
- {
- Logger.Info("Adding column '{0}' to '{1}'", newColumn.Name, repoType.Name);
- transformationProvider.AddColumn(typeSchema.Name, newColumn);
+ foreach (var newColumn in newColumns)
+ {
+ Logger.Info("Adding column '{0}' to '{1}'", newColumn.Name, repoType.Name);
+ transformationProvider.AddColumn(typeSchema.Name, newColumn);
+ }
}
}
@@ -86,6 +93,12 @@ namespace NzbDrone.Core.Datastore
{
public override void Up()
{
+ //Remove jobs table forcing it to repopulate
+ var repoProvider = new RepositoryProvider();
+ var jobTable = repoProvider.GetSchemaFromType(typeof(JobSetting));
+
+ Database.RemoveTable(jobTable.Name);
+
Migrations.RemoveDeletedColumns(Database);
Migrations.AddNewColumns(Database);
}
diff --git a/NzbDrone.Core/Datastore/RepositoryProvider.cs b/NzbDrone.Core/Datastore/RepositoryProvider.cs
index c4cc3da67..7861b9526 100644
--- a/NzbDrone.Core/Datastore/RepositoryProvider.cs
+++ b/NzbDrone.Core/Datastore/RepositoryProvider.cs
@@ -29,12 +29,9 @@ namespace NzbDrone.Core.Datastore
return type.ToSchemaTable(Connection.MainDataProvider);
}
- public virtual Column[] GetColumnsFromDatabase(string connectionString, string tableName)
+ public virtual Column[] GetColumnsFromDatabase(ITransformationProvider database, string tableName)
{
- var dialact = new SQLiteDialect();
- var mig = new SQLiteTransformationProvider(dialact, connectionString);
-
- return mig.GetColumns(tableName);
+ return database.GetColumns(tableName);
}
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index 5d9c058b9..636beec98 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -128,18 +128,6 @@
False
Libraries\Exceptioneer.WindowsFormsClient.dll
-
- False
- ..\packages\MigratorDotNet.0.9.0.28138\lib\Net40\Migrator.dll
-
-
- False
- ..\packages\MigratorDotNet.0.9.0.28138\lib\Net40\Migrator.Framework.dll
-
-
- False
- ..\packages\MigratorDotNet.0.9.0.28138\lib\Net40\Migrator.Providers.dll
-
False
..\packages\Ninject.2.2.1.0\lib\.NetFramework 4.0\Ninject.dll
@@ -276,6 +264,20 @@
+
+
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}
+ Migrator.Framework
+
+
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}
+ Migrator.Providers
+
+
+ {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}
+ Migrator
+
+