class Sequel::Oracle::Database

Constants

CONNECTION_ERROR_CODES

ORA-00028: your session has been killed ORA-01012: not logged on ORA-02396: exceeded maximum idle time, please connect again ORA-03113: end-of-file on communication channel ORA-03114: not connected to ORACLE ORA-03135: connection lost contact

ORACLE_TYPES
PS_TYPES

Attributes

conversion_procs[R]

Hash of conversion procs for this database.

Public Instance Methods

connect(server) click to toggle source
   # File lib/sequel/adapters/oracle.rb
28 def connect(server)
29   opts = server_opts(server)
30   if opts[:database]
31     dbname = opts[:host] ? \
32       "//#{opts[:host]}#{":#{opts[:port]}" if opts[:port]}/#{opts[:database]}" : opts[:database]
33   else
34     dbname = opts[:host]
35   end
36   conn = OCI8.new(opts[:user], opts[:password], dbname, opts[:privilege])
37   if prefetch_rows = opts.fetch(:prefetch_rows, 100)
38     conn.prefetch_rows = typecast_value_integer(prefetch_rows)
39   end
40   conn.autocommit = true
41   conn.non_blocking = true
42   
43   # The ruby-oci8 gem which retrieves oracle columns with a type of
44   # DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE is complex based on the
45   # ruby version and Oracle version (9 or later)
46   # In the now standard case of Oracle 9 or later, the timezone
47   # is determined by the Oracle session timezone. Thus if the user
48   # requests Sequel provide UTC timezone to the application,
49   # we need to alter the session timezone to be UTC
50   if Sequel.application_timezone == :utc
51     conn.exec("ALTER SESSION SET TIME_ZONE='-00:00'")
52   end
53   
54   class << conn
55     attr_reader :prepared_statements
56   end
57   conn.instance_variable_set(:@prepared_statements, {})
58   
59   conn
60 end
disconnect_connection(c) click to toggle source
   # File lib/sequel/adapters/oracle.rb
62 def disconnect_connection(c)
63   c.logoff
64 rescue OCIException
65   nil
66 end
execute(sql, opts=OPTS, &block) click to toggle source
   # File lib/sequel/adapters/oracle.rb
68 def execute(sql, opts=OPTS, &block)
69   _execute(nil, sql, opts, &block)
70 end
execute_insert(sql, opts=OPTS) click to toggle source
   # File lib/sequel/adapters/oracle.rb
72 def execute_insert(sql, opts=OPTS)
73   _execute(:insert, sql, opts)
74 end
freeze() click to toggle source
Calls superclass method Sequel::Oracle::DatabaseMethods#freeze
   # File lib/sequel/adapters/oracle.rb
76 def freeze
77   @conversion_procs.freeze
78   super
79 end

Private Instance Methods

_execute(type, sql, opts=OPTS) { || ... } click to toggle source
    # File lib/sequel/adapters/oracle.rb
 83 def _execute(type, sql, opts=OPTS, &block)
 84   synchronize(opts[:server]) do |conn|
 85     begin
 86       return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol)
 87       if args = opts[:arguments]
 88         r = conn.parse(sql)
 89         args = cursor_bind_params(conn, r, args)
 90         nr = log_connection_yield(sql, conn, args){r.exec}
 91         r = nr unless defined?(yield)
 92       else
 93         r = log_connection_yield(sql, conn){conn.exec(sql)}
 94       end
 95       if defined?(yield)
 96         yield(r)
 97       elsif type == :insert
 98         last_insert_id(conn, opts)
 99       else
100         r
101       end
102     rescue OCIException, RuntimeError => e
103       # ruby-oci8 is naughty and raises strings in some places
104       raise_error(e)
105     ensure
106       r.close if r.is_a?(::OCI8::Cursor)
107     end
108   end
109 end
adapter_initialize() click to toggle source
    # File lib/sequel/adapters/oracle.rb
