activerecord-oracle_enhanced-adapter 6.0.0.rc3 → 6.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +126 -0
  3. data/README.md +13 -2
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +2 -3
  6. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +0 -1
  7. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +0 -9
  8. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +64 -47
  9. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +4 -5
  10. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +0 -1
  11. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +3 -4
  12. data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +1 -2
  13. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +12 -7
  14. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +0 -1
  15. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +38 -3
  16. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +3 -4
  17. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +1 -1
  18. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +15 -3
  19. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +48 -45
  20. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +16 -17
  21. data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +2 -1
  22. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +57 -15
  23. data/lib/active_record/type/oracle_enhanced/boolean.rb +0 -1
  24. data/lib/active_record/type/oracle_enhanced/integer.rb +0 -1
  25. data/lib/arel/visitors/oracle.rb +253 -0
  26. data/lib/arel/visitors/oracle12.rb +160 -0
  27. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +35 -3
  28. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +6 -1
  29. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +0 -1
  30. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +28 -1
  31. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +2 -1
  32. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +48 -0
  33. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +4 -2
  34. data/spec/spec_config.yaml.template +2 -2
  35. data/spec/spec_helper.rb +13 -4
  36. data/spec/support/stats.sql +3 -0
  37. metadata +30 -26
@@ -18,13 +18,12 @@ module ActiveRecord #:nodoc:
18
18
  module ClassMethods
19
19
  def lob_columns
20
20
  columns.select do |column|
21
- column.sql_type_metadata.sql_type =~ /LOB$/
21
+ column.sql_type_metadata.sql_type.end_with?("LOB")
22
22
  end
23
23
  end
24
24
  end
25
25
 
26
26
  private
27
-
28
27
  def enhanced_write_lobs
29
28
  if self.class.connection.is_a?(ConnectionAdapters::OracleEnhancedAdapter) &&
30
29
  !(self.class.custom_create_method || self.class.custom_update_method)
@@ -97,6 +97,10 @@ module ActiveRecord
97
97
  @raw_connection.exec(sql, *bindvars, &block)
98
98
  end
99
99
 
100
+ def with_retry(&block)
101
+ @raw_connection.with_retry(&block)
102
+ end
103
+
100
104
  def prepare(sql)
101
105
  Cursor.new(self, @raw_connection.parse(sql))
102
106
  end
@@ -265,7 +269,6 @@ module ActiveRecord
265
269
  end
266
270
 
267
271
  private
268
-
269
272
  def date_without_time?(value)
270
273
  case value
271
274
  when OraDate
@@ -319,9 +322,9 @@ module ActiveRecord
319
322
  # connection using host, port and database name
320
323
  elsif host || port
321
324
  host ||= "localhost"
