ferry 1.0.0 → 1.0.1
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/.gitignore +2 -0
- data/.travis.yml +14 -0
- data/README.md +42 -12
- data/bin/ferry +20 -24
- data/doc/ferry_rake_contents.rb +8 -0
- data/lib/ferry.rb +1 -0
- data/lib/ferry/exporter.rb +3 -3
- data/lib/ferry/importer.rb +7 -7
- data/lib/ferry/switcher.rb +20 -10
- data/lib/ferry/utilities.rb +11 -9
- data/lib/ferry/version.rb +1 -1
- data/script/mysql2_install.sh +19 -0
- data/script/postgresql_install.sh +30 -0
- data/spec/config/database.yml +6 -0
- data/spec/ferry_spec.rb +1 -0
- data/spec/support/categories_invalid_col.csv +2 -0
- data/spec/support/categories_null_name.csv +2 -0
- data/spec/support/categories_repeat_id.csv +2 -0
- data/spec/support/emails_import.csv +1 -0
- data/spec/support/emails_invalid.csv +2101 -0
- data/spec/support/schema.rb +1 -1
- data/spec/tests/exporter_tests.rb +104 -63
- data/spec/tests/importer_tests.rb +185 -58
- data/spec/tests/utilities_tests.rb +32 -0
- metadata +18 -2
data/spec/support/schema.rb
CHANGED
@@ -13,27 +13,43 @@ describe("export functionality") do
|
|
13
13
|
Contexts.teardown
|
14
14
|
FileUtils.rm_rf('db')
|
15
15
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
16
|
+
|
17
|
+
describe "to_csv" do
|
18
|
+
it "call should create a populated csv file" do
|
19
|
+
exporter.to_csv('sqlite3', 'carts')
|
20
|
+
file_path = File.expand_path("..",Dir.pwd) + "/spec/db/csv/sqlite3/carts.csv"
|
21
|
+
expect(File).to exist(file_path)
|
22
|
+
lines = CSV.read(file_path)
|
23
|
+
expect(lines.length).to eql(27)
|
24
|
+
expect(lines[0]).to eql(["id", "email"])
|
25
|
+
expect(lines[1]).to eql(["1", "abby@example.com"])
|
26
|
+
expect(lines[26]).to eql(["26", "zach@example.com"])
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should error if specified table does not exist" do
|
30
|
+
expect{exporter.to_csv('sqlite3', 'cart')}.to raise_error #correct table is "carts"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "to_yaml" do
|
36
|
+
it "call should create a populated yaml file" do
|
37
|
+
exporter.to_yaml('sqlite3', 'carts')
|
38
|
+
file_path = File.expand_path("..",Dir.pwd) + "/spec/db/yaml/sqlite3/carts.yml"
|
39
|
+
expect(File).to exist(file_path)
|
40
|
+
output = YAML.load_file(file_path)
|
41
|
+
expect(output["carts"].length).to eql(2)
|
42
|
+
expect(output["carts"].keys).to eql(["columns","records"])
|
43
|
+
expect(output["carts"]["columns"]).to eql(["id","email"])
|
44
|
+
expect(output["carts"]["records"][0]).to eql([1,"abby@example.com"])
|
45
|
+
expect(output["carts"]["records"][25]).to eql([26,"zach@example.com"])
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should error if specified table does not exist" do
|
49
|
+
expect{exporter.to_yaml('sqlite3', 'cart')}.to raise_error #correct table is "carts"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
37
53
|
end
|
38
54
|
|
39
55
|
describe "postgresql db" do
|
@@ -46,27 +62,40 @@ describe("export functionality") do
|
|
46
62
|
Contexts.teardown
|
47
63
|
FileUtils.rm_rf('db')
|
48
64
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
65
|
+
|
66
|
+
describe "to_csv" do
|
67
|
+
it "call should create a populated csv file" do
|
68
|
+
exporter.to_csv('postgresql', 'carts')
|
69
|
+
file_path = File.expand_path("..",Dir.pwd) + "/spec/db/csv/postgresql/carts.csv"
|
70
|
+
expect(File).to exist(file_path)
|
71
|
+
lines = CSV.read(file_path)
|
72
|
+
expect(lines.length).to eql(27)
|
73
|
+
expect(lines[0]).to eql(["id", "email"])
|
74
|
+
expect(lines[1]).to eql(["1", "abby@example.com"])
|
75
|
+
expect(lines[26]).to eql(["26", "zach@example.com"])
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should error if specified table does not exist" do
|
79
|
+
expect{exporter.to_csv('postgresql', 'cart')}.to raise_error #correct table is "carts"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
describe "to_yaml" do
|
83
|
+
it "call should create a populated yaml file" do
|
84
|
+
exporter.to_yaml('postgresql', 'carts')
|
85
|
+
file_path = File.expand_path("..",Dir.pwd) + "/spec/db/yaml/postgresql/carts.yml"
|
86
|
+
expect(File).to exist(file_path)
|
87
|
+
output = YAML.load_file(file_path)
|
88
|
+
expect(output["carts"].length).to eql(2)
|
89
|
+
expect(output["carts"].keys).to eql(["columns","records"])
|
90
|
+
expect(output["carts"]["columns"]).to eql(["id","email"])
|
91
|
+
expect(output["carts"]["records"][0]).to eql(["1","abby@example.com"])
|
92
|
+
expect(output["carts"]["records"][25]).to eql(["26","zach@example.com"])
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should error if specified table does not exist" do
|
96
|
+
expect{exporter.to_yaml('postgresql', 'cart')}.to raise_error #correct table is "carts"
|
97
|
+
end
|
98
|
+
end
|
70
99
|
end
|
71
100
|
|
72
101
|
describe "mysql2 db" do
|
@@ -79,27 +108,39 @@ describe("export functionality") do
|
|
79
108
|
Contexts.teardown
|
80
109
|
FileUtils.rm_rf('db')
|
81
110
|
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
111
|
+
|
112
|
+
describe "to_csv" do
|
113
|
+
it "call should create a populated csv file" do
|
114
|
+
exporter.to_csv('mysql2', 'carts')
|
115
|
+
file_path = File.expand_path("..",Dir.pwd) + "/spec/db/csv/mysql2/carts.csv"
|
116
|
+
expect(File).to exist(file_path)
|
117
|
+
lines = CSV.read(file_path)
|
118
|
+
expect(lines.length).to eql(27)
|
119
|
+
expect(lines[0]).to eql(["id", "email"])
|
120
|
+
expect(lines[1]).to eql(["1", "abby@example.com"])
|
121
|
+
expect(lines[26]).to eql(["26", "zach@example.com"])
|
122
|
+
end
|
123
|
+
it "should error if specified table does not exist" do
|
124
|
+
expect{exporter.to_csv('mysql2', 'cart')}.to raise_error #correct table is "carts"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "to_yaml" do
|
129
|
+
it "call should create a populated yaml file" do
|
130
|
+
exporter.to_yaml('mysql2', 'carts')
|
131
|
+
file_path = File.expand_path("..",Dir.pwd) + "/spec/db/yaml/mysql2/carts.yml"
|
132
|
+
expect(File).to exist(file_path)
|
133
|
+
output = YAML.load_file(file_path)
|
134
|
+
expect(output["carts"].length).to eql(2)
|
135
|
+
expect(output["carts"].keys).to eql(["columns","records"])
|
136
|
+
expect(output["carts"]["columns"]).to eql(["id","email"])
|
137
|
+
expect(output["carts"]["records"][0]).to eql([1,"abby@example.com"])
|
138
|
+
expect(output["carts"]["records"][25]).to eql([26,"zach@example.com"])
|
139
|
+
end
|
140
|
+
it "should error if specified table does not exist" do
|
141
|
+
expect{exporter.to_yaml('mysql2', 'cart')}.to raise_error #correct table is "carts"
|
142
|
+
end
|
143
|
+
end
|
103
144
|
end
|
104
145
|
end
|
105
146
|
end
|
@@ -2,68 +2,195 @@ importer = Ferry::Importer.new
|
|
2
2
|
|
3
3
|
Dir.chdir("spec") unless Dir.pwd.split('/').last == "spec"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
5
|
+
|
6
|
+
describe "#import" do
|
7
|
+
describe "sqlite3 db" do
|
8
|
+
before(:all) do
|
9
|
+
connect("sqlite3")
|
10
|
+
Contexts.setup
|
11
|
+
end
|
12
|
+
after(:all) do
|
13
|
+
Contexts.teardown
|
14
|
+
Category.delete_all
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should import a valid csv into ActiveRecord" do
|
18
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/categories_import.csv"
|
19
|
+
importer.import("sqlite3", "categories", import_path)
|
20
|
+
expect(Category.all.length).to eql(146)
|
21
|
+
expect(Category.find_by(id: 42).name).to eql("outdoor decor")
|
22
|
+
expect(Category.find_by(id: 42).description).to eql("Pellentesque magna odio, blandit in nisi fringilla, commodo.")
|
23
|
+
expect(Category.find_by(id: 42).float_score).to eql(42.42)
|
24
|
+
expect(Category.find_by(id: 42).active).to eql(true)
|
25
|
+
expect(Category.find_by(id: 9).name).to eql("boys' clothing")
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
28
|
+
#SQL INSERT tests
|
29
|
+
|
30
|
+
it "should error if given a non-csv file" do
|
31
|
+
expect{importer.import("sqlite3", "categories", File.expand_path("..",Dir.pwd) + "/spec/support/categories_import.xml")}.to raise_error
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should error if file does not exist" do
|
35
|
+
expect{importer.import("sqlite3", "categories", File.expand_path("..",Dir.pwd) + "/spec/support/invalid.csv")}.to raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should error if invalid table name" do
|
39
|
+
expect{importer.import("sqlite3", "category", File.expand_path("..",Dir.pwd) + "/spec/support/categories_import.csv")}.to raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should error if columns are invalid" do
|
43
|
+
expect{importer.import("sqlite3", "categories", File.expand_path("..",Dir.pwd) + "/spec/support/categories_invalid_col.csv")}.to raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should error if values do not meet db constraints" do
|
47
|
+
expect{importer.import("sqlite3", "categories", File.expand_path("..",Dir.pwd) + "/spec/support/categories_null_name.csv")}.to raise_error
|
48
|
+
|
49
|
+
expect{importer.import("sqlite3", "categories", File.expand_path("..",Dir.pwd) + "/spec/support/categories_repeat_id.csv")}.to raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "mass insert tests (sqlite)" do
|
55
|
+
before(:each) do
|
56
|
+
connect("sqlite3")
|
57
|
+
Contexts.setup
|
58
|
+
end
|
59
|
+
after(:each) do
|
60
|
+
Contexts.teardown
|
61
|
+
Cart.delete_all
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be able to import >500 records" do
|
65
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/emails_import.csv" #2100 records
|
66
|
+
importer.import("sqlite3", "carts", import_path)
|
67
|
+
expect(Cart.find_by(id: 42).email).to eql("Albert@example.com")
|
68
|
+
expect(Cart.find_by(id: 542).email).to eql("Agustu@example.com")
|
69
|
+
expect(Cart.find_by(id: 1042).email).to eql("Smith@example.com")
|
70
|
+
expect(Cart.find_by(id: 1542).email).to eql("Kare@example.com")
|
71
|
+
expect(Cart.find_by(id: 2042).email).to eql("Yolanda@example.com")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should not commit import if any record errors" do
|
75
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/emails_invalid.csv" #2100 records, last one is invalid
|
76
|
+
expect{importer.import("sqlite3", "carts", import_path)}.to raise_error
|
77
|
+
expect(Cart.find_by(id: 42)).to eql(nil)
|
78
|
+
expect(Cart.find_by(id: 542)).to eql(nil)
|
79
|
+
expect(Cart.find_by(id: 1042)).to eql(nil)
|
80
|
+
expect(Cart.find_by(id: 1542)).to eql(nil)
|
81
|
+
expect(Cart.find_by(id: 2042)).to eql(nil)
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "postgresql db" do
|
88
|
+
before(:all) do
|
89
|
+
connect("postgresql")
|
90
|
+
# requires you to have a ferry_test db in pg
|
91
|
+
Contexts.setup
|
92
|
+
end
|
93
|
+
after(:all) do
|
94
|
+
Contexts.teardown
|
95
|
+
Category.delete_all
|
96
|
+
end
|
97
|
+
it "should import a valid csv into ActiveRecord" do
|
98
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/categories_import.csv"
|
99
|
+
importer.import("postgresql", "categories", import_path)
|
100
|
+
expect(Category.all.length).to eql(146)
|
101
|
+
expect(Category.find_by(id: 42).name).to eql("outdoor decor")
|
102
|
+
expect(Category.find_by(id: 42).description).to eql("Pellentesque magna odio, blandit in nisi fringilla, commodo.")
|
103
|
+
expect(Category.find_by(id: 42).float_score).to eql(42.42)
|
104
|
+
expect(Category.find_by(id: 42).active).to eql(true)
|
105
|
+
expect(Category.find_by(id: 9).name).to eql("boys' clothing")
|
46
106
|
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "mass insert tests (postgresql)" do
|
110
|
+
before(:each) do
|
111
|
+
connect("postgresql")
|
112
|
+
Contexts.setup
|
113
|
+
end
|
114
|
+
after(:each) do
|
115
|
+
Contexts.teardown
|
116
|
+
Cart.delete_all
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should be able to import >500 records" do
|
120
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/emails_import.csv" #2100 records
|
121
|
+
importer.import("sqlite3", "carts", import_path)
|
122
|
+
expect(Cart.find_by(id: 42).email).to eql("Albert@example.com")
|
123
|
+
expect(Cart.find_by(id: 542).email).to eql("Agustu@example.com")
|
124
|
+
expect(Cart.find_by(id: 1042).email).to eql("Smith@example.com")
|
125
|
+
expect(Cart.find_by(id: 1542).email).to eql("Kare@example.com")
|
126
|
+
expect(Cart.find_by(id: 2042).email).to eql("Yolanda@example.com")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should not commit import if any record errors" do
|
130
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/emails_invalid.csv" #2100 records, last one is invalid
|
131
|
+
expect{importer.import("sqlite3", "carts", import_path)}.to raise_error
|
132
|
+
expect(Cart.find_by(id: 42)).to eql(nil)
|
133
|
+
expect(Cart.find_by(id: 542)).to eql(nil)
|
134
|
+
expect(Cart.find_by(id: 1042)).to eql(nil)
|
135
|
+
expect(Cart.find_by(id: 1542)).to eql(nil)
|
136
|
+
expect(Cart.find_by(id: 2042)).to eql(nil)
|
137
|
+
end
|
138
|
+
|
47
139
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "mysql2 db" do
|
143
|
+
before(:all) do
|
144
|
+
connect("mysql2")
|
145
|
+
# requires you to have a ferry_test db in pg
|
146
|
+
Contexts.setup
|
147
|
+
end
|
148
|
+
after(:all) do
|
149
|
+
Contexts.teardown
|
150
|
+
Category.delete_all
|
151
|
+
end
|
152
|
+
it "should import a valid csv values into ActiveRecord" do
|
153
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/categories_import.csv"
|
154
|
+
importer.import("mysql2", "categories", import_path)
|
155
|
+
expect(Category.all.length).to eql(146)
|
156
|
+
expect(Category.find_by(id: 42).name).to eql("outdoor decor")
|
157
|
+
expect(Category.find_by(id: 42).description).to eql("Pellentesque magna odio, blandit in nisi fringilla, commodo.")
|
158
|
+
expect(Category.find_by(id: 42).float_score).to eql(42.42)
|
159
|
+
expect(Category.find_by(id: 42).active).to eql(true)
|
160
|
+
expect(Category.find_by(id: 9).name).to eql("boys' clothing")
|
67
161
|
end
|
68
162
|
end
|
163
|
+
|
164
|
+
describe "mass insert tests (mysql2)" do
|
165
|
+
before(:each) do
|
166
|
+
connect("mysql2")
|
167
|
+
Contexts.setup
|
168
|
+
end
|
169
|
+
after(:each) do
|
170
|
+
Contexts.teardown
|
171
|
+
Cart.delete_all
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should be able to import >500 records" do
|
175
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/emails_import.csv" #2100 records
|
176
|
+
importer.import("sqlite3", "carts", import_path)
|
177
|
+
expect(Cart.find_by(id: 42).email).to eql("Albert@example.com")
|
178
|
+
expect(Cart.find_by(id: 542).email).to eql("Agustu@example.com")
|
179
|
+
expect(Cart.find_by(id: 1042).email).to eql("Smith@example.com")
|
180
|
+
expect(Cart.find_by(id: 1542).email).to eql("Kare@example.com")
|
181
|
+
expect(Cart.find_by(id: 2042).email).to eql("Yolanda@example.com")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should not commit import if any record errors" do
|
185
|
+
import_path = File.expand_path("..",Dir.pwd) + "/spec/support/emails_invalid.csv" #2100 records, last one is invalid
|
186
|
+
expect{importer.import("sqlite3", "carts", import_path)}.to raise_error
|
187
|
+
expect(Cart.find_by(id: 42)).to eql(nil)
|
188
|
+
expect(Cart.find_by(id: 542)).to eql(nil)
|
189
|
+
expect(Cart.find_by(id: 1042)).to eql(nil)
|
190
|
+
expect(Cart.find_by(id: 1542)).to eql(nil)
|
191
|
+
expect(Cart.find_by(id: 2042)).to eql(nil)
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
end
|
69
196
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
utils = Ferry::Utilities.new
|
2
|
+
|
3
|
+
Dir.chdir("spec") unless Dir.pwd.split('/').last == "spec"
|
4
|
+
|
5
|
+
describe("utility functions") do
|
6
|
+
describe "#db_connect" do
|
7
|
+
|
8
|
+
it "#sqlite3" do
|
9
|
+
expect{utils.db_connect("sqlite3")}.not_to raise_error
|
10
|
+
expect(ActiveRecord::Base.connection.adapter_name).to eql('SQLite')
|
11
|
+
end
|
12
|
+
|
13
|
+
it "#postgresql" do
|
14
|
+
expect{utils.db_connect("postgresql")}.not_to raise_error
|
15
|
+
expect(ActiveRecord::Base.connection.adapter_name).to eql('PostgreSQL')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "#mysql2" do
|
19
|
+
expect{utils.db_connect("mysql2")}.not_to raise_error
|
20
|
+
expect(ActiveRecord::Base.connection.adapter_name).to eql('Mysql2')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "#no environment with given name" do
|
24
|
+
expect{utils.db_connect("invalid_env")}.to raise_error
|
25
|
+
end
|
26
|
+
|
27
|
+
it "#unsupported DB type" do
|
28
|
+
expect{utils.db_connect("oracle")}.to raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|