module ActiveRecord::ConnectionAdapters::OracleEnhanced::DatabaseStatements

Public Instance Methods

begin_isolated_db_transaction(isolation) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 180
def begin_isolated_db_transaction(isolation)
  begin_db_transaction
  execute "SET TRANSACTION ISOLATION LEVEL  #{transaction_isolation_levels.fetch(isolation)}"
end
default_sequence_name(table_name, primary_key = nil) click to toggle source

Returns default sequence name for table. Will take all or first 26 characters of table name and append _seq suffix

# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 211
def default_sequence_name(table_name, primary_key = nil)
  table_name.to_s.gsub((/(^|\.)([\w$-]{1,#{sequence_name_length - 4}})([\w$-]*)$/), '\1\2_seq')
end
empty_insert_statement_value() click to toggle source

Oracle Database does not support this feature Refer community.oracle.com/ideas/13845 and consider to vote if you need this feature.

# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 246
def empty_insert_statement_value
  raise NotImplementedError
end
exec_delete(sql, name = nil, binds = [])
Alias for: exec_update
exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil) click to toggle source

New method in ActiveRecord 3.1

# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 94
def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
  sql, binds = sql_for_insert(sql, pk, binds)
  type_casted_binds = type_casted_binds(binds)

  log(sql, name, binds, type_casted_binds) do
    cached = false
    cursor = nil
    returning_id_col = returning_id_index = nil
    with_retry do
      if without_prepared_statement?(binds)
        cursor = @connection.prepare(sql)
      else
        unless @statements.key?(sql)
          @statements[sql] = @connection.prepare(sql)
        end

        cursor = @statements[sql]

        cursor.bind_params(type_casted_binds)

        if /:returning_id/.match?(sql)
          # it currently expects that returning_id comes last part of binds
          returning_id_index = binds.size
          cursor.bind_returning_param(returning_id_index, Integer)
        end

        cached = true
      end

      cursor.exec_update
    end

    rows = []
    if returning_id_index
      returning_id = cursor.get_returning_param(returning_id_index, Integer).to_i
      rows << [returning_id]
    end
    cursor.close unless cached
    build_result(columns: returning_id_col || [], rows: rows)
  end
end
exec_query(sql, name = "SQL", binds = [], prepare: false, async: false) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 18
def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)
  sql = transform_query(sql)

  type_casted_binds = type_casted_binds(binds)

  log(sql, name, binds, type_casted_binds, async: async) do
    cursor = nil
    cached = false
    with_retry do
      if without_prepared_statement?(binds)
        cursor = @connection.prepare(sql)
      else
        unless @statements.key? sql
          @statements[sql] = @connection.prepare(sql)
        end

        cursor = @statements[sql]

        cursor.bind_params(type_casted_binds)

        cached = true
      end

      cursor.exec
    end

    if (name == "EXPLAIN") && sql.start_with?("EXPLAIN")
      res = true
    else
      columns = cursor.get_col_names.map do |col_name|
        oracle_downcase(col_name)
      end
      rows = []
      fetch_options = { get_lob_value: (name != "Writable Large Object") }
      while row = cursor.fetch(fetch_options)
        rows << row
      end
      res = build_result(columns: columns, rows: rows)
    end

    cursor.close unless cached
    res
  end
end
exec_update(sql, name = nil, binds = []) click to toggle source

New method in ActiveRecord 3.1

# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 137
def exec_update(sql, name = nil, binds = [])
  type_casted_binds = type_casted_binds(binds)

  log(sql, name, binds, type_casted_binds) do
    with_retry do
      cached = false
      if without_prepared_statement?(binds)
        cursor = @connection.prepare(sql)
      else
        if @statements.key?(sql)
          cursor = @statements[sql]
        else
          cursor = @statements[sql] = @connection.prepare(sql)
        end

        cursor.bind_params(type_casted_binds)

        cached = true
      end

      res = cursor.exec_update
      cursor.close unless cached
      res
    end
  end
end
Also aliased as: exec_delete
execute(sql, name = nil, async: false) click to toggle source

Executes a SQL statement

# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 12
def execute(sql, name = nil, async: false)
  sql = transform_query(sql)

  log(sql, name, async: async) { @connection.exec(sql) }
end
explain(arel, binds = []) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 67
def explain(arel, binds = [])
  sql = "EXPLAIN PLAN FOR #{to_sql(arel, binds)}"
  return if /FROM all_/.match?(sql)
  if ORACLE_ENHANCED_CONNECTION == :jdbc
    exec_query(sql, "EXPLAIN", binds)
  else
    exec_query(sql, "EXPLAIN")
  end
  select_values("SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)", "EXPLAIN").join("\n")
end
insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) click to toggle source
Calls superclass method
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 88
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
  pk = nil if id_value
  super
end
insert_fixtures_set(fixture_set, tables_to_delete = []) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 231
def insert_fixtures_set(fixture_set, tables_to_delete = [])
  disable_referential_integrity do
    transaction(requires_new: true) do
      tables_to_delete.each { |table| delete "DELETE FROM #{quote_table_name(table)}", "Fixture Delete" }

      fixture_set.each do |table_name, rows|
        rows.each { |row| insert_fixture(row, table_name) }
      end
    end
  end
end
sql_for_insert(sql, pk, binds) click to toggle source

New method in ActiveRecord 3.1 Will add RETURNING clause in case of trigger generated primary keys

Calls superclass method
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 80
def sql_for_insert(sql, pk, binds)
  unless pk == false || pk.nil? || pk.is_a?(Array) || pk.is_a?(String)
    sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO :returning_id"
    (binds = binds.dup) << ActiveRecord::Relation::QueryAttribute.new("returning_id", nil, Type::OracleEnhanced::Integer.new)
  end
  super
end
supports_explain?() click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 63
def supports_explain?
  true
end
transaction_isolation_levels() click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 170
def transaction_isolation_levels
  # Oracle database supports `READ COMMITTED` and `SERIALIZABLE`
  # No read uncommitted nor repeatable read supppoted
  # http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_10005.htm#SQLRF55422
  {
    read_committed:   "READ COMMITTED",
    serializable:     "SERIALIZABLE"
  }
end

Private Instance Methods

with_retry() { || ... } click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb, line 274
def with_retry
  @connection.with_retry do
    yield
  rescue
    @statements.clear
    raise
  end
end