322
- host = "[#{host}]" if host =~ /^[^\[].*:/ # IPv6
325
+ host = "[#{host}]" if /^[^\[].*:/.match?(host) # IPv6
323
326
  port ||= 1521
324
- database = "/#{database}" unless database.match(/^\//)
327
+ database = "/#{database}" unless database.start_with?("/")
325
328
  "//#{host}:#{port}#{database}"
326
329
  # if no host is specified then assume that
327
330
  # database parameter is TNS alias or TNS connection string
@@ -423,13 +426,11 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
423
426
  LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114, 3135 ] #:nodoc:
424
427
 
425
428
  # Adds auto-recovery functionality.
426
- #
427
- # See: http://www.jiubao.org/ruby-oci8/api.en.html#label-11
428
- def exec(sql, *bindvars, &block) #:nodoc:
429
+ def with_retry #:nodoc:
429
430
  should_retry = self.class.auto_retry? && autocommit?
430
431
 
431
432
  begin
432
- @connection.exec(sql, *bindvars, &block)
433
+ yield
433
434
  rescue OCIException => e
434
435
  raise unless e.is_a?(OCIError) && LOST_CONNECTION_ERROR_CODES.include?(e.code)
435
436
  @active = false
@@ -439,5 +440,9 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
439
440
  retry
440
441
  end
441
442
  end
443
+
444
+ def exec(sql, *bindvars, &block) #:nodoc:
445
+ with_retry { @connection.exec(sql, *bindvars, &block) }
446
+ end
442
447
  end
443
448
  #:startdoc:
@@ -97,7 +97,6 @@ module ActiveRecord #:nodoc:
97
97
  end
98
98
 
99
99
  private
100
-
101
100
  # Creates a record with custom create method
102
101
  # and returns its id.
103
102
  def _create_record
@@ -132,8 +132,43 @@ module ActiveRecord
132
132
  end
133
133
  end
134
134
 
135
- private
135
+ def column_name_matcher
136
+ COLUMN_NAME
137
+ end
138
+
139
+ def column_name_with_order_matcher
140
+ COLUMN_NAME_WITH_ORDER
141
+ end
142
+
143
+ COLUMN_NAME = /
144
+ \A
145
+ (
146
+ (?:
147
+ # "table_name"."column_name" | function(one or no argument)
148
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
149
+ )
150
+ (?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
151
+ )
152
+ (?:\s*,\s*\g<1>)*
153
+ \z
154
+ /ix
155
+
156
+ COLUMN_NAME_WITH_ORDER = /
157
+ \A
158
+ (
159
+ (?:
160
+ # "table_name"."column_name" | function(one or no argument)
161
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
162
+ )
163
+ (?:\s+ASC|\s+DESC)?
164
+ (?:\s+NULLS\s+(?:FIRST|LAST))?
165
+ )
166
+ (?:\s*,\s*\g<1>)*
167
+ \z
168
+ /ix
169
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
136
170
 
171
+ private
137
172
  def oracle_downcase(column_name)
138
173
  return nil if column_name.nil?
139
174
  /[a-z]/.match?(column_name) ? column_name : column_name.downcase
@@ -143,8 +178,8 @@ module ActiveRecord
143
178
  end
144
179
  end
145
180
 
146
- # if MRI or YARV
147
- if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
181
+ # if MRI or YARV or TruffleRuby
182
+ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby"
148
183
  require "active_record/connection_adapters/oracle_enhanced/oci_quoting"
149
184
  # if JRuby
150
185
  elsif RUBY_ENGINE == "jruby"
@@ -3,11 +3,10 @@
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module OracleEnhanced
6
- class SchemaCreation < AbstractAdapter::SchemaCreation
6
+ class SchemaCreation < SchemaCreation
7
7
  private
8
-
9
8
  def visit_ColumnDefinition(o)
10
- if [:blob, :clob, :nclob].include?(sql_type = type_to_sql(o.type, o.options).downcase.to_sym)
9
+ if [:blob, :clob, :nclob].include?(sql_type = type_to_sql(o.type, **o.options).downcase.to_sym)
11
10
  if (tablespace = default_tablespace_for(sql_type))
12
11
  @lob_tablespaces ||= {}
13
12
  @lob_tablespaces[o.name] = tablespace
@@ -36,7 +35,7 @@ module ActiveRecord
36
35
  create_sql << " TABLESPACE #{tablespace}"
37
36
  end
38
37
  end
39
- add_table_options!(create_sql, table_options(o))
38
+ add_table_options!(create_sql, o)
40
39
  create_sql << " AS #{to_sql(o.as)}" if o.as
41
40
  create_sql
42
41
  end
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  ].each do |column_type|
18
18
  module_eval <<-CODE, __FILE__, __LINE__ + 1
19
19
  def #{column_type}(*args, **options)
20
- args.each { |name| column(name, :#{column_type}, options) }
20
+ args.each { |name| column(name, :#{column_type}, **options) }
21
21
  end
22
22
  CODE
23
23
  end
@@ -4,7 +4,15 @@ module ActiveRecord #:nodoc:
4
4
  module ConnectionAdapters #:nodoc:
5
5
  module OracleEnhanced #:nodoc:
6
6
  class SchemaDumper < ConnectionAdapters::SchemaDumper #:nodoc:
7
+ DEFAULT_PRIMARY_KEY_COLUMN_SPEC = { precision: "38", null: "false" }.freeze
8
+ private_constant :DEFAULT_PRIMARY_KEY_COLUMN_SPEC
9
+
7
10
  private
11
+ def column_spec_for_primary_key(column)
12
+ spec = super
13
+ spec.except!(:precision) if prepare_column_options(column) == DEFAULT_PRIMARY_KEY_COLUMN_SPEC
14
+ spec
15
+ end
8
16
 
9
17
  def tables(stream)
10
18
  # do not include materialized views in schema dump - they should be created separately after schema creation
@@ -51,6 +59,7 @@ module ActiveRecord #:nodoc:
51
59
  else
52
60
  statement_parts = [ ("add_context_index " + remove_prefix_and_suffix(table).inspect) ]
53
61
  statement_parts << index.columns.inspect
62
+ statement_parts << ("sync: " + $1.inspect) if index.parameters =~ /SYNC\((.*?)\)/
54
63
  statement_parts << ("name: " + index.name.inspect)
55
64
  end
56
65
  else
@@ -72,7 +81,7 @@ module ActiveRecord #:nodoc:
72
81
  index_statements = indexes.map do |index|
73
82
  " t.index #{index_parts(index).join(', ')}" unless index.type == "CTXSYS.CONTEXT"
74
83
  end
75
- stream.puts index_statements.sort.join("\n")
84
+ stream.puts index_statements.compact.sort.join("\n")
76
85
  end
77
86
  end
78
87
 
@@ -107,7 +116,10 @@ module ActiveRecord #:nodoc:
107
116
  tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
108
117
  pkcol = columns.detect { |c| c.name == pk }
109
118
  pkcolspec = column_spec_for_primary_key(pkcol)
110
- if pkcolspec.present?
119
+ unless pkcolspec.empty?
120
+ if pkcolspec != pkcolspec.slice(:id, :default)
121
+ pkcolspec = { id: { type: pkcolspec.delete(:id), **pkcolspec }.compact }
122
+ end
111
123
  tbl.print ", #{format_colspec(pkcolspec)}"
112
124
  end
113
125
  when Array
@@ -168,7 +180,7 @@ module ActiveRecord #:nodoc:
168
180
 
169
181
  def extract_expression_for_virtual_column(column)
170
182
  column_name = column.name
171
- @connection.select_value(<<~SQL.squish, "Table comment", [bind_string("table_name", table_name.upcase), bind_string("column_name", column_name.upcase)]).inspect
183
+ @connection.select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name.upcase), bind_string("column_name", column_name.upcase)]).inspect
172
184
  select data_default from all_tab_columns
173
185
  where owner = SYS_CONTEXT('userenv', 'current_schema')
174
186
  and table_name = :table_name
@@ -11,7 +11,7 @@ module ActiveRecord
11
11
  # see: abstract/schema_statements.rb
12
12
 
13
13
  def tables #:nodoc:
14
- select_values(<<~SQL.squish, "tables")
14
+ select_values(<<~SQL.squish, "SCHEMA")
15
15
  SELECT DECODE(table_name, UPPER(table_name), LOWER(table_name), table_name)
16
16
  FROM all_tables
17
17
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
@@ -43,7 +43,7 @@ module ActiveRecord
43
43
  table_owner, table_name = default_owner, real_name
44
44
  end
45
45
 
46
- select_values(<<~SQL.squish, "table exists", [bind_string("owner", table_owner), bind_string("table_name", table_name)]).any?
46
+ select_values(<<~SQL.squish, "SCHEMA", [bind_string("owner", table_owner), bind_string("table_name", table_name)]).any?
47
47
  SELECT owner, table_name
48
48
  FROM all_tables
49
49
  WHERE owner = :owner
@@ -59,20 +59,20 @@ module ActiveRecord
59
59
  end
60
60
 
61
61
  def views # :nodoc:
62
- select_values(<<~SQL.squish, "views")
62
+ select_values(<<~SQL.squish, "SCHEMA")
63
63
  SELECT LOWER(view_name) FROM all_views WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
64
64
  SQL
65
65
  end
66
66
 
67
67
  def materialized_views #:nodoc:
68
- select_values(<<~SQL.squish, "materialized views")
68
+ select_values(<<~SQL.squish, "SCHEMA")
69
69
  SELECT LOWER(mview_name) FROM all_mviews WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
70
70
  SQL
71
71
  end
72
72
 
73
73
  # get synonyms for schema dump
74
74
  def synonyms
75
- result = select_all(<<~SQL.squish, "synonyms")
75
+ result = select_all(<<~SQL.squish, "SCHEMA")
76
76
  SELECT synonym_name, table_owner, table_name
77
77
  FROM all_synonyms where owner = SYS_CONTEXT('userenv', 'current_schema')
78
78
  SQL
@@ -87,7 +87,7 @@ module ActiveRecord
87
87
  (_owner, table_name) = @connection.describe(table_name)
88
88
  default_tablespace_name = default_tablespace
89
89
 
90
- result = select_all(<<~SQL.squish, "indexes", [bind_string("table_name", table_name)])
90
+ result = select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
91
91
  SELECT LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
92
92
  i.index_type, i.ityp_owner, i.ityp_name, i.parameters,
93
93
  LOWER(i.tablespace_name) AS tablespace_name,
@@ -117,7 +117,7 @@ module ActiveRecord
117
117
  statement_parameters = nil
118
118
  if row["index_type"] == "DOMAIN" && row["ityp_owner"] == "CTXSYS" && row["ityp_name"] == "CONTEXT"
119
119
  procedure_name = default_datastore_procedure(row["index_name"])
120
- source = select_values(<<~SQL.squish, "procedure", [bind_string("procedure_name", procedure_name.upcase)]).join
120
+ source = select_values(<<~SQL.squish, "SCHEMA", [bind_string("procedure_name", procedure_name.upcase)]).join
121
121
  SELECT text
122
122
  FROM all_source
123
123
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
@@ -196,19 +196,19 @@ module ActiveRecord
196
196
  # t.string :last_name, :comment => “Surname”
197
197
  # end
198
198
 
199
- def create_table(table_name, **options)
200
- create_sequence = options[:id] != false
201
- td = create_table_definition table_name, options
199
+ def create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options)
200
+ create_sequence = id != false
201
+ td = create_table_definition(
202
+ table_name, **options.extract!(:temporary, :options, :as, :comment, :tablespace, :organization)
203
+ )
202
204
 
203
- if options[:id] != false && !options[:as]
204
- pk = options.fetch(:primary_key) do
205
- Base.get_primary_key table_name.to_s.singularize
206
- end
205
+ if id && !td.as
206
+ pk = primary_key || Base.get_primary_key(table_name.to_s.singularize)
207
207
 
208
208
  if pk.is_a?(Array)
209
209
  td.primary_keys pk
210
210
  else
211
- td.primary_key pk, options.fetch(:id, :primary_key), options
211
+ td.primary_key pk, id, **options
212
212
  end
213
213
  end
214
214
 
@@ -226,8 +226,10 @@ module ActiveRecord
226
226
  yield td if block_given?
227
227
  create_sequence = create_sequence || td.create_sequence
228
228
 
229
- if options[:force] && data_source_exists?(table_name)
230
- drop_table(table_name, options)
229
+ if force && data_source_exists?(table_name)
230
+ drop_table(table_name, force: force, if_exists: true)
231
+ else
232
+ schema_cache.clear_data_source_cache!(table_name.to_s)
231
233
  end
232
234
 
233
235
  execute schema_creation.accept td
@@ -235,14 +237,14 @@ module ActiveRecord
235
237
  create_sequence_and_trigger(table_name, options) if create_sequence
236
238
 
237
239
  if supports_comments? && !supports_comments_in_create?
238
- if table_comment = options[:comment].presence
240
+ if table_comment = td.comment.presence
239
241
  change_table_comment(table_name, table_comment)
240
242
  end
241
243
  td.columns.each do |column|
242
244
  change_column_comment(table_name, column.name, column.comment) if column.comment.present?
243
245
  end
244
246
  end
245
- td.indexes.each { |c, o| add_index table_name, c, o }
247
+ td.indexes.each { |c, o| add_index table_name, c, **o }
246
248
 
247
249
  rebuild_primary_key_index_to_default_tablespace(table_name, options)
248
250
  end
@@ -251,13 +253,16 @@ module ActiveRecord
251
253
  if new_name.to_s.length > DatabaseLimits::IDENTIFIER_MAX_LENGTH
252
254
  raise ArgumentError, "New table name '#{new_name}' is too long; the limit is #{DatabaseLimits::IDENTIFIER_MAX_LENGTH} characters"
253
255
  end
256
+ schema_cache.clear_data_source_cache!(table_name.to_s)
257
+ schema_cache.clear_data_source_cache!(new_name.to_s)
254
258
  execute "RENAME #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
255
259
  execute "RENAME #{quote_table_name("#{table_name}_seq")} TO #{default_sequence_name(new_name)}" rescue nil
256
260
 
257
261
  rename_table_indexes(table_name, new_name)
258
262
  end
259
263
 
260
- def drop_table(table_name, options = {}) #:nodoc:
264
+ def drop_table(table_name, **options) #:nodoc:
265
+ schema_cache.clear_data_source_cache!(table_name.to_s)
261
266
  execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE CONSTRAINTS' if options[:force] == :cascade}"
262
267
  seq_name = options[:sequence_name] || default_sequence_name(table_name)
263
268
  execute "DROP SEQUENCE #{quote_table_name(seq_name)}" rescue nil
@@ -287,8 +292,8 @@ module ActiveRecord
287
292
  end
288
293
  end
289
294
 
290
- def add_index(table_name, column_name, options = {}) #:nodoc:
291
- index_name, index_type, quoted_column_names, tablespace, index_options = add_index_options(table_name, column_name, options)
295
+ def add_index(table_name, column_name, **options) #:nodoc:
296
+ index_name, index_type, quoted_column_names, tablespace, index_options = add_index_options(table_name, column_name, **options)
292
297
  execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})#{tablespace} #{index_options}"
