activerecord-oracle_enhanced-adapter 1.7.11 → 1.8.0.beta1

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/Gemfile +20 -11
  4. data/History.md +123 -4
  5. data/RUNNING_TESTS.md +79 -55
  6. data/Rakefile +13 -19
  7. data/VERSION +1 -1
  8. data/activerecord-oracle_enhanced-adapter.gemspec +16 -17
  9. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +1 -1
  10. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +7 -59
  11. data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +6 -50
  12. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +11 -11
  13. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +117 -117
  14. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +30 -23
  15. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +10 -10
  16. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +48 -70
  17. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +1 -4
  18. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +51 -69
  19. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +4 -4
  20. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +76 -76
  21. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +13 -42
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +60 -64
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +33 -47
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +146 -159
  25. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +94 -132
  26. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +3 -3
  27. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +65 -100
  28. data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +1 -1
  29. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +250 -487
  30. data/lib/active_record/oracle_enhanced/type/boolean.rb +7 -10
  31. data/lib/active_record/oracle_enhanced/type/integer.rb +3 -4
  32. data/lib/active_record/oracle_enhanced/type/national_character_string.rb +1 -1
  33. data/lib/active_record/oracle_enhanced/type/raw.rb +2 -3
  34. data/lib/active_record/oracle_enhanced/type/string.rb +2 -2
  35. data/lib/active_record/oracle_enhanced/type/text.rb +2 -2
  36. data/lib/activerecord-oracle_enhanced-adapter.rb +2 -2
  37. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +57 -131
  38. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +32 -34
  39. data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +40 -42
  40. data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +83 -85
  41. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +205 -286
  42. data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +14 -6
  43. data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +3 -5
  44. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +42 -49
  45. data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +1 -3
  46. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +68 -71
  47. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +51 -92
  48. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +221 -327
  49. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +16 -18
  50. data/spec/spec_helper.rb +59 -57
  51. metadata +10 -10
@@ -1,4 +1,4 @@
1
- require 'digest/sha1'
1
+ require "digest/sha1"
2
2
 
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
@@ -80,10 +80,10 @@ module ActiveRecord
80
80
  if supports_comments? && !supports_comments_in_create?
81
81
  change_table_comment(table_name, comment) if comment
82
82
  td.columns.each do |column|
83
- change_column_comment(table_name, column.name, column.comment) if column.comment
83
+ change_column_comment(table_name, column.name, column.comment) if column.comment.present?
84
84
  end
85
85
  end
86
- td.indexes.each { |c,o| add_index table_name, c, o }
86
+ td.indexes.each { |c, o| add_index table_name, c, o }
87
87
 
88
88
  rebuild_primary_key_index_to_default_tablespace(table_name, options)
89
89
  end
@@ -113,10 +113,6 @@ module ActiveRecord
113
113
  self.all_schema_indexes = nil
114
114
  end
115
115
 
116
- def dump_schema_information #:nodoc:
117
- super
118
- end
119
-
120
116
  def insert_versions_sql(versions) # :nodoc:
121
117
  sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
122
118
 
@@ -137,18 +133,10 @@ module ActiveRecord
137
133
  end
138
134
  end
139
135
 
140
- def initialize_schema_migrations_table
141
- super
142
- end
143
-
144
- def update_table_definition(table_name, base) #:nodoc:
145
- OracleEnhanced::Table.new(table_name, base)
146
- end
147
-
148
136
  def add_index(table_name, column_name, options = {}) #:nodoc:
149
137
  index_name, index_type, quoted_column_names, tablespace, index_options = add_index_options(table_name, column_name, options)
150
138
  execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})#{tablespace} #{index_options}"
151
- if index_type == 'UNIQUE'
139
+ if index_type == "UNIQUE"
152
140
  unless quoted_column_names =~ /\(.*\)/
153
141
  execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{quote_column_name(index_name)} #{index_type} (#{quoted_column_names})"
154
142
  end
