ruby-plsql 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,13 @@
1
+ == 0.2.0 2008-06-26
2
+
3
+ * New features
4
+ * Added JRuby and Oracle JDBC driver support with the same functionality as in case of MRI and ruby-oci8 driver
5
+ * All database driver specifics are extracted in separate Connection class with OCIConnection and JDBCConnection subclasses
6
+ * Improvements
7
+ * PL/SQL functions/procedures with DATE return values and output parameters returns Time values by default (previously DateTime values
8
+ were returned by default). If value is too old then DateTime value is returned. From Ruby Time, DateTime and Date values can be
9
+ passed as arguments to DATE parameters.
10
+
1
11
  == 0.1.6 2008-06-16
2
12
 
3
13
  * Improvements
data/Manifest.txt CHANGED
@@ -5,6 +5,8 @@ README.txt
5
5
  Rakefile
6
6
  config/hoe.rb
7
7
  config/requirements.rb
8
+ lib/oradate_patch.rb
9
+ lib/plsql/connection.rb
8
10
  lib/plsql/package.rb
9
11
  lib/plsql/procedure.rb
10
12
  lib/plsql/schema.rb
@@ -0,0 +1,10 @@
1
+ class OraDate
2
+ if defined? DateTime # ruby 1.8.0 or upper
3
+ # RSI: create DateTime in local timezone
4
+ def to_datetime
5
+ DateTime.parse(Time.local(year, month, day, hour, minute, second).iso8601)
6
+ rescue
7
+ DateTime.new(year, month, day, hour, minute, second)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,440 @@
1
+ module PLSQL
2
+ class Connection
3
+ attr_reader :raw_connection
4
+ attr_reader :raw_driver
5
+
6
+ def initialize(raw_drv, raw_conn)
7
+ @raw_driver = raw_drv
8
+ @raw_connection = raw_conn
9
+ end
10
+
11
+ def self.create(raw_conn)
12
+ if !raw_conn.respond_to?(:java_class) && defined?(OCI8)
13
+ OCIConnection.new(:oci, raw_conn)
14
+ elsif raw_conn.respond_to?(:java_class) && raw_conn.java_class.to_s =~ /jdbc/
15
+ JDBCConnection.new(:jdbc, raw_conn)
16
+ else
17
+ raise ArgumentError, "Unknown raw driver"
18
+ end
19
+ end
20
+
21
+ def oci?
22
+ @raw_driver == :oci
23
+ end
24
+
25
+ def jdbc?
26
+ @raw_driver == :jdbc
27
+ end
28
+
29
+ def logoff
30
+ raise NoMethodError, "Not implemented for this raw driver"
31
+ end
32
+
33
+ def select_first(sql, *bindvars)
34
+ raise NoMethodError, "Not implemented for this raw driver"
35
+ end
36
+
37
+ def select_all(sql, *bindvars, &block)
38
+ raise NoMethodError, "Not implemented for this raw driver"
39
+ end
40
+
41
+ def exec(sql, *bindvars)
42
+ raise NoMethodError, "Not implemented for this raw driver"
43
+ end
44
+
45
+ def parse(sql)
46
+ raise NoMethodError, "Not implemented for this raw driver"
47
+ end
48
+
49
+ end
50
+
51
+ class OCIConnection < Connection
52
+
53
+ def logoff
54
+ raw_connection.logoff
55
+ end
56
+
57
+ def select_first(sql, *bindvars)
58
+ cursor = raw_connection.exec(sql, *bindvars)
59
+ result = cursor.fetch
60
+ if result
61
+ result.map { |val| ora_value_to_ruby_value(val) }
62
+ else
63
+ nil
64
+ end
65
+ ensure
66
+ cursor.close rescue nil
67
+ end
68
+
69
+ def select_all(sql, *bindvars, &block)
70
+ cursor = raw_connection.exec(sql, *bindvars)
71
+ results = []
72
+ row_count = 0
73
+ while row = cursor.fetch
74
+ row_with_typecast = row.map {|val| ora_value_to_ruby_value(val) }
75
+ if block_given?
76
+ yield(row_with_typecast)
77
+ row_count += 1
78
+ else
79
+ results << row_with_typecast
80
+ end
81
+ end
82
+ block_given? ? row_count : results
83
+ ensure
84
+ cursor.close rescue nil
85
+ end
86
+
87
+ def exec(sql, *bindvars)
88
+ raw_connection.exec(sql, *bindvars)
89
+ end
90
+
91
+ class Cursor
92
+ attr_accessor :raw_cursor
93
+
94
+ def initialize(raw_cur)
95
+ @raw_cursor = raw_cur
96
+ end
97
+
98
+ def bind_param(key, value, type=nil, length=nil, in_out='IN')
99
+ raw_cursor.bind_param(key, value, type, length)
100
+ end
101
+
102
+ def exec(*bindvars)
103
+ raw_cursor.exec(*bindvars)
104
+ end
105
+
106
+ def [](key)
107
+ raw_cursor[key]
108
+ end
109
+
110
+ def close
111
+ raw_cursor.close
112
+ end
113
+ end
114
+
115
+ def parse(sql)
116
+ Cursor.new(raw_connection.parse(sql))
117
+ end
118
+
119
+
120
+ def plsql_to_ruby_data_type(data_type, data_length)
121
+ case data_type
122
+ when "VARCHAR2"
123
+ [String, data_length || 4000]
124
+ when "NUMBER"
125
+ [OraNumber, nil]
126
+ when "DATE"
127
+ [DateTime, nil]
128
+ when "TIMESTAMP"
129
+ [Time, nil]
130
+ # CLOB
131
+ # BLOB
132
+ else
133
+ [String, 4000]
134
+ end
135
+ end
136
+
137
+ def ruby_value_to_ora_value(val, type)
138
+ if type == OraNumber
139
+ val.nil? || val.is_a?(Fixnum) ? val : val.to_f
140
+ elsif type == DateTime
141
+ val ? val.to_datetime : nil
142
+ else
143
+ val
144
+ end
145
+ end
146
+
147
+ def ora_value_to_ruby_value(val)
148
+ case val
149
+ when Float, OraNumber
150
+ ora_number_to_ruby_number(val)
151
+ when DateTime, OraDate
152
+ ora_date_to_ruby_date(val)
153
+ else
154
+ val
155
+ end
156
+ end
157
+
158
+
159
+ private
160
+
161
+ def ora_number_to_ruby_number(num)
162
+ num.to_i == num.to_f ? num.to_i : num.to_f
163
+ end
164
+
165
+ def ora_date_to_ruby_date(val)
166
+ case val
167
+ when DateTime
168
+ Time.parse(val.strftime("%c")) rescue val
169
+ when OraDate
170
+ val.to_time rescue val.to_datetime
171
+ else
172
+ val
173
+ end
174
+ end
175
+
176
+ end
177
+
178
+
179
+
180
+ class JDBCConnection < Connection
181
+ def logoff
182
+ raw_connection.close
183
+ true
184
+ rescue
185
+ false
186
+ end
187
+
188
+ def select_first(sql, *bindvars)
189
+ stmt = prepare_statement(sql, *bindvars)
190
+ rset = stmt.executeQuery
191
+ metadata = rset.getMetaData
192
+ column_count = metadata.getColumnCount
193
+ if rset.next
194
+ (1..column_count).map do |i|
195
+ get_ruby_value_from_result_set(rset,i,metadata.getColumnTypeName(i))
196
+ end
197
+ else
198
+ nil
199
+ end
200
+ ensure
201
+ rset.close rescue nil
202
+ stmt.close rescue nil
203
+ end
204
+
205
+ def select_all(sql, *bindvars, &block)
206
+ stmt = prepare_statement(sql, *bindvars)
207
+ results = []
208
+ row_count = 0
209
+ rset = stmt.executeQuery
210
+ metadata = rset.getMetaData
211
+ column_count = metadata.getColumnCount
212
+ while rset.next
213
+ row_with_typecast = (1..column_count).map do |i|
214
+ get_ruby_value_from_result_set(rset,i,metadata.getColumnTypeName(i))
215
+ end
216
+ if block_given?
217
+ yield(row_with_typecast)
218
+ row_count += 1
219
+ else
220
+ results << row_with_typecast
221
+ end
222
+ end
223
+ block_given? ? row_count : results
224
+ ensure
225
+ rset.close rescue nil
226
+ stmt.close rescue nil
227
+ end
228
+
229
+ def exec(sql, *bindvars)
230
+ cs = prepare_call(sql, *bindvars)
231
+ cs.execute
232
+ true
233
+ ensure
234
+ cs.close rescue nil
235
+ end
236
+
237
+ class Cursor
238
+
239
+ def initialize(sql, conn)
240
+ @sql = sql
241
+ @connection = conn
242
+ @params = sql.scan(/\:\w+/)
243
+ @out_types = {}
244
+ @out_index = {}
245
+ @statement = @connection.prepare_call(sql)
246
+ end
247
+
248
+ def bind_param(key, value, type=nil, length=nil, in_out='IN')
249
+ @connection.set_bind_variable(@statement, key, value, type, length)
250
+ if in_out =~ /OUT/
251
+ @out_types[key] = type || value.class
252
+ @out_index[key] = bind_param_index(key)
253
+ @statement.registerOutParameter(@out_index[key],@connection.get_java_sql_type(value,type))
254
+ end
255
+ end
256
+
257
+ def exec
258
+ @statement.execute
259
+ end
260
+
261
+ def [](key)
262
+ @connection.get_bind_variable(@statement, @out_index[key], @out_types[key])
263
+ end
264
+
265
+ def close
266
+ @statement.close
267
+ end
268
+
269
+ private
270
+
271
+ def bind_param_index(key)
272
+ return key if key.kind_of? Integer
273
+ key = ":#{key.to_s}" unless key.to_s =~ /^:/
274
+ @params.index(key)+1
275
+ end
276
+ end
277
+
278
+ def parse(sql)
279
+ Cursor.new(sql, self)
280
+ end
281
+
282
+ def prepare_statement(sql, *bindvars)
283
+ stmt = raw_connection.prepareStatement(sql)
284
+ bindvars.each_with_index do |bv, i|
285
+ set_bind_variable(stmt, i+1, bv)
286
+ end
287
+ stmt
288
+ end
289
+
290
+ def prepare_call(sql, *bindvars)
291
+ stmt = raw_connection.prepareCall(sql)
292
+ bindvars.each_with_index do |bv, i|
293
+ set_bind_variable(stmt, i+1, bv)
294
+ end
295
+ stmt
296
+ end
297
+
298
+ def get_java_sql_type(value, type)
299
+ case type ? type.to_s : value.class.to_s
300
+ when 'Fixnum', 'Bignum', 'Integer'
301
+ java.sql.Types::INTEGER
302
+ when 'Float'
303
+ java.sql.Types::FLOAT
304
+ when 'BigDecimal'
305
+ java.sql.Types::NUMERIC
306
+ when 'String'
307
+ java.sql.Types::VARCHAR
308
+ when 'Date'
309
+ java.sql.Types::DATE
310
+ when 'Time'
311
+ java.sql.Types::DATE
312
+ when 'DateTime'
313
+ java.sql.Types::DATE
314
+ else
315
+ java.sql.Types::VARCHAR
316
+ end
317
+ end
318
+
319
+ def set_bind_variable(stmt, i, value, type=nil, length=nil)
320
+ key = i.kind_of?(Integer) ? nil : i.to_s.gsub(':','')
321
+ case !value.nil? && type ? type.to_s : value.class.to_s
322
+ when 'Fixnum', 'Bignum', 'Integer'
323
+ stmt.send("setInt#{key && "AtName"}", key || i, value)
324
+ when 'Float'
325
+ stmt.send("setFloat#{key && "AtName"}", key || i, value)
326
+ when 'BigDecimal'
327
+ stmt.send("setBigDecimal#{key && "AtName"}", key || i, java.math.BigDecimal.new(value.to_s))
328
+ when 'String'
329
+ stmt.send("setString#{key && "AtName"}", key || i, value)
330
+ when 'Date'
331
+ stmt.send("setDate#{key && "AtName"}", key || i, java.sql.Date.new(Time.parse(value.to_s).to_i*1000))
332
+ when 'Time'
333
+ stmt.send("setTime#{key && "AtName"}", key || i, java.sql.Time.new(value.to_i*1000))
334
+ when 'DateTime'
335
+ stmt.send("setTime#{key && "AtName"}", key || i, java.sql.Time.new(Time.parse(value.strftime("%c")).to_i*1000))
336
+ when 'NilClass'
337
+ stmt.send("setNull#{key && "AtName"}", key || i, get_java_sql_type(value, type))
338
+ end
339
+ end
340
+
341
+ def get_bind_variable(stmt, i, type)
342
+ case type.to_s
343
+ when 'Fixnum', 'Bignum', 'Integer'
344
+ stmt.getInt(i)
345
+ when 'Float'
346
+ stmt.getFloat(i)
347
+ when 'BigDecimal'
348
+ bd = stmt.getBigDecimal(i)
349
+ bd && BigDecimal.new(bd.to_s)
350
+ when 'String'
351
+ stmt.getString(i)
352
+ when 'Date','Time','DateTime'
353
+ ts = stmt.getTimestamp(i)
354
+ # ts && Time.parse(Time.at(ts.getTime/1000).iso8601)
355
+ ts && Time.local(1900+ts.year, ts.month+1, ts.date, ts.hours, ts.minutes, ts.seconds)
356
+ end
357
+ end
358
+
359
+ def get_ruby_value_from_result_set(rset, i, type_name)
360
+ case type_name
361
+ when "CHAR", "VARCHAR2"
362
+ rset.getString(i)
363
+ when "NUMBER"
364
+ d = rset.getBigDecimal(i)
365
+ if d.nil?
366
+ nil
367
+ elsif d.scale == 0
368
+ d.longValue
369
+ else
370
+ d.doubleValue
371
+ end
372
+ when "DATE", "TIMESTAMP"
373
+ Time.at(rset.getTimestamp(i).getTime/1000)
374
+ else
375
+ nil
376
+ end
377
+ end
378
+
379
+ def plsql_to_ruby_data_type(data_type, data_length)
380
+ case data_type
381
+ when "VARCHAR2"
382
+ [String, data_length || 4000]
383
+ when "NUMBER"
384
+ [BigDecimal, nil]
385
+ when "DATE"
386
+ [Time, nil]
387
+ when "TIMESTAMP"
388
+ [Time, nil]
389
+ # CLOB
390
+ # BLOB
391
+ else
392
+ [String, 4000]
393
+ end
394
+ end
395
+
396
+ def ruby_value_to_ora_value(val, type)
397
+ if type == BigDecimal
398
+ val.nil? || val.is_a?(Fixnum) ? val : val.to_f
399
+ elsif type == Time
400
+ date_to_time(val)
401
+ else
402
+ val
403
+ end
404
+ end
405
+
406
+ def ora_value_to_ruby_value(val)
407
+ case val
408
+ when Float, BigDecimal
409
+ ora_number_to_ruby_number(val)
410
+ # when OraDate
411
+ # ora_date_to_ruby_date(val)
412
+ else
413
+ val
414
+ end
415
+ end
416
+
417
+ private
418
+
419
+ def ora_number_to_ruby_number(num)
420
+ num.to_i == num.to_f ? num.to_i : num.to_f
421
+ end
422
+
423
+ # def ora_date_to_ruby_date(val)
424
+ # val.to_time
425
+ # end
426
+
427
+ def date_to_time(val)
428
+ case val
429
+ when Time
430
+ val
431
+ when DateTime
432
+ Time.parse(val.strftime("%c"))
433
+ when Date
434
+ Time.parse(val.strftime("%c"))
435
+ end
436
+ end
437
+
438
+ end
439
+
440
+ end
@@ -34,7 +34,7 @@ module PLSQL
34
34
  @out_list = {}