293
298
  if index_type == "UNIQUE"
294
299
  unless /\(.*\)/.match?(quoted_column_names)
@@ -306,13 +311,11 @@ module ActiveRecord
306
311
  index_type = options[:unique] ? "UNIQUE" : ""
307
312
  index_name = options[:name].to_s if options.key?(:name)
308
313
  tablespace = tablespace_for(:index, options[:tablespace])
309
- max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length
310
- # TODO: This option is used for NOLOGGING, needs better argumetn name
314
+ # TODO: This option is used for NOLOGGING, needs better argument name
311
315
  index_options = options[:options]
312
316
 
313
- if index_name.to_s.length > max_index_length
314
- raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
315
- end
317
+ validate_index_length!(table_name, index_name, options.fetch(:internal, false))
318
+
316
319
  if table_exists?(table_name) && index_name_exists?(table_name, index_name)
317
320
  raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
318
321
  end
@@ -323,8 +326,8 @@ module ActiveRecord
323
326
 
324
327
  # Remove the given index from the table.
325
328
  # Gives warning if index does not exist
326
- def remove_index(table_name, options = {}) #:nodoc:
327
- index_name = index_name_for_remove(table_name, options)
329
+ def remove_index(table_name, column_name = nil, **options) #:nodoc:
330
+ index_name = index_name_for_remove(table_name, column_name, options)
328
331
  # TODO: It should execute only when index_type == "UNIQUE"
