Class ActiveRecord::ConnectionAdapters::OCIAdapter
In: vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb
Parent: AbstractAdapter

This is an Oracle adapter for the ActiveRecord persistence framework. It relies upon the OCI8 driver (rubyforge.org/projects/ruby-oci8/), which works with Oracle 8i and above. It was developed on Windows 2000 against an 8i database, using ActiveRecord 1.6.0 and OCI8 0.1.9. It has also been tested against a 9i database.

Usage notes:

  • Key generation uses a sequence "rails_sequence" for all tables. (I couldn’t find a simple and safe way of passing table-specific sequence information to the adapter.)
  • Oracle uses DATE or TIMESTAMP datatypes for both dates and times. Consequently I have had to resort to some hacks to get data converted to Date or Time in Ruby. If the column_name ends in _time it’s created as a Ruby Time. Else if the hours/minutes/seconds are 0, I make it a Ruby Date. Else it’s a Ruby Time. This is nasty - but if you use Duck Typing you’ll probably not care very much. In 9i it’s tempting to map DATE to Date and TIMESTAMP to Time but I don’t think that is valid - too many databases use DATE for both. Timezones and sub-second precision on timestamps are not supported.
  • Default values that are functions (such as "SYSDATE") are not supported. This is a restriction of the way active record supports default values.
  • Referential integrity constraints are not fully supported. Under at least some circumstances, active record appears to delete parent and child records out of sequence and out of transaction scope. (Or this may just be a problem of test setup.)

Options:

  • :username — Defaults to root
  • :password — Defaults to nothing
  • :host — Defaults to localhost

Methods

Public Instance methods

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 202
202:         def adapter_name()
203:           'OCI'
204:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 182
182:         def add_limit!(sql, limit)
183:           sql << "LIMIT=" << limit.to_s
184:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 186
186:         def begin_db_transaction()
187:           @connection.autocommit = false
188:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 152
152:         def columns(table_name, name = nil)
153:           cols = select_all(%Q{
154:               select column_name, data_type, data_default, data_length, data_scale
155:               from user_tab_columns where table_name = '#{table_name.upcase}'}
156:           ).map { |row|
157:             OCIColumn.new row['column_name'].downcase, row['data_default'],
158:               row['data_length'], row['data_type'], row['data_scale']
159:           }
160:           cols
161:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 190
190:         def commit_db_transaction()
191:           @connection.commit
192:         ensure
193:           @connection.autocommit = true
194:         end
delete(sql, name = nil)

Alias for execute

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 175
175:         def execute(sql, name = nil)
176:           log(sql, name, @connection) { @connection.exec sql }
177:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 163
163:         def insert(sql, name = nil, pk = nil, id_value = nil)
164:           if pk.nil? # Who called us? What does the sql look like? No idea!
165:             execute sql, name
166:           elsif id_value # Pre-assigned id
167:             log(sql, name, @connection) { @connection.exec sql }
168:           else # Assume the sql contains a bind-variable for the id
169:             id_value = select_one("select rails_sequence.nextval id from dual")['id']
170:             log(sql, name, @connection) { @connection.exec sql, id_value }
171:           end
172:           id_value
173:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 106
106:         def quote(value, column = nil)
107:           if column and column.type == :binary then %Q{empty_#{ column.sql_type }()}
108:           else case value
109:             when String     then %Q{'#{quote_string(value)}'}
110:             when NilClass     then 'null'
111:             when TrueClass    then '1'
112:             when FalseClass   then '0'
113:             when Numeric    then value.to_s
114:             when Date, Time   then %Q{'#{value.strftime("%Y-%m-%d %H:%M:%S")}'}
115:             else           %Q{'#{quote_string(value.to_yaml)}'}
116:             end
117:           end
118:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 102
102:         def quote_string(s)
103:           s.gsub /'/, "''"
104:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 196
196:         def rollback_db_transaction()
197:           @connection.rollback
198:         ensure
199:           @connection.autocommit = true
200:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 120
120:         def select_all(sql, name = nil)
121:           offset = sql =~ /OFFSET (\d+)$/ ? $1.to_i : -1
122:           sql, limit = $1, $2.to_i if sql =~ /(.*)(?: LIMIT[= ](\d+))(\s*OFFSET \d+)?$/
123:           cursor = log(sql, name, @connection) { @connection.exec sql }
124:           cols = cursor.get_col_names.map { |x| x.downcase }
125:           rows = []
126:           while row = cursor.fetch
127:             next if cursor.row_count <= offset
128:             hash = Hash.new
129:             cols.each_with_index { |col, i|
130:               hash[col] = case row[i]
131:                 when OCI8::LOB
132:                   name == 'Writable Large Object' ? row[i]: row[i].read
133:                 when OraDate
134:                   (row[i].hour == 0 and row[i].minute == 0 and row[i].second == 0) ?
135:                     row[i].to_date : row[i].to_time
136:                 else row[i]
137:                 end
138:             }
139:             rows << hash
140:             break if rows.size == limit
141:           end
142:           rows
143:         ensure
144:           cursor.close if cursor
145:         end

[Source]

     # File vendor/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 147
147:         def select_one(sql, name = nil)
148:           result = select_all sql, name
149:           result.size > 0 ? result.first : nil
150:         end
update(sql, name = nil)

Alias for execute

[Validate]