activerecord-oracle_enhanced-adapter 6.1.6 → 7.0.0.rc1

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +53 -2
  3. data/README.md +1 -1
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +1 -1
  6. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +2 -2
  7. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +22 -13
  8. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +3 -3
  9. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +1 -1
  10. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +16 -17
  11. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +1 -1
  12. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +12 -6
  13. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +1 -1
  14. data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +4 -4
  15. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +18 -18
  16. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +1 -1
  17. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +6 -6
  18. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +16 -16
  19. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +1 -1
  20. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +1 -1
  21. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +6 -6
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +35 -27
  23. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +30 -29
  24. data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +1 -1
  25. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +124 -99
  26. data/lib/arel/visitors/oracle.rb +6 -2
  27. data/lib/arel/visitors/oracle12.rb +4 -0
  28. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +18 -1
  29. data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +2 -2
  30. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +5 -5
  31. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +3 -3
  32. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +5 -5
  33. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +10 -10
  34. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +34 -7
  35. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +5 -5
  36. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +2 -2
  37. metadata +5 -5
@@ -8,25 +8,25 @@ module ActiveRecord
8
8
  #
9
9
  # see: abstract/quoting.rb
10
10
 
11
- def quote_column_name(name) #:nodoc:
11
+ def quote_column_name(name) # :nodoc:
12
12
  name = name.to_s
