Module: SimpleOracleJDBC::Binding

Includes:
TypeMap
Included in:
DBCall, Sql
Defined in:
lib/simple_oracle_jdbc/bindings.rb

Constant Summary collapse

RUBY_TO_JDBC_TYPES =
{
  Date       => OracleTypes::DATE,
  Time       => OracleTypes::TIMESTAMP,
  String     => OracleTypes::VARCHAR,
   #   Clob       => OracleTypes::VARCHAR,
  Fixnum     => OracleTypes::INTEGER,
  Integer    => OracleTypes::INTEGER,
  Bignum     => OracleTypes::NUMERIC,
  Float      => OracleTypes::NUMERIC,
  :refcursor => OracleTypes::CURSOR,
  :raw       => OracleTypes::RAW
}

Instance Method Summary collapse

Methods included from TypeMap

#java_date_as_date, #java_date_as_time, #java_integer_as_integer, #java_number_as_float, #java_string_as_string, #oracle_raw_as_string, #ruby_any_date_as_jdbc_date, #ruby_date_as_jdbc_date, #ruby_number_as_jdbc_number, #ruby_raw_string_as_jdbc_raw, #ruby_time_as_jdbc_timestamp

Instance Method Details

#bind_date(obj, v, i) ⇒ Object



144
145
146
147
148
149
150
151
# File 'lib/simple_oracle_jdbc/bindings.rb', line 144

def bind_date(obj, v, i)
  if v
    # %Q is micro seconds since epoch. Divide by 1000 to get milli-sec
    obj.set_date(i, ruby_date_as_jdbc_date(v))
  else
    obj.set_null(i, OracleTypes::DATE)
  end
end

#bind_int(obj, v, i) ⇒ Object



171
172
173
174
175
176
177
# File 'lib/simple_oracle_jdbc/bindings.rb', line 171

def bind_int(obj, v, i)
  if v
    obj.set_long(i, v)
  else
    obj.set_null(i, OracleTypes::INTEGER)
  end
end

#bind_number(obj, v, i) ⇒ Object



179
180
181
182
183
184
185
# File 'lib/simple_oracle_jdbc/bindings.rb', line 179

def bind_number(obj, v, i)
  if v
    obj.set_number(i, ruby_number_as_jdbc_number(v))
  else
    obj.set_null(i, OracleTypes::NUMBER)
  end
end

#bind_out_parameter(obj, index, type, value) ⇒ Object

:nodoc:



135
136
137
138
139
140
141
142
# File 'lib/simple_oracle_jdbc/bindings.rb', line 135

def bind_out_parameter(obj, index, type, value)
  if type == SimpleOracleJDBC::OraArray or type == SimpleOracleJDBC::OraRecord
    value.register_as_out_parameter(@connection, obj, index)
  else
    internal_type = RUBY_TO_JDBC_TYPES[type] || OracleTypes::VARCHAR
    obj.register_out_parameter(index, internal_type)
  end
end

#bind_raw(obj, v, i) ⇒ Object



193
194
195
196
197
198
199
# File 'lib/simple_oracle_jdbc/bindings.rb', line 193

def bind_raw(obj, v, i)
  if v
    obj.set_raw(i, ruby_raw_string_as_jdbc_raw(v))
  else
    obj.set_null(i, OracleTypes::RAW)
  end
end

#bind_refcursor(obj, v, i) ⇒ Object



187
188
189
190
191
# File 'lib/simple_oracle_jdbc/bindings.rb', line 187

def bind_refcursor(obj, v, i)
  if v
    raise "not implemented"
  end
end

#bind_string(obj, v, i) ⇒ Object



163
164
165
166
167
168
169
# File 'lib/simple_oracle_jdbc/bindings.rb', line 163

def bind_string(obj, v, i)
  if v
    obj.set_string(i, v)
  else
    obj.set_null(i, OracleTypes::VARCHAR)
  end
end

#bind_time(obj, v, i) ⇒ Object



153
154
155
156
157
158
159
160
161
# File 'lib/simple_oracle_jdbc/bindings.rb', line 153

def bind_time(obj, v, i)
  if v
    # Need to use an Oracle TIMESTAMP - dates don't allow a time to be specified
    # for some reason, even though a date in Oracle contains a time.
    obj.setTIMESTAMP(i, ruby_time_as_jdbc_timestamp(v))
  else
    obj.set_null(i, OracleTypes::TIMESTAMP)
  end
end

#bind_value(obj, v, i) ⇒ Object

Given a JDBC prepared call or prepared statement, a value and a bind index, the value will be bound to JDBC statement.

If value is a single value, ie not an array in is considered an IN parameter.

If value is an array, then it should have either 2 or 3 elements.

  • 2 elements indictes the value is an IN parameter, element 0 indicates the type

of the bind variable, and element 1 is the value, eg:

[String, "Some_value"]
  • 3 elements indicates the value is an OUT or an IN OUT parameter (useful only when using

stored procedures), eg:

[String, "Some_value", :out]
[:refcursor, nil, :out]

When binding values, Ruby types are mapped to Java / JDBC types based on the type of the passed in Ruby object. The mapping is as follows:

