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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.arel_visitor_type(config = nil) ⇒ Object



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

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.



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

def self.emulate_booleans; @@emulate_booleans; end

.emulate_booleans=(emulate) ⇒ Object

See Also:

  • #emulate_booleans?


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

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


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

def self.emulate_booleans?; @@emulate_booleans; end

.jdbc_connection_classObject



29
30
31
# File 'lib/arjdbc/oracle/adapter.rb', line 29

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

.update_lob_values=(update) ⇒ Object

See Also:

  • #update_lob_values?


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

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)


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

def self.update_lob_values?; @@update_lob_values; end

Instance Method Details

#adapter_nameObject



99
100
101
# File 'lib/arjdbc/oracle/adapter.rb', line 99

def adapter_name
  ADAPTER_NAME
end

#add_column_options!(sql, options) ⇒ Object



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

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


215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/arjdbc/oracle/adapter.rb', line 215

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.



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

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



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

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



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

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



377
378
379
# File 'lib/arjdbc/oracle/adapter.rb', line 377

def charset
  database_parameters['NLS_CHARACTERSET']
end

#collationObject



381
382
383
# File 'lib/arjdbc/oracle/adapter.rb', line 381

def collation
  database_parameters['NLS_COMP']
end

#column_name_lengthObject



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

def column_name_length; IDENTIFIER_LENGTH; end

#columns(table_name, name = nil) ⇒ Object

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



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

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

#columns_for_distinct(columns, orders) ⇒ Object



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/arjdbc/oracle/adapter.rb', line 322

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



152
153
154
155
156
157
158
159
160
# File 'lib/arjdbc/oracle/adapter.rb', line 152

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

#current_databaseObject



232
233
234
# File 'lib/arjdbc/oracle/adapter.rb', line 232

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

#current_schemaObject



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

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

#current_schema=(schema_owner) ⇒ Object



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

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

#current_userObject



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

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

#database_parametersObject



385
386
387
388
389
390
391
# File 'lib/arjdbc/oracle/adapter.rb', line 385

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

#default_sequence_name(table_name, column = nil) ⇒ Object



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

def default_sequence_name(table_name, column = nil)
  # TODO: remove schema prefix if present (before truncating)
  "#{table_name.to_s[0, IDENTIFIER_LENGTH - 4]}_seq"
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")



317
318
319
# File 'lib/arjdbc/oracle/adapter.rb', line 317

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

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



175
176
177
178
179
180
181
182
# File 'lib/arjdbc/oracle/adapter.rb', line 175

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 "DROP SEQUENCE #{quote_table_name(seq_name)}" rescue nil
end

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



580
581
582
583
584
585
586
587
# File 'lib/arjdbc/oracle/adapter.rb', line 580

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



589
590
591
592
593
594
595
596
# File 'lib/arjdbc/oracle/adapter.rb', line 589

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



507
508
509
510
511
512
# File 'lib/arjdbc/oracle/adapter.rb', line 507

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



133
134
135
# File 'lib/arjdbc/oracle/adapter.rb', line 133

def in_clause_length
  1000
end

#index_name_lengthObject



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

def index_name_length;  IDENTIFIER_LENGTH; end

#indexes(table, name = nil) ⇒ Object



209
210
211
# File 'lib/arjdbc/oracle/adapter.rb', line 209

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

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



566
567
568
569
570
571
572
573
574
575
576
577
# File 'lib/arjdbc/oracle/adapter.rb', line 566

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)



539
540
541
542
543
544
545
546
547
548
549
550
551
552
# File 'lib/arjdbc/oracle/adapter.rb', line 539

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



34
35
36
# File 'lib/arjdbc/oracle/adapter.rb', line 34

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

#modify_types(types) ⇒ Object



124
125
126
127
128
129
130
# File 'lib/arjdbc/oracle/adapter.rb', line 124

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

#native_database_typesObject



120
121
122
# File 'lib/arjdbc/oracle/adapter.rb', line 120

def native_database_types
  super.merge(NATIVE_DATABASE_TYPES)
end

#next_sequence_value(sequence_name) ⇒ Object



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

def next_sequence_value(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:



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

def prefetch_primary_key?(table_name = nil)
  return true if table_name.nil?
  table_name = table_name.to_s
  columns(table_name).count { |column| column.primary } == 1
end

#quote(value, column = nil) ⇒ Object



420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# File 'lib/arjdbc/oracle/adapter.rb', line 420

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) ⇒ Object



401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/arjdbc/oracle/adapter.rb', line 401

def quote_column_name(name)
  # if only valid lowercase column characters in name
  if ( name = name.to_s ) =~ /\A[a-z][a-z_0-9\$#]*\Z/
    # 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
    # remove double quotes which cannot be used inside quoted identifier
    "\"#{name.gsub('"', '')}\""
  end
end

#quote_raw(value) ⇒ Object



482
483
484
485
# File 'lib/arjdbc/oracle/adapter.rb', line 482

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



396
397
398
# File 'lib/arjdbc/oracle/adapter.rb', line 396

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.



473
474
475
476
477
478
479
480
# File 'lib/arjdbc/oracle/adapter.rb', line 473

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



245
246
247
# File 'lib/arjdbc/oracle/adapter.rb', line 245

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



284
285
286
# File 'lib/arjdbc/oracle/adapter.rb', line 284

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

#remove_index(table_name, options = {}) ⇒ Object



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

def remove_index(table_name, options = {})
  execute "DROP INDEX #{index_name(table_name, options)}"
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object



276
277
278
279
# File 'lib/arjdbc/oracle/adapter.rb', line 276

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



163
164
165
166
167
168
169
170
171
172
# File 'lib/arjdbc/oracle/adapter.rb', line 163

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



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

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

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



556
557
558
559
560
561
562
563
# File 'lib/arjdbc/oracle/adapter.rb', line 556

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)


503
504
505
# File 'lib/arjdbc/oracle/adapter.rb', line 503

def supports_explain?
  true
end

#supports_migrations?Boolean

Returns:

  • (Boolean)


488
489
490
# File 'lib/arjdbc/oracle/adapter.rb', line 488

def supports_migrations?
  true
end

#supports_primary_key?Boolean

Returns:

  • (Boolean)


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

def supports_primary_key?
  true
end

#supports_savepoints?Boolean

Returns:

  • (Boolean)


498
499
500
# File 'lib/arjdbc/oracle/adapter.rb', line 498

def supports_savepoints?
  true
end

#table_alias_lengthObject

maximum length of Oracle identifiers is 30



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

def table_alias_length; IDENTIFIER_LENGTH; end

#table_definition(*args) ⇒ Object



83
84
85
# File 'lib/arjdbc/oracle/adapter.rb', line 83

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

#table_name_lengthObject



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

def table_name_length;  IDENTIFIER_LENGTH; end

#tablesObject



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

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

#tablespace(table_name) ⇒ Object



373
374
375
# File 'lib/arjdbc/oracle/adapter.rb', line 373

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)


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

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

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



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/arjdbc/oracle/adapter.rb', line 185

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



414
415
416
417
# File 'lib/arjdbc/oracle/adapter.rb', line 414

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:



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

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

#use_insert_returning?Boolean

Returns:

  • (Boolean)


610
611
612
613
614
615
# File 'lib/arjdbc/oracle/adapter.rb', line 610

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