rubyrep 1.0.9 → 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.
Files changed (38) hide show
  1. data/History.txt +5 -0
  2. data/config/hoe.rb +2 -2
  3. data/config/requirements.rb +1 -1
  4. data/lib/rubyrep/committers/buffered_committer.rb +20 -15
  5. data/lib/rubyrep/configuration.rb +11 -7
  6. data/lib/rubyrep/connection_extenders/connection_extenders.rb +1 -1
  7. data/lib/rubyrep/connection_extenders/jdbc_extender.rb +16 -34
  8. data/lib/rubyrep/connection_extenders/postgresql_extender.rb +66 -0
  9. data/lib/rubyrep/proxy_connection.rb +30 -3
  10. data/lib/rubyrep/replication_helper.rb +33 -3
  11. data/lib/rubyrep/replication_run.rb +20 -1
  12. data/lib/rubyrep/replicators/replicators.rb +6 -1
  13. data/lib/rubyrep/replicators/two_way_replicator.rb +12 -20
  14. data/lib/rubyrep/sync_helper.rb +14 -6
  15. data/lib/rubyrep/syncers/syncers.rb +3 -3
  16. data/lib/rubyrep/syncers/two_way_syncer.rb +4 -4
  17. data/lib/rubyrep/table_sync.rb +23 -1
  18. data/lib/rubyrep/version.rb +2 -2
  19. data/spec/configuration_spec.rb +5 -0
  20. data/spec/connection_extender_interface_spec.rb +16 -21
  21. data/spec/db_specific_connection_extenders_spec.rb +1 -1
  22. data/spec/logged_change_spec.rb +2 -2
  23. data/spec/noisy_connection_spec.rb +7 -9
  24. data/spec/postgresql_schema_support_spec.rb +5 -2
  25. data/spec/postgresql_support_spec.rb +8 -2
  26. data/spec/proxy_connection_spec.rb +34 -30
  27. data/spec/replication_helper_spec.rb +40 -0
  28. data/spec/replication_run_spec.rb +114 -3
  29. data/spec/replicators_spec.rb +5 -0
  30. data/spec/strange_name_support_spec.rb +14 -3
  31. data/spec/sync_helper_spec.rb +11 -4
  32. data/spec/syncers_spec.rb +6 -6
  33. data/spec/table_sync_spec.rb +60 -4
  34. data/spec/two_way_replicator_spec.rb +18 -38
  35. data/spec/two_way_syncer_spec.rb +6 -6
  36. data/spec/type_casting_cursor_spec.rb +8 -8
  37. data/tasks/database.rake +6 -0
  38. metadata +4 -4
@@ -60,6 +60,7 @@ describe Configuration do
60
60
  config = Configuration.new
61
61
  config.options_for_table('b').should == \
62
62
  Syncers::TwoWaySyncer.default_options.clone.
63
+ merge(Replicators::TwoWayReplicator.default_options.clone).
63
64
  merge(config.options)
64
65
  end
65
66
 
@@ -124,6 +125,7 @@ describe Configuration do
124
125
  config.include_tables(/a/, {:bla => :blub})
125
126
  config.options_for_table('b').should == \
126
127
  Syncers::TwoWaySyncer.default_options.clone.
128
+ merge(Replicators::TwoWayReplicator.default_options.clone).
127
129
  merge(config.options)
128
130
  end
129
131
 
@@ -132,6 +134,7 @@ describe Configuration do
132
134
  config.include_tables(/a/, {:bla => :blub})
133
135
  config.options_for_table('a').should == \
134
136
  Syncers::TwoWaySyncer.default_options.clone.
137
+ merge(Replicators::TwoWayReplicator.default_options.clone).
135
138
  merge(config.options).
136
139
  merge(:bla => :blub)
137
140
  end
@@ -144,6 +147,7 @@ describe Configuration do
144
147
  config.include_tables('y', {:bla => :foo})
145
148
  config.options_for_table('a').should == \
146
149
  Syncers::TwoWaySyncer.default_options.clone.
150
+ merge(Replicators::TwoWayReplicator.default_options.clone).
147
151
  merge(config.options).