13
- self.class.quoted_column_names[name] ||= if /\A[a-z][a-z_0-9\$#]*\Z/.match?(name)
13
+ self.class.quoted_column_names[name] ||= if /\A[a-z][a-z_0-9$#]*\Z/.match?(name)
14
14
  "\"#{name.upcase}\""
15
15
  else
16
16
  # remove double quotes which cannot be used inside quoted identifier
17
- "\"#{name.gsub('"', '')}\""
17
+ "\"#{name.delete('"')}\""
18
18
  end
19
19
  end
20
20
 
21
21
  # This method is used in add_index to identify either column name (which is quoted)
22
22
  # or function based index (in which case function expression is not quoted)
23
- def quote_column_name_or_expression(name) #:nodoc:
23
+ def quote_column_name_or_expression(name) # :nodoc:
24
24
  name = name.to_s
25
25
  case name
26
26
  # if only valid lowercase column characters in name
27
- when /^[a-z][a-z_0-9\$#]*$/
27
+ when /^[a-z][a-z_0-9$#]*$/
28
28
  "\"#{name.upcase}\""
29
- when /^[a-z][a-z_0-9\$#\-]*$/i
29
+ when /^[a-z][a-z_0-9$#\-]*$/i
30
30
  "\"#{name}\""
31
31
  # if other characters present then assume that it is expression
32
32
  # which should not be quoted
@@ -55,7 +55,7 @@ module ActiveRecord
55
55
  # contain letters, digits, _, $ or #
56
56
  # can be prefixed with schema name
57
57
  # CamelCase table names should be quoted
58
- def self.valid_table_name?(name) #:nodoc:
58
+ def self.valid_table_name?(name) # :nodoc:
59
59
  object_name = name.to_s
60
60
  !!(object_name =~ VALID_TABLE_NAME && !mixed_case?(object_name))
61
61
  end
@@ -65,16 +65,16 @@ module ActiveRecord
65
65
  !!(object_name =~ /[A-Z]/ && object_name =~ /[a-z]/)
66
66
  end
67
67
 
68
- def quote_table_name(name) #:nodoc:
68
+ def quote_table_name(name) # :nodoc:
69
69
  name, _link = name.to_s.split("@")
70
70
  self.class.quoted_table_names[name] ||= [name.split(".").map { |n| quote_column_name(n) }].join(".")
71
71
  end
72
72
 
73
- def quote_string(s) #:nodoc:
73
+ def quote_string(s) # :nodoc:
74
74
  s.gsub(/'/, "''")
75
75
  end
76
76
 
77
- def _quote(value) #:nodoc:
77
+ def quote(value) # :nodoc:
78
78
  case value
79
79
  when Type::OracleEnhanced::CharacterString::Data then
80
80
  "'#{quote_string(value.to_s)}'"
@@ -91,31 +91,31 @@ module ActiveRecord
91
91
  end
92
92
  end
93
93
 
94
- def quoted_true #:nodoc:
94
+ def quoted_true # :nodoc:
95
95
  return "'Y'" if emulate_booleans_from_strings
96
96
  "1"
97
97
  end
98
98
 
99
- def unquoted_true #:nodoc:
99
+ def unquoted_true # :nodoc:
100
100
  return "Y" if emulate_booleans_from_strings
101
101
  "1"
102
102
  end
103
103
 
104
- def quoted_false #:nodoc:
104
+ def quoted_false # :nodoc:
105
105
  return "'N'" if emulate_booleans_from_strings
106
106
  "0"
107
107
  end
108
108
 
109
- def unquoted_false #:nodoc:
109
+ def unquoted_false # :nodoc:
110
110
  return "N" if emulate_booleans_from_strings
111
111
  "0"
112
112
  end
113
113
 
114
- def _type_cast(value)
114
+ def type_cast(value)
115
115
  case value
116
116
  when Type::OracleEnhanced::TimestampTz::Data, Type::OracleEnhanced::TimestampLtz::Data
117
117
  if value.acts_like?(:time)
118
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
118
+ zone_conversion_method = ActiveRecord.default_timezone == :utc ? :getutc : :getlocal
119
119
  value.respond_to?(zone_conversion_method) ? value.send(zone_conversion_method) : value
120
120
  else
121
121
  value
@@ -21,7 +21,7 @@ module ActiveRecord
21
21
  statements << accept(o.primary_keys) if o.primary_keys
22
22
 
23
23
  if supports_foreign_keys?
24
- statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
24
+ statements.concat(o.foreign_keys.map { |fk| accept fk })
25
25
  end
26
26
 
27
27
  create_sql << "(#{statements.join(', ')})" if statements.present?
@@ -35,7 +35,7 @@ module ActiveRecord
35
35
  end
36
36
  end
37
37
 
38
- class SynonymDefinition < Struct.new(:name, :table_owner, :table_name) #:nodoc:
38
+ class SynonymDefinition < Struct.new(:name, :table_owner, :table_name) # :nodoc:
39
39
  end
40
40
 
41
41
  class IndexDefinition < ActiveRecord::ConnectionAdapters::IndexDefinition
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActiveRecord #:nodoc:
4
- module ConnectionAdapters #:nodoc:
5
- module OracleEnhanced #:nodoc:
6
- class SchemaDumper < ConnectionAdapters::SchemaDumper #:nodoc:
3
+ module ActiveRecord # :nodoc:
4
+ module ConnectionAdapters # :nodoc:
5
+ module OracleEnhanced # :nodoc:
6
+ class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
7
7
  DEFAULT_PRIMARY_KEY_COLUMN_SPEC = { precision: "38", null: "false" }.freeze
8
8
  private_constant :DEFAULT_PRIMARY_KEY_COLUMN_SPEC
9
9
 
@@ -47,7 +47,7 @@ module ActiveRecord #:nodoc:
47
47
 
48
48
  def _indexes(table, stream)
49
49
  if (indexes = @connection.indexes(table)).any?
50
- add_index_statements = indexes.map do |index|
50
+ add_index_statements = indexes.filter_map do |index|
51
51
  case index.type
52
52
  when nil
53
53
  # do nothing here. see indexes_in_create
@@ -67,7 +67,7 @@ module ActiveRecord #:nodoc:
67
67
  statement_parts = ["# unrecognized index #{index.name.inspect} with type #{index.type.inspect}"]
68
68
  end
69
69
  " " + statement_parts.join(", ") unless statement_parts.empty?
70
- end.compact
70
+ end
71
71
 
72
72
  return if add_index_statements.empty?
73
73
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "digest/sha1"
3
+ require "openssl"
4
4
 
5
5
  module ActiveRecord
6
6
  module ConnectionAdapters
@@ -10,7 +10,7 @@ module ActiveRecord
10
10
  #
11
11
  # see: abstract/schema_statements.rb
12
12
 
13
- def tables #:nodoc:
13
+ def tables # :nodoc:
14
14
  select_values(<<~SQL.squish, "SCHEMA")
15
15
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
16
16
  DECODE(table_name, UPPER(table_name), LOWER(table_name), table_name)
@@ -66,7 +66,7 @@ module ActiveRecord
66
66
  SQL
67
67
  end
68
68
 
69
- def materialized_views #:nodoc:
69
+ def materialized_views # :nodoc:
70
70
  select_values(<<~SQL.squish, "SCHEMA")
71
71
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
72
72
  LOWER(mview_name) FROM all_mviews WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
@@ -86,7 +86,7 @@ module ActiveRecord
86
86
  end
87
87
  end
88
88
 
89
- def indexes(table_name) #:nodoc:
89
+ def indexes(table_name) # :nodoc:
90
90
  (_owner, table_name) = @connection.describe(table_name)
91
91
  default_tablespace_name = default_tablespace
92
92
 
@@ -252,7 +252,7 @@ module ActiveRecord
252
252
  rebuild_primary_key_index_to_default_tablespace(table_name, options)
253
253
  end
254
254
 
255
- def rename_table(table_name, new_name) #:nodoc:
255
+ def rename_table(table_name, new_name) # :nodoc:
256
256
  if new_name.to_s.length > DatabaseLimits::IDENTIFIER_MAX_LENGTH
257
257
  raise ArgumentError, "New table name '#{new_name}' is too long; the limit is #{DatabaseLimits::IDENTIFIER_MAX_LENGTH} characters"
258
258
  end
@@ -264,7 +264,7 @@ module ActiveRecord
264
264
  rename_table_indexes(table_name, new_name)
265
265
  end
266
266
 
267
- def drop_table(table_name, **options) #:nodoc:
267
+ def drop_table(table_name, **options) # :nodoc:
268
268
  schema_cache.clear_data_source_cache!(table_name.to_s)
269
269
  execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE CONSTRAINTS' if options[:force] == :cascade}"
270
270
  seq_name = options[:sequence_name] || default_sequence_name(table_name)
@@ -295,7 +295,7 @@ module ActiveRecord
295
295
  end
296
296
  end
297
297
 
298
- def add_index(table_name, column_name, **options) #:nodoc:
298
+ def add_index(table_name, column_name, **options) # :nodoc:
299
299
  index_name, index_type, quoted_column_names, tablespace, index_options = add_index_options(table_name, column_name, **options)
300
300
  execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})#{tablespace} #{index_options}"
301
301
  if index_type == "UNIQUE"
@@ -305,7 +305,7 @@ module ActiveRecord
305
305
  end
306
306
  end
307
307
 
308
- def add_index_options(table_name, column_name, comment: nil, **options) #:nodoc:
308
+ def add_index_options(table_name, column_name, comment: nil, **options) # :nodoc:
309
309
  column_names = Array(column_name)
310
310
  index_name = index_name(table_name, column: column_names)
311
311
 
@@ -329,7 +329,7 @@ module ActiveRecord
329
329
 
330
330
  # Remove the given index from the table.
331
331
  # Gives warning if index does not exist
332
- def remove_index(table_name, column_name = nil, **options) #:nodoc:
332
+ def remove_index(table_name, column_name = nil, **options) # :nodoc:
333
333
  index_name = index_name_for_remove(table_name, column_name, options)
334
334
  # TODO: It should execute only when index_type == "UNIQUE"
335
335
  execute "ALTER TABLE #{quote_table_name(table_name)} DROP CONSTRAINT #{quote_column_name(index_name)}" rescue nil
@@ -337,7 +337,7 @@ module ActiveRecord
337
337
  end
338
338
 
339
339
  # returned shortened index name if default is too large
340
- def index_name(table_name, options) #:nodoc:
340
+ def index_name(table_name, options) # :nodoc:
341
341
  default_name = super(table_name, options).to_s
342
342
  # sometimes options can be String or Array with column names
343
343
  options = {} unless options.is_a?(Hash)
@@ -353,7 +353,7 @@ module ActiveRecord
353
353
  end
354
354
  # generate unique name using hash function
355
355
  if shortened_name.length > identifier_max_length
356
- shortened_name = "i" + Digest::SHA1.hexdigest(default_name)[0, identifier_max_length - 1]
356
+ shortened_name = "i" + OpenSSL::Digest::SHA1.hexdigest(default_name)[0, identifier_max_length - 1]
357
357
  end
358
358
  @logger.warn "#{adapter_name} shortened default index name #{default_name} to #{shortened_name}" if @logger
359
359
  shortened_name
@@ -367,17 +367,17 @@ module ActiveRecord
367
367
  # Will always query database and not index cache.
368
368
  def index_name_exists?(table_name, index_name)
369
369
  (_owner, table_name) = @connection.describe(table_name)
370
- result = select_value(<<~SQL.squish, "SCHEMA")
370
+ result = select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("index_name", index_name.to_s.upcase)])
371
371
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ 1 FROM all_indexes i
372
372
  WHERE i.owner = SYS_CONTEXT('userenv', 'current_schema')
373
373
  AND i.table_owner = SYS_CONTEXT('userenv', 'current_schema')
374
- AND i.table_name = '#{table_name}'
375
- AND i.index_name = '#{index_name.to_s.upcase}'
374
+ AND i.table_name = :table_name
375
+ AND i.index_name = :index_name
376
376
  SQL
377
377
  result == 1
378
378
  end
379
379
 
380
- def rename_index(table_name, old_name, new_name) #:nodoc:
380
+ def rename_index(table_name, old_name, new_name) # :nodoc:
381
381
  validate_index_length!(table_name, new_name)
382
382
  execute "ALTER INDEX #{quote_column_name(old_name)} rename to #{quote_column_name(new_name)}"
383
383
  end
@@ -412,7 +412,7 @@ module ActiveRecord
412
412
  OracleEnhanced::ReferenceDefinition.new(ref_name, **options).add_to(update_table_definition(table_name, self))
413
413
  end
414
414
 
415
- def add_column(table_name, column_name, type, **options) #:nodoc:
415
+ def add_column(table_name, column_name, type, **options) # :nodoc:
416
416
  type = aliased_types(type.to_s, type)
417
417
  at = create_alter_table table_name
418
418
  at.add_column(column_name, type, **options)
@@ -429,14 +429,14 @@ module ActiveRecord
429
429
  fallback
430
430
  end
431
431
 
432
- def change_column_default(table_name, column_name, default_or_changes) #:nodoc:
432
+ def change_column_default(table_name, column_name, default_or_changes) # :nodoc:
433
433
  default = extract_new_default_value(default_or_changes)
434
434
  execute "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
435
435
  ensure
436
436
  clear_table_columns_cache(table_name)
437
437
  end
438
438
 
439
- def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
439
+ def change_column_null(table_name, column_name, null, default = nil) # :nodoc:
440
440
  column = column_for(table_name, column_name)
441
441
 
442
442
  unless null || default.nil?
@@ -446,7 +446,7 @@ module ActiveRecord
446
446
  change_column table_name, column_name, column.sql_type, null: null
447
447
  end
448
448
 
449
- def change_column(table_name, column_name, type, **options) #:nodoc:
449
+ def change_column(table_name, column_name, type, **options) # :nodoc:
450
450
  column = column_for(table_name, column_name)
451
451
 
452
452
  # remove :null option if its value is the same as current column definition
@@ -470,19 +470,27 @@ module ActiveRecord
470
470
  clear_table_columns_cache(table_name)
471
471
  end
472
472
 
473
- def rename_column(table_name, column_name, new_column_name) #:nodoc:
473
+ def rename_column(table_name, column_name, new_column_name) # :nodoc:
474
474
  execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} to #{quote_column_name(new_column_name)}"
475
475
  rename_column_indexes(table_name, column_name, new_column_name)
476
476
  ensure
477
477
  clear_table_columns_cache(table_name)
478
478
  end
479
479
 
480
- def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
480
+ def remove_column(table_name, column_name, type = nil, options = {}) # :nodoc:
481
481
  execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)} CASCADE CONSTRAINTS"
