activerecord-jdbc-adapter 1.3.6 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Appraisals +9 -5
- data/Gemfile +11 -3
- data/History.md +18 -0
- data/Rakefile +8 -0
- data/lib/arjdbc/db2/adapter.rb +23 -2
- data/lib/arjdbc/derby/adapter.rb +33 -3
- data/lib/arjdbc/firebird/adapter.rb +10 -2
- data/lib/arjdbc/jdbc.rb +35 -5
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/connection.rb +10 -6
- data/lib/arjdbc/jdbc/connection_methods.rb +2 -2
- data/lib/arjdbc/jdbc/driver.rb +2 -2
- data/lib/arjdbc/jdbc/jdbc.rake +4 -3
- data/lib/arjdbc/jdbc/railtie.rb +1 -1
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -3
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -3
- data/lib/arjdbc/mssql/adapter.rb +25 -5
- data/lib/arjdbc/mssql/limit_helpers.rb +5 -2
- data/lib/arjdbc/mysql/adapter.rb +10 -3
- data/lib/arjdbc/mysql/connection_methods.rb +20 -0
- data/lib/arjdbc/oracle/adapter.rb +18 -1
- data/lib/arjdbc/tasks/databases.rake +1 -1
- data/lib/arjdbc/tasks/derby_database_tasks.rb +11 -11
- data/lib/arjdbc/tasks/h2_database_tasks.rb +9 -9
- data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +10 -10
- data/lib/arjdbc/tasks/jdbc_database_tasks.rb +69 -22
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +14 -4
- data/lib/arjdbc/tasks/oracle_database_tasks.rb +7 -4
- data/lib/arjdbc/version.rb +1 -1
- data/lib/jdbc_adapter.rb +1 -1
- data/lib/jdbc_adapter/rake_tasks.rb +4 -3
- data/lib/jdbc_adapter/version.rb +4 -2
- data/rakelib/02-test.rake +10 -0
- data/rakelib/db.rake +5 -3
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +35 -8
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23a7dd04ff60809e25a4e3353934e7333eb95f85
|
4
|
+
data.tar.gz: 5e5f2405ab90b8162afb541ca07149b1c1905359
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f7e7f103b585be60afc053e89c60f4826409740b8a223380292ab57dd4d141a22e7ac2974b2c4c9b06e6ddb2f5971e32c5a01a20d73fc011f227adc5086322a
|
7
|
+
data.tar.gz: bd7e172e76bb7e2f492f4735124361060a5ddde25f036a67d80d9422e6b69d793ce270e19c33ddf74f659b820aa85eb4ea62c346ad9ddcbb104c4ac45cd84a34
|
data/Appraisals
CHANGED
@@ -12,16 +12,20 @@ appraise "rails31" do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
appraise "rails32" do
|
15
|
-
gem "activerecord", "~> 3.2.
|
15
|
+
gem "activerecord", "~> 3.2.17", :require => false
|
16
16
|
end
|
17
17
|
|
18
18
|
appraise "rails40" do
|
19
19
|
# NOTE: make sure you're using --1.9 with AR-4.0
|
20
|
-
gem "activerecord", "~> 4.0.
|
20
|
+
gem "activerecord", "~> 4.0.4", :require => false
|
21
21
|
end
|
22
22
|
|
23
23
|
appraise "rails41" do
|
24
24
|
# NOTE: make sure you're using --1.9 with AR-4.1
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
if branch = ENV['rails_branch']
|
26
|
+
gem "activerecord", :github => 'rails/rails', :branch => branch, :require => false
|
27
|
+
gem 'rails', :github => 'rails/rails', :branch => branch
|
28
|
+
else
|
29
|
+
gem "activerecord", '4.1.0.rc1', :require => false
|
30
|
+
end
|
31
|
+
end
|
data/Gemfile
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
|
3
|
+
if version = ENV['AR_VERSION']
|
4
|
+
gem 'activerecord', version, :require => nil
|
5
|
+
else
|
6
|
+
gem 'activerecord', :require => nil
|
7
|
+
end
|
4
8
|
gem 'thread_safe', :require => nil # "optional" - we can roll without it
|
5
9
|
if defined?(JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
|
6
10
|
gem 'jruby-openssl', :platform => :jruby
|
@@ -15,8 +19,12 @@ group :development do
|
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
18
|
-
|
19
|
-
gem '
|
22
|
+
if RUBY_VERSION < '1.9'
|
23
|
+
gem 'rake', '< 10.2.0', :require => nil
|
24
|
+
else
|
25
|
+
gem 'rake', :require => nil
|
26
|
+
end
|
27
|
+
gem 'appraisal', '~> 0.5.2', :require => nil
|
20
28
|
|
21
29
|
# appraisal ignores group block declarations :
|
22
30
|
|
data/History.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## 1.3.7 (04/14/14)
|
2
|
+
|
3
|
+
- [postgres] set prepared values with array columns on AR < 4.0 correctly
|
4
|
+
- [postgres] handle null values in array columns with AR < 4.0 (fixes #548)
|
5
|
+
- [mysql] support for config[:reconnect] (might need some fine tuning to match mysql2)
|
6
|
+
- fix ordering on an aggregate in MSSQL (#532) (should fix #437 for good)
|
7
|
+
- introduce a deprecation (warn) method for AR-JDBC and start using it
|
8
|
+
- [mysql] do not set defaults for text/blob columns on rename/change (#543)
|
9
|
+
- try resolving config 'database' (if missing) from JDBC url: in rake tasks
|
10
|
+
- [mysql] needs to `reconnect!` when recreating database (fixes #539)
|
11
|
+
- remove_column compatibility with Rails 4.x for Oracle, Derby and MSSQL (#541)
|
12
|
+
- Fix connection without user and password (#542)
|
13
|
+
- fix db2 remove_column for ActiveRecord 4 (#537)
|
14
|
+
- FireBird's DB meta-identifier is 31 chars maximum, thanks @mariuz (#538)
|
15
|
+
- [derby] add emulate booleans option for derby adapter
|
16
|
+
|
17
|
+
Code Contributors (in no particular order): mark100net, Pierrick Rouxel, @iaddict
|
18
|
+
|
1
19
|
## 1.3.6 (02/04/14)
|
2
20
|
|
3
21
|
- fix rails 4-0-stable compatibility (see #530)
|
data/Rakefile
CHANGED
@@ -42,28 +42,36 @@ end
|
|
42
42
|
# DRIVERS
|
43
43
|
|
44
44
|
desc "Build drivers"
|
45
|
+
task "build:drivers" => DRIVERS.map { |name| "#{name}:build" }
|
45
46
|
task "drivers:build" => DRIVERS.map { |name| "#{name}:build" }
|
46
47
|
|
47
48
|
desc "Install drivers"
|
49
|
+
task "install:drivers" => DRIVERS.map { |name| "#{name}:install" }
|
48
50
|
task "drivers:install" => DRIVERS.map { |name| "#{name}:install" }
|
49
51
|
|
50
52
|
desc "Release drivers"
|
53
|
+
task "release:drivers" => DRIVERS.map { |name| "#{name}:release" }
|
51
54
|
task "drivers:release" => DRIVERS.map { |name| "#{name}:release" }
|
52
55
|
|
53
56
|
# ADAPTERS
|
54
57
|
|
55
58
|
desc "Build adapters"
|
59
|
+
task "build:adapters" => [ 'build' ] + ADAPTERS.map { |name| "#{name}:build" }
|
56
60
|
task "adapters:build" => [ 'build' ] + ADAPTERS.map { |name| "#{name}:build" }
|
57
61
|
|
58
62
|
desc "Install adapters"
|
63
|
+
task "install:adapters" => [ 'install' ] + ADAPTERS.map { |name| "#{name}:install" }
|
59
64
|
task "adapters:install" => [ 'install' ] + ADAPTERS.map { |name| "#{name}:install" }
|
60
65
|
|
61
66
|
desc "Release adapters"
|
67
|
+
task "release:adapters" => [ 'release' ] + ADAPTERS.map { |name| "#{name}:release" }
|
62
68
|
task "adapters:release" => [ 'release' ] + ADAPTERS.map { |name| "#{name}:release" }
|
63
69
|
|
64
70
|
# ALL
|
65
71
|
|
72
|
+
task "build:all" => [ 'build' ] + TARGETS.map { |name| "#{name}:build" }
|
66
73
|
task "all:build" => [ 'build' ] + TARGETS.map { |name| "#{name}:build" }
|
74
|
+
task "install:all" => [ 'install' ] + TARGETS.map { |name| "#{name}:install" }
|
67
75
|
task "all:install" => [ 'install' ] + TARGETS.map { |name| "#{name}:install" }
|
68
76
|
|
69
77
|
task :filelist do
|
data/lib/arjdbc/db2/adapter.rb
CHANGED
@@ -350,6 +350,13 @@ module ArJdbc
|
|
350
350
|
super(type, limit, precision, scale)
|
351
351
|
end
|
352
352
|
|
353
|
+
def add_column(table_name, column_name, type, options = {})
|
354
|
+
# The keyword COLUMN allows to use reserved names for columns (ex: date)
|
355
|
+
add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
356
|
+
add_column_options!(add_column_sql, options)
|
357
|
+
execute(add_column_sql)
|
358
|
+
end
|
359
|
+
|
353
360
|
def add_column_options!(sql, options)
|
354
361
|
# handle case of defaults for CLOB columns,
|
355
362
|
# which might get incorrect if we write LOBs in the after_save callback
|
@@ -498,17 +505,26 @@ module ArJdbc
|
|
498
505
|
end
|
499
506
|
end
|
500
507
|
|
508
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
509
|
+
|
510
|
+
def remove_column(table_name, column_name, type = nil, options = {})
|
511
|
+
db2_remove_column(table_name, column_name)
|
512
|
+
end
|
513
|
+
|
514
|
+
else
|
515
|
+
|
501
516
|
def remove_column(table_name, *column_names)
|
502
517
|
# http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.admin.dbobj.doc/doc/t0020132.html
|
503
518
|
outcome = nil
|
504
519
|
column_names = column_names.flatten
|
505
520
|
for column_name in column_names
|
506
|
-
|
507
|
-
outcome = execute_table_change(sql, table_name, 'Remove Column')
|
521
|
+
outcome = db2_remove_column(table_name, column_name)
|
508
522
|
end
|
509
523
|
column_names.size == 1 ? outcome : nil
|
510
524
|
end
|
511
525
|
|
526
|
+
end
|
527
|
+
|
512
528
|
def rename_table(name, new_name)
|
513
529
|
# http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000980.html
|
514
530
|
execute_table_change("RENAME TABLE #{name} TO #{new_name}", new_name, 'Rename Table')
|
@@ -646,6 +662,11 @@ module ArJdbc
|
|
646
662
|
end
|
647
663
|
end
|
648
664
|
|
665
|
+
def db2_remove_column(table_name, column_name)
|
666
|
+
sql = "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
|
667
|
+
execute_table_change(sql, table_name, 'Remove Column')
|
668
|
+
end
|
669
|
+
|
649
670
|
end
|
650
671
|
end
|
651
672
|
|
data/lib/arjdbc/derby/adapter.rb
CHANGED
@@ -25,6 +25,19 @@ module ArJdbc
|
|
25
25
|
[ /derby/i, lambda { |config, column| column.extend(Column) } ]
|
26
26
|
end
|
27
27
|
|
28
|
+
# @private
|
29
|
+
@@emulate_booleans = true
|
30
|
+
|
31
|
+
# Boolean emulation can be disabled using :
|
32
|
+
#
|
33
|
+
# ArJdbc::Derby.emulate_booleans = false
|
34
|
+
#
|
35
|
+
def self.emulate_booleans?; @@emulate_booleans; end
|
36
|
+
# @deprecated Use {#emulate_booleans?} instead.
|
37
|
+
def self.emulate_booleans; @@emulate_booleans; end
|
38
|
+
# @see #emulate_booleans?
|
39
|
+
def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
|
40
|
+
|
28
41
|
# @note Part of this module is implemented in "native" Java.
|
29
42
|
# @see ActiveRecord::ConnectionAdapters::JdbcColumn
|
30
43
|
module Column
|
@@ -53,7 +66,7 @@ module ArJdbc
|
|
53
66
|
|
54
67
|
def simplified_type(field_type)
|
55
68
|
case field_type
|
56
|
-
when /^smallint/i then :boolean
|
69
|
+
when /^smallint/i then Derby.emulate_booleans? ? :boolean : :integer
|
57
70
|
when /^bigint|int/i then :integer
|
58
71
|
when /^real|double/i then :float
|
59
72
|
when /^dec/i then # DEC is a DECIMAL alias
|
@@ -282,12 +295,29 @@ module ArJdbc
|
|
282
295
|
super
|
283
296
|
end unless const_defined? :SchemaCreation
|
284
297
|
|
298
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
299
|
+
|
300
|
+
# @override
|
301
|
+
def remove_column(table_name, column_name, type = nil, options = {})
|
302
|
+
do_remove_column(table_name, column_name)
|
303
|
+
end
|
304
|
+
|
305
|
+
else
|
306
|
+
|
285
307
|
# @override
|
286
308
|
def remove_column(table_name, *column_names)
|
287
309
|
for column_name in column_names.flatten
|
288
|
-
|
310
|
+
do_remove_column(table_name, column_name)
|
289
311
|
end
|
290
|
-
end
|
312
|
+
end
|
313
|
+
alias remove_columns remove_column
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
def do_remove_column(table_name, column_name)
|
318
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)} RESTRICT"
|
319
|
+
end
|
320
|
+
private :do_remove_column
|
291
321
|
|
292
322
|
# @override
|
293
323
|
def change_column(table_name, column_name, type, options = {})
|
@@ -193,8 +193,16 @@ module ArJdbc
|
|
193
193
|
columns(table_name).count { |column| column.primary } == 1
|
194
194
|
end
|
195
195
|
|
196
|
-
|
197
|
-
|
196
|
+
IDENTIFIER_LENGTH = 31 # usual DB meta-identifier: 31 chars maximum
|
197
|
+
|
198
|
+
def table_alias_length; IDENTIFIER_LENGTH; end
|
199
|
+
def table_name_length; IDENTIFIER_LENGTH; end
|
200
|
+
def index_name_length; IDENTIFIER_LENGTH; end
|
201
|
+
def column_name_length; IDENTIFIER_LENGTH; end
|
202
|
+
|
203
|
+
def default_sequence_name(table_name, column = nil)
|
204
|
+
# TODO: remove schema prefix if present (before truncating)
|
205
|
+
"#{table_name.to_s[0, IDENTIFIER_LENGTH - 4]}_seq"
|
198
206
|
end
|
199
207
|
|
200
208
|
# Set the sequence to the max value of the table's column.
|
data/lib/arjdbc/jdbc.rb
CHANGED
@@ -1,6 +1,36 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
require 'set'
|
2
|
+
require 'active_support/deprecation'
|
3
|
+
|
4
|
+
module ArJdbc
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def warn(message, once = nil)
|
9
|
+
super(message) || true if warn?(message, once)
|
10
|
+
end
|
11
|
+
|
12
|
+
def deprecate(message, once = nil)
|
13
|
+
ActiveSupport::Deprecation.warn(message, caller) || true if warn?(message, once)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
@@warns = Set.new
|
19
|
+
|
20
|
+
def warn?(message, once)
|
21
|
+
return nil unless message
|
22
|
+
return false if @@warns.include?(message)
|
23
|
+
@@warns << message.dup if once
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
require 'arjdbc/jdbc/adapter'
|
30
|
+
|
31
|
+
if Java::JavaLang::Boolean.getBoolean('arjdbc.extensions.discover')
|
32
|
+
self.discover_extensions
|
33
|
+
else
|
34
|
+
require 'arjdbc/discover'
|
35
|
+
end
|
6
36
|
end
|
Binary file
|
@@ -34,7 +34,9 @@ module ActiveRecord
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# @deprecated no longer used - only kept for compatibility
|
37
|
-
def set_native_database_types
|
37
|
+
def set_native_database_types
|
38
|
+
ArJdbc.deprecate "set_native_database_types is no longer used and does nothing override native_database_types instead"
|
39
|
+
end
|
38
40
|
|
39
41
|
def self.jndi_config?(config)
|
40
42
|
config[:jndi] || config[:data_source]
|
@@ -74,12 +76,13 @@ module ActiveRecord
|
|
74
76
|
|
75
77
|
def setup_jdbc_factory
|
76
78
|
if ! config[:url] || ( ! config[:driver] && ! config[:driver_instance] )
|
77
|
-
|
79
|
+
msg = config[:url] ? ":url = #{config[:url]}" : ":driver = #{config[:driver]}"
|
80
|
+
raise ::ActiveRecord::ConnectionNotEstablished, "jdbc adapter requires :driver and :url (got #{msg})"
|
78
81
|
end
|
79
82
|
|
80
83
|
url = jdbc_url
|
81
|
-
username = config[:username]
|
82
|
-
password = config[:password]
|
84
|
+
username = config[:username]
|
85
|
+
password = config[:password]
|
83
86
|
jdbc_driver = ( config[:driver_instance] ||=
|
84
87
|
JdbcDriver.new(config[:driver].to_s, config[:properties]) )
|
85
88
|
|
@@ -93,8 +96,9 @@ module ActiveRecord
|
|
93
96
|
|
94
97
|
def jdbc_url
|
95
98
|
url = config[:url].to_s
|
96
|
-
if
|
97
|
-
|
99
|
+
if options = config[:options]
|
100
|
+
ArJdbc.deprecate "use config[:properties] to specify connection URL properties instead of config[:options]"
|
101
|
+
options = options.map { |key, val| "#{key}=#{val}" }.join('&') if Hash === options
|
98
102
|
url = url['?'] ? "#{url}&#{options}" : "#{url}?#{options}" unless options.empty?
|
99
103
|
config[:url] = url; config[:options] = nil
|
100
104
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module ArJdbc
|
2
|
-
if
|
2
|
+
if ActiveRecord.const_defined? :ConnectionHandling # 4.0
|
3
3
|
ConnectionMethods = ActiveRecord::ConnectionHandling
|
4
4
|
else # 3.x
|
5
5
|
ConnectionMethods = (class << ActiveRecord::Base; self; end)
|
@@ -27,4 +27,4 @@ module ArJdbc
|
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
30
|
-
end
|
30
|
+
end
|
data/lib/arjdbc/jdbc/driver.rb
CHANGED
@@ -34,8 +34,8 @@ module ActiveRecord
|
|
34
34
|
def connection(url, user, pass)
|
35
35
|
# bypass DriverManager to get around problem with dynamically loaded jdbc drivers
|
36
36
|
properties = self.properties.clone
|
37
|
-
properties.setProperty("user", user) if user
|
38
|
-
properties.setProperty("password", pass) if pass
|
37
|
+
properties.setProperty("user", user.to_s) if user
|
38
|
+
properties.setProperty("password", pass.to_s) if pass
|
39
39
|
@driver.connect(url, properties)
|
40
40
|
end
|
41
41
|
end
|
data/lib/arjdbc/jdbc/jdbc.rake
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
load 'arjdbc/tasks.rb'
|
2
|
+
|
3
|
+
require 'arjdbc'
|
4
|
+
ArJdbc.deprecate "load 'arjdbc/tasks.rb' (or 'arjdbc/tasks/database.rake') instead of 'arjdbc/jdbc/jdbc.rake'"
|
data/lib/arjdbc/jdbc/railtie.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
load 'arjdbc/tasks.rb'
|
1
|
+
load 'arjdbc/tasks.rb'
|
2
|
+
|
3
|
+
ArJdbc.deprecate "load 'arjdbc/tasks.rb' instead of 'arjdbc/jdbc/rake_tasks.rb'"
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'arjdbc/util/serialized_attributes'
|
1
|
+
require 'arjdbc/util/serialized_attributes'
|
2
|
+
|
3
|
+
ArJdbc.deprecate "require 'arjdbc/util/serialized_attributes' instead of 'arjdbc/jdbc/serialized_attributes_helper'"
|
data/lib/arjdbc/mssql/adapter.rb
CHANGED
@@ -423,18 +423,38 @@ module ArJdbc
|
|
423
423
|
end
|
424
424
|
end
|
425
425
|
|
426
|
-
def
|
426
|
+
def remove_columns(table_name, *column_names)
|
427
427
|
raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty?
|
428
428
|
# remove_columns(:posts, :foo, :bar) old syntax : remove_columns(:posts, [:foo, :bar])
|
429
429
|
clear_cached_table(table_name)
|
430
|
+
|
431
|
+
return do_remove_column(table_name, column_names.first) if column_names.size == 1
|
430
432
|
column_names.flatten.each do |column_name|
|
431
|
-
|
432
|
-
remove_default_constraint(table_name, column_name)
|
433
|
-
remove_indexes(table_name, column_name) unless sqlserver_2000?
|
434
|
-
execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
|
433
|
+
do_remove_column(table_name, column_name)
|
435
434
|
end
|
436
435
|
end
|
437
436
|
|
437
|
+
def do_remove_column(table_name, column_name)
|
438
|
+
remove_check_constraints(table_name, column_name)
|
439
|
+
remove_default_constraint(table_name, column_name)
|
440
|
+
remove_indexes(table_name, column_name) unless sqlserver_2000?
|
441
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
|
442
|
+
end
|
443
|
+
private :do_remove_column
|
444
|
+
|
445
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
446
|
+
|
447
|
+
# @override
|
448
|
+
def remove_column(table_name, column_name, type = nil, options = {})
|
449
|
+
remove_columns(table_name, column_name)
|
450
|
+
end
|
451
|
+
|
452
|
+
else
|
453
|
+
|
454
|
+
def remove_column(table_name, *column_names); remove_columns(table_name, *column_names) end
|
455
|
+
|
456
|
+
end
|
457
|
+
|
438
458
|
def remove_default_constraint(table_name, column_name)
|
439
459
|
clear_cached_table(table_name)
|
440
460
|
if sqlserver_2000?
|
@@ -4,6 +4,7 @@ module ArJdbc
|
|
4
4
|
|
5
5
|
# @private
|
6
6
|
FIND_SELECT = /\b(SELECT(\s+DISTINCT)?)\b(.*)/mi
|
7
|
+
FIND_AGGREGATE_FUNCTIONS = /AVG|COUNT|COUNT_BIG|MAX|MIN|SUM|STDDEV|STDEVP|VAR|VARP/
|
7
8
|
|
8
9
|
module SqlServerReplaceLimitOffset
|
9
10
|
|
@@ -28,8 +29,10 @@ module ArJdbc
|
|
28
29
|
# ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: Column 'users.id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
|
29
30
|
# SELECT t.* FROM ( SELECT ROW_NUMBER() OVER(ORDER BY users.id) AS _row_num, [users].[lft], COUNT([users].[lft]) FROM [users] GROUP BY [users].[lft] HAVING COUNT([users].[lft]) > 1 ) AS t WHERE t._row_num BETWEEN 1 AND 1
|
30
31
|
if rest_of_query.downcase.include?('group by')
|
31
|
-
if order.
|
32
|
-
|
32
|
+
if order.match(/^ORDER +BY +(#{FIND_AGGREGATE_FUNCTIONS})\(/i)
|
33
|
+
# do nothing
|
34
|
+
elsif order.count(',') == 0
|
35
|
+
order.gsub!(/ORDER +BY +([^\s]+)(\s+ASC|\s+DESC)?/i, 'ORDER BY MIN(\1)\2')
|
33
36
|
else
|
34
37
|
raise('Only one order condition allowed.')
|
35
38
|
end
|
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -341,6 +341,7 @@ module ArJdbc
|
|
341
341
|
def recreate_database(name, options = {})
|
342
342
|
drop_database(name)
|
343
343
|
create_database(name, options)
|
344
|
+
reconnect!
|
344
345
|
end
|
345
346
|
|
346
347
|
# @override
|
@@ -406,7 +407,8 @@ module ArJdbc
|
|
406
407
|
column = column_for(table_name, column_name)
|
407
408
|
|
408
409
|
unless options_include_default?(options)
|
409
|
-
|
410
|
+
# NOTE: no defaults for BLOB/TEXT columns with MySQL
|
411
|
+
options[:default] = column.default if type != :text && type != :binary
|
410
412
|
end
|
411
413
|
|
412
414
|
unless options.has_key?(:null)
|
@@ -422,17 +424,22 @@ module ArJdbc
|
|
422
424
|
# @override
|
423
425
|
def rename_column(table_name, column_name, new_column_name)
|
424
426
|
options = {}
|
427
|
+
|
425
428
|
if column = columns(table_name).find { |c| c.name == column_name.to_s }
|
426
|
-
|
429
|
+
type = column.type
|
430
|
+
options[:default] = column.default if type != :text && type != :binary
|
431
|
+
options[:null] = column.null
|
427
432
|
else
|
428
433
|
raise ActiveRecord::ActiveRecordError, "No such column: #{table_name}.#{column_name}"
|
429
434
|
end
|
435
|
+
|
430
436
|
current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'")["Type"]
|
437
|
+
|
431
438
|
rename_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}"
|
432
439
|
add_column_options!(rename_column_sql, options)
|
433
440
|
execute(rename_column_sql)
|
434
441
|
rename_column_indexes(table_name, column_name, new_column_name) if respond_to?(:rename_column_indexes) # AR-4.0 SchemaStatements
|
435
|
-
end
|
442
|
+
end
|
436
443
|
|
437
444
|
def add_column_position!(sql, options)
|
438
445
|
if options[:first]
|
@@ -31,6 +31,26 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
31
31
|
properties['useUnicode'] = 'true' unless properties.key?('useUnicode') # otherwise platform default
|
32
32
|
encoding = config.key?(:encoding) ? config[:encoding] : 'utf8'
|
33
33
|
properties['characterEncoding'] = encoding if encoding
|
34
|
+
if ! ( reconnect = config[:reconnect] ).nil?
|
35
|
+
properties['autoReconnect'] ||= reconnect.to_s
|
36
|
+
# properties['maxReconnects'] ||= '3'
|
37
|
+
# with reconnect fail-over sets connection read-only (by default)
|
38
|
+
# properties['failOverReadOnly'] ||= 'false'
|
39
|
+
end
|
40
|
+
if config[:sslkey] || sslcert = config[:sslcert] # || config[:use_ssl]
|
41
|
+
properties['useSSL'] ||= true
|
42
|
+
properties['requireSSL'] ||= true
|
43
|
+
properties['clientCertificateKeyStoreUrl'] ||= begin
|
44
|
+
java.io.File.new(sslcert).to_url.to_s
|
45
|
+
end if sslcert
|
46
|
+
if sslca = config[:sslca]
|
47
|
+
properties['trustCertificateKeyStoreUrl'] ||= begin
|
48
|
+
java.io.File.new(sslca).to_url.to_s
|
49
|
+
end
|
50
|
+
else
|
51
|
+
properties['verifyServerCertificate'] ||= false
|
52
|
+
end
|
53
|
+
end
|
34
54
|
|
35
55
|
jdbc_connection(config)
|
36
56
|
end
|
@@ -278,12 +278,29 @@ module ArJdbc
|
|
278
278
|
"RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
|
279
279
|
end
|
280
280
|
|
281
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
282
|
+
|
283
|
+
# @override
|
284
|
+
def remove_column(table_name, column_name, type = nil, options = {})
|
285
|
+
do_remove_column(table_name, column_name)
|
286
|
+
end
|
287
|
+
|
288
|
+
else
|
289
|
+
|
281
290
|
# @override
|
282
291
|
def remove_column(table_name, *column_names)
|
283
292
|
for column_name in column_names.flatten
|
284
|
-
|
293
|
+
do_remove_column(table_name, column_name)
|
285
294
|
end
|
286
295
|
end
|
296
|
+
alias remove_columns remove_column
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
def do_remove_column(table_name, column_name)
|
301
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
|
302
|
+
end
|
303
|
+
private :do_remove_column
|
287
304
|
|
288
305
|
# SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
|
289
306
|
#
|
@@ -42,7 +42,7 @@ namespace :db do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
if defined? adapt_jdbc_config
|
45
|
-
|
45
|
+
ArJdbc.warn "double loading #{__FILE__} please delete lib/tasks/jdbc.rake if present!"
|
46
46
|
end
|
47
47
|
|
48
48
|
def adapt_jdbc_config(config)
|
@@ -8,28 +8,28 @@ module ArJdbc
|
|
8
8
|
establish_connection(config)
|
9
9
|
ActiveRecord::Base.connection
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def drop
|
13
|
-
db_dir = expand_path(config
|
13
|
+
db_dir = expand_path resolve_database(config, true)
|
14
14
|
if File.exist?(db_dir)
|
15
15
|
FileUtils.rm_r(db_dir)
|
16
16
|
FileUtils.rmdir(db_dir) rescue nil
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
SIZEABLE = %w( VARCHAR CLOB BLOB )
|
21
21
|
|
22
22
|
def structure_dump(filename)
|
23
23
|
establish_connection(config)
|
24
24
|
dump = File.open(filename, "w:utf-8")
|
25
|
-
|
25
|
+
|
26
26
|
meta_data = connection.jdbc_connection.meta_data
|
27
27
|
tables_rs = meta_data.getTables(nil, nil, nil, ["TABLE"].to_java(:String))
|
28
|
-
|
28
|
+
|
29
29
|
while tables_rs.next
|
30
30
|
table_name = tables_rs.getString('TABLE_NAME') # getString(3)
|
31
31
|
dump << "CREATE TABLE #{connection.quote_table_name(table_name)} (\n"
|
32
|
-
|
32
|
+
|
33
33
|
columns_rs = meta_data.getColumns(nil, nil, table_name, nil)
|
34
34
|
first_col = true
|
35
35
|
while columns_rs.next
|
@@ -43,7 +43,7 @@ module ArJdbc
|
|
43
43
|
type = columns_rs.getString(6)
|
44
44
|
column_size = columns_rs.getString(7)
|
45
45
|
nulling = ( columns_rs.getString(18) == 'NO' ? " NOT NULL" : nil )
|
46
|
-
|
46
|
+
|
47
47
|
create_column = connection.quote_column_name(column_name)
|
48
48
|
create_column << " #{type}"
|
49
49
|
create_column << ( SIZEABLE.include?(type) ? "(#{column_size})" : "" )
|
@@ -57,15 +57,15 @@ module ArJdbc
|
|
57
57
|
end
|
58
58
|
dump << "\n);\n\n"
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
dump.close
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def structure_load(filename)
|
65
65
|
establish_connection(config)
|
66
66
|
IO.read(filename).split(/;\n*/m).each { |ddl| connection.execute(ddl) }
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
private
|
70
70
|
|
71
71
|
AUTO_INCREMENT_SQL = '' <<
|
@@ -89,7 +89,7 @@ module ArJdbc
|
|
89
89
|
end
|
90
90
|
''
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
@@ -3,27 +3,27 @@ require 'arjdbc/tasks/hsqldb_database_tasks'
|
|
3
3
|
module ArJdbc
|
4
4
|
module Tasks
|
5
5
|
class H2DatabaseTasks < HSQLDBDatabaseTasks
|
6
|
-
|
6
|
+
|
7
7
|
protected
|
8
|
-
|
8
|
+
|
9
9
|
# @override
|
10
10
|
def do_drop_database(config)
|
11
|
-
# ActiveRecord::JDBCError: org.h2.jdbc.JdbcSQLException:
|
12
|
-
# Database is already closed (to disable automatic closing at VM
|
13
|
-
# shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-170]:
|
11
|
+
# ActiveRecord::JDBCError: org.h2.jdbc.JdbcSQLException:
|
12
|
+
# Database is already closed (to disable automatic closing at VM
|
13
|
+
# shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-170]:
|
14
14
|
# SHUTDOWN COMPACT
|
15
|
-
#
|
15
|
+
#
|
16
16
|
# connection.shutdown
|
17
|
-
connection.drop_database config
|
17
|
+
connection.drop_database resolve_database(config)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
# @override
|
21
21
|
def delete_database_files(config)
|
22
22
|
return unless db_base = database_base_name(config)
|
23
23
|
db_files = [ "#{db_base}.h2.db", "#{db_base}.lock.db", "#{db_base}.trace.db" ]
|
24
24
|
db_files.each { |file| File.delete(file) if File.exist?(file) }
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -8,7 +8,7 @@ module ArJdbc
|
|
8
8
|
establish_connection(config)
|
9
9
|
ActiveRecord::Base.connection
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def drop
|
13
13
|
error = nil
|
14
14
|
begin
|
@@ -27,14 +27,14 @@ module ArJdbc
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
alias :purge :drop
|
30
|
-
|
30
|
+
|
31
31
|
protected
|
32
|
-
|
32
|
+
|
33
33
|
def do_drop_database(config)
|
34
|
-
connection.drop_database config
|
34
|
+
connection.drop_database resolve_database(config)
|
35
35
|
connection.shutdown
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def delete_database_files(config)
|
39
39
|
return unless db_base = database_base_name(config)
|
40
40
|
Dir.glob("#{db_base}.*").each do |file|
|
@@ -55,16 +55,16 @@ module ArJdbc
|
|
55
55
|
FileUtils.rmdir(db_base)
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
private
|
60
|
-
|
60
|
+
|
61
61
|
def database_base_name(config)
|
62
|
-
db = config
|
62
|
+
db = resolve_database(config, true)
|
63
63
|
db[0, 4] == 'mem:' ? nil : begin
|
64
|
-
expand_path db[0,
|
64
|
+
expand_path db[0, 5] == 'file:' ? db[5..-1] : db
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
module ArJdbc
|
2
2
|
module Tasks
|
3
3
|
# Sharing task related code between AR 3.x and 4.x
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# @note this class needs to conform to the API available since AR 4.0
|
6
6
|
# mostly to be usable with ActiveRecord::Tasks::DatabaseTasks module
|
7
7
|
class JdbcDatabaseTasks
|
8
|
-
|
8
|
+
|
9
9
|
attr_reader :configuration
|
10
10
|
alias_method :config, :configuration
|
11
|
-
|
11
|
+
|
12
12
|
def initialize(configuration)
|
13
13
|
@configuration = configuration
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
delegate :connection, :establish_connection, :to => ActiveRecord::Base
|
17
17
|
|
18
18
|
def create
|
@@ -25,14 +25,14 @@ module ArJdbc
|
|
25
25
|
rescue #=> error # database does not exists :
|
26
26
|
url = config['url']
|
27
27
|
url = $1 if url && url =~ /^(.*(?<!\/)\/)(?=\w)/
|
28
|
-
|
28
|
+
|
29
29
|
establish_connection(config.merge('database' => nil, 'url' => url))
|
30
|
-
|
30
|
+
|
31
31
|
unless connection.respond_to?(:create_database)
|
32
32
|
raise "AR-JDBC adapter '#{adapter_with_spec}' does not support create_database"
|
33
33
|
end
|
34
|
-
connection.create_database(config
|
35
|
-
|
34
|
+
connection.create_database(resolve_database(config), config)
|
35
|
+
|
36
36
|
establish_connection(config)
|
37
37
|
end
|
38
38
|
end
|
@@ -42,7 +42,7 @@ module ArJdbc
|
|
42
42
|
unless ActiveRecord::Base.connection.respond_to?(:drop_database)
|
43
43
|
raise "AR-JDBC adapter '#{adapter_with_spec}' does not support drop_database"
|
44
44
|
end
|
45
|
-
connection.drop_database config
|
45
|
+
connection.drop_database resolve_database(config)
|
46
46
|
end
|
47
47
|
|
48
48
|
def purge
|
@@ -73,7 +73,7 @@ module ArJdbc
|
|
73
73
|
raise "AR-JDBC adapter '#{adapter_with_spec}' does not support collation"
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
def structure_dump(filename)
|
78
78
|
establish_connection(config)
|
79
79
|
if connection.respond_to?(:structure_dump)
|
@@ -94,29 +94,76 @@ module ArJdbc
|
|
94
94
|
raise "AR-JDBC adapter '#{adapter_with_spec}' does not support structure_load"
|
95
95
|
end
|
96
96
|
end
|
97
|
-
|
98
|
-
private
|
99
|
-
|
100
|
-
def adapter_with_spec
|
101
|
-
adapter, spec = config['adapter'], config['adapter_spec']
|
102
|
-
spec ? "#{adapter} (#{spec})" : adapter
|
103
|
-
end
|
104
|
-
|
97
|
+
|
105
98
|
protected
|
106
|
-
|
99
|
+
|
107
100
|
def expand_path(path)
|
108
101
|
require 'pathname'
|
109
102
|
path = Pathname.new path
|
110
103
|
return path.to_s if path.absolute?
|
111
104
|
rails_root ? File.join(rails_root, path) : File.expand_path(path)
|
112
105
|
end
|
113
|
-
|
106
|
+
|
107
|
+
def resolve_database(config, file_paths = false)
|
108
|
+
config['database'] || resolve_database_from_url(config['url'] || '', file_paths)
|
109
|
+
end
|
110
|
+
|
111
|
+
def resolve_database_from_url(url, file_paths = false)
|
112
|
+
( config = config_from_url(url, file_paths) ) ? config['database'] : nil
|
113
|
+
end
|
114
|
+
|
114
115
|
private
|
115
|
-
|
116
|
+
|
117
|
+
def config_from_url(url, file_paths = false)
|
118
|
+
match = url.match %r{
|
119
|
+
^ jdbc:
|
120
|
+
( [\w]+ ): # $1 protocol
|
121
|
+
(?: ([\w]+) : )? # $2 (sub-protocol)
|
122
|
+
(?://)?
|
123
|
+
(?: ([\w\-]*) (?: [/:] ([\w\-]*) )? @ (?://)? )? # user[:password]@ or user[/password]@ ($3 $4)
|
124
|
+
( [\w\.\-]+ )? # $5 host (or database if there's nothing left)
|
125
|
+
(?: : (\d+) )? # $6 port if any
|
126
|
+
(?: :? (/?[\w\-\./~]+) [\?;]? )? ([^/]*?) $
|
127
|
+
# $7 database part (ends with '?' or ';') and $8 query string - properties
|
128
|
+
}x
|
129
|
+
|
130
|
+
return nil unless match
|
131
|
+
|
132
|
+
config = {}
|
133
|
+
config['_protocol'] = match[1]
|
134
|
+
config['_sub_protocol'] = match[2] if match[2]
|
135
|
+
config['username'] = match[3] if match[3]
|
136
|
+
config['password'] = match[4] if match[4]
|
137
|
+
host = match[5]; port = match[6]
|
138
|
+
database = match[7]
|
139
|
+
if database.nil? && port.nil?
|
140
|
+
config['database'] = database = host
|
141
|
+
else
|
142
|
+
config['host'] = host if host
|
143
|
+
config['port'] = port if port
|
144
|
+
config['database'] = database
|
145
|
+
end
|
146
|
+
if database && ! file_paths && database[0...1] == '/'
|
147
|
+
config['database'] = database[1..-1]
|
148
|
+
end
|
149
|
+
if query_string = match[8]
|
150
|
+
properties = query_string.split('&').inject({}) do |memo, pair|
|
151
|
+
pair = pair.split("="); memo[ pair[0] ] = pair[1]; memo
|
152
|
+
end
|
153
|
+
config['properties'] = properties
|
154
|
+
end
|
155
|
+
config
|
156
|
+
end
|
157
|
+
|
158
|
+
def adapter_with_spec
|
159
|
+
adapter, spec = config['adapter'], config['adapter_spec']
|
160
|
+
spec ? "#{adapter} (#{spec})" : adapter
|
161
|
+
end
|
162
|
+
|
116
163
|
def rails_root
|
117
164
|
defined?(Rails.root) ? Rails.root : ( RAILS_ROOT )
|
118
165
|
end
|
119
|
-
|
166
|
+
|
120
167
|
end
|
121
168
|
end
|
122
169
|
end
|
@@ -6,22 +6,32 @@ module ArJdbc
|
|
6
6
|
|
7
7
|
def purge
|
8
8
|
test = deep_dup(configuration)
|
9
|
-
test_database = test
|
9
|
+
test_database = resolve_database(test)
|
10
10
|
test['database'] = 'master'
|
11
11
|
establish_connection(test)
|
12
12
|
connection.recreate_database!(test_database)
|
13
13
|
end
|
14
14
|
|
15
15
|
def structure_dump(filename)
|
16
|
+
config = config_from_url_if_needed
|
16
17
|
`smoscript -s #{config['host']} -d #{config['database']} -u #{config['username']} -p #{config['password']} -f #{filename} -A -U`
|
17
18
|
end
|
18
19
|
|
19
20
|
def structure_load(filename)
|
21
|
+
config = config_from_url_if_needed
|
20
22
|
`sqlcmd -S #{config['host']} -d #{config['database']} -U #{config['username']} -P #{config['password']} -i #{filename}`
|
21
23
|
end
|
22
|
-
|
24
|
+
|
23
25
|
private
|
24
|
-
|
26
|
+
|
27
|
+
def config_from_url_if_needed
|
28
|
+
config = self.config
|
29
|
+
if config['url'] && ! config.key?('database')
|
30
|
+
config = config_from_url(config['url'])
|
31
|
+
end
|
32
|
+
config
|
33
|
+
end
|
34
|
+
|
25
35
|
def deep_dup(hash)
|
26
36
|
dup = hash.dup
|
27
37
|
dup.each_pair do |k,v|
|
@@ -30,7 +40,7 @@ module ArJdbc
|
|
30
40
|
end
|
31
41
|
dup
|
32
42
|
end
|
33
|
-
|
43
|
+
|
34
44
|
end
|
35
45
|
end
|
36
46
|
end
|
@@ -8,6 +8,9 @@ module ArJdbc
|
|
8
8
|
print "Please provide the SYSTEM password for your oracle installation\n>"
|
9
9
|
system_password = $stdin.gets.strip
|
10
10
|
establish_connection(config.merge('username' => 'SYSTEM', 'password' => system_password))
|
11
|
+
unless ( config = self.config ).key?('username')
|
12
|
+
config = config_from_url(config['url']) if config['url']
|
13
|
+
end
|
11
14
|
begin
|
12
15
|
connection.execute "CREATE USER #{config['username']} IDENTIFIED BY #{config['password']}"
|
13
16
|
rescue => e
|
@@ -22,13 +25,13 @@ module ArJdbc
|
|
22
25
|
connection.execute "GRANT create table TO #{config['username']}"
|
23
26
|
connection.execute "GRANT create sequence TO #{config['username']}"
|
24
27
|
end
|
25
|
-
|
28
|
+
|
26
29
|
def drop
|
27
30
|
self.class.load_enhanced_structure_dump
|
28
31
|
establish_connection(config)
|
29
32
|
connection.execute_structure_dump(connection.full_drop)
|
30
33
|
end
|
31
|
-
|
34
|
+
|
32
35
|
def purge
|
33
36
|
self.class.load_enhanced_structure_dump
|
34
37
|
establish_connection(:test)
|
@@ -47,7 +50,7 @@ module ArJdbc
|
|
47
50
|
establish_connection(config)
|
48
51
|
connection.execute_structure_dump(File.read(filename))
|
49
52
|
end
|
50
|
-
|
53
|
+
|
51
54
|
def self.load_enhanced_structure_dump
|
52
55
|
unless defined? ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
53
56
|
ActiveRecord::ConnectionAdapters.module_eval do
|
@@ -56,7 +59,7 @@ module ArJdbc
|
|
56
59
|
end
|
57
60
|
require 'arjdbc/tasks/oracle/enhanced_structure_dump'
|
58
61
|
end
|
59
|
-
|
62
|
+
|
60
63
|
end
|
61
64
|
end
|
62
65
|
end
|
data/lib/arjdbc/version.rb
CHANGED
data/lib/jdbc_adapter.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'arjdbc
|
1
|
+
require 'arjdbc/tasks.rb'
|
2
|
+
|
3
|
+
require 'arjdbc'
|
4
|
+
ArJdbc.deprecate "load 'arjdbc/tasks.rb' instead of 'jdbc_adapter/rake_tasks.rb'"
|
data/lib/jdbc_adapter/version.rb
CHANGED
data/rakelib/02-test.rake
CHANGED
@@ -47,6 +47,16 @@ task 'test_appraisal_hint' do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
desc "Run unit tests (not connecting to a DB)."
|
51
|
+
Rake::TestTask.new(:test_unit) do |test_task|
|
52
|
+
test_task.test_files = FileList["test/unit*_test.rb"] + FileList["test/unit/*_test.rb"]
|
53
|
+
test_task.libs << 'lib' if defined?(JRUBY_VERSION)
|
54
|
+
test_task.libs << 'test'
|
55
|
+
test_task.verbose = true if $VERBOSE
|
56
|
+
set_test_task_compat_version test_task
|
57
|
+
end
|
58
|
+
task :test_units => :test_unit # alias
|
59
|
+
|
50
60
|
Rake::TestTask.class_eval { attr_reader :test_files }
|
51
61
|
|
52
62
|
def test_task_for(adapter, options = {})
|
data/rakelib/db.rake
CHANGED
@@ -4,6 +4,7 @@ namespace :db do
|
|
4
4
|
|
5
5
|
desc "Creates the test database for MySQL"
|
6
6
|
task :mysql do
|
7
|
+
fail "could not create test database: mysql executable not found" unless mysql = which('mysql')
|
7
8
|
load 'test/db/mysql_config.rb' # rescue nil
|
8
9
|
script = sql_script <<-SQL, 'mysql'
|
9
10
|
DROP DATABASE IF EXISTS `#{MYSQL_CONFIG[:database]}`;
|
@@ -19,12 +20,13 @@ SQL
|
|
19
20
|
params['--password'] = password
|
20
21
|
end
|
21
22
|
puts "Creating MySQL (test) database: #{MYSQL_CONFIG[:database]}"
|
22
|
-
sh "cat #{script.path} | mysql #{params.to_a.join(' ')}", :verbose => $VERBOSE # so password is not echoed
|
23
|
+
sh "cat #{script.path} | #{mysql} #{params.to_a.join(' ')}", :verbose => $VERBOSE # so password is not echoed
|
23
24
|
end
|
24
25
|
|
25
26
|
desc "Creates the test database for PostgreSQL"
|
26
27
|
task :postgresql do
|
27
|
-
fail unless
|
28
|
+
fail 'could not create test database: psql executable not found' unless psql = which('psql')
|
29
|
+
fail 'could not create test database: missing "postgres" role' unless PostgresHelper.postgres_role?
|
28
30
|
load 'test/db/postgres_config.rb' # rescue nil
|
29
31
|
script = sql_script <<-SQL, 'psql'
|
30
32
|
DROP DATABASE IF EXISTS #{POSTGRES_CONFIG[:database]};
|
@@ -35,7 +37,7 @@ SQL
|
|
35
37
|
params = { '-U' => ENV['PSQL_USER'] || 'postgres' }
|
36
38
|
params['-q'] = nil unless $VERBOSE
|
37
39
|
puts "Creating PostgreSQL (test) database: #{POSTGRES_CONFIG[:database]}"
|
38
|
-
sh "cat #{script.path} | psql #{params.to_a.join(' ')}", :verbose => $VERBOSE
|
40
|
+
sh "cat #{script.path} | #{psql} #{params.to_a.join(' ')}", :verbose => $VERBOSE
|
39
41
|
end
|
40
42
|
task :postgres => :postgresql
|
41
43
|
|
@@ -35,7 +35,6 @@ import java.sql.SQLException;
|
|
35
35
|
import java.sql.Statement;
|
36
36
|
import java.sql.Timestamp;
|
37
37
|
import java.sql.Types;
|
38
|
-
import java.util.List;
|
39
38
|
import java.util.Map;
|
40
39
|
import java.util.UUID;
|
41
40
|
|
@@ -43,6 +42,7 @@ import org.jruby.Ruby;
|
|
43
42
|
import org.jruby.RubyArray;
|
44
43
|
import org.jruby.RubyBoolean;
|
45
44
|
import org.jruby.RubyClass;
|
45
|
+
import org.jruby.RubyFixnum;
|
46
46
|
import org.jruby.RubyFloat;
|
47
47
|
import org.jruby.RubyHash;
|
48
48
|
import org.jruby.RubyIO;
|
@@ -56,6 +56,8 @@ import org.jruby.util.ByteList;
|
|
56
56
|
|
57
57
|
import org.postgresql.PGConnection;
|
58
58
|
import org.postgresql.PGStatement;
|
59
|
+
import org.postgresql.core.BaseConnection;
|
60
|
+
import org.postgresql.jdbc4.Jdbc4Array;
|
59
61
|
import org.postgresql.util.PGInterval;
|
60
62
|
import org.postgresql.util.PGobject;
|
61
63
|
|
@@ -204,25 +206,50 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
204
206
|
private static final ByteList INTERVAL =
|
205
207
|
new ByteList( new byte[] { 'i','n','t','e','r','v','a','l' }, false );
|
206
208
|
|
209
|
+
private static final ByteList ARRAY_END = new ByteList( new byte[] { '[',']' }, false );
|
210
|
+
|
207
211
|
@Override
|
208
212
|
protected void setStringParameter(final ThreadContext context,
|
209
213
|
final Connection connection, final PreparedStatement statement,
|
210
214
|
final int index, final IRubyObject value,
|
211
215
|
final IRubyObject column, final int type) throws SQLException {
|
212
|
-
|
216
|
+
final RubyString sqlType;
|
217
|
+
if ( column != null && ! column.isNil() ) {
|
218
|
+
sqlType = (RubyString) column.callMethod(context, "sql_type");
|
219
|
+
}
|
213
220
|
else {
|
214
|
-
|
215
|
-
|
221
|
+
sqlType = null;
|
222
|
+
}
|
216
223
|
|
224
|
+
if ( value.isNil() ) {
|
225
|
+
if ( rawArrayType == Boolean.TRUE ) { // array's type is :string
|
226
|
+
if ( sqlType != null && sqlType.getByteList().endsWith( ARRAY_END ) ) {
|
227
|
+
statement.setNull(index, Types.ARRAY); return;
|
228
|
+
}
|
229
|
+
statement.setNull(index, type); return;
|
230
|
+
}
|
231
|
+
statement.setNull(index, Types.VARCHAR);
|
232
|
+
}
|
233
|
+
else {
|
234
|
+
final String valueStr = value.asString().toString();
|
235
|
+
if ( sqlType != null ) {
|
236
|
+
if ( rawArrayType == Boolean.TRUE && sqlType.getByteList().endsWith( ARRAY_END ) ) {
|
237
|
+
final Array valueArr = new Jdbc4Array(connection.unwrap(BaseConnection.class), oidType(column), valueStr);
|
238
|
+
statement.setArray(index, valueArr); return;
|
239
|
+
}
|
217
240
|
if ( sqlType.getByteList().startsWith( INTERVAL ) ) {
|
218
|
-
statement.setObject( index, new PGInterval(
|
219
|
-
return;
|
241
|
+
statement.setObject( index, new PGInterval( valueStr ) ); return;
|
220
242
|
}
|
221
243
|
}
|
222
|
-
statement.setString( index,
|
244
|
+
statement.setString( index, valueStr );
|
223
245
|
}
|
224
246
|
}
|
225
247
|
|
248
|
+
private static int oidType(final IRubyObject column) {
|
249
|
+
final IRubyObject oid_type = column.getInstanceVariables().getInstanceVariable("@oid_type");
|
250
|
+
return RubyFixnum.fix2int(oid_type);
|
251
|
+
}
|
252
|
+
|
226
253
|
@Override
|
227
254
|
protected void setObjectParameter(final ThreadContext context,
|
228
255
|
final Connection connection, final PreparedStatement statement,
|
@@ -463,7 +490,7 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
463
490
|
final Ruby runtime, final ResultSet resultSet, final int column)
|
464
491
|
throws SQLException {
|
465
492
|
if ( rawArrayType == Boolean.TRUE ) { // pre AR 4.0 compatibility
|
466
|
-
return
|
493
|
+
return stringToRuby(context, runtime, resultSet, column);
|
467
494
|
}
|
468
495
|
// NOTE: avoid `finally { array.free(); }` on PostgreSQL due :
|
469
496
|
// java.sql.SQLFeatureNotSupportedException:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-jdbc-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sieger, Ola Bini, Karol Bucek and JRuby contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -238,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
238
238
|
version: '0'
|
239
239
|
requirements: []
|
240
240
|
rubyforge_project: jruby-extras
|
241
|
-
rubygems_version: 2.
|
241
|
+
rubygems_version: 2.2.2
|
242
242
|
signing_key:
|
243
243
|
specification_version: 4
|
244
244
|
summary: JDBC adapter for ActiveRecord, for use within JRuby on Rails.
|