148
152
  merge(:bla => :blok)
149
153
  end
@@ -172,6 +176,7 @@ describe Configuration do
172
176
  config.add_table_options(/a/, {:foo => :bar})
173
177
  config.options_for_table('a').should == \
174
178
  Syncers::TwoWaySyncer.default_options.clone.
179
+ merge(Replicators::TwoWayReplicator.default_options.clone).
175
180
  merge(config.options).
176
181
  merge(:bla => :blub, :foo => :bar)
177
182
  end
@@ -55,7 +55,7 @@ describe "ConnectionExtender", :shared => true do
55
55
  result = session.left.select_cursor(:table => 'scanner_records', :row_buffer_size => 2)
56
56
  result.next_row
57
57
  result.next_row
58
- result.next_row['id'].should == '3'
58
+ result.next_row['id'].should == 3
59
59
  result.clear
60
60
  end
61
61
 
@@ -63,7 +63,7 @@ describe "ConnectionExtender", :shared => true do
63
63
  session = Session.new
64
64
  result = session.left.select_cursor :table => 'extender_one_record'
65
65
  result.next?.should be_true
66
- result.next_row.should == {'id' => "1", 'name' => 'Alice'}
66
+ result.next_row.should == {'id' => 1, 'name' => 'Alice'}
67
67
  end
68
68
 
69
69
  it "select_cursor next_row should raise if there are no records" do
@@ -74,21 +74,16 @@ describe "ConnectionExtender", :shared => true do
74
74
 
75
75
  it "select_cursor next_row should handle multi byte characters correctly" do
76
76
  session = Session.new
77
- result = session.left.select_cursor :query => "select id, multi_byte from extender_type_check"
78
- row = result.next_row
79
- row.should == {
80
- 'id' => "1",
81
- 'multi_byte' => "よろしくお願(ねが)いします yoroshiku onegai shimasu: I humbly ask for your favor."
82
- }
77
+ result = session.left.select_record(:table => "extender_type_check")['multi_byte'].
78
+ should == "よろしくお願(ねが)いします yoroshiku onegai shimasu: I humbly ask for your favor."
83
79
  end
84
80
 
85
81
  it "select_cursor should read null values correctly" do
86
82
  session = Session.new
87
- result = session.left.select_cursor(
83
+ result = session.left.select_record(
88
84
  :table => 'extender_combined_key',
89
- :row_keys => [{'first_id' => 3, 'second_id' => 1}]
90
- )
91
- result.next_row.should == {'first_id' => '3', 'second_id' => '1', 'name' => nil}
85
+ :row_keys => ['first_id' => 3, 'second_id' => 1]
86
+ ).should == {'first_id' => 3, 'second_id' => 1, 'name' => nil}
92
87
  end
93
88
 
94
89
  it "should read and write binary data correctly" do
@@ -99,17 +94,16 @@ describe "ConnectionExtender", :shared => true do
99
94
  begin
100
95
  session.left.begin_db_transaction
101
96
  session.left.insert_record('extender_type_check', {'id' => 6, 'binary_test' => org_data})
102
-
97
+
103
98
  row = session.left.select_one(
104
99
  'select md5(binary_test) as md5 from extender_type_check where id = 6'
105
100
  )
106
101
  row['md5'].should == Digest::MD5.hexdigest(org_data)
107
102
 
108
- cursor = session.left.select_cursor(
109
- :query => "select id, binary_test from extender_type_check where id = 6"
110
- )
111
- cursor = TypeCastingCursor.new session.left, 'extender_type_check', cursor
112
- result_data = cursor.next_row['binary_test']
103
+ result_data = session.left.select_record(
104
+ :table => "extender_type_check",
105
+ :row_keys => ["id" => 6]
106
+ )['binary_test']
113
107
  Digest::MD5.hexdigest(result_data).should == Digest::MD5.hexdigest(org_data)
114
108
  ensure
115
109
  session.left.rollback_db_transaction
@@ -127,9 +121,10 @@ describe "ConnectionExtender", :shared => true do
127
121
  sql = "insert into extender_type_check(id, text_test) values(2, '#{org_data}')"
