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.
- checksums.yaml +4 -4
- data/History.md +126 -0
- data/README.md +13 -2
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +2 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +0 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +0 -9
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +64 -47
- data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +4 -5
- data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +0 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +3 -4
- data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +1 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +12 -7
- data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +0 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +38 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +3 -4
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +15 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +48 -45
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +16 -17
- data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +2 -1
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +57 -15
- data/lib/active_record/type/oracle_enhanced/boolean.rb +0 -1
- data/lib/active_record/type/oracle_enhanced/integer.rb +0 -1
- data/lib/arel/visitors/oracle.rb +253 -0
- data/lib/arel/visitors/oracle12.rb +160 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +35 -3
- data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +6 -1
- data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +0 -1
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +28 -1
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +2 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +48 -0
- data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +4 -2
- data/spec/spec_config.yaml.template +2 -2
- data/spec/spec_helper.rb +13 -4
- data/spec/support/stats.sql +3 -0
- 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
|
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
|
325
|
+
host = "[#{host}]" if /^[^\[].*:/.match?(host) # IPv6
|
323
326
|
port ||= 1521
|
324
|
-
database = "/#{database}" unless database.
|
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
|
-
|
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:
|
@@ -132,8 +132,43 @@ module ActiveRecord
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
|
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 <
|
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,
|
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,
|
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
|
-
|
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, "
|
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, "
|
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, "
|
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, "
|
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, "
|
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, "
|
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, "
|
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, "
|
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 =
|
201
|
-
td = create_table_definition
|
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
|
204
|
-
pk =
|
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,
|
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
|
230
|
-
drop_table(table_name,
|
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 =
|
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
|
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
|
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
|
-
|
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
|
-
|
314
|
-
|
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,
|
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, "
|
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,
|
406
|
-
OracleEnhanced::ReferenceDefinition.new(
|
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
|
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
|
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, "
|
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, "
|
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, "
|
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, "
|
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, "
|
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(
|
623
|
-
OracleEnhanced::TableDefinition.new(self,
|
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
|
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
|