Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for MySQL databases was added into RoundhousE #3

Merged
merged 7 commits into from
Jun 20, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.custom/ilmergeDLL.build
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<include name="${dirs.merge.from}\*.exe" />
<include name="${dirs.merge.from}\NHibernate.JetDriver.dll" />
<include name="${dirs.merge.from}\StructureMap.dll" />
<include name="${dirs.merge.from}\MySql.Data.dll" />
</items>
</in>
<do>
Expand Down Expand Up @@ -93,6 +94,7 @@
<include name="NHibernate.JetDriver.dll" />
<include name="StructureMap.dll" />
<include name="Microsoft.Build.Framework.*" />
<include name="MySql.Data.dll" />
</fileset>
</delete>
</target>
Expand Down
Binary file added lib/MySqlConnector/MySql.Data.dll
Binary file not shown.
Binary file added lib/NUnit/nunit.framework.dll
Binary file not shown.
10,385 changes: 10,385 additions & 0 deletions lib/NUnit/nunit.framework.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion product/roundhouse.console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace roundhouse.console
using infrastructure.app.logging;
using infrastructure.extensions;

internal class Program
public class Program
{
private static readonly ILog the_logger = LogManager.GetLogger(typeof(Program));

Expand Down
4 changes: 4 additions & 0 deletions product/roundhouse.console/roundhouse.console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down
61 changes: 61 additions & 0 deletions product/roundhouse.databases.mysql/MySqlAdoNetProviderResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Reflection;
using roundhouse.infrastructure;
// ReSharper disable InconsistentNaming

namespace roundhouse.databases.mysql
{
public class MySqlAdoNetProviderResolver
{
private readonly bool is_merged;

public MySqlAdoNetProviderResolver()
{
is_merged = Assembly.GetExecutingAssembly().GetName().Name
== ApplicationParameters.get_merged_assembly_name();
}

public void register_db_provider_factory()
{
var dataSet = (DataSet)ConfigurationManager.GetSection("system.data");

var mySqlClientRow = dataSet.Tables[0]
.AsEnumerable()
.Where(x => x.Field<string>(2) == "MySql.Data.MySqlClient")
.SingleOrDefault();

if (mySqlClientRow != null)
{
dataSet.Tables[0].Rows.Remove(mySqlClientRow);
}

var clientFactoryType = is_merged
? "MySql.Data.MySqlClient.MySqlClientFactory, " + ApplicationParameters.get_merged_assembly_name()
: "MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data";

dataSet.Tables[0].Rows.Add(
"MySQL Data Provider",
".Net Framework Data Provider for MySQL",
"MySql.Data.MySqlClient",
clientFactoryType);
}

public void enable_loading_from_merged_assembly()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => load_MySqlData_assembly(e.Name);
}

private Assembly load_MySqlData_assembly(string assemblyName)
{
if (is_merged && assemblyName == "MySql.Data")
{
return Assembly.GetExecutingAssembly();
}

return null;
}
}
}
94 changes: 94 additions & 0 deletions product/roundhouse.databases.mysql/MySqlDatabase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using MySql.Data.MySqlClient;
// ReSharper disable InconsistentNaming

