activerecord-jdbc-adapter 1.3.6 → 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|