35
35
  @return = {}
36
36
  @overloaded = false
37
- num_rows = @schema.connection.exec("
37
+ num_rows = @schema.connection.select_all("
38
38
  SELECT a.argument_name, a.position, a.data_type, a.in_out, a.data_length, a.data_precision, a.data_scale, a.overload
39
39
  FROM all_arguments a, all_objects o
40
40
  WHERE o.owner = :owner
@@ -76,7 +76,7 @@ module PLSQL
76
76
  @overloads = @arguments.keys.sort
77
77
  @overloads.each do |overload|
78
78
  @argument_list[overload] = @arguments[overload].keys.sort {|k1, k2| @arguments[overload][k1][:position] <=> @arguments[overload][k2][:position]}
79
- @out_list[overload] = @argument_list[overload].select {|k| @arguments[overload][k][:in_out] == 'OUT'}
79
+ @out_list[overload] = @argument_list[overload].select {|k| @arguments[overload][k][:in_out] =~ /OUT/}
80
80
  end
81
81
  end
82
82
 
@@ -145,12 +145,13 @@ module PLSQL
145
145
 
146
146
  args_list.each do |k|
147
147
  data_type, data_length = plsql_to_ruby_data_type(@arguments[overload][k])
148
- cursor.bind_param(":#{k.to_s}", ruby_value_to_ora_value(args_hash[k], data_type), data_type, data_length)
148
+ cursor.bind_param(":#{k.to_s}", ruby_value_to_ora_value(args_hash[k], data_type),
149
+ data_type, data_length, @arguments[overload][k][:in_out])
149
150
  end
150
151
 
151
152
  if @return[overload]
152
153
  data_type, data_length = plsql_to_ruby_data_type(@return[overload])
153
- cursor.bind_param(":return", nil, data_type, data_length)
154
+ cursor.bind_param(":return", nil, data_type, data_length, 'OUT')
154
155
  end
155
156
 
156
157
  cursor.exec
@@ -181,47 +182,15 @@ module PLSQL
181
182
  private
182
183
 
183
184
  def plsql_to_ruby_data_type(argument)
184
- case argument[:data_type]
185
- when "VARCHAR2"
186
- [String, argument[:data_length] ? argument[:data_length] : 4000]
187
- when "NUMBER"
188
- [OraNumber, nil]
189
- when "DATE"
190
- [DateTime, nil]
191
- when "TIMESTAMP"
192
- [Time, nil]
193
- # CLOB
194
- # BLOB
195
- else
196
- [String, 4000]
197
- end
185
+ @schema.connection.plsql_to_ruby_data_type(argument[:data_type],argument[:data_length])
198
186
  end
199
187
 
200
188
  def ruby_value_to_ora_value(val, type)
201
- if type == OraNumber
202
- val.nil? || val.is_a?(Fixnum) ? val : val.to_f
203
- elsif type == DateTime
204
- val ? val.to_datetime : nil
205
- else
206
- val
207
- end
208
- end
209
-
210
- def ora_number_to_ruby_number(num)
211
- if num.to_i == num.to_f
212
- num.to_i
213
- else
214
- num.to_f
215
- end
189
+ @schema.connection.ruby_value_to_ora_value(val, type)
216
190
  end
217
191
 
218
192
  def ora_value_to_ruby_value(val)
219
- case val
220
- when OraNumber
221
- ora_number_to_ruby_number(val)
222
- else
223
- val
224
- end
193
+ @schema.connection.ora_value_to_ruby_value(val)
225
194
  end
226
195
 
227
196
  end
data/lib/plsql/schema.rb CHANGED
@@ -14,8 +14,8 @@ module PLSQL
14
14
 
15
15
  end
16
16
 
17
- def initialize(conn = nil, schema = nil, first = true)
18
- self.connection = conn
17
+ def initialize(raw_conn = nil, schema = nil, first = true)
18
+ self.connection = raw_conn
19
19
  @schema_name = schema ? schema.to_s.upcase : nil
20
20
  @first = first
21
21
  end
@@ -24,8 +24,8 @@ module PLSQL
24
24
  @connection
25
25
  end
26
26
 
27
- def connection=(conn)
28
- @connection = conn
27
+ def connection=(raw_conn)
28
+ @connection = raw_conn ? Connection.create(raw_conn) : nil
29
29
  if @connection
30
30
  @procedures = {}
31
31
  @packages = {}
@@ -48,10 +48,11 @@ module PLSQL
48
48
  end
49
49
 
50
50
  def select_first(sql, *bindvars)
51
- cursor = connection.exec(sql, *bindvars)
52
- result = cursor.fetch
53
- cursor.close
54
- result
51
+ # cursor = connection.exec(sql, *bindvars)
52
+ # result = cursor.fetch
53
+ # cursor.close
54
+ # result
55
+ connection.select_first(sql, *bindvars)
55
56
  end
56
57
 
57
58
  def commit
@@ -87,7 +88,7 @@ module PLSQL
87
88
  def find_other_schema(name)
88
89
  return nil unless @first && connection
89
90
  if select_first("SELECT username FROM all_users WHERE username = :username", name.to_s.upcase)
90
- Schema.new(connection, name, false)
91
+ Schema.new(connection.raw_connection, name, false)
91
92
  else
92
93
  nil
93
94
  end
data/lib/ruby_plsql.rb CHANGED
@@ -3,14 +3,41 @@ $:.unshift File.dirname(__FILE__)
3
3
  module RubyPlsql #:nodoc:
4
4
  end
5
5
 
6
- begin
7
- require "oci8"
8
-
9
- %w(schema procedure package).each do |file|
10
- require File.dirname(__FILE__) + "/plsql/#{file}"
6
+ unless defined?(JRUBY_VERSION)
7
+ begin
8
+ require "oci8"
9
+ require "oradate_patch"
10
+ rescue LoadError
11
+ puts <<-EOS
12
+ To use ruby_plsql you must install ruby-oci8 library.
13
+ EOS
14
+ end
15
+ else
16
+ begin
17
+ require "java"
18
+ ojdbc_jar = "ojdbc14.jar"
19
+ if ojdbc_jar_path = ENV["PATH"].split(":").find{|d| File.exists?(File.join(d,ojdbc_jar))}
20
+ require File.join(ojdbc_jar_path,ojdbc_jar)
21
+ else
22
+ require ojdbc_jar
23
+ end
24
+ import java.sql.Statement
25
+ import java.sql.Connection
26
+ import java.sql.SQLException
27
+ import java.sql.Types
28
+ import java.sql.DriverManager
29
+ DriverManager.registerDriver Java::oracle.jdbc.driver.OracleDriver.new
30
+ rescue LoadError
31
+ puts <<-EOS
32
+ To use ruby_plsql you must have Oracle JDBC driver installed.
33
+ EOS
11
34
  end
12
- rescue LoadError
13
- puts <<-EOS
14
- To use ruby_plsql you must install ruby-oci8 library.
15
- EOS
35
+ end
36
+
37
+ require "time"
38
+ require "date"
39
+ require "bigdecimal"
40
+
41
+ %w(connection schema procedure package).each do |file|
42
+ require File.dirname(__FILE__) + "/plsql/#{file}"
16
43
  end
@@ -1,8 +1,8 @@
1
1
  module RubyPlsql #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 1
5
- TINY = 6
4
+ MINOR = 2
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe "Package" do
4
4
  before(:all) do
5
- plsql.connection = conn = OCI8.new("hr","hr","xe")
5
+ plsql.connection = get_connection
6
6
  plsql.connection.exec <<-EOS
7
7
  CREATE OR REPLACE PACKAGE test_package IS
8
8
  FUNCTION test_procedure ( p_string VARCHAR2 )
@@ -6,7 +6,7 @@ require "activerecord"
6
6
  describe "Function with string parameters" do
7
7
 
8
8
  before(:all) do
9
- plsql.connection = conn = OCI8.new("hr","hr","xe")
9
+ plsql.connection = get_connection
10
10
  plsql.connection.exec <<-EOS
11
11
  CREATE OR REPLACE FUNCTION test_uppercase
12
12
  ( p_string VARCHAR2 )
@@ -59,7 +59,7 @@ end
59
59
  describe "Function with numeric parameters" do
60
60
 
61
61
  before(:all) do
62
- plsql.connection = conn = OCI8.new("hr","hr","xe")
62
+ plsql.connection = get_connection
63
63
  plsql.connection.exec <<-EOS
64
64
  CREATE OR REPLACE FUNCTION test_sum
65
65
  ( p_num1 NUMBER, p_num2 NUMBER )
@@ -100,7 +100,7 @@ end
100
100
  describe "Function with date parameters" do
101
101
 
102
102
  before(:all) do
103
- plsql.connection = conn = OCI8.new("hr","hr","xe")
103
+ plsql.connection = get_connection
104
104
  plsql.connection.exec <<-EOS
105
105
  CREATE OR REPLACE FUNCTION test_date
106
106
  ( p_date DATE )
@@ -116,26 +116,49 @@ describe "Function with date parameters" do
116
116
  plsql.logoff
117
117
  end
118
118
 
119
- it "should process DateTime parameters" do
120
- now = DateTime.new(2008,8,12,14,28,0)
121
- plsql.test_date(now).should == now + 1
119
+ it "should process Time parameters" do
120
+ now = Time.local(2008,8,12,14,28,0)
121
+ plsql.test_date(now).should == now + 60*60*24
122
122
  end
123
123
 
124
+ it "should process DateTime parameters" do
125
+ now = DateTime.parse(Time.local(2008,8,12,14,28,0).iso8601)
126
+ result = plsql.test_date(now)
127
+ result.class.should == Time
128
+ result.should == Time.parse((now + 1).strftime("%c"))
129
+ end
130
+
124
131
  it "should process old DateTime parameters" do
125
- now = DateTime.new(1900,1,1,12,0,0)
126
- plsql.test_date(now).should == now + 1
132
+ now = DateTime.new(1901,1,1,12,0,0)
133
+ result = plsql.test_date(now)
134
+ unless defined?(JRUBY_VERSION)
135
+ result.class.should == DateTime
136
+ result.should == now + 1
137
+ else
138
+ result.class.should == Time
139
+ result.should == Time.parse((now + 1).strftime("%c"))
140
+ end
127
141
  end
128
142
 
129
143
  it "should process Date parameters" do
130
144
  now = Date.new(2008,8,12)
131
- plsql.test_date(now).should == now + 1
145
+ result = plsql.test_date(now)
146
+ result.class.should == Time
147
+ result.should == Time.parse((now + 1).strftime("%c"))
132
148
  end
133
-
149
+
134
150
  it "should process old Date parameters" do
135
- now = Date.new(1900,1,1)
136
- plsql.test_date(now).should == now + 1
151
+ now = Date.new(1901,1,1)
152
+ result = plsql.test_date(now)
153
+ unless defined?(JRUBY_VERSION)
154
+ # result.class.should == DateTime
155
+ result.should == now + 1
156
+ else
157
+ result.class.should == Time
158
+ result.should == Time.parse((now + 1).strftime("%c"))
159
+ end
137
160
  end
138
-
161
+
139
162
  it "should process nil date parameter as NULL" do
140
163
  plsql.test_date(nil).should be_nil
141
164
  end
@@ -145,7 +168,7 @@ end
145
168
  describe "Function with timestamp parameters" do
146
169
 
147
170
  before(:all) do
148
- plsql.connection = conn = OCI8.new("hr","hr","xe")
171
+ plsql.connection = get_connection
149
172
  plsql.connection.exec <<-EOS
150
173
  CREATE OR REPLACE FUNCTION test_timestamp
151
174
  ( p_time TIMESTAMP )
@@ -170,7 +193,7 @@ end
170
193
 
171
194
  describe "Procedure with output parameters" do
172
195
  before(:all) do
173
- plsql.connection = conn = OCI8.new("hr","hr","xe")
196
+ plsql.connection = get_connection
174
197
  plsql.connection.exec <<-EOS
175
198
  CREATE OR REPLACE PROCEDURE test_copy
176
199
  ( p_from VARCHAR2, p_to OUT VARCHAR2, p_to_double OUT VARCHAR2 )
@@ -206,7 +229,7 @@ end
206
229
 
207
230
  describe "Package with procedures with same name but different argument lists" do
208
231
  before(:all) do
209
- plsql.connection = conn = OCI8.new("hr","hr","xe")
232
+ plsql.connection = get_connection
210
233
  plsql.connection.exec <<-EOS
211
234
  CREATE OR REPLACE PACKAGE test_package2 IS
212
235
  FUNCTION test_procedure ( p_string VARCHAR2 )
@@ -295,7 +318,7 @@ end
295
318
 
296
319
  describe "Function with output parameters" do
297
320
  before(:all) do
298
- plsql.connection = conn = OCI8.new("hr","hr","xe")
321
+ plsql.connection = get_connection
299
322
  plsql.connection.exec <<-EOS
300
323
  CREATE OR REPLACE FUNCTION test_copy_function
301
324
  ( p_from VARCHAR2, p_to OUT VARCHAR2, p_to_double OUT VARCHAR2 )
@@ -334,7 +357,7 @@ end
334
357
 
335
358
  describe "Function without parameters" do
336
359
  before(:all) do
337
- plsql.connection = conn = OCI8.new("hr","hr","xe")
360
+ plsql.connection = get_connection
338
361
  plsql.connection.exec <<-EOS
339
362
  CREATE OR REPLACE FUNCTION test_no_params
340
363
  RETURN VARCHAR2
@@ -8,24 +8,28 @@ describe "Schema" do
8
8
 
9
9
  end
10
10
 
11
- describe "Connection" do
11
+ describe "Schema connection" do
12
12
 
13
13
  before(:each) do
14
- @conn = OCI8.new("hr","hr","xe")
14
+ @conn = get_connection
15
15
  end
16
16
 
17
17
  after(:each) do
18
- @conn.logoff
18
+ unless defined? JRUBY_VERSION
19
+ @conn.logoff
20
+ else
21
+ @conn.close
22
+ end
19
23
  end
20
24
 
21
25
  it "should connect to test database" do
22
26
  plsql.connection = @conn
23
- plsql.connection.should == @conn
27
+ plsql.connection.raw_connection.should == @conn
24
28
  end
25
29
 
26
30
  it "should connect to test database using connection alias" do
27
31
  plsql(:hr).connection = @conn
28
- plsql(:hr).connection.should == @conn
32
+ plsql(:hr).connection.raw_connection.should == @conn
29
33
  end
30
34
 
31
35
  it "should return schema name" do
@@ -41,12 +45,11 @@ end
41
45
 
42
46
  describe "Named Schema" do
43
47
  before(:all) do
44
- @conn = OCI8.new("hr","hr","xe")
45
- plsql.connection = @conn
48
+ plsql.connection = @conn = get_connection
46
49
  end
47
50
 
48
51
  after(:all) do
49
- @conn.logoff
52
+ plsql.connection.logoff
50
53
  end
51
54
 
52
55
  it "should find existing schema" do
@@ -54,7 +57,7 @@ describe "Named Schema" do
54
57
  end
55
58
 
56
59
  it "should have the same connection as default schema" do
57
- plsql.hr.connection.should == @conn
60
+ plsql.hr.connection.raw_connection.should == @conn
58
61
  end
59
62
 
60
63
  it "should return schema name" do
data/spec/spec_helper.rb CHANGED
@@ -7,3 +7,11 @@ rescue LoadError
7
7
  end
8
8
 
9
9
  require File.expand_path(File.dirname(__FILE__) + "/../lib/ruby_plsql")
10
+
11
+ def get_connection
12
+ unless defined?(JRUBY_VERSION)
13
+ OCI8.new("hr","hr","xe")
14
+ else
15
+ DriverManager.getConnection("jdbc:oracle:thin:@ubuntu710:1521:XE","hr","hr")
16
+ end
17
+ end
data/website/index.html CHANGED
@@ -33,7 +33,7 @@
33
33
  <h1>Ruby API for PL/SQL</h1>
34
34
  <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/ruby-plsql"; return false'>
35
35
  <p>Get Version</p>
36
- <a href="http://rubyforge.org/projects/ruby-plsql" class="numbers">0.1.6</a>
36
+ <a href="http://rubyforge.org/projects/ruby-plsql" class="numbers">0.2.0</a>
37
37
  </div>
38
38
  <h1>&#x2192; &#8216;ruby-plsql&#8217;</h1>
39
39
 
@@ -41,7 +41,9 @@
41
41
  <h2>What</h2>
42
42
 
43
43
 
44
- <p>ruby-plsql gem provides simple Ruby <span class="caps">API</span> for calling Oracle PL/SQL procedures. This gem requires ruby-oci8 for connection to Oracle database.</p>
44
+ <p>ruby-plsql gem provides simple Ruby <span class="caps">API</span> for calling Oracle PL/SQL procedures.
45
+ ruby-plsql support both <span class="caps">MRI</span> and JRuby runtime environments.
46
+ This gem requires ruby-oci8 library (if <span class="caps">MRI</span> is used) or Oracle <span class="caps">JDBC</span> driver (ojdbc14.jar) (if JRuby is used) for connection to Oracle database.</p>
45
47
 
46
48
 
47
49
  <h2>Installing</h2>
@@ -88,10 +90,10 @@
88
90
  <h2>How to submit patches</h2>
89
91
 
90
92
 
91
- <p>Submit bugs and patches to <a href="http://rubyforge.org/tracker/?group_id=5816">RubyForge</a></p>
93
+ <p>Submit bugs and patches to <a href="http://rsim.lighthouseapp.com/projects/11470-ruby-plsql">Lighthouse</a></p>
92
94
 
93
95
 
94
- <p>The trunk repository is <code>http://ruby-plsql.rubyforge.org/svn/</code> for anonymous access.</p>
96
+ <p>Source code is located at <a href="http://github.com/rsim/ruby-plsql">GitHub</a></p>
95
97
 
96
98
 
97
99
  <h2>License</h2>
@@ -99,7 +101,7 @@
99
101
 
100
102
  <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
101
103
  <p class="coda">
102
- <a href="http://blog.rayapps.com">Raimonds Simanovskis</a>, 16th March 2008<br>
104
+ <a href="http://blog.rayapps.com">Raimonds Simanovskis</a>, 26th June 2008<br>
103
105
  Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
104
106
  </p>
105
107
  </div>
data/website/index.txt CHANGED
@@ -5,7 +5,9 @@ h1. &#x2192; 'ruby-plsql'
5
5
 
6
6
  h2. What
7
7
 
8
- ruby-plsql gem provides simple Ruby API for calling Oracle PL/SQL procedures. This gem requires ruby-oci8 for connection to Oracle database.
8
+ ruby-plsql gem provides simple Ruby API for calling Oracle PL/SQL procedures.
9
+ ruby-plsql support both MRI and JRuby runtime environments.
10
+ This gem requires ruby-oci8 library (if MRI is used) or Oracle JDBC driver (ojdbc14.jar) (if JRuby is used) for connection to Oracle database.
9
11
 
10
12
  h2. Installing
11
13
 
@@ -41,9 +43,9 @@ Submit your feedback as comments "here.":http://blog.rayapps.com/2008/03/15/ruby
41
43
 
42
44
  h2. How to submit patches
43
45
 
44
- Submit bugs and patches to "RubyForge":http://rubyforge.org/tracker/?group_id=5816
46
+ Submit bugs and patches to "Lighthouse":http://rsim.lighthouseapp.com/projects/11470-ruby-plsql
45
47
 
46
- The trunk repository is <code>http://ruby-plsql.rubyforge.org/svn/</code> for anonymous access.
48
+ Source code is located at "GitHub":http://github.com/rsim/ruby-plsql
47
49
 
48
50
  h2. License
49
51
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-plsql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raimonds Simanovskis
@@ -34,6 +34,8 @@ files:
34
34
  - Rakefile
35
35
  - config/hoe.rb
36
36
  - config/requirements.rb
37
+ - lib/oradate_patch.rb
38
+ - lib/plsql/connection.rb
37
39
  - lib/plsql/package.rb
38
40
  - lib/plsql/procedure.rb
39
41
  - lib/plsql/schema.rb