Class: PLSQL::JDBCConnection

Inherits:
Connection show all
Defined in:
lib/plsql/jdbc_connection.rb

Overview

:nodoc:

Defined Under Namespace

Classes: CallableStatement, Cursor

Constant Summary collapse

RUBY_CLASS_TO_SQL_TYPE =
{
  Fixnum => java.sql.Types::INTEGER,
  Bignum => java.sql.Types::INTEGER,
  Integer => java.sql.Types::INTEGER,
  Float => java.sql.Types::FLOAT,
  BigDecimal => java.sql.Types::NUMERIC,
  String => java.sql.Types::VARCHAR,
  Java::OracleSql::CLOB => Java::oracle.jdbc.OracleTypes::CLOB,
  Java::OracleSql::BLOB => Java::oracle.jdbc.OracleTypes::BLOB,
  Date => java.sql.Types::DATE,
  Time => java.sql.Types::TIMESTAMP,
  DateTime => java.sql.Types::DATE,
  Java::OracleSql::ARRAY => Java::oracle.jdbc.OracleTypes::ARRAY,
  Array => Java::oracle.jdbc.OracleTypes::ARRAY,
  Java::OracleSql::STRUCT => Java::oracle.jdbc.OracleTypes::STRUCT,
  Hash => Java::oracle.jdbc.OracleTypes::STRUCT,
  java.sql.ResultSet => Java::oracle.jdbc.OracleTypes::CURSOR,
}
SQL_TYPE_TO_RUBY_CLASS =
{
  java.sql.Types::CHAR => String,
  java.sql.Types::VARCHAR => String,
  java.sql.Types::NUMERIC => BigDecimal,
  java.sql.Types::INTEGER => Fixnum,
  java.sql.Types::DATE => Time,
  java.sql.Types::TIMESTAMP => Time,
  Java::oracle.jdbc.OracleTypes::TIMESTAMPTZ => Time,
  Java::oracle.jdbc.OracleTypes::TIMESTAMPLTZ => Time,
  java.sql.Types::BLOB => String,
  java.sql.Types::CLOB => String,
  java.sql.Types::ARRAY => Java::OracleSql::ARRAY,
  java.sql.Types::STRUCT => Java::OracleSql::STRUCT,
  Java::oracle.jdbc.OracleTypes::CURSOR => java.sql.ResultSet
}

Instance Attribute Summary

Attributes inherited from Connection

#activerecord_class, #raw_driver

Instance Method Summary collapse

Methods inherited from Connection

create, #describe_synonym, #initialize, #jdbc?, #oci?, #raw_connection, #select_all, #select_first, #select_hash_all, #select_hash_first

Constructor Details

This class inherits a constructor from PLSQL::Connection

Instance Method Details

#autocommit=(value) ⇒ Object



53
54
55
# File 'lib/plsql/jdbc_connection.rb', line 53

def autocommit=(value)
  raw_connection.setAutoCommit(value)
end

#autocommit?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/plsql/jdbc_connection.rb', line 49

def autocommit?
  raw_connection.getAutoCommit
end

#commitObject



41
42
43
# File 'lib/plsql/jdbc_connection.rb', line 41

def commit
  raw_connection.commit
end

#cursor_from_query(sql, bindvars = [], options = {}) ⇒ Object



174
175
176
# File 'lib/plsql/jdbc_connection.rb', line 174

def cursor_from_query(sql, bindvars=[], options={})
  Cursor.new_from_query(self, sql, bindvars, options)
end

#database_versionObject



482
483
484
# File 'lib/plsql/jdbc_connection.rb', line 482

def database_version
  @database_version ||= (md = raw_connection.) && [md.getDatabaseMajorVersion, md.getDatabaseMinorVersion]
end

#exec(sql, *bindvars) ⇒ Object



61
62
63
64
65
66
67
# File 'lib/plsql/jdbc_connection.rb', line 61

def exec(sql, *bindvars)
  cs = prepare_call(sql, *bindvars)
  cs.execute
  true
ensure
  cs.close rescue nil
end

#get_bind_variable(stmt, i, type) ⇒ Object



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/plsql/jdbc_connection.rb', line 278

