added better db migration support than what Subsonic provides out of the box.

This commit is contained in:
kay.one 2011-05-23 17:34:57 -07:00
commit ce63f05512
91 changed files with 7218 additions and 48 deletions

View file

@ -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
{
/// <summary>
/// Represents a table column.
/// </summary>
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; }
}
}
}

View file

@ -0,0 +1,50 @@
using System;
namespace Migrator.Framework
{
/// <summary>
/// Represents a table column properties.
/// </summary>
[Flags]
public enum ColumnProperty
{
None = 0,
/// <summary>
/// Null is allowable
/// </summary>
Null = 1,
/// <summary>
/// Null is not allowable
/// </summary>
NotNull = 2,
/// <summary>
/// Identity column, autoinc
/// </summary>
Identity = 4,
/// <summary>
/// Unique Column
/// </summary>
Unique = 8,
/// <summary>
/// Indexed Column
/// </summary>
Indexed = 16,
/// <summary>
/// Unsigned Column
/// </summary>
Unsigned = 32,
/// <summary>
/// Foreign Key
/// </summary>
ForeignKey = Unsigned | Null,
/// <summary>
/// Primary Key
/// </summary>
PrimaryKey = 64 | Unsigned | NotNull,
/// <summary>
/// Primary key. Make the column a PrimaryKey and unsigned
/// </summary>
PrimaryKeyWithIdentity = PrimaryKey | Identity
}
}

View file

@ -0,0 +1,11 @@
namespace Migrator.Framework
{
public enum ForeignKeyConstraint
{
Cascade,
SetNull,
NoAction,
Restrict,
SetDefault
}
}

View file

@ -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; }
}
}

View file

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
namespace Migrator.Framework
{
public interface ILogger
{
/// <summary>
/// Log that we have started a migration
/// </summary>
/// <param name="currentVersion">Start list of versions</param>
/// <param name="finalVersion">Final Version</param>
void Started(List<long> currentVersion, long finalVersion);
/// <summary>
/// Log that we are migrating up
/// </summary>
/// <param name="version">Version we are migrating to</param>
/// <param name="migrationName">Migration name</param>
void MigrateUp(long version, string migrationName);
/// <summary>
/// Log that we are migrating down
/// </summary>
/// <param name="version">Version we are migrating to</param>
/// <param name="migrationName">Migration name</param>
void MigrateDown(long version, string migrationName);
/// <summary>
/// Inform that a migration corresponding to the number of
/// version is untraceable (not found?) and will be ignored.
/// </summary>
/// <param name="version">Version we couldnt find</param>
void Skipping(long version);
/// <summary>
/// Log that we are rolling back to version
/// </summary>
/// <param name="originalVersion">
/// version
/// </param>
void RollingBack(long originalVersion);
/// <summary>
/// Log a Sql statement that changes the schema or content of the database as part of a migration
/// </summary>
/// <remarks>
/// SELECT statements should not be logged using this method as they do not alter the data or schema of the
/// database.
/// </remarks>
/// <param name="sql">The Sql statement to log</param>
void ApplyingDBChange(string sql);
/// <summary>
/// Log that we had an exception on a migration
/// </summary>
/// <param name="version">The version of the migration that caused the exception.</param>
/// <param name="migrationName">The name of the migration that caused the exception.</param>
/// <param name="ex">The exception itself</param>
void Exception(long version, string migrationName, Exception ex);
/// <summary>
/// Log that we had an exception on a migration
/// </summary>
/// <param name="message">An informative message to show to the user.</param>
/// <param name="ex">The exception itself</param>
void Exception(string message, Exception ex);
/// <summary>
/// Log that we have finished a migration
/// </summary>
/// <param name="currentVersion">List of versions with which we started</param>
/// <param name="finalVersion">Final Version</param>
void Finished(List<long> currentVersion, long finalVersion);
/// <summary>
/// Log a message
/// </summary>
/// <param name="format">The format string ("{0}, blabla {1}").</param>
/// <param name="args">Parameters to apply to the format string.</param>
void Log(string format, params object[] args);
/// <summary>
/// Log a Warning
/// </summary>
/// <param name="format">The format string ("{0}, blabla {1}").</param>
/// <param name="args">Parameters to apply to the format string.</param>
void Warn(string format, params object[] args);
/// <summary>
/// Log a Trace Message
/// </summary>
/// <param name="format">The format string ("{0}, blabla {1}").</param>
/// <param name="args">Parameters to apply to the format string.</param>
void Trace(string format, params object[] args);
}
}

