forked from thomasjo/manatee
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
189 lines (176 loc) · 9.02 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using Manatee;
using System.IO;
using System.Text.RegularExpressions;
namespace VidPub.Tasks {
class Program {
static Migrator _development;
static Migrator _test;
static Migrator _production;
//this will allow you to sync a test DB with your dev DB by running the same migrations
//there
static bool _syncTestDB = Convert.ToBoolean(ConfigurationManager.AppSettings["SyncTestDatabase"]);
static string[] _args;
static void Main(string[] args) {
var migrationDir = LocateMigrations();
_args = args;
_development = new Migrator(migrationDir, "development");
_test = new Migrator(migrationDir, "test",silent:true);
_production = new Migrator(migrationDir, "production");
SayHello();
}
static string GetNameStub() {
var nextMigration = _development.LastVersion+1;
if (nextMigration < 10) {
return string.Format("00{0}", nextMigration);
} else if (nextMigration < 100) {
return string.Format("0{0}", nextMigration);
} else {
return string.Format("{0}", nextMigration);
}
}
static void Generate(string name) {
//drop the name to lower, add _'s, and an extension
var splits = name.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
var fileName = name.ToLower().Replace(" ", "_") + ".js";
var template = Templates.Blank;
//timestamp it
var formattedName = string.Format("{0}_{1}", GetNameStub(), fileName);
if (fileName.StartsWith("create")) {
template = Templates.CreateTable;
var tableName = name.Replace("create_", "").Replace("Create_","");
template = template.Replace("my_table", tableName);
} else if (fileName.StartsWith("add")) {
template = Templates.AddColumn;
} else if (fileName.StartsWith("index")) {
template = Templates.AddIndex;
} else if (fileName.StartsWith("fk") || fileName.StartsWith("foreign_key")) {
template = Templates.FK;
}
var migrationPath = Path.Combine(LocateMigrations(),formattedName);
using (var stream = new FileStream(migrationPath, FileMode.Create)) {
var chars = template.ToCharArray();
var bits = new ASCIIEncoding().GetBytes(chars);
stream.Write(bits,0,bits.Length);
}
}
static int WhichVersion(string command) {
int result = -1;
var stems = command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < stems.Length; i++) {
var bit = stems[i];
if (bit == "/v")
int.TryParse(stems[i + 1], out result);
}
return result;
}
static bool ShouldExecute(string command) {
var stems = command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < stems.Length; i++) {
var bit = stems[i];
if (bit == "/p")
return false;
}
return true ;
}
static void DecideWhatToDo(string command){
int version = WhichVersion(command);
bool shouldExecute = ShouldExecute(command);
if(command.StartsWith("up")){
if (version < 0)
version = _development.LastVersion;
//roll it to the top
_development.Migrate(version, execute: shouldExecute);
if(_syncTestDB)
_test.Migrate(version, execute: shouldExecute);
}else if(command.StartsWith("g") || command.StartsWith("c")){
Console.WriteLine("Generating a Migration...");
var name = command.Replace("g ", "").Replace("c ", "");
Generate(name);
}else if(command.StartsWith("down") || command.StartsWith("back") || command.StartsWith("rollback")){
//go back one if the version isn't specified
if (version < 0)
version = _development.CurrentVersion - 1;
_development.Migrate(version, execute: shouldExecute);
if (_syncTestDB)
_test.Migrate(version, execute: shouldExecute);
} else if (command.StartsWith("migrate")) {
if (version < 0)
version = _development.LastVersion;
_development.Migrate(version, execute: shouldExecute);
if (_syncTestDB)
_test.Migrate(version, execute: shouldExecute);
} else if (command.StartsWith("exit") || command.StartsWith("quit")) {
Environment.Exit(1);
return;
}else if(command.StartsWith("list")){
ListMigrations();
} else if (command.StartsWith("push")) {
//send it to production
_production.Migrate();
}else{
HelpEmOut();
}
Console.WriteLine("Done! What next?");
var cmd = Console.ReadLine();
DecideWhatToDo(cmd);
}
static void ListMigrations(){
var migrationDir = new DirectoryInfo(LocateMigrations());
var files = migrationDir.GetFiles();
var reg = new Regex("\\d");
var counter = 1;
var currentVersion = _development.CurrentVersion;
foreach (var file in files)
{
var wasRun = "-";
if (counter > currentVersion)
wasRun = "+";
var fileName = Path.GetFileNameWithoutExtension(file.Name);
var migName = reg.Replace(fileName, "").Trim().Replace("_", " ");
Console.WriteLine("{0} {1}",wasRun,migName);
counter++;
}
}
static void HelpEmOut(){
Console.WriteLine("You can say 'up', 'down', or 'migrate' with some arguments. Those arguments are:");
Console.WriteLine(" ... /v - this is the version number to go up or down to. To wipe our your DB, /v 0");
Console.WriteLine(" ... /p - Print out the commands only");
Console.WriteLine(" ... 'back' or rollback goes back a single version");
Console.WriteLine(" ... 'up' will run every migration not run");
Console.WriteLine(" ... 'exit' or 'quit' will... well you know.");
Console.WriteLine(" ... 'list' will roll out a list of all the migrations");
Console.WriteLine(" ... 'create', 'generate', or just 'c' or 'g' stub out a template for you and stick it in your migrations directory");
Console.WriteLine(" ... 'push' will send your database changes up to your Production box");
Console.WriteLine(" ... When you generate a migration, be sure to use good naming - I'll do my best to stup it out for you.");
Console.WriteLine(" ... - for instance, if you use a name like 'create_mytable' - I'll know to stub out create syntax for you");
Console.WriteLine(" ... - the trick is to start the name with the operation. If you do, I'll do the right thing");
Console.WriteLine(" ... - create_ will do a create table, add_ will add a column, index_ will create an index template, fk_ will create an FK template");
Console.WriteLine(" ... - finally - if you name it with _'s, I'll do my best to figure out a table, column, or index name");
Console.WriteLine("----------------------------------------------------------------------------------");
Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
var command = Console.ReadLine();
DecideWhatToDo(command);
}
static void SayHello() {
Console.WriteLine("Manatee - Migrations for .NET");
Console.WriteLine("Current DB Version: {0}",_development.CurrentVersion);
Console.WriteLine("You have {0} migrations with {1} un-run. Type 'list' to see more details", _development.LastVersion, _development.LastVersion - _development.CurrentVersion);
Console.WriteLine(">> (type 'h' or 'help' for assistance)");
var command = Console.ReadLine();
DecideWhatToDo(command);
}
static string LocateMigrations() {
//this is the bin/release or bin/debug
var binDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
//get the root - go up two levels
var rootDirectory = binDirectory.Parent.Parent;
//return the Migrations directory
return Path.Combine(rootDirectory.FullName, "Migrations");
}
}
}