111 def adapter_initialize
112   @autosequence = @opts[:autosequence]
113   @primary_key_sequences = {}
114   @conversion_procs = ORACLE_TYPES.dup
115 end
begin_transaction(conn, opts=OPTS) click to toggle source
    # File lib/sequel/adapters/oracle.rb
224 def begin_transaction(conn, opts=OPTS)
225   log_connection_yield('Transaction.begin', conn){conn.autocommit = false}
226   set_transaction_isolation(conn, opts)
227 end
commit_transaction(conn, opts=OPTS) click to toggle source
    # File lib/sequel/adapters/oracle.rb
229 def commit_transaction(conn, opts=OPTS)
230   log_connection_yield('Transaction.commit', conn){conn.commit}
231 end
connection_execute_method() click to toggle source
    # File lib/sequel/adapters/oracle.rb
143 def connection_execute_method
144   :exec
145 end
cursor_bind_params(conn, cursor, args) click to toggle source
    # File lib/sequel/adapters/oracle.rb
120 def cursor_bind_params(conn, cursor, args)
121   i = 0
122   args.map do |arg, type|
123     i += 1
124     case arg
125     when true
126       arg = 'Y'
127     when false
128       arg = 'N'
129     when BigDecimal
130       arg = arg.to_f
131     when ::Sequel::SQL::Blob
132       arg = ::OCI8::BLOB.new(conn, arg)
133     when String
134       if type == 'clob'
135         arg = ::OCI8::CLOB.new(conn, arg)
136       end
137     end
138     cursor.bind_param(i, arg, PS_TYPES[type] || arg.class)
139     arg
140   end
141 end
database_error_classes() click to toggle source
    # File lib/sequel/adapters/oracle.rb
147 def database_error_classes
148   [OCIException, RuntimeError]
149 end
database_specific_error_class(exception, opts) click to toggle source
    # File lib/sequel/adapters/oracle.rb
151 def database_specific_error_class(exception, opts)
152   return super unless exception.respond_to?(:code)
153   case exception.code
154   when 1400, 1407
155     NotNullConstraintViolation
156   when 1
157     UniqueConstraintViolation
158   when 2291, 2292
159     ForeignKeyConstraintViolation
160   when 2290
161     CheckConstraintViolation
162   when 8177
163     SerializationFailure
164   else
165     super
166   end
167 end
dataset_class_default() click to toggle source
    # File lib/sequel/adapters/oracle.rb
169 def dataset_class_default
170   Dataset
171 end
disconnect_error?(e, opts) click to toggle source
Calls superclass method Sequel::Database#disconnect_error?
    # File lib/sequel/adapters/oracle.rb
233 def disconnect_error?(e, opts)
234   super || (e.is_a?(::OCIError) && CONNECTION_ERROR_CODES.include?(e.code))
235 end
execute_prepared_statement(conn, type, name, opts) { || ... } click to toggle source
    # File lib/sequel/adapters/oracle.rb
173 def execute_prepared_statement(conn, type, name, opts)
174   ps = prepared_statement(name)
175   sql = ps.prepared_sql
176   if cursora = conn.prepared_statements[name]
177     cursor, cursor_sql = cursora
178     if cursor_sql != sql
179       cursor.close
180       cursor = nil
181     end
182   end
183   unless cursor
184     cursor = log_connection_yield("PREPARE #{name}: #{sql}", conn){conn.parse(sql)}
185     conn.prepared_statements[name] = [cursor, sql]
186   end
187   args = cursor_bind_params(conn, cursor, opts[:arguments])
188   log_sql = "EXECUTE #{name}"
189   if ps.log_sql
190     log_sql += " ("
191     log_sql << sql
192     log_sql << ")"
193   end
194   r = log_connection_yield(log_sql, conn, args){cursor.exec}
195   if defined?(yield)
196     yield(cursor)
197   elsif type == :insert
198     last_insert_id(conn, opts)
199   else
200     r
201   end
202 end
last_insert_id(conn, opts) click to toggle source
    # File lib/sequel/adapters/oracle.rb
