activerecord-oracle_enhanced-adapter 7.0.2 → 7.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +32 -0
  3. data/README.md +0 -1
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +5 -0
  6. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +1 -1
  7. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +2 -2
  8. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +26 -21
  9. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +15 -2
  10. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +9 -2
  11. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +3 -3
  12. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +24 -15
  13. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +3 -3
  14. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +7 -5
  15. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +1 -1
  16. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +5 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +1 -1
  18. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +22 -22
  19. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +17 -17
  20. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +71 -28
  21. data/lib/activerecord-oracle_enhanced-adapter.rb +8 -0
  22. data/lib/arel/visitors/oracle.rb +6 -3
  23. data/lib/arel/visitors/oracle12.rb +6 -5
  24. data/lib/arel/visitors/oracle_common.rb +46 -0
  25. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +24 -5
  26. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +7 -2
  27. data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +2 -2
  28. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +3 -0
  29. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +25 -15
  30. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +15 -18
  31. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +14 -10
  32. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +2 -2
  33. data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +24 -0
  34. data/spec/active_record/oracle_enhanced/type/custom_spec.rb +2 -0
  35. data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +4 -2
  36. data/spec/active_record/oracle_enhanced/type/integer_spec.rb +8 -0
  37. data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +3 -3
  38. data/spec/active_record/oracle_enhanced/type/raw_spec.rb +15 -0
  39. data/spec/active_record/oracle_enhanced/type/text_spec.rb +18 -3
  40. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +5 -1
  41. data/spec/spec_config.yaml.template +2 -2
  42. data/spec/spec_helper.rb +14 -3
  43. metadata +11 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ccca4d74a21127a5e9404fa7784605866ba5696d7b754f4e6bb7d439f1dea17a
4
- data.tar.gz: 2bbce4871b4058a7d3071599dfd3c502ab52f9f313d2826b78efd713a1c3102c
3
+ metadata.gz: 0ae057b4554fc7445518df5442839379547ea94ecae188766f51de26af7b44ca
4
+ data.tar.gz: 57d0c16ba1e23aae7b8667019bf7ee3046f0d95f9a7b1372041776d2228a608e
5
5
  SHA512:
