schema_transformer 0.1.0
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.
- data/README.markdown +83 -0
- data/Rakefile +29 -0
- data/TODO +11 -0
- data/bin/schema_transformer +4 -0
- data/gemspec.rb +20 -0
- data/lib/schema_transformer/base.rb +260 -0
- data/lib/schema_transformer/cli.rb +99 -0
- data/lib/schema_transformer/help.rb +43 -0
- data/lib/schema_transformer/version.rb +3 -0
- data/lib/schema_transformer.rb +10 -0
- data/notes/copier.rb +14 -0
- data/notes/copier_scratchpad.rb +45 -0
- data/notes/pager.rb +101 -0
- data/notes/schema_transformer_notes.txt +44 -0
- data/test/fake_app/config/database.yml +34 -0
- data/test/fake_app/config/schema_transformations/books.json +1 -0
- data/test/fake_app/config/schema_transformations/users.json +1 -0
- data/test/fake_app/log/schema_transformer.log +58795 -0
- data/test/schema_transformer_test.rb +210 -0
- metadata +85 -0
data/notes/pager.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# Most of this is ripped off from WillPaginate::Collection
|
2
|
+
#
|
3
|
+
# Required options:
|
4
|
+
# * <tt>per_page</tt> - number of items per page
|
5
|
+
# Optional options:
|
6
|
+
# * <tt>page</tt> - starting page, defaults to 1
|
7
|
+
# * <tt>total</tt> - total number of items, defaults to 0
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
#
|
11
|
+
# pager = Pager.new(:per_page => 5, :total => 23)
|
12
|
+
# pager.start_index => 0
|
13
|
+
# pager.end_index => 4
|
14
|
+
#
|
15
|
+
# pager = Pager.new(:page => 2, :per_page => 5, :total => 23)
|
16
|
+
# pager.start_index => 5
|
17
|
+
# pager.end_index => 9
|
18
|
+
#
|
19
|
+
# # interator will always loop starting from page 1, even if you have initialize page another value.
|
20
|
+
# pager.each do |page|
|
21
|
+
# page.start_index
|
22
|
+
# page.end_index
|
23
|
+
# end
|
24
|
+
class Pager
|
25
|
+
include Enumerable
|
26
|
+
|
27
|
+
def each
|
28
|
+
old = @current_page # want to remember the old current page
|
29
|
+
@current_page = 1
|
30
|
+
@total_pages.times do
|
31
|
+
yield(self)
|
32
|
+
@current_page += 1
|
33
|
+
end
|
34
|
+
@current_page = old
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :current_page, :per_page, :total_pages
|
38
|
+
attr_accessor :total_entries
|
39
|
+
|
40
|
+
def initialize(options)
|
41
|
+
@current_page = options[:page] ? options[:page].to_i : 1
|
42
|
+
@per_page = options[:per_page].to_i
|
43
|
+
@total_entries = options[:total].to_i
|
44
|
+
@total_pages = (@total_entries / @per_page.to_f).ceil
|
45
|
+
end
|
46
|
+
|
47
|
+
# The total number of pages.
|
48
|
+
def page_count
|
49
|
+
@total_pages
|
50
|
+
end
|
51
|
+
|
52
|
+
# Current offset of the paginated collection. If we're on the first page,
|
53
|
+
# it is always 0. If we're on the 2nd page and there are 30 entries per page,
|
54
|
+
# the offset is 30. This property is useful if you want to render ordinals
|
55
|
+
# besides your records: simply start with offset + 1.
|
56
|
+
#
|
57
|
+
def offset
|
58
|
+
(current_page - 1) * per_page
|
59
|
+
end
|
60
|
+
|
61
|
+
# current_page - 1 or nil if there is no previous page
|
62
|
+
def previous_page
|
63
|
+
current_page > 1 ? (current_page - 1) : nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def previous_page!
|
67
|
+
@current_page = previous_page if previous_page
|
68
|
+
end
|
69
|
+
|
70
|
+
# current_page + 1 or nil if there is no next page
|
71
|
+
def next_page
|
72
|
+
current_page < page_count ? (current_page + 1) : nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def next_page!
|
76
|
+
@current_page = next_page if next_page
|
77
|
+
end
|
78
|
+
|
79
|
+
def start_index
|
80
|
+
offset
|
81
|
+
end
|
82
|
+
|
83
|
+
def end_index
|
84
|
+
[start_index + (per_page - 1), @total_entries].min
|
85
|
+
end
|
86
|
+
|
87
|
+
# true if current_page is the final page
|
88
|
+
def last_page?
|
89
|
+
next_page.nil?
|
90
|
+
end
|
91
|
+
|
92
|
+
# true if current_page is the final page
|
93
|
+
def first_page?
|
94
|
+
previous_page.nil?
|
95
|
+
end
|
96
|
+
|
97
|
+
# true if current_page is the final page
|
98
|
+
def first_page!
|
99
|
+
@current_page = 1
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# 1. create new table with schema
|
4
|
+
# 2. batch copy data
|
5
|
+
# 3. maintainenance page
|
6
|
+
# 4. batch copy final data
|
7
|
+
# 5. rename tables
|
8
|
+
# 6. remove maintenance page
|
9
|
+
|
10
|
+
# 1. create new table with schema
|
11
|
+
CREATE TABLE article_revisions_new LIKE article_revisions;
|
12
|
+
ALTER TABLE article_revisions_new
|
13
|
+
ADD INDEX idx_slide_id (slide_id);
|
14
|
+
|
15
|
+
|
16
|
+
# 2. batch copy data
|
17
|
+
|
18
|
+
max = SELECT max(`article_revisions`.id) AS max_id FROM `article_revisions`;
|
19
|
+
|
20
|
+
Article::Revision
|
21
|
+
|
22
|
+
Article.find_in_batches(batch_size => 100 ) { |articles| articles.each { |a| ... } }
|
23
|
+
|
24
|
+
Article::Revision.maximum
|
25
|
+
Pager.new()
|
26
|
+
|
27
|
+
insert into article_revisions_new (select * from )
|
28
|
+
|
29
|
+
insert into article_revisions_new (
|
30
|
+
select id, title, body, article_id, number, note, editor_id, created_at, blurb, teaser, source, slide_id
|
31
|
+
from article_revisions where id <= 0 LIMIT 10000
|
32
|
+
);
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
Article::Revision Load (170.7ms) SELECT * FROM `article_revisions` WHERE (article_revisions.id >= 0) ORDER BY article_revisions.id ASC LIMIT 1000
|
37
|
+
Article::Revision Load (78.8ms) SELECT * FROM `article_revisions` WHERE (article_revisions.id > 1430719) ORDER BY article_revisions.id ASC LIMIT 1000
|
38
|
+
Article::Revision Load (78.1ms) SELECT * FROM `article_revisions` WHERE (article_revisions.id > 1431725) ORDER BY article_revisions.id ASC LIMIT 1000
|
39
|
+
|
40
|
+
|
41
|
+
# 3. maintainenance page
|
42
|
+
# 4. batch copy final data
|
43
|
+
# 5. rename tables
|
44
|
+
# 6. remove maintenance page
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# beta
|
2
|
+
#common: &common
|
3
|
+
# database: bleacherreport_staging
|
4
|
+
# adapter: mysql
|
5
|
+
# username: deploy
|
6
|
+
# password: sOqjaxGVmI
|
7
|
+
# host: 127.0.0.1
|
8
|
+
# port: 3307
|
9
|
+
|
10
|
+
# production
|
11
|
+
#common: &common
|
12
|
+
# database: bleacherreport_production
|
13
|
+
# adapter: mysql
|
14
|
+
# username: deploy
|
15
|
+
# password: 1Kyxa6cFsa
|
16
|
+
# host: 127.0.0.1
|
17
|
+
# port: 3307
|
18
|
+
|
19
|
+
# local
|
20
|
+
common: &common
|
21
|
+
adapter: mysql
|
22
|
+
username: root
|
23
|
+
password:
|
24
|
+
host: localhost
|
25
|
+
database: br1
|
26
|
+
socket: /opt/local/var/run/mysql5/mysqld.sock
|
27
|
+
|
28
|
+
development:
|
29
|
+
<<: *common
|
30
|
+
database: schema_transformer
|
31
|
+
|
32
|
+
test:
|
33
|
+
<<: *common
|
34
|
+
database: schema_transformer_test
|
@@ -0,0 +1 @@
|
|
1
|
+
{"mod":"ADD COLUMN active tinyint(1) DEFAULT '0'","table":"books"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"mod":"ADD COLUMN active tinyint(1) DEFAULT '0', \n ADD COLUMN title varchar(255) DEFAULT 'Mr', \n DROP COLUMN about_me","table":"users"}
|