Module: ArJdbc::Oracle

Included in:
ActiveRecord::ConnectionAdapters::OracleAdapter
Defined in:
lib/arjdbc/oracle/column.rb,
lib/arjdbc/oracle/adapter.rb

Defined Under Namespace

Modules: Column Classes: TableDefinition

Constant Summary collapse

ADAPTER_NAME =
'Oracle'.freeze
NATIVE_DATABASE_TYPES =
{
  :primary_key => "NUMBER(38) NOT NULL PRIMARY KEY",
  :string => { :name => "VARCHAR2", :limit => 255 },
  :text => { :name => "CLOB" },
  :integer => { :name => "NUMBER", :limit => 38 },
  :float => { :name => "NUMBER" },
  :decimal => { :name => "DECIMAL" },
  :datetime => { :name => "DATE" },
  :timestamp => { :name => "TIMESTAMP" },
  :time => { :name => "DATE" },
  :date => { :name => "DATE" },
  :binary => { :name => "BLOB" },
  :boolean => { :name => "NUMBER", :limit => 1 },
  :raw => { :name => "RAW", :limit => 2000 },
  :xml => { :name => 'XMLTYPE' }
}
IDENTIFIER_LENGTH =
30
AUTOGENERATED_SEQUENCE_NAME =

use in set_sequence_name to avoid fetching primary key value from sequence

'autogenerated'.freeze
@@do_not_prefetch_primary_key =
{}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.arel_visitor_type(config = nil) ⇒ Object



126
127
128
# File 'lib/arjdbc/oracle/adapter.rb', line 126

def self.arel_visitor_type(config = nil)
  ::Arel::Visitors::Oracle
end

.column_selectorObject

See Also:

  • ActiveRecord::ConnectionAdapters::JdbcColumn#column_types


5
6
7
# File 'lib/arjdbc/oracle/column.rb', line 5

def self.column_selector
  [ /oracle/i, lambda { |config, column| column.extend(Column) } ]
end

.emulate_booleansObject

Deprecated.

Use #emulate_booleans? instead.



89
# File 'lib/arjdbc/oracle/adapter.rb', line 89

def self.emulate_booleans; @@emulate_booleans; end

.emulate_booleans=(emulate) ⇒ Object

See Also:

  • #emulate_booleans?


91
# File 'lib/arjdbc/oracle/adapter.rb', line 91

def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end

.emulate_booleans?Boolean

Boolean emulation can be disabled using :

ArJdbc::Oracle.emulate_booleans = false

Returns:

  • (Boolean)

See Also:

  • ActiveRecord::ConnectionAdapters::OracleAdapter#emulate_booleans


87
# File 'lib/arjdbc/oracle/adapter.rb', line 87

def self.emulate_booleans?; @@emulate_booleans; end

.jdbc_connection_classObject



53
54
55
# File 'lib/arjdbc/oracle/adapter.rb', line 53

def self.jdbc_connection_class
  ::ActiveRecord::ConnectionAdapters::OracleJdbcConnection
end

.update_lob_values=(update) ⇒ Object

See Also:

  • #update_lob_values?


71
# File 'lib/arjdbc/oracle/adapter.rb', line 71

def self.update_lob_values=(update); @@update_lob_values = update; end

.update_lob_values?Boolean

Note:

This only applies when prepared statements are not used.

Updating records with LOB values (binary/text columns) in a separate statement can be disabled using :

ArJdbc::Oracle.update_lob_values = false

Returns:

  • (Boolean)


69
# File 'lib/arjdbc/oracle/adapter.rb', line 69

def self.update_lob_values?; @@update_lob_values; end

Instance Method Details

#adapter_nameObject



138
139
140
# File 'lib/arjdbc/oracle/adapter.rb', line 138

def adapter_name
  ADAPTER_NAME
end

#add_column_options!(sql, options) ⇒ Object



416
417
418
419
420
421
422
# File 'lib/arjdbc/oracle/adapter.rb', line 416

def add_column_options!(sql, options)
  # handle case  of defaults for CLOB columns, which would otherwise get "quoted" incorrectly
  if options_include_default?(options) && (column = options[:column]) && column.type == :text
    sql << " DEFAULT #{quote(options.delete(:default))}"
  end
  super
