activerecord-oracle_enhanced-adapter 6.1.6 → 7.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +53 -2
- data/README.md +1 -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 +16 -17
- data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +12 -6
- 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 +35 -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 +124 -99
- 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/timestamp_spec.rb +2 -2
- 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)
|
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,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)
|
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)
|
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 =
|
375
|
-
AND i.index_name =
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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 = {})
|
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)
|
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)
|
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, **)
|
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)
|
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)
|
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
|
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
|