simpleOracleJDBC 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -130,7 +130,8 @@ The best way to learn how to use Simple Oracle JDBC is to read through the sampl
130
130
  # Integer => OracleTypes::INTEGER,
131
131
  # Bignum => OracleTypes::NUMERIC,
132
132
  # Float => OracleTypes::NUMERIC,
133
- # :refcursor => OracleTypes::CURSOR
133
+ # :refcursor => OracleTypes::CURSOR,
134
+ # :raw => OracleTypes::RAW
134
135
  # }
135
136
  #
136
137
  # The second element is the value, which should be nil for out parameters and can take a
@@ -201,4 +202,4 @@ Types that cannot be retrieved from an SQL result set
201
202
  * CLOB
202
203
  * Cursor
203
204
  * Long
204
- * nvarchar etc
205
+ * nvarchar etc
@@ -13,7 +13,8 @@ module SimpleOracleJDBC
13
13
  Integer => OracleTypes::INTEGER,
14
14
  Bignum => OracleTypes::NUMERIC,
15
15
  Float => OracleTypes::NUMERIC,
16
- :refcursor => OracleTypes::CURSOR
16
+ :refcursor => OracleTypes::CURSOR,
17
+ :raw => OracleTypes::RAW
17
18
  }
18
19
 
19
20
  # Given a JDBC prepared call or prepared statement, a value and a bind index, the value
@@ -45,7 +46,8 @@ module SimpleOracleJDBC
45
46
  # Integer => OracleTypes::INTEGER,
46
47
  # Bignum => OracleTypes::NUMERIC,
47
48
  # Float => OracleTypes::NUMERIC,
48
- # :refcursor => OracleTypes::CURSOR
49
+ # :refcursor => OracleTypes::CURSOR,
50
+ # :raw => OracleTypes::RAW
49
51
  # }
50
52
  #
51
53
  # Note that to bind a ref_cursor, there is no natural Ruby class, so it can only be bound using
@@ -78,6 +80,8 @@ module SimpleOracleJDBC
78
80
  bind_number(obj, value, i)
79
81
  elsif type == :refcursor
80
82
  bind_refcursor(obj, value, i)
83
+ elsif type == :raw
84
+ bind_raw(obj, value, i)
81
85
  else
82
86
  raise UnknownBindType, type.to_s
83
87
  end
@@ -101,6 +105,8 @@ module SimpleOracleJDBC
101
105
  retrieve_time(obj, i)
102
106
  when 'CHAR', 'VARCHAR2', 'CLOB'
103
107
  retrieve_string(obj, i)
108
+ when 'RAW'
109
+ retrieve_raw(obj, i)
104
110
  else
105
111
  raise UnknownSQLType, obj.get_meta_data.get_column_type_name(i)
106
112
  end
@@ -169,6 +175,16 @@ module SimpleOracleJDBC
169
175
  end
170
176
  end
171
177
 
178
+ def bind_raw(obj, v, i)
179
+ if v
180
+ raw = Java::OracleSql::RAW.new(v)
181
+ obj.set_raw(i, raw)
182
+ else
183
+ obj.set_null(i, OracleTypes::RAW)
184
+ end
185
+ end
186
+
187
+
172
188
  def retrieve_date(obj, i)
173
189
  jdate = obj.get_date(i)
174
190
  if jdate
@@ -216,5 +232,14 @@ module SimpleOracleJDBC
216
232
  results
217
233
  end
218
234
 
235
+ def retrieve_raw(obj, i)
236
+ v = obj.get_raw(i)
237
+ if v
238
+ v.string_value
239
+ else
240
+ nil
241
+ end
242
+ end
243
+
219
244
  end
220
245
  end
@@ -102,6 +102,8 @@ module SimpleOracleJDBC
102
102
  retrieve_number(@call, i)
103
103
  elsif bind[0] == :refcursor
104
104
  retrieve_refcursor(@call, i)
105
+ elsif bind[0] == :raw
106
+ retrieve_raw(@call, i)
105
107
  end
106
108
  else
107
109
  # If its not an array, it was just an IN, so just pull the bind
@@ -74,13 +74,14 @@ module SimpleOracleJDBC
74
74
 
