activerecord-oracle_enhanced-adapter 1.7.11 → 1.8.0.beta1

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/Gemfile +20 -11
  4. data/History.md +123 -4
  5. data/RUNNING_TESTS.md +79 -55
  6. data/Rakefile +13 -19
  7. data/VERSION +1 -1
  8. data/activerecord-oracle_enhanced-adapter.gemspec +16 -17
  9. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +1 -1
  10. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +7 -59
  11. data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +6 -50
  12. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +11 -11
  13. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +117 -117
  14. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +30 -23
  15. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +10 -10
  16. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +48 -70
  17. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +1 -4
  18. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +51 -69
  19. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +4 -4
  20. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +76 -76
  21. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +13 -42
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +60 -64
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +33 -47
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +146 -159
  25. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +94 -132
  26. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +3 -3
  27. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +65 -100
  28. data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +1 -1
  29. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +250 -487
  30. data/lib/active_record/oracle_enhanced/type/boolean.rb +7 -10
  31. data/lib/active_record/oracle_enhanced/type/integer.rb +3 -4
  32. data/lib/active_record/oracle_enhanced/type/national_character_string.rb +1 -1
  33. data/lib/active_record/oracle_enhanced/type/raw.rb +2 -3
  34. data/lib/active_record/oracle_enhanced/type/string.rb +2 -2
  35. data/lib/active_record/oracle_enhanced/type/text.rb +2 -2
  36. data/lib/activerecord-oracle_enhanced-adapter.rb +2 -2
  37. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +57 -131
  38. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +32 -34
  39. data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +40 -42
  40. data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +83 -85
  41. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +205 -286
  42. data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +14 -6
  43. data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +3 -5
  44. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +42 -49
  45. data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +1 -3
  46. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +68 -71
  47. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +51 -92
  48. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +221 -327
  49. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +16 -18
  50. data/spec/spec_helper.rb +59 -57
  51. metadata +10 -10
@@ -16,10 +16,10 @@ module ActiveRecord
16
16
  reload_type_map
17
17
  end
18
18
 
19
- def exec_query(sql, name = 'SQL', binds = [], prepare: false)
19
+ def exec_query(sql, name = "SQL", binds = [], prepare: false)
20
20
  type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
21
21
 
22
- log(sql, name, binds) do
22
+ log(sql, name, binds, type_casted_binds) do
23
23
  cursor = nil
24
24
  cached = false
25
25
  if without_prepared_statement?(binds)
@@ -38,14 +38,14 @@ module ActiveRecord
38
38
 
39
39
  cursor.exec
40
40
 
41
- if name == 'EXPLAIN' and sql =~ /^EXPLAIN/
41
+ if (name == "EXPLAIN") && sql =~ /^EXPLAIN/
42
42
  res = true
43
43
  else
44
44
  columns = cursor.get_col_names.map do |col_name|
45
45
  @connection.oracle_downcase(col_name)
46
46
  end
47
47
  rows = []
48
- fetch_options = {:get_lob_value => (name != 'Writable Large Object')}
48
+ fetch_options = { get_lob_value: (name != "Writable Large Object") }
49
49
  while row = cursor.fetch(fetch_options)
50
50
  rows << row
51
51
  end
@@ -69,17 +69,11 @@ module ActiveRecord
69
69
  sql = "EXPLAIN PLAN FOR #{to_sql(arel, binds)}"
70
70
  return if sql =~ /FROM all_/
71
71
  if ORACLE_ENHANCED_CONNECTION == :jdbc
72
- exec_query(sql, 'EXPLAIN', binds)
72
+ exec_query(sql, "EXPLAIN", binds)
73
73
  else
74
- exec_query(sql, 'EXPLAIN')
74
+ exec_query(sql, "EXPLAIN")
75
75
  end
76
- select_values("SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)", 'EXPLAIN').join("\n")
77
- end
78
-
79
- # Returns an array of arrays containing the field values.
80
- # Order is the same as that returned by #columns.
81
- def select_rows(sql, name = nil, binds = [])
82
- exec_query(sql, name, binds).rows
76
+ select_values("SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)", "EXPLAIN").join("\n")
83
77
  end
84
78
 
85
79
  # New method in ActiveRecord 3.1