482
482
  ensure
483
483
  clear_table_columns_cache(table_name)
484
484
  end
485
485
 
486
+ def remove_columns(table_name, *column_names, type: nil, **options) # :nodoc:
487
+ quoted_column_names = column_names.map { |column_name| quote_column_name(column_name) }.join(", ")
488
+
489
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP (#{quoted_column_names}) CASCADE CONSTRAINTS"
490
+ ensure
491
+ clear_table_columns_cache(table_name)
492
+ end
493
+
486
494
  def change_table_comment(table_name, comment_or_changes)
487
495
  clear_cache!
488
496
  comment = extract_new_comment_value(comment_or_changes)
@@ -499,7 +507,7 @@ module ActiveRecord
499
507
  execute "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} IS '#{comment}'"
500
508
  end
501
509
 
502
- def table_comment(table_name) #:nodoc:
510
+ def table_comment(table_name) # :nodoc:
503
511
  # TODO
504
512
  (_owner, table_name) = @connection.describe(table_name)
505
513
  select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
@@ -515,7 +523,7 @@ module ActiveRecord
515
523
  end
516
524
  end
517
525
 
518
- def column_comment(table_name, column_name) #:nodoc:
526
+ def column_comment(table_name, column_name) # :nodoc:
519
527
  # TODO: it does not exist in Abstract adapter
520
528
  (_owner, table_name) = @connection.describe(table_name)
521
529
  select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
@@ -527,7 +535,7 @@ module ActiveRecord
527
535
  end
528
536
 
529
537
  # Maps logical Rails types to Oracle-specific data types.
530
- def type_to_sql(type, limit: nil, precision: nil, scale: nil, **) #:nodoc:
538
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **) # :nodoc:
531
539
  # Ignore options for :text, :ntext and :binary columns
