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.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +18 -0
  5. data/Gemfile.lock +84 -0
  6. data/History.txt +6 -0
  7. data/README.txt +1 -1
  8. data/Rakefile +6 -27
  9. data/bin/rubyrep +1 -1
  10. data/config/mysql_config.rb +2 -2
  11. data/config/postgres_config.rb +5 -3
  12. data/lib/rubyrep/command_runner.rb +1 -1
  13. data/lib/rubyrep/connection_extenders/connection_extenders.rb +30 -44
  14. data/lib/rubyrep/connection_extenders/mysql_extender.rb +23 -1
  15. data/lib/rubyrep/connection_extenders/postgresql_extender.rb +31 -168
  16. data/lib/rubyrep/generate_runner.rb +1 -1
  17. data/lib/rubyrep/logged_change.rb +1 -1
  18. data/lib/rubyrep/proxy_connection.rb +22 -12
  19. data/lib/rubyrep/replication_difference.rb +1 -1
  20. data/lib/rubyrep/replication_extenders/mysql_replication.rb +1 -1
  21. data/lib/rubyrep/replication_helper.rb +1 -1
  22. data/lib/rubyrep/replication_runner.rb +10 -0
  23. data/lib/rubyrep/scan_report_printers/scan_detail_reporter.rb +1 -1
  24. data/lib/rubyrep/table_spec_resolver.rb +1 -1
  25. data/lib/rubyrep/type_casting_cursor.rb +8 -4
  26. data/lib/rubyrep/version.rb +1 -7
  27. data/lib/rubyrep.rb +4 -3
  28. data/rubyrep +4 -0
  29. data/rubyrep.bat +5 -0
  30. data/rubyrep.gemspec +29 -0
  31. data/sims/performance/big_rep_spec.rb +34 -17
  32. data/sims/performance/performance.rake +11 -31
  33. data/tasks/database.rake +14 -14
  34. data/tasks/java.rake +18 -5
  35. data/tasks/rspec.rake +14 -34
  36. data/tasks/stats.rake +1 -16
  37. metadata +99 -162
  38. data/.gemtest +0 -0
  39. data/config/requirements.rb +0 -32
  40. data/lib/rubyrep/connection_extenders/jdbc_extender.rb +0 -65
  41. data/spec/base_runner_spec.rb +0 -218
  42. data/spec/buffered_committer_spec.rb +0 -274
  43. data/spec/command_runner_spec.rb +0 -145
  44. data/spec/committers_spec.rb +0 -178
  45. data/spec/configuration_spec.rb +0 -203
  46. data/spec/connection_extender_interface_spec.rb +0 -141
  47. data/spec/connection_extenders_registration_spec.rb +0 -164
  48. data/spec/database_proxy_spec.rb +0 -48
  49. data/spec/database_rake_spec.rb +0 -40
  50. data/spec/db_specific_connection_extenders_spec.rb +0 -34
  51. data/spec/db_specific_replication_extenders_spec.rb +0 -38
  52. data/spec/direct_table_scan_spec.rb +0 -61
  53. data/spec/dolphins.jpg +0 -0
  54. data/spec/generate_runner_spec.rb +0 -84
  55. data/spec/initializer_spec.rb +0 -46
  56. data/spec/log_helper_spec.rb +0 -39
  57. data/spec/logged_change_loader_spec.rb +0 -68
  58. data/spec/logged_change_spec.rb +0 -470
  59. data/spec/noisy_connection_spec.rb +0 -78
  60. data/spec/postgresql_replication_spec.rb +0 -48
  61. data/spec/postgresql_schema_support_spec.rb +0 -212
  62. data/spec/postgresql_support_spec.rb +0 -63
  63. data/spec/progress_bar_spec.rb +0 -77
  64. data/spec/proxied_table_scan_spec.rb +0 -151
  65. data/spec/proxy_block_cursor_spec.rb +0 -197
  66. data/spec/proxy_connection_spec.rb +0 -423
  67. data/spec/proxy_cursor_spec.rb +0 -56
  68. data/spec/proxy_row_cursor_spec.rb +0 -66
  69. data/spec/proxy_runner_spec.rb +0 -70
  70. data/spec/replication_difference_spec.rb +0 -161
  71. data/spec/replication_extender_interface_spec.rb +0 -367
  72. data/spec/replication_extenders_spec.rb +0 -32
  73. data/spec/replication_helper_spec.rb +0 -178
  74. data/spec/replication_initializer_spec.rb +0 -509
  75. data/spec/replication_run_spec.rb +0 -443
  76. data/spec/replication_runner_spec.rb +0 -254
  77. data/spec/replicators_spec.rb +0 -36
  78. data/spec/rubyrep_spec.rb +0 -8
  79. data/spec/scan_detail_reporter_spec.rb +0 -119
  80. data/spec/scan_progress_printers_spec.rb +0 -68
  81. data/spec/scan_report_printers_spec.rb +0 -67
  82. data/spec/scan_runner_spec.rb +0 -50
  83. data/spec/scan_summary_reporter_spec.rb +0 -61
  84. data/spec/session_spec.rb +0 -253
  85. data/spec/spec.opts +0 -1
  86. data/spec/spec_helper.rb +0 -305
  87. data/spec/strange_name_support_spec.rb +0 -135
  88. data/spec/sync_helper_spec.rb +0 -169
  89. data/spec/sync_runner_spec.rb +0 -78
  90. data/spec/syncers_spec.rb +0 -171
  91. data/spec/table_scan_helper_spec.rb +0 -36
  92. data/spec/table_scan_spec.rb +0 -49
  93. data/spec/table_sorter_spec.rb +0 -30
  94. data/spec/table_spec_resolver_spec.rb +0 -111
  95. data/spec/table_sync_spec.rb +0 -140
  96. data/spec/task_sweeper_spec.rb +0 -47
  97. data/spec/trigger_mode_switcher_spec.rb +0 -83
  98. data/spec/two_way_replicator_spec.rb +0 -721
  99. data/spec/two_way_syncer_spec.rb +0 -256
  100. data/spec/type_casting_cursor_spec.rb +0 -50
  101. data/spec/uninstall_runner_spec.rb +0 -93
  102. data/tasks/rubyrep.tailor +0 -18
  103. 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
