migsql 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/migsql +1 -1
- data/lib/migsql/app.rb +50 -36
- data/lib/migsql/migration.rb +35 -46
- data/lib/migsql/sqlserver.rb +13 -32
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a4290a355bd2a6c5a68be7f11db3ae46f48f877
|
4
|
+
data.tar.gz: 87ff7d1ca701dab1570acb45c443d05b32565ad4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 501d32de6a8ed95adaf753f920d735f6c92d7c6c125a1e61bfc51206ba8af012128fc2eb8bab0459d8d442553f02424f38e519ef7f585d4859d906179bf6798d
|
7
|
+
data.tar.gz: 69cde86f82c4552a81a8ff1337f93ed7b0c03b4fe0ed751478f814125e7edc6a2c8846385f830f37abf586dd845a97da597bc634057d2bc1b23cc95a6248325d
|
data/bin/migsql
CHANGED
data/lib/migsql/app.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'colorize'
|
2
2
|
class MigSql
|
3
|
-
|
4
3
|
def initialize
|
5
4
|
@migration = Migration.new './db/config.yml'
|
6
5
|
@migration.load
|
@@ -9,15 +8,15 @@ class MigSql
|
|
9
8
|
def handle_argv(argv)
|
10
9
|
if argv.length == 0
|
11
10
|
puts 'Usage: migsql {init|create-migration|migrate}'.white
|
12
|
-
else
|
11
|
+
else
|
13
12
|
case argv[0]
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
13
|
+
when 'init'
|
14
|
+
handle_init
|
15
|
+
when 'create-migration'
|
16
|
+
handle_create_migration argv
|
17
|
+
when 'migrate'
|
18
|
+
handle_migrate argv
|
19
|
+
end
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
@@ -25,22 +24,27 @@ class MigSql
|
|
25
24
|
if File.directory?('./db')
|
26
25
|
puts 'Error: the ./db directory already exists'.red
|
27
26
|
else
|
28
|
-
@migration.create_server
|
27
|
+
@migration.create_server(
|
28
|
+
'example_database',
|
29
|
+
'127.0.0.1',
|
30
|
+
'dbname',
|
31
|
+
'username',
|
32
|
+
'password'
|
33
|
+
)
|
29
34
|
@migration.save
|
30
35
|
puts 'Default configuration created in ./db/config.yml'.green
|
31
36
|
end
|
32
|
-
end
|
37
|
+
end
|
33
38
|
|
34
39
|
def handle_create_migration(argv)
|
35
40
|
migration_name = argv[1]
|
36
41
|
migration_server = get_migration_server(argv[2])
|
37
|
-
|
38
|
-
|
39
|
-
end
|
42
|
+
@migration.create_migration migration_server, migration_name\
|
43
|
+
unless migration_server.nil?
|
40
44
|
end
|
41
45
|
|
42
46
|
def handle_migrate(argv)
|
43
|
-
if argv[1] == 'to'
|
47
|
+
if argv[1] == 'to'
|
44
48
|
migration_server = @migration.get_first_server_name
|
45
49
|
migration_target = argv[2]
|
46
50
|
else
|
@@ -48,37 +52,47 @@ class MigSql
|
|
48
52
|
migration_target = argv[3]
|
49
53
|
end
|
50
54
|
o_target = migration_target
|
51
|
-
if
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
55
|
+
return if migration_server.nil?
|
56
|
+
migration_target = get_migration_target(migration_server, migration_target)
|
57
|
+
if !migration_target.nil?
|
58
|
+
from = @migration.get_migration_status(migration_server)
|
59
|
+
plan = calculate_migration_plan(migration_server, migration_target, from)
|
60
|
+
@migration.apply_migration_plan(migration_server, plan, migration_target)\
|
61
|
+
unless plan.nil?
|
62
|
+
else
|
63
|
+
puts "Error: No migration found with name: #{o_target}".red
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def calculate_migration_plan(migration_server, to, from)
|
68
|
+
@migration.get_migration_plan(
|
69
|
+
migration_server,
|
70
|
+
to,
|
71
|
+
from
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_migration_target(migration_server, migration_target)
|
76
|
+
if migration_target.nil?
|
77
|
+
@migration.get_latest_migration(migration_server)
|
78
|
+
else
|
79
|
+
@migration.get_migration_by_name(migration_server, migration_target)
|
66
80
|
end
|
67
81
|
end
|
68
82
|
|
69
83
|
def get_migration_server(server_name)
|
70
84
|
if @migration.count_servers == 0
|
71
85
|
puts 'Error: Please run migsql init first'.red
|
86
|
+
server_name = nil
|
72
87
|
elsif @migration.count_servers > 1 && server_name.nil?
|
73
|
-
puts 'Error: Your config has multiple servers,
|
88
|
+
puts 'Error: Your config has multiple servers,
|
89
|
+
please specify which server to create the migration on'.red
|
74
90
|
elsif !server_name.nil? && @migration.get_server(server_name).nil?
|
75
91
|
puts "Error: No server named #{server_name} found in your config".red
|
76
|
-
nil
|
92
|
+
server_name = nil
|
77
93
|
elsif @migration.count_servers == 1
|
78
|
-
@migration.get_first_server_name
|
79
|
-
else
|
80
|
-
server_name
|
94
|
+
server_name = @migration.get_first_server_name
|
81
95
|
end
|
96
|
+
server_name
|
82
97
|
end
|
83
|
-
|
84
98
|
end
|
data/lib/migsql/migration.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'rake'
|
2
1
|
require 'fileutils'
|
3
2
|
require 'yaml'
|
4
3
|
require 'tiny_tds'
|
@@ -6,14 +5,14 @@ require 'colorize'
|
|
6
5
|
require_relative 'sqlserver'
|
7
6
|
|
8
7
|
class Migration
|
9
|
-
def initialize(path)
|
8
|
+
def initialize(path)
|
10
9
|
@path = path
|
11
10
|
@root = File.dirname(@path)
|
12
|
-
@servers =
|
13
|
-
end
|
11
|
+
@servers = {}
|
12
|
+
end
|
14
13
|
|
15
14
|
def create_server(name, address, database, username, password)
|
16
|
-
|
15
|
+
@servers[name] = SqlServer.new name, address, database, username, password
|
17
16
|
end
|
18
17
|
|
19
18
|
def get_server(name)
|
@@ -23,19 +22,17 @@ class Migration
|
|
23
22
|
def get_first_server_name
|
24
23
|
@servers.keys.first
|
25
24
|
end
|
26
|
-
|
25
|
+
|
27
26
|
def save
|
28
|
-
FileUtils
|
27
|
+
FileUtils.mkdir_p @root
|
29
28
|
File.open(@path, 'w') { |f| f.write @servers.to_yaml }
|
30
29
|
end
|
31
30
|
|
32
31
|
def load
|
33
|
-
if File.file?(@path)
|
34
|
-
@servers = YAML.load_file(@path)
|
35
|
-
end
|
32
|
+
@servers = YAML.load_file(@path) if File.file?(@path)
|
36
33
|
end
|
37
34
|
|
38
|
-
def count_servers
|
35
|
+
def count_servers
|
39
36
|
@servers.length
|
40
37
|
end
|
41
38
|
|
@@ -45,10 +42,9 @@ class Migration
|
|
45
42
|
server_root = "#{@root}/#{server_name}"
|
46
43
|
up = "#{server_root}/#{migration_name}_up.sql"
|
47
44
|
down = "#{server_root}/#{migration_name}_down.sql"
|
48
|
-
FileUtils
|
49
|
-
FileUtils
|
50
|
-
FileUtils
|
51
|
-
|
45
|
+
FileUtils.mkdir_p server_root
|
46
|
+
FileUtils.touch up
|
47
|
+
FileUtils.touch down
|
52
48
|
puts "Migration '#{migration_name}' created.".green
|
53
49
|
puts "Up: #{up}".white
|
54
50
|
puts "Down: #{down}".white
|
@@ -66,59 +62,55 @@ class Migration
|
|
66
62
|
end
|
67
63
|
|
68
64
|
def get_migration_plan(server_name, to, from)
|
69
|
-
to
|
65
|
+
to ||= get_latest_migration(server_name)
|
70
66
|
to_i = /([0-9]+)_?.*/.match(to).captures[0]
|
71
|
-
|
72
67
|
from_i = /([0-9]+)_?.*/.match(from).captures[0]
|
73
|
-
|
74
|
-
if to_i > from_i
|
68
|
+
if to_i > from_i
|
75
69
|
plan = get_up_plan server_name, to_i, from_i
|
76
70
|
elsif to_i < from_i
|
77
71
|
plan = get_down_plan server_name, to_i, from_i
|
78
72
|
else
|
79
73
|
puts 'No migration needed, database already at current level'.green
|
80
74
|
end
|
81
|
-
|
75
|
+
plan
|
82
76
|
end
|
83
77
|
|
84
|
-
def
|
85
|
-
plan = Array.new
|
78
|
+
def get_migration_files(server_name, direction)
|
86
79
|
server_root = "#{@root}/#{server_name}"
|
87
|
-
Dir["#{server_root}/*
|
80
|
+
Dir["#{server_root}/*_#{direction}.sql"].sort
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_up_plan(server_name, to, from)
|
84
|
+
plan = []
|
85
|
+
get_migration_files(server_name, 'up').each do |migration|
|
88
86
|
current_item = /([0-9]+)_?.*/.match(migration).captures[0]
|
89
|
-
if current_item > from && current_item <= to
|
90
|
-
|
91
|
-
end
|
92
|
-
}
|
87
|
+
plan.push(migration) if current_item > from && current_item <= to
|
88
|
+
end
|
93
89
|
plan
|
94
90
|
end
|
95
91
|
|
96
92
|
def get_down_plan(server_name, to, from)
|
97
|
-
plan =
|
98
|
-
|
99
|
-
Dir["#{server_root}/*_down.sql"].sort.reverse.each {|migration|
|
93
|
+
plan = []
|
94
|
+
get_migration_files(server_name, 'down').reverse.each do |migration|
|
100
95
|
current_item = /([0-9]+)_?.*/.match(migration).captures[0]
|
101
|
-
if current_item > to && current_item <= from
|
102
|
-
|
103
|
-
end
|
104
|
-
}
|
96
|
+
plan.push(migration) if current_item > to && current_item <= from
|
97
|
+
end
|
105
98
|
plan
|
106
99
|
end
|
107
100
|
|
108
101
|
def get_migration_by_name(server_name, name)
|
109
|
-
server_root = "#{@root}/#{server_name}"
|
102
|
+
server_root = "#{@root}/#{server_name}"
|
110
103
|
migration = Dir["#{server_root}/*#{name}_up.sql"][0]
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
return migration
|
104
|
+
migration = /([0-9]+_.*)(_up|_down)\.sql/.match(migration).captures[0]\
|
105
|
+
unless migration.nil?
|
106
|
+
migration
|
115
107
|
end
|
116
108
|
|
117
109
|
def apply_migration_plan(server_name, migration_plan, final_state)
|
118
110
|
puts "Applying migration to: #{server_name}".yellow
|
119
|
-
migration_plan.each
|
111
|
+
migration_plan.each do |migration|
|
120
112
|
apply_migration server_name, migration
|
121
|
-
|
113
|
+
end
|
122
114
|
server = get_server(server_name)
|
123
115
|
server.set_migration_status(final_state)
|
124
116
|
puts "Migration Complete, current state: #{final_state}".green
|
@@ -130,11 +122,8 @@ class Migration
|
|
130
122
|
server = get_server(server_name)
|
131
123
|
server.apply_migration(migration)
|
132
124
|
end
|
133
|
-
|
134
|
-
def get_migration_status(server_name)
|
125
|
+
|
126
|
+
def get_migration_status(server_name)
|
135
127
|
get_server(server_name).get_migration_status
|
136
128
|
end
|
137
|
-
|
138
129
|
end
|
139
|
-
|
140
|
-
|
data/lib/migsql/sqlserver.rb
CHANGED
@@ -5,7 +5,7 @@ require 'tiny_tds'
|
|
5
5
|
require 'colorize'
|
6
6
|
|
7
7
|
class SqlServer
|
8
|
-
def initialize(name, address, database, username, password)
|
8
|
+
def initialize(name, address, database, username, password)
|
9
9
|
@name = name
|
10
10
|
@address = address
|
11
11
|
@database = database
|
@@ -13,21 +13,7 @@ class SqlServer
|
|
13
13
|
@password = password
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
return @name
|
18
|
-
end
|
19
|
-
def address
|
20
|
-
return @address
|
21
|
-
end
|
22
|
-
def database
|
23
|
-
return @database
|
24
|
-
end
|
25
|
-
def username
|
26
|
-
return @username
|
27
|
-
end
|
28
|
-
def password
|
29
|
-
return @password
|
30
|
-
end
|
16
|
+
attr_reader :name, :address, :database, :username, :password
|
31
17
|
|
32
18
|
def get_sql(name)
|
33
19
|
File.read("#{File.dirname(__FILE__)}/../../sql/#{name}.sql")
|
@@ -35,8 +21,8 @@ class SqlServer
|
|
35
21
|
|
36
22
|
def get_client
|
37
23
|
TinyTds::Client.new(
|
38
|
-
:username => username,
|
39
|
-
:password => password,
|
24
|
+
:username => username,
|
25
|
+
:password => password,
|
40
26
|
:host => address,
|
41
27
|
:database => database
|
42
28
|
)
|
@@ -45,37 +31,32 @@ class SqlServer
|
|
45
31
|
def get_migration_status
|
46
32
|
client = get_client
|
47
33
|
begin
|
48
|
-
results = client.execute(
|
34
|
+
results = client.execute('SELECT migration FROM _migration')
|
49
35
|
result = results.each(:first => true)[0]['migration']
|
50
|
-
if result.length == 0
|
51
|
-
|
52
|
-
|
53
|
-
return result
|
54
|
-
end
|
55
|
-
rescue Exception => ex
|
56
|
-
return '0'
|
36
|
+
result = '0' if result.length == 0
|
37
|
+
rescue
|
38
|
+
result = '0'
|
57
39
|
end
|
40
|
+
result
|
58
41
|
end
|
59
|
-
|
42
|
+
|
60
43
|
def set_migration_status(to)
|
61
44
|
client = get_client
|
62
45
|
sql = [
|
63
46
|
get_sql('create_migration_table'),
|
64
47
|
"UPDATE _migration SET migration = '#{to}'"
|
65
|
-
].join(' ')
|
48
|
+
].join(' ')
|
66
49
|
client.execute(sql).each
|
67
50
|
end
|
68
|
-
|
51
|
+
|
69
52
|
def remove_migration
|
70
53
|
client = get_client
|
71
54
|
client.execute('DROP TABLE _migration')
|
72
55
|
end
|
73
56
|
|
74
|
-
def apply_migration(path)
|
57
|
+
def apply_migration(path)
|
75
58
|
client = get_client
|
76
59
|
sql = File.read(path)
|
77
60
|
client.execute(sql)
|
78
61
|
end
|
79
|
-
|
80
62
|
end
|
81
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: migsql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karl Stoney
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tiny_tds
|