View file

@ -0,0 +1,39 @@
namespace Migrator.Framework
{
public interface IMigration
{
string Name { get; }
/// <summary>
/// Represents the database.
/// <see cref="ITransformationProvider"></see>.
/// </summary>
/// <seealso cref="ITransformationProvider">Migration.Framework.ITransformationProvider</seealso>
ITransformationProvider Database { get; set; }
/// <summary>
/// Defines tranformations to port the database to the current version.
/// </summary>
void Up();
/// <summary>
/// This is run after the Up transaction has been committed
/// </summary>
void AfterUp();
/// <summary>
/// Defines transformations to revert things done in <c>Up</c>.
/// </summary>
void Down();
/// <summary>
/// This is run after the Down transaction has been committed
/// </summary>
void AfterDown();
/// <summary>
/// This gets called once on the first migration object.
/// </summary>
void InitializeOnce(string[] args);
}
}

View file

@ -0,0 +1,469 @@
using System;
using System.Data;
using System.Collections.Generic;
namespace Migrator.Framework
{
/// <summary>
/// The main interface to use in Migrations to make changes on a database schema.
/// </summary>
public interface ITransformationProvider : IDisposable
{
/// <summary>
/// Get this provider or a NoOp provider if you are not running in the context of 'provider'.
/// </summary>
ITransformationProvider this[string provider] { get;}
/// <summary>
/// The list of Migrations currently applied to the database.
/// </summary>
List<long> AppliedMigrations { get; }
ILogger Logger { get; set; }
/// <summary>
/// Add a column to an existing table
/// </summary>
/// <param name="table">The name of the table that will get the new column</param>
/// <param name="column">The name of the new column</param>
/// <param name="type">The data type for the new columnd</param>
/// <param name="size">The precision or size of the column</param>
/// <param name="property">Properties that can be ORed together</param>
/// <param name="defaultValue">The default value of the column if no value is given in a query</param>
void AddColumn(string table, string column, DbType type, int size, ColumnProperty property, object defaultValue);
/// <summary>
/// Add a column to an existing table
/// </summary>
/// <param name="table">The name of the table that will get the new column</param>
/// <param name="column">The name of the new column</param>
/// <param name="type">The data type for the new columnd</param>
void AddColumn(string table, string column, DbType type);
/// <summary>
/// Add a column to an existing table
/// </summary>
/// <param name="table">The name of the table that will get the new column</param>
/// <param name="column">The name of the new column</param>
/// <param name="type">The data type for the new columnd</param>
/// <param name="size">The precision or size of the column</param>
void AddColumn(string table, string column, DbType type, int size);
/// <summary>
/// Add a column to an existing table
/// </summary>
/// <param name="table">The name of the table that will get the new column</param>
/// <param name="column">The name of the new column</param>
/// <param name="type">The data type for the new columnd</param>
/// <param name="size">The precision or size of the column</param>
/// <param name="property">Properties that can be ORed together</param>
void AddColumn(string table, string column, DbType type, int size, ColumnProperty property);
/// <summary>
/// Add a column to an existing table
/// </summary>
/// <param name="table">The name of the table that will get the new column</param>
/// <param name="column">The name of the new column</param>
/// <param name="type">The data type for the new columnd</param>
/// <param name="property">Properties that can be ORed together</param>
void AddColumn(string table, string column, DbType type, ColumnProperty property);
/// <summary>
/// Add a column to an existing table with the default column size.
/// </summary>
/// <param name="table">The name of the table that will get the new column</param>
/// <param name="column">The name of the new column</param>
/// <param name="type">The data type for the new columnd</param>
/// <param name="defaultValue">The default value of the column if no value is given in a query</param>
void AddColumn(string table, string column, DbType type, object defaultValue);
/// <summary>
/// Add a column to an existing table
/// </summary>
/// <param name="table">The name of the table that will get the new column</param>
/// <param name="column">An instance of a <see cref="Column">Column</see> with the specified properties</param>
void AddColumn(string table, Column column);
/// <summary>
/// Add a foreign key constraint
/// </summary>
/// <param name="name">The name of the foreign key. e.g. FK_TABLE_REF</param>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="foreignColumns">The columns that are the foreign keys (eg. FK_id)</param>
/// <param name="primaryTable">The table that holds the primary keys (eg. Table.PK_id)</param>
/// <param name="primaryColumns">The columns that are the primary keys (eg. PK_id)</param>
void AddForeignKey(string name, string foreignTable, string[] foreignColumns, string primaryTable, string[] primaryColumns);
/// <summary>
/// Add a foreign key constraint
/// </summary>
/// <param name="name">The name of the foreign key. e.g. FK_TABLE_REF</param>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="foreignColumns">The columns that are the foreign keys (eg. FK_id)</param>
/// <param name="primaryTable">The table that holds the primary keys (eg. Table.PK_id)</param>
/// <param name="primaryColumns">The columns that are the primary keys (eg. PK_id)</param>
/// <param name="constraint">Constraint parameters</param>
void AddForeignKey(string name, string foreignTable, string[] foreignColumns, string primaryTable, string[] primaryColumns, ForeignKeyConstraint constraint);
/// <summary>
/// Add a foreign key constraint
/// </summary>
///
/// <param name="name">The name of the foreign key. e.g. FK_TABLE_REF</param>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="foreignColumn">The column that is the foreign key (eg. FK_id)</param>
/// <param name="primaryTable">The table that holds the primary keys (eg. Table.PK_id)</param>
/// <param name="primaryColumn">The column that is the primary key (eg. PK_id)</param>
void AddForeignKey(string name, string foreignTable, string foreignColumn, string primaryTable, string primaryColumn);
/// <summary>
/// Add a foreign key constraint
/// </summary>
/// <param name="name">The name of the foreign key. e.g. FK_TABLE_REF</param>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="foreignColumn">The column that is the foreign key (eg. FK_id)</param>
/// <param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
/// <param name="primaryColumn">The column that is the primary key (eg. PK_id)</param>
/// <param name="constraint">Constraint parameters</param>
void AddForeignKey(string name, string foreignTable, string foreignColumn, string primaryTable, string primaryColumn, ForeignKeyConstraint constraint);
/// <summary>
/// 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.
/// </summary>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="foreignColumn">The column that is the foreign key (eg. FK_id)</param>
/// <param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
/// <param name="primaryColumn">The column that is the primary key (eg. PK_id)</param>
void GenerateForeignKey(string foreignTable, string foreignColumn, string primaryTable, string primaryColumn);
/// <summary>
/// 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.
/// </summary>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="foreignColumns">The columns that are the foreign keys (eg. FK_id)</param>
/// <param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
/// <param name="primaryColumns">The column that is the primary key (eg. PK_id)</param>
void GenerateForeignKey(string foreignTable, string[] foreignColumns, string primaryTable, string[] primaryColumns);
/// <summary>
/// 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.
/// </summary>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="foreignColumns">The columns that are the foreign keys (eg. FK_id)</param>
/// <param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
/// <param name="primaryColumns">The columns that are the primary keys (eg. PK_id)</param>
/// <param name="constraint">Constraint parameters</param>
void GenerateForeignKey(string foreignTable, string[] foreignColumns, string primaryTable, string[] primaryColumns, ForeignKeyConstraint constraint);
/// <summary>
/// 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.
/// </summary>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="foreignColumn">The columns that are the foreign keys (eg. FK_id)</param>
/// <param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
/// <param name="primaryColumn">The column that is the primary key (eg. PK_id)</param>
/// <param name="constraint">Constraint parameters</param>
void GenerateForeignKey(string foreignTable, string foreignColumn, string primaryTable, string primaryColumn,
ForeignKeyConstraint constraint);
/// <summary>
/// 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.
/// </summary>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
void GenerateForeignKey(string foreignTable, string primaryTable);
/// <summary>
/// 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.
/// </summary>
/// <param name="foreignTable">The table that the foreign key will be created in (eg. Table.FK_id)</param>
/// <param name="primaryTable">The table that holds the primary key (eg. Table.PK_id)</param>
/// <param name="constraint"></param>
void GenerateForeignKey(string foreignTable, string primaryTable, ForeignKeyConstraint constraint);
/// <summary>
/// Add a primary key to a table
/// </summary>
/// <param name="name">The name of the primary key to add.</param>
/// <param name="table">The name of the table that will get the primary key.</param>
/// <param name="columns">The name of the column or columns that are in the primary key.</param>
void AddPrimaryKey(string name, string table, params string[] columns);
/// <summary>
/// Add a constraint to a table
/// </summary>
/// <param name="name">The name of the constraint to add.</param>
/// <param name="table">The name of the table that will get the constraint</param>
/// <param name="columns">The name of the column or columns that will get the constraint.</param>
void AddUniqueConstraint(string name, string table, params string[] columns);
/// <summary>
/// Add a constraint to a table
/// </summary>
/// <param name="name">The name of the constraint to add.</param>
/// <param name="table">The name of the table that will get the constraint</param>
/// <param name="checkSql">The check constraint definition.</param>
void AddCheckConstraint(string name, string table, string checkSql);
/// <summary>
/// Add a table
/// </summary>
/// <param name="name">The name of the table to add.</param>
/// <param name="columns">The columns that are part of the table.</param>
void AddTable(string name, params Column[] columns);
/// <summary>
/// Add a table
/// </summary>
/// <param name="name">The name of the table to add.</param>
/// <param name="engine">The name of the database engine to use. (MySQL)</param>
/// <param name="columns">The columns that are part of the table.</param>
void AddTable(string name, string engine, params Column[] columns);
/// <summary>
/// Start a transction
/// </summary>
void BeginTransaction();
/// <summary>
/// Change the definition of an existing column.
/// </summary>
/// <param name="table">The name of the table that will get the new column</param>
/// <param name="column">An instance of a <see cref="Column">Column</see> with the specified properties and the name of an existing column</param>
void ChangeColumn(string table, Column column);
/// <summary>
/// Check to see if a column exists
/// </summary>
/// <param name="table"></param>
/// <param name="column"></param>
/// <returns></returns>
bool ColumnExists(string table, string column);
/// <summary>
/// Commit the running transction
/// </summary>
void Commit();
/// <summary>
/// Check to see if a constraint exists
/// </summary>
/// <param name="name">The name of the constraint</param>
/// <param name="table">The table that the constraint lives on.</param>
/// <returns></returns>
bool ConstraintExists(string table, string name);
/// <summary>
/// Check to see if a primary key constraint exists on the table
/// </summary>
/// <param name="name">The name of the primary key</param>
/// <param name="table">The table that the constraint lives on.</param>
/// <returns></returns>
bool PrimaryKeyExists(string table, string name);
/// <summary>
/// Execute an arbitrary SQL query
/// </summary>
/// <param name="sql">The SQL to execute.</param>
/// <returns></returns>
int ExecuteNonQuery(string sql);
/// <summary>
/// Execute an arbitrary SQL query
/// </summary>
/// <param name="sql">The SQL to execute.</param>
/// <returns></returns>
IDataReader ExecuteQuery(string sql);
/// <summary>
/// Execute an arbitrary SQL query
/// </summary>
/// <param name="sql">The SQL to execute.</param>
/// <returns>A single value that is returned.</returns>
object ExecuteScalar(string sql);
/// <summary>
/// Get the information about the columns in a table
/// </summary>
/// <param name="table">The table name that you want the columns for.</param>
/// <returns></returns>
Column[] GetColumns(string table);
/// <summary>
/// Get information about a single column in a table
/// </summary>
/// <param name="table">The table name that you want the columns for.</param>
/// <param name="column">The column name for which you want information.</param>
/// <returns></returns>
Column GetColumnByName(string table, string column);
/// <summary>
/// Get the names of all of the tables
/// </summary>
/// <returns>The names of all the tables.</returns>
string[] GetTables();
/// <summary>
/// Insert data into a table
/// </summary>
/// <param name="table">The table that will get the new data</param>
/// <param name="columns">The names of the columns</param>
/// <param name="values">The values in the same order as the columns</param>
/// <returns></returns>
int Insert(string table, string[] columns, string[] values);
/// <summary>
/// Delete data from a table
/// </summary>
/// <param name="table">The table that will have the data deleted</param>
/// <param name="columns">The names of the columns used in a where clause</param>
/// <param name="values">The values in the same order as the columns</param>
/// <returns></returns>
int Delete(string table, string[] columns, string[] values);
/// <summary>
/// Delete data from a table
/// </summary>
/// <param name="table">The table that will have the data deleted</param>
/// <param name="whereColumn">The name of the column used in a where clause</param>
/// <param name="whereValue">The value for the where clause</param>
/// <returns></returns>
int Delete(string table, string whereColumn, string whereValue);
/// <summary>
/// Marks a Migration version number as having been applied
/// </summary>
/// <param name="version">The version number of the migration that was applied</param>
void MigrationApplied(long version);
/// <summary>
/// Marks a Migration version number as having been rolled back from the database
/// </summary>
/// <param name="version">The version number of the migration that was removed</param>
void MigrationUnApplied(long version);
/// <summary>
/// Remove an existing column from a table
/// </summary>
/// <param name="table">The name of the table to remove the column from</param>
/// <param name="column">The column to remove</param>
void RemoveColumn(string table, string column);
/// <summary>
/// Remove an existing foreign key constraint
/// </summary>
/// <param name="table">The table that contains the foreign key.</param>
/// <param name="name">The name of the foreign key to remove</param>
void RemoveForeignKey(string table, string name);
/// <summary>
/// Remove an existing constraint
/// </summary>
/// <param name="table">The table that contains the foreign key.</param>
/// <param name="name">The name of the constraint to remove</param>
void RemoveConstraint(string table, string name);
/// <summary>
/// Remove an existing table
/// </summary>
/// <param name="tableName">The name of the table</param>
void RemoveTable(string tableName);
/// <summary>
/// Rename an existing table
/// </summary>
/// <param name="oldName">The old name of the table</param>
/// <param name="newName">The new name of the table</param>
void RenameTable(string oldName, string newName);
/// <summary>
/// Rename an existing table
/// </summary>
/// <param name="tableName">The name of the table</param>
/// <param name="oldColumnName">The old name of the column</param>
/// <param name="newColumnName">The new name of the column</param>
void RenameColumn(string tableName, string oldColumnName, string newColumnName);
/// <summary>
/// Rollback the currently running transaction.
/// </summary>
void Rollback();
/// <summary>
/// Get values from a table
/// </summary>
/// <param name="what">The columns to select</param>
/// <param name="from">The table to select from</param>
/// <param name="where">The where clause to limit the selection</param>
/// <returns></returns>
IDataReader Select(string what, string from, string where);
/// <summary>
/// Get values from a table
/// </summary>
/// <param name="what">The columns to select</param>
/// <param name="from">The table to select from</param>
/// <returns></returns>
IDataReader Select(string what, string from);
/// <summary>
/// Get a single value from a table
/// </summary>
/// <param name="what">The columns to select</param>
/// <param name="from">The table to select from</param>
/// <param name="where"></param>
/// <returns></returns>
object SelectScalar(string what, string from, string where);
/// <summary>
/// Get a single value from a table
/// </summary>
/// <param name="what">The columns to select</param>
/// <param name="from">The table to select from</param>
/// <returns></returns>
object SelectScalar(string what, string from);
/// <summary>
/// Check if a table already exists
/// </summary>
/// <param name="tableName">The name of the table that you want to check on.</param>
/// <returns></returns>
bool TableExists(string tableName);
/// <summary>
/// Update the values in a table
/// </summary>
/// <param name="table">The name of the table to update</param>
/// <param name="columns">The names of the columns.</param>
/// <param name="columnValues">The values for the columns in the same order as the names.</param>
/// <returns></returns>
int Update(string table, string[] columns, string[] columnValues);
/// <summary>
/// Update the values in a table
/// </summary>
/// <param name="table">The name of the table to update</param>
/// <param name="columns">The names of the columns.</param>
/// <param name="values">The values for the columns in the same order as the names.</param>
/// <param name="where">A where clause to limit the update</param>
/// <returns></returns>
int Update(string table, string[] columns, string[] values, string where);
IDbCommand GetCommand();
void ExecuteSchemaBuilder(SchemaBuilder.SchemaBuilder schemaBuilder);
}
}

