pmacs-activerecord-oracle_enhanced-adapter 1.4.2.rc1 → 1.5.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +11 -40
- data/History.md +170 -0
- data/README.md +61 -5
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +330 -161
- data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +48 -8
- data/lib/active_record/connection_adapters/oracle_enhanced_column_dumper.rb +77 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +8 -24
- data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +4 -13
- data/lib/active_record/connection_adapters/oracle_enhanced_database_tasks.rb +61 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +13 -12
- data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +42 -19
- data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +28 -74
- data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +165 -231
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_creation.rb +89 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +16 -24
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +29 -38
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +93 -42
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +5 -3
- data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +7 -7
- data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -1
- data/lib/pmacs-activerecord-oracle_enhanced-adapter.rb +2 -2
- data/pmacs-activerecord-oracle_enhanced-adapter.gemspec +19 -17
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +35 -99
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +17 -3
- data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +105 -98
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +74 -44
- data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +89 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +3 -3
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +13 -2
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +11 -12
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +252 -60
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +170 -40
- data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +14 -8
- data/spec/spec_helper.rb +25 -54
- metadata +41 -72
- data/lib/active_record/connection_adapters/oracle_enhanced.rake +0 -105
- data/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb +0 -41
- data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +0 -118
- data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +0 -25
- data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +0 -17
- data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +0 -19
@@ -2,34 +2,63 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters #:nodoc:
|
3
3
|
class OracleEnhancedColumn < Column
|
4
4
|
|
5
|
-
attr_reader :table_name, :forced_column_type, :nchar, :virtual_column_data_default #:nodoc:
|
5
|
+
attr_reader :table_name, :forced_column_type, :nchar, :virtual_column_data_default, :returning_id #:nodoc:
|
6
6
|
|
7
|
-
def initialize(name, default, sql_type = nil, null = true, table_name = nil, forced_column_type = nil, virtual=false) #:nodoc:
|
7
|
+
def initialize(name, default, sql_type = nil, null = true, table_name = nil, forced_column_type = nil, virtual=false, returning_id=false) #:nodoc:
|
8
8
|
@table_name = table_name
|
9
9
|
@forced_column_type = forced_column_type
|
10
10
|
@virtual = virtual
|
11
11
|
@virtual_column_data_default = default.inspect if virtual
|
12
|
-
|
13
|
-
|
12
|
+
@returning_id = returning_id
|
13
|
+
if virtual
|
14
|
+
default_value = nil
|
15
|
+
else
|
16
|
+
default_value = self.class.extract_value_from_default(default)
|
17
|
+
end
|
18
|
+
super(name, default_value, sql_type, null)
|
14
19
|
# Is column NCHAR or NVARCHAR2 (will need to use N'...' value quoting for these data types)?
|
15
20
|
# Define only when needed as adapter "quote" method will check at first if instance variable is defined.
|
16
21
|
@nchar = true if @type == :string && sql_type[0,1] == 'N'
|
22
|
+
@object_type = sql_type.include? '.'
|
17
23
|
end
|
18
24
|
|
19
25
|
def type_cast(value) #:nodoc:
|
20
|
-
|
21
|
-
|
22
|
-
|
26
|
+
case type
|
27
|
+
when :raw
|
28
|
+
OracleEnhancedColumn.string_to_raw(value)
|
29
|
+
when :datetime
|
30
|
+
OracleEnhancedAdapter.emulate_dates ? guess_date_or_time(value) : super
|
31
|
+
when :float
|
32
|
+
!value.nil? ? self.class.value_to_decimal(value) : super
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def type_cast_code(var_name)
|
39
|
+
type == :float ? "#{self.class.name}.value_to_decimal(#{var_name})" : super
|
40
|
+
end
|
41
|
+
|
42
|
+
def klass
|
43
|
+
type == :float ? BigDecimal : super
|
23
44
|
end
|
24
45
|
|
25
46
|
def virtual?
|
26
47
|
@virtual
|
27
48
|
end
|
28
49
|
|
50
|
+
def returning_id?
|
51
|
+
@returning_id
|
52
|
+
end
|
53
|
+
|
29
54
|
def lob?
|
30
55
|
self.sql_type =~ /LOB$/i
|
31
56
|
end
|
32
57
|
|
58
|
+
def object_type?
|
59
|
+
@object_type
|
60
|
+
end
|
61
|
+
|
33
62
|
# convert something to a boolean
|
34
63
|
# added y as boolean value
|
35
64
|
def self.value_to_boolean(value) #:nodoc:
|
@@ -71,12 +100,14 @@ module ActiveRecord
|
|
71
100
|
forced_column_type ||
|
72
101
|
case field_type
|
73
102
|
when /decimal|numeric|number/i
|
74
|
-
if OracleEnhancedAdapter.emulate_booleans && field_type ==
|
103
|
+
if OracleEnhancedAdapter.emulate_booleans && field_type.upcase == "NUMBER(1)"
|
75
104
|
:boolean
|
76
105
|
elsif extract_scale(field_type) == 0 ||
|
77
106
|
# if column name is ID or ends with _ID
|
78
107
|
OracleEnhancedAdapter.emulate_integers_by_column_name && OracleEnhancedAdapter.is_integer_column?(name, table_name)
|
79
108
|
:integer
|
109
|
+
elsif field_type.upcase == "NUMBER"
|
110
|
+
OracleEnhancedAdapter.number_datatype_coercion
|
80
111
|
else
|
81
112
|
:decimal
|
82
113
|
end
|
@@ -104,6 +135,15 @@ module ActiveRecord
|
|
104
135
|
end
|
105
136
|
end
|
106
137
|
|
138
|
+
def self.extract_value_from_default(default)
|
139
|
+
case default
|
140
|
+
when String
|
141
|
+
default.gsub(/''/, "'")
|
142
|
+
else
|
143
|
+
default
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
107
147
|
def guess_date_or_time(value)
|
108
148
|
value.respond_to?(:hour) && (value.hour == 0 and value.min == 0 and value.sec == 0) ?
|
109
149
|
Date.new(value.year, value.month, value.day) : value
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
module ConnectionAdapters #:nodoc:
|
3
|
+
module OracleEnhancedColumnDumper #:nodoc:
|
4
|
+
|
5
|
+
def self.included(base) #:nodoc:
|
6
|
+
base.class_eval do
|
7
|
+
private
|
8
|
+
alias_method_chain :column_spec, :oracle_enhanced
|
9
|
+
alias_method_chain :prepare_column_options, :oracle_enhanced
|
10
|
+
alias_method_chain :migration_keys, :oracle_enhanced
|
11
|
+
|
12
|
+
def oracle_enhanced_adapter?
|
13
|
+
# return original method if not using 'OracleEnhanced'
|
14
|
+
if (rails_env = defined?(Rails.env) ? Rails.env : (defined?(RAILS_ENV) ? RAILS_ENV : nil)) &&
|
15
|
+
ActiveRecord::Base.configurations[rails_env] &&
|
16
|
+
ActiveRecord::Base.configurations[rails_env]['adapter'] != 'oracle_enhanced'
|
17
|
+
return false
|
18
|
+
else
|
19
|
+
return true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def column_spec_with_oracle_enhanced(column, types)
|
26
|
+
# return original method if not using 'OracleEnhanced'
|
27
|
+
return column_spec_without_oracle_enhanced(column, types) unless oracle_enhanced_adapter?
|
28
|
+
|
29
|
+
spec = prepare_column_options(column, types)
|
30
|
+
(spec.keys - [:name, :type]).each do |k|
|
31
|
+
key_s = (k == :virtual_type ? "type: " : "#{k.to_s}: ")
|
32
|
+
spec[k] = key_s + spec[k]
|
33
|
+
end
|
34
|
+
spec
|
35
|
+
end
|
36
|
+
|
37
|
+
def prepare_column_options_with_oracle_enhanced(column, types)
|
38
|
+
# return original method if not using 'OracleEnhanced'
|
39
|
+
return prepare_column_options_without_oracle_enhanced(column, types) unless oracle_enhanced_adapter?
|
40
|
+
|
41
|
+
spec = {}
|
42
|
+
|
43
|
+
spec[:name] = column.name.inspect
|
44
|
+
spec[:type] = column.virtual? ? 'virtual' : column.type.to_s
|
45
|
+
spec[:limit] = column.limit.inspect if column.limit != types[column.type][:limit] && column.type != :decimal
|
46
|
+
spec[:precision] = column.precision.inspect if !column.precision.nil?
|
47
|
+
spec[:scale] = column.scale.inspect if !column.scale.nil?
|
48
|
+
spec[:null] = 'false' if !column.null
|
49
|
+
spec[:as] = column.virtual_column_data_default if column.virtual?
|
50
|
+
spec[:default] = default_string(column.default) if column.has_default? && !column.virtual?
|
51
|
+
|
52
|
+
if column.virtual?
|
53
|
+
# Supports backwards compatibility with older OracleEnhancedAdapter versions where 'NUMBER' virtual column type is not included in dump
|
54
|
+
if column.sql_type != "NUMBER" || ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.number_datatype_coercion != :decimal
|
55
|
+
spec[:virtual_type] = column.type.inspect
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
spec
|
60
|
+
end
|
61
|
+
|
62
|
+
def migration_keys_with_oracle_enhanced
|
63
|
+
# TODO `& column_specs.map(&:keys).flatten` should be exetuted here
|
64
|
+
# return original method if not using 'OracleEnhanced'
|
65
|
+
return migration_keys_without_oracle_enhanced unless oracle_enhanced_adapter?
|
66
|
+
|
67
|
+
[:name, :limit, :precision, :scale, :default, :null, :as, :virtual_type]
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
ActiveRecord::ConnectionAdapters::ColumnDumper.class_eval do
|
76
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedColumnDumper
|
77
|
+
end
|
@@ -4,18 +4,13 @@ module ActiveRecord
|
|
4
4
|
class OracleEnhancedConnection #:nodoc:
|
5
5
|
|
6
6
|
def self.create(config)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def after_initialize(config)
|
15
|
-
schema = config[:schema]
|
16
|
-
unless schema.blank?
|
17
|
-
exec "alter session set current_schema = #{schema}"
|
18
|
-
@owner = schema.upcase
|
7
|
+
case ORACLE_ENHANCED_CONNECTION
|
8
|
+
when :oci
|
9
|
+
OracleEnhancedOCIConnection.new(config)
|
10
|
+
when :jdbc
|
11
|
+
OracleEnhancedJDBCConnection.new(config)
|
12
|
+
else
|
13
|
+
nil
|
19
14
|
end
|
20
15
|
end
|
21
16
|
|
@@ -103,22 +98,11 @@ module ActiveRecord
|
|
103
98
|
result.map { |r| r.values.first }
|
104
99
|
end
|
105
100
|
|
106
|
-
|
107
|
-
protected
|
108
|
-
def self.create_connection(config)
|
109
|
-
case ORACLE_ENHANCED_CONNECTION
|
110
|
-
when :oci
|
111
|
-
OracleEnhancedOCIConnection.new(config)
|
112
|
-
when :jdbc
|
113
|
-
OracleEnhancedJDBCConnection.new(config)
|
114
|
-
else
|
115
|
-
nil
|
116
|
-
end
|
117
|
-
end
|
118
101
|
end
|
119
102
|
|
120
103
|
class OracleEnhancedConnectionException < StandardError #:nodoc:
|
121
104
|
end
|
105
|
+
|
122
106
|
end
|
123
107
|
end
|
124
108
|
|
@@ -329,19 +329,10 @@ module ActiveRecord
|
|
329
329
|
|
330
330
|
module ContextIndexClassMethods
|
331
331
|
# Add context index condition.
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
score_label
|
336
|
-
where("CONTAINS(#{connection.quote_column_name(column)}, ?, #{score_label}) > 0", query).
|
337
|
-
order("SCORE(#{score_label}) DESC")
|
338
|
-
end
|
339
|
-
when 2
|
340
|
-
def contains(column, query, options ={})
|
341
|
-
score_label = options[:label].to_i || 1
|
342
|
-
scoped(:conditions => ["CONTAINS(#{connection.quote_column_name(column)}, ?, #{score_label}) > 0", query],
|
343
|
-
:order => "SCORE(#{score_label}) DESC")
|
344
|
-
end
|
332
|
+
def contains(column, query, options ={})
|
333
|
+
score_label = options[:label].to_i || 1
|
334
|
+
where("CONTAINS(#{connection.quote_column_name(column)}, ?, #{score_label}) > 0", query).
|
335
|
+
order("SCORE(#{score_label}) DESC")
|
345
336
|
end
|
346
337
|
end
|
347
338
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class OracleEnhancedAdapter
|
4
|
+
class DatabaseTasks
|
5
|
+
delegate :connection, :establish_connection, :to => ActiveRecord::Base
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
print "Please provide the SYSTEM password for your Oracle installation\n>"
|
13
|
+
system_password = $stdin.gets.strip
|
14
|
+
establish_connection(@config.merge('username' => 'SYSTEM', 'password' => system_password))
|
15
|
+
begin
|
16
|
+
connection.execute "CREATE USER #{@config['username']} IDENTIFIED BY #{@config['password']}"
|
17
|
+
rescue => e
|
18
|
+
if e.message =~ /ORA-01920/ # user name conflicts with another user or role name
|
19
|
+
connection.execute "ALTER USER #{@config['username']} IDENTIFIED BY #{@config['password']}"
|
20
|
+
else
|
21
|
+
raise e
|
22
|
+
end
|
23
|
+
end
|
24
|
+
connection.execute "GRANT unlimited tablespace TO #{@config['username']}"
|
25
|
+
connection.execute "GRANT create session TO #{@config['username']}"
|
26
|
+
connection.execute "GRANT create table TO #{@config['username']}"
|
27
|
+
connection.execute "GRANT create sequence TO #{@config['username']}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def drop
|
31
|
+
establish_connection(@config)
|
32
|
+
connection.execute_structure_dump(connection.full_drop)
|
33
|
+
end
|
34
|
+
|
35
|
+
def purge
|
36
|
+
drop
|
37
|
+
connection.execute('PURGE RECYCLEBIN') rescue nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def structure_dump(filename)
|
41
|
+
establish_connection(@config)
|
42
|
+
File.open(filename, 'w:utf-8') { |f| f << connection.structure_dump }
|
43
|
+
if connection.supports_migrations?
|
44
|
+
File.open(filename, 'a') { |f| f << connection.dump_schema_information }
|
45
|
+
end
|
46
|
+
if @config['structure_dump'] == 'db_stored_code'
|
47
|
+
File.open(filename, 'a') { |f| f << connection.structure_dump_db_stored_code }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def structure_load(filename)
|
52
|
+
establish_connection(@config)
|
53
|
+
connection.execute_structure_dump(File.read(filename))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
ActiveRecord::Tasks::DatabaseTasks.register_task(/(oci|oracle)/, ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter::DatabaseTasks)
|
61
|
+
|
@@ -4,20 +4,22 @@ module ActiveRecord #:nodoc:
|
|
4
4
|
|
5
5
|
module InstanceMethods #:nodoc:
|
6
6
|
private
|
7
|
-
|
7
|
+
|
8
8
|
def _field_changed?(attr, old, value)
|
9
9
|
if column = column_for_attribute(attr)
|
10
10
|
# Added also :decimal type
|
11
|
-
if (
|
12
|
-
# For nullable integer columns, NULL gets stored in database for blank (i.e. '') values.
|
11
|
+
if ([:integer, :decimal, :float].include? column.type) && column.null && (old.nil? || old == 0) && value.blank?
|
12
|
+
# For nullable integer/decimal/float columns, NULL gets stored in database for blank (i.e. '') values.
|
13
13
|
# Hence we don't record it as a change if the value changes from nil to ''.
|
14
14
|
# If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
|
15
15
|
# be typecast back to 0 (''.to_i => 0)
|
16
16
|
value = nil
|
17
|
-
# Oracle stores empty string '' as NULL
|
18
|
-
# therefore need to convert empty string value to nil if old value is nil
|
19
17
|
elsif column.type == :string && column.null && old.nil?
|
18
|
+
# Oracle stores empty string '' as NULL
|
19
|
+
# therefore need to convert empty string value to nil if old value is nil
|
20
20
|
value = nil if value == ''
|
21
|
+
elsif old == 0 && value.is_a?(String) && value.present? && non_zero?(value)
|
22
|
+
value = nil
|
21
23
|
else
|
22
24
|
value = column.type_cast(value)
|
23
25
|
end
|
@@ -25,7 +27,11 @@ module ActiveRecord #:nodoc:
|
|
25
27
|
|
26
28
|
old != value
|
27
29
|
end
|
28
|
-
|
30
|
+
|
31
|
+
def non_zero?(value)
|
32
|
+
value !~ /\A0+(\.0+)?\z/
|
33
|
+
end
|
34
|
+
|
29
35
|
end
|
30
36
|
|
31
37
|
end
|
@@ -35,10 +41,5 @@ end
|
|
35
41
|
if ActiveRecord::Base.method_defined?(:changed?)
|
36
42
|
ActiveRecord::Base.class_eval do
|
37
43
|
include ActiveRecord::ConnectionAdapters::OracleEnhancedDirty::InstanceMethods
|
38
|
-
# Starting with rails 3.2.9 the method #field_changed?
|
39
|
-
# was renamed to #_field_changed?
|
40
|
-
if private_method_defined?(:field_changed?)
|
41
|
-
alias_method :field_changed?, :_field_changed?
|
42
|
-
end
|
43
44
|
end
|
44
|
-
end
|
45
|
+
end
|
@@ -2,24 +2,36 @@ begin
|
|
2
2
|
require "java"
|
3
3
|
require "jruby"
|
4
4
|
|
5
|
-
# ojdbc6.jar or ojdbc5.jar file should be in
|
5
|
+
# ojdbc7.jar, ojdbc6.jar or ojdbc5.jar file should be in application ./lib directory or in load path or in ENV['PATH']
|
6
6
|
|
7
7
|
java_version = java.lang.System.getProperty("java.version")
|
8
|
-
|
9
|
-
|
10
|
-
elsif java_version
|
11
|
-
|
8
|
+
ojdbc_jars = if java_version =~ /^1.5/
|
9
|
+
%w(ojdbc5.jar)
|
10
|
+
elsif java_version =~ /^1.6/
|
11
|
+
%w(ojdbc6.jar)
|
12
|
+
elsif java_version >= '1.7'
|
13
|
+
# Oracle 11g client ojdbc6.jar is also compatible with Java 1.7
|
14
|
+
# Oracle 12c client provides new ojdbc7.jar
|
15
|
+
%w(ojdbc7.jar ojdbc6.jar)
|
12
16
|
else
|
13
17
|
nil
|
14
18
|
end
|
15
19
|
|
16
|
-
|
20
|
+
if ojdbc_jars && ENV_JAVA['java.class.path'] !~ Regexp.new(ojdbc_jars.join('|'))
|
17
21
|
# On Unix environment variable should be PATH, on Windows it is sometimes Path
|
18
|
-
env_path = (ENV["PATH"] || ENV["Path"] || '').split(
|
22
|
+
env_path = (ENV["PATH"] || ENV["Path"] || '').split(File::PATH_SEPARATOR)
|
19
23
|
# Look for JDBC driver at first in lib subdirectory (application specific JDBC file version)
|
20
24
|
# then in Ruby load path and finally in environment PATH
|
21
|
-
|
22
|
-
|
25
|
+
['./lib'].concat($LOAD_PATH).concat(env_path).detect do |dir|
|
26
|
+
# check any compatible JDBC driver in the priority order
|
27
|
+
ojdbc_jars.any? do |ojdbc_jar|
|
28
|
+
if File.exists?(file_path = File.join(dir, ojdbc_jar))
|
29
|
+
puts "WARNING: JDK #{java_version} is not officially supported by #{ojdbc_jar}" if java_version >= '1.8'
|
30
|
+
puts "See http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#01_03 for supported versions"
|
31
|
+
require file_path
|
32
|
+
true
|
33
|
+
end
|
34
|
+
end
|
23
35
|
end
|
24
36
|
end
|
25
37
|
|
@@ -33,7 +45,7 @@ begin
|
|
33
45
|
|
34
46
|
rescue LoadError, NameError
|
35
47
|
# JDBC driver is unavailable.
|
36
|
-
raise LoadError, "ERROR: ActiveRecord oracle_enhanced adapter could not load Oracle JDBC driver. Please install #{
|
48
|
+
raise LoadError, "ERROR: ActiveRecord oracle_enhanced adapter could not load Oracle JDBC driver. Please install #{ojdbc_jars ? ojdbc_jars.join(' or ') : "Oracle JDBC"} library."
|
37
49
|
end
|
38
50
|
|
39
51
|
|
@@ -86,7 +98,7 @@ module ActiveRecord
|
|
86
98
|
@raw_connection = @raw_connection.innermost_delegate
|
87
99
|
elsif @raw_connection.respond_to?(:getUnderlyingConnection)
|
88
100
|
@pooled_connection = @raw_connection
|
89
|
-
@raw_connection = @raw_connection.underlying_connection
|
101
|
+
@raw_connection = @raw_connection.underlying_connection
|
90
102
|
end
|
91
103
|
|
92
104
|
config[:driver] ||= @raw_connection.meta_data.connection.java_class.name
|
@@ -149,8 +161,14 @@ module ActiveRecord
|
|
149
161
|
|
150
162
|
self.autocommit = true
|
151
163
|
|
152
|
-
|
153
|
-
|
164
|
+
schema = config[:schema] && config[:schema].to_s
|
165
|
+
if schema.blank?
|
166
|
+
# default schema owner
|
167
|
+
@owner = username.upcase unless username.nil?
|
168
|
+
else
|
169
|
+
exec "alter session set current_schema = #{schema}"
|
170
|
+
@owner = schema
|
171
|
+
end
|
154
172
|
|
155
173
|
@raw_connection
|
156
174
|
end
|
@@ -285,7 +303,7 @@ module ActiveRecord
|
|
285
303
|
# else
|
286
304
|
# nil
|
287
305
|
# end
|
288
|
-
|
306
|
+
|
289
307
|
# Workaround with CallableStatement
|
290
308
|
s = @raw_connection.prepareCall("BEGIN #{sql}; END;")
|
291
309
|
s.registerOutParameter(1, java.sql.Types::BIGINT)
|
@@ -309,7 +327,8 @@ module ActiveRecord
|
|
309
327
|
@raw_statement = raw_statement
|
310
328
|
end
|
311
329
|
|
312
|
-
def bind_param(position, value,
|
330
|
+
def bind_param(position, value, column = nil)
|
331
|
+
col_type = column && column.type
|
313
332
|
java_value = ruby_to_java_value(value, col_type)
|
314
333
|
case value
|
315
334
|
when Integer
|
@@ -336,10 +355,14 @@ module ActiveRecord
|
|
336
355
|
when Time
|
337
356
|
@raw_statement.setTimestamp(position, java_value)
|
338
357
|
when NilClass
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
358
|
+
if column && column.object_type?
|
359
|
+
@raw_statement.setNull(position, java.sql.Types::STRUCT, column.sql_type)
|
360
|
+
else
|
361
|
+
# TODO: currently nil is always bound as NULL with VARCHAR type.
|
362
|
+
# When nils will actually be used by ActiveRecord as bound parameters
|
363
|
+
# then need to pass actual column type.
|
364
|
+
@raw_statement.setNull(position, java.sql.Types::VARCHAR)
|
365
|
+
end
|
343
366
|
else
|
344
367
|
raise ArgumentError, "Don't know how to bind variable with type #{value.class}"
|
345
368
|
end
|