6
- metadata.gz: 03b7ace961ddc9ef03b105ba9d5be8db2d0e31f6ff42ac36717fbbee3b16cd94ac0b8c1a19463e142a74f82b804638829298b55f9ea899e85410ee5ed36713ab
7
- data.tar.gz: af6d24396e7cfe60e854cf2edbfed0c5dac325232aa4936d62cd40aec85e06a7659fba8bf5d5bfe0f36c43636ac18effb38a592f548a43d56609f04d0a4112bf
6
+ metadata.gz: 688ad4ebead316af951e1efdca85be5b91606df1a3eca0dbbfd405750b2850ef43ec8ed46e002e191d4e5850d935d2097237696911e841a03997f060584aef5f
7
+ data.tar.gz: 9cd2c4a638386bdd3780c48a84f94af7fe853fe2beee6d6fd1ce0826d35d4bd08874109e2e9a6f11db7a440cfb88e9b03ac42586ecf2cc31978cca61925eac61
data/History.md CHANGED
@@ -1,3 +1,35 @@
1
+ ## 7.1.0.beta1 / 2024-09-23
2
+
3
+ * Changes and bug fixes
4
+ * Support Rails 7.1 [#2384]
5
+ * All attributes serialized before writing [#2203]
6
+ * Support LIKE case-insensitive matching [#2247]
7
+ * Support LOB equality [#2258]
8
+ * Rename the raw connection ivar to @raw_connection [#2265]
9
+ * Require 'activerecord', not 'rails' not to attempt to install digest [#2241]
10
+ * Add ruby-oci8 as dependency only for CRuby [#2240]
11
+ * Address uninitialized constant TestEmployee::AttributeSignature::Base64 [#2264]
12
+ * Enable Lint/EnsureReturn cop [#2259]
13
+ * Enable Performance/OpenStruct cop [#2263]
14
+ * Enable Style/MapToHash cop [#2266]
15
+ * Fix broken link [#2250]
16
+ * Use debug gem to replace byebug [#2275]
17
+ * Support linting YAML files [#2272]
18
+
19
+ * Known issues
20
+ * `build_explain_clause(options = [])` has not been implemented yet [#2394]
21
+ * `supports_fetch_first_n_rows_and_offset?` always returns `false` [#2395]
22
+ * Oracle enhanced adapter has not been tested against JRuby
23
+ * bug_report_templates are not tested [#2318]
24
+
25
+ ## 7.0.3 / 2023-08-10
26
+
27
+ * Changes and bug fixes
28
+ * Support Rails 7.0.7
29
+ * Make ActiveRecord's quoted name caches thread-safe on JRuby/TruffleRuby [#2347, #2346]
30
+ * Address `NameError: uninitialized constant TestEmployee::AttributeSignature::Base64` [#2347]
31
+ * Address `Style/RedundantRegexpEscape` offense [#2347]
32
+
1
33
  ## 7.0.2 / 2022-01-21
2
34
 
3
35
  * Changes and bug fixes
data/README.md CHANGED
@@ -18,7 +18,6 @@ When using Ruby on Rails version 7.0 then in Gemfile include
18
18
  ```ruby
19
19
  # Use oracle as the database for Active Record
20
20
  gem 'activerecord-oracle_enhanced-adapter', '~> 7.0.0'
21
- gem 'ruby-oci8' # only for CRuby users
22
21
  ```
23
22
 
24
23
  ### Rails 6.1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.0.2
1
+ 7.1.0.beta1
@@ -13,6 +13,11 @@ module ActiveRecord
13
13
  def virtual?
14
14
  virtual
15
15
  end
16
+
17
+ def auto_incremented_by_db?
18
+ # TODO: Identify if a column is the primary key and is auto-incremented (e.g. by a sequence)
19
+ super
20
+ end
16
21
  end
17
22
  end
18
23
  end
@@ -101,7 +101,7 @@ module ActiveRecord
101
101
  _oracle_downcase(col_name)
102
102
  end
103
103
  row = cursor.fetch
104
- columns.each_with_index.map { |x, i| [x, row[i]] }.to_h if row
104
+ columns.each_with_index.to_h { |x, i| [x, row[i]] } if row
105
105
  ensure
106
106
  cursor.close
107
107
  end
@@ -17,13 +17,13 @@ module ActiveRecord
17
17
  def table_name_length
18
18
  IDENTIFIER_MAX_LENGTH
19
19
  end
20
- deprecate :table_name_length
20
+ deprecate :table_name_length, deprecator: ActiveSupport::Deprecation.new
21
21
 
22
22
  # the maximum length of a column name
23
23
  def column_name_length
24
24
  IDENTIFIER_MAX_LENGTH
25
25
  end
26
- deprecate :column_name_length
26
+ deprecate :column_name_length, deprecator: ActiveSupport::Deprecation.new
27
27
 
28
28
  # the maximum length of an index name
29
29
  # supported by this database
@@ -9,13 +9,13 @@ module ActiveRecord
9
9
  # see: abstract/database_statements.rb
10
10
 
11
11
  # Executes a SQL statement
12
- def execute(sql, name = nil, async: false)
12
+ def execute(sql, name = nil, async: false, allow_retry: false)
13
13
  sql = transform_query(sql)
14
14
 
15
- log(sql, name, async: async) { @connection.exec(sql) }
15
+ log(sql, name, async: async) { _connection.exec(sql, allow_retry: allow_retry) }
16
16
  end
17
17
 
18
- def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)
18
+ def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false, allow_retry: false)
19
19
  sql = transform_query(sql)
20
20
 
21
21
  type_casted_binds = type_casted_binds(binds)
@@ -25,10 +25,10 @@ module ActiveRecord
25
25
  cached = false
26
26
  with_retry do
27
27
  if without_prepared_statement?(binds)
28
- cursor = @connection.prepare(sql)
28
+ cursor = _connection.prepare(sql)
29
29
  else
30
30
  unless @statements.key? sql
31
- @statements[sql] = @connection.prepare(sql)
31
+ @statements[sql] = _connection.prepare(sql)
32
32
  end
33
33
 
34
34
  cursor = @statements[sql]
@@ -59,6 +59,7 @@ module ActiveRecord
59
59
  res
60
60
  end
61
61
  end
62
+ alias_method :internal_exec_query, :exec_query
62
63
 
63
64
  def supports_explain?
64
65
  true
@@ -77,7 +78,7 @@ module ActiveRecord
77
78
 
78
79
  # New method in ActiveRecord 3.1
79
80
  # Will add RETURNING clause in case of trigger generated primary keys
80
- def sql_for_insert(sql, pk, binds)
81
+ def sql_for_insert(sql, pk, binds, _returning)
81
82
  unless pk == false || pk.nil? || pk.is_a?(Array) || pk.is_a?(String)
82
83
  sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO :returning_id"
83
84
  (binds = binds.dup) << ActiveRecord::Relation::QueryAttribute.new("returning_id", nil, Type::OracleEnhanced::Integer.new)
@@ -85,14 +86,14 @@ module ActiveRecord
85
86
  super
86
87
  end
87
88
 
88
- def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
89
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil)
89
90
  pk = nil if id_value
90
- super
91
+ Array(super || id_value)
91
92
  end
92
93
 
93
94
  # New method in ActiveRecord 3.1
94
- def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
95
- sql, binds = sql_for_insert(sql, pk, binds)
95
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning: nil)
96
+ sql, binds = sql_for_insert(sql, pk, binds, returning)
96
97
  type_casted_binds = type_casted_binds(binds)
97
98
 
98
99
  log(sql, name, binds, type_casted_binds) do
@@ -101,10 +102,10 @@ module ActiveRecord
101
102
  returning_id_col = returning_id_index = nil
102
103
  with_retry do
103
104
  if without_prepared_statement?(binds)
104
- cursor = @connection.prepare(sql)
105
+ cursor = _connection.prepare(sql)
105
106
  else
106
107
  unless @statements.key?(sql)
107
- @statements[sql] = @connection.prepare(sql)
108
+ @statements[sql] = _connection.prepare(sql)
108
109
  end
109
110
 
110
111
  cursor = @statements[sql]
@@ -141,12 +142,12 @@ module ActiveRecord
141
142
  with_retry do
142
143
  cached = false
143
144
  if without_prepared_statement?(binds)
144
- cursor = @connection.prepare(sql)
145
+ cursor = _connection.prepare(sql)
145
146
  else
146
147
  if @statements.key?(sql)
147
148
  cursor = @statements[sql]
148
149
  else
149
- cursor = @statements[sql] = @connection.prepare(sql)
150
+ cursor = @statements[sql] = _connection.prepare(sql)
150
151
  end
151
152
 
152
153
  cursor.bind_params(type_casted_binds)
@@ -163,8 +164,12 @@ module ActiveRecord
163
164
 
164
165
  alias :exec_delete :exec_update
165
166
 
167
+ def returning_column_values(result)
168
+ result.rows.first
169
+ end
170
+
166
171
  def begin_db_transaction # :nodoc:
167
- @connection.autocommit = false
172
+ _connection.autocommit = false
168
173
  end
169
174
 
170
175
  def transaction_isolation_levels
@@ -183,15 +188,15 @@ module ActiveRecord
183
188
  end
184
189
 
185
190
  def commit_db_transaction # :nodoc:
186
- @connection.commit
191
+ _connection.commit
187
192
  ensure
188
- @connection.autocommit = true
193
+ _connection.autocommit = true
189
194
  end
190
195
 
191
196
  def exec_rollback_db_transaction # :nodoc:
192
- @connection.rollback
197
+ _connection.rollback
193
198
  ensure
194
- @connection.autocommit = true
199
+ _connection.autocommit = true
195
200
  end
196
201
 
197
202
  def create_savepoint(name = current_savepoint_name) # :nodoc:
@@ -265,14 +270,14 @@ module ActiveRecord
265
270
  raise ActiveRecord::RecordNotFound, "statement #{sql} returned no rows"
266
271
  end
267
272
  lob = lob_record[col.name]
268
- @connection.write_lob(lob, value.to_s, col.type == :binary)
273
+ _connection.write_lob(lob, value.to_s, col.type == :binary)
269
274
  end
270
275
  end
271
276
  end
272
277
 
273
278
  private
274
279
  def with_retry
275
- @connection.with_retry do
280
+ _connection.with_retry do
276
281
  yield
277
282
  rescue
278
283
  @statements.clear
@@ -31,8 +31,21 @@ module ActiveRecord
31
31
  end
32
32
 
33
33
  private
34
- def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false)
35
- super
34
+ def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false, &block)
35
+ @instrumenter.instrument(
36
+ "sql.active_record",
37
+ sql: sql,
38
+ name: name,
39
+ binds: binds,
40
+ type_casted_binds: type_casted_binds,
41
+ statement_name: statement_name,
42
+ async: async,
43
+ connection: self,
44
+ &block
45
+ )
46
+ rescue => e
47
+ # FIXME: raise ex.set_query(sql, binds)
48
+ raise translate_exception_class(e, sql, binds)
36
49
  ensure
37
50
  log_dbms_output if dbms_output_enabled?
38
51
  end
@@ -135,6 +135,13 @@ module ActiveRecord
135
135
  properties.put("defaultRowPrefetch", "#{prefetch_rows}") if prefetch_rows
136
136
  properties.put("internal_logon", privilege) if privilege
137
137
 
138
+ if config[:jdbc_connect_properties] # arbitrary additional properties for JDBC connection
139
+ raise "jdbc_connect_properties should contain an associative array / hash" unless config[:jdbc_connect_properties].is_a? Hash
140
+ config[:jdbc_connect_properties].each do |key, value|
141
+ properties.put(key, value)
142
+ end
143
+ end
144
+
138
145
  begin
139
146
  @raw_connection = java.sql.DriverManager.getConnection(url, properties)
140
147
  rescue
@@ -295,7 +302,7 @@ module ActiveRecord
295
302
 
296
303
  class Cursor
297
304
  def initialize(connection, raw_statement)
298
- @connection = connection
305
+ @raw_connection = connection
299
306
  @raw_statement = raw_statement
300
307
  end
301
308
 
@@ -384,7 +391,7 @@ module ActiveRecord
384
391
  row_values = []
385
392
  column_types.each_with_index do |column_type, i|
386
393
  row_values <<
387
- @connection.get_ruby_value_from_result_set(@raw_result_set, i + 1, column_type, get_lob_value)
394
+ @raw_connection.get_ruby_value_from_result_set(@raw_result_set, i + 1, column_type, get_lob_value)
388
395
  end
389
396
  row_values
390
397
  else
@@ -7,15 +7,15 @@ module ActiveRecord
7
7
  def type_cast(value)
8
8
  case value
9
9
  when ActiveModel::Type::Binary::Data
10
- blob = Java::OracleSql::BLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::BLOB::DURATION_SESSION)
10
+ blob = Java::OracleSql::BLOB.createTemporary(@raw_connection.raw_connection, false, Java::OracleSql::BLOB::DURATION_SESSION)
11
11
  blob.setBytes(1, value.to_s.to_java_bytes)
12
12
  blob
13
13
  when Type::OracleEnhanced::Text::Data
14
- clob = Java::OracleSql::CLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::CLOB::DURATION_SESSION)
14
+ clob = Java::OracleSql::CLOB.createTemporary(@raw_connection.raw_connection, false, Java::OracleSql::CLOB::DURATION_SESSION)
15
15
  clob.setString(1, value.to_s)
16
16
  clob
17
17
  when Type::OracleEnhanced::NationalCharacterText::Data
18
- clob = Java::OracleSql::NCLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::NCLOB::DURATION_SESSION)
18
+ clob = Java::OracleSql::NCLOB.createTemporary(@raw_connection.raw_connection, false, Java::OracleSql::NCLOB::DURATION_SESSION)
19
19
  clob.setString(1, value.to_s)
20
20
  clob
21
21
  else
@@ -41,7 +41,7 @@ module ActiveRecord
41
41
  # ActiveRecord Oracle enhanced adapter puts OCI8EnhancedAutoRecover wrapper around OCI8
42
42
  # in this case we need to pass original OCI8 connection
43
43
  else
44
- @raw_connection.instance_variable_get(:@connection)
44
+ @raw_connection.instance_variable_get(:@raw_connection)
45
45
  end
46
46
  end
47
47
 
@@ -87,18 +87,22 @@ module ActiveRecord
87
87
  @raw_connection.active?
88
88
  end
89
89
 
90
+ def reset
91
+ @raw_connection.reset
92
+ end
93
+
90
94
  def reset!
91
95
  @raw_connection.reset!
92
96
  rescue OCIException => e
93
97
  raise OracleEnhanced::ConnectionException, e.message
94
98
  end
95
99
 
96
- def exec(sql, *bindvars, &block)
97
- @raw_connection.exec(sql, *bindvars, &block)
100
+ def exec(sql, *bindvars, allow_retry: false, &block)
101
+ with_retry(allow_retry: allow_retry) { @raw_connection.exec(sql, *bindvars, &block) }
98
102
  end
99
103
 
100
- def with_retry(&block)
101
- @raw_connection.with_retry(&block)
104
+ def with_retry(allow_retry: false, &block)
105
+ @raw_connection.with_retry(allow_retry: allow_retry, &block)
102
106
  end
103
107
 
104
108
  def prepare(sql)
@@ -107,7 +111,7 @@ module ActiveRecord
107
111
 
108
112
  class Cursor
109
113
  def initialize(connection, raw_cursor)
110
- @connection = connection
114
+ @raw_connection = connection
111
115
  @raw_cursor = raw_cursor
112
116
  end
113
117
 
@@ -159,7 +163,7 @@ module ActiveRecord
159
163
  get_lob_value = options[:get_lob_value]
160
164
  col_index = 0
161
165
  row.map do |col|
162
- col_value = @connection.typecast_result_value(col, get_lob_value)
166
+ col_value = @raw_connection.typecast_result_value(col, get_lob_value)
163
167
  col_metadata = @raw_cursor.column_metadata.fetch(col_index)
164
168
  if !col_metadata.nil?
165
169
  key = col_metadata.data_type
@@ -390,27 +394,32 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) # :nodoc:
390
394
  @active = true
391
395
  @config = config
392
396
  @factory = factory
393
- @connection = @factory.new_connection @config
394
- super @connection
397
+ @raw_connection = @factory.new_connection @config
398
+ super @raw_connection
395
399
  end
396
400
 
397
401
  # Checks connection, returns true if active. Note that ping actively
398
402
  # checks the connection, while #active? simply returns the last
399
403
  # known state.
400
404
  def ping # :nodoc:
401
- @connection.exec("select 1 from dual") { |r| nil }
405
+ @raw_connection.exec("select 1 from dual") { |r| nil }
402
406
  @active = true
403
407
  rescue
404
408
  @active = false
405
409
  raise
406
410
  end
407
411
 
412
+ def reset
413
+ # tentative
414
+ reset!
415
+ end
416
+
408
417
  # Resets connection, by logging off and creating a new connection.
409
418
  def reset! # :nodoc:
410
419
  logoff rescue nil
411
420
  begin
412
- @connection = @factory.new_connection @config
413
- __setobj__ @connection
421
+ @raw_connection = @factory.new_connection @config
422
+ __setobj__ @raw_connection
414
423
  @active = true
415
424
  rescue
416
425
  @active = false
@@ -426,8 +435,8 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) # :nodoc:
426
435
  LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114, 3135 ] # :nodoc:
427
436
 
428
437
  # Adds auto-recovery functionality.
429
- def with_retry # :nodoc:
430
- should_retry = self.class.auto_retry? && autocommit?
438
+ def with_retry(allow_retry: false) # :nodoc:
439
+ should_retry = (allow_retry || self.class.auto_retry?) && autocommit?
431
440
 
432
441
  begin
433
442
  yield
@@ -442,7 +451,7 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) # :nodoc:
442
451
  end
443
452
 
444
453
  def exec(sql, *bindvars, &block) # :nodoc:
445
- with_retry { @connection.exec(sql, *bindvars, &block) }
454
+ with_retry { @raw_connection.exec(sql, *bindvars, &block) }
446
455
  end
447
456
  end
448
457
  # :startdoc:
@@ -9,19 +9,19 @@ module ActiveRecord
9
9
  when ActiveModel::Type::Binary::Data
10
10
  lob_value = value == "" ? " " : value
11
11
  bind_type = OCI8::BLOB
12
- ora_value = bind_type.new(@connection.raw_oci_connection, lob_value)
12
+ ora_value = bind_type.new(_connection.raw_oci_connection, lob_value)
13
13
  ora_value.size = 0 if value == ""
14
14
  ora_value
15
15
  when Type::OracleEnhanced::Text::Data
16
16
  lob_value = value.to_s == "" ? " " : value.to_s
17
17
  bind_type = OCI8::CLOB
18
- ora_value = bind_type.new(@connection.raw_oci_connection, lob_value)
18
+ ora_value = bind_type.new(_connection.raw_oci_connection, lob_value)
19
19
  ora_value.size = 0 if value.to_s == ""
20
20
  ora_value
21
21
  when Type::OracleEnhanced::NationalCharacterText::Data
22
22
  lob_value = value.to_s == "" ? " " : value.to_s
23
23
  bind_type = OCI8::NCLOB
24
- ora_value = bind_type.new(@connection.raw_oci_connection, lob_value)
24
+ ora_value = bind_type.new(_connection.raw_oci_connection, lob_value)
25
25
  ora_value.size = 0 if value.to_s == ""
26
26
  ora_value
27
27
  else
@@ -7,10 +7,12 @@ module ActiveRecord
7
7
  # QUOTING ==================================================
8
8
  #
9
9
  # see: abstract/quoting.rb
10
+ QUOTED_COLUMN_NAMES = Concurrent::Map.new # :nodoc:
11
+ QUOTED_TABLE_NAMES = Concurrent::Map.new # :nodoc:
10
12
 
11
13
  def quote_column_name(name) # :nodoc:
12
14
  name = name.to_s
13
- self.class.quoted_column_names[name] ||= if /\A[a-z][a-z_0-9$#]*\Z/.match?(name)
15
+ QUOTED_COLUMN_NAMES[name] ||= if /\A[a-z][a-z_0-9$#]*\Z/.match?(name)
14
16
  "\"#{name.upcase}\""
15
17
  else
16
18
  # remove double quotes which cannot be used inside quoted identifier
@@ -26,7 +28,7 @@ module ActiveRecord
26
28
  # if only valid lowercase column characters in name
27
29
  when /^[a-z][a-z_0-9$#]*$/
28
30
  "\"#{name.upcase}\""
29
- when /^[a-z][a-z_0-9$#\-]*$/i
31
+ when /^[a-z][a-z_0-9$#-]*$/i
30
32
  "\"#{name}\""
31
33
  # if other characters present then assume that it is expression
32
34
  # which should not be quoted
@@ -67,7 +69,7 @@ module ActiveRecord
67
69
 
68
70
  def quote_table_name(name) # :nodoc:
69
71
  name, _link = name.to_s.split("@")
70
- self.class.quoted_table_names[name] ||= [name.split(".").map { |n| quote_column_name(n) }].join(".")
72
+ QUOTED_TABLE_NAMES[name] ||= [name.split(".").map { |n| quote_column_name(n) }].join(".")
71
73
  end
72
74
 
73
75
  def quote_string(s) # :nodoc:
@@ -142,7 +144,7 @@ module ActiveRecord
142
144
  (
143
145
  (?:
144
146
  # "table_name"."column_name" | function(one or no argument)
145
- ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
147
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+") | \w+\((?:|\g<2>)\))
146
148
  )
147
149
  (?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
148
150
  )
@@ -155,7 +157,7 @@ module ActiveRecord
155
157
  (
156
158
  (?:
157
159
  # "table_name"."column_name" | function(one or no argument)
158
- ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
160
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+") | \w+\((?:|\g<2>)\))
159
161
  )
160
162
  (?:\s+ASC|\s+DESC)?
161
163
  (?:\s+NULLS\s+(?:FIRST|LAST))?
@@ -20,7 +20,7 @@ module ActiveRecord
20
20
  statements = o.columns.map { |c| accept c }
21
21
  statements << accept(o.primary_keys) if o.primary_keys
22
22
 
23
- if supports_foreign_keys?
23
+ if use_foreign_keys?
24
24
  statements.concat(o.foreign_keys.map { |fk| accept fk })
25
25
  end
26
26
 
@@ -81,6 +81,11 @@ module ActiveRecord
81
81
  super(*args, type: :integer, **options)
82
82
  end
83
83
  alias :belongs_to :references
84
+
85
+ private
86
+ def valid_column_definition_options
87
+ super + [ :as, :sequence_name, :sequence_start_value, :type ]
88
+ end
84
89
  end
85
90
 
86
91
  class AlterTable < ActiveRecord::ConnectionAdapters::AlterTable
@@ -181,7 +181,7 @@ module ActiveRecord # :nodoc:
181
181
  def extract_expression_for_virtual_column(column)
182
182
  column_name = column.name
183
183
  @connection.select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name.upcase), bind_string("column_name", column_name.upcase)]).inspect
184
- select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ data_default from all_tab_columns
184
+ select data_default from all_tab_columns
185
185
  where owner = SYS_CONTEXT('userenv', 'current_schema')
186
186
  and table_name = :table_name
187
187
  and column_name = :column_name