@@ -173,29 +161,18 @@ module ActiveRecord
173
161
  if index_name.to_s.length > max_index_length
174
162
  raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
175
163
  end
176
- if index_name_exists?(table_name, index_name, false)
164
+ if table_exists?(table_name) && index_name_exists?(table_name, index_name)
177
165
  raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
178
166
  end
179
167
 
180
168
  quoted_column_names = column_names.map { |e| quote_column_name_or_expression(e) }.join(", ")
181
- [index_name, index_type, quoted_column_names, tablespace, index_options]
169
+ [index_name, index_type, quoted_column_names, tablespace, index_options]
182
170
  end
183
171
 
184
172
  # Remove the given index from the table.
185
173
  # Gives warning if index does not exist
186
174
  def remove_index(table_name, options = {}) #:nodoc:
187
175
  index_name = index_name_for_remove(table_name, options)
188
- unless index_name_exists?(table_name, index_name, true)
189
- # sometimes options can be String or Array with column names
190
- options = {} unless options.is_a?(Hash)
191
- if options.has_key? :name
192
- options_without_column = options.dup
193
- options_without_column.delete :column
194
- index_name_without_column = index_name(table_name, options_without_column)
195
- return index_name_without_column if index_name_exists?(table_name, index_name_without_column, false)
196
- end
197
- raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
198
- end
199
176
  #TODO: It should execute only when index_type == "UNIQUE"
200
177
  execute "ALTER TABLE #{quote_table_name(table_name)} DROP CONSTRAINT #{quote_column_name(index_name)}" rescue nil
201
178
  execute "DROP INDEX #{quote_column_name(index_name)}"
@@ -216,11 +193,11 @@ module ActiveRecord
216
193
 
217
194
  # leave just first three letters from each word
218
195
  if shortened_name.length > identifier_max_length
219
- shortened_name = shortened_name.split('_').map{|w| w[0,3]}.join('_')
196
+ shortened_name = shortened_name.split("_").map { |w| w[0, 3] }.join("_")
220
197
  end
221
198
  # generate unique name using hash function
222
199
  if shortened_name.length > identifier_max_length
223
- shortened_name = 'i'+Digest::SHA1.hexdigest(default_name)[0,identifier_max_length-1]
200
+ shortened_name = "i" + Digest::SHA1.hexdigest(default_name)[0, identifier_max_length - 1]
224
201
  end
225
202
  @logger.warn "#{adapter_name} shortened default index name #{default_name} to #{shortened_name}" if @logger
226
203
  shortened_name
@@ -232,7 +209,12 @@ module ActiveRecord
232
209
  # as there's no way to determine the correct answer in that case.
233
210
  #
234
211
  # Will always query database and not index cache.
235
- def index_name_exists?(table_name, index_name, default)
212
+ def index_name_exists?(table_name, index_name, default = nil)
213
+ unless default.nil?
214
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
215
+ Passing default to #index_name_exists? is deprecated without replacement.
216
+ MSG
217
+ end
236
218
  (owner, table_name, db_link) = @connection.describe(table_name)
237
219
  result = select_value(<<-SQL)
238
220
  SELECT 1 FROM all_indexes#{db_link} i
@@ -245,31 +227,23 @@ module ActiveRecord
245
227
  end
246
228
 
247
229
  def rename_index(table_name, old_name, new_name) #:nodoc:
248
- unless index_name_exists?(table_name, old_name, true)
249
- raise ArgumentError, "Index name '#{old_name}' on table '#{table_name}' does not exist"
250
- end
251
- if new_name.length > allowed_index_name_length
252
- raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
253
- end
230
+ validate_index_length!(table_name, new_name)
254
231
  execute "ALTER INDEX #{quote_column_name(old_name)} rename to #{quote_column_name(new_name)}"
255
232
  ensure
256
233
  self.all_schema_indexes = nil
257
234
  end
258
235
 