View file

@ -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

View file

@ -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

View file

@ -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);
}
}
}

View file

@ -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
{
/// <summary>
/// ILogger interface.
/// Implicit in this interface is that the logger will delegate actual
/// logging to the <see cref="ILogWriter"/>(s) that have been attached
/// </summary>
public interface IAttachableLogger: ILogger
{
/// <summary>
/// Attach an <see cref="ILogWriter"/>
/// </summary>
/// <param name="writer"></param>
void Attach(ILogWriter writer);
/// <summary>
/// Detach an <see cref="ILogWriter"/>
/// </summary>
/// <param name="writer"></param>
void Detach(ILogWriter writer);
}
}

View file

@ -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
{
/// <summary>
/// Handles writing a message to the log medium (i.e. file, console)
/// </summary>
public interface ILogWriter
{
/// <summary>
/// Write this message
/// </summary>
/// <param name="message"></param>
/// <param name="args"></param>
void Write(string message, params object[] args);
/// <summary>
/// Write this message, as a line
/// </summary>
/// <param name="message"></param>
/// <param name="args"></param>
void WriteLine(string message, params object[] args);
}
}

View file

@ -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
{
/// <summary>
/// Text logger for the migration mediator
/// </summary>
public class Logger : IAttachableLogger
{
private readonly bool _trace;
private readonly List<ILogWriter> _writers = new List<ILogWriter>();
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<long> 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(), "<Migration not found>");
}
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<long> 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<long> versions)
{
if (versions.Count > 0)
{
return versions[versions.Count - 1].ToString();
}
return "No migrations applied yet!";
}
}
}

