activerecord-oracle_enhanced-adapter 1.7.7 → 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 +225 -0
- data/README.md +14 -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 +58 -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 +51 -79
- 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 +112 -132
- 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 +292 -539
- 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 +2 -3
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +82 -162
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +35 -35
- 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 +270 -365
- 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 +73 -77
- 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 +263 -329
- 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 -83
- 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,13 +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
108
|
# connection using TNS alias, or connection-string from DATABASE_URL
|
|
113
|
-
using_tns_alias = !host && !config[:url] && ENV[
|
|
114
|
-
if database && (using_tns_alias || host ==
|
|
109
|
+
using_tns_alias = !host && !config[:url] && ENV["TNS_ADMIN"]
|
|
110
|
+
if database && (using_tns_alias || host == "connection-string")
|
|
115
111
|
url = "jdbc:oracle:thin:@#{database}"
|
|
116
112
|
else
|
|
117
113
|
unless database.match(/^(\:|\/)/)
|
|
@@ -123,7 +119,7 @@ module ActiveRecord
|
|
|
123
119
|
|
|
124
120
|
prefetch_rows = config[:prefetch_rows] || 100
|
|
125
121
|
# get session time_zone from configuration or from TZ environment variable
|
|
126
|
-
time_zone = config[:time_zone] || ENV[
|
|
122
|
+
time_zone = config[:time_zone] || ENV["TZ"] || java.util.TimeZone.default.getID
|
|
127
123
|
|
|
128
124
|
properties = java.util.Properties.new
|
|
129
125
|
properties.put("user", username)
|
|
@@ -141,13 +137,17 @@ module ActiveRecord
|
|
|
141
137
|
end
|
|
142
138
|
|
|
143
139
|
# Set session time zone to current time zone
|
|
144
|
-
|
|
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
|
|
145
145
|
|
|
146
146
|
# Set default number of rows to prefetch
|
|
147
147
|
# @raw_connection.setDefaultRowPrefetch(prefetch_rows) if prefetch_rows
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
cursor_sharing = config[:cursor_sharing] ||
|
|
150
|
+
cursor_sharing = config[:cursor_sharing] || "force"
|
|
151
151
|
exec "alter session set cursor_sharing = #{cursor_sharing}"
|
|
152
152
|
|
|
153
153
|
# Initialize NLS parameters
|
|
@@ -330,7 +330,7 @@ module ActiveRecord
|
|
|
330
330
|
@raw_statement = raw_statement
|
|
331
331
|
end
|
|
332
332
|
|
|
333
|
-
def bind_params(
|
|
333
|
+
def bind_params(*bind_vars)
|
|
334
334
|
index = 1
|
|
335
335
|
bind_vars.flatten.each do |var|
|
|
336
336
|
if Hash === var
|
|
@@ -342,17 +342,7 @@ module ActiveRecord
|
|
|
342
342
|
end
|
|
343
343
|
end
|
|
344
344
|
|
|
345
|
-
def bind_param(position, value
|
|
346
|
-
if column
|
|
347
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
|
348
|
-
*******************************************************
|
|
349
|
-
Passing a column to `bind_param` will be deprecated.
|
|
350
|
-
`type_casted_binds` should be already type casted
|
|
351
|
-
so that `bind_param` should not need to know column.
|
|
352
|
-
*******************************************************
|
|
353
|
-
MSG
|
|
354
|
-
end
|
|
355
|
-
|
|
345
|
+
def bind_param(position, value)
|
|
356
346
|
case value
|
|
357
347
|
when Integer
|
|
358
348
|
@raw_statement.setLong(position, value)
|
|
@@ -376,17 +366,13 @@ module ActiveRecord
|
|
|
376
366
|
when Java::JavaSql::Timestamp
|
|
377
367
|
@raw_statement.setTimestamp(position, value)
|
|
378
368
|
when Time
|
|
379
|
-
|
|
380
|
-
@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)
|
|
381
371
|
when NilClass
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
# When nils will actually be used by ActiveRecord as bound parameters
|
|
387
|
-
# then need to pass actual column type.
|
|
388
|
-
@raw_statement.setNull(position, java.sql.Types::VARCHAR)
|
|
389
|
-
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)
|
|
390
376
|
else
|
|
391
377
|
raise ArgumentError, "Don't know how to bind variable with type #{value.class}"
|
|
392
378
|
end
|
|
@@ -414,21 +400,21 @@ module ActiveRecord
|
|
|
414
400
|
end
|
|
415
401
|
|
|
416
402
|
def column_types
|
|
417
|
-
@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 }
|
|
418
404
|
end
|
|
419
405
|
|
|
420
406
|
def column_names
|
|
421
|
-
@column_names ||= (1..metadata.getColumnCount).map{|i| metadata.getColumnName(i)}
|
|
407
|
+
@column_names ||= (1..metadata.getColumnCount).map { |i| metadata.getColumnName(i) }
|
|
422
408
|
end
|
|
423
409
|
alias :get_col_names :column_names
|
|
424
410
|
|
|
425
|
-
def fetch(options={})
|
|
411
|
+
def fetch(options = {})
|
|
426
412
|
if @raw_result_set.next
|
|
427
413
|
get_lob_value = options[:get_lob_value]
|
|
428
414
|
row_values = []
|
|
429
415
|
column_types.each_with_index do |column_type, i|
|
|
430
416
|
row_values <<
|
|
431
|
-
@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)
|
|
432
418
|
end
|
|
433
419
|
row_values
|
|
434
420
|
else
|
|
@@ -452,7 +438,6 @@ module ActiveRecord
|
|
|
452
438
|
def close
|
|
453
439
|
@raw_statement.close
|
|
454
440
|
end
|
|
455
|
-
|
|
456
441
|
end
|
|
457
442
|
|
|
458
443
|
def select(sql, name = nil, return_column_names = false)
|
|
@@ -473,14 +458,14 @@ module ActiveRecord
|
|
|
473
458
|
|
|
474
459
|
cols_types_index = (1..column_count).map do |i|
|
|
475
460
|
col_name = oracle_downcase(metadata.getColumnName(i))
|
|
476
|
-
next if col_name ==
|
|
461
|
+
next if col_name == "raw_rnum_"
|
|
477
462
|
column_hash[col_name] = nil
|
|
478
463
|
[col_name, metadata.getColumnTypeName(i).to_sym, i]
|
|
479
464
|
end
|
|
480
465
|
cols_types_index.delete(nil)
|
|
481
466
|
|
|
482
467
|
rows = []
|
|
483
|
-
get_lob_value = !(name ==
|
|
468
|
+
get_lob_value = !(name == "Writable Large Object")
|
|
484
469
|
|
|
485
470
|
while rset.next
|
|
486
471
|
hash = column_hash.dup
|
|
@@ -500,7 +485,7 @@ module ActiveRecord
|
|
|
500
485
|
if is_binary
|
|
501
486
|
lob.setBytes(1, value.to_java_bytes)
|
|
502
487
|
else
|
|
503
|
-
lob.setString(1,value)
|
|
488
|
+
lob.setString(1, value)
|
|
504
489
|
end
|
|
505
490
|
end
|
|
506
491
|
|
|
@@ -525,17 +510,15 @@ module ActiveRecord
|
|
|
525
510
|
else
|
|
526
511
|
BigDecimal.new(d.stringValue)
|
|
527
512
|
end
|
|
513
|
+
when :BINARY_FLOAT
|
|
514
|
+
rset.getFloat(i)
|
|
528
515
|
when :VARCHAR2, :CHAR, :LONG, :NVARCHAR2, :NCHAR
|
|
529
516
|
rset.getString(i)
|
|
530
517
|
when :DATE
|
|
531
518
|
if dt = rset.getDATE(i)
|
|
532
519
|
d = dt.dateValue
|
|
533
520
|
t = dt.timeValue
|
|
534
|
-
|
|
535
|
-
Date.new(d.year + 1900, d.month + 1, d.date)
|
|
536
|
-
else
|
|
537
|
-
Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
|
|
538
|
-
end
|
|
521
|
+
Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
|
|
539
522
|
else
|
|
540
523
|
nil
|
|
541
524
|
end
|
|
@@ -549,7 +532,7 @@ module ActiveRecord
|
|
|
549
532
|
get_lob_value ? lob_to_ruby_value(rset.getBlob(i)) : rset.getBlob(i)
|
|
550
533
|
when :RAW
|
|
551
534
|
raw_value = rset.getRAW(i)
|
|
552
|
-
raw_value && raw_value.getBytes.to_a.pack(
|
|
535
|
+
raw_value && raw_value.getBytes.to_a.pack("C*")
|
|
553
536
|
else
|
|
554
537
|
nil
|
|
555
538
|
end
|
|
@@ -557,24 +540,22 @@ module ActiveRecord
|
|
|
557
540
|
|
|
558
541
|
private
|
|
559
542
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
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
|
|
573
557
|
end
|
|
574
558
|
end
|
|
575
|
-
end
|
|
576
|
-
|
|
577
559
|
end
|
|
578
|
-
|
|
579
560
|
end
|
|
580
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
|
|
@@ -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,16 +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
|
|
|
335
313
|
# using a connection string via DATABASE_URL
|
|
336
|
-
connection_string = if host ==
|
|
314
|
+
connection_string = if host == "connection-string"
|
|
337
315
|
database
|
|
338
316
|
# connection using host, port and database name
|
|
339
317
|
elsif host || port
|
|
340
|
-
host ||=
|
|
318
|
+
host ||= "localhost"
|
|
341
319
|
host = "[#{host}]" if host =~ /^[^\[].*:/ # IPv6
|
|
342
320
|
port ||= 1521
|
|
343
321
|
database = "/#{database}" unless database.match(/^\//)
|
|
@@ -369,20 +347,15 @@ module ActiveRecord
|
|
|
369
347
|
conn
|
|
370
348
|
end
|
|
371
349
|
end
|
|
372
|
-
|
|
373
|
-
|
|
374
350
|
end
|
|
375
351
|
end
|
|
376
352
|
|
|
377
|
-
|
|
378
|
-
|
|
379
353
|
class OCI8 #:nodoc:
|
|
380
|
-
|
|
381
354
|
def describe(name)
|
|
382
355
|
info = describe_table(name.to_s)
|
|
383
356
|
raise %Q{"DESC #{name}" failed} if info.nil?
|
|
384
|
-
if info.respond_to?
|
|
385
|
-
[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]
|
|
386
359
|
else
|
|
387
360
|
[info.obj_schema, info.obj_name]
|
|
388
361
|
end
|
|
@@ -411,7 +384,7 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
|
|
|
411
384
|
@active = true
|
|
412
385
|
@config = config
|
|
413
386
|
@factory = factory
|
|
414
|
-
@connection
|
|
387
|
+
@connection = @factory.new_connection @config
|
|
415
388
|
super @connection
|
|
416
389
|
end
|
|
417
390
|
|
|
@@ -463,6 +436,5 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
|
|
|
463
436
|
retry
|
|
464
437
|
end
|
|
465
438
|
end
|
|
466
|
-
|
|
467
439
|
end
|
|
468
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
|