namespace roundhouse.databases.mysql
{
using System;
using infrastructure.app;
using infrastructure.extensions;

public class MySqlDatabase : AdoNetDatabase
{
private readonly MySqlAdoNetProviderResolver _mySqlAdoNetProviderResolver;

public MySqlDatabase()
{
_mySqlAdoNetProviderResolver = new MySqlAdoNetProviderResolver();
_mySqlAdoNetProviderResolver.register_db_provider_factory();
_mySqlAdoNetProviderResolver.enable_loading_from_merged_assembly();
}

public override bool split_batch_statements
{
get { return false; }
set { throw new Exception("This options could not be changed because MySQL database migrator always splits batch statements by using MySqlScript class from MySQL ADO.NET provider"); }
}

public override void initialize_connections(ConfigurationPropertyHolder configuration_property_holder)
{
// IMO in this method SqlServerDatabase and OracleDatabase implementations has unmaintainable code,
// I'm not sure that DbConnectionStringBuilder could be useful here but I will just skip all parsing code.
// The main goal of pasing is to get full connection string and put it into configuration_property_holder.ConnectionString.

configuration_property_holder.ConnectionString = connection_string;

set_provider();
if (string.IsNullOrEmpty(admin_connection_string))
{
var builder = new MySqlConnectionStringBuilder(connection_string);
builder.Database = "information_schema";
admin_connection_string = builder.ConnectionString;
}

// TODO: Initialize configuration/system.data/DbProviderFactories app.config section in code.
}

public override void set_provider()
{
// TODO Investigate how to get provider name using MySQL API instead of hardcoded string.
// http://stackoverflow.com/questions/1216626/how-to-use-ado-net-dbproviderfactory-with-mysql/1216887#1216887
provider = "MySql.Data.MySqlClient";
}

public override string create_database_script()
{
return string.Format(
@"CREATE DATABASE IF NOT EXISTS `{0}`;",
database_name);
}

public override void run_database_specific_tasks()
{
// TODO Do we need anything for MySQL? For ex MS SQL Server implemenation has schema creation script and Oracle creates db-sequences.
// TODO MS SQL Server could support different database schema for migration tables but MySQL doesn't support this actually.
// For MySQL CREATE SCHEMA just alias to CREATE DATABASE
}

// http://bugs.mysql.com/bug.php?id=46429
public override void run_sql(string sql_to_run)
{
if (string.IsNullOrEmpty(sql_to_run)) return;

// TODO Investigate how pass CommandTimeout into commands which will be during MySqlScript execution.
var connection = server_connection.underlying_type().downcast_to<MySqlConnection>();
var script = new MySqlScript(connection, sql_to_run);
script.Execute();
}

public override string set_recovery_mode_script(bool simple)
{
// TODO Do MySQL has recovery modes which could be initialized by running SQL statement?
return string.Empty;
}

public override string restore_database_script(string restore_from_path, string custom_restore_options)
{
throw new NotImplementedException();
}

public override string delete_database_script()
{
throw new NotImplementedException();
}
}
}
35 changes: 35 additions & 0 deletions product/roundhouse.databases.mysql/orm/ScriptsRunErrorMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// ReSharper disable DoNotCallOverridableMethodsInConstructor

namespace roundhouse.databases.mysql.orm
{
using System;
using FluentNHibernate.Mapping;
using infrastructure;
using model;

[CLSCompliant(false)]
public class ScriptsRunErrorMapping : ClassMap<ScriptsRunError>
{
public ScriptsRunErrorMapping()
{
HibernateMapping.Schema(ApplicationParameters.CurrentMappings.roundhouse_schema_name);
Table(ApplicationParameters.CurrentMappings.scripts_run_errors_table_name);
Not.LazyLoad();
HibernateMapping.DefaultAccess.Property();
HibernateMapping.DefaultCascade.SaveUpdate();

Id(x => x.id).Column("id").GeneratedBy.Identity().UnsavedValue(0);
Map(x => x.repository_path);
Map(x => x.version).Length(50);
Map(x => x.script_name);
Map(x => x.text_of_script).CustomSqlType("mediumtext");
Map(x => x.erroneous_part_of_script).CustomSqlType("mediumtext");
Map(x => x.error_message).CustomSqlType("mediumtext");

//audit
Map(x => x.entry_date);
Map(x => x.modified_date);
Map(x => x.entered_by).Length(50);
}
}
}
34 changes: 34 additions & 0 deletions product/roundhouse.databases.mysql/orm/ScriptsRunMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// ReSharper disable DoNotCallOverridableMethodsInConstructor