@@ -92,11 +86,17 @@ module ActiveRecord
92
86
  super
93
87
  end
94
88
 
89
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
90
+ pk = nil if id_value
91
+ super
92
+ end
93
+
95
94
  # New method in ActiveRecord 3.1
96
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
95
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
96
+ sql, binds = sql_for_insert(sql, pk, nil, sequence_name, binds)
97
97
  type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
98
98
 
99
- log(sql, name, binds) do
99
+ log(sql, name, binds, type_casted_binds) do
100
100
  returning_id_col = returning_id_index = nil
101
101
  if without_prepared_statement?(binds)
102
102
  cursor = @connection.prepare(sql)
@@ -129,19 +129,19 @@ module ActiveRecord
129
129
  end
130
130
 
131
131
  # New method in ActiveRecord 3.1
132
- def exec_update(sql, name, binds)
132
+ def exec_update(sql, name = nil, binds = [])
133
133
  type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
134
134
 
135
- log(sql, name, binds) do
135
+ log(sql, name, binds, type_casted_binds) do
136
136
  cached = false
137
137
  if without_prepared_statement?(binds)
138
138
  cursor = @connection.prepare(sql)
139
139
  else
140
- cursor = if @statements.key?(sql)
141
- @statements[sql]
142
- else
143
- @statements[sql] = @connection.prepare(sql)
144
- end
140
+ if @statements.key?(sql)
141
+ cursor = @statements[sql]
142
+ else
143
+ cursor = @statements[sql] = @connection.prepare(sql)
144
+ end
145
145
 
146
146
  cursor.bind_params(type_casted_binds)
147
147
 
@@ -202,7 +202,7 @@ module ActiveRecord
202
202
  # Returns default sequence name for table.
203
203
  # Will take all or first 26 characters of table name and append _seq suffix
204
204
  def default_sequence_name(table_name, primary_key = nil)
