mongify 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.yardopts +3 -0
- data/CHANGELOG.rdoc +5 -0
- data/Gemfile.lock +52 -6
- data/LICENSE +1 -1
- data/README.rdoc +29 -11
- data/Rakefile +37 -9
- data/features/options.feature +2 -0
- data/features/print.feature +1 -1
- data/features/process.feature +10 -1
- data/features/step_definitions/process_steps.rb +11 -1
- data/features/support/env.rb +1 -1
- data/lib/mongify/cli/application.rb +7 -7
- data/lib/mongify/cli/command/worker.rb +18 -14
- data/lib/mongify/cli/options.rb +2 -1
- data/lib/mongify/configuration.rb +5 -5
- data/lib/mongify/database/base_connection.rb +6 -6
- data/lib/mongify/database/column.rb +40 -40
- data/lib/mongify/database/data_row.rb +9 -9
- data/lib/mongify/database/no_sql_connection.rb +61 -35
- data/lib/mongify/database/sql_connection.rb +44 -15
- data/lib/mongify/database/table.rb +62 -46
- data/lib/mongify/exceptions.rb +5 -5
- data/lib/mongify/progressbar.rb +15 -15
- data/lib/mongify/status.rb +8 -8
- data/lib/mongify/translation.rb +19 -17
- data/lib/mongify/translation/process.rb +16 -123
- data/lib/mongify/translation/processor_common.rb +132 -0
- data/lib/mongify/translation/sync.rb +112 -0
- data/lib/mongify/ui.rb +9 -9
- data/lib/mongify/version.rb +1 -1
- data/mongify.gemspec +4 -2
- data/spec/files/deleting_fields_from_embedding_parent_translation.rb +19 -0
- data/spec/files/embedded_parent_translation.rb +1 -1
- data/spec/mongify/cli/application_spec.rb +1 -1
- data/spec/mongify/cli/options_spec.rb +1 -1
- data/spec/mongify/cli/worker_command_spec.rb +46 -17
- data/spec/mongify/database/column_spec.rb +21 -21
- data/spec/mongify/database/data_row_spec.rb +11 -11
- data/spec/mongify/database/no_sql_connection_spec.rb +61 -27
- data/spec/mongify/database/sql_connection_spec.rb +62 -2
- data/spec/mongify/database/table_spec.rb +53 -29
- data/spec/mongify/translation/printer_spec.rb +2 -2
- data/spec/mongify/translation/process_spec.rb +50 -34
- data/spec/mongify/translation/sync_spec.rb +184 -0
- data/spec/mongify/translation_spec.rb +8 -8
- data/spec/mongify/ui_spec.rb +12 -12
- data/spec/mongify_spec.rb +1 -1
- data/spec/spec_helper.rb +8 -1
- data/spec/support/config_reader.rb +2 -2
- data/spec/support/database_generator.rb +68 -25
- data/spec/support/database_output.txt +17 -0
- metadata +41 -6
@@ -13,11 +13,11 @@ describe Mongify::Translation do
|
|
13
13
|
@table2.column('id', :key)
|
14
14
|
@translation.add_table(@table2)
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
subject{@translation}
|
18
18
|
|
19
19
|
it "should output correctly" do
|
20
|
-
subject.print.should == <<-EOF
|
20
|
+
subject.print.should == <<-EOF
|
21
21
|
table "users" do
|
22
22
|
\tcolumn "first_name", :string
|
23
23
|
\tcolumn "age", :integer
|
@@ -8,15 +8,15 @@ describe Mongify::Translation::Process do
|
|
8
8
|
@translation = Mongify::Translation.new
|
9
9
|
Mongify::Configuration.out_stream = nil
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it "validates a sqlconnection" do
|
13
13
|
lambda { @translation.process('bad param', 'bad param2') }.should raise_error(Mongify::SqlConnectionRequired)
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "should require a NoSqlConnection" do
|
17
17
|
lambda { @translation.process(@sql_connection, 'bad param2') }.should raise_error(Mongify::NoSqlConnectionRequired)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
describe "process" do
|
21
21
|
before(:each) do
|
22
22
|
@translation.stub(:remove_pre_mongified_ids)
|
@@ -44,7 +44,7 @@ describe Mongify::Translation::Process do
|
|
44
44
|
@translation.should_receive(:remove_pre_mongified_ids)
|
45
45
|
@translation.process(@sql_connection, @no_sql_connection)
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
it "should add pre_mongified_id index to database" do
|
49
49
|
tables = [stub(:name => 'users')]
|
50
50
|
@translation.stub(:copy_tables).and_return(tables)
|
@@ -52,13 +52,13 @@ describe Mongify::Translation::Process do
|
|
52
52
|
@translation.process(@sql_connection, @no_sql_connection)
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it "should ask_to_drop_database if mongodb_connection is forced" do
|
57
57
|
@no_sql_connection.should_receive(:forced?).and_return(true)
|
58
58
|
@no_sql_connection.should_receive(:ask_to_drop_database).and_return(false)
|
59
59
|
@translation.process(@sql_connection, @no_sql_connection)
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
context "fetch_reference_ids" do
|
63
63
|
it "should get correct information" do
|
64
64
|
@no_sql_connection = mock()
|
@@ -81,37 +81,38 @@ describe Mongify::Translation::Process do
|
|
81
81
|
@translation.send(:fetch_reference_ids, @table, {'user_ids' => [1, 2]}).should == {'user_ids' => [500, 501]}
|
82
82
|
end
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
context "processing actions" do
|
86
86
|
before(:each) do
|
87
|
-
@sql_connection
|
87
|
+
@sql_connection.stub(:select_paged_rows).and_return([{'first_name'=> 'Timmy', 'last_name' => 'Zuza', 'preference_id' => 1}])
|
88
88
|
@translation.stub(:sql_connection).and_return(@sql_connection)
|
89
|
-
|
89
|
+
|
90
90
|
@no_sql_connection = mock()
|
91
91
|
@translation.stub(:no_sql_connection).and_return(@no_sql_connection)
|
92
|
-
|
92
|
+
|
93
93
|
@table = mock(:translate => {'first_name'=> 'Timmy', 'last_name' => 'Zuza', 'preference_id' => 1},
|
94
|
-
:name => 'users',
|
95
|
-
:embedded? => false,
|
94
|
+
:name => 'users',
|
95
|
+
:embedded? => false,
|
96
96
|
:sql_name => 'users')
|
97
|
-
|
97
|
+
|
98
98
|
@translation.stub(:tables).and_return([@table])
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
context "copy_data" do
|
102
102
|
it "should call translate on the tables" do
|
103
|
-
@no_sql_connection.should_receive(:insert_into).with("users", {"last_name"=>"Zuza", "preference_id"=>1, "first_name"=>"Timmy"}).and_return(true)
|
103
|
+
@no_sql_connection.should_receive(:insert_into).with("users", [{"last_name"=>"Zuza", "preference_id"=>1, "first_name"=>"Timmy"}]).and_return(true)
|
104
104
|
@translation.send(:copy_data)
|
105
105
|
end
|
106
106
|
it "should allow rename of table" do
|
107
107
|
@table.stub(:name).and_return('people')
|
108
|
-
@no_sql_connection.should_receive(:insert_into).with("people", {"last_name"=>"Zuza", "preference_id"=>1, "first_name"=>"Timmy"}).and_return(true)
|
108
|
+
@no_sql_connection.should_receive(:insert_into).with("people", [{"last_name"=>"Zuza", "preference_id"=>1, "first_name"=>"Timmy"}]).and_return(true)
|
109
109
|
@translation.send(:copy_data)
|
110
110
|
end
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
context "copy_embed_tables" do
|
114
114
|
before(:each) do
|
115
|
+
@sql_connection.stub(:select_rows).and_return([{'first_name'=> 'Timmy', 'last_name' => 'Zuza', 'preference_id' => 1}])
|
115
116
|
@target_table = mock(:name => 'posts', :embedded? => false, :sql_name => 'posts')
|
116
117
|
@embed_table = mock(:translate => {}, :name => 'comments', :embedded? => true, :embed_on => 'post_id', :embed_in => 'posts', :embedded_as_object? => false, :sql_name => 'comments')
|
117
118
|
@no_sql_connection.stub(:find_one).and_return({'_id' => 500})
|
@@ -148,29 +149,35 @@ describe Mongify::Translation::Process do
|
|
148
149
|
@no_sql_connection.should_receive(:update).with("posts", 500, {"$set"=>{"notes"=>{'first_name' => 'bob'}}})
|
149
150
|
@translation.send(:copy_embedded_tables)
|
150
151
|
end
|
151
|
-
|
152
|
+
|
152
153
|
context "parent modification" do
|
154
|
+
it 'should unset fields deleted in the parent row' do
|
155
|
+
@embed_table = mock(:translate => [{}, {'email' => 'true'}, {'field_1' => '1'}], :name => 'preferences', :sql_name => 'preferences', :embedded? => true, :embed_on => 'post_id', :embed_in => 'posts', :embedded_as_object? => true)
|
156
|
+
@translation.stub(:tables).and_return([@target_table, @embed_table])
|
157
|
+
@no_sql_connection.should_receive(:update).with("posts", 500, {"$set"=>{"preferences"=>{}, "email"=>"true"}, "$unset"=>{'field_1' => '1'}})
|
158
|
+
@translation.send(:copy_embedded_tables)
|
159
|
+
end
|
153
160
|
it "should work with embedded objects" do
|
154
|
-
@embed_table = mock(:translate => [{}, {'email' => 'true'}], :name => 'preferences', :sql_name => 'preferences', :embedded? => true, :embed_on => 'post_id', :embed_in => 'posts', :embedded_as_object? => true)
|
161
|
+
@embed_table = mock(:translate => [{}, {'email' => 'true'}, {}], :name => 'preferences', :sql_name => 'preferences', :embedded? => true, :embed_on => 'post_id', :embed_in => 'posts', :embedded_as_object? => true)
|
155
162
|
@translation.stub(:tables).and_return([@target_table, @embed_table])
|
156
163
|
@no_sql_connection.should_receive(:update).with("posts", 500, {"$set"=>{"preferences"=>{}, "email"=>"true"}})
|
157
164
|
@translation.send(:copy_embedded_tables)
|
158
165
|
end
|
159
166
|
it "should work with embedded arrays" do
|
160
|
-
@embed_table = mock(:translate => [{}, {'email' => 'true'}], :name => 'preferences', :sql_name => 'preferences', :embedded? => true, :embed_on => 'post_id', :embed_in => 'posts', :embedded_as_object? => false)
|
167
|
+
@embed_table = mock(:translate => [{}, {'email' => 'true'}, {}], :name => 'preferences', :sql_name => 'preferences', :embedded? => true, :embed_on => 'post_id', :embed_in => 'posts', :embedded_as_object? => false)
|
161
168
|
@translation.stub(:tables).and_return([@target_table, @embed_table])
|
162
169
|
@no_sql_connection.should_receive(:update).with("posts", 500, {"$addToSet"=>{"preferences"=>{}}, "$set" => {"email"=>"true"}})
|
163
170
|
@translation.send(:copy_embedded_tables)
|
164
171
|
end
|
165
172
|
it "should not set embedded attribute in parent" do
|
166
|
-
@embed_table = mock(:translate => [{'first_name' => 'joe'}, {'email' => 'true', 'comments' => [{'first_name' => 'bob'}]}], :name => 'comments', :sql_name => 'comments', :embedded? => true, :embed_on => 'post_id', :embed_in => 'posts', :embedded_as_object? => false)
|
173
|
+
@embed_table = mock(:translate => [{'first_name' => 'joe'}, {'email' => 'true', 'comments' => [{'first_name' => 'bob'}]}, {}], :name => 'comments', :sql_name => 'comments', :embedded? => true, :embed_on => 'post_id', :embed_in => 'posts', :embedded_as_object? => false)
|
167
174
|
@translation.stub(:tables).and_return([@target_table, @embed_table])
|
168
175
|
@no_sql_connection.should_receive(:update).with("posts", 500, {"$addToSet" => {"comments" => {"first_name" => "joe"}}, "$set" => {"email" => "true"}})
|
169
176
|
@translation.send(:copy_embedded_tables)
|
170
177
|
end
|
171
178
|
end
|
172
179
|
end
|
173
|
-
|
180
|
+
|
174
181
|
context "append_parent_object" do
|
175
182
|
before(:each) do
|
176
183
|
@parent = {"preference" => "email"}
|
@@ -188,8 +195,17 @@ describe Mongify::Translation::Process do
|
|
188
195
|
@obj = {"$setAppend" => {"existing" => "true"}}
|
189
196
|
@translation.send(:append_parent_object, @obj, @parent).should == {"$setAppend" => {"existing" => "true"}}
|
190
197
|
end
|
198
|
+
it "should not unset values if no unset_key is given" do
|
199
|
+
@obj = {"$setAppend" => {"existing" => "true"}}
|
200
|
+
@translation.send(:append_parent_object, @obj, @parent, {}).should == {"$set" => {"preference" => "email"}, "$setAppend" => {"existing" => "true"}}
|
201
|
+
end
|
202
|
+
it "should unset values if unset_keys are given" do
|
203
|
+
@obj = {"$set" => {"existing" => "true"}}
|
204
|
+
@translation.send(:append_parent_object, @obj, @parent, {'field_1' => '1'}).should ==
|
205
|
+
{"$set" => {"existing" => "true", "preference" => "email"}, '$unset' => {'field_1' => '1'}}
|
206
|
+
end
|
191
207
|
end
|
192
|
-
|
208
|
+
|
193
209
|
context "update_reference_ids" do
|
194
210
|
it "should work correctly" do
|
195
211
|
@no_sql_connection.should_receive(:select_rows).and_return([{'_id' => 100, 'user_id' => 1}, {'_id'=> 101, 'user_id' => 2}])
|
@@ -206,32 +222,32 @@ describe Mongify::Translation::Process do
|
|
206
222
|
@translation.send(:update_reference_ids)
|
207
223
|
end
|
208
224
|
end
|
209
|
-
|
225
|
+
|
210
226
|
context "copy_polymorphic_tables" do
|
211
227
|
before(:each) do
|
212
|
-
@ref_table = mock(:name => 'user_accounts',
|
228
|
+
@ref_table = mock(:name => 'user_accounts',
|
213
229
|
:embedded? => false,
|
214
230
|
:ignored? => false,
|
215
231
|
:sql_name => 'user_accounts')
|
216
232
|
@translation.stub(:find).with('user_accounts').and_return([@ref_table])
|
217
|
-
|
233
|
+
|
218
234
|
@sql_connection.stub(:select_rows).with('comments').and_return([{'commentable_id' => 1, 'commentable_type' => 'UserAccount', 'data' => 'good'}])
|
219
235
|
@no_sql_connection.stub(:get_id_using_pre_mongified_id).with('user_accounts', 1).and_return(500)
|
220
236
|
end
|
221
237
|
context "embedded" do
|
222
238
|
it "should work correctly" do
|
223
239
|
@table = mock(:translate => {'data' => 123},
|
224
|
-
:name => 'comments',
|
240
|
+
:name => 'comments',
|
225
241
|
:embedded? => true,
|
226
242
|
:polymorphic_as => 'commentable',
|
227
|
-
:polymorphic? => true,
|
243
|
+
:polymorphic? => true,
|
228
244
|
:ignored? => false,
|
229
245
|
:embedded_as_object? => false,
|
230
246
|
:sql_name => 'comments',
|
231
247
|
:reference_columns => [])
|
232
248
|
|
233
249
|
@translation.stub(:all_tables).and_return([@table])
|
234
|
-
|
250
|
+
|
235
251
|
@no_sql_connection.should_receive(:update).with('user_accounts', 500, {'$addToSet' => {'comments' => {'data' => 123}}})
|
236
252
|
@translation.send(:copy_polymorphic_tables)
|
237
253
|
end
|
@@ -239,10 +255,10 @@ describe Mongify::Translation::Process do
|
|
239
255
|
context "not embedded" do
|
240
256
|
it "should work" do
|
241
257
|
@table = mock(:translate => {'data' => 123, 'commentable_type' => 'UserAccount', 'commentable_id' => 1},
|
242
|
-
:name => 'comments',
|
258
|
+
:name => 'comments',
|
243
259
|
:embedded? => false,
|
244
260
|
:polymorphic_as => 'commentable',
|
245
|
-
:polymorphic? => true,
|
261
|
+
:polymorphic? => true,
|
246
262
|
:ignored? => false,
|
247
263
|
:embedded_as_object? => false,
|
248
264
|
:sql_name => 'comments',
|
@@ -255,10 +271,10 @@ describe Mongify::Translation::Process do
|
|
255
271
|
end
|
256
272
|
it "should copy even if there is no polymorphic data" do
|
257
273
|
@table = mock(:translate => {'data' => 123, 'commentable_type' => nil, 'commentable_id' => nil},
|
258
|
-
:name => 'comments',
|
274
|
+
:name => 'comments',
|
259
275
|
:embedded? => false,
|
260
276
|
:polymorphic_as => 'commentable',
|
261
|
-
:polymorphic? => true,
|
277
|
+
:polymorphic? => true,
|
262
278
|
:ignored? => false,
|
263
279
|
:embedded_as_object? => false,
|
264
280
|
:sql_name => 'comments',
|
@@ -272,7 +288,7 @@ describe Mongify::Translation::Process do
|
|
272
288
|
end
|
273
289
|
end
|
274
290
|
end
|
275
|
-
|
291
|
+
|
276
292
|
context "remove_pre_mongified_ids" do
|
277
293
|
it "should remove_pre_mongified_ids on no_sql_connection" do
|
278
294
|
@no_sql_connection.should_receive(:remove_pre_mongified_ids).with(anything)
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongify::Translation::Sync do
|
4
|
+
before(:each) do
|
5
|
+
DatabaseGenerator.clear_mongodb
|
6
|
+
@sql_connection = DatabaseGenerator.sqlite_connection
|
7
|
+
@no_sql_connection = DatabaseGenerator.mongo_connection
|
8
|
+
@translation = Mongify::Translation.new
|
9
|
+
Mongify::Configuration.out_stream = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "validates a sqlconnection" do
|
13
|
+
lambda { @translation.sync('bad param', 'bad param2') }.should raise_error(Mongify::SqlConnectionRequired)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should require a NoSqlConnection" do
|
17
|
+
lambda { @translation.sync(@sql_connection, 'bad param2') }.should raise_error(Mongify::NoSqlConnectionRequired)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "sync" do
|
21
|
+
before(:each) do
|
22
|
+
@translation.stub(:setup_sync_table)
|
23
|
+
@translation.stub(:setup_db_index)
|
24
|
+
@translation.stub(:sync_data)
|
25
|
+
@translation.stub(:set_last_updated_at)
|
26
|
+
@translation.stub(:sync_update_reference_ids)
|
27
|
+
@translation.stub(:copy_embedded_tables)
|
28
|
+
end
|
29
|
+
it "should create sync helper table if it doesn't exist" do
|
30
|
+
@translation.should_receive(:setup_sync_table)
|
31
|
+
@translation.sync(@sql_connection, @no_sql_connection)
|
32
|
+
end
|
33
|
+
it "should setup index on pre_mongify_id" do
|
34
|
+
@translation.should_receive(:setup_db_index)
|
35
|
+
@translation.sync(@sql_connection, @no_sql_connection)
|
36
|
+
end
|
37
|
+
it "should call copy_data" do
|
38
|
+
@translation.should_receive(:sync_data)
|
39
|
+
@translation.sync(@sql_connection, @no_sql_connection)
|
40
|
+
end
|
41
|
+
it "should call set_last_updated_at to mark synced data in the source" do
|
42
|
+
@translation.should_receive(:set_last_updated_at)
|
43
|
+
@translation.sync(@sql_connection, @no_sql_connection)
|
44
|
+
end
|
45
|
+
it "should call sync_update_reference_ids" do
|
46
|
+
@translation.should_receive(:sync_update_reference_ids)
|
47
|
+
@translation.sync(@sql_connection, @no_sql_connection)
|
48
|
+
end
|
49
|
+
it "should call copy_embedded_tables" do
|
50
|
+
@translation.should_receive(:copy_embedded_tables)
|
51
|
+
@translation.sync(@sql_connection, @no_sql_connection)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "syncing actions" do
|
56
|
+
before(:each) do
|
57
|
+
@sql_connection = mock(:select_rows => [{'first_name'=> 'Timmy', 'last_name' => 'Zuza', 'preference_id' => 1}])
|
58
|
+
@translation.stub(:sql_connection).and_return(@sql_connection)
|
59
|
+
|
60
|
+
@no_sql_connection = mock()
|
61
|
+
@translation.stub(:no_sql_connection).and_return(@no_sql_connection)
|
62
|
+
|
63
|
+
@table = mock(:translate => {'first_name'=> 'Timmy', 'last_name' => 'Zuza', 'preference_id' => 1},
|
64
|
+
:name => 'users',
|
65
|
+
:embedded? => false,
|
66
|
+
:sql_name => 'users')
|
67
|
+
|
68
|
+
@translation.stub(:tables).and_return([@table])
|
69
|
+
end
|
70
|
+
|
71
|
+
context "SyncHelperMigrator" do
|
72
|
+
it "should create a table with index in the up dir" do
|
73
|
+
migrator = Mongify::Translation::Sync::SyncHelperMigrator.new
|
74
|
+
helper = Mongify::Translation::Sync::SYNC_HELPER_TABLE
|
75
|
+
t = mock({:string => 1, :datetime => 1})
|
76
|
+
t.should_receive(:string).with(:table_name)
|
77
|
+
t.should_receive(:datetime).with(:last_updated_at)
|
78
|
+
migrator.stub(:create_table).and_yield(t)
|
79
|
+
migrator.should_receive(:create_table).with(helper, :id => false)
|
80
|
+
migrator.stub(:add_index)
|
81
|
+
migrator.should_receive(:add_index).with(helper, :table_name)
|
82
|
+
migrator.up
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "setup_sync_table" do
|
87
|
+
before(:each) do
|
88
|
+
@helper = Mongify::Translation::Sync::SYNC_HELPER_TABLE
|
89
|
+
@query = "SELECT count(*) FROM #{@helper}"
|
90
|
+
@sql_connection.stub(:execute).with(@query).and_return(5)
|
91
|
+
@sql_connection.should_receive(:execute).with(@query)
|
92
|
+
@translation.stub(:copy_tables).and_return([mock(:sql_name => 'table1')])
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should create sync helper table if it doesn't exist" do
|
96
|
+
@sql_connection.stub(:execute).with(@query).and_raise
|
97
|
+
migrator = mock(:up)
|
98
|
+
Mongify::Translation::Sync::SyncHelperMigrator.stub(:new).and_return(migrator)
|
99
|
+
migrator.should_receive(:up)
|
100
|
+
@translation.stub(:copy_tables).and_return([])
|
101
|
+
@translation.send(:setup_sync_table)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should find rows for existing table representatives" do
|
105
|
+
@sql_connection.stub(:count).and_return(1)
|
106
|
+
@sql_connection.should_receive(:count).with(@helper, "table_name = 'table1'")
|
107
|
+
@translation.send(:setup_sync_table)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should insert new records for non existing table representatives" do
|
111
|
+
@sql_connection.stub(:count).and_return(0)
|
112
|
+
@sql_connection.should_receive(:count).with(@helper, "table_name = 'table1'")
|
113
|
+
insert_query = "INSERT INTO #{@helper} (table_name, last_updated_at) VALUES ('table1', '1970-01-01')"
|
114
|
+
@sql_connection.stub(:execute).with(insert_query)
|
115
|
+
@sql_connection.should_receive(:execute).with(insert_query)
|
116
|
+
@translation.send(:setup_sync_table)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "set_last_updated_at" do
|
121
|
+
it "should update last_updated_at timestamp for each table that generated sync data" do
|
122
|
+
@translation.stub(:copy_tables).and_return([mock(:sql_name => 'table1')])
|
123
|
+
@translation.max_updated_at = {'table1' => {'max_updated_at_id' => 1, 'key_column' => 'id'}}
|
124
|
+
helper = Mongify::Translation::Sync::SYNC_HELPER_TABLE
|
125
|
+
query = "UPDATE #{helper} SET last_updated_at = (SELECT updated_at FROM table1 WHERE id = '1') WHERE table_name = 'table1'"
|
126
|
+
@sql_connection.stub(:execute).with(query)
|
127
|
+
@sql_connection.should_receive(:execute).with(query)
|
128
|
+
@translation.send(:set_last_updated_at)
|
129
|
+
end
|
130
|
+
it "should not update last_updated_at timestamp for each table that did not generate any sync data" do
|
131
|
+
@translation.stub(:copy_tables).and_return([mock(:sql_name => 'table1')])
|
132
|
+
@translation.max_updated_at = {}
|
133
|
+
@translation.send(:set_last_updated_at)
|
134
|
+
@translation.max_updated_at = {'table1' => {'key_column' => 'id'}}
|
135
|
+
@translation.send(:set_last_updated_at)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "sync_data" do
|
140
|
+
it "should upsert rows that match the new/updated query, mark them as drafts and compute the max updated at" do
|
141
|
+
helper = Mongify::Translation::Sync::SYNC_HELPER_TABLE
|
142
|
+
t = mock(:sql_name => 'table1', :name => 'table1')
|
143
|
+
@translation.stub(:copy_tables).and_return([t])
|
144
|
+
t1, t2 = Time.new(1980).to_s, Time.new(2000).to_s
|
145
|
+
rows = [{"id" => 1, "updated_at" => t1}, {"id" => 2, "updated_at" => t2}]
|
146
|
+
t.stub(:translate).twice.and_return({'pre_mongified_id' => 1, 'updated_at' => t1}, {'pre_mongified_id' => 2, 'updated_at' => t2})
|
147
|
+
|
148
|
+
query = "SELECT t.* FROM table1 t, #{helper} u WHERE t.updated_at > u.last_updated_at AND u.table_name = 'table1'"
|
149
|
+
@sql_connection.stub(:select_by_query).and_return(rows)
|
150
|
+
@sql_connection.should_receive(:select_by_query).with(query)
|
151
|
+
|
152
|
+
draft = Mongify::Translation::Sync::DRAFT_KEY
|
153
|
+
|
154
|
+
@no_sql_connection.stub(:upsert).with('table1', {'pre_mongified_id' => 1, 'updated_at' => t1, draft => true}).and_return(true)
|
155
|
+
@no_sql_connection.stub(:upsert).with('table1', {'pre_mongified_id' => 2, 'updated_at' => t2, draft => true}).and_return(true)
|
156
|
+
@no_sql_connection.should_receive(:upsert).twice
|
157
|
+
|
158
|
+
t.stub(:key_column).and_return(mock({name: 'id'}))
|
159
|
+
|
160
|
+
@translation.send(:sync_data)
|
161
|
+
|
162
|
+
@translation.max_updated_at.should == {'table1' => {'max_updated_at_id' => 2, 'key_column' => 'id'}}
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "sync_update_reference_ids" do
|
168
|
+
it "should delete the draft key" do
|
169
|
+
t = mock(:name => 'table1')
|
170
|
+
@translation.stub(:copy_tables).and_return([t])
|
171
|
+
query = {Mongify::Translation::Sync::DRAFT_KEY => true}
|
172
|
+
row = mock
|
173
|
+
row.stub(:[]).with("_id").and_return(1)
|
174
|
+
@no_sql_connection.stub(:select_by_query).and_return([row])
|
175
|
+
@no_sql_connection.should_receive(:select_by_query).with('table1', query)
|
176
|
+
@translation.stub(:fetch_reference_ids).and_return({})
|
177
|
+
@translation.should_receive(:fetch_reference_ids).with(t, row)
|
178
|
+
@no_sql_connection.should_receive(:update).with('table1', 1, {"$unset" => query})
|
179
|
+
@translation.send(:sync_update_reference_ids)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
@@ -5,7 +5,7 @@ describe Mongify::Translation do
|
|
5
5
|
@file_path = File.expand_path(File.dirname(__FILE__) + '/../files/translation.rb')
|
6
6
|
@translation = Mongify::Translation.parse(@file_path)
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
context "self.load" do
|
10
10
|
it "should require connection" do
|
11
11
|
lambda {Mongify::Translation.load}.should raise_error(ArgumentError)
|
@@ -33,13 +33,13 @@ describe Mongify::Translation do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
context "parsed content" do
|
38
38
|
context "tables" do
|
39
39
|
it "should have 4 tables" do
|
40
40
|
@translation.should have(4).tables
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it "should setup 'comments'" do
|
44
44
|
table = @translation.tables.find{|t| t.name == 'comments'}
|
45
45
|
table.should_not be_nil
|
@@ -47,23 +47,23 @@ describe Mongify::Translation do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
context "find" do
|
52
52
|
before(:each) do
|
53
53
|
@user_table = mock(:name => 'users')
|
54
54
|
@translation.stub(:all_tables).and_return([mock(:name => 'comments'),
|
55
|
-
@user_table,
|
55
|
+
@user_table,
|
56
56
|
mock(:name => 'posts')])
|
57
57
|
end
|
58
58
|
it "should work" do
|
59
|
-
|
59
|
+
|
60
60
|
@translation.find('users').should == @user_table
|
61
61
|
end
|
62
62
|
it "should return nil if nothing is found" do
|
63
63
|
@translation.find('apples').should be_nil
|
64
64
|
end
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
context "tables reference" do
|
68
68
|
before(:each) do
|
69
69
|
@copy_table = mock(:name => 'users', :ignored? => false, :embedded? => false, :polymorphic? => false)
|
@@ -93,7 +93,7 @@ describe Mongify::Translation do
|
|
93
93
|
@translation.polymorphic_tables.should == [@polymorphic_table]
|
94
94
|
end
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
context "add_table" do
|
98
98
|
before(:each) do
|
99
99
|
@table = Mongify::Database::Table.new("users")
|