@@ -0,0 +1,7 @@
1
+ statsvn/*
2
+ coverage/*
3
+ profile/*
4
+ doc/*
5
+ website/.*\.html$
6
+ pkg/*
7
+ tmp/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
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) 2009 Arndt Lehmann
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
- require 'config/requirements'
2
- require 'config/hoe' if Object.const_defined? 'Hoe' # setup Hoe + all gem configuration
1
+ namespace :bundler do
2
+ require "bundler/gem_tasks"
3
+ end
3
4
 
4
- require 'lib/rubyrep'
5
- require 'tasks/task_helper'
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
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
4
4
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  RR::Initializer::run do |config|
5
5
  config.left = {
6
- :adapter => 'mysql',
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 => 'mysql',
16
+ :adapter => 'mysql2',
17
17
  :database => 'rr_right',
18
18
  :username => 'root',
19
19
  :password => '',
@@ -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
@@ -32,7 +32,7 @@ module RR
32
32
 
33
33
  # Prints the version to stderr
34
34
  def self.show_version
35
- $stdout.puts "rubyrep version #{RR::VERSION::STRING}"
35
+ $stdout.puts "rubyrep version #{RR::VERSION}"
36
36
  end
37
37
 
38
38
 
@@ -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
- # Dummy ActiveRecord descendant only used to create database connections.
43
- class DummyActiveRecord < ActiveRecord::Base
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
- if RUBY_PLATFORM =~ /java/
56
- adapter = config[:adapter]
57
-
58
- # As recommended in the activerecord-jdbc-adapter use the jdbc versions
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
- DummyActiveRecord.establish_connection(config.merge(:adapter => adapter))
63
- else
64
- DummyActiveRecord.establish_connection(config)
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
- connection = DummyActiveRecord.connection
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::BufferedLogger.new(config[:logger])
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
- logger.debug payload[:sql].squeeze(" ")
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 :mysql => self
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
- column_ids = column_parray.sub(/^\{(.*)\}$/,'\1').split(',').map {|a| a.to_i}
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
- # Sets the schema search path as per configuration parameters
190
- def initialize_search_path
191
- execute "SET search_path TO #{config[:schema_search_path] || 'public'}"
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
- # *** Moneky patch***
195
- # Returns the column objects for the named table.
196
- # Fixes JRuby schema support
197
- def columns(table_name, name = nil)
198
- jdbc_connection = @connection.connection # the actual JDBC DatabaseConnection
199
- @unquoted_schema ||= select_one("show search_path")['search_path']
200
-
201
- # check if table exists
202
- table_results = jdbc_connection.meta_data.get_tables(
203
- jdbc_connection.catalog,
204
- @unquoted_schema,
205
- table_name,
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
@@ -9,7 +9,7 @@ module RR
9
9
  CONFIG_TEMPLATE = <<EOF
10
10
  RR::Initializer::run do |config|
11
11
  config.left = {
12
- :adapter => 'postgresql', # or 'mysql'
12
+ :adapter => 'postgresql', # or 'mysql2'
13
13
  :database => 'SCOTT',
14
14
  :username => 'scott',
15
15
  :password => 'tiger',
@@ -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