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 219 def begin_transaction(conn, opts=OPTS) 220 log_connection_yield('Transaction.begin', conn){conn.autocommit = false} 221 set_transaction_isolation(conn, opts) 222 end
commit_transaction(conn, opts=OPTS)
click to toggle source
# File lib/sequel/adapters/oracle.rb 224 def commit_transaction(conn, opts=OPTS) 225 log_connection_yield('Transaction.commit', conn){conn.commit} 226 end
connection_execute_method()
click to toggle source
# File lib/sequel/adapters/oracle.rb 138 def connection_execute_method 139 :exec 140 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 end 133 cursor.bind_param(i, arg, PS_TYPES[type] || arg.class) 134 arg 135 end 136 end
database_error_classes()
click to toggle source
# File lib/sequel/adapters/oracle.rb 142 def database_error_classes 143 [OCIException, RuntimeError] 144 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 146 def database_specific_error_class(exception, opts) 147 return super unless exception.respond_to?(:code) 148 case exception.code 149 when 1400, 1407 150 NotNullConstraintViolation 151 when 1 152 UniqueConstraintViolation 153 when 2291, 2292 154 ForeignKeyConstraintViolation 155 when 2290 156 CheckConstraintViolation 157 when 8177 158 SerializationFailure 159 else 160 super 161 end 162 end
dataset_class_default()
click to toggle source
# File lib/sequel/adapters/oracle.rb 164 def dataset_class_default 165 Dataset 166 end
disconnect_error?(e, opts)
click to toggle source
Calls superclass method
Sequel::Database#disconnect_error?
# File lib/sequel/adapters/oracle.rb 228 def disconnect_error?(e, opts) 229 super || (e.is_a?(::OCIError) && CONNECTION_ERROR_CODES.include?(e.code)) 230 end
execute_prepared_statement(conn, type, name, opts) { |cursor| ... }
click to toggle source
# File lib/sequel/adapters/oracle.rb 168 def execute_prepared_statement(conn, type, name, opts) 169 ps = prepared_statement(name) 170 sql = ps.prepared_sql 171 if cursora = conn.prepared_statements[name] 172 cursor, cursor_sql = cursora 173 if cursor_sql != sql 174 cursor.close 175 cursor = nil 176 end 177 end 178 unless cursor 179 cursor = log_connection_yield("PREPARE #{name}: #{sql}", conn){conn.parse(sql)} 180 conn.prepared_statements[name] = [cursor, sql] 181 end 182 args = cursor_bind_params(conn, cursor, opts[:arguments]) 183 log_sql = "EXECUTE #{name}" 184 if ps.log_sql 185 log_sql += " (" 186 log_sql << sql 187 log_sql << ")" 188 end 189 r = log_connection_yield(log_sql, conn, args){cursor.exec} 190 if block_given? 191 yield(cursor) 192 elsif type == :insert 193 last_insert_id(conn, opts) 194 else 195 r 196 end 197 end
last_insert_id(conn, opts)
click to toggle source
# File lib/sequel/adapters/oracle.rb 199 def last_insert_id(conn, opts) 200 unless sequence = opts[:sequence] 201 if t = opts[:table] 202 sequence = sequence_for_table(t) 203 end 204 end 205 if sequence 206 sql = "SELECT #{literal(sequence)}.currval FROM dual" 207 begin 208 cursor = log_connection_yield(sql, conn){conn.exec(sql)} 209 row = cursor.fetch 210 row.each{|v| return (v.to_i if v)} 211 rescue OCIError 212 nil 213 ensure 214 cursor.close if cursor 215 end 216 end 217 end
oracle_column_type(h)
click to toggle source
# File lib/sequel/adapters/oracle.rb 232 def oracle_column_type(h) 233 case h[:oci8_type] 234 when :number 235 case h[:scale] 236 when 0 237 :integer 238 when -127 239 :float 240 else 241 :decimal 242 end 243 when :date 244 :datetime 245 else 246 schema_column_type(h[:db_type]) 247 end 248 end
remove_transaction(conn, committed)
click to toggle source
Calls superclass method
Sequel::Database#remove_transaction
# File lib/sequel/adapters/oracle.rb 250 def remove_transaction(conn, committed) 251 conn.autocommit = true 252 ensure 253 super 254 end
rollback_transaction(conn, opts=OPTS)
click to toggle source
# File lib/sequel/adapters/oracle.rb 256 def rollback_transaction(conn, opts=OPTS) 257 log_connection_yield('Transaction.rollback', conn){conn.rollback} 258 end
schema_parse_table(table, opts=OPTS)
click to toggle source
# File lib/sequel/adapters/oracle.rb 260 def schema_parse_table(table, opts=OPTS) 261 schema, table = schema_and_table(table) 262 schema ||= opts[:schema] 263 schema_and_table = if ds = opts[:dataset] 264 ds.literal(schema ? SQL::QualifiedIdentifier.new(schema, table) : SQL::Identifier.new(table)) 265 else 266 "#{"#{quote_identifier(schema)}." if schema}#{quote_identifier(table)}" 267 end 268 table_schema = [] 269 m = output_identifier_meth(ds) 270 im = input_identifier_meth(ds) 271 272 # Primary Keys 273 ds = metadata_dataset. 274 from{[all_constraints.as(:cons), all_cons_columns.as(:cols)]}. 275 where{{ 276 cols[:table_name]=>im.call(table), 277 cons[:constraint_type]=>'P', 278 cons[:constraint_name]=>cols[:constraint_name], 279 cons[:owner]=>cols[:owner]}} 280 ds = ds.where{{cons[:owner]=>im.call(schema)}} if schema 281 pks = ds.select_map{cols[:column_name]} 282 283 # Default values 284 defaults = begin 285 metadata_dataset.from(:all_tab_cols). 286 where(:table_name=>im.call(table)). 287 as_hash(:column_name, :data_default) 288 rescue DatabaseError 289 {} 290 end 291 292 metadata = synchronize(opts[:server]) do |conn| 293 begin 294 log_connection_yield("Connection.describe_table", conn){conn.describe_table(schema_and_table)} 295 rescue OCIError => e 296 raise_error(e) 297 end 298 end 299 metadata.columns.each do |column| 300 h = { 301 :primary_key => pks.include?(column.name), 302 :default => defaults[column.name], 303 :oci8_type => column.data_type, 304 :db_type => column.type_string, 305 :type_string => column.type_string, 306 :charset_form => column.charset_form, 307 :char_used => column.char_used?, 308 :char_size => column.char_size, 309 :data_size => column.data_size, 310 :precision => column.precision, 311 :scale => column.scale, 312 :fsprecision => column.fsprecision, 313 :lfprecision => column.lfprecision, 314 :allow_null => column.nullable? 315 } 316 h[:type] = oracle_column_type(h) 317 h[:auto_increment] = h[:type] == :integer if h[:primary_key] 318 h[:max_length] = h[:char_size] if h[:type] == :string 319 table_schema << [m.call(column.name), h] 320 end 321 table_schema 322 end