|
#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.Reflection;
using System.IO;
using Migrator.Tools;
using System.Collections.Generic;
using System.Collections;
using System.Runtime.InteropServices;
namespace Migrator.MigratorConsole
{
/// <summary>
/// Commande line utility to run the migrations
/// </summary>
/// </remarks>
public class MigratorConsole
{
private string _provider;
private string _connectionString;
private string _migrationsAssembly;
private bool _list = false;
private bool _trace = false;
private string _dumpTo;
private int _migrateTo = -1;
private bool _migrateUp = false;
private bool _migrateDown = false;
private bool allParamsSpecified = true;
/// <summary>
/// Builds a new console
/// </summary>
/// <param name="argv">Command line arguments</param>
public MigratorConsole(string[] argv)
{
System.Threading.Thread.Sleep(1000);
Console.Out.WriteLine("Migrator.Console.exe started....");
try
{
ParseArguments(argv);
}
catch (ArgumentException ex)
{
Console.Out.Write(ex.Message);
allParamsSpecified = false;
}
}
/// <summary>
/// Run the migrator's console
/// </summary>
/// <returns>-1 if error, else 0</returns>
public int Run()
{
if (!allParamsSpecified)
return 1;
try
{
if (_list)
List();
else if (_dumpTo != null)
Dump();
else
Migrate();
}
catch (ArgumentException aex)
{
Console.WriteLine("Invalid argument '{0}' : {1}", aex.ParamName, aex.Message);
Console.WriteLine();
PrintUsage();
return -1;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return -1;
}
return 0;
}
/// <summary>
/// Runs the migrations.
/// </summary>
public void Migrate()
{
CheckArguments();
Migrator mig = GetMigrator();
if (_migrateUp)
mig.MigrateUp();
else if (_migrateDown)
mig.MigrateDown();
else if (_migrateTo == -1)
mig.MigrateToLastVersion();
else
mig.MigrateTo(_migrateTo);
}
/// <summary>
/// List migrations.
/// </summary>
public void List()
{
CheckArguments();
Migrator mig = GetMigrator();
int currentVersion = mig.CurrentVersion;
Console.WriteLine("Available migrations:");
foreach (Type t in mig.MigrationsTypes)
{
int v = Migrator.GetMigrationVersion(t);
Console.WriteLine("{0} {1} {2}",
v == currentVersion ? "=>" : " ",
v.ToString().PadLeft(3),
Migrator.GetMigrationDescription(t)
);
}
}
public void Dump()
{
CheckArguments();
SchemaDumper dumper = new SchemaDumper(_provider, _connectionString);
dumper.DumpTo(_dumpTo);
}
/// <summary>
/// Show usage information and help.
/// </summary>
public void PrintUsage()
{
int tab = 17;
Version ver = Assembly.GetExecutingAssembly().GetName().Version;
Console.WriteLine("Database migrator - v{0}.{1}.{2}", ver.Major, ver.Minor, ver.Revision);
Console.WriteLine();
Console.WriteLine("usage:\nMigrator.Console.exe provider connectionString migrationsAssembly [options]");
Console.WriteLine();
Console.WriteLine("\t{0} {1}", "provider".PadRight(tab), "The database provider (SqlServer, MySql, Postgre)");
Console.WriteLine("\t{0} {1}", "connectionString".PadRight(tab), "Connection string to the database");
Console.WriteLine("\t{0} {1}", "migrationAssembly".PadRight(tab), "Path to the assembly containing the migrations");
Console.WriteLine("Options:");
Console.WriteLine("\t-{0}{1}", "to=<version>".PadRight(tab), "Migrats to specified version");
Console.WriteLine("\t-{0}{1}", "up".PadRight(tab), "Migrates up a version");
Console.WriteLine("\t-{0}{1}", "down".PadRight(tab), "Migrates down a version");
Console.WriteLine("\t-{0}{1}", "list".PadRight(tab), "List migrations");
Console.WriteLine("\t-{0}{1}", "trace".PadRight(tab), "Show debug informations");
Console.WriteLine();
Console.WriteLine("-up, -down, and -to options are mutually exclusive");
}
#region Private helper methods
private Assembly GetAssembly()
{
return Assembly.LoadFrom(_migrationsAssembly); ;
}
private Migration GetBeginMigration()
{
foreach (Type t in GetAssembly().GetTypes())
{
MigrationBeginAttribute attrib = (MigrationBeginAttribute)
Attribute.GetCustomAttribute(t, typeof(MigrationBeginAttribute));
if (attrib != null && typeof(Migration).IsAssignableFrom(t))
{
return (Migration)Activator.CreateInstance(t);
}
}
return new NullMigration();
}
private Migration GetEndMigration()
{
foreach (Type t in GetAssembly().GetTypes())
{
MigrationEndAttribute attrib = (MigrationEndAttribute)
Attribute.GetCustomAttribute(t, typeof(MigrationEndAttribute));
if (attrib != null && typeof(Migration).IsAssignableFrom(t))
{
return (Migration)Activator.CreateInstance(t);
}
}
return new NullMigration();
}
private ArrayList GetGeneralMigrations()
{
ArrayList migrations = new ArrayList();
foreach (Type t in GetAssembly().GetTypes())
{
MigrationAttribute attrib = (MigrationAttribute)
Attribute.GetCustomAttribute(t, typeof(MigrationAttribute));
if (attrib != null && typeof(Migration).IsAssignableFrom(t))
{
if (!attrib.Ignore)
{
migrations.Add(t);
}
}
}
migrations.Sort(new MigrationTypeComparer(true));
return migrations;
}
private void CheckArguments()
{
if (_connectionString == null)
throw new ArgumentException("Connection string missing", "connectionString");
if (_migrationsAssembly == null)
throw new ArgumentException("Migrations assembly missing", "migrationsAssembly");
}
private Migrator GetMigrator()
{
GuidAttribute guidAttribute = (GuidAttribute)Attribute.GetCustomAttribute(GetAssembly(), typeof(GuidAttribute));
// This is done incase we are scanning a 4.0 dll, the console is compiled against 4.0 so it can do all the assembly scanning
var logger = new Loggers.ConsoleLogger(_trace);
return new Migrator(_provider, _connectionString, GetGeneralMigrations(), GetBeginMigration(), GetEndMigration(), guidAttribute, logger);
}
private void ParseArguments(string[] argv)
{
for (int i = 0; i < argv.Length; i++)
{
if (argv[i].ToLower().Equals("-list"))
{
_list = true;
}
else if (argv[i].ToLower().Equals("-trace"))
{
_trace = true;
}
else if (argv[i].ToLower().StartsWith("-to="))
{
if (!int.TryParse(argv[i].ToLower().Replace("-to=", ""), out _migrateTo))
throw new ArgumentException("migrate to values must be integers");
}
else if (argv[i].ToLower().Equals("-up"))
{
_migrateUp = true;
}
else if (argv[i].ToLower().Equals("-down"))
{
_migrateDown = true;
}
else
{
if (i == 0) _provider = argv[i];
if (i == 1) _connectionString = argv[i];
if (i == 2) _migrationsAssembly = argv[i];
}
}
List<String> messages = new List<String>();
if (!_list && argv.Length > 0)
{
if (!(_migrateUp ^ _migrateDown ^ _migrateTo > 0) && !(_migrateTo < 0)) messages.Add("You must specify only one up, down, or to command.");
if (_provider == null) messages.Add("Provider not specified (SqlServer, MySql, Postgre).");
if (_connectionString == null) messages.Add("Connection string not specified.");
if (_migrationsAssembly == null) messages.Add("Migration assembly not specified");
if (messages.Count > 0)
throw new ArgumentException("\n\n" + String.Join(" \n", messages.ToArray()) + "\n\n");
}
}
#endregion
}
}
|
Loading...