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 +3 -2
- data/lib/simple_oracle_jdbc/bindings.rb +27 -2
- data/lib/simple_oracle_jdbc/db_call.rb +2 -0
- data/lib/simple_oracle_jdbc/result_set.rb +3 -2
- data/lib/simple_oracle_jdbc/sql.rb +17 -1
- data/test/binding_test.rb +31 -0
- metadata +2 -4
- data/lib/simple_oracle_jdbc/#bindings.rb# +0 -214
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
|
-
|
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
|
-
|
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.
|
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-
|
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
|