ruby-plsql 0.2.2 → 0.2.3
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/History.txt +8 -0
- data/README.txt +2 -2
- data/lib/plsql/connection.rb +0 -421
- data/lib/plsql/jdbc_connection.rb +302 -0
- data/lib/plsql/oci_connection.rb +165 -0
- data/lib/plsql/procedure.rb +3 -0
- data/lib/ruby_plsql.rb +2 -2
- data/lib/ruby_plsql/version.rb +1 -1
- data/spec/plsql/procedure_spec.rb +102 -3
- data/spec/spec_helper.rb +14 -2
- metadata +15 -24
- data/Manifest.txt +0 -33
- data/Rakefile +0 -4
- data/config/hoe.rb +0 -70
- data/config/requirements.rb +0 -17
- data/log/debug.log +0 -0
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -74
- data/setup.rb +0 -1585
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/rspec.rake +0 -21
- data/tasks/website.rake +0 -17
- data/website/index.html +0 -112
- data/website/index.txt +0 -53
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -138
- data/website/template.rhtml +0 -48
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.2.3 2008-10-17
|
2
|
+
* Improvements
|
3
|
+
* Added CLOB data type support for input and output parameters and function return values
|
4
|
+
(both for MRI/OCI and JRuby/JDBC)
|
5
|
+
(ruby-oci8 version should be at least 1.0.3 as it contains CLOB handling bug fixes)
|
6
|
+
* Bug fixes
|
7
|
+
* Fixed calling of procedures without parameters
|
8
|
+
|
1
9
|
== 0.2.2 2008-08-20
|
2
10
|
* Bug fixes
|
3
11
|
* Workaround for strange Oracle data dictionary bug when procedure with no parameters has row with empty fields in all_arguments
|
data/README.txt
CHANGED
@@ -14,7 +14,7 @@ Look ar RSpec tests under spec directory for usage examples.
|
|
14
14
|
|
15
15
|
== FEATURES/PROBLEMS:
|
16
16
|
|
17
|
-
* Currently just NUMBER, VARCHAR2, DATE, TIMESTAMP argument types are supported for PL/SQL procedures
|
17
|
+
* Currently just NUMBER, VARCHAR2, DATE, TIMESTAMP, CLOB argument types are supported for PL/SQL procedures
|
18
18
|
|
19
19
|
== SYNOPSIS:
|
20
20
|
|
@@ -37,7 +37,7 @@ plsql.logoff
|
|
37
37
|
== REQUIREMENTS:
|
38
38
|
|
39
39
|
MRI
|
40
|
-
* Requires ruby-oci8 library to connect to Oracle
|
40
|
+
* Requires ruby-oci8 library to connect to Oracle (please use version 1.0.3 or later)
|
41
41
|
JRuby
|
42
42
|
* Requires Oracle JDBC driver (ojdbc14.jar should be somewhere in PATH) to connect to Oracle
|
43
43
|
|
data/lib/plsql/connection.rb
CHANGED
@@ -63,426 +63,5 @@ module PLSQL
|
|
63
63
|
end
|
64
64
|
|
65
65
|
end
|
66
|
-
|
67
|
-
class OCIConnection < Connection
|
68
|
-
|
69
|
-
def logoff
|
70
|
-
raw_connection.logoff
|
71
|
-
end
|
72
|
-
|
73
|
-
def commit
|
74
|
-
raw_connection.commit
|
75
|
-
end
|
76
|
-
|
77
|
-
def rollback
|
78
|
-
raw_connection.rollback
|
79
|
-
end
|
80
|
-
|
81
|
-
def autocommit?
|
82
|
-
raw_connection.autocommit?
|
83
|
-
end
|
84
|
-
|
85
|
-
def autocommit=(value)
|
86
|
-
raw_connection.autocommit = value
|
87
|
-
end
|
88
|
-
|
89
|
-
def select_first(sql, *bindvars)
|
90
|
-
cursor = raw_connection.exec(sql, *bindvars)
|
91
|
-
result = cursor.fetch
|
92
|
-
if result
|
93
|
-
result.map { |val| ora_value_to_ruby_value(val) }
|
94
|
-
else
|
95
|
-
nil
|
96
|
-
end
|
97
|
-
ensure
|
98
|
-
cursor.close rescue nil
|
99
|
-
end
|
100
|
-
|
101
|
-
def select_all(sql, *bindvars, &block)
|
102
|
-
cursor = raw_connection.exec(sql, *bindvars)
|
103
|
-
results = []
|
104
|
-
row_count = 0
|
105
|
-
while row = cursor.fetch
|
106
|
-
row_with_typecast = row.map {|val| ora_value_to_ruby_value(val) }
|
107
|
-
if block_given?
|
108
|
-
yield(row_with_typecast)
|
109
|
-
row_count += 1
|
110
|
-
else
|
111
|
-
results << row_with_typecast
|
112
|
-
end
|
113
|
-
end
|
114
|
-
block_given? ? row_count : results
|
115
|
-
ensure
|
116
|
-
cursor.close rescue nil
|
117
|
-
end
|
118
|
-
|
119
|
-
def exec(sql, *bindvars)
|
120
|
-
raw_connection.exec(sql, *bindvars)
|
121
|
-
end
|
122
|
-
|
123
|
-
class Cursor
|
124
|
-
attr_accessor :raw_cursor
|
125
|
-
|
126
|
-
def initialize(raw_cur)
|
127
|
-
@raw_cursor = raw_cur
|
128
|
-
end
|
129
|
-
|
130
|
-
def bind_param(key, value, type=nil, length=nil, in_out='IN')
|
131
|
-
raw_cursor.bind_param(key, value, type, length)
|
132
|
-
end
|
133
|
-
|
134
|
-
def exec(*bindvars)
|
135
|
-
raw_cursor.exec(*bindvars)
|
136
|
-
end
|
137
|
-
|
138
|
-
def [](key)
|
139
|
-
raw_cursor[key]
|
140
|
-
end
|
141
|
-
|
142
|
-
def close
|
143
|
-
raw_cursor.close
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def parse(sql)
|
148
|
-
Cursor.new(raw_connection.parse(sql))
|
149
|
-
end
|
150
|
-
|
151
|
-
|
152
|
-
def plsql_to_ruby_data_type(data_type, data_length)
|
153
|
-
case data_type
|
154
|
-
when "VARCHAR2"
|
155
|
-
[String, data_length || 4000]
|
156
|
-
when "NUMBER"
|
157
|
-
[OraNumber, nil]
|
158
|
-
when "DATE"
|
159
|
-
[DateTime, nil]
|
160
|
-
when "TIMESTAMP"
|
161
|
-
[Time, nil]
|
162
|
-
# CLOB
|
163
|
-
# BLOB
|
164
|
-
else
|
165
|
-
[String, 4000]
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
def ruby_value_to_ora_value(val, type)
|
170
|
-
if type == OraNumber
|
171
|
-
val.nil? || val.is_a?(Fixnum) ? val : val.to_f
|
172
|
-
elsif type == DateTime
|
173
|
-
val ? val.to_datetime : nil
|
174
|
-
else
|
175
|
-
val
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
def ora_value_to_ruby_value(val)
|
180
|
-
case val
|
181
|
-
when Float, OraNumber
|
182
|
-
ora_number_to_ruby_number(val)
|
183
|
-
when DateTime, OraDate
|
184
|
-
ora_date_to_ruby_date(val)
|
185
|
-
else
|
186
|
-
val
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
|
191
|
-
private
|
192
|
-
|
193
|
-
def ora_number_to_ruby_number(num)
|
194
|
-
num.to_i == num.to_f ? num.to_i : num.to_f
|
195
|
-
end
|
196
|
-
|
197
|
-
def ora_date_to_ruby_date(val)
|
198
|
-
case val
|
199
|
-
when DateTime
|
200
|
-
Time.parse(val.strftime("%c")) rescue val
|
201
|
-
when OraDate
|
202
|
-
val.to_time rescue val.to_datetime
|
203
|
-
else
|
204
|
-
val
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
end
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
class JDBCConnection < Connection
|
213
|
-
def logoff
|
214
|
-
raw_connection.close
|
215
|
-
true
|
216
|
-
rescue
|
217
|
-
false
|
218
|
-
end
|
219
|
-
|
220
|
-
def commit
|
221
|
-
raw_connection.commit
|
222
|
-
end
|
223
|
-
|
224
|
-
def rollback
|
225
|
-
raw_connection.rollback
|
226
|
-
end
|
227
|
-
|
228
|
-
def autocommit?
|
229
|
-
raw_connection.getAutoCommit
|
230
|
-
end
|
231
|
-
|
232
|
-
def autocommit=(value)
|
233
|
-
raw_connection.setAutoCommit(value)
|
234
|
-
end
|
235
|
-
|
236
|
-
def select_first(sql, *bindvars)
|
237
|
-
stmt = prepare_statement(sql, *bindvars)
|
238
|
-
rset = stmt.executeQuery
|
239
|
-
metadata = rset.getMetaData
|
240
|
-
column_count = metadata.getColumnCount
|
241
|
-
if rset.next
|
242
|
-
(1..column_count).map do |i|
|
243
|
-
get_ruby_value_from_result_set(rset,i,metadata.getColumnTypeName(i))
|
244
|
-
end
|
245
|
-
else
|
246
|
-
nil
|
247
|
-
end
|
248
|
-
ensure
|
249
|
-
rset.close rescue nil
|
250
|
-
stmt.close rescue nil
|
251
|
-
end
|
252
|
-
|
253
|
-
def select_all(sql, *bindvars, &block)
|
254
|
-
stmt = prepare_statement(sql, *bindvars)
|
255
|
-
results = []
|
256
|
-
row_count = 0
|
257
|
-
rset = stmt.executeQuery
|
258
|
-
metadata = rset.getMetaData
|
259
|
-
column_count = metadata.getColumnCount
|
260
|
-
while rset.next
|
261
|
-
row_with_typecast = (1..column_count).map do |i|
|
262
|
-
get_ruby_value_from_result_set(rset,i,metadata.getColumnTypeName(i))
|
263
|
-
end
|
264
|
-
if block_given?
|
265
|
-
yield(row_with_typecast)
|
266
|
-
row_count += 1
|
267
|
-
else
|
268
|
-
results << row_with_typecast
|
269
|
-
end
|
270
|
-
end
|
271
|
-
block_given? ? row_count : results
|
272
|
-
ensure
|
273
|
-
rset.close rescue nil
|
274
|
-
stmt.close rescue nil
|
275
|
-
end
|
276
|
-
|
277
|
-
def exec(sql, *bindvars)
|
278
|
-
cs = prepare_call(sql, *bindvars)
|
279
|
-
cs.execute
|
280
|
-
true
|
281
|
-
ensure
|
282
|
-
cs.close rescue nil
|
283
|
-
end
|
284
|
-
|
285
|
-
class Cursor
|
286
|
-
|
287
|
-
def initialize(sql, conn)
|
288
|
-
@sql = sql
|
289
|
-
@connection = conn
|
290
|
-
@params = sql.scan(/\:\w+/)
|
291
|
-
@out_types = {}
|
292
|
-
@out_index = {}
|
293
|
-
@statement = @connection.prepare_call(sql)
|
294
|
-
end
|
295
|
-
|
296
|
-
def bind_param(key, value, type=nil, length=nil, in_out='IN')
|
297
|
-
@connection.set_bind_variable(@statement, key, value, type, length)
|
298
|
-
if in_out =~ /OUT/
|
299
|
-
@out_types[key] = type || value.class
|
300
|
-
@out_index[key] = bind_param_index(key)
|
301
|
-
@statement.registerOutParameter(@out_index[key],@connection.get_java_sql_type(value,type))
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
def exec
|
306
|
-
@statement.execute
|
307
|
-
end
|
308
|
-
|
309
|
-
def [](key)
|
310
|
-
@connection.get_bind_variable(@statement, @out_index[key], @out_types[key])
|
311
|
-
end
|
312
|
-
|
313
|
-
def close
|
314
|
-
@statement.close
|
315
|
-
end
|
316
|
-
|
317
|
-
private
|
318
|
-
|
319
|
-
def bind_param_index(key)
|
320
|
-
return key if key.kind_of? Integer
|
321
|
-
key = ":#{key.to_s}" unless key.to_s =~ /^:/
|
322
|
-
@params.index(key)+1
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
def parse(sql)
|
327
|
-
Cursor.new(sql, self)
|
328
|
-
end
|
329
|
-
|
330
|
-
def prepare_statement(sql, *bindvars)
|
331
|
-
stmt = raw_connection.prepareStatement(sql)
|
332
|
-
bindvars.each_with_index do |bv, i|
|
333
|
-
set_bind_variable(stmt, i+1, bv)
|
334
|
-
end
|
335
|
-
stmt
|
336
|
-
end
|
337
|
-
|
338
|
-
def prepare_call(sql, *bindvars)
|
339
|
-
stmt = raw_connection.prepareCall(sql)
|
340
|
-
bindvars.each_with_index do |bv, i|
|
341
|
-
set_bind_variable(stmt, i+1, bv)
|
342
|
-
end
|
343
|
-
stmt
|
344
|
-
end
|
345
|
-
|
346
|
-
def get_java_sql_type(value, type)
|
347
|
-
case type ? type.to_s : value.class.to_s
|
348
|
-
when 'Fixnum', 'Bignum', 'Integer'
|
349
|
-
java.sql.Types::INTEGER
|
350
|
-
when 'Float'
|
351
|
-
java.sql.Types::FLOAT
|
352
|
-
when 'BigDecimal'
|
353
|
-
java.sql.Types::NUMERIC
|
354
|
-
when 'String'
|
355
|
-
java.sql.Types::VARCHAR
|
356
|
-
when 'Date'
|
357
|
-
java.sql.Types::DATE
|
358
|
-
when 'Time'
|
359
|
-
java.sql.Types::DATE
|
360
|
-
when 'DateTime'
|
361
|
-
java.sql.Types::DATE
|
362
|
-
else
|
363
|
-
java.sql.Types::VARCHAR
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
def set_bind_variable(stmt, i, value, type=nil, length=nil)
|
368
|
-
key = i.kind_of?(Integer) ? nil : i.to_s.gsub(':','')
|
369
|
-
case !value.nil? && type ? type.to_s : value.class.to_s
|
370
|
-
when 'Fixnum', 'Bignum', 'Integer'
|
371
|
-
stmt.send("setInt#{key && "AtName"}", key || i, value)
|
372
|
-
when 'Float'
|
373
|
-
stmt.send("setFloat#{key && "AtName"}", key || i, value)
|
374
|
-
when 'BigDecimal'
|
375
|
-
stmt.send("setBigDecimal#{key && "AtName"}", key || i, java.math.BigDecimal.new(value.to_s))
|
376
|
-
when 'String'
|
377
|
-
stmt.send("setString#{key && "AtName"}", key || i, value)
|
378
|
-
when 'Date'
|
379
|
-
stmt.send("setDate#{key && "AtName"}", key || i, java.sql.Date.new(Time.parse(value.to_s).to_i*1000))
|
380
|
-
when 'Time'
|
381
|
-
stmt.send("setTime#{key && "AtName"}", key || i, java.sql.Time.new(value.to_i*1000))
|
382
|
-
when 'DateTime'
|
383
|
-
stmt.send("setTime#{key && "AtName"}", key || i, java.sql.Time.new(Time.parse(value.strftime("%c")).to_i*1000))
|
384
|
-
when 'NilClass'
|
385
|
-
stmt.send("setNull#{key && "AtName"}", key || i, get_java_sql_type(value, type))
|
386
|
-
end
|
387
|
-
end
|
388
|
-
|
389
|
-
def get_bind_variable(stmt, i, type)
|
390
|
-
case type.to_s
|
391
|
-
when 'Fixnum', 'Bignum', 'Integer'
|
392
|
-
stmt.getInt(i)
|
393
|
-
when 'Float'
|
394
|
-
stmt.getFloat(i)
|
395
|
-
when 'BigDecimal'
|
396
|
-
bd = stmt.getBigDecimal(i)
|
397
|
-
bd && BigDecimal.new(bd.to_s)
|
398
|
-
when 'String'
|
399
|
-
stmt.getString(i)
|
400
|
-
when 'Date','Time','DateTime'
|
401
|
-
ts = stmt.getTimestamp(i)
|
402
|
-
# ts && Time.parse(Time.at(ts.getTime/1000).iso8601)
|
403
|
-
ts && Time.local(1900+ts.year, ts.month+1, ts.date, ts.hours, ts.minutes, ts.seconds)
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
def get_ruby_value_from_result_set(rset, i, type_name)
|
408
|
-
case type_name
|
409
|
-
when "CHAR", "VARCHAR2"
|
410
|
-
rset.getString(i)
|
411
|
-
when "NUMBER"
|
412
|
-
d = rset.getBigDecimal(i)
|
413
|
-
if d.nil?
|
414
|
-
nil
|
415
|
-
elsif d.scale == 0
|
416
|
-
d.longValue
|
417
|
-
else
|
418
|
-
d.doubleValue
|
419
|
-
end
|
420
|
-
when "DATE", "TIMESTAMP"
|
421
|
-
Time.at(rset.getTimestamp(i).getTime/1000)
|
422
|
-
else
|
423
|
-
nil
|
424
|
-
end
|
425
|
-
end
|
426
|
-
|
427
|
-
def plsql_to_ruby_data_type(data_type, data_length)
|
428
|
-
case data_type
|
429
|
-
when "VARCHAR2"
|
430
|
-
[String, data_length || 4000]
|
431
|
-
when "NUMBER"
|
432
|
-
[BigDecimal, nil]
|
433
|
-
when "DATE"
|
434
|
-
[Time, nil]
|
435
|
-
when "TIMESTAMP"
|
436
|
-
[Time, nil]
|
437
|
-
# CLOB
|
438
|
-
# BLOB
|
439
|
-
else
|
440
|
-
[String, 4000]
|
441
|
-
end
|
442
|
-
end
|
443
|
-
|
444
|
-
def ruby_value_to_ora_value(val, type)
|
445
|
-
if type == BigDecimal
|
446
|
-
val.nil? || val.is_a?(Fixnum) ? val : val.to_f
|
447
|
-
elsif type == Time
|
448
|
-
date_to_time(val)
|
449
|
-
else
|
450
|
-
val
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
|
-
def ora_value_to_ruby_value(val)
|
455
|
-
case val
|
456
|
-
when Float, BigDecimal
|
457
|
-
ora_number_to_ruby_number(val)
|
458
|
-
# when OraDate
|
459
|
-
# ora_date_to_ruby_date(val)
|
460
|
-
else
|
461
|
-
val
|
462
|
-
end
|
463
|
-
end
|
464
|
-
|
465
|
-
private
|
466
|
-
|
467
|
-
def ora_number_to_ruby_number(num)
|
468
|
-
num.to_i == num.to_f ? num.to_i : num.to_f
|
469
|
-
end
|
470
|
-
|
471
|
-
# def ora_date_to_ruby_date(val)
|
472
|
-
# val.to_time
|
473
|
-
# end
|
474
|
-
|
475
|
-
def date_to_time(val)
|
476
|
-
case val
|
477
|
-
when Time
|
478
|
-
val
|
479
|
-
when DateTime
|
480
|
-
Time.parse(val.strftime("%c"))
|
481
|
-
when Date
|
482
|
-
Time.parse(val.strftime("%c"))
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
|
-
end
|
487
66
|
|
488
67
|
end
|