ruby-plsql 0.1.6 → 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/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