activerecord-oracle_enhanced-adapter 6.1.4 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.md +78 -0
- data/README.md +12 -1
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +2 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +22 -13
- data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +3 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +19 -22
- data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +14 -8
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +4 -4
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +18 -18
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +6 -6
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +16 -16
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +6 -6
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +37 -27
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +30 -29
- data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +123 -98
- data/lib/arel/visitors/oracle.rb +6 -2
- data/lib/arel/visitors/oracle12.rb +4 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +18 -1
- data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +2 -2
- data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +5 -5
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +3 -3
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +5 -5
- data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +10 -10
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +34 -7
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +5 -5
- data/spec/active_record/oracle_enhanced/type/custom_spec.rb +88 -0
- data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +2 -2
- metadata +22 -6
@@ -8,25 +8,25 @@ module ActiveRecord
|
|
8
8
|
#
|
9
9
|
# see: abstract/quoting.rb
|
10
10
|
|
11
|
-
def quote_column_name(name)
|
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
|
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.
|
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)
|
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
|
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)
|
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)
|
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)
|
73
|
+
def quote_string(s) # :nodoc:
|
74
74
|
s.gsub(/'/, "''")
|
75
75
|
end
|
76
76
|
|
77
|
-
def
|
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
|
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
|
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
|
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
|
109
|
+
def unquoted_false # :nodoc:
|
110
110
|
return "N" if emulate_booleans_from_strings
|
111
111
|
"0"
|
112
112
|
end
|
113
113
|
|
114
|
-
def
|
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
|
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 { |
|
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)
|
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
|
4
|
-
module ConnectionAdapters
|
5
|
-
module OracleEnhanced
|
6
|
-
class SchemaDumper < ConnectionAdapters::SchemaDumper
|
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.
|
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
|
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 "
|
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
|
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
|
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)
|
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)
|
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)
|
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)
|
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)
|
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,9 @@ 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)
|
332
|
+
def remove_index(table_name, column_name = nil, **options) # :nodoc:
|
333
|
+
return if options[:if_exists] && !index_exists?(table_name, column_name, **options)
|
334
|
+
|
333
335
|
index_name = index_name_for_remove(table_name, column_name, options)
|
334
336
|
# TODO: It should execute only when index_type == "UNIQUE"
|
335
337
|
execute "ALTER TABLE #{quote_table_name(table_name)} DROP CONSTRAINT #{quote_column_name(index_name)}" rescue nil
|
@@ -337,7 +339,7 @@ module ActiveRecord
|
|
337
339
|
end
|
338
340
|
|
339
341
|
# returned shortened index name if default is too large
|
340
|
-
def index_name(table_name, options)
|
342
|
+
def index_name(table_name, options) # :nodoc:
|
341
343
|
default_name = super(table_name, options).to_s
|
342
344
|
# sometimes options can be String or Array with column names
|
343
345
|
options = {} unless options.is_a?(Hash)
|
@@ -353,7 +355,7 @@ module ActiveRecord
|
|
353
355
|
end
|
354
356
|
# generate unique name using hash function
|
355
357
|
if shortened_name.length > identifier_max_length
|
356
|
-
shortened_name = "i" + Digest::SHA1.hexdigest(default_name)[0, identifier_max_length - 1]
|
358
|
+
shortened_name = "i" + OpenSSL::Digest::SHA1.hexdigest(default_name)[0, identifier_max_length - 1]
|
357
359
|
end
|
358
360
|
@logger.warn "#{adapter_name} shortened default index name #{default_name} to #{shortened_name}" if @logger
|
359
361
|
shortened_name
|
@@ -367,17 +369,17 @@ module ActiveRecord
|
|
367
369
|
# Will always query database and not index cache.
|
368
370
|
def index_name_exists?(table_name, index_name)
|
369
371
|
(_owner, table_name) = @connection.describe(table_name)
|
370
|
-
result = select_value(<<~SQL.squish, "SCHEMA")
|
372
|
+
result = select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("index_name", index_name.to_s.upcase)])
|
371
373
|
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ 1 FROM all_indexes i
|
372
374
|
WHERE i.owner = SYS_CONTEXT('userenv', 'current_schema')
|
373
375
|
AND i.table_owner = SYS_CONTEXT('userenv', 'current_schema')
|
374
|
-
AND i.table_name =
|
375
|
-
AND i.index_name =
|
376
|
+
AND i.table_name = :table_name
|
377
|
+
AND i.index_name = :index_name
|
376
378
|
SQL
|
377
379
|
result == 1
|
378
380
|
end
|
379
381
|
|
380
|
-
def rename_index(table_name, old_name, new_name)
|
382
|
+
def rename_index(table_name, old_name, new_name) # :nodoc:
|
381
383
|
validate_index_length!(table_name, new_name)
|
382
384
|
execute "ALTER INDEX #{quote_column_name(old_name)} rename to #{quote_column_name(new_name)}"
|
383
385
|
end
|
@@ -412,7 +414,7 @@ module ActiveRecord
|
|
412
414
|
OracleEnhanced::ReferenceDefinition.new(ref_name, **options).add_to(update_table_definition(table_name, self))
|
413
415
|
end
|
414
416
|
|
415
|
-
def add_column(table_name, column_name, type, **options)
|
417
|
+
def add_column(table_name, column_name, type, **options) # :nodoc:
|
416
418
|
type = aliased_types(type.to_s, type)
|
417
419
|
at = create_alter_table table_name
|
418
420
|
at.add_column(column_name, type, **options)
|
@@ -429,14 +431,14 @@ module ActiveRecord
|
|
429
431
|
fallback
|
430
432
|
end
|
431
433
|
|
432
|
-
def change_column_default(table_name, column_name, default_or_changes)
|
434
|
+
def change_column_default(table_name, column_name, default_or_changes) # :nodoc:
|
433
435
|
default = extract_new_default_value(default_or_changes)
|
434
436
|
execute "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
|
435
437
|
ensure
|
436
438
|
clear_table_columns_cache(table_name)
|
437
439
|
end
|
438
440
|
|
439
|
-
def change_column_null(table_name, column_name, null, default = nil)
|
441
|
+
def change_column_null(table_name, column_name, null, default = nil) # :nodoc:
|
440
442
|
column = column_for(table_name, column_name)
|
441
443
|
|
442
444
|
unless null || default.nil?
|
@@ -446,7 +448,7 @@ module ActiveRecord
|
|
446
448
|
change_column table_name, column_name, column.sql_type, null: null
|
447
449
|
end
|
448
450
|
|
449
|
-
def change_column(table_name, column_name, type, **options)
|
451
|
+
def change_column(table_name, column_name, type, **options) # :nodoc:
|
450
452
|
column = column_for(table_name, column_name)
|
451
453
|
|
452
454
|
# remove :null option if its value is the same as current column definition
|
@@ -470,19 +472,27 @@ module ActiveRecord
|
|
470
472
|
clear_table_columns_cache(table_name)
|
471
473
|
end
|
472
474
|
|
473
|
-
def rename_column(table_name, column_name, new_column_name)
|
475
|
+
def rename_column(table_name, column_name, new_column_name) # :nodoc:
|
474
476
|
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} to #{quote_column_name(new_column_name)}"
|
475
477
|
rename_column_indexes(table_name, column_name, new_column_name)
|
476
478
|
ensure
|
477
479
|
clear_table_columns_cache(table_name)
|
478
480
|
end
|
479
481
|
|
480
|
-
def remove_column(table_name, column_name, type = nil, options = {})
|
482
|
+
def remove_column(table_name, column_name, type = nil, options = {}) # :nodoc:
|
481
483
|
execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)} CASCADE CONSTRAINTS"
|
482
484
|
ensure
|
483
485
|
clear_table_columns_cache(table_name)
|
484
486
|
end
|
485
487
|
|
488
|
+
def remove_columns(table_name, *column_names, type: nil, **options) # :nodoc:
|
489
|
+
quoted_column_names = column_names.map { |column_name| quote_column_name(column_name) }.join(", ")
|
490
|
+
|
491
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} DROP (#{quoted_column_names}) CASCADE CONSTRAINTS"
|
492
|
+
ensure
|
493
|
+
clear_table_columns_cache(table_name)
|
494
|
+
end
|
495
|
+
|
486
496
|
def change_table_comment(table_name, comment_or_changes)
|
487
497
|
clear_cache!
|
488
498
|
comment = extract_new_comment_value(comment_or_changes)
|
@@ -499,7 +509,7 @@ module ActiveRecord
|
|
499
509
|
execute "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} IS '#{comment}'"
|
500
510
|
end
|
501
511
|
|
502
|
-
def table_comment(table_name)
|
512
|
+
def table_comment(table_name) # :nodoc:
|
503
513
|
# TODO
|
504
514
|
(_owner, table_name) = @connection.describe(table_name)
|
505
515
|
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
|
@@ -515,7 +525,7 @@ module ActiveRecord
|
|
515
525
|
end
|
516
526
|
end
|
517
527
|
|
518
|
-
def column_comment(table_name, column_name)
|
528
|
+
def column_comment(table_name, column_name) # :nodoc:
|
519
529
|
# TODO: it does not exist in Abstract adapter
|
520
530
|
(_owner, table_name) = @connection.describe(table_name)
|
521
531
|
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
|
@@ -527,7 +537,7 @@ module ActiveRecord
|
|
527
537
|
end
|
528
538
|
|
529
539
|
# Maps logical Rails types to Oracle-specific data types.
|
530
|
-
def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
|
540
|
+
def type_to_sql(type, limit: nil, precision: nil, scale: nil, **) # :nodoc:
|
531
541
|
# Ignore options for :text, :ntext and :binary columns
|
532
542
|
return super(type) if ["text", "ntext", "binary"].include?(type.to_s)
|
533
543
|
|
@@ -544,7 +554,7 @@ module ActiveRecord
|
|
544
554
|
end
|
545
555
|
|
546
556
|
# get table foreign keys for schema dump
|
547
|
-
def foreign_keys(table_name)
|
557
|
+
def foreign_keys(table_name) # :nodoc:
|
548
558
|
(_owner, desc_table_name) = @connection.describe(table_name)
|
549
559
|
|
550
560
|
fk_info = select_all(<<~SQL.squish, "SCHEMA", [bind_string("desc_table_name", desc_table_name)])
|
@@ -588,7 +598,7 @@ module ActiveRecord
|
|
588
598
|
|
589
599
|
# REFERENTIAL INTEGRITY ====================================
|
590
600
|
|
591
|
-
def disable_referential_integrity(&block)
|
601
|
+
def disable_referential_integrity(&block) # :nodoc:
|
592
602
|
old_constraints = select_all(<<~SQL.squish, "SCHEMA")
|
593
603
|
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ constraint_name, owner, table_name
|
594
604
|
FROM all_constraints
|
@@ -661,7 +671,7 @@ module ActiveRecord
|
|
661
671
|
type_metadata,
|
662
672
|
field["nullable"] == "Y",
|
663
673
|
comment: field["column_comment"]
|
664
|
-
|
674
|
+
)
|
665
675
|
end
|
666
676
|
|
667
677
|
def fetch_type_metadata(sql_type, virtual = nil)
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module ActiveRecord
|
4
|
-
module ConnectionAdapters
|
5
|
-
module OracleEnhanced
|
6
|
-
module StructureDump
|
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
|
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 =
|
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)
|
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)
|
79
|
-
data_default = data_default.
|
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)
|
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)
|
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)
|
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
|
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
|
179
|
-
WHERE
|
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 = {})
|
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
|
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 =
|
224
|
-
AND 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
|
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
|
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
|
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
|
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)
|
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 =
|
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
|
4
|
+
module ConnectionAdapters # :nodoc:
|
5
5
|
module OracleEnhanced
|
6
6
|
class TypeMetadata < DelegateClass(ActiveRecord::ConnectionAdapters::SqlTypeMetadata) # :nodoc:
|
7
7
|
include Deduplicable
|