end

#add_limit_offset!(sql, options) ⇒ Object

Note:

Only used with (non-AREL) ActiveRecord 2.3.

See Also:

  • Arel::Visitors::Oracle


319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/arjdbc/oracle/adapter.rb', line 319

def add_limit_offset!(sql, options)
  offset = options[:offset] || 0
  if limit = options[:limit]
    sql.replace "SELECT * FROM " <<
      "(select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_ where rownum <= #{offset + limit})" <<
      " WHERE raw_rnum_ > #{offset}"
  elsif offset > 0
    sql.replace "SELECT * FROM " <<
      "(select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_)" <<
      " WHERE raw_rnum_ > #{offset}"
  end
end

#add_order_by_for_association_limiting!(sql, options) ⇒ Object

ORDER BY clause for the passed order option.

Uses column aliases as defined by #distinct.



498
499
500
501
502
503
504
505
506
507
# File 'lib/arjdbc/oracle/adapter.rb', line 498

def add_order_by_for_association_limiting!(sql, options)
  return sql if options[:order].blank?

  order_columns = extract_order_columns(options[:order]) do |columns|
    columns.map! { |s| $1 if s =~ / (.*)/ }; columns
  end
  order = order_columns.map { |s, i| "alias_#{i}__ #{s}" } # @see {#distinct}

  sql << "ORDER BY #{order.join(', ')}"
end

#change_column(table_name, column_name, type, options = {}) ⇒ Object



425
426
427
428
429
430
# File 'lib/arjdbc/oracle/adapter.rb', line 425

def change_column(table_name, column_name, type, options = {})
  change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} " <<
    "MODIFY #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit])}"
  add_column_options!(change_column_sql, options)
  execute(change_column_sql)
end

#change_column_default(table_name, column_name, default) ⇒ Object



411
412
413
# File 'lib/arjdbc/oracle/adapter.rb', line 411

def change_column_default(table_name, column_name, default)
  execute "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
end

#charsetObject



534
535
536
# File 'lib/arjdbc/oracle/adapter.rb', line 534

def charset
  database_parameters['NLS_CHARACTERSET']
end

#clear_cache!Object



167
168
169
170
# File 'lib/arjdbc/oracle/adapter.rb', line 167

def clear_cache!
  super
  reload_type_map
end

#collationObject



538
539
540
# File 'lib/arjdbc/oracle/adapter.rb', line 538

def collation
  database_parameters['NLS_COMP']
end

#column_name_lengthObject



240
# File 'lib/arjdbc/oracle/adapter.rb', line 240

def column_name_length; IDENTIFIER_LENGTH; end

#columns(table_name, name = nil) ⇒ Object

NOTE: better to use current_schema instead of the configured one ?!



526
527
528
# File 'lib/arjdbc/oracle/adapter.rb', line 526

def columns(table_name, name = nil)
  @connection.columns_internal(table_name.to_s, nil, oracle_schema)
end

#columns_for_distinct(columns, orders) ⇒ Object



479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'lib/arjdbc/oracle/adapter.rb', line 479

def columns_for_distinct(columns, orders)
  return columns if orders.blank?
  if orders.is_a?(Array) # AR 3.x vs 4.x
    orders = orders.map { |column| column.is_a?(String) ? column : column.to_sql }
  else
    orders = extract_order_columns(orders)
  end
  # construct a valid DISTINCT clause, ie. one that includes the ORDER BY columns, using
  # FIRST_VALUE such that the inclusion of these columns doesn't invalidate the DISTINCT
  order_columns = orders.map do |c, i|
    "FIRST_VALUE(#{c.split.first}) OVER (PARTITION BY #{columns} ORDER BY #{c}) AS alias_#{i}__"
  end
  columns = [ columns ]; columns.flatten!
  columns.push( *order_columns ).join(', ')
end

#create_table(name, options = {}) ⇒ Object



256
257
258
259
260
261
262
263
264
# File 'lib/arjdbc/oracle/adapter.rb', line 256

def create_table(name, options = {})
  super(name, options)
  unless options[:id] == false
    seq_name = options[:sequence_name] || default_sequence_name(name)
    start_value = options[:sequence_start_value] || 10000
    raise ActiveRecord::StatementInvalid.new("name #{seq_name} too long") if seq_name.length > table_alias_length
    execute "CREATE SEQUENCE #{quote_table_name(seq_name)} START WITH #{start_value}"
  end