namespace roundhouse.databases.mysql.orm
{
using System;
using FluentNHibernate.Mapping;
using infrastructure;
using model;

[CLSCompliant(false)]
public class ScriptsRunMapping : ClassMap<ScriptsRun>
{
public ScriptsRunMapping()
{
HibernateMapping.Schema(ApplicationParameters.CurrentMappings.roundhouse_schema_name);
Table(ApplicationParameters.CurrentMappings.scripts_run_table_name);
Not.LazyLoad();
HibernateMapping.DefaultAccess.Property();
HibernateMapping.DefaultCascade.SaveUpdate();

Id(x => x.id).Column("id").GeneratedBy.Identity().UnsavedValue(0);
Map(x => x.version_id);
Map(x => x.script_name);
Map(x => x.text_of_script).CustomSqlType("mediumtext");
Map(x => x.text_hash).Length(512);
Map(x => x.one_time_script);

//audit
Map(x => x.entry_date);
Map(x => x.modified_date);
Map(x => x.entered_by).Length(50);
}
}
}
31 changes: 31 additions & 0 deletions product/roundhouse.databases.mysql/orm/VersionMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// ReSharper disable RedundantNameQualifier
// ReSharper disable DoNotCallOverridableMethodsInConstructor

namespace roundhouse.databases.mysql.orm
{
using System;
using FluentNHibernate.Mapping;
using infrastructure;

[CLSCompliant(false)]
public class VersionMapping : ClassMap<roundhouse.model.Version>
{
public VersionMapping()
{
HibernateMapping.Schema(ApplicationParameters.CurrentMappings.roundhouse_schema_name);
Table(ApplicationParameters.CurrentMappings.version_table_name);
Not.LazyLoad();
HibernateMapping.DefaultAccess.Property();
HibernateMapping.DefaultCascade.SaveUpdate();

Id(x => x.id).Column("id").GeneratedBy.Identity().UnsavedValue(0);
Map(x => x.repository_path);
Map(x => x.version).Length(50);

//audit
Map(x => x.entry_date);
Map(x => x.modified_date);
Map(x => x.entered_by).Length(50);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,31 @@
<Reference Include="NHibernate.ByteCode.Castle">
<HintPath>..\..\packages\NHibernate.Castle.3.1.0.4000\lib\Net35\NHibernate.ByteCode.Castle.dll</HintPath>
</Reference>
<Reference Include="MySql.Data, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\MySqlConnector\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\SolutionVersion.cs">
<Link>Properties\SolutionVersion.cs</Link>
</Compile>
<Compile Include="MySqlAdoNetProviderResolver.cs" />
<Compile Include="MySqlDatabase.cs" />
<Compile Include="orm\ScriptsRunErrorMapping.cs" />
<Compile Include="orm\ScriptsRunMapping.cs" />
<Compile Include="orm\VersionMapping.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ItemGroup> <ProjectReference Include="..\roundhouse\roundhouse.csproj"> <Project>{A95DE649-D5BA-4402-9D9C-3D8D67E2FF44}</Project> <Name>roundhouse</Name> </ProjectReference> </ItemGroup> <ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
Expand Down
32 changes: 32 additions & 0 deletions product/roundhouse.tests.integration/MySQLDatabaseTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using roundhouse.console;
using roundhouse.consoles;
using roundhouse.databases.mysql;
using roundhouse.infrastructure.app.logging;
using roundhouse.migrators;
using TestFixtureAttribute = NUnit.Framework.TestFixtureAttribute;
using TestAttribute = NUnit.Framework.TestAttribute;
// ReSharper disable InconsistentNaming

namespace roundhouse.tests.integration
{
[TestFixture]
public class MySQLDatabaseTest
{
[Test]
public void Debug_migrator()
{
var args = new []
{
@"/db=TestRoundhousE",
@"/f=..\..\db\MySQL\TestRoundhousE",
//@"/cs=server=localhost;uid=username;Password=password;database=TestRoundhousE;",
@"/cs=server=tcdev02;uid=alexey.diyan;Password=03ambul19G;database=TestRoundhousE;",
@"/dt=roundhouse.databases.mysql.MySqlDatabase, roundhouse.databases.mysql",
@"/schemaname=TestRoundhousE"
};

Log4NetAppender.configure();
Program.run_migrator(Program.set_up_configuration_and_build_the_container(args));
}
}
}
Loading