329
332
  execute "ALTER TABLE #{quote_table_name(table_name)} DROP CONSTRAINT #{quote_column_name(index_name)}" rescue nil
330
333
  execute "DROP INDEX #{quote_column_name(index_name)}"
@@ -361,7 +364,7 @@ module ActiveRecord
361
364
  # Will always query database and not index cache.
362
365
  def index_name_exists?(table_name, index_name)
363
366
  (_owner, table_name) = @connection.describe(table_name)
364
- result = select_value(<<~SQL.squish, "index name exists")
367
+ result = select_value(<<~SQL.squish, "SCHEMA")
365
368
  SELECT 1 FROM all_indexes i
366
369
  WHERE i.owner = SYS_CONTEXT('userenv', 'current_schema')
367
370
  AND i.table_owner = SYS_CONTEXT('userenv', 'current_schema')
@@ -402,14 +405,14 @@ module ActiveRecord
402
405
  execute "DROP SYNONYM #{quote_table_name(name)}"
403
406
  end
404
407
 
405
- def add_reference(table_name, *args)
406
- OracleEnhanced::ReferenceDefinition.new(*args).add_to(update_table_definition(table_name, self))
408
+ def add_reference(table_name, ref_name, **options)
409
+ OracleEnhanced::ReferenceDefinition.new(ref_name, **options).add_to(update_table_definition(table_name, self))
407
410
  end