end

#create_table_definition(name, temporary, options, as = nil) ⇒ Object



122
123
124
# File 'lib/arjdbc/oracle/adapter.rb', line 122

def create_table_definition(name, temporary, options, as = nil)
  TableDefinition.new native_database_types, name, temporary, options, as
end

#current_databaseObject



336
337
338
# File 'lib/arjdbc/oracle/adapter.rb', line 336

def current_database
  @current_database ||= execute("SELECT sys_context('userenv', 'db_name') db FROM dual").first['db']
end

#current_schemaObject



340
341
342
# File 'lib/arjdbc/oracle/adapter.rb', line 340

def current_schema
  execute("SELECT sys_context('userenv', 'current_schema') schema FROM dual").first['schema']
end

#current_schema=(schema_owner) ⇒ Object



344
345
346
# File 'lib/arjdbc/oracle/adapter.rb', line 344

def current_schema=(schema_owner)
  execute("ALTER SESSION SET current_schema=#{schema_owner}")
end

#current_userObject



332
333
334
# File 'lib/arjdbc/oracle/adapter.rb', line 332

def current_user
  @current_user ||= execute("SELECT sys_context('userenv', 'session_user') su FROM dual").first['su']
end

#database_parametersObject



542
543
544
545
546
547
548
# File 'lib/arjdbc/oracle/adapter.rb', line 542

def database_parameters
  return @database_parameters unless ( @database_parameters ||= {} ).empty?
  @connection.execute_query_raw("SELECT * FROM NLS_DATABASE_PARAMETERS") do
    |name, value| @database_parameters[name] = value
  end
  @database_parameters
end

#distinct(columns, order_by) ⇒ Object

SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.

Oracle requires the ORDER BY columns to be in the SELECT list for DISTINCT queries. However, with those columns included in the SELECT DISTINCT list, you won't actually get a distinct list of the column you want (presuming the column has duplicates with multiple values for the ordered-by columns. So we use the FIRST_VALUE function to get a single (first) value for each column, effectively making every row the same.

distinct("posts.id", "posts.created_at desc")



474
475
476
# File 'lib/arjdbc/oracle/adapter.rb', line 474

def distinct(columns, order_by)
  "DISTINCT #{columns_for_distinct(columns, order_by)}"
end

#drop_table(name, options = {}) ⇒ Object



279
280
281
282
283
284
285
286
# File 'lib/arjdbc/oracle/adapter.rb', line 279

def drop_table(name, options = {})
  outcome = super(name)
  return outcome if name == 'schema_migrations'
  seq_name = options.key?(:sequence_name) ? # pass nil/false - no sequence
    options[:sequence_name] : default_sequence_name(name)
  return outcome unless seq_name
  execute_quietly "DROP SEQUENCE #{quote_table_name(seq_name)}"
end

#exec_insert(sql, name, binds, pk = nil, sequence_name = nil) ⇒ Object



830
831
832
833
834
835
836
837
# File 'lib/arjdbc/oracle/adapter.rb', line 830

def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
  if pk && use_insert_returning?
    if sql.is_a?(String) && sql.index('RETURNING')
      return exec_insert_returning(sql, name, binds, pk)
    end
  end
  super(sql, name, binds) # assume no generated id for table
end

#exec_insert_returning(sql, name, binds, pk = nil) ⇒ Object



839
840
841
842
843
844
845
846
# File 'lib/arjdbc/oracle/adapter.rb', line 839

def exec_insert_returning(sql, name, binds, pk = nil)
  sql = to_sql(sql, binds) if sql.respond_to?(:to_sql)
  if prepared_statements?
    log(sql, name, binds) { @connection.execute_insert_returning(sql, binds) }
  else
    log(sql, name) { @connection.execute_insert_returning(sql, nil) }
  end
end

#explain(arel, binds = []) ⇒ Object



670
671
672
673
674
675
# File 'lib/arjdbc/oracle/adapter.rb', line 670