RUBY_TO_JDBC_TYPES = {
  Date       => OracleTypes::DATE,
  Time       => OracleTypes::TIMESTAMP,
  String     => OracleTypes::VARCHAR,
  Fixnum     => OracleTypes::INTEGER,
  Integer    => OracleTypes::INTEGER,
  Bignum     => OracleTypes::NUMERIC,
  Float      => OracleTypes::NUMERIC,
  :refcursor => OracleTypes::CURSOR,
  :raw       => OracleTypes::RAW
}

Note that to bind a ref_cursor, there is no natural Ruby class, so it can only be bound using the array form for values.

Also note that in this version, it is not possible to bind a ref_cursor into a procedure - it can only be retrieved.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/simple_oracle_jdbc/bindings.rb', line 60

def bind_value(obj, v, i)
  type  = v.class
  value = v
  if v.is_a? Array
    # class is being overriden from the input
    type = v[0]
    value = v[1]

    if v.length == 3
      bind_out_parameter(obj, i, type, value)
    end
  end

  if type == Date
    bind_date(obj, value, i)
  elsif type == Time
    bind_time(obj, value, i)
  elsif type == String
    bind_string(obj, value, i)
  elsif type == Fixnum or type == Integer
    bind_int(obj, value, i)
  elsif type == Float
    bind_number(obj, value, i)
  elsif type == :refcursor
    bind_refcursor(obj, value, i)
  elsif type == :raw
    bind_raw(obj, value, i)
  elsif type == SimpleOracleJDBC::OraArray
    value.bind_to_call(@connection, obj, i)
  elsif type == SimpleOracleJDBC::OraRecord
    value.bind_to_call(@connection, obj, i)
  else
    raise UnknownBindType, type.to_s
  end
end

#retrieve_date(obj, i) ⇒ Object



201
202
203
204
# File 'lib/simple_oracle_jdbc/bindings.rb', line 201

def retrieve_date(obj, i)
  jdate = obj.get_date(i)
  java_date_as_date(jdate)
end

#retrieve_int(obj, i) ⇒ Object



215
216
217
218
219
220
221
# File 'lib/simple_oracle_jdbc/bindings.rb', line 215

def retrieve_int(obj, i)
  v = obj.get_long(i)
  if obj.was_null
    v = nil
  end
  java_integer_as_integer(v)
end

#retrieve_number(obj, i) ⇒ Object



223
224
225
226
# File 'lib/simple_oracle_jdbc/bindings.rb', line 223

def retrieve_number(obj, i)
  v = obj.get_number(i)
  java_number_as_float(v)
end

#retrieve_raw(obj, i) ⇒ Object



236
237
238
239
# File 'lib/simple_oracle_jdbc/bindings.rb', line 236

def retrieve_raw(obj, i)
  v = obj.get_raw(i)
  oracle_raw_as_string(v)
end

#retrieve_refcursor(obj, i) ⇒ Object



228
229
230
231
232
233
234
# File 'lib/simple_oracle_jdbc/bindings.rb', line 228

def retrieve_refcursor(obj, i)
  rset = obj.get_object(i)
  # Dummy connection passed as it is never needed?
  results = Sql.new(nil)
  results.result_set = rset
  results
end

#retrieve_string(obj, i) ⇒ Object



211
212
213
# File 'lib/simple_oracle_jdbc/bindings.rb', line 211

def retrieve_string(obj, i)
  obj.get_string(i)
end

#retrieve_time(obj, i) ⇒ Object



206
207
208
209
# File 'lib/simple_oracle_jdbc/bindings.rb', line 206

def retrieve_time(obj, i)
  jdate = obj.get_timestamp(i)
  java_date_as_time(jdate)
end

#retrieve_value(obj, i) ⇒ Object

Given a open JDBC result set and a column index, the value is retrieved and mapped into a Ruby type.

The columns are indexed from 1 in the array.

If the retrieved value is null, nil is returned.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/simple_oracle_jdbc/bindings.rb', line 102

def retrieve_value(obj, i)
  case obj..get_column_type_name(i)
  when 'NUMBER'
    retrieve_number(obj, i)
  when 'INTEGER'
    retrieve_int(obj, i)
  when 'DATE'
    retrieve_time(obj, i)
  when 'TIMESTAMP'
    retrieve_time(obj, i)
  when 'CHAR', 'VARCHAR2', 'CLOB'
    retrieve_string(obj, i)
  when 'RAW'
    retrieve_raw(obj, i)
  else
    # If it is not one of the built-in tyes, it could be a user defined type
    # returning either an array or record type.
    type_code = obj..get_column_type(i)
    if Java::JavaSql::Types::ARRAY == type_code
      @array ||= Array.new
      @array[i] ||= OraArray.new(obj..get_column_type_name(i), nil)
      @array[i].retrieve_out_value(@connection, obj, i)
    elsif Java::JavaSql::Types::STRUCT == type_code
      @array ||= Array.new
      @array[i] ||= OraRecord.new(obj..get_column_type_name(i), nil)
      @array[i].retrieve_out_value(@connection, obj, i)
    else
      raise UnknownSQLType, obj..get_column_type_name(i)
    end
  end
end