mongify 1.0.1 → 1.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.
- 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")
|