activerecord-oracle_enhanced-adapter 1.7.11 → 1.8.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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