532
540
  return super(type) if ["text", "ntext", "binary"].include?(type.to_s)
533
541
 
@@ -544,7 +552,7 @@ module ActiveRecord
544
552
  end
545
553
 
546
554
  # get table foreign keys for schema dump
547
- def foreign_keys(table_name) #:nodoc:
555
+ def foreign_keys(table_name) # :nodoc:
548
556
  (_owner, desc_table_name) = @connection.describe(table_name)
549
557
 
550
558
  fk_info = select_all(<<~SQL.squish, "SCHEMA", [bind_string("desc_table_name", desc_table_name)])
@@ -588,7 +596,7 @@ module ActiveRecord
588
596
 
589
597
  # REFERENTIAL INTEGRITY ====================================
590
598
 
591
- def disable_referential_integrity(&block) #:nodoc:
599
+ def disable_referential_integrity(&block) # :nodoc:
592
600
  old_constraints = select_all(<<~SQL.squish, "SCHEMA")
593
601
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ constraint_name, owner, table_name
594
602
  FROM all_constraints
@@ -661,7 +669,7 @@ module ActiveRecord
661
669
  type_metadata,
662
670
  field["nullable"] == "Y",
663
671
  comment: field["column_comment"]
664
- )
672
+ )
665
673
  end
666
674
 