def get_bind_variable(stmt, i, type)
  case type.to_s.to_sym
  when :Fixnum, :Bignum, :Integer
    stmt.getInt(i)
  when :Float
    stmt.getFloat(i)
  when :BigDecimal
    bd = stmt.getBigDecimal(i)
    bd && BigDecimal.new(bd.to_s)
  when :String
    stmt.getString(i)
  when :'Java::OracleSql::CLOB'
    stmt.getClob(i)
  when :'Java::OracleSql::BLOB'
    stmt.getBlob(i)
  when :Date, :DateTime
    stmt.getDATE(i)
  when :Time
    stmt.getTimestamp(i)
  when :'Java::OracleSql::ARRAY'
    stmt.getArray(i)
  when :'Java::OracleSql::STRUCT'
    stmt.getSTRUCT(i)
  when :'Java::JavaSql::ResultSet'
    stmt.getCursor(i)
  end
end

#get_java_sql_type(value, type) ⇒ Object



229
230
231
# File 'lib/plsql/jdbc_connection.rb', line 229

def get_java_sql_type(value, type)
  RUBY_CLASS_TO_SQL_TYPE[type || value.class] || java.sql.Types::VARCHAR
end

#get_ruby_value_from_result_set(rset, i, metadata) ⇒ Object



306
307
308
309
310
# File 'lib/plsql/jdbc_connection.rb', line 306

def get_ruby_value_from_result_set(rset, i, )
  ruby_type = SQL_TYPE_TO_RUBY_CLASS[[:sql_type]]
  ora_value = get_bind_variable(rset, i, ruby_type)
  result_new = ora_value_to_ruby_value(ora_value)
end

#logoffObject



34
35
36
37
38
39
# File 'lib/plsql/jdbc_connection.rb', line 34

def logoff
  raw_connection.close
  true
rescue
  false
end

#ora_value_to_ruby_value(value) ⇒ Object



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/plsql/jdbc_connection.rb', line 438