View file

@ -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<long> 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<long> appliedVersions, long currentVersion)
{
_innerLogger.Finished(appliedVersions, currentVersion);
_streamWriter.Close();
}
}
}

View file

@ -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);
}
}
}

View file

@ -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
{
/// <summary>
/// ILogger interface.
/// Implicit in this interface is that the logger will delegate actual
/// logging to the <see cref="ILogWriter"/>(s) that have been attached
/// </summary>
public interface IAttachableLogger: ILogger
{
/// <summary>
/// Attach an <see cref="ILogWriter"/>
/// </summary>
/// <param name="writer"></param>
void Attach(ILogWriter writer);
/// <summary>
/// Detach an <see cref="ILogWriter"/>
/// </summary>
/// <param name="writer"></param>
void Detach(ILogWriter writer);
}
}

View file

@ -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
{
/// <summary>
/// Handles writing a message to the log medium (i.e. file, console)
/// </summary>
public interface ILogWriter
{
/// <summary>
/// Write this message
/// </summary>
/// <param name="message"></param>
/// <param name="args"></param>
void Write(string message, params object[] args);
/// <summary>
/// Write this message, as a line
/// </summary>
/// <param name="message"></param>
/// <param name="args"></param>
void WriteLine(string message, params object[] args);
}
}