236
+ def add_reference(table_name, *args)
237
+ ActiveRecord::ConnectionAdapters::OracleEnhanced::ReferenceDefinition.new(*args).add_to(update_table_definition(table_name, self))
238
+ end
239
+
259
240
  def add_column(table_name, column_name, type, options = {}) #:nodoc:
260
- if type.to_sym == :virtual
261
- type = options[:type]
262
- end
263
241
  type = aliased_types(type.to_s, type)
264
- add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} "
265
- add_column_sql << type_to_sql(type, options[:limit], options[:precision], options[:scale]) if type
266
-
267
- add_column_options!(add_column_sql, options.merge(:type=>type, :column_name=>column_name, :table_name=>table_name))
268
-
269
- add_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, table_name, column_name) if type
270
-
271
- execute(add_column_sql)
272
-
242
+ at = create_alter_table table_name
243
+ at.add_column(column_name, type, options)
244
+ add_column_sql = schema_creation.accept at
245
+ add_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, table_name, column_name)
246
+ execute add_column_sql
273
247
  create_sequence_and_trigger(table_name, options) if type && type.to_sym == :primary_key
274
248
  change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
275
249
  ensure
@@ -294,7 +268,7 @@ module ActiveRecord
294
268
  execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
295
269
  end
296
270
 
297
- change_column table_name, column_name, column.sql_type, :null => null
271
+ change_column table_name, column_name, column.sql_type, null: null
298
272
  end
299
273
 
300
274
  def change_column(table_name, column_name, type, options = {}) #:nodoc:
@@ -308,14 +282,15 @@ module ActiveRecord
308
282
  if type.to_sym == :virtual
309
283
  type = options[:type]
310
284
  end
311
- change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} "
312
- change_column_sql << "#{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" if type
313
-
314
- add_column_options!(change_column_sql, options.merge(:type=>type, :column_name=>column_name, :table_name=>table_name))
315
-
316
- change_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, options[:table_name], options[:column_name]) if type
317
285
 
286
+ td = create_table_definition(table_name)
287
+ cd = td.new_column_definition(column.name, type, options)
288
+ change_column_stmt = schema_creation.accept cd
289
+ change_column_stmt << tablespace_for((type_to_sql(type).downcase.to_sym), nil, options[:table_name], options[:column_name]) if type
290
+ change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{change_column_stmt}"
318
291
  execute(change_column_sql)
292
+
293
+ change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
319
294
  ensure
320
295
  clear_table_columns_cache(table_name)
321
296
  end
@@ -366,9 +341,9 @@ module ActiveRecord
366
341
  end
367
342
 
368
343
  # Maps logical Rails types to Oracle-specific data types.
369
- def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
344
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **) #:nodoc:
370
345
  # Ignore options for :text and :binary columns
371
- return super(type, nil, nil, nil) if ['text', 'binary'].include?(type.to_s)
346
+ return super(type) if ["text", "binary"].include?(type.to_s)
372
347
 
373
348
  super
374
349
  end
@@ -382,28 +357,11 @@ module ActiveRecord
382
357
  SQL
383
358
  end
384
359
 
385
- def add_foreign_key(from_table, to_table, options = {})
386
- if options[:dependent]
387
- ActiveSupport::Deprecation.warn "`:dependent` option will be deprecated. Please use `:on_delete` option"
388
- end
389
- case options[:dependent]
390
- when :delete then options[:on_delete] = :cascade
391
- when :nullify then options[:on_delete] = :nullify
392
- else
393
- end
394
-
395
- super
396
- end
397
-
398
- def remove_foreign_key(from_table, options_or_to_table = {})
399
- super
400
- end
401
-
402
360
  # get table foreign keys for schema dump
403
361
  def foreign_keys(table_name) #:nodoc:
404
362
  (owner, desc_table_name, db_link) = @connection.describe(table_name)
405
363
 
406
- fk_info = select_all(<<-SQL, 'Foreign Keys')
364
+ fk_info = select_all(<<-SQL, "Foreign Keys")
407
365
  SELECT r.table_name to_table
408
366
  ,rc.column_name references_column
409
367
  ,cc.column_name