205
- table_name.to_s.gsub((/(^|\.)([\w$-]{1,#{sequence_name_length-4}})([\w$-]*)$/), '\1\2_seq')
205
+ table_name.to_s.gsub((/(^|\.)([\w$-]{1,#{sequence_name_length - 4}})([\w$-]*)$/), '\1\2_seq')
206
206
  end
207
207
 
208
208
  # Inserts the given fixture into the table. Overridden to properly handle lobs.
@@ -220,6 +220,13 @@ module ActiveRecord
220
220
  write_lobs(table_name, klass, fixture, klass.lob_columns)
221
221
  end
222
222
  end
223
+
224
+ # Oracle Database does not support this feature
225
+ # Refer https://community.oracle.com/ideas/13845 and consider to vote
226
+ # if you need this feature.
227
+ def empty_insert_statement_value
228
+ raise NotImplementedError
229
+ end
223
230
  end
224
231
  end
225
232
  end
@@ -1,21 +1,21 @@
1
- require 'active_record/base'
1
+ require "active_record/base"
2
2
 
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  class OracleEnhancedAdapter
6
6
  class DatabaseTasks
7
- delegate :connection, :establish_connection, :to => ActiveRecord::Base
7
+ delegate :connection, :establish_connection, to: ActiveRecord::Base
8
8
 
9
9
  def initialize(config)
10
10
  @config = config
11
11
  end
12
12
 
13
13
  def create
14
- system_password = ENV.fetch('ORACLE_SYSTEM_PASSWORD') {
14
+ system_password = ENV.fetch("ORACLE_SYSTEM_PASSWORD") {
15
15
  print "Please provide the SYSTEM password for your Oracle installation (set ORACLE_SYSTEM_PASSWORD to avoid this prompt)\n>"
16
16
  $stdin.gets.strip
17
17
  }
18
- establish_connection(@config.merge('username' => 'SYSTEM', 'password' => system_password))
18
+ establish_connection(@config.merge("username" => "SYSTEM", "password" => system_password))
19
19
  begin
20
20
  connection.execute "CREATE USER #{@config['username']} IDENTIFIED BY #{@config['password']}"
21
21
  rescue => e
@@ -39,18 +39,18 @@ module ActiveRecord
39
39
 
40
40
  def purge
41
41
  drop
42
- connection.execute('PURGE RECYCLEBIN') rescue nil
42
+ connection.execute("PURGE RECYCLEBIN") rescue nil
43
43
  end
44
44
 
45
- def structure_dump(filename)
45
+ def structure_dump(filename, extra_flags)
46
46
  establish_connection(@config)
47
- File.open(filename, 'w:utf-8') { |f| f << connection.structure_dump }
48
- if @config['structure_dump'] == 'db_stored_code'
49
- File.open(filename, 'a') { |f| f << connection.structure_dump_db_stored_code }
47
+ File.open(filename, "w:utf-8") { |f| f << connection.structure_dump }
48
+ if @config["structure_dump"] == "db_stored_code"
49
+ File.open(filename, "a") { |f| f << connection.structure_dump_db_stored_code }
50
50
  end
51
51
  end
52
52
 
53
- def structure_load(filename)
53
+ def structure_load(filename, extra_flags)
54
54
  establish_connection(@config)
55
55
  connection.execute_structure_dump(File.read(filename))
56
56
  end
@@ -2,27 +2,25 @@ begin
2
2
  require "java"
3
3
  require "jruby"
4
4
 
5
- # ojdbc7.jar, ojdbc6.jar or ojdbc5.jar file should be in application ./lib directory or in load path or in ENV['PATH']
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
- 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)
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
- if ojdbc_jars && ENV_JAVA['java.class.path'] !~ Regexp.new(ojdbc_jars.join('|'))
14
+ # Oracle 11g client ojdbc6.jar is also compatible with Java 1.7
15
+ # Oracle 12c client provides new ojdbc7.jar
16
+ ojdbc_jars = %w(ojdbc7.jar ojdbc6.jar)
17
+
18
+ if ENV_JAVA["java.class.path"] !~ Regexp.new(ojdbc_jars.join("|"))
21
19
  # On Unix environment variable should be PATH, on Windows it is sometimes Path
22
- env_path = (ENV["PATH"] || ENV["Path"] || '').split(File::PATH_SEPARATOR)
20
+ env_path = (ENV["PATH"] || ENV["Path"] || "").split(File::PATH_SEPARATOR)
23
21
  # Look for JDBC driver at first in lib subdirectory (application specific JDBC file version)
24
22
  # then in Ruby load path and finally in environment PATH
25
- ['./lib'].concat($LOAD_PATH).concat(env_path).detect do |dir|
23
+ ["./lib"].concat($LOAD_PATH).concat(env_path).detect do |dir|
26
24
  # check any compatible JDBC driver in the priority order
27
25
  ojdbc_jars.any? do |ojdbc_jar|
28
26
  if File.exists?(file_path = File.join(dir, ojdbc_jar))
@@ -43,7 +41,7 @@ begin
43
41
 
44
42
  rescue LoadError, NameError
45
43
  # JDBC driver is unavailable.
46
- raise LoadError, "ERROR: ActiveRecord oracle_enhanced adapter could not load Oracle JDBC driver. Please install #{ojdbc_jars ? ojdbc_jars.join(' or ') : "Oracle JDBC"} library."
44
+ raise LoadError, "ERROR: ActiveRecord oracle_enhanced adapter could not load Oracle JDBC driver. Please install #{ojdbc_jars.join(' or ') } library."
47
45
  end
48
46
 
49
47
  module ActiveRecord
@@ -74,7 +72,7 @@ module ActiveRecord
74
72
 
75
73
  # tomcat needs first lookup method, oc4j (and maybe other application servers) need second method
76
74
  begin
77
- env = ctx.lookup('java:/comp/env')
75
+ env = ctx.lookup("java:/comp/env")
78
76
  ds = env.lookup(jndi)
79
77
  rescue
80
78
  ds = ctx.lookup(jndi)
@@ -102,13 +100,13 @@ module ActiveRecord
102
100
  # to_s needed if username, password or database is specified as number in database.yml file
103
101
  username = config[:username] && config[:username].to_s
104
102
  password = config[:password] && config[:password].to_s
105
- database = config[:database] && config[:database].to_s || 'XE'
103
+ database = config[:database] && config[:database].to_s || "XE"
106
104
  host, port = config[:host], config[:port]
107
105
  privilege = config[:privilege] && config[:privilege].to_s
108
106
 
109
107
  # connection using TNS alias, or connection-string from DATABASE_URL
110
- using_tns_alias = !host && !config[:url] && ENV['TNS_ADMIN']
111
- if database && (using_tns_alias || host == 'connection-string')
108
+ using_tns_alias = !host && !config[:url] && ENV["TNS_ADMIN"]
109
+ if database && (using_tns_alias || host == "connection-string")
112
110
  url = "jdbc:oracle:thin:@#{database}"
113
111
  else
114
112
  unless database.match(/^(\:|\/)/)
@@ -120,7 +118,7 @@ module ActiveRecord
120
118
 
121
119
  prefetch_rows = config[:prefetch_rows] || 100
122
120
  # get session time_zone from configuration or from TZ environment variable
123
- time_zone = config[:time_zone] || ENV['TZ'] || java.util.TimeZone.default.getID
121
+ time_zone = config[:time_zone] || ENV["TZ"] || java.util.TimeZone.default.getID
124
122
 
125
123
  properties = java.util.Properties.new
126
124
  properties.put("user", username)
@@ -144,7 +142,7 @@ module ActiveRecord
144
142
  # @raw_connection.setDefaultRowPrefetch(prefetch_rows) if prefetch_rows
145
143
  end
146
144
 
147
- cursor_sharing = config[:cursor_sharing] || 'force'
145
+ cursor_sharing = config[:cursor_sharing] || "force"
148
146
  exec "alter session set cursor_sharing = #{cursor_sharing}"
149
147
 
150
148
  # Initialize NLS parameters
@@ -327,7 +325,7 @@ module ActiveRecord
327
325
  @raw_statement = raw_statement
328
326
  end
329
327
 
330
- def bind_params( *bind_vars )
328
+ def bind_params(*bind_vars)
331
329
  index = 1
332
330
  bind_vars.flatten.each do |var|
333
331
  if Hash === var
@@ -339,17 +337,7 @@ module ActiveRecord
339
337
  end
340
338
  end
341
339
 
342
- def bind_param(position, value, column = nil)
343
- if column
344
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
345
- *******************************************************
346
- Passing a column to `bind_param` will be deprecated.
347
- `type_casted_binds` should be already type casted
348
- so that `bind_param` should not need to know column.
349
- *******************************************************
350
- MSG
351
- end
352
-
340
+ def bind_param(position, value)
353
341
  case value
354
342
  when Integer
355
343
  @raw_statement.setLong(position, value)
@@ -376,14 +364,10 @@ module ActiveRecord
376
364
  # TODO: Really needed or not
377
365
  @raw_statement.setTimestamp(position, value)
378
366
  when NilClass
379
- if column && column.object_type?
380
- @raw_statement.setNull(position, java.sql.Types::STRUCT, column.sql_type)
381
- else
382
- # TODO: currently nil is always bound as NULL with VARCHAR type.
383
- # When nils will actually be used by ActiveRecord as bound parameters
384
- # then need to pass actual column type.
385
- @raw_statement.setNull(position, java.sql.Types::VARCHAR)
386
- end
367
+ # TODO: currently nil is always bound as NULL with VARCHAR type.
368
+ # When nils will actually be used by ActiveRecord as bound parameters
369
+ # then need to pass actual column type.
370
+ @raw_statement.setNull(position, java.sql.Types::VARCHAR)
387
371
  else
388
372
  raise ArgumentError, "Don't know how to bind variable with type #{value.class}"
389
373
  end
@@ -411,21 +395,21 @@ module ActiveRecord
411
395
  end
412
396
 
413
397
  def column_types
414
- @column_types ||= (1..metadata.getColumnCount).map{|i| metadata.getColumnTypeName(i).to_sym}
398
+ @column_types ||= (1..metadata.getColumnCount).map { |i| metadata.getColumnTypeName(i).to_sym }
415
399
  end
416
400
 
417
401
  def column_names
418
- @column_names ||= (1..metadata.getColumnCount).map{|i| metadata.getColumnName(i)}
402
+ @column_names ||= (1..metadata.getColumnCount).map { |i| metadata.getColumnName(i) }
419
403
  end
420
404
  alias :get_col_names :column_names
421
405
 
422
- def fetch(options={})
406
+ def fetch(options = {})
423
407
  if @raw_result_set.next
424
408
  get_lob_value = options[:get_lob_value]
425
409
  row_values = []
426
410
  column_types.each_with_index do |column_type, i|
427
411
  row_values <<
428
- @connection.get_ruby_value_from_result_set(@raw_result_set, i+1, column_type, get_lob_value)
412
+ @connection.get_ruby_value_from_result_set(@raw_result_set, i + 1, column_type, get_lob_value)
429
413
  end
430
414
  row_values
431
415
  else
@@ -469,14 +453,14 @@ module ActiveRecord
469
453
 
470
454
  cols_types_index = (1..column_count).map do |i|
471
455
  col_name = oracle_downcase(metadata.getColumnName(i))
472
- next if col_name == 'raw_rnum_'
456
+ next if col_name == "raw_rnum_"
473
457
  column_hash[col_name] = nil
474
458
  [col_name, metadata.getColumnTypeName(i).to_sym, i]
475
459
  end
476
460
  cols_types_index.delete(nil)
477
461
 
478
462
  rows = []
479
- get_lob_value = !(name == 'Writable Large Object')
463
+ get_lob_value = !(name == "Writable Large Object")
480
464
 
481
465
  while rset.next
482
466
  hash = column_hash.dup
@@ -496,7 +480,7 @@ module ActiveRecord
496
480
  if is_binary
497
481
  lob.setBytes(1, value.to_java_bytes)
498
482
  else
499
- lob.setString(1,value)
483
+ lob.setString(1, value)
500
484
  end
501
485
  end
502
486
 
@@ -521,19 +505,13 @@ module ActiveRecord
521
505
  else
522
506
  BigDecimal.new(d.stringValue)
523
507
  end
524
- when :BINARY_FLOAT
525
- rset.getFloat(i)
526
508
  when :VARCHAR2, :CHAR, :LONG, :NVARCHAR2, :NCHAR
527
509
  rset.getString(i)
528
510
  when :DATE
529
511
  if dt = rset.getDATE(i)
530
512
  d = dt.dateValue
531
513
  t = dt.timeValue
532
- if OracleEnhancedAdapter.emulate_dates && t.hours == 0 && t.minutes == 0 && t.seconds == 0
533
- Date.new(d.year + 1900, d.month + 1, d.date)
534
- else
535
- Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
536
- end
514
+ Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
537
515
  else
538
516
  nil
539
517
  end
@@ -547,7 +525,7 @@ module ActiveRecord
547
525
  get_lob_value ? lob_to_ruby_value(rset.getBlob(i)) : rset.getBlob(i)
548
526
  when :RAW
549
527
  raw_value = rset.getRAW(i)
550
- raw_value && raw_value.getBytes.to_a.pack('C*')
528
+ raw_value && raw_value.getBytes.to_a.pack("C*")
551
529
  else
552
530
  nil
553
531
  end
@@ -555,22 +533,22 @@ module ActiveRecord
555
533
 
556
534
  private
557
535
 
558
- def lob_to_ruby_value(val)
559
- case val
560
- when ::Java::OracleSql::CLOB
561
- if val.isEmptyLob
562
- nil
563
- else
564
- val.getSubString(1, val.length)
565
- end
566
- when ::Java::OracleSql::BLOB
567
- if val.isEmptyLob
568
- nil
569
- else
570
- String.from_java_bytes(val.getBytes(1, val.length))
536
+ def lob_to_ruby_value(val)
537
+ case val
538
+ when ::Java::OracleSql::CLOB
539
+ if val.isEmptyLob
540
+ nil
541
+ else
542
+ val.getSubString(1, val.length)
543
+ end
544
+ when ::Java::OracleSql::BLOB
545
+ if val.isEmptyLob
546
+ nil
547
+ else
548
+ String.from_java_bytes(val.getBytes(1, val.length))
549
+ end
571
550
  end
572
551
  end
573
- end
574
552
  end
575
553
  end
576
554
  end
@@ -15,10 +15,7 @@ module ActiveRecord
15
15
  when Date, DateTime
16
16
  Java::oracle.sql.DATE.new(value.strftime("%Y-%m-%d %H:%M:%S"))
17
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
- when Java::JavaSql::Timestamp
20
- # Returning value as it is likely this value was already type casted from Time to Java::JavaSql::Timestamp
21
- value
18
+ Java::java.sql.Timestamp.new(value.year - 1900, value.month - 1, value.day, value.hour, value.min, value.sec, value.usec * 1000)
22
19
  else
23
20
  super
24
21
  end
@@ -1,4 +1,4 @@
1
- require 'delegate'
1
+ require "delegate"
2
2
 
3
3
  begin
4
4
  require "oci8"
@@ -11,7 +11,7 @@ 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
@@ -98,9 +98,9 @@ module ActiveRecord
98
98
  # and return :insert_id value
99
99
  def exec_with_returning(sql)
100
100
  cursor = @raw_connection.parse(sql)
101
- cursor.bind_param(':insert_id', nil, Integer)
101
+ cursor.bind_param(":insert_id", nil, Integer)
102
102
  cursor.exec
103
- cursor[':insert_id']
103
+ cursor[":insert_id"]
104
104
  ensure
105
105
  cursor.close rescue nil
106
106
  end
@@ -115,7 +115,7 @@ module ActiveRecord
115
115
  @raw_cursor = raw_cursor
116
116
  end
117
117
 
118
- def bind_params( *bind_vars )
118
+ def bind_params(*bind_vars)
119
119
  index = 1
120
120
  bind_vars.flatten.each do |var|
121
121
  if Hash === var
@@ -127,30 +127,16 @@ module ActiveRecord
127
127
  end
128
128
  end
129
129
 
130
- def bind_param(position, value, column = nil)
131
- if column
132
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
133
- *******************************************************
134
- Passing a column to `bind_param` will be deprecated.
135
- `type_casted_binds` should be already type casted
136
- so that `bind_param` should not need to know column.
137
- *******************************************************
138
- MSG
139
- end
140
-
141
- if column && column.object_type?
142
- @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)
143
138
  else
144
- case value
145
- when ActiveRecord::OracleEnhanced::Type::Raw
146
- @raw_cursor.bind_param(position, ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting.encode_raw(value))
147
- when ActiveModel::Type::Decimal
148
- @raw_cursor.bind_param(position, BigDecimal.new(value.to_s))
149
- when NilClass
150
- @raw_cursor.bind_param(position, nil, String)
151
- else
152
- @raw_cursor.bind_param(position, value)
153
- end
139
+ @raw_cursor.bind_param(position, value)
154
140
  end
155
141
  end
156
142
 
@@ -170,7 +156,7 @@ module ActiveRecord
170
156
  @raw_cursor.get_col_names
171
157
  end
172
158
 
173
- def fetch(options={})
159
+ def fetch(options = {})
174
160
  if row = @raw_cursor.fetch
175
161
  get_lob_value = options[:get_lob_value]
176
162
  row.map do |col|
@@ -194,13 +180,13 @@ module ActiveRecord
194
180
  # Ignore raw_rnum_ which is used to simulate LIMIT and OFFSET
195
181
  cursor.get_col_names.each do |col_name|
196
182
  col_name = oracle_downcase(col_name)
197
- cols << col_name unless col_name == 'raw_rnum_'
183
+ cols << col_name unless col_name == "raw_rnum_"
198
184
  end
199
185
  # Reuse the same hash for all rows
200
186
  column_hash = {}
201
- cols.each {|c| column_hash[c] = nil}
187
+ cols.each { |c| column_hash[c] = nil }
202
188
  rows = []
203
- get_lob_value = !(name == 'Writable Large Object')
189
+ get_lob_value = !(name == "Writable Large Object")
204
190
 
205
191
  while row = cursor.fetch
206
192
  hash = column_hash.dup
@@ -223,7 +209,7 @@ module ActiveRecord
223
209
 
224
210
  def describe(name)
225
211
  # fall back to SELECT based describe if using database link
226
- return super if name.to_s.include?('@')
212
+ return super if name.to_s.include?("@")
227
213
  quoted_name = ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting.valid_table_name?(name) ? name : "\"#{name}\""
228
214
  @raw_connection.describe(quoted_name)
229
215
  rescue OCIException => e
@@ -261,17 +247,13 @@ module ActiveRecord
261
247
  if get_lob_value
262
248
  data = value.read || "" # if value.read returns nil, then we have an empty_clob() i.e. an empty string
263
249
  # In Ruby 1.9.1 always change encoding to ASCII-8BIT for binaries
264
- data.force_encoding('ASCII-8BIT') if data.respond_to?(:force_encoding) && value.is_a?(OCI8::BLOB)
250
+ data.force_encoding("ASCII-8BIT") if data.respond_to?(:force_encoding) && value.is_a?(OCI8::BLOB)
265
251
  data
266
252
  else
267
253
  value
268
254
  end
269
255
  when Time, DateTime
270
- if OracleEnhancedAdapter.emulate_dates && date_without_time?(value)
271
- value.to_date
272
- else
273
- create_time_with_default_timezone(value)
274
- end
256
+ create_time_with_default_timezone(value)
275
257
  else
276
258
  value
277
259
  end
@@ -283,32 +265,32 @@ module ActiveRecord
283
265
 
284
266
  private
285
267
 
286
- def date_without_time?(value)
287
- case value
288
- when OraDate
289
- value.hour == 0 && value.minute == 0 && value.second == 0
290
- else
291
- value.hour == 0 && value.min == 0 && value.sec == 0
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
292
275
  end
293
- end
294
276
 
295
- def create_time_with_default_timezone(value)
296
- year, month, day, hour, min, sec, usec = case value
297
- when Time
298
- [value.year, value.month, value.day, value.hour, value.min, value.sec, value.usec]
299
- when OraDate
300
- [value.year, value.month, value.day, value.hour, value.minute, value.second, 0]
301
- else
302
- [value.year, value.month, value.day, value.hour, value.min, value.sec, 0]
303
- end
304
- # code from Time.time_with_datetime_fallback
305
- begin
306
- Time.send(Base.default_timezone, year, month, day, hour, min, sec, usec)
307
- rescue
308
- offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
309
- ::DateTime.civil(year, month, day, hour, min, sec, offset)
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
310
293
  end
311
- end
312
294
  end
313
295
 
314
296
  # The OracleEnhancedOCIFactory factors out the code necessary to connect and
@@ -324,16 +306,16 @@ module ActiveRecord
324
306
  privilege = config[:privilege] && config[:privilege].to_sym
325
307
  async = config[:allow_concurrency]
326
308
  prefetch_rows = config[:prefetch_rows] || 100
327
- cursor_sharing = config[:cursor_sharing] || 'force'
309
+ cursor_sharing = config[:cursor_sharing] || "force"
328
310
  # get session time_zone from configuration or from TZ environment variable
329
- time_zone = config[:time_zone] || ENV['TZ']
311
+ time_zone = config[:time_zone] || ENV["TZ"]
330
312
 
331
313
  # using a connection string via DATABASE_URL
332
- connection_string = if host == 'connection-string'
314
+ connection_string = if host == "connection-string"
333
315
  database
334
316
  # connection using host, port and database name
335
317
  elsif host || port
336
- host ||= 'localhost'
318
+ host ||= "localhost"
337
319
  host = "[#{host}]" if host =~ /^[^\[].*:/ # IPv6
338
320
  port ||= 1521
339
321
  database = "/#{database}" unless database.match(/^\//)
@@ -372,8 +354,8 @@ class OCI8 #:nodoc:
372
354
  def describe(name)
373
355
  info = describe_table(name.to_s)
374
356
  raise %Q{"DESC #{name}" failed} if info.nil?
375
- if info.respond_to? :obj_link and info.obj_link
376
- [info.obj_schema, info.obj_name, '@' + info.obj_link]
357
+ if info.respond_to?(:obj_link) && info.obj_link
358
+ [info.obj_schema, info.obj_name, "@" + info.obj_link]
377
359
  else
378
360
  [info.obj_schema, info.obj_name]
379
361
  end
@@ -402,7 +384,7 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
402
384
  @active = true
403
385
  @config = config
404
386
  @factory = factory
405
- @connection = @factory.new_connection @config
387
+ @connection = @factory.new_connection @config
406
388
  super @connection
407
389
  end
408
390