View file

@ -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
{
/// <summary>
/// Text logger for the migration mediator
/// </summary>
public class Logger : IAttachableLogger
{
private readonly bool _trace;
private readonly List<ILogWriter> _writers = new List<ILogWriter>();
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<long> 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(), "<Migration not found>");
}
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<long> 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<long> versions)
{
if (versions.Count > 0)
{
return versions[versions.Count - 1].ToString();
}
return "No migrations applied yet!";
}
}
}

View file

@ -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<long> 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<long> appliedVersions, long currentVersion)
{
_innerLogger.Finished(appliedVersions, currentVersion);
_streamWriter.Close();
}
}
}

View file

@ -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
{
/// <summary>
/// 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 <c>Up()</c> method must apply the modifications (eg.: create a table)
/// and the <c>Down()</c> method must revert, or rollback the modifications
/// (eg.: delete a table).
/// <para>
/// Each migration must be decorated with the <c>[Migration(0)]</c> attribute.
/// Each migration number (0) must be unique, or else a
/// <c>DuplicatedVersionException</c> will be trown.
/// </para>
/// <para>
/// All migrations are executed inside a transaction. If an exception is
/// thrown, the transaction will be rolledback and transformations wont be
/// applied.
/// </para>
/// <para>
/// 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.:
/// <c>002_CreateTableTest.cs</c>.
/// </para>
/// <para>
/// Use the <c>Database</c> property to apply transformation and the
/// <c>Logger</c> property to output informations in the console (or other).
/// For more details on transformations see
/// <see cref="ITransformationProvider">ITransformationProvider</see>.
/// </para>
/// </summary>
/// <example>
/// The following migration creates a new Customer table.
/// (File <c>003_AddCustomerTable.cs</c>)
/// <code>
/// [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");
/// }
/// }
/// </code>
/// </example>
public abstract class Migration : IMigration
{
private ITransformationProvider _transformationProvider;
public string Name
{
get { return StringUtils.ToHumanName(GetType().Name); }
}
/// <summary>
/// Defines tranformations to port the database to the current version.
/// </summary>
public abstract void Up();
/// <summary>
/// This is run after the Up transaction has been committed
/// </summary>
public virtual void AfterUp()
{
}
/// <summary>
/// Defines transformations to revert things done in <c>Up</c>.
/// </summary>
public abstract void Down();
/// <summary>
/// This is run after the Down transaction has been committed
/// </summary>
public virtual void AfterDown()
{
}
/// <summary>
/// Represents the database.
/// <see cref="ITransformationProvider"></see>.
/// </summary>
/// <seealso cref="ITransformationProvider">Migration.Framework.ITransformationProvider</seealso>
public ITransformationProvider Database
{
get { return _transformationProvider; }
set { _transformationProvider = value; }
}
/// <summary>
/// This gets called once on the first migration object.
/// </summary>
public virtual void InitializeOnce(string[] args)
{
}
}
}