75
75
  # Closes the result set if it exists, and also closes the SQL statement that created the result
76
76
  # set.
77
- # TODO - does it make sense to close the statement here too?
78
77
  def close_result_set
79
78
  if @result_set
80
79
  @result_set.close
81
80
  @result_set = nil
82
81
  end
83
- close_statement
82
+ if @auto_statement_close
83
+ close_statement
84
+ end
84
85
  end
85
86
 
86
87
  private
@@ -31,12 +31,14 @@ module SimpleOracleJDBC
31
31
  # Creates a new instance of this class. Not intended to be used directly. Use the factory
32
32
  # class methods prepare or execute instead.
33
33
  def initialize
34
+ @auto_statement_close = true
34
35
  end
35
36
 
36
37
  # Takes a JDBC connection object and an SQL statement and returns a SimpleOracleJDBC::Sql
37
38
  # object with the prepared statement.
38
39
  def self.prepare(connection, sql)
39
40
  sql_object = self.new
41
+ sql_object.disable_auto_statement_close
40
42
  sql_object.prepare(connection,sql)
41
43
  end
42
44
 
@@ -71,7 +73,9 @@ module SimpleOracleJDBC
71
73
  unless @sql =~ /^\s*select/i
72
74
  @result_set = nil
73
75
  @statement.execute()
74
- close_statement
76
+ if @auto_statement_close
77
+ close_statement
78
+ end
75
79
  else
76
80
  @result_set = @statement.execute_query()
77
81
  end
@@ -92,5 +96,17 @@ module SimpleOracleJDBC
92
96
  end
93
97
  end
94
98
 
99
+
100
+ # If a statement was prepared, it is likely it is going to be reused, so the statement
101
+ # handle should not be closed after execution.
102
+ #
103
+ # If the statement is directly executed, then the prepared handle was never requested
104
+ # and so it probably should be closed.
105
+ #
106
+ # This method is called by the prepare class/factory method
107
+ def disable_auto_statement_close
108
+ @auto_statement_close = false
109
+ end
110
+
95
111
  end
96
112
  end
data/test/binding_test.rb CHANGED
@@ -127,6 +127,24 @@ class BindingTest < Test::Unit::TestCase
127
127
  assert_equal(rows[0][0], 'X')
128
128
  end
129
129
 
