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 +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
|