408
411
 
409
- def add_column(table_name, column_name, type, options = {}) #:nodoc:
412
+ def add_column(table_name, column_name, type, **options) #:nodoc:
410
413
  type = aliased_types(type.to_s, type)
411
414
  at = create_alter_table table_name
412
- at.add_column(column_name, type, options)
415
+ at.add_column(column_name, type, **options)
413
416
  add_column_sql = schema_creation.accept at
414
417
  add_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, table_name, column_name)
415
418
  execute add_column_sql
@@ -440,7 +443,7 @@ module ActiveRecord
440
443
  change_column table_name, column_name, column.sql_type, null: null
441
444
  end
442
445
 
443
- def change_column(table_name, column_name, type, options = {}) #:nodoc:
446
+ def change_column(table_name, column_name, type, **options) #:nodoc:
444
447
  column = column_for(table_name, column_name)
445
448
 
446
449
  # remove :null option if its value is the same as current column definition
@@ -453,7 +456,7 @@ module ActiveRecord
453
456
  end
454
457
 
455
458
  td = create_table_definition(table_name)
456
- cd = td.new_column_definition(column.name, type, options)
459
+ cd = td.new_column_definition(column.name, type, **options)
457
460
  change_column_stmt = schema_creation.accept cd
458
461
  change_column_stmt << tablespace_for((type_to_sql(type).downcase.to_sym), nil, options[:table_name], options[:column_name]) if type
