activerecord-oracle_enhanced-adapter 6.0.0 → 6.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +36 -0
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +61 -42
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +10 -4
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +36 -0
- 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 +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +26 -23
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +22 -19
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +31 -7
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +26 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +1 -1
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +2 -1
- data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +2 -2
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +78 -0
- data/spec/spec_helper.rb +0 -2
- metadata +20 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1410c7eb8f55a7b4c96b8016f31c573512699978498ee6effae6d4875b1e3f31
|
4
|
+
data.tar.gz: 36cbc570c5c5a1c6d074353f1de0d8d6ce07c90fd5b906727d7ee2e78a473a1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f1ba2aed7eef1fa08e31c4fe7f43762eb077b10e412f9db61228589d1387f440b64b17db05fd3fd796e0eb4ebc8ca00f91f767f0ea6402e079783265cb583a6
|
7
|
+
data.tar.gz: 700df5182daf9a04a67dcc478aa378d9deb8d09fba726ccf2ce9878b8c1dc70f56a5a135048e00438e5078b9916467f8b356e6a3a4bc5bc8897fb874a8a686c3
|
data/History.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
## 6.0.5 / 2020-12-17
|
2
|
+
|
3
|
+
* Changes and bug fixes
|
4
|
+
* Address `next_sequence_value` ArgumentError syntax [#2048 #2050]
|
5
|
+
* Add /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ hint to address slow SCHEMA queries [#2055, #2069]
|
6
|
+
* `build_subselect` does not have ordering [#2023, #2070, #2073]
|
7
|
+
|
8
|
+
## 6.0.4 / 2020-08-18
|
9
|
+
|
10
|
+
* Changes and bug fixes
|
11
|
+
* create_table_definition and add_column take keyword arguments [#1942, #2043]
|
12
|
+
* Fix keyword arguments errors for Ruby 2.8.0-dev [#1977,#2043]
|
13
|
+
* Fix a build errors when using Ruby 2.8.0-dev [#1983, #2043]
|
14
|
+
|
15
|
+
## 6.0.3 / 2020-06-16
|
16
|
+
|
17
|
+
* Changes and bug fixes
|
18
|
+
* Auto retry works for other `exec_*` methods [#1976, #1981]
|
19
|
+
* Allow column name with function (e.g. `length(title)`) as safe SQL string [#2017, #2018]
|
20
|
+
|
21
|
+
* CI
|
22
|
+
* CI against latest Ruby versions [#1979]
|
23
|
+
|
24
|
+
## 6.0.2 / 2019-12-25
|
25
|
+
|
26
|
+
* Changes and bug fixes
|
27
|
+
* Uninstall SimpleCov [#1968]
|
28
|
+
|
29
|
+
## 6.0.1 / 2019-12-20
|
30
|
+
|
31
|
+
* Changes and bug fixes
|
32
|
+
* Address `undefined local variable or method `sql' [#1932 #1962 #1963]
|
33
|
+
|
34
|
+
* CI
|
35
|
+
* CI against Ruby 2.6.4 and Ruby 2.5.6 [#1922]
|
36
|
+
|
1
37
|
## 6.0.0 / 2019-08-17
|
2
38
|
|
3
39
|
* Major changes, including changes since 6.0.0.beta1
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
6.0.
|
1
|
+
6.0.6
|
@@ -24,21 +24,23 @@ module ActiveRecord
|
|
24
24
|
log(sql, name, binds, type_casted_binds) do
|
25
25
|
cursor = nil
|
26
26
|
cached = false
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
@statements
|
32
|
-
|
27
|
+
with_retry do
|
28
|
+
if without_prepared_statement?(binds)
|
29
|
+
cursor = @connection.prepare(sql)
|
30
|
+
else
|
31
|
+
unless @statements.key? sql
|
32
|
+
@statements[sql] = @connection.prepare(sql)
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
+
cursor = @statements[sql]
|
35
36
|
|
36
|
-
|
37
|
+
cursor.bind_params(type_casted_binds)
|
37
38
|
|
38
|
-
|
39
|
-
|
39
|
+
cached = true
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
+
cursor.exec
|
43
|
+
end
|
42
44
|
|
43
45
|
if (name == "EXPLAIN") && sql =~ /^EXPLAIN/
|
44
46
|
res = true
|
@@ -96,29 +98,32 @@ module ActiveRecord
|
|
96
98
|
|
97
99
|
log(sql, name, binds, type_casted_binds) do
|
98
100
|
cached = false
|
101
|
+
cursor = nil
|
99
102
|
returning_id_col = returning_id_index = nil
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
@statements
|
105
|
-
|
103
|
+
with_retry do
|
104
|
+
if without_prepared_statement?(binds)
|
105
|
+
cursor = @connection.prepare(sql)
|
106
|
+
else
|
107
|
+
unless @statements.key?(sql)
|
108
|
+
@statements[sql] = @connection.prepare(sql)
|
109
|
+
end
|
110
|
+
|
111
|
+
cursor = @statements[sql]
|
106
112
|
|
107
|
-
|
113
|
+
cursor.bind_params(type_casted_binds)
|
108
114
|
|
109
|
-
|
115
|
+
if /:returning_id/.match?(sql)
|
116
|
+
# it currently expects that returning_id comes last part of binds
|
117
|
+
returning_id_index = binds.size
|
118
|
+
cursor.bind_returning_param(returning_id_index, Integer)
|
119
|
+
end
|
110
120
|
|
111
|
-
|
112
|
-
# it currently expects that returning_id comes last part of binds
|
113
|
-
returning_id_index = binds.size
|
114
|
-
cursor.bind_returning_param(returning_id_index, Integer)
|
121
|
+
cached = true
|
115
122
|
end
|
116
123
|
|
117
|
-
|
124
|
+
cursor.exec_update
|
118
125
|
end
|
119
126
|
|
120
|
-
cursor.exec_update
|
121
|
-
|
122
127
|
rows = []
|
123
128
|
if returning_id_index
|
124
129
|
returning_id = cursor.get_returning_param(returning_id_index, Integer).to_i
|
@@ -134,24 +139,26 @@ module ActiveRecord
|
|
134
139
|
type_casted_binds = type_casted_binds(binds)
|
135
140
|
|
136
141
|
log(sql, name, binds, type_casted_binds) do
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
if @statements.key?(sql)
|
142
|
-
cursor = @statements[sql]
|
142
|
+
with_retry do
|
143
|
+
cached = false
|
144
|
+
if without_prepared_statement?(binds)
|
145
|
+
cursor = @connection.prepare(sql)
|
143
146
|
else
|
144
|
-
|
145
|
-
|
147
|
+
if @statements.key?(sql)
|
148
|
+
cursor = @statements[sql]
|
149
|
+
else
|
150
|
+
cursor = @statements[sql] = @connection.prepare(sql)
|
151
|
+
end
|
146
152
|
|
147
|
-
|
153
|
+
cursor.bind_params(type_casted_binds)
|
148
154
|
|
149
|
-
|
150
|
-
|
155
|
+
cached = true
|
156
|
+
end
|
151
157
|
|
152
|
-
|
153
|
-
|
154
|
-
|
158
|
+
res = cursor.exec_update
|
159
|
+
cursor.close unless cached
|
160
|
+
res
|
161
|
+
end
|
155
162
|
end
|
156
163
|
end
|
157
164
|
|
@@ -247,12 +254,14 @@ module ActiveRecord
|
|
247
254
|
columns.each do |col|
|
248
255
|
value = attributes[col.name]
|
249
256
|
# changed sequence of next two lines - should check if value is nil before converting to yaml
|
250
|
-
next
|
257
|
+
next unless value
|
251
258
|
if klass.attribute_types[col.name].is_a? Type::Serialized
|
252
259
|
value = klass.attribute_types[col.name].serialize(value)
|
260
|
+
# value can be nil after serialization because ActiveRecord serializes [] and {} as nil
|
261
|
+
next unless value
|
253
262
|
end
|
254
263
|
uncached do
|
255
|
-
unless lob_record = select_one(<<~SQL.squish, "Writable Large Object")
|
264
|
+
unless lob_record = select_one(sql = <<~SQL.squish, "Writable Large Object")
|
256
265
|
SELECT #{quote_column_name(col.name)} FROM #{quote_table_name(table_name)}
|
257
266
|
WHERE #{quote_column_name(klass.primary_key)} = #{id} FOR UPDATE
|
258
267
|
SQL
|
@@ -263,6 +272,16 @@ module ActiveRecord
|
|
263
272
|
end
|
264
273
|
end
|
265
274
|
end
|
275
|
+
|
276
|
+
private
|
277
|
+
def with_retry
|
278
|
+
@connection.with_retry do
|
279
|
+
yield
|
280
|
+
rescue
|
281
|
+
@statements.clear
|
282
|
+
raise
|
283
|
+
end
|
284
|
+
end
|
266
285
|
end
|
267
286
|
end
|
268
287
|
end
|
@@ -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
|
@@ -423,13 +427,11 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
|
|
423
427
|
LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114, 3135 ] #:nodoc:
|
424
428
|
|
425
429
|
# 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:
|
430
|
+
def with_retry #:nodoc:
|
429
431
|
should_retry = self.class.auto_retry? && autocommit?
|
430
432
|
|
431
433
|
begin
|
432
|
-
|
434
|
+
yield
|
433
435
|
rescue OCIException => e
|
434
436
|
raise unless e.is_a?(OCIError) && LOST_CONNECTION_ERROR_CODES.include?(e.code)
|
435
437
|
@active = false
|
@@ -439,5 +441,9 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
|
|
439
441
|
retry
|
440
442
|
end
|
441
443
|
end
|
444
|
+
|
445
|
+
def exec(sql, *bindvars, &block) #:nodoc:
|
446
|
+
with_retry { @connection.exec(sql, *bindvars, &block) }
|
447
|
+
end
|
442
448
|
end
|
443
449
|
#:startdoc:
|
@@ -132,6 +132,42 @@ module ActiveRecord
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
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
|
170
|
+
|
135
171
|
private
|
136
172
|
|
137
173
|
def oracle_downcase(column_name)
|
@@ -7,7 +7,7 @@ module ActiveRecord
|
|
7
7
|
private
|
8
8
|
|
9
9
|
def visit_ColumnDefinition(o)
|
10
|
-
if [:blob, :clob, :nclob].include?(sql_type = type_to_sql(o.type,
|
10
|
+
if [:blob, :clob, :nclob].include?(sql_type = type_to_sql(o.type, **o.options).downcase.to_sym)
|
11
11
|
if (tablespace = default_tablespace_for(sql_type))
|
12
12
|
@lob_tablespaces ||= {}
|
13
13
|
@lob_tablespaces[o.name] = tablespace
|
@@ -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
|
@@ -169,7 +169,7 @@ module ActiveRecord #:nodoc:
|
|
169
169
|
def extract_expression_for_virtual_column(column)
|
170
170
|
column_name = column.name
|
171
171
|
@connection.select_value(<<~SQL.squish, "Table comment", [bind_string("table_name", table_name.upcase), bind_string("column_name", column_name.upcase)]).inspect
|
172
|
-
select data_default from all_tab_columns
|
172
|
+
select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ data_default from all_tab_columns
|
173
173
|
where owner = SYS_CONTEXT('userenv', 'current_schema')
|
174
174
|
and table_name = :table_name
|
175
175
|
and column_name = :column_name
|
@@ -12,7 +12,8 @@ module ActiveRecord
|
|
12
12
|
|
13
13
|
def tables #:nodoc:
|
14
14
|
select_values(<<~SQL.squish, "tables")
|
15
|
-
SELECT
|
15
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
16
|
+
DECODE(table_name, UPPER(table_name), LOWER(table_name), table_name)
|
16
17
|
FROM all_tables
|
17
18
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
18
19
|
AND secondary = 'N'
|
@@ -44,7 +45,7 @@ module ActiveRecord
|
|
44
45
|
end
|
45
46
|
|
46
47
|
select_values(<<~SQL.squish, "table exists", [bind_string("owner", table_owner), bind_string("table_name", table_name)]).any?
|
47
|
-
SELECT owner, table_name
|
48
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, table_name
|
48
49
|
FROM all_tables
|
49
50
|
WHERE owner = :owner
|
50
51
|
AND table_name = :table_name
|
@@ -60,13 +61,15 @@ module ActiveRecord
|
|
60
61
|
|
61
62
|
def views # :nodoc:
|
62
63
|
select_values(<<~SQL.squish, "views")
|
63
|
-
SELECT
|
64
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
65
|
+
LOWER(view_name) FROM all_views WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
64
66
|
SQL
|
65
67
|
end
|
66
68
|
|
67
69
|
def materialized_views #:nodoc:
|
68
70
|
select_values(<<~SQL.squish, "materialized views")
|
69
|
-
SELECT
|
71
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
72
|
+
LOWER(mview_name) FROM all_mviews WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
70
73
|
SQL
|
71
74
|
end
|
72
75
|
|
@@ -88,7 +91,7 @@ module ActiveRecord
|
|
88
91
|
default_tablespace_name = default_tablespace
|
89
92
|
|
90
93
|
result = select_all(<<~SQL.squish, "indexes", [bind_string("table_name", table_name)])
|
91
|
-
SELECT LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
|
94
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
|
92
95
|
i.index_type, i.ityp_owner, i.ityp_name, i.parameters,
|
93
96
|
LOWER(i.tablespace_name) AS tablespace_name,
|
94
97
|
LOWER(c.column_name) AS column_name, e.column_expression,
|
@@ -118,7 +121,7 @@ module ActiveRecord
|
|
118
121
|
if row["index_type"] == "DOMAIN" && row["ityp_owner"] == "CTXSYS" && row["ityp_name"] == "CONTEXT"
|
119
122
|
procedure_name = default_datastore_procedure(row["index_name"])
|
120
123
|
source = select_values(<<~SQL.squish, "procedure", [bind_string("procedure_name", procedure_name.upcase)]).join
|
121
|
-
SELECT text
|
124
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ text
|
122
125
|
FROM all_source
|
123
126
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
124
127
|
AND name = :procedure_name
|
@@ -198,7 +201,7 @@ module ActiveRecord
|
|
198
201
|
|
199
202
|
def create_table(table_name, **options)
|
200
203
|
create_sequence = options[:id] != false
|
201
|
-
td = create_table_definition table_name, options
|
204
|
+
td = create_table_definition table_name, **options
|
202
205
|
|
203
206
|
if options[:id] != false && !options[:as]
|
204
207
|
pk = options.fetch(:primary_key) do
|
@@ -208,7 +211,7 @@ module ActiveRecord
|
|
208
211
|
if pk.is_a?(Array)
|
209
212
|
td.primary_keys pk
|
210
213
|
else
|
211
|
-
td.primary_key pk, options.fetch(:id, :primary_key), options
|
214
|
+
td.primary_key pk, options.fetch(:id, :primary_key), **options
|
212
215
|
end
|
213
216
|
end
|
214
217
|
|
@@ -288,7 +291,7 @@ module ActiveRecord
|
|
288
291
|
end
|
289
292
|
|
290
293
|
def add_index(table_name, column_name, options = {}) #:nodoc:
|
291
|
-
index_name, index_type, quoted_column_names, tablespace, index_options = add_index_options(table_name, column_name, options)
|
294
|
+
index_name, index_type, quoted_column_names, tablespace, index_options = add_index_options(table_name, column_name, **options)
|
292
295
|
execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})#{tablespace} #{index_options}"
|
293
296
|
if index_type == "UNIQUE"
|
294
297
|
unless /\(.*\)/.match?(quoted_column_names)
|
@@ -362,7 +365,7 @@ module ActiveRecord
|
|
362
365
|
def index_name_exists?(table_name, index_name)
|
363
366
|
(_owner, table_name) = @connection.describe(table_name)
|
364
367
|
result = select_value(<<~SQL.squish, "index name exists")
|
365
|
-
SELECT 1 FROM all_indexes i
|
368
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ 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')
|
368
371
|
AND i.table_name = '#{table_name}'
|
@@ -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
|
@@ -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}"
|
@@ -496,7 +499,7 @@ module ActiveRecord
|
|
496
499
|
def table_comment(table_name) #:nodoc:
|
497
500
|
(_owner, table_name) = @connection.describe(table_name)
|
498
501
|
select_value(<<~SQL.squish, "Table comment", [bind_string("table_name", table_name)])
|
499
|
-
SELECT comments FROM all_tab_comments
|
502
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ comments FROM all_tab_comments
|
500
503
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
501
504
|
AND table_name = :table_name
|
502
505
|
SQL
|
@@ -512,7 +515,7 @@ module ActiveRecord
|
|
512
515
|
# TODO: it does not exist in Abstract adapter
|
513
516
|
(_owner, table_name) = @connection.describe(table_name)
|
514
517
|
select_value(<<~SQL.squish, "Column comment", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
|
515
|
-
SELECT comments FROM all_col_comments
|
518
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ comments FROM all_col_comments
|
516
519
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
517
520
|
AND table_name = :table_name
|
518
521
|
AND column_name = :column_name
|
@@ -529,7 +532,7 @@ module ActiveRecord
|
|
529
532
|
|
530
533
|
def tablespace(table_name)
|
531
534
|
select_value(<<~SQL.squish, "tablespace")
|
532
|
-
SELECT tablespace_name
|
535
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ tablespace_name
|
533
536
|
FROM all_tables
|
534
537
|
WHERE table_name='#{table_name.to_s.upcase}'
|
535
538
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -541,7 +544,7 @@ module ActiveRecord
|
|
541
544
|
(_owner, desc_table_name) = @connection.describe(table_name)
|
542
545
|
|
543
546
|
fk_info = select_all(<<~SQL.squish, "Foreign Keys", [bind_string("desc_table_name", desc_table_name)])
|
544
|
-
SELECT r.table_name to_table
|
547
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ r.table_name to_table
|
545
548
|
,rc.column_name references_column
|
546
549
|
,cc.column_name
|
547
550
|
,c.constraint_name name
|
@@ -583,7 +586,7 @@ module ActiveRecord
|
|
583
586
|
|
584
587
|
def disable_referential_integrity(&block) #:nodoc:
|
585
588
|
old_constraints = select_all(<<~SQL.squish, "Foreign Keys to disable and enable")
|
586
|
-
SELECT constraint_name, owner, table_name
|
589
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ constraint_name, owner, table_name
|
587
590
|
FROM all_constraints
|
588
591
|
WHERE constraint_type = 'R'
|
589
592
|
AND status = 'ENABLED'
|
@@ -619,8 +622,8 @@ module ActiveRecord
|
|
619
622
|
OracleEnhanced::SchemaCreation.new self
|
620
623
|
end
|
621
624
|
|
622
|
-
def create_table_definition(*args)
|
623
|
-
OracleEnhanced::TableDefinition.new(self, *args)
|
625
|
+
def create_table_definition(*args, **options)
|
626
|
+
OracleEnhanced::TableDefinition.new(self, *args, **options)
|
624
627
|
end
|
625
628
|
|
626
629
|
def new_column_from_field(table_name, field)
|
@@ -699,7 +702,7 @@ module ActiveRecord
|
|
699
702
|
return unless tablespace
|
700
703
|
|
701
704
|
index_name = select_value(<<~SQL.squish, "Index name for primary key", [bind_string("table_name", table_name.upcase)])
|
702
|
-
SELECT index_name FROM all_constraints
|
705
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ index_name FROM all_constraints
|
703
706
|
WHERE table_name = :table_name
|
704
707
|
AND constraint_type = 'P'
|
705
708
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -9,7 +9,8 @@ module ActiveRecord #:nodoc:
|
|
9
9
|
|
10
10
|
def structure_dump #:nodoc:
|
11
11
|
sequences = select(<<~SQL.squish, "sequences to dump at structure dump")
|
12
|
-
SELECT
|
12
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
13
|
+
sequence_name, min_value, max_value, increment_by, order_flag, cycle_flag
|
13
14
|
FROM all_sequences
|
14
15
|
where sequence_owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
15
16
|
SQL
|
@@ -18,7 +19,7 @@ module ActiveRecord #:nodoc:
|
|
18
19
|
"CREATE SEQUENCE #{quote_table_name(result["sequence_name"])} MINVALUE #{result["min_value"]} MAXVALUE #{result["max_value"]} INCREMENT BY #{result["increment_by"]} #{result["order_flag"] == 'Y' ? "ORDER" : "NOORDER"} #{result["cycle_flag"] == 'Y' ? "CYCLE" : "NOCYCLE"}"
|
19
20
|
end
|
20
21
|
tables = select_values(<<~SQL.squish, "tables at structure dump")
|
21
|
-
SELECT table_name FROM all_tables t
|
22
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name FROM all_tables t
|
22
23
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') AND secondary = 'N'
|
23
24
|
AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv
|
24
25
|
WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
|
@@ -30,7 +31,7 @@ module ActiveRecord #:nodoc:
|
|
30
31
|
virtual_columns = virtual_columns_for(table_name) if supports_virtual_columns?
|
31
32
|
ddl = +"CREATE#{ ' GLOBAL TEMPORARY' if temporary_table?(table_name)} TABLE \"#{table_name}\" (\n"
|
32
33
|
columns = select_all(<<~SQL.squish, "columns at structure dump")
|
33
|
-
SELECT column_name, data_type, data_length, char_used, char_length,
|
34
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name, data_type, data_length, char_used, char_length,
|
34
35
|
data_precision, data_scale, data_default, nullable
|
35
36
|
FROM all_tab_columns
|
36
37
|
WHERE table_name = '#{table_name}'
|
@@ -54,8 +55,9 @@ module ActiveRecord #:nodoc:
|
|
54
55
|
structure << structure_dump_column_comments(table_name)
|
55
56
|
end
|
56
57
|
|
57
|
-
join_with_statement_token(structure) <<
|
58
|
-
|
58
|
+
join_with_statement_token(structure) <<
|
59
|
+
structure_dump_fk_constraints <<
|
60
|
+
structure_dump_views
|
59
61
|
end
|
60
62
|
|
61
63
|
def structure_dump_column(column) #:nodoc:
|
@@ -90,7 +92,7 @@ module ActiveRecord #:nodoc:
|
|
90
92
|
def structure_dump_primary_key(table) #:nodoc:
|
91
93
|
opts = { name: "", cols: [] }
|
92
94
|
pks = select_all(<<~SQL.squish, "Primary Keys")
|
93
|
-
SELECT a.constraint_name, a.column_name, a.position
|
95
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ a.constraint_name, a.column_name, a.position
|
94
96
|
FROM all_cons_columns a
|
95
97
|
JOIN all_constraints c
|
96
98
|
ON a.constraint_name = c.constraint_name
|
@@ -109,7 +111,7 @@ module ActiveRecord #:nodoc:
|
|
109
111
|
def structure_dump_unique_keys(table) #:nodoc:
|
110
112
|
keys = {}
|
111
113
|
uks = select_all(<<~SQL.squish, "Primary Keys")
|
112
|
-
SELECT a.constraint_name, a.column_name, a.position
|
114
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ a.constraint_name, a.column_name, a.position
|
113
115
|
FROM all_cons_columns a
|
114
116
|
JOIN all_constraints c
|
115
117
|
ON a.constraint_name = c.constraint_name
|
@@ -145,7 +147,7 @@ module ActiveRecord #:nodoc:
|
|
145
147
|
|
146
148
|
def structure_dump_fk_constraints #:nodoc:
|
147
149
|
foreign_keys = select_all(<<~SQL.squish, "foreign keys at structure dump")
|
148
|
-
SELECT table_name FROM all_tables
|
150
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name FROM all_tables
|
149
151
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
150
152
|
SQL
|
151
153
|
fks = foreign_keys.map do |table|
|
@@ -173,7 +175,7 @@ module ActiveRecord #:nodoc:
|
|
173
175
|
def structure_dump_column_comments(table_name)
|
174
176
|
comments = []
|
175
177
|
columns = select_values(<<~SQL.squish, "column comments at structure dump")
|
176
|
-
SELECT column_name FROM user_tab_columns
|
178
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name FROM user_tab_columns
|
177
179
|
WHERE table_name = '#{table_name}' ORDER BY column_id
|
178
180
|
SQL
|
179
181
|
|
@@ -207,7 +209,7 @@ module ActiveRecord #:nodoc:
|
|
207
209
|
def structure_dump_db_stored_code #:nodoc:
|
208
210
|
structure = []
|
209
211
|
all_source = select_all(<<~SQL.squish, "stored program at structure dump")
|
210
|
-
SELECT DISTINCT name, type
|
212
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ DISTINCT name, type
|
211
213
|
FROM all_source
|
212
214
|
WHERE type IN ('PROCEDURE', 'PACKAGE', 'PACKAGE BODY', 'FUNCTION', 'TRIGGER', 'TYPE')
|
213
215
|
AND name NOT LIKE 'BIN$%'
|
@@ -216,7 +218,7 @@ module ActiveRecord #:nodoc:
|
|
216
218
|
all_source.each do |source|
|
217
219
|
ddl = +"CREATE OR REPLACE \n"
|
218
220
|
texts = select_all(<<~SQL.squish, "all source at structure dump")
|
219
|
-
SELECT text
|
221
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ text
|
220
222
|
FROM all_source
|
221
223
|
WHERE name = '#{source['name']}'
|
222
224
|
AND type = '#{source['type']}'
|
@@ -239,7 +241,7 @@ module ActiveRecord #:nodoc:
|
|
239
241
|
def structure_dump_views #:nodoc:
|
240
242
|
structure = []
|
241
243
|
views = select_all(<<~SQL.squish, "views at structure dump")
|
242
|
-
SELECT view_name, text FROM all_views
|
244
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ view_name, text FROM all_views
|
243
245
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY view_name ASC
|
244
246
|
SQL
|
245
247
|
views.each do |view|
|
@@ -251,7 +253,7 @@ module ActiveRecord #:nodoc:
|
|
251
253
|
def structure_dump_synonyms #:nodoc:
|
252
254
|
structure = []
|
253
255
|
synonyms = select_all(<<~SQL.squish, "synonyms at structure dump")
|
254
|
-
SELECT owner, synonym_name, table_name, table_owner
|
256
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, synonym_name, table_name, table_owner
|
255
257
|
FROM all_synonyms
|
256
258
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
257
259
|
SQL
|
@@ -264,13 +266,14 @@ module ActiveRecord #:nodoc:
|
|
264
266
|
|
265
267
|
def structure_drop #:nodoc:
|
266
268
|
sequences = select_values(<<~SQL.squish, "sequences to drop at structure dump")
|
267
|
-
SELECT
|
269
|
+
SELECT/*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
270
|
+
sequence_name FROM all_sequences where sequence_owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
268
271
|
SQL
|
269
272
|
statements = sequences.map do |seq|
|
270
273
|
"DROP SEQUENCE \"#{seq}\""
|
271
274
|
end
|
272
275
|
tables = select_values(<<~SQL.squish, "tables to drop at structure dump")
|
273
|
-
SELECT table_name from all_tables t
|
276
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name from all_tables t
|
274
277
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') AND secondary = 'N'
|
275
278
|
AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv
|
276
279
|
WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
|
@@ -286,7 +289,7 @@ module ActiveRecord #:nodoc:
|
|
286
289
|
|
287
290
|
def temp_table_drop #:nodoc:
|
288
291
|
temporary_tables = select_values(<<~SQL.squish, "temporary tables to drop at structure dump")
|
289
|
-
SELECT table_name FROM all_tables
|
292
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ table_name FROM all_tables
|
290
293
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
291
294
|
AND secondary = 'N' AND temporary = 'Y' ORDER BY 1
|
292
295
|
SQL
|
@@ -321,7 +324,7 @@ module ActiveRecord #:nodoc:
|
|
321
324
|
# return [{'column_name' => 'FOOS', 'data_default' => '...'}, ...]
|
322
325
|
def virtual_columns_for(table)
|
323
326
|
select_all(<<~SQL.squish, "virtual columns for")
|
324
|
-
SELECT column_name, data_default
|
327
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ column_name, data_default
|
325
328
|
FROM all_tab_cols
|
326
329
|
WHERE virtual_column = 'YES'
|
327
330
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -332,7 +335,7 @@ module ActiveRecord #:nodoc:
|
|
332
335
|
def drop_sql_for_feature(type)
|
333
336
|
short_type = type == "materialized view" ? "mview" : type
|
334
337
|
features = select_values(<<~SQL.squish, "features to drop")
|
335
|
-
SELECT #{short_type}_name FROM all_#{short_type.tableize}
|
338
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ #{short_type}_name FROM all_#{short_type.tableize}
|
336
339
|
where owner = SYS_CONTEXT('userenv', 'current_schema')
|
337
340
|
SQL
|
338
341
|
statements = features.map do |name|
|
@@ -343,7 +346,7 @@ module ActiveRecord #:nodoc:
|
|
343
346
|
|
344
347
|
def drop_sql_for_object(type)
|
345
348
|
objects = select_values(<<~SQL.squish, "objects to drop")
|
346
|
-
SELECT object_name FROM all_objects
|
349
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ object_name FROM all_objects
|
347
350
|
WHERE object_type = '#{type.upcase}' and owner = SYS_CONTEXT('userenv', 'current_schema')
|
348
351
|
SQL
|
349
352
|
statements = objects.map do |name|
|
@@ -449,7 +449,7 @@ module ActiveRecord
|
|
449
449
|
# when inserting a new database record (see #prefetch_primary_key?).
|
450
450
|
def next_sequence_value(sequence_name)
|
451
451
|
# if sequence_name is set to :autogenerated then it means that primary key will be populated by trigger
|
452
|
-
raise ArgumentError "Trigger based primary key is not supported" if sequence_name == AUTOGENERATED_SEQUENCE_NAME
|
452
|
+
raise ArgumentError.new "Trigger based primary key is not supported" if sequence_name == AUTOGENERATED_SEQUENCE_NAME
|
453
453
|
# call directly connection method to avoid prepared statement which causes fetching of next sequence value twice
|
454
454
|
select_value(<<~SQL.squish, "next sequence value")
|
455
455
|
SELECT #{quote_table_name(sequence_name)}.NEXTVAL FROM dual
|
@@ -526,7 +526,7 @@ module ActiveRecord
|
|
526
526
|
# Default tablespace name of current user
|
527
527
|
def default_tablespace
|
528
528
|
select_value(<<~SQL.squish, "default tablespace")
|
529
|
-
SELECT LOWER(default_tablespace) FROM user_users
|
529
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ LOWER(default_tablespace) FROM user_users
|
530
530
|
WHERE username = SYS_CONTEXT('userenv', 'current_schema')
|
531
531
|
SQL
|
532
532
|
end
|
@@ -535,7 +535,7 @@ module ActiveRecord
|
|
535
535
|
(owner, desc_table_name) = @connection.describe(table_name)
|
536
536
|
|
537
537
|
select_all(<<~SQL.squish, "Column definitions")
|
538
|
-
SELECT cols.column_name AS name, cols.data_type AS sql_type,
|
538
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ cols.column_name AS name, cols.data_type AS sql_type,
|
539
539
|
cols.data_default, cols.nullable, cols.virtual_column, cols.hidden_column,
|
540
540
|
cols.data_type_owner AS sql_type_owner,
|
541
541
|
DECODE(cols.data_type, 'NUMBER', data_precision,
|
@@ -567,7 +567,7 @@ module ActiveRecord
|
|
567
567
|
(owner, desc_table_name) = @connection.describe(table_name)
|
568
568
|
|
569
569
|
seqs = select_values(<<~SQL.squish, "Sequence")
|
570
|
-
select us.sequence_name
|
570
|
+
select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ us.sequence_name
|
571
571
|
from all_sequences us
|
572
572
|
where us.sequence_owner = '#{owner}'
|
573
573
|
and us.sequence_name = upper(#{quote(default_sequence_name(desc_table_name))})
|
@@ -575,7 +575,7 @@ module ActiveRecord
|
|
575
575
|
|
576
576
|
# changed back from user_constraints to all_constraints for consistency
|
577
577
|
pks = select_values(<<~SQL.squish, "Primary Key")
|
578
|
-
SELECT cc.column_name
|
578
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ cc.column_name
|
579
579
|
FROM all_constraints c, all_cons_columns cc
|
580
580
|
WHERE c.owner = '#{owner}'
|
581
581
|
AND c.table_name = #{quote(desc_table_name)}
|
@@ -609,7 +609,7 @@ module ActiveRecord
|
|
609
609
|
(_owner, desc_table_name) = @connection.describe(table_name)
|
610
610
|
|
611
611
|
pks = select_values(<<~SQL.squish, "Primary Keys", [bind_string("table_name", desc_table_name)])
|
612
|
-
SELECT cc.column_name
|
612
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ cc.column_name
|
613
613
|
FROM all_constraints c, all_cons_columns cc
|
614
614
|
WHERE c.owner = SYS_CONTEXT('userenv', 'current_schema')
|
615
615
|
AND c.table_name = :table_name
|
@@ -639,7 +639,8 @@ module ActiveRecord
|
|
639
639
|
|
640
640
|
def temporary_table?(table_name) #:nodoc:
|
641
641
|
select_value(<<~SQL.squish, "temporary table", [bind_string("table_name", table_name.upcase)]) == "Y"
|
642
|
-
SELECT
|
642
|
+
SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
|
643
|
+
temporary FROM all_tables WHERE table_name = :table_name and owner = SYS_CONTEXT('userenv', 'current_schema')
|
643
644
|
SQL
|
644
645
|
end
|
645
646
|
|
@@ -746,3 +747,26 @@ require "active_record/connection_adapters/oracle_enhanced/version"
|
|
746
747
|
module ActiveRecord
|
747
748
|
autoload :OracleEnhancedProcedures, "active_record/connection_adapters/oracle_enhanced/procedures"
|
748
749
|
end
|
750
|
+
|
751
|
+
# Backport #2070 into relese60 branch by adding some dirty monkey patch
|
752
|
+
# Because #2002 has been merged to release61 branch or newer, not available for release60 branch.
|
753
|
+
module Arel # :nodoc: all
|
754
|
+
module Visitors
|
755
|
+
class Oracle < Arel::Visitors::ToSql
|
756
|
+
private
|
757
|
+
def build_subselect(key, o)
|
758
|
+
stmt = super
|
759
|
+
stmt.orders = [] # `orders` will never be set to prevent `ORA-00907`.
|
760
|
+
stmt
|
761
|
+
end
|
762
|
+
end
|
763
|
+
class Oracle12 < Arel::Visitors::ToSql
|
764
|
+
private
|
765
|
+
def build_subselect(key, o)
|
766
|
+
stmt = super
|
767
|
+
stmt.orders = [] # `orders` will never be set to prevent `ORA-00907`.
|
768
|
+
stmt
|
769
|
+
end
|
770
|
+
end
|
771
|
+
end
|
772
|
+
end
|
@@ -387,10 +387,22 @@ describe "OracleEnhancedConnection" do
|
|
387
387
|
end
|
388
388
|
|
389
389
|
describe "auto reconnection" do
|
390
|
+
include SchemaSpecHelper
|
391
|
+
|
390
392
|
before(:all) do
|
391
393
|
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
392
394
|
@conn = ActiveRecord::Base.connection.instance_variable_get("@connection")
|
393
395
|
@sys_conn = ActiveRecord::ConnectionAdapters::OracleEnhanced::Connection.create(SYS_CONNECTION_PARAMS)
|
396
|
+
schema_define do
|
397
|
+
create_table :posts, force: true
|
398
|
+
end
|
399
|
+
class ::Post < ActiveRecord::Base
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
after(:all) do
|
404
|
+
Object.send(:remove_const, "Post")
|
405
|
+
ActiveRecord::Base.clear_cache!
|
394
406
|
end
|
395
407
|
|
396
408
|
before(:each) do
|
@@ -440,6 +452,20 @@ describe "OracleEnhancedConnection" do
|
|
440
452
|
expect { @conn.select("SELECT * FROM dual") }.to raise_error(OCIError)
|
441
453
|
end
|
442
454
|
end
|
455
|
+
|
456
|
+
it "should reconnect and execute query if connection is lost and auto retry is enabled" do
|
457
|
+
Post.create!
|
458
|
+
ActiveRecord::Base.connection.auto_retry = true
|
459
|
+
kill_current_session
|
460
|
+
expect(Post.take).not_to be_nil
|
461
|
+
end
|
462
|
+
|
463
|
+
it "should not reconnect and execute query if connection is lost and auto retry is disabled" do
|
464
|
+
Post.create!
|
465
|
+
ActiveRecord::Base.connection.auto_retry = false
|
466
|
+
kill_current_session
|
467
|
+
expect { Post.take }.to raise_error(ActiveRecord::StatementInvalid)
|
468
|
+
end
|
443
469
|
end
|
444
470
|
|
445
471
|
describe "describe table" do
|
@@ -21,7 +21,7 @@ describe "OracleEnhancedAdapter schema dump" do
|
|
21
21
|
def create_test_posts_table(options = {})
|
22
22
|
options[:force] = true
|
23
23
|
schema_define do
|
24
|
-
create_table :test_posts, options do |t|
|
24
|
+
create_table :test_posts, **options do |t|
|
25
25
|
t.string :title
|
26
26
|
t.timestamps null: true
|
27
27
|
end
|
@@ -80,7 +80,8 @@ describe "OracleEnhancedAdapter schema definition" do
|
|
80
80
|
describe "sequence creation parameters" do
|
81
81
|
def create_test_employees_table(sequence_start_value = nil)
|
82
82
|
schema_define do
|
83
|
-
|
83
|
+
options = sequence_start_value ? { sequence_start_value: sequence_start_value } : {}
|
84
|
+
create_table :test_employees, **options do |t|
|
84
85
|
t.string :first_name
|
85
86
|
t.string :last_name
|
86
87
|
end
|
@@ -66,7 +66,7 @@ describe "OracleEnhancedAdapter structure dump" do
|
|
66
66
|
ALTER TABLE TEST_POSTS
|
67
67
|
ADD CONSTRAINT fk_test_post_foo FOREIGN KEY (foo_id) REFERENCES foos(id)
|
68
68
|
SQL
|
69
|
-
dump = ActiveRecord::Base.connection.
|
69
|
+
dump = ActiveRecord::Base.connection.structure_dump
|
70
70
|
expect(dump.split('\n').length).to eq(1)
|
71
71
|
expect(dump).to match(/ALTER TABLE \"?TEST_POSTS\"? ADD CONSTRAINT \"?FK_TEST_POST_FOO\"? FOREIGN KEY \(\"?FOO_ID\"?\) REFERENCES \"?FOOS\"?\(\"?ID\"?\)/i)
|
72
72
|
end
|
@@ -86,7 +86,7 @@ describe "OracleEnhancedAdapter structure dump" do
|
|
86
86
|
ADD CONSTRAINT fk_test_post_baz FOREIGN KEY (baz_id) REFERENCES foos(baz_id)
|
87
87
|
SQL
|
88
88
|
|
89
|
-
dump = ActiveRecord::Base.connection.
|
89
|
+
dump = ActiveRecord::Base.connection.structure_dump
|
90
90
|
expect(dump.split('\n').length).to eq(1)
|
91
91
|
expect(dump).to match(/ALTER TABLE \"?TEST_POSTS\"? ADD CONSTRAINT \"?FK_TEST_POST_BAZ\"? FOREIGN KEY \(\"?BAZ_ID\"?\) REFERENCES \"?FOOS\"?\(\"?BAZ_ID\"?\)/i)
|
92
92
|
end
|
@@ -150,6 +150,45 @@ describe "OracleEnhancedAdapter" do
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
+
describe "`has_many` assoc has `dependent: :delete_all` with `order`" do
|
154
|
+
before(:all) do
|
155
|
+
schema_define do
|
156
|
+
create_table :test_posts do |t|
|
157
|
+
t.string :title
|
158
|
+
end
|
159
|
+
create_table :test_comments do |t|
|
160
|
+
t.integer :test_post_id
|
161
|
+
t.string :description
|
162
|
+
end
|
163
|
+
add_index :test_comments, :test_post_id
|
164
|
+
end
|
165
|
+
class ::TestPost < ActiveRecord::Base
|
166
|
+
has_many :test_comments, -> { order(:id) }, dependent: :delete_all
|
167
|
+
end
|
168
|
+
class ::TestComment < ActiveRecord::Base
|
169
|
+
belongs_to :test_post
|
170
|
+
end
|
171
|
+
TestPost.transaction do
|
172
|
+
post = TestPost.create!(title: "Title")
|
173
|
+
TestComment.create!(test_post_id: post.id, description: "Description")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
after(:all) do
|
178
|
+
schema_define do
|
179
|
+
drop_table :test_comments
|
180
|
+
drop_table :test_posts
|
181
|
+
end
|
182
|
+
Object.send(:remove_const, "TestPost")
|
183
|
+
Object.send(:remove_const, "TestComment")
|
184
|
+
ActiveRecord::Base.clear_cache!
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should not occur `ActiveRecord::StatementInvalid: OCIError: ORA-00907: missing right parenthesis`" do
|
188
|
+
expect { TestPost.first.destroy }.not_to raise_error
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
153
192
|
describe "eager loading" do
|
154
193
|
before(:all) do
|
155
194
|
schema_define do
|
@@ -392,6 +431,45 @@ describe "OracleEnhancedAdapter" do
|
|
392
431
|
end
|
393
432
|
end
|
394
433
|
|
434
|
+
describe "Binary lob column" do
|
435
|
+
before(:all) do
|
436
|
+
schema_define do
|
437
|
+
create_table :test_binary_columns do |t|
|
438
|
+
t.binary :attachment
|
439
|
+
end
|
440
|
+
end
|
441
|
+
class ::TestBinaryColumn < ActiveRecord::Base
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
after(:all) do
|
446
|
+
schema_define do
|
447
|
+
drop_table :test_binary_columns
|
448
|
+
end
|
449
|
+
Object.send(:remove_const, "TestBinaryColumn")
|
450
|
+
ActiveRecord::Base.table_name_prefix = nil
|
451
|
+
ActiveRecord::Base.clear_cache!
|
452
|
+
end
|
453
|
+
|
454
|
+
before(:each) do
|
455
|
+
set_logger
|
456
|
+
end
|
457
|
+
|
458
|
+
after(:each) do
|
459
|
+
clear_logger
|
460
|
+
end
|
461
|
+
|
462
|
+
it "should serialize with non UTF-8 data" do
|
463
|
+
binary_value = +"Hello \x93\xfa\x96\x7b"
|
464
|
+
binary_value.force_encoding "UTF-8"
|
465
|
+
|
466
|
+
binary_column_object = TestBinaryColumn.new
|
467
|
+
binary_column_object.attachment = binary_value
|
468
|
+
|
469
|
+
expect(binary_column_object.save!).to eq(true)
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
395
473
|
describe "quoting" do
|
396
474
|
before(:all) do
|
397
475
|
schema_define do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-oracle_enhanced-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.
|
4
|
+
version: 6.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Raimonds Simanovskis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -135,38 +135,38 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
135
|
- !ruby/object:Gem::Version
|
136
136
|
version: 1.8.11
|
137
137
|
requirements: []
|
138
|
-
rubygems_version: 3.
|
138
|
+
rubygems_version: 3.2.3
|
139
139
|
signing_key:
|
140
140
|
specification_version: 4
|
141
141
|
summary: Oracle enhanced adapter for ActiveRecord
|
142
142
|
test_files:
|
143
|
-
- spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb
|
144
143
|
- spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb
|
145
|
-
- spec/active_record/connection_adapters/
|
146
|
-
- spec/active_record/connection_adapters/oracle_enhanced/
|
144
|
+
- spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb
|
145
|
+
- spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb
|
147
146
|
- spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb
|
147
|
+
- spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb
|
148
|
+
- spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb
|
148
149
|
- spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb
|
150
|
+
- spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb
|
149
151
|
- spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb
|
150
|
-
- spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb
|
151
|
-
- spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb
|
152
|
-
- spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb
|
153
152
|
- spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb
|
154
|
-
- spec/active_record/connection_adapters/
|
155
|
-
- spec/active_record/
|
156
|
-
- spec/active_record/oracle_enhanced/type/dirty_spec.rb
|
157
|
-
- spec/active_record/oracle_enhanced/type/text_spec.rb
|
158
|
-
- spec/active_record/oracle_enhanced/type/timestamp_spec.rb
|
153
|
+
- spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb
|
154
|
+
- spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb
|
159
155
|
- spec/active_record/oracle_enhanced/type/binary_spec.rb
|
160
|
-
- spec/active_record/oracle_enhanced/type/
|
161
|
-
- spec/active_record/oracle_enhanced/type/raw_spec.rb
|
156
|
+
- spec/active_record/oracle_enhanced/type/boolean_spec.rb
|
162
157
|
- spec/active_record/oracle_enhanced/type/character_string_spec.rb
|
163
|
-
- spec/active_record/oracle_enhanced/type/json_spec.rb
|
164
158
|
- spec/active_record/oracle_enhanced/type/decimal_spec.rb
|
165
|
-
- spec/active_record/oracle_enhanced/type/
|
166
|
-
- spec/active_record/oracle_enhanced/type/
|
159
|
+
- spec/active_record/oracle_enhanced/type/dirty_spec.rb
|
160
|
+
- spec/active_record/oracle_enhanced/type/float_spec.rb
|
167
161
|
- spec/active_record/oracle_enhanced/type/integer_spec.rb
|
162
|
+
- spec/active_record/oracle_enhanced/type/json_spec.rb
|
163
|
+
- spec/active_record/oracle_enhanced/type/national_character_string_spec.rb
|
164
|
+
- spec/active_record/oracle_enhanced/type/national_character_text_spec.rb
|
165
|
+
- spec/active_record/oracle_enhanced/type/raw_spec.rb
|
166
|
+
- spec/active_record/oracle_enhanced/type/text_spec.rb
|
167
|
+
- spec/active_record/oracle_enhanced/type/timestamp_spec.rb
|
168
168
|
- spec/spec_config.yaml.template
|
169
|
+
- spec/spec_helper.rb
|
169
170
|
- spec/support/alter_system_set_open_cursors.sql
|
170
171
|
- spec/support/alter_system_user_password.sql
|
171
172
|
- spec/support/create_oracle_enhanced_users.sql
|
172
|
-
- spec/spec_helper.rb
|