128
122
  session.left.execute sql
129
123
 
130
- org_cursor = session.left.select_cursor(:query => "select id, text_test from extender_type_check where id = 2")
131
- cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
132
- result_data = cursor.next_row['text_test']
124
+ result_data = session.left.select_record(
125
+ :table => "extender_type_check",
126
+ :row_keys => ["id" => 2]
127
+ )["text_test"]
133
128
  ensure
134
129
  session.left.rollback_db_transaction
135
130
  end
@@ -6,7 +6,7 @@ include RR
6
6
  extenders = [:mysql, :postgres]
7
7
 
8
8
  extenders.each do |extender|
9
- describe "#{extender.to_s.capitalize} Replication Extender" do
9
+ describe "#{extender.to_s.capitalize} Connection Extender" do
10
10
  before(:each) do
11
11
  @org_test_db = ENV['RR_TEST_DB']
12
12
  ENV['RR_TEST_DB'] = extender.to_s
@@ -121,8 +121,8 @@ describe LoggedChange do
121
121
  change = LoggedChange.new loader
122
122
  change.load_specified 'left_table', {'id' => 1}
123
123
 
124
- change.first_changed_at.to_s.should == t1.to_s
125
- change.last_changed_at.to_s.should == t2.to_s
124
+ (change.first_changed_at - t1).abs.should < 1
125
+ (change.last_changed_at - t2).abs.should < 1
126
126
  ensure
127
127
  session.left.rollback_db_transaction
128
128
  end
@@ -12,10 +12,8 @@ describe NoisyConnection do
12
12
 
13
13
  it "select_cursor should return correct results" do
14
14
  @connection.sweeper.should_receive(:ping).exactly(4).times
15
- fetcher = @connection.select_cursor(:table => 'scanner_records')
16
- row = fetcher.next_row
17
- row.should == {
18
- 'id' => '1',
15
+ @connection.select_record(:table => 'scanner_records').should == {
16
+ 'id' => 1,
19
17
  'name' => 'Alice - exists in both databases'
20
18
  }
21
19
  end
@@ -26,9 +24,8 @@ describe NoisyConnection do
26
24
  begin
27
25
  @connection.insert_record('extender_combined_key', 'first_id' => 8, 'second_id' => '9', 'name' => nil)
28
26
  @connection.select_one(
29
- "select first_id, second_id, name
30
- from extender_combined_key where (first_id, second_id) = (8, 9)") \
31
- .should == {'first_id' => '8', 'second_id' => '9', "name" => nil}
27
+ "select name from extender_combined_key where (first_id, second_id) = (8, 9)"
28
+ ).should == {"name" => nil}
32
29
  ensure
33
30
  @connection.rollback_db_transaction
34
31
  end
@@ -39,8 +36,9 @@ describe NoisyConnection do
39
36
  @connection.begin_db_transaction
40
37
  begin
41
38
  @connection.update_record('scanner_records', 'id' => 1, 'name' => 'update_test')
42
- @connection.select_one("select * from scanner_records where id = 1") \
43
- .should == {'id' => '1', 'name' => 'update_test'}
39
+ @connection.select_one(
40
+ "select name from scanner_records where id = 1"
41
+ ).should == {'name' => 'update_test'}
44
42
  ensure
45
43
  @connection.rollback_db_transaction
46
44
  end
@@ -61,9 +61,12 @@ describe "PostgreSQL schema support" do
61
61
  should == 'select "id", "name" from "rr_simple" order by "id"'
62
62
  end
63
63
 
64
- it "TypeCasingCursor should work" do
64
+ it "TypeCastingCursor should work" do
65
65
  session = Session.new
66
- org_cursor = session.left.select_cursor(:query => "select id, name from rr_simple where id = 1")
66
+ org_cursor = session.left.select_cursor(
67
+ :query => "select id, name from rr_simple where id = 1",
68
+ :type_cast => false
69
+ )
67
70
  cursor = TypeCastingCursor.new session.left, 'rr_simple', org_cursor
68
71
 
69
72
  row = cursor.next_row
@@ -23,7 +23,10 @@ describe "PostgreSQL support" do
23
23
  {'id' => 2, 'timestamp' => Time.local(2009, "feb", 16, 20, 48, 1, 543)}
24
24
  )