667
675
  def fetch_type_metadata(sql_type, virtual = nil)
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActiveRecord #:nodoc:
4
- module ConnectionAdapters #:nodoc:
5
- module OracleEnhanced #:nodoc:
6
- module StructureDump #:nodoc:
3
+ module ActiveRecord # :nodoc:
4
+ module ConnectionAdapters # :nodoc:
5
+ module OracleEnhanced # :nodoc:
6
+ module StructureDump # :nodoc:
7
7
  # Statements separator used in structure dump to allow loading of structure dump also with SQL*Plus
8
8
  STATEMENT_TOKEN = "\n\n/\n\n"
9
9
 
10
- def structure_dump #:nodoc:
10
+ def structure_dump # :nodoc:
11
11
  sequences = select(<<~SQL.squish, "SCHEMA")
12
12
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
13
13
  sequence_name, min_value, max_value, increment_by, order_flag, cycle_flag
@@ -30,11 +30,11 @@ module ActiveRecord #:nodoc:
30
30
  tables.each do |table_name|
31
31
  virtual_columns = virtual_columns_for(table_name) if supports_virtual_columns?
32
32
  ddl = +"CREATE#{ ' GLOBAL TEMPORARY' if temporary_table?(table_name)} TABLE \"#{table_name}\" (\n"
33
- columns = select_all(<<~SQL.squish, "SCHEMA")
33
+ columns = select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
34
34
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name, data_type, data_length, char_used, char_length,
35
35
  data_precision, data_scale, data_default, nullable
36
36
  FROM all_tab_columns
37
- WHERE table_name = '#{table_name}'
37
+ WHERE table_name = :table_name
38
38
  AND owner = SYS_CONTEXT('userenv', 'current_schema')
39
39
  ORDER BY column_id
40
40
  SQL