def explain(arel, binds = [])
  sql = "EXPLAIN PLAN FOR #{to_sql(arel, binds)}"
  return if sql =~ /FROM all_/
  exec_update(sql, 'EXPLAIN', binds)
  select_values("SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)", 'EXPLAIN').join("\n")
end

#in_clause_lengthObject Also known as: ids_in_list_limit

Prevent ORA-01795 for in clauses with more than 1000



229
230
231
# File 'lib/arjdbc/oracle/adapter.rb', line 229

def in_clause_length
  1000
end

#index_name_lengthObject



239
# File 'lib/arjdbc/oracle/adapter.rb', line 239

def index_name_length;  IDENTIFIER_LENGTH; end

#indexes(table, name = nil) ⇒ Object



313
314
315
# File 'lib/arjdbc/oracle/adapter.rb', line 313

def indexes(table, name = nil)
  @connection.indexes(table, name, schema_owner)
end

#initialize_type_map(m) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/arjdbc/oracle/adapter.rb', line 142

def initialize_type_map(m)
  super

  m.register_type(%r(NUMBER)i) do |sql_type|
    scale = extract_scale(sql_type)
    precision = extract_precision(sql_type)
    limit = extract_limit(sql_type)
    if scale == 0
      if Oracle.emulate_booleans? && limit == 1
        ActiveRecord::Type::Boolean.new
      else
        ActiveRecord::Type::Integer.new(:precision => precision, :limit => limit)
      end
    else
      ActiveRecord::Type::Decimal.new(:precision => precision, :scale => scale)
    end
  end

  register_class_with_limit m, %r(date)i,      ActiveRecord::Type::DateTime
  register_class_with_limit m, %r(raw)i,       RawType
  register_class_with_limit m, %r(timestamp)i, TimestampType

  m.register_type %r(xmltype)i, XmlType.new
end

#insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object



816
817
818
819
820
821
822
823
824
825
826
827
# File 'lib/arjdbc/oracle/adapter.rb', line 816

def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
  # NOTE: ActiveRecord::Relation calls our {#next_sequence_value}
  # (from its `insert`) and passes the returned id_value here ...
  sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
  if id_value
    exec_update(sql, name, binds)
    return id_value
  else
    value = exec_insert(sql, name, binds, pk, sequence_name)
    id_value || last_inserted_id(value)
  end
end

#insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) ⇒ Object (protected)



789
790
791
792
793
794
795
796
797
798
799
800
801
802
# File 'lib/arjdbc/oracle/adapter.rb', line 789

def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
  # if PK is already pre-fetched from sequence or if there is no PK :
  if id_value || pk.nil?
    execute(sql, name)
    return id_value
  end

  if pk && use_insert_returning? # true by default on AR <= 3.0
    sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO ?"
    exec_insert_returning(sql, name, nil, pk)
  else
    execute(sql, name)
  end
end

#jdbc_column_classObject



58
# File 'lib/arjdbc/oracle/adapter.rb', line 58

def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::OracleColumn end

#modify_types(types) ⇒ Object



220
221
222
223
224
225
226
# File 'lib/arjdbc/oracle/adapter.rb', line 220

def modify_types(types)
  super(types)
  NATIVE_DATABASE_TYPES.each do |key, value|
    types[key] = value.dup
  end
  types
end

#native_database_typesObject



216
217
218
# File 'lib/arjdbc/oracle/adapter.rb', line 216

def native_database_types
  super.merge(NATIVE_DATABASE_TYPES)
end

#next_sequence_value(sequence_name) ⇒ Object