130
+ def test_raw_can_be_bound_and_retrieved
131
+ call = @interface.prepare_proc("begin
132
+ :l_raw := :i_raw;
133
+ end;")
134
+ call.execute([:raw, nil, :out], [:raw, "DEDEDEDEFF"])
135
+ assert(call[1].is_a?(String), "Ensure a string is returned")
136
+ assert(call[1], "DEDEDEDEFF")
137
+ end
138
+
139
+ def test_null_raw_can_be_bound_and_retrieved
140
+ call = @interface.prepare_proc("begin
141
+ :l_raw := :i_raw;
142
+ end;")
143
+ call.execute([:raw, nil, :out], [:raw, nil])
144
+ assert_nil(call[1])
145
+ end
146
+
147
+
130
148
  def test_unknown_data_type_raises_exeception_when_bound
131
149
  call = @interface.prepare_proc("begin
132
150
  :l_date := :i_date;
@@ -220,6 +238,19 @@ class BindingTest < Test::Unit::TestCase
220
238
  assert_equal(results[0][0], nil)
221
239
  end
222
240
 
241
+ def test_raw_is_retrieved_as_ruby_string
242
+ sql = @interface.execute_sql("select cast('DFDFDFDF' as raw(16)) from dual")
243
+ results = sql.all_array
244
+ assert_equal(results[0][0], "DFDFDFDF")
245
+ end
246
+
247
+ def test_null_raw_is_retrieved_as_nil
248
+ sql = @interface.execute_sql("select cast(null as raw(16)) from dual")
249
+ results = sql.all_array
250
+ assert_equal(results[0][0], nil)
251
+ end
252
+
253
+
223
254
  def test_unknown_data_type_from_sql_raises_exeception
224
255
  sql = @interface.execute_sql("select cast('hello there' as nvarchar2(1000)) from dual")
225
256
  assert_raises SimpleOracleJDBC::UnknownSQLType do
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: simpleOracleJDBC
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.3
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Stephen O'Donnell
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-12 00:00:00.000000000 Z
12
+ date: 2013-08-09 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A lightweight wrapper around the JDBC interface to make it easier to make SQL and stored procedure calls.
15
15
  email: stephen@betteratoracle.com
@@ -34,8 +34,6 @@ files:
34
34
  dGVzdC90ZXN0X3J1bm5lci5yYg==
35
35
  - !binary |-
36
36
  bGliL3NpbXBsZV9vcmFjbGVfamRiYy5yYg==
37
- - !binary |-
38
- bGliL3NpbXBsZV9vcmFjbGVfamRiYy8jYmluZGluZ3MucmIj
39
37
  - !binary |-
40
38
  bGliL3NpbXBsZV9vcmFjbGVfamRiYy9iaW5kaW5ncy5yYg==
41
39
  - !binary |-
@@ -1,214 +0,0 @@
1
- module SimpleOracleJDBC
2
- module Binding
3
-
4
- # Provides a set of methods to map Ruby types to their JDBC equivalent and back again.
5
-
6
-
7
- RUBY_TO_JDBC_TYPES = {
8
- Date => OracleTypes::DATE,
9
- Time => OracleTypes::TIMESTAMP,
10
- String => OracleTypes::VARCHAR,
11
- Fixnum => OracleTypes::INTEGER,
12
- Integer => OracleTypes::INTEGER,
13
- Bignum => OracleTypes::NUMERIC,
14
- Float => OracleTypes::NUMERIC,
15
- :refcursor => OracleTypes::CURSOR
16
- }
17
-
18
- # Given a JDBC prepared call or prepared statement, a value and a bind index, the value
19
- # will be bound to JDBC statement.
20
- #
21
- # If value is a single value, ie not an array in is considered an IN parameter.
22
- #
23
- # If value is an array, then it should have either 2 or 3 elements.
24
- #
25
- # * 2 elements indictes the value is an IN parameter, element 0 indicates the type
26
- # of the bind variable, and element 1 is the value, eg:
27
- #
28
- # [String, "Some_value"]
29
- #
30
- # * 3 elements indicates the value is an OUT or an IN OUT parameter (useful only when using
31
- # stored procedures), eg:
32
- #
33
- # [String, "Some_value", :out]
34
- # [:refcursor, nil, :out]
35
- #
36
- # When binding values, Ruby types are mapped to Java / JDBC types based on the type
37
- # of the passed in Ruby object. The mapping is as follows:
38
- #
39
- # RUBY_TO_JDBC_TYPES = {
40
- # Date => OracleTypes::DATE,
41
- # Time => OracleTypes::TIMESTAMP,
42
- # String => OracleTypes::VARCHAR,
43
- # Fixnum => OracleTypes::INTEGER,
44
- # Integer => OracleTypes::INTEGER,
45
- # Bignum => OracleTypes::NUMERIC,
46
- # Float => OracleTypes::NUMERIC,
47
- # :refcursor => OracleTypes::CURSOR
48
- # }
49
- #
50
- # Note that to bind a ref_cursor, there is no natural Ruby class, so it can only be bound using
51
- # the array form for values.
52
- #
53
- # Also note that in this version, it is not possible to bind a ref_cursor into a procedure - it can
54
- # only be retrieved.
55
- def bind_value(obj, v, i)
56
- type = v.class
57
- value = v
58
- if v.is_a? Array
59
- # class is being overriden from the input
60
- type = v[0]
61
- value = v[1]
62
-
63
- if v.length == 3
64
- bind_out_parameter(obj, i, type)
65
- end
66
- end
67
-
68
- if type == Date
69
- bind_date(obj, value, i)
70
- elsif type == Time
71
- bind_time(obj, value, i)
72
- elsif type == String
73
- bind_string(obj, value, i)
74
- elsif type == Fixnum or type == Integer
75
- bind_int(obj, value, i)
76
- elsif type == Float
77
- bind_number(obj, value, i)
78
- elsif type == :refcursor
79
- bind_refcursor(obj, value, i)
80
- else
81
- raise UnknownBindType, type.to_s
82
- end
83
- end
84
-
85
- # Given a open JDBC result set and a column index, the value is retrieved
86
- # and mapped into a Ruby type.
87
- #
88
- # The columns are indexed from 1 in the array.
89
- #
90
- # If the retrieved value is null, nil is returned.
91
- def retrieve_value(obj, i)
92
- case obj.get_meta_data.get_column_type_name(i)
93
- when 'NUMBER'
94
- retrieve_number(obj, i)
95
- when 'INTEGER'
96
- retrieve_int(obj, i)
97
- when 'DATE'
98
- retrieve_time(obj, i)
99
- when 'TIMESTAMP'
100
- retrieve_time(obj, i)
101
- when 'CHAR', 'VARCHAR2'
102
- retrieve_string(obj, i)
103
- else
104
- raise UnknownSQLType, obj.get_meta_data.get_column_type_name(i)
105
- end
106
- end
107
-
108
- # :nodoc:
109
- def bind_out_parameter(obj, index, type)
110
- internal_type = RUBY_TO_JDBC_TYPES[type] || OracleTypes::VARCHAR
111
- obj.register_out_parameter(index, internal_type)
112
- end
113
-
114
- def bind_date(obj, v, i)
115
- if v
116
- # %Q is micro seconds since epoch. Divide by 1000 to get milli-sec
117
- jdbc_date = Java::JavaSql::Date.new(v.strftime("%s").to_f * 1000)
118
- obj.set_date(i, jdbc_date)
119
- else
120
- obj.set_null(i, OracleTypes::DATE)
121
- end
122
- end
123
-
124
- def bind_time(obj, v, i)
125
- if v
126
- # Need to use an Oracle TIMESTAMP - dates don't allow a time to be specified
127
- # for some reason, even though a date in Oracle contains a time.
128
- jdbc_time = TIMESTAMP.new(Java::JavaSql::Timestamp.new(v.to_f * 1000))
129
- obj.setTIMESTAMP(i, jdbc_time)
130
- else
131
- obj.set_null(i, OracleTypes::TIMESTAMP)
132
- end
133
- end
134
-
135
- def bind_string(obj, v, i)
136
- if v
137
- obj.set_string(i, v)
138
- else
139
- obj.set_null(i, OracleTypes::VARCHAR)
140
- end
141
- end
142
-
143
- def bind_int(obj, v, i)
144
- if v
145
- obj.set_int(i, v)
146
- else
147
- obj.set_null(i, OracleTypes::INTEGER)
148
- end
149
- end
150
-
151
- def bind_number(obj, v, i)
152
- if v
153
- obj.set_number(i, Java::OracleSql::NUMBER.new(v))
154
- else
155
- obj.set_null(i, OracleTypes::NUMBER)
156
- end
157
- end
158
-
159
- def bind_refcursor(obj, v, i)
160
- if v
161
- raise "not implemented"
162
- end
163
- end
164
-
165
- def retrieve_date(obj, i)
166
- jdate = obj.get_date(i)
167
- if jdate
168
- rt = Time.at(jdate.date_value.get_time.to_f / 1000)
169
- Date.new(rt.year, rt.month, rt.day)
170
- else
171
- nil
172
- end
173
- end
174
-
175
- def retrieve_time(obj, i)
176
- jdate = obj.get_timestamp(i)
177
- if jdate
178
- Time.at(jdate.get_time.to_f / 1000)
179
- else
180
- nil
181
- end
182
- end
183
-
184
- def retrieve_string(obj, i)
185
- obj.get_string(i)
186
- end
187
-
188
- def retrieve_int(obj, i)
189
- v = obj.get_int(i)
190
- if obj.was_null
191
- nil
192
- else
193
- v
194
- end
195
- end
196
-
197
- def retrieve_number(obj, i)
198
- v = obj.get_number(i)
199
- if v
200
- v.double_value
201
- else
202
- nil
203
- end
204
- end
205
-
206
- def retrieve_refcursor(obj, i)
207
- rset = obj.get_object(i)
208
- results = Sql.new
209
- results.result_set = rset
210
- results
211
- end
212
-
213
- end
214
- end