View file

@ -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
{
/// <summary>
/// Describe a migration
/// </summary>
public class MigrationAttribute : Attribute
{
private long _version;
private bool _ignore = false;
/// <summary>
/// Describe the migration
/// </summary>
/// <param name="version">The unique version of the migration.</param>
public MigrationAttribute(long version)
{
Version = version;
}
/// <summary>
/// The version reflected by the migration
/// </summary>
public long Version
{
get { return _version; }
private set { _version = value; }
}
/// <summary>
/// Set to <c>true</c> to ignore this migration.
/// </summary>
public bool Ignore
{
get { return _ignore; }
set { _ignore = value; }
}
}
}

View file

@ -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
{
/// <summary>
/// Base class for migration errors.
/// </summary>
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) {}
}
}

View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{5270F048-E580-486C-B14C-E5B9F6E539D4}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Migrator.Framework</RootNamespace>
<AssemblyName>Migrator.Framework</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>MigratorDotNet.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
</ItemGroup>
<ItemGroup>
<Compile Include="Column.cs" />
<Compile Include="ColumnProperty.cs" />
<Compile Include="ForeignKeyConstraint.cs" />
<Compile Include="IColumn.cs" />
<Compile Include="ILogger.cs" />
<Compile Include="IMigration.cs" />
<Compile Include="ITransformationProvider.cs" />
<Compile Include="Loggers\ConsoleWriter.cs" />
<Compile Include="Loggers\IAttachableLogger.cs" />
<Compile Include="Loggers\ILogWriter.cs" />
<Compile Include="Loggers\Logger.cs" />
<Compile Include="Loggers\SqlScriptFileLogger.cs" />
<Compile Include="Migration.cs" />
<Compile Include="MigrationAttribute.cs" />
<Compile Include="MigrationException.cs" />
<Compile Include="SchemaBuilder\AddColumnExpression.cs" />
<Compile Include="SchemaBuilder\AddTableExpression.cs" />
<Compile Include="SchemaBuilder\DeleteTableExpression.cs" />
<Compile Include="SchemaBuilder\FluentColumn.cs" />
<Compile Include="SchemaBuilder\ForeignKey.cs" />
<Compile Include="SchemaBuilder\IColumnOptions.cs" />
<Compile Include="SchemaBuilder\IDeleteTableOptions.cs" />
<Compile Include="SchemaBuilder\IFluentColumn.cs" />
<Compile Include="SchemaBuilder\IForeignKeyOptions.cs" />
<Compile Include="SchemaBuilder\ISchemaBuilderExpression.cs" />
<Compile Include="SchemaBuilder\RenameTableExpression.cs" />
<Compile Include="SchemaBuilder\SchemaBuilder.cs" />
<Compile Include="StringUtils.cs" />
</ItemGroup>
<ItemGroup>
<None Include="MigratorDotNet.snk" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Binary file not shown.

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,5 @@
K 13
svn:mergeinfo
V 0
END