Returns the next sequence value from a sequence generator. Not generally called directly; used by ActiveRecord to get the next primary key value when inserting a new database record (see #prefetch_primary_key?).



731
732
733
734
735
736
737
# File 'lib/arjdbc/oracle/adapter.rb', line 731

def next_sequence_value(sequence_name)
  # if sequence_name is set to :autogenerated then it means that primary key will be populated by trigger
  return nil if sequence_name == AUTOGENERATED_SEQUENCE_NAME
  sequence_name = quote_table_name(sequence_name)
  sql = "SELECT #{sequence_name}.NEXTVAL id FROM dual"
  log(sql, 'SQL') { @connection.next_sequence_value(sequence_name) }
end

#prefetch_primary_key?(table_name = nil) ⇒ Boolean

Returns true for Oracle adapter (since Oracle requires primary key values to be pre-fetched before insert).

Returns:

  • (Boolean)

See Also:



690
691
692
693
694
695
696
697
698
699
700
701
# File 'lib/arjdbc/oracle/adapter.rb', line 690

def prefetch_primary_key?(table_name = nil)
  return true if table_name.nil?
  do_not_prefetch_hash = @@do_not_prefetch_primary_key
  do_not_prefetch = do_not_prefetch_hash[ table_name = table_name.to_s ]
  if do_not_prefetch.nil?
    owner, desc_table_name, db_link = describe(table_name)
    do_not_prefetch_hash[table_name] = do_not_prefetch =
      ! has_primary_key?(table_name, owner, desc_table_name, db_link) ||
      has_primary_key_trigger?(table_name, owner, desc_table_name, db_link)
  end
  ! do_not_prefetch
end

#primary_key(table_name) ⇒ Object

Returns just a table's primary key



764
765
766
767
# File 'lib/arjdbc/oracle/adapter.rb', line 764

def primary_key(table_name)
  pk_and_sequence = pk_and_sequence_for(table_name)
  pk_and_sequence && pk_and_sequence.first
end

#quote(value, column = nil) ⇒ Object



584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
# File 'lib/arjdbc/oracle/adapter.rb', line 584

def quote(value, column = nil)
  return value if sql_literal?(value)

  column_type = column && column.type
  if column_type == :text || column_type == :binary
    return 'NULL' if value.nil? || value == ''
    if update_lob_value?(value, column)
      if /(.*?)\([0-9]+\)/ =~ ( sql_type = column.sql_type )
        %Q{empty_#{ $1.downcase }()}
      else
        %Q{empty_#{ sql_type.respond_to?(:downcase) ? sql_type.downcase : 'blob' }()}
      end
    else
      "'#{quote_string(value.to_s)}'"
    end
  elsif column_type == :xml
    "XMLTYPE('#{quote_string(value)}')" # XMLTYPE ?
  elsif column_type == :raw
    quote_raw(value)
  else
    if column.respond_to?(:primary) && column.primary && column.klass != String
      return value.to_i.to_s
    end

    if column_type == :datetime || column_type == :time
      if value.acts_like?(:time)
        %Q{TO_DATE('#{get_time(value).strftime("%Y-%m-%d %H:%M:%S")}','YYYY-MM-DD HH24:MI:SS')}
      else
        value.blank? ? 'NULL' : %Q{DATE'#{value}'} # assume correctly formated DATE (string)
      end
    elsif ( like_date = value.acts_like?(:date) ) || column_type == :date
      if value.acts_like?(:time) # value.respond_to?(:strftime)
        %Q{DATE'#{get_time(value).strftime("%Y-%m-%d")}'}
      elsif like_date
        %Q{DATE'#{quoted_date(value)}'} # DATE 'YYYY-MM-DD'
      else
        value.blank? ? 'NULL' : %Q{DATE'#{value}'} # assume correctly formated DATE (string)
      end
    elsif ( like_time = value.acts_like?(:time) ) || column_type == :timestamp
      if like_time
        %Q{TIMESTAMP'#{quoted_date(value, true)}'} # TIMESTAMP 'YYYY-MM-DD HH24:MI:SS.FF'
      else
        value.blank? ? 'NULL' : %Q{TIMESTAMP'#{value}'} # assume correctly formated TIMESTAMP (string)
      end
    else
      super
    end
  end
end

#quote_column_name(name, handle_expression = false) ⇒ Object



561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
# File 'lib/arjdbc/oracle/adapter.rb', line 561

def quote_column_name(name, handle_expression = false)
  # if only valid lowercase column characters in name
  if ( name = name.to_s ) =~ LOWER_CASE_ONLY
    # putting double-quotes around an identifier causes Oracle to treat the
    # identifier as case sensitive (otherwise assumes case-insensitivity) !
    # all upper case is an exception, where double-quotes are meaningless
    "\"#{name.upcase}\"" # name.upcase
  else
    if handle_expression
      name =~ /^[a-z][a-z_0-9\$#\-]*$/i ? "\"#{name}\"" : name
    else
      # remove double quotes which cannot be used inside quoted identifier
      "\"#{name.gsub('"', '')}\""
    end
  end
end

#quote_raw(value) ⇒ Object



646
647
648
649
# File 'lib/arjdbc/oracle/adapter.rb', line 646

def quote_raw(value)
  value = value.unpack('C*') if value.is_a?(String)
  "'#{value.map { |x| "%02X" % x }.join}'"
end

#quote_table_name(name) ⇒ Object



553
554
555
# File 'lib/arjdbc/oracle/adapter.rb', line 553

def quote_table_name(name)
  name.to_s.split('.').map{ |n| n.split('@').map{ |m| quote_column_name(m) }.join('@') }.join('.')
end

#quoted_date(value, time = nil) ⇒ Object

Quote date/time values for use in SQL input. Includes milliseconds if the value is a Time responding to usec.



637
638
639
640
641
642
643
644
# File 'lib/arjdbc/oracle/adapter.rb', line 637

def quoted_date(value, time = nil)
  if time || ( time.nil? && value.acts_like?(:time) )
    usec = value.respond_to?(:usec) && (value.usec / 10000.0).round # .428000 -> .43
    return "#{get_time(value).to_s(:db)}.#{sprintf("%02d", usec)}" if usec
    # value.strftime("%Y-%m-%d %H:%M:%S")
  end
  value.to_s(:db)
end

#release_savepoint(name = nil) ⇒ Object



349
350
351
# File 'lib/arjdbc/oracle/adapter.rb', line 349

def release_savepoint(name = nil)
  # no RELEASE SAVEPOINT statement in Oracle (JDBC driver throws "Unsupported feature")
end

#remove_column(table_name, *column_names) ⇒ Object Also known as: remove_columns



441
442
443
# File 'lib/arjdbc/oracle/adapter.rb', line 441

def remove_column(table_name, column_name, type = nil, options = {})
  do_remove_column(table_name, column_name)
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object



433
434
435
436
# File 'lib/arjdbc/oracle/adapter.rb', line 433

def rename_column(table_name, column_name, new_column_name)
  execute "ALTER TABLE #{quote_table_name(table_name)} " <<
    "RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
end

#rename_table(name, new_name) ⇒ Object



267
268
269
270
271
272
273
274
275
276
# File 'lib/arjdbc/oracle/adapter.rb', line 267

def rename_table(name, new_name)
  if new_name.to_s.length > table_name_length
    raise ArgumentError, "New table name '#{new_name}' is too long; the limit is #{table_name_length} characters"
  end
  if "#{new_name}_seq".to_s.length > sequence_name_length
    raise ArgumentError, "New sequence name '#{new_name}_seq' is too long; the limit is #{sequence_name_length} characters"
  end
  execute "RENAME #{quote_table_name(name)} TO #{quote_table_name(new_name)}"
  execute "RENAME #{quote_table_name("#{name}_seq")} TO #{quote_table_name("#{new_name}_seq")}" rescue nil
end

#select(sql, name = nil, binds = []) ⇒ Object



677
678
679
680
681
682
# File 'lib/arjdbc/oracle/adapter.rb', line 677

def select(sql, name = nil, binds = [])
  result = super # AR::Result (4.0) or Array (<= 3.2)
  result.columns.delete('raw_rnum_') if result.respond_to?(:columns)
  result.each { |row| row.delete('raw_rnum_') } # Hash rows even for AR::Result
  result
end

#sequence_name_lengthObject



241
# File 'lib/arjdbc/oracle/adapter.rb', line 241

def sequence_name_length; IDENTIFIER_LENGTH end

#sql_for_insert(sql, pk, id_value, sequence_name, binds) ⇒ Object



806
807
808
809
810
811
812
813
# File 'lib/arjdbc/oracle/adapter.rb', line 806

def sql_for_insert(sql, pk, id_value, sequence_name, binds)
  unless id_value || pk.nil?
    if pk && use_insert_returning?
      sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO ?"
    end
  end
  [ sql, binds ]
end

#supports_explain?Boolean

Returns:

  • (Boolean)


661
# File 'lib/arjdbc/oracle/adapter.rb', line 661

def supports_explain?; true end

#supports_foreign_keys?Boolean

Returns:

  • (Boolean)


770
# File 'lib/arjdbc/oracle/adapter.rb', line 770

def supports_foreign_keys?; true end

#supports_migrations?Boolean

Returns:

  • (Boolean)


652
# File 'lib/arjdbc/oracle/adapter.rb', line 652

def supports_migrations?; true end

#supports_primary_key?Boolean

Returns:

  • (Boolean)


655
# File 'lib/arjdbc/oracle/adapter.rb', line 655

def supports_primary_key?; true end

#supports_savepoints?Boolean

Returns:

  • (Boolean)


658
# File 'lib/arjdbc/oracle/adapter.rb', line 658

def supports_savepoints?; true end

#supports_views?Boolean

Returns:

  • (Boolean)


664
# File 'lib/arjdbc/oracle/adapter.rb', line 664

def supports_views?; true end

#table_alias_lengthObject

maximum length of Oracle identifiers is 30



237
# File 'lib/arjdbc/oracle/adapter.rb', line 237

def table_alias_length; IDENTIFIER_LENGTH; end

#table_definition(*args) ⇒ Object



118
119
120
# File 'lib/arjdbc/oracle/adapter.rb', line 118

def table_definition(*args)
  new_table_definition(TableDefinition, *args)
end

#table_name_lengthObject



238
# File 'lib/arjdbc/oracle/adapter.rb', line 238

def table_name_length;  IDENTIFIER_LENGTH; end

#tablesObject



521
522
523
# File 'lib/arjdbc/oracle/adapter.rb', line 521

def tables
  @connection.tables(nil, oracle_schema)
end

#tablespace(table_name) ⇒ Object



530
531
532
# File 'lib/arjdbc/oracle/adapter.rb', line 530

def tablespace(table_name)
  select_value "SELECT tablespace_name FROM user_tables WHERE table_name='#{table_name.to_s.upcase}'"
end

#temporary_table?(table_name) ⇒ Boolean

Returns:

  • (Boolean)


517
518
519
# File 'lib/arjdbc/oracle/adapter.rb', line 517

def temporary_table?(table_name)
  select_value("SELECT temporary FROM user_tables WHERE table_name = '#{table_name.upcase}'") == 'Y'
end

#truncate(table_name, name = nil) ⇒ Object



666
667
668
# File 'lib/arjdbc/oracle/adapter.rb', line 666

def truncate(table_name, name = nil)
  execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
end

#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/arjdbc/oracle/adapter.rb', line 289

def type_to_sql(type, limit = nil, precision = nil, scale = nil)
  case type.to_sym
  when :binary
    # { BLOB | BINARY LARGE OBJECT } [ ( length [{K |M |G }] ) ]
    # although Oracle does not like limit (length) with BLOB (or CLOB) :
    #
    # CREATE TABLE binaries (data BLOB, short_data BLOB(1024));
    # ORA-00907: missing right parenthesis             *
    #
    # TODO do we need to worry about NORMAL vs. non IN-TABLE BLOBs ?!
    # http://dba.stackexchange.com/questions/8770/improve-blob-writing-performance-in-oracle-11g
    # - if the LOB is smaller than 3900 bytes it can be stored inside the
    #   table row; by default this is enabled,
    #   unless you specify DISABLE STORAGE IN ROW
    # - normal LOB - stored in a separate segment, outside of table,
    #   you may even put it in another tablespace;
    super(type, nil, nil, nil)
  when :text
    super(type, nil, nil, nil)
  else
    super
  end
end

#unquote_table_name(name) ⇒ Object



578
579
580
581
# File 'lib/arjdbc/oracle/adapter.rb', line 578

def unquote_table_name(name)
  name = name[1...-1] if name[0, 1] == '"'
  name.upcase == name ? name.downcase : name
end

#update_lob_value?(value, column = nil) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



75
76
77
# File 'lib/arjdbc/oracle/adapter.rb', line 75

def update_lob_value?(value, column = nil)
  Oracle.update_lob_values? && ! prepared_statements? && ! ( value.nil? || value == '' )
end

#use_insert_returning?Boolean

Returns:

  • (Boolean)


860
861
862
863
864
865
# File 'lib/arjdbc/oracle/adapter.rb', line 860

def use_insert_returning?
  if @use_insert_returning.nil?
    @use_insert_returning = false
  end
  @use_insert_returning
end