Class ActiveRecord::ConnectionAdapters::OCIAdapter
In: vendor/rails/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/rails/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 201
201:         def adapter_name()
202:           'OCI'
203:         end

[Source]

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

[Source]

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

[Source]

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

Alias for execute

[Source]

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

[Source]

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

[Source]

     # File vendor/rails/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/rails/activerecord/lib/active_record/connection_adapters/oci_adapter.rb, line 102
102:         def quote_string(string)
103:           string.gsub(/'/, "''")
104:         end

[Source]

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

[Source]

     # File vendor/rails/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 : 0
122:           sql, limit = $1, $2.to_i if sql =~ /(.*)(?: LIMIT[= ](\d+))(\s*OFFSET \d+)?$/
123:           if limit
124:             sql = "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_ where rownum <= #{offset+limit}) where raw_rnum_ > #{offset}"
125:           elsif offset > 0
126:             sql = "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_) where raw_rnum_ > #{offset}"
127:           end
128:           cursor = log(sql, name) { @connection.exec sql }
129:           cols = cursor.get_col_names.map { |x| x.downcase }
130:           rows = []
131:           while row = cursor.fetch
132:             hash = Hash.new
133:             cols.each_with_index { |col, i|
134:               hash[col] = case row[i]
135:                 when OCI8::LOB
136:                   name == 'Writable Large Object' ? row[i]: row[i].read
137:                 when OraDate
138:                   (row[i].hour == 0 and row[i].minute == 0 and row[i].second == 0) ?
139:                     row[i].to_date : row[i].to_time
140:                 else row[i]
141:                 end unless col == 'raw_rnum_'
142:             }
143:             rows << hash
144:           end
145:           rows
146:         ensure
147:           cursor.close if cursor
148:         end

[Source]

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

Alias for execute

[Validate]