activerecord-oracle_enhanced-adapter 7.0.3 → 7.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +24 -0
- data/README.md +0 -1
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +5 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +2 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +26 -21
- data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +15 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +9 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +3 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +24 -15
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +3 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +2 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +5 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +22 -22
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +17 -17
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +71 -28
- data/lib/activerecord-oracle_enhanced-adapter.rb +8 -0
- data/lib/arel/visitors/oracle.rb +6 -3
- data/lib/arel/visitors/oracle12.rb +6 -5
- data/lib/arel/visitors/oracle_common.rb +46 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +24 -5
- data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +7 -2
- data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +2 -2
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +3 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +25 -15
- data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +15 -18
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +14 -10
- data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +2 -2
- data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +24 -0
- data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +4 -2
- data/spec/active_record/oracle_enhanced/type/integer_spec.rb +8 -0
- data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +3 -3
- data/spec/active_record/oracle_enhanced/type/raw_spec.rb +15 -0
- data/spec/active_record/oracle_enhanced/type/text_spec.rb +18 -3
- data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +5 -1
- data/spec/spec_config.yaml.template +2 -2
- data/spec/spec_helper.rb +14 -3
- metadata +8 -6
@@ -12,7 +12,7 @@ module ActiveRecord
|
|
12
12
|
|
13
13
|
def tables # :nodoc:
|
14
14
|
select_values(<<~SQL.squish, "SCHEMA")
|
15
|
-
SELECT
|
15
|
+
SELECT
|
16
16
|
DECODE(table_name, UPPER(table_name), LOWER(table_name), table_name)
|
17
17
|
FROM all_tables
|
18
18
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -45,7 +45,7 @@ module ActiveRecord
|
|
45
45
|
end
|
46
46
|
|
47
47
|
select_values(<<~SQL.squish, "SCHEMA", [bind_string("owner", table_owner), bind_string("table_name", table_name)]).any?
|
48
|
-
SELECT
|
48
|
+
SELECT owner, table_name
|
49
49
|
FROM all_tables
|
50
50
|
WHERE owner = :owner
|
51
51
|
AND table_name = :table_name
|
@@ -53,7 +53,7 @@ module ActiveRecord
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def data_source_exists?(table_name)
|
56
|
-
(_owner, _table_name) =
|
56
|
+
(_owner, _table_name) = _connection.describe(table_name)
|
57
57
|
true
|
58
58
|
rescue
|
59
59
|
false
|
@@ -61,14 +61,14 @@ module ActiveRecord
|
|
61
61
|
|
62
62
|
def views # :nodoc:
|
63
63
|
select_values(<<~SQL.squish, "SCHEMA")
|
64
|
-
SELECT
|
64
|
+
SELECT
|
65
65
|
LOWER(view_name) FROM all_views WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
66
66
|
SQL
|
67
67
|
end
|
68
68
|
|
69
69
|
def materialized_views # :nodoc:
|
70
70
|
select_values(<<~SQL.squish, "SCHEMA")
|
71
|
-
SELECT
|
71
|
+
SELECT
|
72
72
|
LOWER(mview_name) FROM all_mviews WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
73
73
|
SQL
|
74
74
|
end
|
@@ -87,11 +87,11 @@ module ActiveRecord
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def indexes(table_name) # :nodoc:
|
90
|
-
(_owner, table_name) =
|
90
|
+
(_owner, table_name) = _connection.describe(table_name)
|
91
91
|
default_tablespace_name = default_tablespace
|
92
92
|
|
93
93
|
result = select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
|
94
|
-
SELECT
|
94
|
+
SELECT LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
|
95
95
|
i.index_type, i.ityp_owner, i.ityp_name, i.parameters,
|
96
96
|
LOWER(i.tablespace_name) AS tablespace_name,
|
97
97
|
LOWER(c.column_name) AS column_name, e.column_expression,
|
@@ -121,7 +121,7 @@ module ActiveRecord
|
|
121
121
|
if row["index_type"] == "DOMAIN" && row["ityp_owner"] == "CTXSYS" && row["ityp_name"] == "CONTEXT"
|
122
122
|
procedure_name = default_datastore_procedure(row["index_name"])
|
123
123
|
source = select_values(<<~SQL.squish, "SCHEMA", [bind_string("procedure_name", procedure_name.upcase)]).join
|
124
|
-
SELECT
|
124
|
+
SELECT text
|
125
125
|
FROM all_source
|
126
126
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
127
127
|
AND name = :procedure_name
|
@@ -276,7 +276,7 @@ module ActiveRecord
|
|
276
276
|
end
|
277
277
|
|
278
278
|
def insert_versions_sql(versions) # :nodoc:
|
279
|
-
sm_table = quote_table_name(ActiveRecord::
|
279
|
+
sm_table = quote_table_name(ActiveRecord::Base.connection.schema_migration.table_name)
|
280
280
|
|
281
281
|
if supports_multi_insert?
|
282
282
|
versions.inject(+"INSERT ALL\n") { |sql, version|
|
@@ -300,7 +300,7 @@ module ActiveRecord
|
|
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"
|
302
302
|
unless /\(.*\)/.match?(quoted_column_names)
|
303
|
-
execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{quote_column_name(index_name)} #{index_type} (#{quoted_column_names})"
|
303
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{quote_column_name(index_name)} #{index_type} (#{quoted_column_names}) USING INDEX #{quote_column_name(index_name)}"
|
304
304
|
end
|
305
305
|
end
|
306
306
|
end
|
@@ -368,9 +368,9 @@ module ActiveRecord
|
|
368
368
|
#
|
369
369
|
# Will always query database and not index cache.
|
370
370
|
def index_name_exists?(table_name, index_name)
|
371
|
-
(_owner, table_name) =
|
371
|
+
(_owner, table_name) = _connection.describe(table_name)
|
372
372
|
result = select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("index_name", index_name.to_s.upcase)])
|
373
|
-
SELECT
|
373
|
+
SELECT 1 FROM all_indexes i
|
374
374
|
WHERE i.owner = SYS_CONTEXT('userenv', 'current_schema')
|
375
375
|
AND i.table_owner = SYS_CONTEXT('userenv', 'current_schema')
|
376
376
|
AND i.table_name = :table_name
|
@@ -511,9 +511,9 @@ module ActiveRecord
|
|
511
511
|
|
512
512
|
def table_comment(table_name) # :nodoc:
|
513
513
|
# TODO
|
514
|
-
(_owner, table_name) =
|
514
|
+
(_owner, table_name) = _connection.describe(table_name)
|
515
515
|
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
|
516
|
-
SELECT
|
516
|
+
SELECT comments FROM all_tab_comments
|
517
517
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
518
518
|
AND table_name = :table_name
|
519
519
|
SQL
|
@@ -527,9 +527,9 @@ module ActiveRecord
|
|
527
527
|
|
528
528
|
def column_comment(table_name, column_name) # :nodoc:
|
529
529
|
# TODO: it does not exist in Abstract adapter
|
530
|
-
(_owner, table_name) =
|
530
|
+
(_owner, table_name) = _connection.describe(table_name)
|
531
531
|
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
|
532
|
-
SELECT
|
532
|
+
SELECT comments FROM all_col_comments
|
533
533
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
534
534
|
AND table_name = :table_name
|
535
535
|
AND column_name = :column_name
|
@@ -546,7 +546,7 @@ module ActiveRecord
|
|
546
546
|
|
547
547
|
def tablespace(table_name)
|
548
548
|
select_value(<<~SQL.squish, "SCHEMA")
|
549
|
-
SELECT
|
549
|
+
SELECT tablespace_name
|
550
550
|
FROM all_tables
|
551
551
|
WHERE table_name='#{table_name.to_s.upcase}'
|
552
552
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -555,10 +555,10 @@ module ActiveRecord
|
|
555
555
|
|
556
556
|
# get table foreign keys for schema dump
|
557
557
|
def foreign_keys(table_name) # :nodoc:
|
558
|
-
(_owner, desc_table_name) =
|
558
|
+
(_owner, desc_table_name) = _connection.describe(table_name)
|
559
559
|
|
560
560
|
fk_info = select_all(<<~SQL.squish, "SCHEMA", [bind_string("desc_table_name", desc_table_name)])
|
561
|
-
SELECT
|
561
|
+
SELECT r.table_name to_table
|
562
562
|
,rc.column_name references_column
|
563
563
|
,cc.column_name
|
564
564
|
,c.constraint_name name
|
@@ -600,7 +600,7 @@ module ActiveRecord
|
|
600
600
|
|
601
601
|
def disable_referential_integrity(&block) # :nodoc:
|
602
602
|
old_constraints = select_all(<<~SQL.squish, "SCHEMA")
|
603
|
-
SELECT
|
603
|
+
SELECT constraint_name, owner, table_name
|
604
604
|
FROM all_constraints
|
605
605
|
WHERE constraint_type = 'R'
|
606
606
|
AND status = 'ENABLED'
|
@@ -639,7 +639,7 @@ module ActiveRecord
|
|
639
639
|
OracleEnhanced::TableDefinition.new(self, name, **options)
|
640
640
|
end
|
641
641
|
|
642
|
-
def new_column_from_field(table_name, field)
|
642
|
+
def new_column_from_field(table_name, field, definitions)
|
643
643
|
limit, scale = field["limit"], field["scale"]
|
644
644
|
if limit || scale
|
645
645
|
field["sql_type"] += "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
|
@@ -715,7 +715,7 @@ module ActiveRecord
|
|
715
715
|
return unless tablespace
|
716
716
|
|
717
717
|
index_name = select_value(<<~SQL.squish, "Index name for primary key", [bind_string("table_name", table_name.upcase)])
|
718
|
-
SELECT
|
718
|
+
SELECT index_name FROM all_constraints
|
719
719
|
WHERE table_name = :table_name
|
720
720
|
AND constraint_type = 'P'
|
721
721
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -9,7 +9,7 @@ module ActiveRecord # :nodoc:
|
|
9
9
|
|
10
10
|
def structure_dump # :nodoc:
|
11
11
|
sequences = select(<<~SQL.squish, "SCHEMA")
|
12
|
-
SELECT
|
12
|
+
SELECT
|
13
13
|
sequence_name, min_value, max_value, increment_by, order_flag, cycle_flag
|
14
14
|
FROM all_sequences
|
15
15
|
where sequence_owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
@@ -19,7 +19,7 @@ module ActiveRecord # :nodoc:
|
|
19
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"}"
|
20
20
|
end
|
21
21
|
tables = select_values(<<~SQL.squish, "SCHEMA")
|
22
|
-
SELECT
|
22
|
+
SELECT table_name FROM all_tables t
|
23
23
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') AND secondary = 'N'
|
24
24
|
AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv
|
25
25
|
WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
|
@@ -31,7 +31,7 @@ module ActiveRecord # :nodoc:
|
|
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
33
|
columns = select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
|
34
|
-
SELECT
|
34
|
+
SELECT 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
37
|
WHERE table_name = :table_name
|
@@ -92,7 +92,7 @@ module ActiveRecord # :nodoc:
|
|
92
92
|
def structure_dump_primary_key(table) # :nodoc:
|
93
93
|
opts = { name: "", cols: [] }
|
94
94
|
pks = select_all(<<~SQL.squish, "SCHEMA")
|
95
|
-
SELECT
|
95
|
+
SELECT a.constraint_name, a.column_name, a.position
|
96
96
|
FROM all_cons_columns a
|
97
97
|
JOIN all_constraints c
|
98
98
|
ON a.constraint_name = c.constraint_name
|
@@ -111,7 +111,7 @@ module ActiveRecord # :nodoc:
|
|
111
111
|
def structure_dump_unique_keys(table) # :nodoc:
|
112
112
|
keys = {}
|
113
113
|
uks = select_all(<<~SQL.squish, "SCHEMA")
|
114
|
-
SELECT
|
114
|
+
SELECT a.constraint_name, a.column_name, a.position
|
115
115
|
FROM all_cons_columns a
|
116
116
|
JOIN all_constraints c
|
117
117
|
ON a.constraint_name = c.constraint_name
|
@@ -147,7 +147,7 @@ module ActiveRecord # :nodoc:
|
|
147
147
|
|
148
148
|
def structure_dump_fk_constraints # :nodoc:
|
149
149
|
foreign_keys = select_all(<<~SQL.squish, "SCHEMA")
|
150
|
-
SELECT
|
150
|
+
SELECT table_name FROM all_tables
|
151
151
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
152
152
|
SQL
|
153
153
|
fks = foreign_keys.map do |table|
|
@@ -175,7 +175,7 @@ module ActiveRecord # :nodoc:
|
|
175
175
|
def structure_dump_column_comments(table_name)
|
176
176
|
comments = []
|
177
177
|
columns = select_values(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
|
178
|
-
SELECT
|
178
|
+
SELECT column_name FROM all_tab_columns
|
179
179
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
180
180
|
AND table_name = :table_name ORDER BY column_id
|
181
181
|
SQL
|
@@ -210,7 +210,7 @@ module ActiveRecord # :nodoc:
|
|
210
210
|
def structure_dump_db_stored_code # :nodoc:
|
211
211
|
structure = []
|
212
212
|
all_source = select_all(<<~SQL.squish, "SCHEMA")
|
213
|
-
SELECT
|
213
|
+
SELECT DISTINCT name, type
|
214
214
|
FROM all_source
|
215
215
|
WHERE type IN ('PROCEDURE', 'PACKAGE', 'PACKAGE BODY', 'FUNCTION', 'TRIGGER', 'TYPE')
|
216
216
|
AND name NOT LIKE 'BIN$%'
|
@@ -219,7 +219,7 @@ module ActiveRecord # :nodoc:
|
|
219
219
|
all_source.each do |source|
|
220
220
|
ddl = +"CREATE OR REPLACE \n"
|
221
221
|
texts = select_all(<<~SQL.squish, "all source at structure dump", [bind_string("source_name", source["name"]), bind_string("source_type", source["type"])])
|
222
|
-
SELECT
|
222
|
+
SELECT text
|
223
223
|
FROM all_source
|
224
224
|
WHERE name = :source_name
|
225
225
|
AND type = :source_type
|
@@ -242,7 +242,7 @@ module ActiveRecord # :nodoc:
|
|
242
242
|
def structure_dump_views # :nodoc:
|
243
243
|
structure = []
|
244
244
|
views = select_all(<<~SQL.squish, "SCHEMA")
|
245
|
-
SELECT
|
245
|
+
SELECT view_name, text FROM all_views
|
246
246
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY view_name ASC
|
247
247
|
SQL
|
248
248
|
views.each do |view|
|
@@ -254,7 +254,7 @@ module ActiveRecord # :nodoc:
|
|
254
254
|
def structure_dump_synonyms # :nodoc:
|
255
255
|
structure = []
|
256
256
|
synonyms = select_all(<<~SQL.squish, "SCHEMA")
|
257
|
-
SELECT
|
257
|
+
SELECT owner, synonym_name, table_name, table_owner
|
258
258
|
FROM all_synonyms
|
259
259
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
260
260
|
SQL
|
@@ -267,14 +267,14 @@ module ActiveRecord # :nodoc:
|
|
267
267
|
|
268
268
|
def structure_drop # :nodoc:
|
269
269
|
sequences = select_values(<<~SQL.squish, "SCHEMA")
|
270
|
-
SELECT
|
270
|
+
SELECT
|
271
271
|
sequence_name FROM all_sequences where sequence_owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY 1
|
272
272
|
SQL
|
273
273
|
statements = sequences.map do |seq|
|
274
274
|
"DROP SEQUENCE \"#{seq}\""
|
275
275
|
end
|
276
276
|
tables = select_values(<<~SQL.squish, "SCHEMA")
|
277
|
-
SELECT
|
277
|
+
SELECT table_name from all_tables t
|
278
278
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') AND secondary = 'N'
|
279
279
|
AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv
|
280
280
|
WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
|
@@ -290,7 +290,7 @@ module ActiveRecord # :nodoc:
|
|
290
290
|
|
291
291
|
def temp_table_drop # :nodoc:
|
292
292
|
temporary_tables = select_values(<<~SQL.squish, "SCHEMA")
|
293
|
-
SELECT
|
293
|
+
SELECT table_name FROM all_tables
|
294
294
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
|
295
295
|
AND secondary = 'N' AND temporary = 'Y' ORDER BY 1
|
296
296
|
SQL
|
@@ -324,7 +324,7 @@ module ActiveRecord # :nodoc:
|
|
324
324
|
# return [{'column_name' => 'FOOS', 'data_default' => '...'}, ...]
|
325
325
|
def virtual_columns_for(table)
|
326
326
|
select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table.upcase)])
|
327
|
-
SELECT
|
327
|
+
SELECT column_name, data_default
|
328
328
|
FROM all_tab_cols
|
329
329
|
WHERE virtual_column = 'YES'
|
330
330
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
@@ -335,7 +335,7 @@ module ActiveRecord # :nodoc:
|
|
335
335
|
def drop_sql_for_feature(type)
|
336
336
|
short_type = type == "materialized view" ? "mview" : type
|
337
337
|
features = select_values(<<~SQL.squish, "SCHEMA")
|
338
|
-
SELECT
|
338
|
+
SELECT #{short_type}_name FROM all_#{short_type.tableize}
|
339
339
|
where owner = SYS_CONTEXT('userenv', 'current_schema')
|
340
340
|
SQL
|
341
341
|
statements = features.map do |name|
|
@@ -346,7 +346,7 @@ module ActiveRecord # :nodoc:
|
|
346
346
|
|
347
347
|
def drop_sql_for_object(type)
|
348
348
|
objects = select_values(<<~SQL.squish, "SCHEMA")
|
349
|
-
SELECT
|
349
|
+
SELECT object_name FROM all_objects
|
350
350
|
WHERE object_type = '#{type.upcase}' and owner = SYS_CONTEXT('userenv', 'current_schema')
|
351
351
|
SQL
|
352
352
|
statements = objects.map do |name|
|
@@ -121,6 +121,12 @@ module ActiveRecord
|
|
121
121
|
# * <tt>:tcp_keepalive</tt> - TCP keepalive is enabled for OCI client, defaults to true
|
122
122
|
# * <tt>:tcp_keepalive_time</tt> - TCP keepalive time for OCI client, defaults to 600
|
123
123
|
# * <tt>:jdbc_statement_cache_size</tt> - number of cached SQL cursors to keep open, disabled per default (for unpooled JDBC only)
|
124
|
+
# * <tt>:jdbc_connect_properties</tt> - Additional properties for establishing Oracle JDBC connection (for unpooled JDBC only)
|
125
|
+
# example to require encryption and checksumming for network connection:
|
126
|
+
# adapter: oracle_enhanced
|
127
|
+
# jdbc_connect_properties:
|
128
|
+
# 'oracle.net.encryption_client': REQUIRED
|
129
|
+
# 'oracle.net.crypto_checksum_client': REQUIRED
|
124
130
|
#
|
125
131
|
# Optionals NLS parameters:
|
126
132
|
#
|
@@ -240,8 +246,10 @@ module ActiveRecord
|
|
240
246
|
end
|
241
247
|
end
|
242
248
|
|
243
|
-
def initialize(
|
244
|
-
super(
|
249
|
+
def initialize(config_or_deprecated_connection, deprecated_logger = nil, deprecated_connection_options = nil, deprecated_config = nil) # :nodoc:
|
250
|
+
super(config_or_deprecated_connection, deprecated_logger, deprecated_connection_options, deprecated_config)
|
251
|
+
|
252
|
+
@raw_connection = ConnectionAdapters::OracleEnhanced::Connection.create(@config)
|
245
253
|
@enable_dbms_output = false
|
246
254
|
@do_not_prefetch_primary_key = {}
|
247
255
|
@columns_cache = {}
|
@@ -269,6 +277,11 @@ module ActiveRecord
|
|
269
277
|
end
|
270
278
|
end
|
271
279
|
|
280
|
+
def return_value_after_insert?(column) # :nodoc:
|
281
|
+
# TODO: Return true if there this column will be populated (e.g by a sequence)
|
282
|
+
super
|
283
|
+
end
|
284
|
+
|
272
285
|
def build_statement_pool
|
273
286
|
StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
|
274
287
|
end
|
@@ -298,11 +311,12 @@ module ActiveRecord
|
|
298
311
|
end
|
299
312
|
|
300
313
|
def supports_fetch_first_n_rows_and_offset?
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
314
|
+
false
|
315
|
+
|
316
|
+
# TODO: At this point the connection is not initialized yet,
|
317
|
+
# so `database_version` raises an error
|
318
|
+
#
|
319
|
+
# !use_old_oracle_visitor && database_version.first >= 12
|
306
320
|
end
|
307
321
|
|
308
322
|
def supports_datetime_with_precision?
|
@@ -426,12 +440,13 @@ module ActiveRecord
|
|
426
440
|
|
427
441
|
def auto_retry=(value) # :nodoc:
|
428
442
|
@auto_retry = value
|
429
|
-
|
443
|
+
_connection.auto_retry = value if _connection
|
430
444
|
end
|
431
445
|
|
432
446
|
# return raw OCI8 or JDBC connection
|
433
447
|
def raw_connection
|
434
|
-
|
448
|
+
verify!
|
449
|
+
_connection.raw_connection
|
435
450
|
end
|
436
451
|
|
437
452
|
# Returns true if the connection is active.
|
@@ -440,19 +455,30 @@ module ActiveRecord
|
|
440
455
|
# #active? method is also available, but that simply returns the
|
441
456
|
# last known state, which isn't good enough if the connection has
|
442
457
|
# gone stale since the last use.
|
443
|
-
|
458
|
+
_connection.ping
|
444
459
|
rescue OracleEnhanced::ConnectionException
|
445
460
|
false
|
446
461
|
end
|
447
462
|
|
463
|
+
def reconnect
|
464
|
+
_connection.reset # tentative
|
465
|
+
rescue OracleEnhanced::ConnectionException
|
466
|
+
connect
|
467
|
+
end
|
468
|
+
|
448
469
|
# Reconnects to the database.
|
449
470
|
def reconnect! # :nodoc:
|
450
471
|
super
|
451
|
-
|
472
|
+
_connection.reset!
|
452
473
|
rescue OracleEnhanced::ConnectionException => e
|
453
474
|
@logger.warn "#{adapter_name} automatic reconnection failed: #{e.message}" if @logger
|
454
475
|
end
|
455
476
|
|
477
|
+
def clear_cache!(*args, **kwargs)
|
478
|
+
super
|
479
|
+
self.class.clear_type_map!
|
480
|
+
end
|
481
|
+
|
456
482
|
def reset!
|
457
483
|
clear_cache!
|
458
484
|
super
|
@@ -461,12 +487,12 @@ module ActiveRecord
|
|
461
487
|
# Disconnects from the database.
|
462
488
|
def disconnect! # :nodoc:
|
463
489
|
super
|
464
|
-
|
490
|
+
_connection.logoff rescue nil
|
465
491
|
end
|
466
492
|
|
467
493
|
def discard!
|
468
494
|
super
|
469
|
-
|
495
|
+
_connection = nil
|
470
496
|
end
|
471
497
|
|
472
498
|
# use in set_sequence_name to avoid fetching primary key value from sequence
|
@@ -491,7 +517,7 @@ module ActiveRecord
|
|
491
517
|
table_name = table_name.to_s
|
492
518
|
do_not_prefetch = @do_not_prefetch_primary_key[table_name]
|
493
519
|
if do_not_prefetch.nil?
|
494
|
-
owner, desc_table_name =
|
520
|
+
owner, desc_table_name = _connection.describe(table_name)
|
495
521
|
@do_not_prefetch_primary_key[table_name] = do_not_prefetch = !has_primary_key?(table_name, owner, desc_table_name)
|
496
522
|
end
|
497
523
|
!do_not_prefetch
|
@@ -554,16 +580,16 @@ module ActiveRecord
|
|
554
580
|
# Default tablespace name of current user
|
555
581
|
def default_tablespace
|
556
582
|
select_value(<<~SQL.squish, "SCHEMA")
|
557
|
-
SELECT
|
583
|
+
SELECT LOWER(default_tablespace) FROM user_users
|
558
584
|
WHERE username = SYS_CONTEXT('userenv', 'current_schema')
|
559
585
|
SQL
|
560
586
|
end
|
561
587
|
|
562
588
|
def column_definitions(table_name)
|
563
|
-
(owner, desc_table_name) =
|
589
|
+
(owner, desc_table_name) = _connection.describe(table_name)
|
564
590
|
|
565
591
|
select_all(<<~SQL.squish, "SCHEMA", [bind_string("owner", owner), bind_string("table_name", desc_table_name)])
|
566
|
-
SELECT
|
592
|
+
SELECT cols.column_name AS name, cols.data_type AS sql_type,
|
567
593
|
cols.data_default, cols.nullable, cols.virtual_column, cols.hidden_column,
|
568
594
|
cols.data_type_owner AS sql_type_owner,
|
569
595
|
DECODE(cols.data_type, 'NUMBER', data_precision,
|
@@ -592,10 +618,10 @@ module ActiveRecord
|
|
592
618
|
# Find a table's primary key and sequence.
|
593
619
|
# *Note*: Only primary key is implemented - sequence will be nil.
|
594
620
|
def pk_and_sequence_for(table_name, owner = nil, desc_table_name = nil) # :nodoc:
|
595
|
-
(owner, desc_table_name) =
|
621
|
+
(owner, desc_table_name) = _connection.describe(table_name)
|
596
622
|
|
597
623
|
seqs = select_values_forcing_binds(<<~SQL.squish, "SCHEMA", [bind_string("owner", owner), bind_string("sequence_name", default_sequence_name(desc_table_name))])
|
598
|
-
select
|
624
|
+
select us.sequence_name
|
599
625
|
from all_sequences us
|
600
626
|
where us.sequence_owner = :owner
|
601
627
|
and us.sequence_name = upper(:sequence_name)
|
@@ -603,7 +629,7 @@ module ActiveRecord
|
|
603
629
|
|
604
630
|
# changed back from user_constraints to all_constraints for consistency
|
605
631
|
pks = select_values_forcing_binds(<<~SQL.squish, "SCHEMA", [bind_string("owner", owner), bind_string("table_name", desc_table_name)])
|
606
|
-
SELECT
|
632
|
+
SELECT cc.column_name
|
607
633
|
FROM all_constraints c, all_cons_columns cc
|
608
634
|
WHERE c.owner = :owner
|
609
635
|
AND c.table_name = :table_name
|
@@ -634,10 +660,10 @@ module ActiveRecord
|
|
634
660
|
end
|
635
661
|
|
636
662
|
def primary_keys(table_name) # :nodoc:
|
637
|
-
(_owner, desc_table_name) =
|
663
|
+
(_owner, desc_table_name) = _connection.describe(table_name)
|
638
664
|
|
639
665
|
pks = select_values_forcing_binds(<<~SQL.squish, "SCHEMA", [bind_string("table_name", desc_table_name)])
|
640
|
-
SELECT
|
666
|
+
SELECT cc.column_name
|
641
667
|
FROM all_constraints c, all_cons_columns cc
|
642
668
|
WHERE c.owner = SYS_CONTEXT('userenv', 'current_schema')
|
643
669
|
AND c.table_name = :table_name
|
@@ -667,7 +693,7 @@ module ActiveRecord
|
|
667
693
|
|
668
694
|
def temporary_table?(table_name) # :nodoc:
|
669
695
|
select_value_forcing_binds(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name.upcase)]) == "Y"
|
670
|
-
SELECT
|
696
|
+
SELECT
|
671
697
|
temporary FROM all_tables WHERE table_name = :table_name and owner = SYS_CONTEXT('userenv', 'current_schema')
|
672
698
|
SQL
|
673
699
|
end
|
@@ -678,8 +704,14 @@ module ActiveRecord
|
|
678
704
|
alias table_alias_length max_identifier_length
|
679
705
|
alias index_name_length max_identifier_length
|
680
706
|
|
707
|
+
# This is to ensure rails is not shortening the index name,
|
708
|
+
# in order to preserve the local shortening behavior.
|
709
|
+
def max_index_name_size
|
710
|
+
128
|
711
|
+
end
|
712
|
+
|
681
713
|
def get_database_version
|
682
|
-
|
714
|
+
_connection.database_version
|
683
715
|
end
|
684
716
|
|
685
717
|
def check_version
|
@@ -690,7 +722,20 @@ module ActiveRecord
|
|
690
722
|
end
|
691
723
|
end
|
692
724
|
|
725
|
+
private def _connection
|
726
|
+
@unconfigured_connection || @raw_connection
|
727
|
+
end
|
728
|
+
|
693
729
|
class << self
|
730
|
+
def type_map
|
731
|
+
@type_map ||= Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
732
|
+
@type_map
|
733
|
+
end
|
734
|
+
|
735
|
+
def clear_type_map!
|
736
|
+
@type_map = nil
|
737
|
+
end
|
738
|
+
|
694
739
|
private
|
695
740
|
def initialize_type_map(m)
|
696
741
|
super
|
@@ -724,10 +769,8 @@ module ActiveRecord
|
|
724
769
|
end
|
725
770
|
end
|
726
771
|
|
727
|
-
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
728
|
-
|
729
772
|
def type_map
|
730
|
-
|
773
|
+
self.class.type_map
|
731
774
|
end
|
732
775
|
|
733
776
|
def extract_value_from_default(default)
|
@@ -749,7 +792,7 @@ module ActiveRecord
|
|
749
792
|
end
|
750
793
|
|
751
794
|
def translate_exception(exception, message:, sql:, binds:) # :nodoc:
|
752
|
-
case
|
795
|
+
case _connection.error_code(exception)
|
753
796
|
when 1
|
754
797
|
RecordNotUnique.new(message, sql: sql, binds: binds)
|
755
798
|
when 60
|
@@ -10,6 +10,14 @@ if defined?(Rails)
|
|
10
10
|
|
11
11
|
ActiveSupport.on_load(:active_record) do
|
12
12
|
require "active_record/connection_adapters/oracle_enhanced_adapter"
|
13
|
+
|
14
|
+
if ActiveRecord::ConnectionAdapters.respond_to?(:register)
|
15
|
+
ActiveRecord::ConnectionAdapters.register(
|
16
|
+
"oracle_enhanced",
|
17
|
+
"ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter",
|
18
|
+
"active_record/connection_adapters/oracle_enhanced_adapter"
|
19
|
+
)
|
20
|
+
end
|
13
21
|
end
|
14
22
|
end
|
15
23
|
end
|
data/lib/arel/visitors/oracle.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "oracle_common"
|
4
|
+
|
3
5
|
module Arel # :nodoc: all
|
4
6
|
module Visitors
|
5
7
|
class Oracle < Arel::Visitors::ToSql
|
8
|
+
include OracleCommon
|
9
|
+
|
6
10
|
private
|
7
11
|
def visit_Arel_Nodes_SelectStatement(o, collector)
|
8
12
|
o = order_hacks(o)
|
@@ -92,7 +96,6 @@ module Arel # :nodoc: all
|
|
92
96
|
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
93
97
|
in_clause_length = @connection.in_clause_length
|
94
98
|
values = o.casted_values.map { |v| @connection.quote(v) }
|
95
|
-
column_name = quote_table_name(o.table_name) + "." + quote_column_name(o.column_name)
|
96
99
|
operator =
|
97
100
|
if o.type == :in
|
98
101
|
" IN ("
|
@@ -101,7 +104,7 @@ module Arel # :nodoc: all
|
|
101
104
|
end
|
102
105
|
|
103
106
|
if !Array === values || values.length <= in_clause_length
|
104
|
-
|
107
|
+
visit o.left, collector
|
105
108
|
collector << operator
|
106
109
|
|
107
110
|
expr =
|
@@ -123,7 +126,7 @@ module Arel # :nodoc: all
|
|
123
126
|
collector << "("
|
124
127
|
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
125
128
|
collector << separator unless i == 0
|
126
|
-
|
129
|
+
visit o.left, collector
|
127
130
|
collector << operator
|
128
131
|
collector << valuez.join(",")
|
129
132
|
collector << ")"
|
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "oracle_common"
|
4
|
+
|
3
5
|
module Arel # :nodoc: all
|
4
6
|
module Visitors
|
5
7
|
class Oracle12 < Arel::Visitors::ToSql
|
8
|
+
include OracleCommon
|
9
|
+
|
6
10
|
private
|
7
11
|
def visit_Arel_Nodes_SelectStatement(o, collector)
|
8
12
|
# Oracle does not allow LIMIT clause with select for update
|
@@ -45,7 +49,6 @@ module Arel # :nodoc: all
|
|
45
49
|
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
46
50
|
in_clause_length = @connection.in_clause_length
|
47
51
|
values = o.casted_values.map { |v| @connection.quote(v) }
|
48
|
-
column_name = quote_table_name(o.table_name) + "." + quote_column_name(o.column_name)
|
49
52
|
operator =
|
50
53
|
if o.type == :in
|
51
54
|
" IN ("
|
@@ -54,7 +57,7 @@ module Arel # :nodoc: all
|
|
54
57
|
end
|
55
58
|
|
56
59
|
if !Array === values || values.length <= in_clause_length
|
57
|
-
|
60
|
+
visit o.left, collector
|
58
61
|
collector << operator
|
59
62
|
|
60
63
|
expr =
|
@@ -76,15 +79,13 @@ module Arel # :nodoc: all
|
|
76
79
|
collector << "("
|
77
80
|
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
78
81
|
collector << separator unless i == 0
|
79
|
-
|
82
|
+
visit o.left, collector
|
80
83
|
collector << operator
|
81
84
|
collector << valuez.join(",")
|
82
85
|
collector << ")"
|
83
86
|
end
|
84
87
|
collector << ")"
|
85
88
|
end
|
86
|
-
|
87
|
-
collector
|
88
89
|
end
|
89
90
|
|
90
91
|
def visit_Arel_Nodes_UpdateStatement(o, collector)
|