@@ -412,7 +370,7 @@ module ActiveRecord
412
370
  FROM all_constraints#{db_link} c, all_cons_columns#{db_link} cc,
413
371
  all_constraints#{db_link} r, all_cons_columns#{db_link} rc
414
372
  WHERE c.owner = '#{owner}'
415
- AND c.table_name = '#{desc_table_name}'
373
+ AND c.table_name = q'[#{desc_table_name}]'
416
374
  AND c.constraint_type = 'R'
417
375
  AND cc.owner = c.owner
418
376
  AND cc.constraint_name = c.constraint_name
@@ -426,19 +384,19 @@ module ActiveRecord
426
384
 
427
385
  fk_info.map do |row|
428
386
  options = {
429
- column: oracle_downcase(row['column_name']),
430
- name: oracle_downcase(row['name']),
431
- primary_key: oracle_downcase(row['references_column'])
387
+ column: oracle_downcase(row["column_name"]),
388
+ name: oracle_downcase(row["name"]),
389
+ primary_key: oracle_downcase(row["references_column"])
432
390
  }
433
- options[:on_delete] = extract_foreign_key_action(row['delete_rule'])
434
- OracleEnhanced::ForeignKeyDefinition.new(oracle_downcase(table_name), oracle_downcase(row['to_table']), options)
391
+ options[:on_delete] = extract_foreign_key_action(row["delete_rule"])
392
+ ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(oracle_downcase(table_name), oracle_downcase(row["to_table"]), options)
435
393
  end
436
394
  end
437
395
 
438
396
  def extract_foreign_key_action(specifier) # :nodoc:
439
397
  case specifier
440
- when 'CASCADE'; :cascade
441
- when 'SET NULL'; :nullify
398
+ when "CASCADE"; :cascade
399
+ when "SET NULL"; :nullify
442
400
  end
443
401
  end
444
402
 
@@ -465,48 +423,52 @@ module ActiveRecord
465
423
  end
466
424
  end
467
425
 
468
- private
469
-
470
426
  def create_alter_table(name)
471
- OracleEnhanced::AlterTable.new create_table_definition(name, false, {})
427
+ ActiveRecord::ConnectionAdapters::OracleEnhanced::AlterTable.new create_table_definition(name, false, {})
472
428
  end
473
429
 
474
- def tablespace_for(obj_type, tablespace_option, table_name=nil, column_name=nil)
475
- tablespace_sql = ''
476
- if tablespace = (tablespace_option || default_tablespace_for(obj_type))
477
- tablespace_sql << if [:blob, :clob].include?(obj_type.to_sym)
478
- " LOB (#{quote_column_name(column_name)}) STORE AS #{column_name.to_s[0..10]}_#{table_name.to_s[0..14]}_ls (TABLESPACE #{tablespace})"
479
- else
480
- " TABLESPACE #{tablespace}"
430
+ def update_table_definition(table_name, base)
431
+ ActiveRecord::ConnectionAdapters::OracleEnhanced::Table.new(table_name, base)
432
+ end
433
+
434
+ private
435
+
436
+ def tablespace_for(obj_type, tablespace_option, table_name = nil, column_name = nil)
437
+ tablespace_sql = ""
438
+ if tablespace = (tablespace_option || default_tablespace_for(obj_type))
439
+ if [:blob, :clob].include?(obj_type.to_sym)
440
+ tablespace_sql << " LOB (#{quote_column_name(column_name)}) STORE AS #{column_name.to_s[0..10]}_#{table_name.to_s[0..14]}_ls (TABLESPACE #{tablespace})"
441
+ else
442
+ tablespace_sql << " TABLESPACE #{tablespace}"
443
+ end
481
444
  end
445
+ tablespace_sql
482
446
  end
483
- tablespace_sql
484
- end
485
447
 
486
- def default_tablespace_for(type)
487
- (default_tablespaces[type] || default_tablespaces[native_database_types[type][:name]]) rescue nil
488
- end
448
+ def default_tablespace_for(type)
449
+ (default_tablespaces[type] || default_tablespaces[native_database_types[type][:name]]) rescue nil
450
+ end
489
451
 
