class Sequel::Oracle::Database
Constants
- CONNECTION_ERROR_CODES
ORA-00028: your session has been killed ORA-01012: not logged on ORA-03113: end-of-file on communication channel ORA-03114: not connected to ORACLE
- DatasetClass
- 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, line 24 def connect(server) opts = server_opts(server) if opts[:database] dbname = opts[:host] ? "//#{opts[:host]}#{":#{opts[:port]}" if opts[:port]}/#{opts[:database]}" : opts[:database] else dbname = opts[:host] end conn = OCI8.new(opts[:user], opts[:password], dbname, opts[:privilege]) if prefetch_rows = opts.fetch(:prefetch_rows, 100) conn.prefetch_rows = typecast_value_integer(prefetch_rows) end conn.autocommit = true conn.non_blocking = true # The ruby-oci8 gem which retrieves oracle columns with a type of # DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE is complex based on the # ruby version (1.9.2 or later) and Oracle version (9 or later) # In the now standard case of 1.9.2 and Oracle 9 or later, the timezone # is determined by the Oracle session timezone. Thus if the user # requests Sequel provide UTC timezone to the application, # we need to alter the session timezone to be UTC if Sequel.application_timezone == :utc conn.exec("ALTER SESSION SET TIME_ZONE='-00:00'") end class << conn attr_reader :prepared_statements end conn.instance_variable_set(:@prepared_statements, {}) conn end
disconnect_connection(c)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 58 def disconnect_connection(c) c.logoff rescue OCIInvalidHandle nil end
execute(sql, opts=OPTS, &block)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 64 def execute(sql, opts=OPTS, &block) _execute(nil, sql, opts, &block) end
execute_insert(sql, opts=OPTS)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 68 def execute_insert(sql, opts=OPTS) _execute(:insert, sql, opts) end
Private Instance Methods
_execute(type, sql, opts=OPTS) { |r| ... }
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 74 def _execute(type, sql, opts=OPTS, &block) synchronize(opts[:server]) do |conn| begin return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol) if args = opts[:arguments] r = conn.parse(sql) args = cursor_bind_params(conn, r, args) nr = log_yield(sql, args){r.exec} r = nr unless block_given? else r = log_yield(sql){conn.exec(sql)} end if block_given? begin yield(r) ensure r.close end elsif type == :insert last_insert_id(conn, opts) else r end rescue OCIException, RuntimeError => e # ruby-oci8 is naughty and raises strings in some places raise_error(e) end end end
adapter_initialize()
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 104 def adapter_initialize @autosequence = @opts[:autosequence] @primary_key_sequences = {} @conversion_procs = ORACLE_TYPES.dup end
begin_transaction(conn, opts=OPTS)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 213 def begin_transaction(conn, opts=OPTS) log_yield(TRANSACTION_BEGIN){conn.autocommit = false} set_transaction_isolation(conn, opts) end
commit_transaction(conn, opts=OPTS)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 218 def commit_transaction(conn, opts=OPTS) log_yield(TRANSACTION_COMMIT){conn.commit} end
connection_execute_method()
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 136 def connection_execute_method :exec end
cursor_bind_params(conn, cursor, args)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 113 def cursor_bind_params(conn, cursor, args) i = 0 args.map do |arg, type| i += 1 case arg when true arg = 'Y' when false arg = 'N' when BigDecimal arg = arg.to_f when ::Sequel::SQL::Blob raise Error, "Sequel's oracle adapter does not currently support using a blob in a bound variable" end if t = PS_TYPES[type] cursor.bind_param(i, arg, t) else cursor.bind_param(i, arg, arg.class) end arg end end
database_error_classes()
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 140 def database_error_classes [OCIException, RuntimeError] end
database_specific_error_class(exception, opts)
click to toggle source
Calls superclass method
Sequel::Database#database_specific_error_class
# File lib/sequel/adapters/oracle.rb, line 144 def database_specific_error_class(exception, opts) return super unless exception.respond_to?(:code) case exception.code when 1400, 1407 NotNullConstraintViolation when 1 UniqueConstraintViolation when 2291, 2292 ForeignKeyConstraintViolation when 2290 CheckConstraintViolation when 8177 SerializationFailure else super end end
disconnect_error?(e, opts)
click to toggle source
Calls superclass method
Sequel::Database#disconnect_error?
# File lib/sequel/adapters/oracle.rb, line 222 def disconnect_error?(e, opts) super || (e.is_a?(::OCIError) && CONNECTION_ERROR_CODES.include?(e.code)) end
execute_prepared_statement(conn, type, name, opts) { |cursor| ... }
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 162 def execute_prepared_statement(conn, type, name, opts) ps = prepared_statement(name) sql = ps.prepared_sql if cursora = conn.prepared_statements[name] cursor, cursor_sql = cursora if cursor_sql != sql cursor.close cursor = nil end end unless cursor cursor = log_yield("PREPARE #{name}: #{sql}"){conn.parse(sql)} conn.prepared_statements[name] = [cursor, sql] end args = cursor_bind_params(conn, cursor, opts[:arguments]) log_sql = "EXECUTE #{name}" if ps.log_sql log_sql << " (" log_sql << sql log_sql << ")" end r = log_yield(log_sql, args){cursor.exec} if block_given? yield(cursor) elsif type == :insert last_insert_id(conn, opts) else r end end
last_insert_id(conn, opts)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 193 def last_insert_id(conn, opts) unless sequence = opts[:sequence] if t = opts[:table] sequence = sequence_for_table(t) end end if sequence sql = "SELECT #{literal(sequence)}.currval FROM dual" begin cursor = log_yield(sql){conn.exec(sql)} row = cursor.fetch row.each{|v| return (v.to_i if v)} rescue OCIError nil ensure cursor.close if cursor end end end
oracle_column_type(h)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 226 def oracle_column_type(h) case h[:oci8_type] when :number case h[:scale] when 0 :integer when -127 :float else :decimal end when :date :datetime else schema_column_type(h[:db_type]) end end
remove_transaction(conn, committed)
click to toggle source
Calls superclass method
Sequel::Database#remove_transaction
# File lib/sequel/adapters/oracle.rb, line 244 def remove_transaction(conn, committed) conn.autocommit = true ensure super end
rollback_transaction(conn, opts=OPTS)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 250 def rollback_transaction(conn, opts=OPTS) log_yield(TRANSACTION_ROLLBACK){conn.rollback} end
schema_parse_table(table, opts=OPTS)
click to toggle source
# File lib/sequel/adapters/oracle.rb, line 254 def schema_parse_table(table, opts=OPTS) schema, table = schema_and_table(table) schema ||= opts[:schema] schema_and_table = if ds = opts[:dataset] ds.literal(schema ? SQL::QualifiedIdentifier.new(schema, table) : SQL::Identifier.new(table)) else "#{"#{quote_identifier(schema)}." if schema}#{quote_identifier(table)}" end table_schema = [] m = output_identifier_meth(ds) im = input_identifier_meth(ds) # Primary Keys ds = metadata_dataset.from(:all_constraints___cons, :all_cons_columns___cols). where(:cols__table_name=>im.call(table), :cons__constraint_type=>'P', :cons__constraint_name=>:cols__constraint_name, :cons__owner=>:cols__owner) ds = ds.where(:cons__owner=>im.call(schema)) if schema pks = ds.select_map(:cols__column_name) # Default values defaults = begin metadata_dataset.from(:all_tab_cols). where(:table_name=>im.call(table)). to_hash(:column_name, :data_default) rescue DatabaseError {} end metadata = synchronize(opts[:server]) do |conn| begin log_yield("Connection.describe_table"){conn.describe_table(schema_and_table)} rescue OCIError => e raise_error(e) end end metadata.columns.each do |column| h = { :primary_key => pks.include?(column.name), :default => defaults[column.name], :oci8_type => column.data_type, :db_type => column.type_string, :type_string => column.type_string, :charset_form => column.charset_form, :char_used => column.char_used?, :char_size => column.char_size, :data_size => column.data_size, :precision => column.precision, :scale => column.scale, :fsprecision => column.fsprecision, :lfprecision => column.lfprecision, :allow_null => column.nullable? } h[:type] = oracle_column_type(h) h[:auto_increment] = h[:type] == :integer if h[:primary_key] h[:max_length] = h[:char_size] if h[:type] == :string table_schema << [m.call(column.name), h] end table_schema end