25
25
 
26
- org_cursor = session.left.select_cursor(:query => "select id, timestamp from extender_type_check where id = 2")
26
+ org_cursor = session.left.select_cursor(
27
+ :query => "select id, timestamp from extender_type_check where id = 2",
28
+ :type_cast => false
29
+ )
27
30
  cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
28
31
 
29
32
  row = cursor.next_row
@@ -43,7 +46,10 @@ describe "PostgreSQL support" do
43
46
  {'id' => 2, 'timestamp' => Time.local(2009, "feb", 16, 13, 37, 11, 126291)}
44
47
  )
45
48
 
46
- org_cursor = session.left.select_cursor(:query => "select id, timestamp from extender_type_check where id = 2")
49
+ org_cursor = session.left.select_cursor(
50
+ :query => "select id, timestamp from extender_type_check where id = 2",
51
+ :type_cast => false
52
+ )
47
53
  cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
48
54
 
49
55
  row = cursor.next_row
@@ -115,9 +115,9 @@ describe ProxyConnection do
115
115
  # (To verify the behaviour for all supported databases)
116
116
 
117
117
  it "select_cursor should return the result fetcher" do
118
- fetcher = @connection.select_cursor(:table => 'scanner_records')
118
+ fetcher = @connection.select_cursor(:table => 'scanner_records', :type_cast => false)
119
119
  fetcher.connection.should == @connection
120
- fetcher.options.should == {:table => 'scanner_records'}
120
+ fetcher.options.should == {:table => 'scanner_records', :type_cast => false}
121
121
  end
122
122
 
123
123
  it "select_cursor should return a type casting cursor if :type_cast option is specified" do
@@ -222,8 +222,10 @@ describe ProxyConnection do
222
222
  @connection.begin_db_transaction
223
223
  begin
224
224
  @connection.insert_record('scanner_records', 'id' => 9, 'name' => 'bla')
225
- @connection.select_one("select * from scanner_records where id = 9") \
226
- .should == {'id' => '9', 'name' => 'bla'}
225
+ @connection.select_record(
226
+ :table => 'scanner_records',
227
+ :row_keys => ['id' => 9]
228
+ ).should == {'id' => 9, 'name' => 'bla'}
227
229
  ensure
228
230
  @connection.rollback_db_transaction
229
231
  end
@@ -233,10 +235,10 @@ describe ProxyConnection do
233
235
  @connection.begin_db_transaction
234
236
  begin
235
237
  @connection.insert_record('extender_combined_key', 'first_id' => 8, 'second_id' => '9')