490
- def column_for(table_name, column_name)
491
- unless column = columns(table_name).find { |c| c.name == column_name.to_s }
492
- raise "No such column: #{table_name}.#{column_name}"
452
+ def column_for(table_name, column_name)
453
+ unless column = columns(table_name).find { |c| c.name == column_name.to_s }
454
+ raise "No such column: #{table_name}.#{column_name}"
455
+ end
456
+ column
493
457
  end
494
- column
495
- end
496
458
 
497
- def create_sequence_and_trigger(table_name, options)
498
- seq_name = options[:sequence_name] || default_sequence_name(table_name)
499
- seq_start_value = options[:sequence_start_value] || default_sequence_start_value
500
- execute "CREATE SEQUENCE #{quote_table_name(seq_name)} START WITH #{seq_start_value}"
459
+ def create_sequence_and_trigger(table_name, options)
460
+ seq_name = options[:sequence_name] || default_sequence_name(table_name)
461
+ seq_start_value = options[:sequence_start_value] || default_sequence_start_value
462
+ execute "CREATE SEQUENCE #{quote_table_name(seq_name)} START WITH #{seq_start_value}"
501
463
 
502
- create_primary_key_trigger(table_name, options) if options[:primary_key_trigger]
503
- end
464
+ create_primary_key_trigger(table_name, options) if options[:primary_key_trigger]
465
+ end
504
466
 
505
- def create_primary_key_trigger(table_name, options)
506
- seq_name = options[:sequence_name] || default_sequence_name(table_name)
507
- trigger_name = options[:trigger_name] || default_trigger_name(table_name)
508
- primary_key = options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)
509
- execute compress_lines(<<-SQL)
467
+ def create_primary_key_trigger(table_name, options)
468
+ seq_name = options[:sequence_name] || default_sequence_name(table_name)
469
+ trigger_name = options[:trigger_name] || default_trigger_name(table_name)
470
+ primary_key = options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)
471
+ execute compress_lines(<<-SQL)
510
472
  CREATE OR REPLACE TRIGGER #{quote_table_name(trigger_name)}
511
473
  BEFORE INSERT ON #{quote_table_name(table_name)} FOR EACH ROW
512
474
  BEGIN
@@ -517,28 +479,28 @@ module ActiveRecord
517
479
  END IF;
518
480
  END;
519
481
  SQL
520
- end
482
+ end
521
483
 
522
- def default_trigger_name(table_name)
523
- # truncate table name if necessary to fit in max length of identifier
524
- "#{table_name.to_s[0,table_name_length-4]}_pkt"
525
- end
484
+ def default_trigger_name(table_name)
485
+ # truncate table name if necessary to fit in max length of identifier
486
+ "#{table_name.to_s[0, table_name_length - 4]}_pkt"
487
+ end
526
488
 
527
- def rebuild_primary_key_index_to_default_tablespace(table_name, options)
528
- tablespace = default_tablespace_for(:index)
489
+ def rebuild_primary_key_index_to_default_tablespace(table_name, options)
490
+ tablespace = default_tablespace_for(:index)
529
491
 
530
- return unless tablespace
492
+ return unless tablespace
531
493
 