def ora_value_to_ruby_value(value)
  case value
  when Float, BigDecimal
    ora_number_to_ruby_number(value)
  when Java::JavaMath::BigDecimal
    value && ora_number_to_ruby_number(BigDecimal.new(value.to_s))
  when Java::OracleSql::DATE
    if value
      d = value.dateValue
      t = value.timeValue
      Time.send(plsql.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
    end
  when Java::JavaSql::Timestamp
    if value
      Time.send(plsql.default_timezone, value.year + 1900, value.month + 1, value.date, value.hours, value.minutes, value.seconds,
        value.nanos / 1000)
    end
  when Java::OracleSql::CLOB
    if value.isEmptyLob
      nil
    else
      value.getSubString(1, value.length)
    end
  when Java::OracleSql::BLOB
    if value.isEmptyLob
      nil
    else
      String.from_java_bytes(value.getBytes(1, value.length))
    end
  when Java::OracleSql::ARRAY
    value.getArray.map{|e| ora_value_to_ruby_value(e)}
  when Java::OracleSql::STRUCT
    descriptor = value.getDescriptor
     = descriptor.
    field_names = (1..descriptor.getLength).map {|i| .getColumnName(i).downcase.to_sym}
    field_values = value.getAttributes.map{|e| ora_value_to_ruby_value(e)}
    ArrayHelpers::to_hash(field_names, field_values)
  when Java::java.sql.ResultSet
    Cursor.new(self, value)
  else
    value
  end
end

#parse(sql) ⇒ Object



170
171
172
# File 'lib/plsql/jdbc_connection.rb', line 170

def parse(sql)
  CallableStatement.new(self, sql)
end

#plsql_to_ruby_data_type(metadata) ⇒ Object



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/plsql/jdbc_connection.rb', line 316

def plsql_to_ruby_data_type()
  data_type, data_length = [:data_type], [:data_length]
  case data_type
  when "VARCHAR2", "CHAR", "NVARCHAR2", "NCHAR"
    [String, data_length || 32767]
  when "CLOB", "NCLOB"
    [Java::OracleSql::CLOB, nil]
  when "BLOB"
    [Java::OracleSql::BLOB, nil]
  when "NUMBER"
    [BigDecimal, nil]
  when "PLS_INTEGER", "BINARY_INTEGER"
    [Fixnum, nil]
  when "DATE"
    [DateTime, nil]
  when "TIMESTAMP", "TIMESTAMP WITH TIME ZONE", "TIMESTAMP WITH LOCAL TIME ZONE"
    [Time, nil]
  when "TABLE", "VARRAY"
    [Java::OracleSql::ARRAY, nil]
  when "OBJECT"
    [Java::OracleSql::STRUCT, nil]
  when "REF CURSOR"
    [java.sql.ResultSet, nil]
  else
    [String, 32767]
  end
end

#prefetch_rows=(value) ⇒ Object



57
58
59
# File 'lib/plsql/jdbc_connection.rb', line 57

def prefetch_rows=(value)
  raw_connection.setDefaultRowPrefetch(value)
end

#prepare_call(sql, *bindvars) ⇒ Object



186
187
188
189
190
191
192
# File 'lib/plsql/jdbc_connection.rb', line 186

def prepare_call(sql, *bindvars)
  stmt = raw_connection.prepareCall(sql)
  bindvars.each_with_index do |bv, i|
    set_bind_variable(stmt, i+1, bv)
  end
  stmt
end

#prepare_statement(sql, *bindvars) ⇒ Object



178
179
180
181
182
183
184
# File 'lib/plsql/jdbc_connection.rb', line 178

def prepare_statement(sql, *bindvars)
  stmt = raw_connection.prepareStatement(sql)
  bindvars.each_with_index do |bv, i|
    set_bind_variable(stmt, i+1, ruby_value_to_ora_value(bv))
  end
  stmt
end

#result_set_to_ruby_data_type(column_type, column_type_name) ⇒ Object



312
313
314
# File 'lib/plsql/jdbc_connection.rb', line 312

def result_set_to_ruby_data_type(column_type, column_type_name)
  
end

#rollbackObject



45
46
47
# File 'lib/plsql/jdbc_connection.rb', line 45

def rollback
  raw_connection.rollback
end

#ruby_value_to_ora_value(value, type = nil, metadata = {}) ⇒ Object



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
# File 'lib/plsql/jdbc_connection.rb', line 344

def ruby_value_to_ora_value(value, type=nil, ={})
  type ||= value.class
  case type.to_s.to_sym
  when :Fixnum, :String
    value
  when :BigDecimal
    case value
    when TrueClass
      java_bigdecimal(1)
    when FalseClass
      java_bigdecimal(0)
    else
      java_bigdecimal(value)
    end
  when :Date, :DateTime
    case value
    when DateTime
      java_date(Time.send(plsql.default_timezone, value.year, value.month, value.day, value.hour, value.min, value.sec))
    when Date
      java_date(Time.send(plsql.default_timezone, value.year, value.month, value.day, 0, 0, 0))
    else
      java_date(value)
    end
  when :Time
    java_timestamp(value)
  when :'Java::OracleSql::CLOB'
    if value
      clob = Java::OracleSql::CLOB.createTemporary(raw_connection, false, Java::OracleSql::CLOB::DURATION_SESSION)
      clob.setString(1, value)
      clob
    else
      Java::OracleSql::CLOB.getEmptyCLOB
    end
  when :'Java::OracleSql::BLOB'
    if value
      blob = Java::OracleSql::BLOB.createTemporary(raw_connection, false, Java::OracleSql::BLOB::DURATION_SESSION)
      blob.setBytes(1, value.to_java_bytes)
      blob
    else
      Java::OracleSql::BLOB.getEmptyBLOB
    end
  when :'Java::OracleSql::ARRAY'
    if value
      raise ArgumentError, "You should pass Array value for collection type parameter" unless value.is_a?(Array)
      descriptor = Java::OracleSql::ArrayDescriptor.createDescriptor([:sql_type_name], raw_connection)
      elem_type = descriptor.getBaseType
      elem_type_name = descriptor.getBaseName
      elem_list = value.map do |elem|
        case elem_type
        when Java::oracle.jdbc.OracleTypes::ARRAY
          ruby_value_to_ora_value(elem, Java::OracleSql::ARRAY, :sql_type_name => elem_type_name)
        when Java::oracle.jdbc.OracleTypes::STRUCT
          ruby_value_to_ora_value(elem, Java::OracleSql::STRUCT, :sql_type_name => elem_type_name)
        else
          ruby_value_to_ora_value(elem)
        end
      end
      Java::OracleSql::ARRAY.new(descriptor, raw_connection, elem_list.to_java)
    end
  when :'Java::OracleSql::STRUCT'
    if value
      raise ArgumentError, "You should pass Hash value for object type parameter" unless value.is_a?(Hash)
      descriptor = Java::OracleSql::StructDescriptor.createDescriptor([:sql_type_name], raw_connection)
       = descriptor.
      struct_fields = (1..descriptor.getLength).inject({}) do |hash, i|
        hash[.getColumnName(i).downcase.to_sym] =
          {:type => .getColumnType(i), :type_name => .getColumnTypeName(i)}
        hash
      end
      object_attrs = java.util.HashMap.new
      value.each do |key, attr_value|
        raise ArgumentError, "Wrong object type field passed to PL/SQL procedure" unless (field = struct_fields[key])
        case field[:type]
        when Java::oracle.jdbc.OracleTypes::ARRAY
          # nested collection
          object_attrs.put(key.to_s.upcase, ruby_value_to_ora_value(attr_value, Java::OracleSql::ARRAY, :sql_type_name => field[:type_name]))
        when Java::oracle.jdbc.OracleTypes::STRUCT
          # nested object type
          object_attrs.put(key.to_s.upcase, ruby_value_to_ora_value(attr_value, Java::OracleSql::STRUCT, :sql_type_name => field[:type_name]))
        else
          object_attrs.put(key.to_s.upcase, ruby_value_to_ora_value(attr_value))
        end
      end
      Java::OracleSql::STRUCT.new(descriptor, raw_connection, object_attrs)
    end
  when :'Java::JavaSql::ResultSet'
    if value
      value.result_set
    end
  else
    value
  end
end

#set_bind_variable(stmt, i, value, type = nil, length = nil, metadata = {}) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/plsql/jdbc_connection.rb', line 233

def set_bind_variable(stmt, i, value, type=nil, length=nil, ={})
  key = i.kind_of?(Integer) ? nil : i.to_s.gsub(':','')
  type_symbol = (!value.nil? && type ? type : value.class).to_s.to_sym
  case type_symbol
  when :Fixnum, :Bignum, :Integer
    stmt.send("setInt#{key && "AtName"}", key || i, value)
  when :Float
    stmt.send("setFloat#{key && "AtName"}", key || i, value)
  when :BigDecimal, :'Java::JavaMath::BigDecimal'
    stmt.send("setBigDecimal#{key && "AtName"}", key || i, value)
  when :String
    stmt.send("setString#{key && "AtName"}", key || i, value)
  when :'Java::OracleSql::CLOB'
    stmt.send("setClob#{key && "AtName"}", key || i, value)
  when :'Java::OracleSql::BLOB'
    stmt.send("setBlob#{key && "AtName"}", key || i, value)
  when :Date, :DateTime, :'Java::OracleSql::DATE'
    stmt.send("setDATE#{key && "AtName"}", key || i, value)
  when :Time, :'Java::JavaSql::Timestamp'
    stmt.send("setTimestamp#{key && "AtName"}", key || i, value)
  when :NilClass
    if ['TABLE', 'VARRAY', 'OBJECT'].include?([:data_type])
      stmt.send("setNull#{key && "AtName"}", key || i, get_java_sql_type(value, type),
        [:sql_type_name])
    elsif [:data_type] == 'REF CURSOR'
      # TODO: cannot bind NULL value to cursor parameter, getting error
      # java.sql.SQLException: Unsupported feature: sqlType=-10
      # Currently do nothing and assume that NULL values will not be passed to IN parameters
      # If cursor is IN/OUT or OUT parameter then it should work
    else
      stmt.send("setNull#{key && "AtName"}", key || i, get_java_sql_type(value, type))
    end
  when :'Java::OracleSql::ARRAY'
    stmt.send("setARRAY#{key && "AtName"}", key || i, value)
  when :'Java::OracleSql::STRUCT'
    stmt.send("setSTRUCT#{key && "AtName"}", key || i, value)
  when :'Java::JavaSql::ResultSet'
    # TODO: cannot find how to pass cursor parameter from JDBC
    # setCursor is giving exception java.sql.SQLException: Unsupported feature
    stmt.send("setCursor#{key && "AtName"}", key || i, value)
  else
    raise ArgumentError, "Don't know how to bind variable with type #{type_symbol}"
  end
end