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

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

Private Instance Methods

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