459
462
  change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{change_column_stmt}"
@@ -494,8 +497,9 @@ module ActiveRecord
494
497
  end
495
498
 
496
499
  def table_comment(table_name) #:nodoc:
500
+ # TODO
497
501
  (_owner, table_name) = @connection.describe(table_name)
498
- select_value(<<~SQL.squish, "Table comment", [bind_string("table_name", table_name)])
502
+ select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
499
503
  SELECT comments FROM all_tab_comments
500
504
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
501
505
  AND table_name = :table_name
@@ -511,7 +515,7 @@ module ActiveRecord
511
515
  def column_comment(table_name, column_name) #:nodoc:
512
516
  # TODO: it does not exist in Abstract adapter
513
517
  (_owner, table_name) = @connection.describe(table_name)
514
- select_value(<<~SQL.squish, "Column comment", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
518
+ select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
515
519
  SELECT comments FROM all_col_comments
516
520
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
517
521
  AND table_name = :table_name
@@ -528,7 +532,7 @@ module ActiveRecord
528
532
  end
529
533
 
530
534
  def tablespace(table_name)
531
- select_value(<<~SQL.squish, "tablespace")
535
+ select_value(<<~SQL.squish, "SCHEMA")
532
536
  SELECT tablespace_name
533
537
  FROM all_tables
534
538
  WHERE table_name='#{table_name.to_s.upcase}'
@@ -540,7 +544,7 @@ module ActiveRecord
540
544
  def foreign_keys(table_name) #:nodoc:
541
545
  (_owner, desc_table_name) = @connection.describe(table_name)
542
546
 
543
- fk_info = select_all(<<~SQL.squish, "Foreign Keys", [bind_string("desc_table_name", desc_table_name)])
547
+ fk_info = select_all(<<~SQL.squish, "SCHEMA", [bind_string("desc_table_name", desc_table_name)])
544
548
  SELECT r.table_name to_table
545
549
  ,rc.column_name references_column
546
550
  ,cc.column_name
@@ -582,7 +586,7 @@ module ActiveRecord
582
586
  # REFERENTIAL INTEGRITY ====================================
583
587
 
584
588
  def disable_referential_integrity(&block) #:nodoc:
585
- old_constraints = select_all(<<~SQL.squish, "Foreign Keys to disable and enable")
589
+ old_constraints = select_all(<<~SQL.squish, "SCHEMA")
586
590
  SELECT constraint_name, owner, table_name
587
591
  FROM all_constraints
588
592
  WHERE constraint_type = 'R'
@@ -614,13 +618,12 @@ module ActiveRecord
614
618
  end
615
619
 
616
620
  private
617
-
618
621
  def schema_creation
619
622
  OracleEnhanced::SchemaCreation.new self
620
623
  end
621
624
 
622
- def create_table_definition(*args)
623
- OracleEnhanced::TableDefinition.new(self, *args)
625
+ def create_table_definition(name, **options)
626
+ OracleEnhanced::TableDefinition.new(self, name, **options)
624
627
  end
625
628
 
626
629
  def new_column_from_field(table_name, field)
@@ -642,7 +645,7 @@ module ActiveRecord
642
645
  # If a default contains a newline these cleanup regexes need to
643
646
  # match newlines.
644
647
  field["data_default"].sub!(/^'(.*)'$/m, '\1')
645
- field["data_default"] = nil if field["data_default"] =~ /^(null|empty_[bc]lob\(\))$/i
648
+ field["data_default"] = nil if /^(null|empty_[bc]lob\(\))$/i.match?(field["data_default"])
646
649
  # TODO: Needs better fix to fallback "N" to false
647
650
  field["data_default"] = false if field["data_default"] == "N" && OracleEnhancedAdapter.emulate_booleans_from_strings
648
651
  end