236
- @connection.select_one(
237
- "select first_id, second_id
238
- from extender_combined_key where (first_id, second_id) = (8, 9)") \
239
- .should == {'first_id' => '8', 'second_id' => '9'}
238
+ @connection.select_record(
239
+ :table => 'extender_combined_key',
240
+ :row_keys => ['first_id' => 8, 'second_id' => 9]
241
+ ).should == {'first_id' => 8, 'second_id' => 9, 'name' => nil}
240
242
  ensure
241
243
  @connection.rollback_db_transaction
242
244
  end
@@ -246,10 +248,10 @@ describe ProxyConnection do
246
248
  @connection.begin_db_transaction
247
249
  begin
248
250
  @connection.insert_record('extender_combined_key', 'first_id' => 8, 'second_id' => '9', 'name' => nil)
249
- @connection.select_one(
250
- "select first_id, second_id, name
251
- from extender_combined_key where (first_id, second_id) = (8, 9)") \
252
- .should == {'first_id' => '8', 'second_id' => '9', "name" => nil}
251
+ @connection.select_record(
252
+ :table => 'extender_combined_key',
253
+ :row_keys => ['first_id' => 8, 'second_id' => 9]
254
+ ).should == {'first_id' => 8, 'second_id' => 9, "name" => nil}
253
255
  ensure
254
256
  @connection.rollback_db_transaction
255
257
  end
@@ -289,8 +291,10 @@ describe ProxyConnection do
289
291
  @connection.begin_db_transaction
290
292
  begin
291
293
  @connection.update_record('scanner_records', 'id' => 1, 'name' => 'update_test')
292
- @connection.select_one("select * from scanner_records where id = 1") \
293
- .should == {'id' => '1', 'name' => 'update_test'}
294
+ @connection.select_record(
295
+ :table => "scanner_records",
296
+ :row_keys => ['id' => 1]
297
+ ).should == {'id' => 1, 'name' => 'update_test'}
294
298
  ensure
295
299
  @connection.rollback_db_transaction
296
300
  end
@@ -314,10 +318,10 @@ describe ProxyConnection do
314
318
  @connection.begin_db_transaction
315
319
  begin
316
320
  @connection.update_record('extender_combined_key', 'first_id' => 1, 'second_id' => '1', 'name' => 'xy')
317
- @connection.select_one(
318
- "select first_id, second_id, name
319
- from extender_combined_key where (first_id, second_id) = (1, 1)") \
320
- .should == {'first_id' => '1', 'second_id' => '1', 'name' => 'xy'}
321
+ @connection.select_record(
322
+ :table => 'extender_combined_key',
323
+ :row_keys => ['first_id' => 1, 'second_id' => 1]
324
+ ).should == {'first_id' => 1, 'second_id' => 1, 'name' => 'xy'}
321
325
  ensure
322
326
  @connection.rollback_db_transaction
323
327
  end
@@ -329,10 +333,10 @@ describe ProxyConnection do
329
333
  @connection.update_record 'extender_combined_key',
330
334
  {'first_id' => '8', 'second_id' => '9', 'name' => 'xy'},
331
335
  {'first_id' => '1', 'second_id' => '1'}
332
- @connection.select_one(
333
- "select first_id, second_id, name
334
- from extender_combined_key where (first_id, second_id) = (8, 9)") \
335
- .should == {'first_id' => '8', 'second_id' => '9', 'name' => 'xy'}
336
+ @connection.select_record(
337
+ :table => 'extender_combined_key',
338
+ :row_keys => ['first_id' => 8, 'second_id' => 9]
339
+ ).should == {'first_id' => 8, 'second_id' => 9, 'name' => 'xy'}
336
340
  ensure
337
341
  @connection.rollback_db_transaction
338
342
  end
@@ -342,10 +346,10 @@ describe ProxyConnection do
342
346
  @connection.begin_db_transaction
343
347
  begin
344
348
  @connection.update_record('extender_combined_key', 'first_id' => 1, 'second_id' => '1', 'name' => nil)
345
- @connection.select_one(
346
- "select first_id, second_id, name
347
- from extender_combined_key where (first_id, second_id) = (1, 1)") \
348
- .should == {'first_id' => '1', 'second_id' => '1', 'name' => nil}
349
+ @connection.select_record(
350
+ :table => 'extender_combined_key',
351
+ :row_keys => ['first_id' => 1, 'second_id' => 1]
352
+ ).should == {'first_id' => 1, 'second_id' => 1, 'name' => nil}
349
353
  ensure
350
354
  @connection.rollback_db_transaction
351
355
  end
@@ -364,10 +368,10 @@ describe ProxyConnection do
364
368
  }
365
369
  @connection.update_record('extender_type_check', test_data)
366
370
 
367
- org_cursor = @connection.select_cursor(:query => "select * from extender_type_check where id = 1")
368
- cursor = TypeCastingCursor.new @connection, 'extender_type_check', org_cursor
369
- result_data = cursor.next_row
370
- result_data.should == test_data
371
+ @connection.select_record(
372
+ :table => "extender_type_check",
373
+ :row_keys => ["id" => 1]
374
+ ).should == test_data
371
375
  ensure
372
376
  @connection.rollback_db_transaction
373
377
  end
@@ -22,6 +22,28 @@ describe ReplicationHelper do
22
22
  helper.session.should == rep_run.session
23
23
  end
24
24
 
25
+ it "type_cast should convert the row values correctly" do
26
+ rep_run = ReplicationRun.new(Session.new, TaskSweeper.new(1))
27
+
28
+ helper = ReplicationHelper.new(rep_run)
29
+ helper.type_cast('scanner_records', 'id' => '1', 'name' => 'bla').
30
+ should == {'id' => 1, 'name' => 'bla'}
31
+
32
+ string_row = {
33
+ 'id' => '1',
34
+ 'decimal_test' => '1.234',
35
+ 'timestamp' => 'Sat Nov 10 20:15:01 +0900 2007',
36
+ 'binary_test' => "\004\b[\n\"\bbla:\ndummyi\006i\ai\b"
37
+ }
38
+ row = helper.type_cast('extender_type_check', string_row)
39
+ row.should == {
40
+ 'id' => 1,
41
+ 'decimal_test' => BigDecimal.new("1.234"),
42
+ 'timestamp' => Time.local(2007,"nov",10,20,15,1),
43
+ 'binary_test' => Marshal.dump(['bla',:dummy,1,2,3])
44
+ }
45
+ end
46
+
25
47
  it "new_transaction? should delegate to the committer" do
26
48
  session = Session.new
27
49
  rep_run = ReplicationRun.new(session, TaskSweeper.new(1))
@@ -85,6 +107,24 @@ describe ReplicationHelper do
85
107
  }
86
108
  end
87
109
 
110
+ it "options_for_table should return the correct options for the table" do
111
+ Initializer.configuration.options = {:a => 1, :b => 2}
112
+ Initializer.configuration.add_table_options 'scanner_records', {:b => 3}
113
+ rep_run = ReplicationRun.new(Session.new, TaskSweeper.new(1))
114
+ helper = ReplicationHelper.new(rep_run)
115
+ options = helper.options_for_table('scanner_records')
116
+ options[:a].should == 1
117
+ options[:b].should == 3
118
+ end
119
+
120
+ it "options_for_table should merge the configured options into the default two way replicator options" do
121
+ rep_run = ReplicationRun.new(Session.new, TaskSweeper.new(1))
122
+ helper = ReplicationHelper.new(rep_run)
123
+ helper.options_for_table('scanner_records').include?(:left_change_handling).should be_true
124
+ helper.options_for_table('scanner_records').include?(:right_change_handling).should be_true
125
+ helper.options_for_table('scanner_records').include?(:replication_conflict_handling).should be_true
126
+ end
127
+
88
128
  it "log_replication_outcome should log the replication outcome correctly" do
89
129
  session = Session.new
90
130
  session.left.begin_db_transaction
@@ -40,6 +40,66 @@ describe ReplicationRun do
40
40
  run.replicator.rep_helper.should == run.helper
41
41
  end
42
42
 
43
+ it "event_filtered? should behave correctly" do
44
+ begin
45
+ config = deep_copy(standard_config)
46
+ config.options[:committer] = :never_commit
47
+ session = Session.new(config)
48
+
49
+ session.left.insert_record 'extender_no_record', {
50
+ 'id' => '1',
51
+ 'name' => 'bla'
52
+ }
53
+ session.left.insert_record 'rr_pending_changes', {
54
+ 'change_table' => 'extender_no_record',
55
+ 'change_key' => 'id|1',
56
+ 'change_type' => 'I',
57
+ 'change_time' => Time.now
58
+ }
59
+
60
+ loaders = LoggedChangeLoaders.new(session)
61
+ loaders.update
62
+ diff = ReplicationDifference.new loaders
63
+ diff.load
64
+
65
+ # No event filter at all
66
+ run = ReplicationRun.new session, TaskSweeper.new(1)
67
+ run.event_filtered?(diff).should be_false
68
+
69
+ # Event filter that does not handle replication events
70
+ session.configuration.options[:event_filter] = Object.new
71
+ run = ReplicationRun.new session, TaskSweeper.new(1)
72
+ run.event_filtered?(diff).should be_false
73
+
74
+ # event_filtered? should signal filtering (i. e. return true) if filter returns false.
75
+ filter = Object.new
76
+ def filter.before_replicate(table, key, helper, diff)
77
+ false
78
+ end
79
+ session.configuration.options[:event_filter] = filter
80
+ run = ReplicationRun.new session, TaskSweeper.new(1)
81
+ run.event_filtered?(diff).should be_true
82
+
83
+ # event_filtered? should return false if filter returns true.
84
+ filter = {}
85
+ def filter.before_replicate(table, key, helper, diff)
86
+ self[:args] = [table, key, helper, diff]
87
+ true
88
+ end
89
+ session.configuration.options[:event_filter] = filter
90
+ run = ReplicationRun.new session, TaskSweeper.new(1)
91
+ run.event_filtered?(diff).should be_false
92
+ filter[:args].should == ['extender_no_record', {'id' => 1}, run.helper, diff]
93
+ ensure
94
+ Committers::NeverCommitter.rollback_current_session
95
+ if session
96
+ session.left.execute "delete from extender_no_record"
97
+ session.right.execute "delete from extender_no_record"
98
+ session.left.execute "delete from rr_pending_changes"
99
+ end
100
+ end
101
+ end
102
+
43
103
  it "run should replicate all logged changes" do
44
104
  begin
45
105
  config = deep_copy(standard_config)
@@ -61,10 +121,61 @@ describe ReplicationRun do
61
121
  run = ReplicationRun.new session, TaskSweeper.new(1)
62
122
  run.run
63
123
 
64
- session.right.select_one("select * from extender_no_record").should == {
124
+ session.right.select_record(:table => "extender_no_record").should == {
125
+ 'id' => 1,
126
+ 'name' => 'bla'
127
+ }
128
+ ensure
129
+ Committers::NeverCommitter.rollback_current_session
130
+ if session
131
+ session.left.execute "delete from extender_no_record"
132
+ session.right.execute "delete from extender_no_record"
133
+ session.left.execute "delete from rr_pending_changes"
134
+ end
135
+ end
136
+ end
137
+
138
+ it "run should not replicate filtered changes" do
139
+ begin
140
+ config = deep_copy(standard_config)
141
+ config.options[:committer] = :never_commit
142
+
143
+ filter = Object.new
144
+ def filter.before_replicate(table, key, helper, diff)
145
+ key['id'] != 1
146
+ end
147
+ config.options[:event_filter] = filter
148
+
149
+ session = Session.new(config)
150
+
151
+ session.left.insert_record 'extender_no_record', {
65
152
  'id' => '1',
66
153
  'name' => 'bla'
67
154
  }
155
+ session.left.insert_record 'extender_no_record', {
156
+ 'id' => '2',
157
+ 'name' => 'blub'
158
+ }
159
+ session.left.insert_record 'rr_pending_changes', {
160
+ 'change_table' => 'extender_no_record',
161
+ 'change_key' => 'id|1',
162
+ 'change_type' => 'I',
163
+ 'change_time' => Time.now
164
+ }
165
+ session.left.insert_record 'rr_pending_changes', {
166
+ 'change_table' => 'extender_no_record',
167
+ 'change_key' => 'id|2',
168
+ 'change_type' => 'I',
169
+ 'change_time' => Time.now
170
+ }
171
+
172
+ run = ReplicationRun.new session, TaskSweeper.new(1)
173
+ run.run
174
+
175
+ session.right.select_records(:table => "extender_no_record").should == [{
176
+ 'id' => 2,
177
+ 'name' => 'blub'
178
+ }]
68
179
  ensure
69
180
  Committers::NeverCommitter.rollback_current_session
70
181
  if session
@@ -247,8 +358,8 @@ describe ReplicationRun do
247
358
  run = ReplicationRun.new session, TaskSweeper.new(1)
248
359
  run.run
249
360
 
250
- session.right.select_one("select * from extender_no_record").should == {
251
- 'id' => '1',
361
+ session.right.select_record(:table => "extender_no_record").should == {
362
+ 'id' => 1,
252
363
  'name' => 'bla'
253
364
  }
254
365
 
@@ -21,6 +21,11 @@ describe Replicators do
21
21
  Replicators.replicators.should == :dummy_data
22
22
  end
23
23
 
24
+ it "configured_replicator should return the correct replicator" do
25
+ options = {:replicator => :two_way}
26
+ Replicators.configured_replicator(options).should == Replicators::TwoWayReplicator
27
+ end
28
+
24
29
  it "register should register the provided replicator" do
25
30
  Replicators.instance_variable_set :@replicators, nil
26
31
  Replicators.register :a_key => :a
@@ -11,10 +11,21 @@ describe "Unusual table and column name support" do
11
11
  session = Session.new
12
12
  session.left.begin_db_transaction
13
13
  begin
14
- session.left.insert_record STRANGE_TABLE, {
15
- 'id' => 1,
16
- STRANGE_COLUMN => 'bla'
14
+ select_row = Proc.new {
15
+ session.left.
16
+ select_one(
17
+ "select #{session.left.quote_column_name(STRANGE_COLUMN)}
18
+ from #{session.left.quote_table_name(STRANGE_TABLE)}")
17
19
  }
20
+
21
+ session.left.insert_record STRANGE_TABLE, 'id' => 1, STRANGE_COLUMN => 'bla'
22
+ select_row.call[STRANGE_COLUMN].should == 'bla'
23
+
24
+ session.left.update_record STRANGE_TABLE, 'id' => 1, STRANGE_COLUMN => 'blub'
25
+ select_row.call[STRANGE_COLUMN].should == 'blub'
26
+
27
+ session.left.delete_record STRANGE_TABLE, 'id' => 1
28
+ select_row.call.should be_nil
18
29
  ensure
19
30
  session.left.rollback_db_transaction
20
31
  end
@@ -21,6 +21,13 @@ describe SyncHelper do
21
21
  helper.session.should == sync.session
22
22
  end
23
23
 
24
+ it "extract_key should extract the primary key column_name => value pairs" do
25
+ sync = TableSync.new(Session.new, 'extender_combined_key')
26
+ helper = SyncHelper.new(sync)
27
+ helper.extract_key('first_id' => 1, 'second_id' => 2, 'name' => 'bla').
28
+ should == {'first_id' => 1, 'second_id' => 2}
29
+ end
30
+
24
31
  it "ensure_event_log should ask the replication_initializer to ensure the event log" do
25
32
  sync = TableSync.new(Session.new, 'scanner_records')
26
33
  helper = SyncHelper.new(sync)
@@ -120,7 +127,7 @@ describe SyncHelper do
120
127
  helper = SyncHelper.new(sync)
121
128
  c = helper.instance_eval {committer}
122
129
  c.should_receive(:insert_record).with(:right, 'scanner_records', :dummy_record)
123
- helper.insert_record :right, :dummy_record
130
+ helper.insert_record :right, 'scanner_records', :dummy_record
124
131
  end
125
132
 
126
133
  it "update_record should update the given record" do
@@ -128,7 +135,7 @@ describe SyncHelper do
128
135
  helper = SyncHelper.new(sync)
129
136
  c = helper.instance_eval {committer}
130
137
  c.should_receive(:update_record).with(:right, 'scanner_records', :dummy_record, nil)
131
- helper.update_record :right, :dummy_record
138
+ helper.update_record :right, 'scaner_records', :dummy_record
132
139
  end
133
140
 
134
141
  it "update_record should update the given record with the provided old key" do
@@ -136,7 +143,7 @@ describe SyncHelper do
136
143
  helper = SyncHelper.new(sync)
137
144
  c = helper.instance_eval {committer}
138
145
  c.should_receive(:update_record).with(:right, 'scanner_records', :dummy_record, :old_key)
139
- helper.update_record :right, :dummy_record, :old_key
146
+ helper.update_record :right, 'scanner_records', :dummy_record, :old_key
140
147
  end
141
148
 
142
149
  it "delete_record should delete the given record" do
@@ -144,7 +151,7 @@ describe SyncHelper do
144
151
  helper = SyncHelper.new(sync)
145
152
  c = helper.instance_eval {committer}
146
153
  c.should_receive(:delete_record).with(:right, 'scanner_records', :dummy_record)
147
- helper.delete_record :right, :dummy_record
154
+ helper.delete_record :right, 'scanner_records', :dummy_record
148
155
  end
149
156
 
150
157
  it "finalize should be delegated to the committer" do