simpleOracleJDBC 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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