532
- index_name = Base.connection.select_value(
533
- "SELECT index_name FROM all_constraints
534
- WHERE table_name = #{quote(table_name.upcase)}
535
- AND constraint_type = 'P'
536
- AND owner = SYS_CONTEXT('userenv', 'current_schema')")
494
+ index_name = Base.connection.select_value(
495
+ "SELECT index_name FROM all_constraints
496
+ WHERE table_name = #{quote(table_name.upcase)}
497
+ AND constraint_type = 'P'
498
+ AND owner = SYS_CONTEXT('userenv', 'current_schema')")
537
499
 
538
- return unless index_name
500
+ return unless index_name
539
501
 
540
- execute("ALTER INDEX #{quote_column_name(index_name)} REBUILD TABLESPACE #{tablespace}")
541
- end
502
+ execute("ALTER INDEX #{quote_column_name(index_name)} REBUILD TABLESPACE #{tablespace}")
503
+ end
542
504
  end
543
505
  end
544
506
  end
@@ -16,7 +16,7 @@ module ActiveRecord
16
16
  # # ...
17
17
  # end
18
18
  #
19
- def add_primary_key_trigger(table_name, options={})
19
+ def add_primary_key_trigger(table_name, options = {})
20
20
  # call the same private method that is used for create_table :primary_key_trigger => true
21
21
  create_primary_key_trigger(table_name, options)
22
22
  end
@@ -50,8 +50,8 @@ module ActiveRecord
50
50
  # get synonyms for schema dump
51
51
  def synonyms #:nodoc:
52
52
  select_all("SELECT synonym_name, table_owner, table_name, db_link FROM all_synonyms where owner = SYS_CONTEXT('userenv', 'session_user')").collect do |row|
53
- OracleEnhanced::SynonymDefinition.new(oracle_downcase(row['synonym_name']),
54
- oracle_downcase(row['table_owner']), oracle_downcase(row['table_name']), oracle_downcase(row['db_link']))
53
+ OracleEnhanced::SynonymDefinition.new(oracle_downcase(row["synonym_name"]),
54
+ oracle_downcase(row["table_owner"]), oracle_downcase(row["table_name"]), oracle_downcase(row["db_link"]))
55
55
  end
56
56
  end
57
57
  end
@@ -15,15 +15,15 @@ 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(%Q{
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
- }).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'])
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
@@ -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['data_type'] =='NUMBER' and !column['data_precision'].nil?
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['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})"
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['data_default'].nil?
55
- col << ' NOT NULL' if column['nullable'] == 'N'
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['data_type'] =='NUMBER' and !column['data_precision'].nil?
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['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})"
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 = {:name => '', :cols => []}
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['constraint_name']
87
- opts[:cols][row['position']-1] = row['column_name']
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['constraint_name']] ||= []
106
- keys[uk['constraint_name']][uk['position']-1] = uk['column_name']
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 = {:name => options[:name], :unique => options[:unique]}
117
- index_name = index_name(table_name, :column => column_names)
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
- columns = Array(options[:column] || options[:columns])
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
- if columns.size > 1
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(%Q{
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
- }).each do |row|
210
- ddl << row['text']
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
- # virtual columns are an 11g feature. This returns [] if feature is not
300
- # present or none are found.
301
- # return [{'column_name' => 'FOOS', 'data_default' => '...'}, ...]
302
- def virtual_columns_for(table)
303
- begin
304
- select_all <<-SQL
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
- # feature not supported previous to 11g
312
- rescue ActiveRecord::StatementInvalid => _e
313
- []
276
+ # feature not supported previous to 11g
277
+ rescue ActiveRecord::StatementInvalid => _e
278
+ []
279
+ end
314
280
  end
315
- end
316
281
 
317
- def drop_sql_for_feature(type)
318
- short_type = type == 'materialized view' ? 'mview' : type
319
- join_with_statement_token(
320
- select_values("SELECT #{short_type}_name FROM all_#{short_type.tableize} where owner = SYS_CONTEXT('userenv', 'session_user')").map do |name|
321
- "DROP #{type.upcase} \"#{name}\""
322
- end)
323
- end
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
- def drop_sql_for_object(type)
326
- join_with_statement_token(
327
- select_values("SELECT object_name FROM all_objects WHERE object_type = '#{type.upcase}' and owner = SYS_CONTEXT('userenv', 'session_user')").map do |name|
328
- "DROP #{type.upcase} \"#{name}\""
329
- end)
330
- end
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
- def join_with_statement_token(array)
333
- string = array.join(STATEMENT_TOKEN)
334
- string << STATEMENT_TOKEN unless string.blank?
335
- string
336
- end
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