View file

@ -0,0 +1,5 @@
K 13
svn:mergeinfo
V 0
END

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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; }
}
}
}

View file

@ -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; }
}
}
}

View file

@ -0,0 +1,13 @@
using System.Data;
namespace Migrator.Framework.SchemaBuilder
{
public interface IColumnOptions
{
SchemaBuilder OfType(DbType dbType);
SchemaBuilder WithSize(int size);
IForeignKeyOptions AsForeignKey();
}
}

View file

@ -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);
}
}

View file

@ -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; }
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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<ISchemaBuilderExpression> _exprs;
public SchemaBuilder()
{
_exprs = new List<ISchemaBuilderExpression>();
}
public IEnumerable<ISchemaBuilderExpression> Expressions
{
get { return _exprs; }
}
/// <summary>
/// Adds a Table to be created to the Schema
/// </summary>
/// <param name="name">Table name to be created</param>
/// <returns>SchemaBuilder for chaining</returns>
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;
}
/// <summary>
/// Reference an existing table.
/// </summary>
/// <param name="newName">Table to reference</param>
/// <returns>SchemaBuilder for chaining</returns>
public SchemaBuilder RenameTable(string newName)
{
if (string.IsNullOrEmpty(newName))
throw new ArgumentNullException("newName");
_exprs.Add(new RenameTableExpression(_currentTable, newName));
_currentTable = newName;
return this;
}
/// <summary>
/// Reference an existing table.
/// </summary>
/// <param name="name">Table to reference</param>
/// <returns>SchemaBuilder for chaining</returns>
public SchemaBuilder WithTable(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
_currentTable = name;
return this;
}
/// <summary>
/// Adds a Column to be created
/// </summary>
/// <param name="name">Column name to be added</param>
/// <returns>IColumnOptions to restrict chaining</returns>
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;
}
}
}

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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; }
}
}
}

