rubyrep 1.2.0 → 2.0.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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +84 -0
- data/History.txt +6 -0
- data/README.txt +1 -1
- data/Rakefile +6 -27
- data/bin/rubyrep +1 -1
- data/config/mysql_config.rb +2 -2
- data/config/postgres_config.rb +5 -3
- data/lib/rubyrep/command_runner.rb +1 -1
- data/lib/rubyrep/connection_extenders/connection_extenders.rb +30 -44
- data/lib/rubyrep/connection_extenders/mysql_extender.rb +23 -1
- data/lib/rubyrep/connection_extenders/postgresql_extender.rb +31 -168
- data/lib/rubyrep/generate_runner.rb +1 -1
- data/lib/rubyrep/logged_change.rb +1 -1
- data/lib/rubyrep/proxy_connection.rb +22 -12
- data/lib/rubyrep/replication_difference.rb +1 -1
- data/lib/rubyrep/replication_extenders/mysql_replication.rb +1 -1
- data/lib/rubyrep/replication_helper.rb +1 -1
- data/lib/rubyrep/replication_runner.rb +10 -0
- data/lib/rubyrep/scan_report_printers/scan_detail_reporter.rb +1 -1
- data/lib/rubyrep/table_spec_resolver.rb +1 -1
- data/lib/rubyrep/type_casting_cursor.rb +8 -4
- data/lib/rubyrep/version.rb +1 -7
- data/lib/rubyrep.rb +4 -3
- data/rubyrep +4 -0
- data/rubyrep.bat +5 -0
- data/rubyrep.gemspec +29 -0
- data/sims/performance/big_rep_spec.rb +34 -17
- data/sims/performance/performance.rake +11 -31
- data/tasks/database.rake +14 -14
- data/tasks/java.rake +18 -5
- data/tasks/rspec.rake +14 -34
- data/tasks/stats.rake +1 -16
- metadata +99 -162
- data/.gemtest +0 -0
- data/config/requirements.rb +0 -32
- data/lib/rubyrep/connection_extenders/jdbc_extender.rb +0 -65
- data/spec/base_runner_spec.rb +0 -218
- data/spec/buffered_committer_spec.rb +0 -274
- data/spec/command_runner_spec.rb +0 -145
- data/spec/committers_spec.rb +0 -178
- data/spec/configuration_spec.rb +0 -203
- data/spec/connection_extender_interface_spec.rb +0 -141
- data/spec/connection_extenders_registration_spec.rb +0 -164
- data/spec/database_proxy_spec.rb +0 -48
- data/spec/database_rake_spec.rb +0 -40
- data/spec/db_specific_connection_extenders_spec.rb +0 -34
- data/spec/db_specific_replication_extenders_spec.rb +0 -38
- data/spec/direct_table_scan_spec.rb +0 -61
- data/spec/dolphins.jpg +0 -0
- data/spec/generate_runner_spec.rb +0 -84
- data/spec/initializer_spec.rb +0 -46
- data/spec/log_helper_spec.rb +0 -39
- data/spec/logged_change_loader_spec.rb +0 -68
- data/spec/logged_change_spec.rb +0 -470
- data/spec/noisy_connection_spec.rb +0 -78
- data/spec/postgresql_replication_spec.rb +0 -48
- data/spec/postgresql_schema_support_spec.rb +0 -212
- data/spec/postgresql_support_spec.rb +0 -63
- data/spec/progress_bar_spec.rb +0 -77
- data/spec/proxied_table_scan_spec.rb +0 -151
- data/spec/proxy_block_cursor_spec.rb +0 -197
- data/spec/proxy_connection_spec.rb +0 -423
- data/spec/proxy_cursor_spec.rb +0 -56
- data/spec/proxy_row_cursor_spec.rb +0 -66
- data/spec/proxy_runner_spec.rb +0 -70
- data/spec/replication_difference_spec.rb +0 -161
- data/spec/replication_extender_interface_spec.rb +0 -367
- data/spec/replication_extenders_spec.rb +0 -32
- data/spec/replication_helper_spec.rb +0 -178
- data/spec/replication_initializer_spec.rb +0 -509
- data/spec/replication_run_spec.rb +0 -443
- data/spec/replication_runner_spec.rb +0 -254
- data/spec/replicators_spec.rb +0 -36
- data/spec/rubyrep_spec.rb +0 -8
- data/spec/scan_detail_reporter_spec.rb +0 -119
- data/spec/scan_progress_printers_spec.rb +0 -68
- data/spec/scan_report_printers_spec.rb +0 -67
- data/spec/scan_runner_spec.rb +0 -50
- data/spec/scan_summary_reporter_spec.rb +0 -61
- data/spec/session_spec.rb +0 -253
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -305
- data/spec/strange_name_support_spec.rb +0 -135
- data/spec/sync_helper_spec.rb +0 -169
- data/spec/sync_runner_spec.rb +0 -78
- data/spec/syncers_spec.rb +0 -171
- data/spec/table_scan_helper_spec.rb +0 -36
- data/spec/table_scan_spec.rb +0 -49
- data/spec/table_sorter_spec.rb +0 -30
- data/spec/table_spec_resolver_spec.rb +0 -111
- data/spec/table_sync_spec.rb +0 -140
- data/spec/task_sweeper_spec.rb +0 -47
- data/spec/trigger_mode_switcher_spec.rb +0 -83
- data/spec/two_way_replicator_spec.rb +0 -721
- data/spec/two_way_syncer_spec.rb +0 -256
- data/spec/type_casting_cursor_spec.rb +0 -50
- data/spec/uninstall_runner_spec.rb +0 -93
- data/tasks/rubyrep.tailor +0 -18
- data/tasks/website.rake +0 -19
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: dce60ecb06296f28c795f0e6f622f44cfb254f36
|
|
4
|
+
data.tar.gz: d93b227992e944a55bd0dc465c58e63189fca282
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0c1617bceecfff4c4337f054db6e34d93a6fc403f10fa4164cd4e66bd6ebf2a1fbf057514dad0c7437dd14b589d0afe9cea745568e8b8e150ed2a86bee642786
|
|
7
|
+
data.tar.gz: 359351384c8600b69c16dddb46434bf43f2b3f2a82f1c6c6d554b38fd4fea3fce9a0d36cd50961b245d24d5ca2a6ed19f70615819e7ad244b96d88437fb50692
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
source 'http://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gem 'activerecord', '~> 4.2'
|
|
4
|
+
|
|
5
|
+
gem 'pg', platform: :ruby
|
|
6
|
+
gem 'mysql2', platform: :ruby
|
|
7
|
+
|
|
8
|
+
gem 'jdbc-postgres', platform: :jruby
|
|
9
|
+
gem 'jdbc-mysql', platform: :jruby
|
|
10
|
+
gem 'activerecord-jdbc-adapter', platform: :jruby
|
|
11
|
+
gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby
|
|
12
|
+
gem 'activerecord-jdbcmysql-adapter', platform: :jruby
|
|
13
|
+
|
|
14
|
+
gem 'rspec'
|
|
15
|
+
gem 'crack'
|
|
16
|
+
gem 'awesome_print', require: 'ap'
|
|
17
|
+
gem 'rake'
|
|
18
|
+
gem 'simplecov', :require => false, :group => :test
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
activemodel (4.2.8)
|
|
5
|
+
activesupport (= 4.2.8)
|
|
6
|
+
builder (~> 3.1)
|
|
7
|
+
activerecord (4.2.8)
|
|
8
|
+
activemodel (= 4.2.8)
|
|
9
|
+
activesupport (= 4.2.8)
|
|
10
|
+
arel (~> 6.0)
|
|
11
|
+
activerecord-jdbc-adapter (1.3.23)
|
|
12
|
+
activerecord (>= 2.2, < 5.0)
|
|
13
|
+
activerecord-jdbcmysql-adapter (1.3.23)
|
|
14
|
+
activerecord-jdbc-adapter (~> 1.3.23)
|
|
15
|
+
jdbc-mysql (>= 5.1.22)
|
|
16
|
+
activerecord-jdbcpostgresql-adapter (1.3.23)
|
|
17
|
+
activerecord-jdbc-adapter (~> 1.3.23)
|
|
18
|
+
jdbc-postgres (>= 9.1)
|
|
19
|
+
activesupport (4.2.8)
|
|
20
|
+
i18n (~> 0.7)
|
|
21
|
+
minitest (~> 5.1)
|
|
22
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
|
23
|
+
tzinfo (~> 1.1)
|
|
24
|
+
arel (6.0.4)
|
|
25
|
+
awesome_print (1.7.0)
|
|
26
|
+
builder (3.2.3)
|
|
27
|
+
crack (0.4.3)
|
|
28
|
+
safe_yaml (~> 1.0.0)
|
|
29
|
+
diff-lcs (1.3)
|
|
30
|
+
docile (1.1.5)
|
|
31
|
+
i18n (0.8.1)
|
|
32
|
+
jdbc-mysql (5.1.42)
|
|
33
|
+
jdbc-postgres (9.4.1206)
|
|
34
|
+
json (2.0.2)
|
|
35
|
+
json (2.0.2-java)
|
|
36
|
+
minitest (5.10.2)
|
|
37
|
+
mysql2 (0.4.6)
|
|
38
|
+
pg (0.20.0)
|
|
39
|
+
rake (12.0.0)
|
|
40
|
+
rspec (3.5.0)
|
|
41
|
+
rspec-core (~> 3.5.0)
|
|
42
|
+
rspec-expectations (~> 3.5.0)
|
|
43
|
+
rspec-mocks (~> 3.5.0)
|
|
44
|
+
rspec-core (3.5.4)
|
|
45
|
+
rspec-support (~> 3.5.0)
|
|
46
|
+
rspec-expectations (3.5.0)
|
|
47
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
48
|
+
rspec-support (~> 3.5.0)
|
|
49
|
+
rspec-mocks (3.5.0)
|
|
50
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
51
|
+
rspec-support (~> 3.5.0)
|
|
52
|
+
rspec-support (3.5.0)
|
|
53
|
+
safe_yaml (1.0.4)
|
|
54
|
+
simplecov (0.14.1)
|
|
55
|
+
docile (~> 1.1.0)
|
|
56
|
+
json (>= 1.8, < 3)
|
|
57
|
+
simplecov-html (~> 0.10.0)
|
|
58
|
+
simplecov-html (0.10.1)
|
|
59
|
+
thread_safe (0.3.6)
|
|
60
|
+
thread_safe (0.3.6-java)
|
|
61
|
+
tzinfo (1.2.3)
|
|
62
|
+
thread_safe (~> 0.1)
|
|
63
|
+
|
|
64
|
+
PLATFORMS
|
|
65
|
+
java
|
|
66
|
+
ruby
|
|
67
|
+
|
|
68
|
+
DEPENDENCIES
|
|
69
|
+
activerecord (~> 4.2)
|
|
70
|
+
activerecord-jdbc-adapter
|
|
71
|
+
activerecord-jdbcmysql-adapter
|
|
72
|
+
activerecord-jdbcpostgresql-adapter
|
|
73
|
+
awesome_print
|
|
74
|
+
crack
|
|
75
|
+
jdbc-mysql
|
|
76
|
+
jdbc-postgres
|
|
77
|
+
mysql2
|
|
78
|
+
pg
|
|
79
|
+
rake
|
|
80
|
+
rspec
|
|
81
|
+
simplecov
|
|
82
|
+
|
|
83
|
+
BUNDLED WITH
|
|
84
|
+
1.14.6
|
data/History.txt
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
== 2.0.0 2017-06-01
|
|
2
|
+
|
|
3
|
+
* Feature: compatibility with Rails 4, Ruby 2.4 and JRuby 9.1
|
|
4
|
+
* Breaking: specify MySQL support in database config with adapter 'mysql2' instead of 'mysql'
|
|
5
|
+
* Breaking: postgres table names must not contains dots (".") anymore
|
|
6
|
+
|
|
1
7
|
== 1.2.0 2011-03-07
|
|
2
8
|
|
|
3
9
|
* Feature: compatibility with Rails 3
|
data/README.txt
CHANGED
|
@@ -15,7 +15,7 @@ Refer to the project website at http://www.rubyrep.org
|
|
|
15
15
|
|
|
16
16
|
(The MIT License)
|
|
17
17
|
|
|
18
|
-
Copyright (c)
|
|
18
|
+
Copyright (c) 2017 Arndt Lehmann
|
|
19
19
|
|
|
20
20
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
21
21
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
|
@@ -1,30 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
require
|
|
1
|
+
namespace :bundler do
|
|
2
|
+
require "bundler/gem_tasks"
|
|
3
|
+
end
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
require_relative 'lib/rubyrep'
|
|
6
|
+
require_relative 'tasks/task_helper'
|
|
6
7
|
|
|
7
8
|
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
|
8
|
-
load 'sims/performance/performance.rake'
|
|
9
|
-
|
|
10
|
-
desc "Creates the repository commit statistics"
|
|
11
|
-
task :repostats do
|
|
12
|
-
# phase 0: create the repository tmp directory
|
|
13
|
-
system 'mkdir -p tmp'
|
|
14
|
-
# phase 1: migrate the hg repository to svn
|
|
15
|
-
tailor_path = '~/usr/tailor/tailor'
|
|
16
|
-
cmd = "#{tailor_path} --use-propset --configfile '#{File.dirname(__FILE__) + '/tasks/rubyrep.tailor'}'"
|
|
17
|
-
system cmd
|
|
18
|
-
|
|
19
|
-
# phase 2: create the repository statistics through the statsvn library
|
|
20
|
-
jar_path = '~/usr/statsvn/statsvn.jar'
|
|
21
|
-
log_path = File.dirname(__FILE__) + '/tmp/statsvn.log'
|
|
22
|
-
checkout_path = '/tmp/rubyrep_tailor/svn'
|
|
23
|
-
svnstats_dir = File.dirname(__FILE__) + '/statsvn'
|
|
24
|
-
|
|
25
|
-
system "cd #{checkout_path}; svn update"
|
|
26
|
-
cmd = "cd #{checkout_path}; svn log -v --xml >#{log_path}"
|
|
27
|
-
system cmd
|
|
28
|
-
cmd = "java -jar #{jar_path} -output-dir #{svnstats_dir} -exclude 'setup.rb:website/**' #{log_path} #{checkout_path}"
|
|
29
|
-
system cmd
|
|
30
|
-
end
|
|
9
|
+
load 'sims/performance/performance.rake'
|
data/bin/rubyrep
CHANGED
data/config/mysql_config.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
RR::Initializer::run do |config|
|
|
5
5
|
config.left = {
|
|
6
|
-
:adapter => '
|
|
6
|
+
:adapter => 'mysql2',
|
|
7
7
|
:database => 'rr_left',
|
|
8
8
|
:username => 'root',
|
|
9
9
|
:password => '',
|
|
@@ -13,7 +13,7 @@ RR::Initializer::run do |config|
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
config.right = {
|
|
16
|
-
:adapter => '
|
|
16
|
+
:adapter => 'mysql2',
|
|
17
17
|
:database => 'rr_right',
|
|
18
18
|
:username => 'root',
|
|
19
19
|
:password => '',
|
data/config/postgres_config.rb
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
RR::Initializer::run do |config|
|
|
5
5
|
config.left = {
|
|
6
6
|
:adapter => 'postgresql',
|
|
7
|
-
:database => 'rr_left',
|
|
7
|
+
:database => 'rr_left',
|
|
8
8
|
:username => 'postgres',
|
|
9
9
|
:password => 'password',
|
|
10
|
-
:host => 'localhost'
|
|
10
|
+
:host => 'localhost',
|
|
11
|
+
:min_messages => 'warning'
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
config.right = {
|
|
@@ -15,7 +16,8 @@ RR::Initializer::run do |config|
|
|
|
15
16
|
:database => 'rr_right',
|
|
16
17
|
:username => 'postgres',
|
|
17
18
|
:password => 'password',
|
|
18
|
-
:host => 'localhost'
|
|
19
|
+
:host => 'localhost',
|
|
20
|
+
:min_messages => 'warning'
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
end
|
|
@@ -3,19 +3,6 @@ class ActiveRecord::ConnectionAdapters::AbstractAdapter
|
|
|
3
3
|
attr_accessor :log_subscriber
|
|
4
4
|
end
|
|
5
5
|
|
|
6
|
-
class ActiveRecord::ConnectionAdapters::Column
|
|
7
|
-
# Bug in ActiveRecord parsing of PostgreSQL timestamps with microseconds:
|
|
8
|
-
# Certain values are incorrectly rounded, thus ending up with timestamps
|
|
9
|
-
# that are off by one microsecond.
|
|
10
|
-
# This monkey patch fixes the problem.
|
|
11
|
-
def self.fast_string_to_time(string)
|
|
12
|
-
if string =~ Format::ISO_DATETIME
|
|
13
|
-
microsec = ($7.to_f * 1_000_000).round # used to be #to_i instead
|
|
14
|
-
new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
6
|
module RR
|
|
20
7
|
|
|
21
8
|
# Connection extenders provide additional database specific functionality
|
|
@@ -39,10 +26,18 @@ module RR
|
|
|
39
26
|
@extenders.merge! extender
|
|
40
27
|
end
|
|
41
28
|
|
|
42
|
-
#
|
|
43
|
-
|
|
29
|
+
# Creates a new ActiveRecord::Base descending class that can be used to create and manage
|
|
30
|
+
# database connections.
|
|
31
|
+
#
|
|
32
|
+
# @return [Class] the new ActiveRecord::Base descending class
|
|
33
|
+
def self.active_record_class_for_database_connection
|
|
34
|
+
active_record_class = Class.new(ActiveRecord::Base)
|
|
35
|
+
@active_record_class_counter ||= 0
|
|
36
|
+
@active_record_class_counter += 1
|
|
37
|
+
RR.const_set("DummyActiveRecord#{@active_record_class_counter}", active_record_class)
|
|
38
|
+
active_record_class
|
|
44
39
|
end
|
|
45
|
-
|
|
40
|
+
|
|
46
41
|
# Creates an ActiveRecord database connection according to the provided +config+ connection hash.
|
|
47
42
|
# Possible values of this parameter are described in ActiveRecord::Base#establish_connection.
|
|
48
43
|
# The database connection is extended with the correct ConnectionExtenders module.
|
|
@@ -52,38 +47,29 @@ module RR
|
|
|
52
47
|
# To go around this, we delete ActiveRecord's memory of the existing database connection
|
|
53
48
|
# as soon as it is created.
|
|
54
49
|
def self.db_connect_without_cache(config)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# of the Adapters. E. g. instead of "postgresql", "jdbcpostgresql".
|
|
60
|
-
adapter = 'jdbc' + adapter unless adapter =~ /^jdbc/
|
|
50
|
+
# active_record_class = active_record_class_for_connection(config)
|
|
51
|
+
# active_record_class = DummyActiveRecord.dup
|
|
52
|
+
active_record_class = active_record_class_for_database_connection
|
|
53
|
+
active_record_class.establish_connection(config)
|
|
61
54
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
|
|
56
|
+
# To suppress Postgres debug messages (which cannot be suppress in another way),
|
|
57
|
+
# temporarily replace stdout.
|
|
58
|
+
org_stdout = $stdout
|
|
59
|
+
$stdout = StringIO.new
|
|
60
|
+
begin
|
|
61
|
+
connection = active_record_class.connection
|
|
62
|
+
ensure
|
|
63
|
+
puts $stdout.string
|
|
64
|
+
$stdout = org_stdout
|
|
65
65
|
end
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
# Delete the database connection from ActiveRecords's 'memory'
|
|
69
|
-
ActiveRecord::Base.connection_handler.connection_pools.delete DummyActiveRecord.name
|
|
70
|
-
|
|
71
|
-
extender = ""
|
|
72
|
-
if RUBY_PLATFORM =~ /java/
|
|
73
|
-
extender = :jdbc
|
|
74
|
-
elsif ConnectionExtenders.extenders.include? config[:adapter].to_sym
|
|
66
|
+
|
|
67
|
+
if ConnectionExtenders.extenders.include? config[:adapter].to_sym
|
|
75
68
|
extender = config[:adapter].to_sym
|
|
76
69
|
else
|
|
77
70
|
raise "No ConnectionExtender available for :#{config[:adapter]}"
|
|
78
71
|
end
|
|
79
72
|
connection.extend ConnectionExtenders.extenders[extender]
|
|
80
|
-
|
|
81
|
-
# Hack to get Postgres schema support under JRuby to par with the standard
|
|
82
|
-
# ruby version
|
|
83
|
-
if RUBY_PLATFORM =~ /java/ and config[:adapter].to_sym == :postgresql
|
|
84
|
-
connection.extend RR::ConnectionExtenders::PostgreSQLExtender
|
|
85
|
-
connection.initialize_search_path
|
|
86
|
-
end
|
|
87
73
|
|
|
88
74
|
replication_module = ReplicationExtenders.extenders[config[:adapter].to_sym]
|
|
89
75
|
connection.extend replication_module if replication_module
|
|
@@ -112,14 +98,15 @@ module RR
|
|
|
112
98
|
if config[:logger].respond_to?(:debug)
|
|
113
99
|
logger = config[:logger]
|
|
114
100
|
else
|
|
115
|
-
logger = ActiveSupport::
|
|
101
|
+
logger = ActiveSupport::Logger.new(config[:logger])
|
|
116
102
|
end
|
|
117
103
|
db_connection.instance_variable_set :@logger, logger
|
|
118
104
|
if ActiveSupport.const_defined?(:Notifications)
|
|
119
105
|
connection_object_id = db_connection.object_id
|
|
120
106
|
db_connection.log_subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |name, start, finish, id, payload|
|
|
121
107
|
if payload[:connection_id] == connection_object_id and logger.debug?
|
|
122
|
-
|
|
108
|
+
sql = payload[:sql].squeeze(" ") rescue payload[:sql]
|
|
109
|
+
logger.debug sql
|
|
123
110
|
end
|
|
124
111
|
end
|
|
125
112
|
end
|
|
@@ -146,7 +133,6 @@ module RR
|
|
|
146
133
|
end
|
|
147
134
|
|
|
148
135
|
install_logger db_connection, config
|
|
149
|
-
|
|
150
136
|
db_connection
|
|
151
137
|
end
|
|
152
138
|
|
|
@@ -4,7 +4,7 @@ module RR
|
|
|
4
4
|
|
|
5
5
|
# Provides various MySQL specific functionality required by Rubyrep.
|
|
6
6
|
module MysqlExtender
|
|
7
|
-
RR::ConnectionExtenders.register :
|
|
7
|
+
RR::ConnectionExtenders.register :mysql2 => self
|
|
8
8
|
|
|
9
9
|
# Returns an ordered list of primary key column names of the given table
|
|
10
10
|
def primary_key_names(table)
|
|
@@ -54,6 +54,28 @@ module RR
|
|
|
54
54
|
end
|
|
55
55
|
result
|
|
56
56
|
end
|
|
57
|
+
|
|
58
|
+
# Quotes the value so it can be used in SQL insert / update statements.
|
|
59
|
+
#
|
|
60
|
+
# @param [Object] value the target value
|
|
61
|
+
# @param [ActiveRecord::ConnectionAdapters::MySQL::Column] column the target column
|
|
62
|
+
# @return [String] the quoted string
|
|
63
|
+
def column_aware_quote(value, column)
|
|
64
|
+
if column.sql_type == 'blob' and RUBY_PLATFORM == 'java'
|
|
65
|
+
quote(column.type_cast_for_database(value))
|
|
66
|
+
else
|
|
67
|
+
quote(value)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Casts a value returned from the database back into the according ruby type.
|
|
72
|
+
#
|
|
73
|
+
# @param [Object] value the received value
|
|
74
|
+
# @param [ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::Column] column the originating column
|
|
75
|
+
# @return [Object] the casted value
|
|
76
|
+
def fixed_type_cast(value, column)
|
|
77
|
+
column.type_cast_from_database value
|
|
78
|
+
end
|
|
57
79
|
end
|
|
58
80
|
end
|
|
59
81
|
end
|
|
@@ -1,83 +1,5 @@
|
|
|
1
1
|
require 'time'
|
|
2
2
|
|
|
3
|
-
# Hack:
|
|
4
|
-
# For some reasons these methods were removed in Rails 2.2.2, thus breaking
|
|
5
|
-
# the binary and multi-lingual data loading.
|
|
6
|
-
# So here they are again.
|
|
7
|
-
module ActiveRecord
|
|
8
|
-
module ConnectionAdapters
|
|
9
|
-
# PostgreSQL-specific extensions to column definitions in a table.
|
|
10
|
-
class PostgreSQLColumn < Column #:nodoc:
|
|
11
|
-
|
|
12
|
-
# Escapes binary strings for bytea input to the database.
|
|
13
|
-
def self.string_to_binary(value)
|
|
14
|
-
if PGconn.respond_to?(:escape_bytea)
|
|
15
|
-
self.class.module_eval do
|
|
16
|
-
define_method(:string_to_binary) do |value|
|
|
17
|
-
PGconn.escape_bytea(value) if value
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
else
|
|
21
|
-
self.class.module_eval do
|
|
22
|
-
define_method(:string_to_binary) do |value|
|
|
23
|
-
if value
|
|
24
|
-
result = ''
|
|
25
|
-
value.each_byte { |c| result << sprintf('\\\\%03o', c) }
|
|
26
|
-
result
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
self.class.string_to_binary(value)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Unescapes bytea output from a database to the binary string it represents.
|
|
35
|
-
def self.binary_to_string(value)
|
|
36
|
-
# In each case, check if the value actually is escaped PostgreSQL bytea output
|
|
37
|
-
# or an unescaped Active Record attribute that was just written.
|
|
38
|
-
if PGconn.respond_to?(:unescape_bytea)
|
|
39
|
-
self.class.module_eval do
|
|
40
|
-
define_method(:binary_to_string) do |value|
|
|
41
|
-
if value =~ /\\\d{3}/
|
|
42
|
-
PGconn.unescape_bytea(value)
|
|
43
|
-
else
|
|
44
|
-
value
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
else
|
|
49
|
-
self.class.module_eval do
|
|
50
|
-
define_method(:binary_to_string) do |value|
|
|
51
|
-
if value =~ /\\\d{3}/
|
|
52
|
-
result = ''
|
|
53
|
-
i, max = 0, value.size
|
|
54
|
-
while i < max
|
|
55
|
-
char = value[i]
|
|
56
|
-
if char == ?\\
|
|
57
|
-
if value[i+1] == ?\\
|
|
58
|
-
char = ?\\
|
|
59
|
-
i += 1
|
|
60
|
-
else
|
|
61
|
-
char = value[i+1..i+3].oct
|
|
62
|
-
i += 3
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
result << char
|
|
66
|
-
i += 1
|
|
67
|
-
end
|
|
68
|
-
result
|
|
69
|
-
else
|
|
70
|
-
value
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
self.class.binary_to_string(value)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
3
|
module RR
|
|
82
4
|
module ConnectionExtenders
|
|
83
5
|
|
|
@@ -107,15 +29,6 @@ module RR
|
|
|
107
29
|
SQL
|
|
108
30
|
end
|
|
109
31
|
|
|
110
|
-
# Disables schema extraction from table names by overwriting the according
|
|
111
|
-
# ActiveRecord method.
|
|
112
|
-
# Necessary to support table names containing dots (".").
|
|
113
|
-
# (This is possible as rubyrep exclusively uses the search_path setting to
|
|
114
|
-
# support PostgreSQL schemas.)
|
|
115
|
-
def extract_pg_identifier_from_name(name)
|
|
116
|
-
return name, nil
|
|
117
|
-
end
|
|
118
|
-
|
|
119
32
|
# Returns an ordered list of primary key column names of the given table
|
|
120
33
|
def primary_key_names(table)
|
|
121
34
|
row = self.select_one(<<-end_sql)
|
|
@@ -138,7 +51,11 @@ module RR
|
|
|
138
51
|
|
|
139
52
|
# Change a Postgres Array of attribute numbers
|
|
140
53
|
# (returned in String form, e. g.: "{1,2}") into an array of Integers
|
|
141
|
-
|
|
54
|
+
if column_parray.kind_of?(Array)
|
|
55
|
+
column_ids = column_parray # in JRuby the attribute numbers are already returned as array
|
|
56
|
+
else
|
|
57
|
+
column_ids = column_parray.sub(/^\{(.*)\}$/,'\1').split(',').map {|a| a.to_i}
|
|
58
|
+
end
|
|
142
59
|
|
|
143
60
|
columns = {}
|
|
144
61
|
rows = self.select_all(<<-end_sql)
|
|
@@ -186,89 +103,35 @@ module RR
|
|
|
186
103
|
result
|
|
187
104
|
end
|
|
188
105
|
|
|
189
|
-
#
|
|
190
|
-
|
|
191
|
-
|
|
106
|
+
# Quotes the value so it can be used in SQL insert / update statements.
|
|
107
|
+
#
|
|
108
|
+
# @param [Object] value the target value
|
|
109
|
+
# @param [ActiveRecord::ConnectionAdapters::PostgreSQLColumn] column the target column
|
|
110
|
+
# @return [String] the quoted string
|
|
111
|
+
def column_aware_quote(value, column)
|
|
112
|
+
if column.try(:sql_type) == 'bytea'
|
|
113
|
+
quoted_value = "'#{escape_bytea value}'"
|
|
114
|
+
# tests showed that there is a wrong leading double backslash under JRuby
|
|
115
|
+
quoted_value.sub!(/\\\\/, '\\')
|
|
116
|
+
quoted_value
|
|
117
|
+
else
|
|
118
|
+
quote value
|
|
119
|
+
end
|
|
192
120
|
end
|
|
193
121
|
|
|
194
|
-
#
|
|
195
|
-
#
|
|
196
|
-
#
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
["TABLE","VIEW","SYNONYM"].to_java(:string)
|
|
207
|
-
)
|
|
208
|
-
table_exists = table_results.next
|
|
209
|
-
table_results.close
|
|
210
|
-
raise "table '#{table_name}' not found" unless table_exists
|
|
211
|
-
|
|
212
|
-
# get ResultSet for columns of table
|
|
213
|
-
column_results = jdbc_connection.meta_data.get_columns(
|
|
214
|
-
jdbc_connection.catalog,
|
|
215
|
-
@unquoted_schema,
|
|
216
|
-
table_name,
|
|
217
|
-
nil
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
# create the Column objects
|
|
221
|
-
columns = []
|
|
222
|
-
while column_results.next
|
|
223
|
-
|
|
224
|
-
# generate type clause
|
|
225
|
-
type_clause = column_results.get_string('TYPE_NAME')
|
|
226
|
-
precision = column_results.get_int('COLUMN_SIZE')
|
|
227
|
-
scale = column_results.get_int('DECIMAL_DIGITS')
|
|
228
|
-
if precision > 0
|
|
229
|
-
type_clause += "(#{precision}#{scale > 0 ? ",#{scale}" : ""})"
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
# create column
|
|
233
|
-
columns << ::ActiveRecord::ConnectionAdapters::JdbcColumn.new(
|
|
234
|
-
@config,
|
|
235
|
-
column_results.get_string('COLUMN_NAME'),
|
|
236
|
-
column_results.get_string('COLUMN_DEF'),
|
|
237
|
-
type_clause,
|
|
238
|
-
column_results.get_string('IS_NULLABLE').strip == "NO"
|
|
239
|
-
)
|
|
122
|
+
# Casts a value returned from the database back into the according ruby type.
|
|
123
|
+
#
|
|
124
|
+
# @param [Object] value the received value
|
|
125
|
+
# @param [ActiveRecord::ConnectionAdapters::PostgreSQLColumn] column the originating column
|
|
126
|
+
# @return [Object] the casted value
|
|
127
|
+
def fixed_type_cast(value, column)
|
|
128
|
+
if column.sql_type == 'bytea' and RUBY_PLATFORM == 'java'
|
|
129
|
+
# Apparently in Java / JRuby binary data are automatically unescaped.
|
|
130
|
+
# So #type_cast_from_database must be prevented from double-unescaping the binary data.
|
|
131
|
+
value
|
|
132
|
+
else
|
|
133
|
+
column.type_cast_from_database value
|
|
240
134
|
end
|
|
241
|
-
column_results.close
|
|
242
|
-
|
|
243
|
-
columns
|
|
244
|
-
end if RUBY_PLATFORM =~ /java/
|
|
245
|
-
|
|
246
|
-
# *** Monkey patch***
|
|
247
|
-
# Returns the list of a table's column names, data types, and default values.
|
|
248
|
-
# This overwrites the according ActiveRecord::PostgreSQLAdapter method
|
|
249
|
-
# to
|
|
250
|
-
# * work with tables containing a dot (".") and
|
|
251
|
-
# * only look for tables in the current schema search path.
|
|
252
|
-
def column_definitions(table_name) #:nodoc:
|
|
253
|
-
rows = self.select_all <<-end_sql
|
|
254
|
-
SELECT
|
|
255
|
-
a.attname as name,
|
|
256
|
-
format_type(a.atttypid, a.atttypmod) as type,
|
|
257
|
-
d.adsrc as source,
|
|
258
|
-
a.attnotnull as notnull
|
|
259
|
-
FROM pg_attribute a LEFT JOIN pg_attrdef d
|
|
260
|
-
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
|
261
|
-
WHERE a.attrelid = (
|
|
262
|
-
SELECT oid FROM pg_class
|
|
263
|
-
WHERE relname = '#{table_name}' AND relnamespace IN
|
|
264
|
-
(SELECT oid FROM pg_namespace WHERE nspname in (#{schemas}))
|
|
265
|
-
LIMIT 1
|
|
266
|
-
)
|
|
267
|
-
AND a.attnum > 0 AND NOT a.attisdropped
|
|
268
|
-
ORDER BY a.attnum
|
|
269
|
-
end_sql
|
|
270
|
-
|
|
271
|
-
rows.map {|row| [row['name'], row['type'], row['source'], row['notnull']]}
|
|
272
135
|
end
|
|
273
136
|
|
|
274
137
|
end
|
|
@@ -153,7 +153,7 @@ module RR
|
|
|
153
153
|
|
|
154
154
|
# Prevents session from going into YAML output
|
|
155
155
|
def to_yaml_properties
|
|
156
|
-
instance_variables.sort.reject {|var_name| ['@session', '@loader'].include? var_name}
|
|
156
|
+
instance_variables.sort.reject {|var_name| [:'@session', :'@loader'].include? var_name}
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
end
|