andyjeffries-rubyrep 1.2.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.
- data/History.txt +83 -0
- data/License.txt +20 -0
- data/Manifest.txt +151 -0
- data/README.txt +37 -0
- data/bin/rubyrep +8 -0
- data/lib/rubyrep.rb +72 -0
- data/lib/rubyrep/base_runner.rb +195 -0
- data/lib/rubyrep/command_runner.rb +144 -0
- data/lib/rubyrep/committers/buffered_committer.rb +151 -0
- data/lib/rubyrep/committers/committers.rb +152 -0
- data/lib/rubyrep/configuration.rb +275 -0
- data/lib/rubyrep/connection_extenders/connection_extenders.rb +165 -0
- data/lib/rubyrep/connection_extenders/jdbc_extender.rb +65 -0
- data/lib/rubyrep/connection_extenders/mysql_extender.rb +59 -0
- data/lib/rubyrep/connection_extenders/postgresql_extender.rb +277 -0
- data/lib/rubyrep/database_proxy.rb +52 -0
- data/lib/rubyrep/direct_table_scan.rb +75 -0
- data/lib/rubyrep/generate_runner.rb +105 -0
- data/lib/rubyrep/initializer.rb +39 -0
- data/lib/rubyrep/log_helper.rb +30 -0
- data/lib/rubyrep/logged_change.rb +160 -0
- data/lib/rubyrep/logged_change_loader.rb +197 -0
- data/lib/rubyrep/noisy_connection.rb +80 -0
- data/lib/rubyrep/proxied_table_scan.rb +171 -0
- data/lib/rubyrep/proxy_block_cursor.rb +145 -0
- data/lib/rubyrep/proxy_connection.rb +431 -0
- data/lib/rubyrep/proxy_cursor.rb +44 -0
- data/lib/rubyrep/proxy_row_cursor.rb +43 -0
- data/lib/rubyrep/proxy_runner.rb +89 -0
- data/lib/rubyrep/replication_difference.rb +100 -0
- data/lib/rubyrep/replication_extenders/mysql_replication.rb +271 -0
- data/lib/rubyrep/replication_extenders/postgresql_replication.rb +236 -0
- data/lib/rubyrep/replication_extenders/replication_extenders.rb +26 -0
- data/lib/rubyrep/replication_helper.rb +142 -0
- data/lib/rubyrep/replication_initializer.rb +327 -0
- data/lib/rubyrep/replication_run.rb +142 -0
- data/lib/rubyrep/replication_runner.rb +166 -0
- data/lib/rubyrep/replicators/replicators.rb +42 -0
- data/lib/rubyrep/replicators/two_way_replicator.rb +361 -0
- data/lib/rubyrep/scan_progress_printers/progress_bar.rb +65 -0
- data/lib/rubyrep/scan_progress_printers/scan_progress_printers.rb +65 -0
- data/lib/rubyrep/scan_report_printers/scan_detail_reporter.rb +111 -0
- data/lib/rubyrep/scan_report_printers/scan_report_printers.rb +67 -0
- data/lib/rubyrep/scan_report_printers/scan_summary_reporter.rb +75 -0
- data/lib/rubyrep/scan_runner.rb +25 -0
- data/lib/rubyrep/session.rb +230 -0
- data/lib/rubyrep/sync_helper.rb +121 -0
- data/lib/rubyrep/sync_runner.rb +31 -0
- data/lib/rubyrep/syncers/syncers.rb +112 -0
- data/lib/rubyrep/syncers/two_way_syncer.rb +174 -0
- data/lib/rubyrep/table_scan.rb +54 -0
- data/lib/rubyrep/table_scan_helper.rb +46 -0
- data/lib/rubyrep/table_sorter.rb +70 -0
- data/lib/rubyrep/table_spec_resolver.rb +142 -0
- data/lib/rubyrep/table_sync.rb +90 -0
- data/lib/rubyrep/task_sweeper.rb +77 -0
- data/lib/rubyrep/trigger_mode_switcher.rb +63 -0
- data/lib/rubyrep/type_casting_cursor.rb +31 -0
- data/lib/rubyrep/uninstall_runner.rb +93 -0
- data/lib/rubyrep/version.rb +9 -0
- data/rubyrep +8 -0
- data/rubyrep.bat +4 -0
- data/setup.rb +1585 -0
- data/spec/base_runner_spec.rb +218 -0
- data/spec/buffered_committer_spec.rb +274 -0
- data/spec/command_runner_spec.rb +145 -0
- data/spec/committers_spec.rb +178 -0
- data/spec/configuration_spec.rb +203 -0
- data/spec/connection_extender_interface_spec.rb +141 -0
- data/spec/connection_extenders_registration_spec.rb +164 -0
- data/spec/database_proxy_spec.rb +48 -0
- data/spec/database_rake_spec.rb +40 -0
- data/spec/db_specific_connection_extenders_spec.rb +34 -0
- data/spec/db_specific_replication_extenders_spec.rb +38 -0
- data/spec/direct_table_scan_spec.rb +61 -0
- data/spec/dolphins.jpg +0 -0
- data/spec/generate_runner_spec.rb +84 -0
- data/spec/initializer_spec.rb +46 -0
- data/spec/log_helper_spec.rb +39 -0
- data/spec/logged_change_loader_spec.rb +68 -0
- data/spec/logged_change_spec.rb +470 -0
- data/spec/noisy_connection_spec.rb +78 -0
- data/spec/postgresql_replication_spec.rb +48 -0
- data/spec/postgresql_schema_support_spec.rb +212 -0
- data/spec/postgresql_support_spec.rb +63 -0
- data/spec/progress_bar_spec.rb +77 -0
- data/spec/proxied_table_scan_spec.rb +151 -0
- data/spec/proxy_block_cursor_spec.rb +197 -0
- data/spec/proxy_connection_spec.rb +423 -0
- data/spec/proxy_cursor_spec.rb +56 -0
- data/spec/proxy_row_cursor_spec.rb +66 -0
- data/spec/proxy_runner_spec.rb +70 -0
- data/spec/replication_difference_spec.rb +161 -0
- data/spec/replication_extender_interface_spec.rb +367 -0
- data/spec/replication_extenders_spec.rb +32 -0
- data/spec/replication_helper_spec.rb +178 -0
- data/spec/replication_initializer_spec.rb +509 -0
- data/spec/replication_run_spec.rb +443 -0
- data/spec/replication_runner_spec.rb +254 -0
- data/spec/replicators_spec.rb +36 -0
- data/spec/rubyrep_spec.rb +8 -0
- data/spec/scan_detail_reporter_spec.rb +119 -0
- data/spec/scan_progress_printers_spec.rb +68 -0
- data/spec/scan_report_printers_spec.rb +67 -0
- data/spec/scan_runner_spec.rb +50 -0
- data/spec/scan_summary_reporter_spec.rb +61 -0
- data/spec/session_spec.rb +253 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +305 -0
- data/spec/strange_name_support_spec.rb +135 -0
- data/spec/sync_helper_spec.rb +169 -0
- data/spec/sync_runner_spec.rb +78 -0
- data/spec/syncers_spec.rb +171 -0
- data/spec/table_scan_helper_spec.rb +36 -0
- data/spec/table_scan_spec.rb +49 -0
- data/spec/table_sorter_spec.rb +30 -0
- data/spec/table_spec_resolver_spec.rb +111 -0
- data/spec/table_sync_spec.rb +140 -0
- data/spec/task_sweeper_spec.rb +47 -0
- data/spec/trigger_mode_switcher_spec.rb +83 -0
- data/spec/two_way_replicator_spec.rb +721 -0
- data/spec/two_way_syncer_spec.rb +256 -0
- data/spec/type_casting_cursor_spec.rb +50 -0
- data/spec/uninstall_runner_spec.rb +93 -0
- metadata +190 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
|
|
3
|
+
include RR
|
|
4
|
+
|
|
5
|
+
describe NoisyConnection do
|
|
6
|
+
before(:each) do
|
|
7
|
+
Initializer.configuration = proxied_config
|
|
8
|
+
@connection = ProxyConnection.new Initializer.configuration.left
|
|
9
|
+
@connection.send(:extend, NoisyConnection)
|
|
10
|
+
@connection.sweeper = TaskSweeper.new(1)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "select_cursor should return correct results" do
|
|
14
|
+
@connection.sweeper.should_receive(:ping).exactly(4).times
|
|
15
|
+
@connection.select_record(:table => 'scanner_records').should == {
|
|
16
|
+
'id' => 1,
|
|
17
|
+
'name' => 'Alice - exists in both databases'
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "insert_record should write nil values correctly" do
|
|
22
|
+
@connection.sweeper.should_receive(:ping).exactly(2).times
|
|
23
|
+
@connection.begin_db_transaction
|
|
24
|
+
begin
|
|
25
|
+
@connection.insert_record('extender_combined_key', 'first_id' => 8, 'second_id' => '9', 'name' => nil)
|
|
26
|
+
@connection.select_one(
|
|
27
|
+
"select name from extender_combined_key where (first_id, second_id) = (8, 9)"
|
|
28
|
+
).should == {"name" => nil}
|
|
29
|
+
ensure
|
|
30
|
+
@connection.rollback_db_transaction
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "update_record should update the specified record" do
|
|
35
|
+
@connection.sweeper.should_receive(:ping).exactly(2).times
|
|
36
|
+
@connection.begin_db_transaction
|
|
37
|
+
begin
|
|
38
|
+
@connection.update_record('scanner_records', 'id' => 1, 'name' => 'update_test')
|
|
39
|
+
@connection.select_one(
|
|
40
|
+
"select name from scanner_records where id = 1"
|
|
41
|
+
).should == {'name' => 'update_test'}
|
|
42
|
+
ensure
|
|
43
|
+
@connection.rollback_db_transaction
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "delete_record should delete the specified record" do
|
|
48
|
+
@connection.sweeper.should_receive(:ping).exactly(2).times
|
|
49
|
+
@connection.begin_db_transaction
|
|
50
|
+
begin
|
|
51
|
+
@connection.delete_record('extender_combined_key', 'first_id' => 1, 'second_id' => '1', 'name' => 'xy')
|
|
52
|
+
@connection.select_one(
|
|
53
|
+
"select first_id, second_id, name
|
|
54
|
+
from extender_combined_key where (first_id, second_id) = (1, 1)") \
|
|
55
|
+
.should be_nil
|
|
56
|
+
ensure
|
|
57
|
+
@connection.rollback_db_transaction
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "commit_db_transaction should update TaskSweeper" do
|
|
62
|
+
@connection.begin_db_transaction
|
|
63
|
+
initializer = ReplicationInitializer.new Session.new(standard_config)
|
|
64
|
+
begin
|
|
65
|
+
@connection.execute "insert into scanner_records(id,name) values(99, 'bla')"
|
|
66
|
+
@connection.sweeper.should_receive(:ping).exactly(2).times
|
|
67
|
+
@connection.commit_db_transaction
|
|
68
|
+
initializer.silence_ddl_notices(:left) do # avoid PostgreSQL warning that no transaction is open
|
|
69
|
+
@connection.rollback_db_transaction
|
|
70
|
+
end
|
|
71
|
+
@connection.select_one("select name from scanner_records where id = 99")['name'].
|
|
72
|
+
should == 'bla'
|
|
73
|
+
ensure
|
|
74
|
+
@connection.execute "delete from scanner_records where id = 99"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'config/test_config.rb'
|
|
4
|
+
|
|
5
|
+
include RR
|
|
6
|
+
|
|
7
|
+
describe "PostgreSQLReplication", :shared => true do
|
|
8
|
+
before(:each) do
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "create_replication_trigger should also work if language plpgsql does not yet exist" do
|
|
12
|
+
session = nil
|
|
13
|
+
begin
|
|
14
|
+
session = Session.new
|
|
15
|
+
session.left.begin_db_transaction
|
|
16
|
+
unless session.left.select_all("select lanname from pg_language where lanname = 'plpgsql'").empty?
|
|
17
|
+
session.left.execute "DROP LANGUAGE plpgsql"
|
|
18
|
+
end
|
|
19
|
+
params = {
|
|
20
|
+
:trigger_name => 'rr_trigger_test',
|
|
21
|
+
:table => 'trigger_test',
|
|
22
|
+
:keys => ['first_id', 'second_id'],
|
|
23
|
+
:log_table => 'rr_pending_changes',
|
|
24
|
+
:key_sep => '|',
|
|
25
|
+
:exclude_rr_activity => false,
|
|
26
|
+
}
|
|
27
|
+
session.left.create_replication_trigger params
|
|
28
|
+
session.left.insert_record 'trigger_test', {
|
|
29
|
+
'first_id' => 1,
|
|
30
|
+
'second_id' => 2,
|
|
31
|
+
'name' => 'bla'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
row = session.left.select_one("select * from rr_pending_changes")
|
|
35
|
+
row.delete 'id'
|
|
36
|
+
row.delete 'change_time'
|
|
37
|
+
row.should == {
|
|
38
|
+
'change_table' => 'trigger_test',
|
|
39
|
+
'change_key' => 'first_id|1|second_id|2',
|
|
40
|
+
'change_new_key' => nil,
|
|
41
|
+
'change_type' => 'I'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
ensure
|
|
45
|
+
session.left.rollback_db_transaction if session
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
|
|
3
|
+
include RR
|
|
4
|
+
|
|
5
|
+
require File.dirname(__FILE__) + "/../config/test_config.rb"
|
|
6
|
+
|
|
7
|
+
describe "PostgreSQL schema support" do
|
|
8
|
+
before(:each) do
|
|
9
|
+
config = deep_copy(standard_config)
|
|
10
|
+
config.options[:rep_prefix] = 'rx'
|
|
11
|
+
config.left[:schema_search_path] = 'rr'
|
|
12
|
+
config.right[:schema_search_path] = 'rr'
|
|
13
|
+
Initializer.configuration = config
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
after(:each) do
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if Initializer.configuration.left[:adapter] == 'postgresql'
|
|
20
|
+
it "tables should show the tables from the schema and no others" do
|
|
21
|
+
session = Session.new
|
|
22
|
+
session.left.tables.include?('rr_simple').should be_true
|
|
23
|
+
session.left.tables.include?('scanner_records').should be_false
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "tables should not show the tables from other schemas" do
|
|
27
|
+
session = Session.new standard_config
|
|
28
|
+
session.left.tables.include?('scanner_records').should be_true
|
|
29
|
+
session.left.tables.include?('rr_simple').should be_false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "primary_key_names should work" do
|
|
33
|
+
session = Session.new
|
|
34
|
+
session.left.primary_key_names('rr_simple').should == ['id']
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "primary_key_names should pick the table in the target schema" do
|
|
38
|
+
session = Session.new
|
|
39
|
+
session.left.primary_key_names('rr_duplicate').should == ['id']
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "column_names should work" do
|
|
43
|
+
session = Session.new
|
|
44
|
+
session.left.column_names('rr_simple').should == ['id', 'name']
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "column_names should pick the table in the target schema" do
|
|
48
|
+
session = Session.new
|
|
49
|
+
session.left.column_names('rr_duplicate').should == ['id', 'name']
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "referenced_tables should work" do
|
|
53
|
+
session = Session.new
|
|
54
|
+
session.left.referenced_tables(['rr_referencing']).should == {
|
|
55
|
+
'rr_referencing' => ['rr_referenced']
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "table_select_query should work" do
|
|
60
|
+
session = Session.new
|
|
61
|
+
session.left.table_select_query('rr_simple').
|
|
62
|
+
should == 'select "id", "name" from "rr_simple" order by "id"'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "TypeCastingCursor should work" do
|
|
66
|
+
session = Session.new
|
|
67
|
+
org_cursor = session.left.select_cursor(
|
|
68
|
+
:query => "select id, name from rr_simple where id = 1",
|
|
69
|
+
:type_cast => false
|
|
70
|
+
)
|
|
71
|
+
cursor = TypeCastingCursor.new session.left, 'rr_simple', org_cursor
|
|
72
|
+
|
|
73
|
+
row = cursor.next_row
|
|
74
|
+
|
|
75
|
+
row.should == {
|
|
76
|
+
'id' => 1,
|
|
77
|
+
'name' => 'bla'
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "sequence_values should pick the table in the target schema" do
|
|
82
|
+
session = Session.new
|
|
83
|
+
session.left.sequence_values('rx', 'rr_duplicate').keys.should == ["rr_duplicate_id_seq"]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "clear_sequence_setup should pick the table in the target schema" do
|
|
87
|
+
session = nil
|
|
88
|
+
begin
|
|
89
|
+
session = Session.new
|
|
90
|
+
initializer = ReplicationInitializer.new(session)
|
|
91
|
+
session.left.begin_db_transaction
|
|
92
|
+
session.right.begin_db_transaction
|
|
93
|
+
table_pair = {:left => 'rr_duplicate', :right => 'rr_duplicate'}
|
|
94
|
+
initializer.ensure_sequence_setup table_pair, 5, 2, 1
|
|
95
|
+
id1, id2 = get_example_sequence_values(session, 'rr_duplicate')
|
|
96
|
+
(id2 - id1).should == 5
|
|
97
|
+
(id1 % 5).should == 2
|
|
98
|
+
|
|
99
|
+
initializer.clear_sequence_setup :left, 'rr_duplicate'
|
|
100
|
+
id1, id2 = get_example_sequence_values(session, 'rr_duplicate')
|
|
101
|
+
(id2 - id1).should == 1
|
|
102
|
+
ensure
|
|
103
|
+
[:left, :right].each do |database|
|
|
104
|
+
initializer.clear_sequence_setup database, 'rr_duplicate' rescue nil if session
|
|
105
|
+
session.send(database).execute "delete from rr_duplicate" rescue nil if session
|
|
106
|
+
session.send(database).rollback_db_transaction rescue nil if session
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "sequence setup should work" do
|
|
113
|
+
session = nil
|
|
114
|
+
begin
|
|
115
|
+
session = Session.new
|
|
116
|
+
initializer = ReplicationInitializer.new(session)
|
|
117
|
+
session.left.begin_db_transaction
|
|
118
|
+
session.right.begin_db_transaction
|
|
119
|
+
table_pair = {:left => 'rr_sequence_test', :right => 'rr_sequence_test'}
|
|
120
|
+
initializer.ensure_sequence_setup table_pair, 5, 2, 1
|
|
121
|
+
id1, id2 = get_example_sequence_values(session, 'rr_sequence_test')
|
|
122
|
+
(id2 - id1).should == 5
|
|
123
|
+
(id1 % 5).should == 2
|
|
124
|
+
ensure
|
|
125
|
+
[:left, :right].each do |database|
|
|
126
|
+
initializer.clear_sequence_setup database, 'rr_sequence_test' rescue nil if session
|
|
127
|
+
session.send(database).execute "delete from rr_sequence_test" rescue nil if session
|
|
128
|
+
session.send(database).rollback_db_transaction rescue nil if session
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "clear_sequence_setup should work" do
|
|
134
|
+
session = nil
|
|
135
|
+
begin
|
|
136
|
+
session = Session.new
|
|
137
|
+
initializer = ReplicationInitializer.new(session)
|
|
138
|
+
session.left.begin_db_transaction
|
|
139
|
+
session.right.begin_db_transaction
|
|
140
|
+
table_pair = {:left => 'rr_sequence_test', :right => 'rr_sequence_test'}
|
|
141
|
+
initializer.ensure_sequence_setup table_pair, 5, 2, 2
|
|
142
|
+
initializer.clear_sequence_setup :left, 'rr_sequence_test'
|
|
143
|
+
id1, id2 = get_example_sequence_values(session, 'rr_sequence_test')
|
|
144
|
+
(id2 - id1).should == 1
|
|
145
|
+
ensure
|
|
146
|
+
[:left, :right].each do |database|
|
|
147
|
+
initializer.clear_sequence_setup database, 'rr_sequence_test' if session
|
|
148
|
+
session.send(database).execute "delete from rr_sequence_test" if session
|
|
149
|
+
session.send(database).rollback_db_transaction if session
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "initializer should create tables in target schema" do
|
|
155
|
+
session = nil
|
|
156
|
+
begin
|
|
157
|
+
config = deep_copy(Initializer.configuration)
|
|
158
|
+
config.options[:rep_prefix] = 'ry'
|
|
159
|
+
session = Session.new config
|
|
160
|
+
session.left.begin_db_transaction
|
|
161
|
+
|
|
162
|
+
initializer = ReplicationInitializer.new(session)
|
|
163
|
+
initializer.create_change_log(:left)
|
|
164
|
+
|
|
165
|
+
# no exception ==> means table was created in target schema
|
|
166
|
+
session.left.select_one("select id from rr.ry_pending_changes")
|
|
167
|
+
ensure
|
|
168
|
+
session.left.rollback_db_transaction if session
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "create_trigger, trigger_exists? and drop_trigger should work" do
|
|
173
|
+
session = nil
|
|
174
|
+
begin
|
|
175
|
+
session = Session.new
|
|
176
|
+
initializer = ReplicationInitializer.new(session)
|
|
177
|
+
session.left.begin_db_transaction
|
|
178
|
+
|
|
179
|
+
initializer.create_trigger :left, 'rr_trigger_test'
|
|
180
|
+
initializer.trigger_exists?(:left, 'rr_trigger_test').
|
|
181
|
+
should be_true
|
|
182
|
+
|
|
183
|
+
# Verify that the trigger can find the pending_changes table even if
|
|
184
|
+
# current search_path does not include it.
|
|
185
|
+
session.left.execute "set search_path = 'public'"
|
|
186
|
+
session.left.execute <<-EOF
|
|
187
|
+
insert into rr.rr_trigger_test(first_id, second_id) values(10, 11)
|
|
188
|
+
EOF
|
|
189
|
+
session.left.execute "set search_path = 'rr'"
|
|
190
|
+
session.left.select_one("select change_key from rx_pending_changes")['change_key'].
|
|
191
|
+
should == "first_id|10|second_id|11"
|
|
192
|
+
|
|
193
|
+
initializer.drop_trigger(:left, 'rr_trigger_test')
|
|
194
|
+
initializer.trigger_exists?(:left, 'rr_trigger_test').
|
|
195
|
+
should be_false
|
|
196
|
+
ensure
|
|
197
|
+
session.left.rollback_db_transaction if session
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it "should work with complex search paths" do
|
|
202
|
+
config = deep_copy(standard_config)
|
|
203
|
+
config.left[:schema_search_path] = 'public,rr'
|
|
204
|
+
config.right[:schema_search_path] = 'public,rr'
|
|
205
|
+
session = Session.new(config)
|
|
206
|
+
|
|
207
|
+
tables = session.left.tables
|
|
208
|
+
tables.include?('rr_simple').should be_true
|
|
209
|
+
tables.include?('scanner_records').should be_true
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
|
|
3
|
+
include RR
|
|
4
|
+
|
|
5
|
+
require File.dirname(__FILE__) + "/../config/test_config.rb"
|
|
6
|
+
|
|
7
|
+
describe "PostgreSQL support" do
|
|
8
|
+
before(:each) do
|
|
9
|
+
Initializer.configuration = standard_config
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
after(:each) do
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
if Initializer.configuration.left[:adapter] == 'postgresql'
|
|
16
|
+
|
|
17
|
+
it "should read & write microsecond times" do
|
|
18
|
+
session = nil
|
|
19
|
+
begin
|
|
20
|
+
session = Session.new
|
|
21
|
+
session.left.begin_db_transaction
|
|
22
|
+
session.left.insert_record('extender_type_check',
|
|
23
|
+
{'id' => 2, 'timestamp' => Time.local(2009, "feb", 16, 20, 48, 1, 543)}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
org_cursor = session.left.select_cursor(
|
|
27
|
+
:query => "select id, timestamp from extender_type_check where id = 2",
|
|
28
|
+
:type_cast => false
|
|
29
|
+
)
|
|
30
|
+
cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
|
|
31
|
+
|
|
32
|
+
row = cursor.next_row
|
|
33
|
+
row['timestamp'].usec.should == 543
|
|
34
|
+
cursor.clear
|
|
35
|
+
ensure
|
|
36
|
+
session.left.rollback_db_transaction if session
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should not round microsecond times to incorrect value" do
|
|
41
|
+
session = nil
|
|
42
|
+
begin
|
|
43
|
+
session = Session.new
|
|
44
|
+
session.left.begin_db_transaction
|
|
45
|
+
session.left.insert_record('extender_type_check',
|
|
46
|
+
{'id' => 2, 'timestamp' => Time.local(2009, "feb", 16, 13, 37, 11, 126291)}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
org_cursor = session.left.select_cursor(
|
|
50
|
+
:query => "select id, timestamp from extender_type_check where id = 2",
|
|
51
|
+
:type_cast => false
|
|
52
|
+
)
|
|
53
|
+
cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
|
|
54
|
+
|
|
55
|
+
row = cursor.next_row
|
|
56
|
+
row['timestamp'].usec.should == 126291
|
|
57
|
+
cursor.clear
|
|
58
|
+
ensure
|
|
59
|
+
session.left.rollback_db_transaction if session
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
|
|
3
|
+
include RR
|
|
4
|
+
include ScanProgressPrinters
|
|
5
|
+
|
|
6
|
+
describe ProgressBar do
|
|
7
|
+
before(:each) do
|
|
8
|
+
@org_stdout = $stdout
|
|
9
|
+
$stdout = StringIO.new
|
|
10
|
+
@old_arg = ProgressBar.arg
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after(:each) do
|
|
14
|
+
ProgressBar.arg = @old_arg
|
|
15
|
+
$stdout = @org_stdout
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "arg should store the command line argument and max_markers return the correct marker number" do
|
|
19
|
+
ProgressBar.arg = nil
|
|
20
|
+
ProgressBar.new(100, Session.new(standard_config), 'bla', 'blub').max_markers.should == ProgressBar::MAX_MARKERS
|
|
21
|
+
ProgressBar.arg = "2"
|
|
22
|
+
ProgressBar.new(100, Session.new(standard_config), 'bla', 'blub').max_markers.should == 2
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "step should use ANSI codes if options :use_ansi is set" do
|
|
26
|
+
session = Session.new(deep_copy(standard_config))
|
|
27
|
+
session.configuration.options[:use_ansi] = true
|
|
28
|
+
bar = ProgressBar.new(10, session, 'bla', 'blub')
|
|
29
|
+
bar.step 1
|
|
30
|
+
bar.step 1
|
|
31
|
+
$stdout.string.should =~ Regexp.new(Regexp.escape("\e[1"))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "step should not use ANSI codes if options :use_ansi is not true" do
|
|
35
|
+
session = Session.new(deep_copy(standard_config))
|
|
36
|
+
session.configuration.options[:use_ansi] = false
|
|
37
|
+
bar = ProgressBar.new(10, session, 'bla', 'blub')
|
|
38
|
+
bar.step 1
|
|
39
|
+
bar.step 1
|
|
40
|
+
$stdout.string.should_not =~ Regexp.new(Regexp.escape("\e[1"))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should register itself with ScanRunner" do
|
|
44
|
+
RR::ScanProgressPrinters.printers[:progress_bar][:printer_class].
|
|
45
|
+
should == ProgressBar
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "step should print the correct progress" do
|
|
49
|
+
bar = ProgressBar.new(1000, Session.new(standard_config), 'bla', 'blub')
|
|
50
|
+
bar.step 200
|
|
51
|
+
bar.step 300
|
|
52
|
+
$stdout.string.count('.').should == ProgressBar::MAX_MARKERS / 2
|
|
53
|
+
bar.step 500
|
|
54
|
+
$stdout.string.count('.').should == ProgressBar::MAX_MARKERS
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "step should work around weird floating point rounding issues" do
|
|
58
|
+
bar = ProgressBar.new(56, Session.new(standard_config), 'bla', 'blub')
|
|
59
|
+
(1..56).each {bar.step 1}
|
|
60
|
+
$stdout.string.count('.').should == ProgressBar::MAX_MARKERS
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "if max_steps is 0, any step call should go to 100% progress" do
|
|
64
|
+
config = deep_copy(standard_config)
|
|
65
|
+
config.options[:use_ansi] = true
|
|
66
|
+
bar = ProgressBar.new(0, Session.new(config), 'bla', 'blub')
|
|
67
|
+
bar.step
|
|
68
|
+
$stdout.string.count('.').should == ProgressBar::MAX_MARKERS
|
|
69
|
+
$stdout.string.should =~ /100%/
|
|
70
|
+
|
|
71
|
+
# Ensure we don't go over 100%
|
|
72
|
+
$stdout = StringIO.new
|
|
73
|
+
bar.step
|
|
74
|
+
$stdout.string.should == ''
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|