Module: ActiveRecord::ConnectionAdapters::OracleEnhanced::DatabaseStatements

Included in:
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
Defined in:
lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb

Instance Method Summary collapse

Instance Method Details

#begin_db_transactionObject

:nodoc:



186
187
188
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 186

def begin_db_transaction #:nodoc:
  @connection.autocommit = false
end

#begin_isolated_db_transaction(isolation) ⇒ Object



200
201
202
203
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 200

def begin_isolated_db_transaction(isolation)
  begin_db_transaction
  execute "SET TRANSACTION ISOLATION LEVEL  #{transaction_isolation_levels.fetch(isolation)}"
end

#clear_cache!Object



14
15
16
17
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 14

def clear_cache!
  @statements.clear
  reload_type_map
end

#commit_db_transactionObject

:nodoc:



205
206
207
208
209
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 205

def commit_db_transaction #:nodoc:
  @connection.commit
ensure
  @connection.autocommit = true
end

#create_savepoint(name = current_savepoint_name) ⇒ Object

:nodoc:



217
218
219
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 217

def create_savepoint(name = current_savepoint_name) #:nodoc:
  execute("SAVEPOINT #{name}")
end

#default_sequence_name(table_name, primary_key = nil) ⇒ Object

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



231
232
233
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 231

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

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

New method in ActiveRecord 3.1



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 117

def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
  type_casted_binds = binds.map { |col, val|
    [col, type_cast(val, col)]
  }
  log(sql, name, type_casted_binds) do
    returning_id_col = returning_id_index = nil
    if without_prepared_statement?(binds)
      cursor = @connection.prepare(sql)
    else
      unless @statements.key?(sql)
        @statements[sql] = @connection.prepare(sql)
      end

      cursor = @statements[sql]

      type_casted_binds.each_with_index do |bind, i|
        col, val = bind
        if col.returning_id?
          returning_id_col = [col]
          returning_id_index = i + 1
          cursor.bind_returning_param(returning_id_index, Integer)
        else
          cursor.bind_param(i + 1, val, col)
        end
      end
    end

    cursor.exec_update

    rows = []
    if returning_id_index
      returning_id = cursor.get_returning_param(returning_id_index, Integer)
      rows << [returning_id]
    end
    ActiveRecord::Result.new(returning_id_col || [], rows)
  end
end

#exec_query(sql, name = 'SQL', binds = []) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 19

def exec_query(sql, name = 'SQL', binds = [])
  type_casted_binds = binds.map { |col, val|
    [col, type_cast(val, col)]
  }
  log(sql, name, type_casted_binds) do
    cursor = nil
    cached = false
    if without_prepared_statement?(binds)
      cursor = @connection.prepare(sql)
    else
      unless @statements.key? sql
        @statements[sql] = @connection.prepare(sql)
      end

      cursor = @statements[sql]

      type_casted_binds.each_with_index do |bind, i|
        col, val = bind
        cursor.bind_param(i + 1, val, col)
      end

      cached = true
    end

    cursor.exec

    if name == 'EXPLAIN' and sql =~ /^EXPLAIN/
      res = true
    else
      columns = cursor.get_col_names.map do |col_name|
        @connection.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 = ActiveRecord::Result.new(columns, rows)
    end

    cursor.close unless cached
    res
  end
end

#exec_rollback_db_transactionObject

:nodoc:



211
212
213
214
215
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 211

def exec_rollback_db_transaction #:nodoc:
  @connection.rollback
ensure
  @connection.autocommit = true
end

#exec_rollback_to_savepoint(name = current_savepoint_name) ⇒ Object

:nodoc:



221
222
223
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 221

def exec_rollback_to_savepoint(name = current_savepoint_name) #:nodoc:
  execute("ROLLBACK TO #{name}")
end

#exec_update(sql, name, binds) ⇒ Object Also known as: exec_delete

New method in ActiveRecord 3.1



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 156

def exec_update(sql, name, binds)
  type_casted_binds = binds.map { |col, val|
    [col, type_cast(val, col)]
  }
  log(sql, name, type_casted_binds) do
    cached = false
    if without_prepared_statement?(binds)
      cursor = @connection.prepare(sql)
    else
      cursor = if @statements.key?(sql)
        @statements[sql]
      else
        @statements[sql] = @connection.prepare(sql)
      end

      type_casted_binds.each_with_index do |bind, i|
        col, val = bind
        cursor.bind_param(i + 1, val, col)
      end
      cached = true
    end

    res = cursor.exec_update
    cursor.close unless cached
    res
  end
end

#execute(sql, name = nil) ⇒ Object

Executes a SQL statement



10
11
12
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 10

def execute(sql, name = nil)
  log(sql, name) { @connection.exec(sql) }
end

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



72
73
74
75
76
77
78
79
80
81
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 72

def explain(arel, binds = [])
  sql = "EXPLAIN PLAN FOR #{to_sql(arel, binds)}"
  return if sql =~ /FROM all_/
  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_fixture(fixture, table_name) ⇒ Object

Inserts the given fixture into the table. Overridden to properly handle lobs.



236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 236

def insert_fixture(fixture, table_name) #:nodoc:
  super

  if ActiveRecord::Base.pluralize_table_names
    klass = table_name.to_s.singularize.camelize
  else
    klass = table_name.to_s.camelize
  end

  klass = klass.constantize rescue nil
  if klass.respond_to?(:ancestors) && klass.ancestors.include?(ActiveRecord::Base)
    write_lobs(table_name, klass, fixture, klass.lob_columns)
  end
end

#release_savepoint(name = current_savepoint_name) ⇒ Object

:nodoc:



225
226
227
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 225

def release_savepoint(name = current_savepoint_name) #:nodoc:
  # there is no RELEASE SAVEPOINT statement in Oracle
end

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

Returns an array of arrays containing the field values. Order is the same as that returned by #columns.



85
86
87
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 85

def select_rows(sql, name = nil, binds = [])
  exec_query(sql, name, binds).rows
end

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

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



107
108
109
110
111
112
113
114
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 107

def sql_for_insert(sql, pk, id_value, sequence_name, binds)
  unless id_value || pk.nil? || (defined?(CompositePrimaryKeys) && pk.kind_of?(CompositePrimaryKeys::CompositeKeys))
    sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO :returning_id"
    returning_id_col = new_column("returning_id", nil, Type::Value.new, "number", true, "dual", true, true)
    (binds = binds.dup) << [returning_id_col, nil]
  end
  [sql, binds]
end

#supports_explain?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 68

def supports_explain?
  true
end

#supports_statement_cache?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 64

def supports_statement_cache?
  true
end

#transaction_isolation_levelsObject



190
191
192
193
194
195
196
197
198
# File 'lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb', line 190

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