204 def last_insert_id(conn, opts)
205   unless sequence = opts[:sequence]
206     if t = opts[:table]
207       sequence = sequence_for_table(t)
208     end
209   end
210   if sequence
211     sql = "SELECT #{literal(sequence)}.currval FROM dual"
212     begin
213       cursor = log_connection_yield(sql, conn){conn.exec(sql)}
214       row = cursor.fetch
215       row.each{|v| return (v.to_i if v)}
216     rescue OCIError
217       nil
218     ensure
219       cursor.close if cursor
220     end
221   end
222 end
oracle_column_type(h) click to toggle source
    # File lib/sequel/adapters/oracle.rb
237 def oracle_column_type(h)
238   case h[:oci8_type]
239   when :number
240     case h[:scale]
241     when 0
242       :integer
243     when -127
244       :float
245     else
246       :decimal
247     end
248   when :date
249     :datetime
250   else
251     schema_column_type(h[:db_type])
252   end
253 end
remove_transaction(conn, committed) click to toggle source
Calls superclass method Sequel::Database#remove_transaction
    # File lib/sequel/adapters/oracle.rb
255 def remove_transaction(conn, committed)
256   conn.autocommit = true
257 ensure
258   super
259 end
rollback_transaction(conn, opts=OPTS) click to toggle source
    # File lib/sequel/adapters/oracle.rb
261 def rollback_transaction(conn, opts=OPTS)
262   log_connection_yield('Transaction.rollback', conn){conn.rollback}
263 end
schema_parse_table(table, opts=OPTS) click to toggle source
    # File lib/sequel/adapters/oracle.rb
265 def schema_parse_table(table, opts=OPTS)
266   schema, table = schema_and_table(table)
267   schema ||= opts[:schema]
268   schema_and_table = if ds = opts[:dataset]
269     ds.literal(schema ? SQL::QualifiedIdentifier.new(schema, table) : SQL::Identifier.new(table))
270   else
271     "#{"#{quote_identifier(schema)}." if schema}#{quote_identifier(table)}"
272   end
273   table_schema = []
274   m = output_identifier_meth(ds)
275   im = input_identifier_meth(ds)
276 
277   # Primary Keys
278   ds = metadata_dataset.
279     from{[all_constraints.as(:cons), all_cons_columns.as(:cols)]}.
280     where{{
281      cols[:table_name]=>im.call(table),
282      cons[:constraint_type]=>'P',
283      cons[:constraint_name]=>cols[:constraint_name],
284      cons[:owner]=>cols[:owner]}}
285   ds = ds.where{{cons[:owner]=>im.call(schema)}} if schema
286   pks = ds.select_map{cols[:column_name]}
287 
288   # Default values
289   defaults = begin
290     metadata_dataset.from(:all_tab_cols).
291       where(:table_name=>im.call(table)).
292       as_hash(:column_name, :data_default)
293   rescue DatabaseError
294     {}
295   end
296 
297   metadata = synchronize(opts[:server]) do |conn|
298     begin
299       log_connection_yield("Connection.describe_table", conn){conn.describe_table(schema_and_table)}
300     rescue OCIError => e
301       raise_error(e)
302     end
303   end
304   metadata.columns.each do |column|
305     h = {
306         :primary_key => pks.include?(column.name),
307         :default => defaults[column.name],
308         :oci8_type => column.data_type,
309         :db_type => column.type_string,
310         :type_string => column.type_string,
311         :charset_form => column.charset_form,
312         :char_used => column.char_used?,
313         :char_size => column.char_size,
314         :data_size => column.data_size,
315         :column_size => column.precision,
316         :precision => column.precision,
317         :scale => column.scale,
318         :fsprecision => column.fsprecision,
319         :lfprecision => column.lfprecision,
320         :allow_null => column.nullable?
321     }
322     h[:type] = oracle_column_type(h)
323     h[:auto_increment] = h[:type] == :integer if h[:primary_key]
324     h[:max_length] = h[:char_size] if h[:type] == :string
325     table_schema << [m.call(column.name), h]
326   end
327   table_schema
328 end