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



145
146
147
# File 'lib/arjdbc/oracle/adapter.rb', line 145

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.



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

def self.emulate_booleans; @@emulate_booleans; end

.emulate_booleans=(emulate) ⇒ Object

See Also:

  • #emulate_booleans?


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

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


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

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?


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

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)


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

def self.update_lob_values?; @@update_lob_values; end

Instance Method Details

#adapter_nameObject



157
158
159
# File 'lib/arjdbc/oracle/adapter.rb', line 157

def adapter_name
  ADAPTER_NAME
end

#add_column_options!(sql, options) ⇒ Object



435
436
437
438
439
440
441
# File 'lib/arjdbc/oracle/adapter.rb', line 435

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


338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/arjdbc/oracle/adapter.rb', line 338

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.



517
518
519
520
521
522
523
524
525
526
# File 'lib/arjdbc/oracle/adapter.rb', line 517

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



444
445
446
447
448
449
# File 'lib/arjdbc/oracle/adapter.rb', line 444

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



430
431
432
# File 'lib/arjdbc/oracle/adapter.rb', line 430

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



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

def charset
  database_parameters['NLS_CHARACTERSET']
end

#clear_cache!Object



186
187
188
189
# File 'lib/arjdbc/oracle/adapter.rb', line 186

def clear_cache!
  super
  reload_type_map
end

#collationObject



557
558
559
# File 'lib/arjdbc/oracle/adapter.rb', line 557

def collation
  database_parameters['NLS_COMP']
end

#column_name_lengthObject



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

def column_name_length; IDENTIFIER_LENGTH; end

#columns(table_name, name = nil) ⇒ Object

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



545
546
547
# File 'lib/arjdbc/oracle/adapter.rb', line 545

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

#columns_for_distinct(columns, orders) ⇒ Object



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

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

#configure_connectionObject

mostly oracle-enhanced config compatibility



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/arjdbc/oracle/adapter.rb', line 60

def configure_connection # mostly oracle-enhanced config compatibility
  jdbc_connection = nil
  if time_zone = config[:time_zone] # || ENV['TZ']
    jdbc_connection ||= jdbc_connection(true)
    jdbc_connection.setSessionTimeZone(time_zone)
  end

  cursor_sharing = config[:cursor_sharing] # || 'force'
  execute "ALTER SESSION SET cursor_sharing = #{cursor_sharing}" if cursor_sharing

  schema = config[:schema] && config[:schema].to_s
  if schema.blank? # default schema owner
    # @owner = username.upcase unless username.nil?
  else
    self.current_schema = schema
    # @owner = schema
  end
end

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



275
276
277
278
279
280
281
282
283
# File 'lib/arjdbc/oracle/adapter.rb', line 275

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



141
142
143
# File 'lib/arjdbc/oracle/adapter.rb', line 141

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

#current_databaseObject



355
356
357
# File 'lib/arjdbc/oracle/adapter.rb', line 355

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

#current_schemaObject



359
360
361
# File 'lib/arjdbc/oracle/adapter.rb', line 359

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

#current_schema=(schema_owner) ⇒ Object



363
364
365
# File 'lib/arjdbc/oracle/adapter.rb', line 363

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

#current_userObject



351
352
353
# File 'lib/arjdbc/oracle/adapter.rb', line 351

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

#database_parametersObject



561
562
563
564
565
566
567
# File 'lib/arjdbc/oracle/adapter.rb', line 561

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")



493
494
495
# File 'lib/arjdbc/oracle/adapter.rb', line 493

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

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



298
299
300
301
302
303
304
305
# File 'lib/arjdbc/oracle/adapter.rb', line 298

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



849
850
851
852
853
854
855
856
# File 'lib/arjdbc/oracle/adapter.rb', line 849

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



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

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



689
690
691
692
693
694
# File 'lib/arjdbc/oracle/adapter.rb', line 689

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



248
249
250
# File 'lib/arjdbc/oracle/adapter.rb', line 248

def in_clause_length
  1000
end

#index_name_lengthObject



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

def index_name_length;  IDENTIFIER_LENGTH; end

#indexes(table, name = nil) ⇒ Object



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

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

#initialize_type_map(m) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/arjdbc/oracle/adapter.rb', line 161

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



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

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)



808
809
810
811
812
813
814
815
816
817
818
819
820
821
# File 'lib/arjdbc/oracle/adapter.rb', line 808

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



239
240
241
242
243
244
245
# File 'lib/arjdbc/oracle/adapter.rb', line 239

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

#native_database_typesObject



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

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?).



750
751
752
753
754
755
756
# File 'lib/arjdbc/oracle/adapter.rb', line 750

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:



709
710
711
712
713
714
715
716
717
718
719
720
# File 'lib/arjdbc/oracle/adapter.rb', line 709

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



783
784
785
786
# File 'lib/arjdbc/oracle/adapter.rb', line 783

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



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
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
# File 'lib/arjdbc/oracle/adapter.rb', line 603

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



580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
# File 'lib/arjdbc/oracle/adapter.rb', line 580

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



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

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



572
573
574
# File 'lib/arjdbc/oracle/adapter.rb', line 572

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.



656
657
658
659
660
661
662
663
# File 'lib/arjdbc/oracle/adapter.rb', line 656

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



368
369
370
# File 'lib/arjdbc/oracle/adapter.rb', line 368

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



460
461
462
# File 'lib/arjdbc/oracle/adapter.rb', line 460

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



452
453
454
455
# File 'lib/arjdbc/oracle/adapter.rb', line 452

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



286
287
288
289
290
291
292
293
294
295
# File 'lib/arjdbc/oracle/adapter.rb', line 286

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



696
697
698
699
700
701
# File 'lib/arjdbc/oracle/adapter.rb', line 696

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



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

def sequence_name_length; IDENTIFIER_LENGTH end

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



825
826
827
828
829
830
831
832
# File 'lib/arjdbc/oracle/adapter.rb', line 825

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)


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

def supports_explain?; true end

#supports_foreign_keys?Boolean

Returns:

  • (Boolean)


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

def supports_foreign_keys?; true end

#supports_migrations?Boolean

Returns:

  • (Boolean)


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

def supports_migrations?; true end

#supports_primary_key?Boolean

Returns:

  • (Boolean)


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

def supports_primary_key?; true end

#supports_savepoints?Boolean

Returns:

  • (Boolean)


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

def supports_savepoints?; true end

#supports_views?Boolean

Returns:

  • (Boolean)


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

def supports_views?; true end

#table_alias_lengthObject

maximum length of Oracle identifiers is 30



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

def table_alias_length; IDENTIFIER_LENGTH; end

#table_definition(*args) ⇒ Object



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

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

#table_name_lengthObject



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

def table_name_length;  IDENTIFIER_LENGTH; end

#tablesObject



540
541
542
# File 'lib/arjdbc/oracle/adapter.rb', line 540

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

#tablespace(table_name) ⇒ Object



549
550
551
# File 'lib/arjdbc/oracle/adapter.rb', line 549

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)


536
537
538
# File 'lib/arjdbc/oracle/adapter.rb', line 536

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



685
686
687
# File 'lib/arjdbc/oracle/adapter.rb', line 685

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



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/arjdbc/oracle/adapter.rb', line 308

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



597
598
599
600
# File 'lib/arjdbc/oracle/adapter.rb', line 597

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:



94
95
96
# File 'lib/arjdbc/oracle/adapter.rb', line 94

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

#use_insert_returning?Boolean

Returns:

  • (Boolean)


879
880
881
882
883
884
# File 'lib/arjdbc/oracle/adapter.rb', line 879

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