@@ -60,7 +60,7 @@ module ActiveRecord #:nodoc:
60
60
  structure_dump_views
61
61
  end
62
62
 
63
- def structure_dump_column(column) #:nodoc:
63
+ def structure_dump_column(column) # :nodoc:
64
64
  col = +"\"#{column['column_name']}\" #{column['data_type']}"
65
65
  if (column["data_type"] == "NUMBER") && !column["data_precision"].nil?
66
66
  col << "(#{column['data_precision'].to_i}"
@@ -75,8 +75,8 @@ module ActiveRecord #:nodoc:
75
75
  col
76
76
  end
77
77
 
78
- def structure_dump_virtual_column(column, data_default) #:nodoc:
79
- data_default = data_default.gsub(/"/, "")
78
+ def structure_dump_virtual_column(column, data_default) # :nodoc:
79
+ data_default = data_default.delete('"')
80
80
  col = +"\"#{column['column_name']}\" #{column['data_type']}"
81
81
  if (column["data_type"] == "NUMBER") && !column["data_precision"].nil?
82
82
  col << "(#{column['data_precision'].to_i}"
@@ -89,7 +89,7 @@ module ActiveRecord #:nodoc:
89
89
  col << " GENERATED ALWAYS AS (#{data_default}) VIRTUAL"
90
90
  end
91
91
 
92
- def structure_dump_primary_key(table) #:nodoc:
92
+ def structure_dump_primary_key(table) # :nodoc:
93
93
  opts = { name: "", cols: [] }
94
94
  pks = select_all(<<~SQL.squish, "SCHEMA")
95
95
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ a.constraint_name, a.column_name, a.position
@@ -108,7 +108,7 @@ module ActiveRecord #:nodoc:
108
108
  opts[:cols].length > 0 ? ",\n CONSTRAINT #{opts[:name]} PRIMARY KEY (#{opts[:cols].join(',')})" : ""
109
109
  end
110
110
 
111
- def structure_dump_unique_keys(table) #:nodoc:
111
+ def structure_dump_unique_keys(table) # :nodoc:
112
112
  keys = {}
113
113
  uks = select_all(<<~SQL.squish, "SCHEMA")
114
114
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ a.constraint_name, a.column_name, a.position
@@ -129,7 +129,7 @@ module ActiveRecord #:nodoc:
129
129
  end
130
130
  end
131
131
 
132
- def structure_dump_indexes(table_name) #:nodoc:
132
+ def structure_dump_indexes(table_name) # :nodoc:
133
133
  indexes(table_name).map do |options|
134
134
  column_names = options.columns
135
135
  options = { name: options.name, unique: options.unique }
@@ -145,7 +145,7 @@ module ActiveRecord #:nodoc:
145
145
  end
146
146
  end
147
147
 
148
- def structure_dump_fk_constraints #:nodoc:
148
+ def structure_dump_fk_constraints # :nodoc:
149
149
  foreign_keys = select_all(<<~SQL.squish, "SCHEMA")
150
150
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name FROM all_tables
151
151
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
@@ -174,9 +174,10 @@ module ActiveRecord #:nodoc:
174
174
 
175
175
  def structure_dump_column_comments(table_name)
176
176
  comments = []
177
- columns = select_values(<<~SQL.squish, "SCHEMA")
178
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name FROM user_tab_columns
179
- WHERE table_name = '#{table_name}' ORDER BY column_id
177
+ columns = select_values(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
178
+ SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name FROM all_tab_columns
179
+ WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
180
+ AND table_name = :table_name ORDER BY column_id
180
181
  SQL
181
182
 
182
183
  columns.each do |column|
@@ -189,7 +190,7 @@ module ActiveRecord #:nodoc:
189
190
  join_with_statement_token(comments)
190
191
  end
191
192
 
192
- def foreign_key_definition(to_table, options = {}) #:nodoc:
193
+ def foreign_key_definition(to_table, options = {}) # :nodoc:
193
194
  column_sql = quote_column_name(options[:column] || "#{to_table.to_s.singularize}_id")
194
195
  references = options[:references] ? options[:references].first : nil
195
196
  references_sql = quote_column_name(options[:primary_key] || references || "id")
@@ -206,7 +207,7 @@ module ActiveRecord #:nodoc:
206
207
  end
207
208
 
208
209
  # Extract all stored procedures, packages, synonyms.
209
- def structure_dump_db_stored_code #:nodoc:
210
+ def structure_dump_db_stored_code # :nodoc:
210
211
  structure = []
211
212
  all_source = select_all(<<~SQL.squish, "SCHEMA")
212
213
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ DISTINCT name, type
@@ -217,11 +218,11 @@ module ActiveRecord #:nodoc:
217
218
  SQL
218
219
  all_source.each do |source|
219
220
  ddl = +"CREATE OR REPLACE \n"
220
- texts = select_all(<<~SQL.squish, "all source at structure dump")
221
+ texts = select_all(<<~SQL.squish, "all source at structure dump", [bind_string("source_name", source["name"]), bind_string("source_type", source["type"])])
221
222
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ text
222
223
  FROM all_source
223
- WHERE name = '#{source['name']}'
224
- AND type = '#{source['type']}'
224
+ WHERE name = :source_name
225
+ AND type = :source_type
225
226
  AND owner = SYS_CONTEXT('userenv', 'current_schema')
226
227
  ORDER BY line
227
228
  SQL
@@ -238,7 +239,7 @@ module ActiveRecord #:nodoc:
238
239
  join_with_statement_token(structure)
239
240
  end
240
241
 
241
- def structure_dump_views #:nodoc:
242
+ def structure_dump_views # :nodoc:
242
243
  structure = []
243
244
  views = select_all(<<~SQL.squish, "SCHEMA")
244
245
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ view_name, text FROM all_views
@@ -250,7 +251,7 @@ module ActiveRecord #:nodoc:
250
251
  join_with_statement_token(structure)
251
252
  end
252
253
 
253
- def structure_dump_synonyms #:nodoc:
254
+ def structure_dump_synonyms # :nodoc:
254
255
  structure = []
255
256
  synonyms = select_all(<<~SQL.squish, "SCHEMA")
256
257
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, synonym_name, table_name, table_owner
@@ -264,7 +265,7 @@ module ActiveRecord #:nodoc:
264
265
  join_with_statement_token(structure)
265
266
  end
266
267
 
267
- def structure_drop #:nodoc:
268
+ def structure_drop # :nodoc:
268
269
  sequences = select_values(<<~SQL.squish, "SCHEMA")
269
270
  SELECT/*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
270
271
  sequence_name FROM all_sequences where sequence_owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
@@ -287,7 +288,7 @@ module ActiveRecord #:nodoc:
287
288
  join_with_statement_token(statements)
288
289
  end
289
290
 
290
- def temp_table_drop #:nodoc:
291
+ def temp_table_drop # :nodoc:
291
292
  temporary_tables = select_values(<<~SQL.squish, "SCHEMA")
292
293
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name FROM all_tables
293
294
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
@@ -299,7 +300,7 @@ module ActiveRecord #:nodoc:
299
300
  join_with_statement_token(statements)
300
301
  end
301
302
 
302
- def full_drop(preserve_tables = false) #:nodoc:
303
+ def full_drop(preserve_tables = false) # :nodoc:
303
304
  s = preserve_tables ? [] : [structure_drop]
304
305
  s << temp_table_drop if preserve_tables
305
306
  s << drop_sql_for_feature("view")
@@ -322,12 +323,12 @@ module ActiveRecord #:nodoc:
322
323
  # Called only if `supports_virtual_columns?` returns true
323
324
  # return [{'column_name' => 'FOOS', 'data_default' => '...'}, ...]
324
325
  def virtual_columns_for(table)
325
- select_all(<<~SQL.squish, "SCHEMA")
326
+ select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table.upcase)])
326
327
  SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name, data_default
327
328
  FROM all_tab_cols
328
329
  WHERE virtual_column = 'YES'
329
330
  AND owner = SYS_CONTEXT('userenv', 'current_schema')
330
- AND table_name = '#{table.upcase}'
331
+ AND table_name = :table_name
331
332
  SQL
332
333
  end
333
334
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
- module ConnectionAdapters #:nodoc:
4
+ module ConnectionAdapters # :nodoc:
5
5
  module OracleEnhanced
6
6
  class TypeMetadata < DelegateClass(ActiveRecord::ConnectionAdapters::SqlTypeMetadata) # :nodoc:
7
7
  include Deduplicable