View file

@ -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; }
}
}
}

View file

@ -0,0 +1,13 @@
using System.Data;
namespace Migrator.Framework.SchemaBuilder
{
public interface IColumnOptions
{
SchemaBuilder OfType(DbType dbType);
SchemaBuilder WithSize(int size);
IForeignKeyOptions AsForeignKey();
}
}

View file

@ -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);
}
}

View file

@ -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; }
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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<ISchemaBuilderExpression> _exprs;
public SchemaBuilder()
{
_exprs = new List<ISchemaBuilderExpression>();
}
public IEnumerable<ISchemaBuilderExpression> Expressions
{
get { return _exprs; }
}
/// <summary>
/// Adds a Table to be created to the Schema
/// </summary>
/// <param name="name">Table name to be created</param>
/// <returns>SchemaBuilder for chaining</returns>
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;
}
/// <summary>
/// Reference an existing table.
/// </summary>
/// <param name="newName">Table to reference</param>
/// <returns>SchemaBuilder for chaining</returns>
public SchemaBuilder RenameTable(string newName)
{
if (string.IsNullOrEmpty(newName))
throw new ArgumentNullException("newName");
_exprs.Add(new RenameTableExpression(_currentTable, newName));
_currentTable = newName;
return this;
}
/// <summary>
/// Reference an existing table.
/// </summary>
/// <param name="name">Table to reference</param>
/// <returns>SchemaBuilder for chaining</returns>
public SchemaBuilder WithTable(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
_currentTable = name;
return this;
}
/// <summary>
/// Adds a Column to be created
/// </summary>
/// <param name="name">Column name to be added</param>
/// <returns>IColumnOptions to restrict chaining</returns>
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;
}
}
}

View file

@ -0,0 +1,43 @@
using System.Text;
using System.Text.RegularExpressions;
namespace Migrator.Framework
{
public class StringUtils
{
/// <summary>
/// Convert a classname to something more readable.
/// ex.: CreateATable => Create a table
/// </summary>
/// <param name="className"></param>
/// <returns></returns>
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();
}
/// <summary>
///
/// </summary>
/// <param name="template"></param>
/// <param name="placeholder"></param>
/// <param name="replacement"></param>
/// <returns></returns>
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();
}
}
}
}