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
Calls superclass method
Sequel::Database#database_specific_error_class
# 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