activerecord-oracle_enhanced-adapter 1.7.11 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.md +206 -4
- data/README.md +37 -1
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +7 -59
- data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +6 -50
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +11 -11
- data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +117 -117
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +37 -27
- data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +10 -10
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +56 -71
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +0 -7
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +51 -69
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +4 -4
- data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +76 -76
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +14 -43
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +60 -64
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +33 -47
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +150 -160
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +95 -133
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +3 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +66 -101
- data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +290 -533
- data/lib/active_record/oracle_enhanced/type/boolean.rb +7 -10
- data/lib/active_record/oracle_enhanced/type/integer.rb +3 -4
- data/lib/active_record/oracle_enhanced/type/json.rb +8 -0
- data/lib/active_record/oracle_enhanced/type/national_character_string.rb +1 -1
- data/lib/active_record/oracle_enhanced/type/raw.rb +2 -3
- data/lib/active_record/oracle_enhanced/type/string.rb +2 -2
- data/lib/active_record/oracle_enhanced/type/text.rb +2 -2
- data/lib/active_record/oracle_enhanced/type/timestamptz.rb +23 -0
- data/lib/activerecord-oracle_enhanced-adapter.rb +2 -2
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +55 -162
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +32 -34
- data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +44 -42
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +250 -357
- data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +14 -6
- data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +3 -5
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +115 -124
- data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +2 -3
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +68 -72
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +64 -80
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +223 -329
- data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +18 -20
- data/spec/spec_config.yaml.template +11 -0
- data/spec/spec_helper.rb +59 -59
- data/spec/support/alter_system_user_password.sql +2 -0
- data/spec/support/create_oracle_enhanced_users.sql +31 -0
- metadata +25 -25
- data/.rspec +0 -2
- data/Gemfile +0 -22
- data/RUNNING_TESTS.md +0 -83
- data/Rakefile +0 -45
- data/activerecord-oracle_enhanced-adapter.gemspec +0 -94
- data/lib/active_record/connection_adapters/oracle_enhanced/cpk.rb +0 -19
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +0 -113
@@ -15,20 +15,20 @@ module ActiveRecord #:nodoc:
|
|
15
15
|
ORDER BY 1").each do |table_name|
|
16
16
|
virtual_columns = virtual_columns_for(table_name)
|
17
17
|
ddl = "CREATE#{ ' GLOBAL TEMPORARY' if temporary_table?(table_name)} TABLE \"#{table_name}\" (\n"
|
18
|
-
cols = select_all(
|
18
|
+
cols = select_all("
|
19
19
|
SELECT column_name, data_type, data_length, char_used, char_length, data_precision, data_scale, data_default, nullable
|
20
20
|
FROM all_tab_columns
|
21
21
|
WHERE table_name = '#{table_name}'
|
22
22
|
AND owner = SYS_CONTEXT('userenv', 'session_user')
|
23
23
|
ORDER BY column_id
|
24
|
-
|
25
|
-
if(v = virtual_columns.find {|col| col[
|
26
|
-
structure_dump_virtual_column(row, v[
|
24
|
+
").map do |row|
|
25
|
+
if (v = virtual_columns.find { |col| col["column_name"] == row["column_name"] })
|
26
|
+
structure_dump_virtual_column(row, v["data_default"])
|
27
27
|
else
|
28
28
|
structure_dump_column(row)
|
29
29
|
end
|
30
30
|
end
|
31
|
-
ddl << cols.join(",\n
|
31
|
+
ddl << cols.map { |col| " #{col}" }.join(",\n")
|
32
32
|
ddl << structure_dump_primary_key(table_name)
|
33
33
|
ddl << "\n)"
|
34
34
|
structure << ddl
|
@@ -43,35 +43,35 @@ module ActiveRecord #:nodoc:
|
|
43
43
|
|
44
44
|
def structure_dump_column(column) #:nodoc:
|
45
45
|
col = "\"#{column['column_name']}\" #{column['data_type']}"
|
46
|
-
if column[
|
46
|
+
if (column["data_type"] == "NUMBER") && !column["data_precision"].nil?
|
47
47
|
col << "(#{column['data_precision'].to_i}"
|
48
|
-
col << ",#{column['data_scale'].to_i}" if !column[
|
49
|
-
col <<
|
50
|
-
elsif column[
|
51
|
-
length = column[
|
52
|
-
col <<
|
48
|
+
col << ",#{column['data_scale'].to_i}" if !column["data_scale"].nil?
|
49
|
+
col << ")"
|
50
|
+
elsif column["data_type"].include?("CHAR") || column["data_type"] == "RAW"
|
51
|
+
length = column["char_used"] == "C" ? column["char_length"].to_i : column["data_length"].to_i
|
52
|
+
col << "(#{length})"
|
53
53
|
end
|
54
|
-
col << " DEFAULT #{column['data_default']}" if !column[
|
55
|
-
col <<
|
54
|
+
col << " DEFAULT #{column['data_default']}" if !column["data_default"].nil?
|
55
|
+
col << " NOT NULL" if column["nullable"] == "N"
|
56
56
|
col
|
57
57
|
end
|
58
58
|
|
59
59
|
def structure_dump_virtual_column(column, data_default) #:nodoc:
|
60
|
-
data_default = data_default.gsub(/"/,
|
60
|
+
data_default = data_default.gsub(/"/, "")
|
61
61
|
col = "\"#{column['column_name']}\" #{column['data_type']}"
|
62
|
-
if column[
|
62
|
+
if (column["data_type"] == "NUMBER") && !column["data_precision"].nil?
|
63
63
|
col << "(#{column['data_precision'].to_i}"
|
64
|
-
col << ",#{column['data_scale'].to_i}" if !column[
|
65
|
-
col <<
|
66
|
-
elsif column[
|
67
|
-
length = column[
|
68
|
-
col <<
|
64
|
+
col << ",#{column['data_scale'].to_i}" if !column["data_scale"].nil?
|
65
|
+
col << ")"
|
66
|
+
elsif column["data_type"].include?("CHAR") || column["data_type"] == "RAW"
|
67
|
+
length = column["char_used"] == "C" ? column["char_length"].to_i : column["data_length"].to_i
|
68
|
+
col << "(#{length})"
|
69
69
|
end
|
70
70
|
col << " GENERATED ALWAYS AS (#{data_default}) VIRTUAL"
|
71
71
|
end
|
72
72
|
|
73
73
|
def structure_dump_primary_key(table) #:nodoc:
|
74
|
-
opts = {:
|
74
|
+
opts = { name: "", cols: [] }
|
75
75
|
pks = select_all(<<-SQL, "Primary Keys")
|
76
76
|
SELECT a.constraint_name, a.column_name, a.position
|
77
77
|
FROM all_cons_columns a
|
@@ -83,10 +83,10 @@ module ActiveRecord #:nodoc:
|
|
83
83
|
AND c.owner = SYS_CONTEXT('userenv', 'current_schema')
|
84
84
|
SQL
|
85
85
|
pks.each do |row|
|
86
|
-
opts[:name] = row[
|
87
|
-
opts[:cols][row[
|
86
|
+
opts[:name] = row["constraint_name"]
|
87
|
+
opts[:cols][row["position"] - 1] = row["column_name"]
|
88
88
|
end
|
89
|
-
opts[:cols].length > 0 ? ",\n CONSTRAINT #{opts[:name]} PRIMARY KEY (#{opts[:cols].join(',')})" :
|
89
|
+
opts[:cols].length > 0 ? ",\n CONSTRAINT #{opts[:name]} PRIMARY KEY (#{opts[:cols].join(',')})" : ""
|
90
90
|
end
|
91
91
|
|
92
92
|
def structure_dump_unique_keys(table) #:nodoc:
|
@@ -102,10 +102,10 @@ module ActiveRecord #:nodoc:
|
|
102
102
|
AND c.owner = SYS_CONTEXT('userenv', 'current_schema')
|
103
103
|
SQL
|
104
104
|
uks.each do |uk|
|
105
|
-
keys[uk[
|
106
|
-
keys[uk[
|
105
|
+
keys[uk["constraint_name"]] ||= []
|
106
|
+
keys[uk["constraint_name"]][uk["position"] - 1] = uk["column_name"]
|
107
107
|
end
|
108
|
-
keys.map do |k,v|
|
108
|
+
keys.map do |k, v|
|
109
109
|
"ALTER TABLE #{table.upcase} ADD CONSTRAINT #{k} UNIQUE (#{v.join(',')})"
|
110
110
|
end
|
111
111
|
end
|
@@ -113,8 +113,8 @@ module ActiveRecord #:nodoc:
|
|
113
113
|
def structure_dump_indexes(table_name) #:nodoc:
|
114
114
|
indexes(table_name).map do |options|
|
115
115
|
column_names = options[:columns]
|
116
|
-
options = {:
|
117
|
-
index_name
|
116
|
+
options = { name: options[:name], unique: options[:unique] }
|
117
|
+
index_name = index_name(table_name, column: column_names)
|
118
118
|
if Hash === options # legacy support, since this param was a string
|
119
119
|
index_type = options[:unique] ? "UNIQUE" : ""
|
120
120
|
index_name = options[:name] || index_name
|
@@ -164,22 +164,11 @@ module ActiveRecord #:nodoc:
|
|
164
164
|
end
|
165
165
|
|
166
166
|
def foreign_key_definition(to_table, options = {}) #:nodoc:
|
167
|
-
|
167
|
+
column_sql = quote_column_name(options[:column] || "#{to_table.to_s.singularize}_id")
|
168
|
+
references = options[:references] ? options[:references].first : nil
|
169
|
+
references_sql = quote_column_name(options[:primary_key] || references || "id")
|
168
170
|
|
169
|
-
|
170
|
-
# composite foreign key
|
171
|
-
columns_sql = columns.map {|c| quote_column_name(c)}.join(',')
|
172
|
-
references = options[:references] || columns
|
173
|
-
references_sql = references.map {|c| quote_column_name(c)}.join(',')
|
174
|
-
else
|
175
|
-
columns_sql = quote_column_name(columns.first || "#{to_table.to_s.singularize}_id")
|
176
|
-
references = options[:references] ? options[:references].first : nil
|
177
|
-
references_sql = quote_column_name(options[:primary_key] || references || "id")
|
178
|
-
end
|
179
|
-
|
180
|
-
table_name = to_table
|
181
|
-
|
182
|
-
sql = "FOREIGN KEY (#{columns_sql}) REFERENCES #{quote_table_name(table_name)}(#{references_sql})"
|
171
|
+
sql = "FOREIGN KEY (#{column_sql}) REFERENCES #{quote_table_name(to_table)}(#{references_sql})"
|
183
172
|
|
184
173
|
case options[:dependent]
|
185
174
|
when :nullify
|
@@ -199,17 +188,17 @@ module ActiveRecord #:nodoc:
|
|
199
188
|
AND name NOT LIKE 'BIN$%'
|
200
189
|
AND owner = SYS_CONTEXT('userenv', 'current_schema') ORDER BY type").each do |source|
|
201
190
|
ddl = "CREATE OR REPLACE \n"
|
202
|
-
select_all(
|
191
|
+
select_all("
|
203
192
|
SELECT text
|
204
193
|
FROM all_source
|
205
194
|
WHERE name = '#{source['name']}'
|
206
195
|
AND type = '#{source['type']}'
|
207
196
|
AND owner = SYS_CONTEXT('userenv', 'current_schema')
|
208
197
|
ORDER BY line
|
209
|
-
|
210
|
-
ddl << row[
|
198
|
+
").each do |row|
|
199
|
+
ddl << row["text"]
|
211
200
|
end
|
212
|
-
ddl << ";" unless ddl.strip[-1,1] ==
|
201
|
+
ddl << ";" unless ddl.strip[-1, 1] == ";"
|
213
202
|
structure << ddl
|
214
203
|
end
|
215
204
|
|
@@ -251,7 +240,7 @@ module ActiveRecord #:nodoc:
|
|
251
240
|
end)
|
252
241
|
end
|
253
242
|
|
254
|
-
def full_drop(preserve_tables=false) #:nodoc:
|
243
|
+
def full_drop(preserve_tables = false) #:nodoc:
|
255
244
|
s = preserve_tables ? [] : [structure_drop]
|
256
245
|
s << temp_table_drop if preserve_tables
|
257
246
|
s << drop_sql_for_feature("view")
|
@@ -264,30 +253,6 @@ module ActiveRecord #:nodoc:
|
|
264
253
|
s.join
|
265
254
|
end
|
266
255
|
|
267
|
-
def add_column_options!(sql, options) #:nodoc:
|
268
|
-
type = options[:type] || ((column = options[:column]) && column.type)
|
269
|
-
type = type && type.to_sym
|
270
|
-
# handle case of defaults for CLOB columns, which would otherwise get "quoted" incorrectly
|
271
|
-
if options_include_default?(options)
|
272
|
-
if type == :text
|
273
|
-
sql << " DEFAULT #{quote(options[:default])}"
|
274
|
-
else
|
275
|
-
# from abstract adapter
|
276
|
-
sql << " DEFAULT #{quote(options[:default], options[:column])}"
|
277
|
-
end
|
278
|
-
end
|
279
|
-
# must explicitly add NULL or NOT NULL to allow change_column to work on migrations
|
280
|
-
if options[:null] == false
|
281
|
-
sql << " NOT NULL"
|
282
|
-
elsif options[:null] == true
|
283
|
-
sql << " NULL" unless type == :primary_key
|
284
|
-
end
|
285
|
-
# add AS expression for virtual columns
|
286
|
-
if options[:as].present?
|
287
|
-
sql << " AS (#{options[:as]})"
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
256
|
def execute_structure_dump(string)
|
292
257
|
string.split(STATEMENT_TOKEN).each do |ddl|
|
293
258
|
execute(ddl) unless ddl.blank?
|
@@ -296,44 +261,44 @@ module ActiveRecord #:nodoc:
|
|
296
261
|
|
297
262
|
private
|
298
263
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
264
|
+
# virtual columns are an 11g feature. This returns [] if feature is not
|
265
|
+
# present or none are found.
|
266
|
+
# return [{'column_name' => 'FOOS', 'data_default' => '...'}, ...]
|
267
|
+
def virtual_columns_for(table)
|
268
|
+
begin
|
269
|
+
select_all <<-SQL
|
305
270
|
SELECT column_name, data_default
|
306
271
|
FROM all_tab_cols
|
307
272
|
WHERE virtual_column = 'YES'
|
308
273
|
AND owner = SYS_CONTEXT('userenv', 'session_user')
|
309
274
|
AND table_name = '#{table.upcase}'
|
310
275
|
SQL
|
311
|
-
|
312
|
-
|
313
|
-
|
276
|
+
# feature not supported previous to 11g
|
277
|
+
rescue ActiveRecord::StatementInvalid => _e
|
278
|
+
[]
|
279
|
+
end
|
314
280
|
end
|
315
|
-
end
|
316
281
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
282
|
+
def drop_sql_for_feature(type)
|
283
|
+
short_type = type == "materialized view" ? "mview" : type
|
284
|
+
join_with_statement_token(
|
285
|
+
select_values("SELECT #{short_type}_name FROM all_#{short_type.tableize} where owner = SYS_CONTEXT('userenv', 'session_user')").map do |name|
|
286
|
+
"DROP #{type.upcase} \"#{name}\""
|
287
|
+
end)
|
288
|
+
end
|
324
289
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
290
|
+
def drop_sql_for_object(type)
|
291
|
+
join_with_statement_token(
|
292
|
+
select_values("SELECT object_name FROM all_objects WHERE object_type = '#{type.upcase}' and owner = SYS_CONTEXT('userenv', 'session_user')").map do |name|
|
293
|
+
"DROP #{type.upcase} \"#{name}\""
|
294
|
+
end)
|
295
|
+
end
|
331
296
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
297
|
+
def join_with_statement_token(array)
|
298
|
+
string = array.join(STATEMENT_TOKEN)
|
299
|
+
string << STATEMENT_TOKEN unless string.blank?
|
300
|
+
string
|
301
|
+
end
|
337
302
|
end
|
338
303
|
end
|
339
304
|
end
|
@@ -1 +1 @@
|
|
1
|
-
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter::VERSION = File.read(File.expand_path(
|
1
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter::VERSION = File.read(File.expand_path("../../../../../VERSION", __FILE__)).chomp
|