activerecord-oracle_enhanced-adapter 1.7.3 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.md +288 -0
- data/README.md +44 -0
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +7 -63
- data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +6 -52
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +13 -16
- data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +117 -119
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +33 -27
- data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +10 -10
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +59 -77
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +0 -4
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +56 -82
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +4 -4
- data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +77 -77
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +16 -45
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +60 -65
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +33 -51
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +149 -162
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +119 -122
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +3 -4
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +69 -107
- data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +315 -538
- data/lib/active_record/oracle_enhanced/type/boolean.rb +7 -11
- data/lib/active_record/oracle_enhanced/type/integer.rb +4 -5
- data/lib/active_record/oracle_enhanced/type/json.rb +8 -0
- data/lib/active_record/oracle_enhanced/type/national_character_string.rb +1 -2
- data/lib/active_record/oracle_enhanced/type/raw.rb +2 -4
- data/lib/active_record/oracle_enhanced/type/string.rb +2 -3
- data/lib/active_record/oracle_enhanced/type/text.rb +2 -4
- data/lib/active_record/oracle_enhanced/type/timestamptz.rb +23 -0
- data/lib/activerecord-oracle_enhanced-adapter.rb +14 -13
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +129 -166
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +50 -33
- data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +44 -42
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +283 -378
- data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +14 -7
- data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +5 -7
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +118 -127
- data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +2 -3
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +74 -78
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +68 -83
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +308 -321
- data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +103 -48
- data/spec/spec_config.yaml.template +11 -0
- data/spec/spec_helper.rb +59 -60
- data/spec/support/alter_system_user_password.sql +2 -0
- data/spec/support/create_oracle_enhanced_users.sql +31 -0
- metadata +25 -25
- data/.rspec +0 -2
- data/Gemfile +0 -22
- data/RUNNING_TESTS.md +0 -50
- data/Rakefile +0 -45
- data/activerecord-oracle_enhanced-adapter.gemspec +0 -95
- data/lib/active_record/connection_adapters/oracle_enhanced/cpk.rb +0 -21
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +0 -113
|
@@ -2,27 +2,26 @@ begin
|
|
|
2
2
|
require "java"
|
|
3
3
|
require "jruby"
|
|
4
4
|
|
|
5
|
-
# ojdbc7.jar
|
|
5
|
+
# ojdbc7.jar or ojdbc6.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
|
-
|
|
11
|
-
|
|
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)
|
|
16
|
-
else
|
|
17
|
-
nil
|
|
8
|
+
# Dropping Java SE 6(1.6) or older version without deprecation cycle.
|
|
9
|
+
# Rails 5.0 already requires CRuby 2.2.2 or higher and JRuby 9.0 supporging CRuby 2.2 requires Java SE 7.
|
|
10
|
+
if java_version < "1.7"
|
|
11
|
+
raise "ERROR: Java SE 6 or older version is not supported. Upgrade Java version to Java SE 7 or higher"
|
|
18
12
|
end
|
|
19
13
|
|
|
20
|
-
|
|
14
|
+
# Oracle 11g client ojdbc6.jar is also compatible with Java 1.7
|
|
15
|
+
# Oracle 12c Release 1 client provides ojdbc7.jar
|
|
16
|
+
# Oracle 12c Release 2 client provides ojdbc8.jar
|
|
17
|
+
ojdbc_jars = %w(ojdbc8.jar ojdbc7.jar ojdbc6.jar)
|
|
18
|
+
|
|
19
|
+
if ENV_JAVA["java.class.path"] !~ Regexp.new(ojdbc_jars.join("|"))
|
|
21
20
|
# On Unix environment variable should be PATH, on Windows it is sometimes Path
|
|
22
|
-
env_path = (ENV["PATH"] || ENV["Path"] ||
|
|
21
|
+
env_path = (ENV["PATH"] || ENV["Path"] || "").split(File::PATH_SEPARATOR)
|
|
23
22
|
# Look for JDBC driver at first in lib subdirectory (application specific JDBC file version)
|
|
24
23
|
# then in Ruby load path and finally in environment PATH
|
|
25
|
-
[
|
|
24
|
+
["./lib"].concat($LOAD_PATH).concat(env_path).detect do |dir|
|
|
26
25
|
# check any compatible JDBC driver in the priority order
|
|
27
26
|
ojdbc_jars.any? do |ojdbc_jar|
|
|
28
27
|
if File.exists?(file_path = File.join(dir, ojdbc_jar))
|
|
@@ -43,16 +42,13 @@ begin
|
|
|
43
42
|
|
|
44
43
|
rescue LoadError, NameError
|
|
45
44
|
# JDBC driver is unavailable.
|
|
46
|
-
raise LoadError, "ERROR: ActiveRecord oracle_enhanced adapter could not load Oracle JDBC driver. Please install #{ojdbc_jars
|
|
45
|
+
raise LoadError, "ERROR: ActiveRecord oracle_enhanced adapter could not load Oracle JDBC driver. Please install #{ojdbc_jars.join(' or ') } library."
|
|
47
46
|
end
|
|
48
47
|
|
|
49
|
-
|
|
50
48
|
module ActiveRecord
|
|
51
49
|
module ConnectionAdapters
|
|
52
|
-
|
|
53
50
|
# JDBC database interface for JRuby
|
|
54
51
|
class OracleEnhancedJDBCConnection < OracleEnhancedConnection #:nodoc:
|
|
55
|
-
|
|
56
52
|
attr_accessor :active
|
|
57
53
|
alias :active? :active
|
|
58
54
|
|
|
@@ -77,7 +73,7 @@ module ActiveRecord
|
|
|
77
73
|
|
|
78
74
|
# tomcat needs first lookup method, oc4j (and maybe other application servers) need second method
|
|
79
75
|
begin
|
|
80
|
-
env = ctx.lookup(
|
|
76
|
+
env = ctx.lookup("java:/comp/env")
|
|
81
77
|
ds = env.lookup(jndi)
|
|
82
78
|
rescue
|
|
83
79
|
ds = ctx.lookup(jndi)
|
|
@@ -105,12 +101,13 @@ module ActiveRecord
|
|
|
105
101
|
# to_s needed if username, password or database is specified as number in database.yml file
|
|
106
102
|
username = config[:username] && config[:username].to_s
|
|
107
103
|
password = config[:password] && config[:password].to_s
|
|
108
|
-
database = config[:database] && config[:database].to_s ||
|
|
104
|
+
database = config[:database] && config[:database].to_s || "XE"
|
|
109
105
|
host, port = config[:host], config[:port]
|
|
110
106
|
privilege = config[:privilege] && config[:privilege].to_s
|
|
111
107
|
|
|
112
|
-
# connection using TNS alias
|
|
113
|
-
|
|
108
|
+
# connection using TNS alias, or connection-string from DATABASE_URL
|
|
109
|
+
using_tns_alias = !host && !config[:url] && ENV["TNS_ADMIN"]
|
|
110
|
+
if database && (using_tns_alias || host == "connection-string")
|
|
114
111
|
url = "jdbc:oracle:thin:@#{database}"
|
|
115
112
|
else
|
|
116
113
|
unless database.match(/^(\:|\/)/)
|
|
@@ -122,7 +119,7 @@ module ActiveRecord
|
|
|
122
119
|
|
|
123
120
|
prefetch_rows = config[:prefetch_rows] || 100
|
|
124
121
|
# get session time_zone from configuration or from TZ environment variable
|
|
125
|
-
time_zone = config[:time_zone] || ENV[
|
|
122
|
+
time_zone = config[:time_zone] || ENV["TZ"] || java.util.TimeZone.default.getID
|
|
126
123
|
|
|
127
124
|
properties = java.util.Properties.new
|
|
128
125
|
properties.put("user", username)
|
|
@@ -140,13 +137,17 @@ module ActiveRecord
|
|
|
140
137
|
end
|
|
141
138
|
|
|
142
139
|
# Set session time zone to current time zone
|
|
143
|
-
|
|
140
|
+
if ActiveRecord::Base.default_timezone == :local
|
|
141
|
+
@raw_connection.setSessionTimeZone(time_zone)
|
|
142
|
+
elsif ActiveRecord::Base.default_timezone == :utc
|
|
143
|
+
@raw_connection.setSessionTimeZone("UTC")
|
|
144
|
+
end
|
|
144
145
|
|
|
145
146
|
# Set default number of rows to prefetch
|
|
146
147
|
# @raw_connection.setDefaultRowPrefetch(prefetch_rows) if prefetch_rows
|
|
147
148
|
end
|
|
148
149
|
|
|
149
|
-
cursor_sharing = config[:cursor_sharing] ||
|
|
150
|
+
cursor_sharing = config[:cursor_sharing] || "force"
|
|
150
151
|
exec "alter session set cursor_sharing = #{cursor_sharing}"
|
|
151
152
|
|
|
152
153
|
# Initialize NLS parameters
|
|
@@ -329,7 +330,7 @@ module ActiveRecord
|
|
|
329
330
|
@raw_statement = raw_statement
|
|
330
331
|
end
|
|
331
332
|
|
|
332
|
-
def bind_params(
|
|
333
|
+
def bind_params(*bind_vars)
|
|
333
334
|
index = 1
|
|
334
335
|
bind_vars.flatten.each do |var|
|
|
335
336
|
if Hash === var
|
|
@@ -341,17 +342,7 @@ module ActiveRecord
|
|
|
341
342
|
end
|
|
342
343
|
end
|
|
343
344
|
|
|
344
|
-
def bind_param(position, value
|
|
345
|
-
if column
|
|
346
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
|
347
|
-
*******************************************************
|
|
348
|
-
Passing a column to `bind_param` will be deprecated.
|
|
349
|
-
`type_casted_binds` should be already type casted
|
|
350
|
-
so that `bind_param` should not need to know column.
|
|
351
|
-
*******************************************************
|
|
352
|
-
MSG
|
|
353
|
-
end
|
|
354
|
-
|
|
345
|
+
def bind_param(position, value)
|
|
355
346
|
case value
|
|
356
347
|
when Integer
|
|
357
348
|
@raw_statement.setLong(position, value)
|
|
@@ -375,17 +366,13 @@ module ActiveRecord
|
|
|
375
366
|
when Java::JavaSql::Timestamp
|
|
376
367
|
@raw_statement.setTimestamp(position, value)
|
|
377
368
|
when Time
|
|
378
|
-
|
|
379
|
-
@raw_statement.setTimestamp(position,
|
|
369
|
+
new_value = Java::java.sql.Timestamp.new(value.year - 1900, value.month - 1, value.day, value.hour, value.min, value.sec, value.usec * 1000)
|
|
370
|
+
@raw_statement.setTimestamp(position, new_value)
|
|
380
371
|
when NilClass
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
# When nils will actually be used by ActiveRecord as bound parameters
|
|
386
|
-
# then need to pass actual column type.
|
|
387
|
-
@raw_statement.setNull(position, java.sql.Types::VARCHAR)
|
|
388
|
-
end
|
|
372
|
+
# TODO: currently nil is always bound as NULL with VARCHAR type.
|
|
373
|
+
# When nils will actually be used by ActiveRecord as bound parameters
|
|
374
|
+
# then need to pass actual column type.
|
|
375
|
+
@raw_statement.setNull(position, java.sql.Types::VARCHAR)
|
|
389
376
|
else
|
|
390
377
|
raise ArgumentError, "Don't know how to bind variable with type #{value.class}"
|
|
391
378
|
end
|
|
@@ -413,21 +400,21 @@ module ActiveRecord
|
|
|
413
400
|
end
|
|
414
401
|
|
|
415
402
|
def column_types
|
|
416
|
-
@column_types ||= (1..metadata.getColumnCount).map{|i| metadata.getColumnTypeName(i).to_sym}
|
|
403
|
+
@column_types ||= (1..metadata.getColumnCount).map { |i| metadata.getColumnTypeName(i).to_sym }
|
|
417
404
|
end
|
|
418
405
|
|
|
419
406
|
def column_names
|
|
420
|
-
@column_names ||= (1..metadata.getColumnCount).map{|i| metadata.getColumnName(i)}
|
|
407
|
+
@column_names ||= (1..metadata.getColumnCount).map { |i| metadata.getColumnName(i) }
|
|
421
408
|
end
|
|
422
409
|
alias :get_col_names :column_names
|
|
423
410
|
|
|
424
|
-
def fetch(options={})
|
|
411
|
+
def fetch(options = {})
|
|
425
412
|
if @raw_result_set.next
|
|
426
413
|
get_lob_value = options[:get_lob_value]
|
|
427
414
|
row_values = []
|
|
428
415
|
column_types.each_with_index do |column_type, i|
|
|
429
416
|
row_values <<
|
|
430
|
-
@connection.get_ruby_value_from_result_set(@raw_result_set, i+1, column_type, get_lob_value)
|
|
417
|
+
@connection.get_ruby_value_from_result_set(@raw_result_set, i + 1, column_type, get_lob_value)
|
|
431
418
|
end
|
|
432
419
|
row_values
|
|
433
420
|
else
|
|
@@ -451,7 +438,6 @@ module ActiveRecord
|
|
|
451
438
|
def close
|
|
452
439
|
@raw_statement.close
|
|
453
440
|
end
|
|
454
|
-
|
|
455
441
|
end
|
|
456
442
|
|
|
457
443
|
def select(sql, name = nil, return_column_names = false)
|
|
@@ -472,14 +458,14 @@ module ActiveRecord
|
|
|
472
458
|
|
|
473
459
|
cols_types_index = (1..column_count).map do |i|
|
|
474
460
|
col_name = oracle_downcase(metadata.getColumnName(i))
|
|
475
|
-
next if col_name ==
|
|
461
|
+
next if col_name == "raw_rnum_"
|
|
476
462
|
column_hash[col_name] = nil
|
|
477
463
|
[col_name, metadata.getColumnTypeName(i).to_sym, i]
|
|
478
464
|
end
|
|
479
465
|
cols_types_index.delete(nil)
|
|
480
466
|
|
|
481
467
|
rows = []
|
|
482
|
-
get_lob_value = !(name ==
|
|
468
|
+
get_lob_value = !(name == "Writable Large Object")
|
|
483
469
|
|
|
484
470
|
while rset.next
|
|
485
471
|
hash = column_hash.dup
|
|
@@ -499,7 +485,7 @@ module ActiveRecord
|
|
|
499
485
|
if is_binary
|
|
500
486
|
lob.setBytes(1, value.to_java_bytes)
|
|
501
487
|
else
|
|
502
|
-
lob.setString(1,value)
|
|
488
|
+
lob.setString(1, value)
|
|
503
489
|
end
|
|
504
490
|
end
|
|
505
491
|
|
|
@@ -524,17 +510,15 @@ module ActiveRecord
|
|
|
524
510
|
else
|
|
525
511
|
BigDecimal.new(d.stringValue)
|
|
526
512
|
end
|
|
513
|
+
when :BINARY_FLOAT
|
|
514
|
+
rset.getFloat(i)
|
|
527
515
|
when :VARCHAR2, :CHAR, :LONG, :NVARCHAR2, :NCHAR
|
|
528
516
|
rset.getString(i)
|
|
529
517
|
when :DATE
|
|
530
518
|
if dt = rset.getDATE(i)
|
|
531
519
|
d = dt.dateValue
|
|
532
520
|
t = dt.timeValue
|
|
533
|
-
|
|
534
|
-
Date.new(d.year + 1900, d.month + 1, d.date)
|
|
535
|
-
else
|
|
536
|
-
Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
|
|
537
|
-
end
|
|
521
|
+
Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
|
|
538
522
|
else
|
|
539
523
|
nil
|
|
540
524
|
end
|
|
@@ -548,7 +532,7 @@ module ActiveRecord
|
|
|
548
532
|
get_lob_value ? lob_to_ruby_value(rset.getBlob(i)) : rset.getBlob(i)
|
|
549
533
|
when :RAW
|
|
550
534
|
raw_value = rset.getRAW(i)
|
|
551
|
-
raw_value && raw_value.getBytes.to_a.pack(
|
|
535
|
+
raw_value && raw_value.getBytes.to_a.pack("C*")
|
|
552
536
|
else
|
|
553
537
|
nil
|
|
554
538
|
end
|
|
@@ -556,24 +540,22 @@ module ActiveRecord
|
|
|
556
540
|
|
|
557
541
|
private
|
|
558
542
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
543
|
+
def lob_to_ruby_value(val)
|
|
544
|
+
case val
|
|
545
|
+
when ::Java::OracleSql::CLOB
|
|
546
|
+
if val.isEmptyLob
|
|
547
|
+
nil
|
|
548
|
+
else
|
|
549
|
+
val.getSubString(1, val.length)
|
|
550
|
+
end
|
|
551
|
+
when ::Java::OracleSql::BLOB
|
|
552
|
+
if val.isEmptyLob
|
|
553
|
+
nil
|
|
554
|
+
else
|
|
555
|
+
String.from_java_bytes(val.getBytes(1, val.length))
|
|
556
|
+
end
|
|
572
557
|
end
|
|
573
558
|
end
|
|
574
|
-
end
|
|
575
|
-
|
|
576
559
|
end
|
|
577
|
-
|
|
578
560
|
end
|
|
579
561
|
end
|
|
@@ -12,10 +12,6 @@ module ActiveRecord
|
|
|
12
12
|
clob = Java::OracleSql::CLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::CLOB::DURATION_SESSION)
|
|
13
13
|
clob.setString(1, value.to_s)
|
|
14
14
|
clob
|
|
15
|
-
when Date, DateTime
|
|
16
|
-
Java::oracle.sql.DATE.new(value.strftime("%Y-%m-%d %H:%M:%S"))
|
|
17
|
-
when Time
|
|
18
|
-
Java::java.sql.Timestamp.new(value.year-1900, value.month-1, value.day, value.hour, value.min, value.sec, value.usec * 1000)
|
|
19
15
|
else
|
|
20
16
|
super
|
|
21
17
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "delegate"
|
|
2
2
|
|
|
3
3
|
begin
|
|
4
4
|
require "oci8"
|
|
@@ -11,17 +11,15 @@ end
|
|
|
11
11
|
|
|
12
12
|
# check ruby-oci8 version
|
|
13
13
|
required_oci8_version = [2, 2, 0]
|
|
14
|
-
oci8_version_ints = OCI8::VERSION.scan(/\d+/).map{|s| s.to_i}
|
|
14
|
+
oci8_version_ints = OCI8::VERSION.scan(/\d+/).map { |s| s.to_i }
|
|
15
15
|
if (oci8_version_ints <=> required_oci8_version) < 0
|
|
16
16
|
raise LoadError, "ERROR: ruby-oci8 version #{OCI8::VERSION} is too old. Please install ruby-oci8 version #{required_oci8_version.join('.')} or later."
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
module ActiveRecord
|
|
20
20
|
module ConnectionAdapters
|
|
21
|
-
|
|
22
21
|
# OCI database interface for MRI
|
|
23
22
|
class OracleEnhancedOCIConnection < OracleEnhancedConnection #:nodoc:
|
|
24
|
-
|
|
25
23
|
def initialize(config)
|
|
26
24
|
@raw_connection = OCI8EnhancedAutoRecover.new(config, OracleEnhancedOCIFactory)
|
|
27
25
|
# default schema owner
|
|
@@ -100,9 +98,9 @@ module ActiveRecord
|
|
|
100
98
|
# and return :insert_id value
|
|
101
99
|
def exec_with_returning(sql)
|
|
102
100
|
cursor = @raw_connection.parse(sql)
|
|
103
|
-
cursor.bind_param(
|
|
101
|
+
cursor.bind_param(":insert_id", nil, Integer)
|
|
104
102
|
cursor.exec
|
|
105
|
-
cursor[
|
|
103
|
+
cursor[":insert_id"]
|
|
106
104
|
ensure
|
|
107
105
|
cursor.close rescue nil
|
|
108
106
|
end
|
|
@@ -117,7 +115,7 @@ module ActiveRecord
|
|
|
117
115
|
@raw_cursor = raw_cursor
|
|
118
116
|
end
|
|
119
117
|
|
|
120
|
-
def bind_params(
|
|
118
|
+
def bind_params(*bind_vars)
|
|
121
119
|
index = 1
|
|
122
120
|
bind_vars.flatten.each do |var|
|
|
123
121
|
if Hash === var
|
|
@@ -129,30 +127,16 @@ module ActiveRecord
|
|
|
129
127
|
end
|
|
130
128
|
end
|
|
131
129
|
|
|
132
|
-
def bind_param(position, value
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
MSG
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
if column && column.object_type?
|
|
144
|
-
@raw_cursor.bind_param(position, value, :named_type, column.sql_type)
|
|
130
|
+
def bind_param(position, value)
|
|
131
|
+
case value
|
|
132
|
+
when ActiveRecord::OracleEnhanced::Type::Raw
|
|
133
|
+
@raw_cursor.bind_param(position, ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting.encode_raw(value))
|
|
134
|
+
when ActiveModel::Type::Decimal
|
|
135
|
+
@raw_cursor.bind_param(position, BigDecimal.new(value.to_s))
|
|
136
|
+
when NilClass
|
|
137
|
+
@raw_cursor.bind_param(position, nil, String)
|
|
145
138
|
else
|
|
146
|
-
|
|
147
|
-
when ActiveRecord::OracleEnhanced::Type::Raw
|
|
148
|
-
@raw_cursor.bind_param(position, ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting.encode_raw(value))
|
|
149
|
-
when ActiveModel::Type::Decimal
|
|
150
|
-
@raw_cursor.bind_param(position, BigDecimal.new(value.to_s))
|
|
151
|
-
when NilClass
|
|
152
|
-
@raw_cursor.bind_param(position, nil, String)
|
|
153
|
-
else
|
|
154
|
-
@raw_cursor.bind_param(position, value)
|
|
155
|
-
end
|
|
139
|
+
@raw_cursor.bind_param(position, value)
|
|
156
140
|
end
|
|
157
141
|
end
|
|
158
142
|
|
|
@@ -172,7 +156,7 @@ module ActiveRecord
|
|
|
172
156
|
@raw_cursor.get_col_names
|
|
173
157
|
end
|
|
174
158
|
|
|
175
|
-
def fetch(options={})
|
|
159
|
+
def fetch(options = {})
|
|
176
160
|
if row = @raw_cursor.fetch
|
|
177
161
|
get_lob_value = options[:get_lob_value]
|
|
178
162
|
row.map do |col|
|
|
@@ -188,7 +172,6 @@ module ActiveRecord
|
|
|
188
172
|
def close
|
|
189
173
|
@raw_cursor.close
|
|
190
174
|
end
|
|
191
|
-
|
|
192
175
|
end
|
|
193
176
|
|
|
194
177
|
def select(sql, name = nil, return_column_names = false)
|
|
@@ -197,13 +180,13 @@ module ActiveRecord
|
|
|
197
180
|
# Ignore raw_rnum_ which is used to simulate LIMIT and OFFSET
|
|
198
181
|
cursor.get_col_names.each do |col_name|
|
|
199
182
|
col_name = oracle_downcase(col_name)
|
|
200
|
-
cols << col_name unless col_name ==
|
|
183
|
+
cols << col_name unless col_name == "raw_rnum_"
|
|
201
184
|
end
|
|
202
185
|
# Reuse the same hash for all rows
|
|
203
186
|
column_hash = {}
|
|
204
|
-
cols.each {|c| column_hash[c] = nil}
|
|
187
|
+
cols.each { |c| column_hash[c] = nil }
|
|
205
188
|
rows = []
|
|
206
|
-
get_lob_value = !(name ==
|
|
189
|
+
get_lob_value = !(name == "Writable Large Object")
|
|
207
190
|
|
|
208
191
|
while row = cursor.fetch
|
|
209
192
|
hash = column_hash.dup
|
|
@@ -226,7 +209,7 @@ module ActiveRecord
|
|
|
226
209
|
|
|
227
210
|
def describe(name)
|
|
228
211
|
# fall back to SELECT based describe if using database link
|
|
229
|
-
return super if name.to_s.include?(
|
|
212
|
+
return super if name.to_s.include?("@")
|
|
230
213
|
quoted_name = ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting.valid_table_name?(name) ? name : "\"#{name}\""
|
|
231
214
|
@raw_connection.describe(quoted_name)
|
|
232
215
|
rescue OCIException => e
|
|
@@ -250,12 +233,12 @@ module ActiveRecord
|
|
|
250
233
|
|
|
251
234
|
def typecast_result_value(value, get_lob_value)
|
|
252
235
|
case value
|
|
253
|
-
when
|
|
236
|
+
when Integer
|
|
254
237
|
value
|
|
255
238
|
when String
|
|
256
239
|
value
|
|
257
240
|
when Float, BigDecimal
|
|
258
|
-
# return
|
|
241
|
+
# return Integer if value is integer (to avoid issues with _before_type_cast values for id attributes)
|
|
259
242
|
value == (v_to_i = value.to_i) ? v_to_i : value
|
|
260
243
|
when OraNumber
|
|
261
244
|
# change OraNumber value (returned in early versions of ruby-oci8 2.0.x) to BigDecimal
|
|
@@ -264,17 +247,13 @@ module ActiveRecord
|
|
|
264
247
|
if get_lob_value
|
|
265
248
|
data = value.read || "" # if value.read returns nil, then we have an empty_clob() i.e. an empty string
|
|
266
249
|
# In Ruby 1.9.1 always change encoding to ASCII-8BIT for binaries
|
|
267
|
-
data.force_encoding(
|
|
250
|
+
data.force_encoding("ASCII-8BIT") if data.respond_to?(:force_encoding) && value.is_a?(OCI8::BLOB)
|
|
268
251
|
data
|
|
269
252
|
else
|
|
270
253
|
value
|
|
271
254
|
end
|
|
272
255
|
when Time, DateTime
|
|
273
|
-
|
|
274
|
-
value.to_date
|
|
275
|
-
else
|
|
276
|
-
create_time_with_default_timezone(value)
|
|
277
|
-
end
|
|
256
|
+
create_time_with_default_timezone(value)
|
|
278
257
|
else
|
|
279
258
|
value
|
|
280
259
|
end
|
|
@@ -286,33 +265,32 @@ module ActiveRecord
|
|
|
286
265
|
|
|
287
266
|
private
|
|
288
267
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
268
|
+
def date_without_time?(value)
|
|
269
|
+
case value
|
|
270
|
+
when OraDate
|
|
271
|
+
value.hour == 0 && value.minute == 0 && value.second == 0
|
|
272
|
+
else
|
|
273
|
+
value.hour == 0 && value.min == 0 && value.sec == 0
|
|
274
|
+
end
|
|
295
275
|
end
|
|
296
|
-
end
|
|
297
276
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
277
|
+
def create_time_with_default_timezone(value)
|
|
278
|
+
year, month, day, hour, min, sec, usec = case value
|
|
279
|
+
when Time
|
|
280
|
+
[value.year, value.month, value.day, value.hour, value.min, value.sec, value.usec]
|
|
281
|
+
when OraDate
|
|
282
|
+
[value.year, value.month, value.day, value.hour, value.minute, value.second, 0]
|
|
283
|
+
else
|
|
284
|
+
[value.year, value.month, value.day, value.hour, value.min, value.sec, 0]
|
|
285
|
+
end
|
|
286
|
+
# code from Time.time_with_datetime_fallback
|
|
287
|
+
begin
|
|
288
|
+
Time.send(Base.default_timezone, year, month, day, hour, min, sec, usec)
|
|
289
|
+
rescue
|
|
290
|
+
offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
|
|
291
|
+
::DateTime.civil(year, month, day, hour, min, sec, offset)
|
|
292
|
+
end
|
|
313
293
|
end
|
|
314
|
-
end
|
|
315
|
-
|
|
316
294
|
end
|
|
317
295
|
|
|
318
296
|
# The OracleEnhancedOCIFactory factors out the code necessary to connect and
|
|
@@ -328,13 +306,16 @@ module ActiveRecord
|
|
|
328
306
|
privilege = config[:privilege] && config[:privilege].to_sym
|
|
329
307
|
async = config[:allow_concurrency]
|
|
330
308
|
prefetch_rows = config[:prefetch_rows] || 100
|
|
331
|
-
cursor_sharing = config[:cursor_sharing] ||
|
|
309
|
+
cursor_sharing = config[:cursor_sharing] || "force"
|
|
332
310
|
# get session time_zone from configuration or from TZ environment variable
|
|
333
|
-
time_zone = config[:time_zone] || ENV[
|
|
311
|
+
time_zone = config[:time_zone] || ENV["TZ"]
|
|
334
312
|
|
|
313
|
+
# using a connection string via DATABASE_URL
|
|
314
|
+
connection_string = if host == "connection-string"
|
|
315
|
+
database
|
|
335
316
|
# connection using host, port and database name
|
|
336
|
-
|
|
337
|
-
host ||=
|
|
317
|
+
elsif host || port
|
|
318
|
+
host ||= "localhost"
|
|
338
319
|
host = "[#{host}]" if host =~ /^[^\[].*:/ # IPv6
|
|
339
320
|
port ||= 1521
|
|
340
321
|
database = "/#{database}" unless database.match(/^\//)
|
|
@@ -344,7 +325,6 @@ module ActiveRecord
|
|
|
344
325
|
else
|
|
345
326
|
database
|
|
346
327
|
end
|
|
347
|
-
|
|
348
328
|
conn = OCI8.new username, password, connection_string, privilege
|
|
349
329
|
conn.autocommit = true
|
|
350
330
|
conn.non_blocking = true if async
|
|
@@ -367,20 +347,15 @@ module ActiveRecord
|
|
|
367
347
|
conn
|
|
368
348
|
end
|
|
369
349
|
end
|
|
370
|
-
|
|
371
|
-
|
|
372
350
|
end
|
|
373
351
|
end
|
|
374
352
|
|
|
375
|
-
|
|
376
|
-
|
|
377
353
|
class OCI8 #:nodoc:
|
|
378
|
-
|
|
379
354
|
def describe(name)
|
|
380
355
|
info = describe_table(name.to_s)
|
|
381
356
|
raise %Q{"DESC #{name}" failed} if info.nil?
|
|
382
|
-
if info.respond_to?
|
|
383
|
-
[info.obj_schema, info.obj_name,
|
|
357
|
+
if info.respond_to?(:obj_link) && info.obj_link
|
|
358
|
+
[info.obj_schema, info.obj_name, "@" + info.obj_link]
|
|
384
359
|
else
|
|
385
360
|
[info.obj_schema, info.obj_name]
|
|
386
361
|
end
|
|
@@ -409,7 +384,7 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
|
|
|
409
384
|
@active = true
|
|
410
385
|
@config = config
|
|
411
386
|
@factory = factory
|
|
412
|
-
@connection
|
|
387
|
+
@connection = @factory.new_connection @config
|
|
413
388
|
super @connection
|
|
414
389
|
end
|
|
415
390
|
|
|
@@ -461,6 +436,5 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
|
|
|
461
436
|
retry
|
|
462
437
|
end
|
|
463
438
|
end
|
|
464
|
-
|
|
465
439
|
end
|
|
466
440
|
#:startdoc:
|
|
@@ -5,16 +5,16 @@ module ActiveRecord
|
|
|
5
5
|
def _type_cast(value)
|
|
6
6
|
case value
|
|
7
7
|
when ActiveModel::Type::Binary::Data
|
|
8
|
-
lob_value = value ==
|
|
8
|
+
lob_value = value == "" ? " " : value
|
|
9
9
|
bind_type = OCI8::BLOB
|
|
10
10
|
ora_value = bind_type.new(@connection.raw_oci_connection, lob_value)
|
|
11
|
-
ora_value.size = 0 if value ==
|
|
11
|
+
ora_value.size = 0 if value == ""
|
|
12
12
|
ora_value
|
|
13
13
|
when ActiveRecord::OracleEnhanced::Type::Text::Data
|
|
14
|
-
lob_value = value.to_s ==
|
|
14
|
+
lob_value = value.to_s == "" ? " " : value.to_s
|
|
15
15
|
bind_type = OCI8::CLOB
|
|
16
16
|
ora_value = bind_type.new(@connection.raw_oci_connection, lob_value)
|
|
17
|
-
ora_value.size = 0 if value.to_s ==
|
|
17
|
+
ora_value.size = 0 if value.to_s == ""
|
|
18
18
|
ora_value
|
|
19
19
|
else
|
|
20
20
|
super
|