ruby-plsql 0.3.1 → 0.4.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.
@@ -44,25 +44,25 @@ describe "Connection" do
44
44
  if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby'
45
45
  describe "OCI data type conversions" do
46
46
  it "should translate PL/SQL VARCHAR2 to Ruby String" do
47
- @conn.plsql_to_ruby_data_type("VARCHAR2", 100).should == [String, 100]
48
- @conn.plsql_to_ruby_data_type("VARCHAR2", nil).should == [String, 32767]
47
+ @conn.plsql_to_ruby_data_type(:data_type => "VARCHAR2", :data_length => 100).should == [String, 100]
48
+ @conn.plsql_to_ruby_data_type(:data_type => "VARCHAR2", :data_length => nil).should == [String, 32767]
49
49
  end
50
50
 
51
51
  it "should translate PL/SQL CLOB to Ruby String" do
52
- @conn.plsql_to_ruby_data_type("CLOB", 100_000).should == [OCI8::CLOB, nil]
53
- @conn.plsql_to_ruby_data_type("CLOB", nil).should == [OCI8::CLOB, nil]
52
+ @conn.plsql_to_ruby_data_type(:data_type => "CLOB", :data_length => 100_000).should == [OCI8::CLOB, nil]
53
+ @conn.plsql_to_ruby_data_type(:data_type => "CLOB", :data_length => nil).should == [OCI8::CLOB, nil]
54
54
  end
55
55
 
56
56
  it "should translate PL/SQL NUMBER to Ruby OraNumber" do
57
- @conn.plsql_to_ruby_data_type("NUMBER", 15).should == [OraNumber, nil]
57
+ @conn.plsql_to_ruby_data_type(:data_type => "NUMBER", :data_length => 15).should == [OraNumber, nil]
58
58
  end
59
59
 
60
60
  it "should translate PL/SQL DATE to Ruby DateTime" do
61
- @conn.plsql_to_ruby_data_type("DATE", nil).should == [DateTime, nil]
61
+ @conn.plsql_to_ruby_data_type(:data_type => "DATE", :data_length => nil).should == [DateTime, nil]
62
62
  end
63
63
 
64
64
  it "should translate PL/SQL TIMESTAMP to Ruby Time" do
65
- @conn.plsql_to_ruby_data_type("TIMESTAMP", nil).should == [Time, nil]
65
+ @conn.plsql_to_ruby_data_type(:data_type => "TIMESTAMP", :data_length => nil).should == [Time, nil]
66
66
  end
67
67
 
68
68
  it "should not translate Ruby Fixnum when OraNumber type specified" do
@@ -114,30 +114,29 @@ describe "Connection" do
114
114
 
115
115
  describe "JDBC data type conversions" do
116
116
  it "should translate PL/SQL VARCHAR2 to Ruby String" do
117
- @conn.plsql_to_ruby_data_type("VARCHAR2", 100).should == [String, 100]
118
- @conn.plsql_to_ruby_data_type("VARCHAR2", nil).should == [String, 32767]
117
+ @conn.plsql_to_ruby_data_type(:data_type => "VARCHAR2", :data_length => 100).should == [String, 100]
118
+ @conn.plsql_to_ruby_data_type(:data_type => "VARCHAR2", :data_length => nil).should == [String, 32767]
119
119
  end
120
120
 
121
121
  it "should translate PL/SQL NUMBER to Ruby BigDecimal" do
122
- @conn.plsql_to_ruby_data_type("NUMBER", 15).should == [BigDecimal, nil]
122
+ @conn.plsql_to_ruby_data_type(:data_type => "NUMBER", :data_length => 15).should == [BigDecimal, nil]
123
123
  end
124
124
 
125
125
  it "should translate PL/SQL DATE to Ruby DateTime" do
126
- @conn.plsql_to_ruby_data_type("DATE", nil).should == [Time, nil]
126
+ @conn.plsql_to_ruby_data_type(:data_type => "DATE", :data_length => nil).should == [Time, nil]
127
127
  end
128
128
 
129
129
  it "should translate PL/SQL TIMESTAMP to Ruby Time" do
130
- @conn.plsql_to_ruby_data_type("TIMESTAMP", nil).should == [Time, nil]
130
+ @conn.plsql_to_ruby_data_type(:data_type => "TIMESTAMP", :data_length => nil).should == [Time, nil]
131
131
  end
132
132
 
133
133
  it "should not translate Ruby Fixnum when BigDecimal type specified" do
134
- @conn.ruby_value_to_ora_value(100, BigDecimal).should eql(100)
134
+ @conn.ruby_value_to_ora_value(100, BigDecimal).should == java.math.BigDecimal.new(100)
135
135
  end
136
136
 
137
137
  it "should translate Ruby Bignum value to BigDecimal when BigDecimal type specified" do
138
138
  big_decimal = @conn.ruby_value_to_ora_value(12345678901234567890, BigDecimal)
139
- big_decimal.class.should == BigDecimal
140
- big_decimal.should == BigDecimal("12345678901234567890")
139
+ big_decimal.should == java.math.BigDecimal.new("12345678901234567890")
141
140
  end
142
141
 
143
142
  # it "should translate Ruby OraDate value to DateTime when DateTime type specified" do
@@ -189,7 +188,7 @@ describe "Connection" do
189
188
 
190
189
  end
191
190
 
192
- describe "SQL statements" do
191
+ describe "SQL SELECT statements" do
193
192
 
194
193
  it "should execute SQL statement and return first result" do
195
194
  @now = Time.local(2008,05,31,23,22,11)
@@ -198,6 +197,13 @@ describe "Connection" do
198
197
  FROM dual").should == ["abc",123,123.456,@now]
199
198
  end
200
199
 
200
+ it "should execute SQL statement and return first result as hash" do
201
+ @now = Time.local(2008,05,31,23,22,11)
202
+ @conn.select_hash_first("SELECT 'abc' a, 123 b, 123.456 c,
203
+ TO_DATE('#{@now.strftime("%Y-%m-%d %H:%M:%S")}', 'YYYY-MM-DD HH24:MI:SS') d
204
+ FROM dual").should == {:a => "abc", :b => 123, :c => 123.456, :d => @now}
205
+ end
206
+
201
207
  it "should execute SQL statement with bind parameters and return first result" do
202
208
  @today = Date.parse("2008-05-31")
203
209
  @now = Time.local(2008,05,31,23,22,11)
@@ -232,7 +238,17 @@ describe "Connection" do
232
238
  TO_DATE('#{@now.strftime("%Y-%m-%d %H:%M:%S")}','YYYY-MM-DD HH24:MI:SS')
233
239
  FROM dual").should == [["abc",123,123.456,@now],["abc",123,123.456,@now]]
234
240
  end
235
-
241
+
242
+ it "should execute SQL statement and return all results as hash" do
243
+ @now = Time.local(2008,05,31,23,22,11)
244
+ @conn.select_hash_all("SELECT 'abc' a, 123 b, 123.456 c,
245
+ TO_DATE('#{@now.strftime("%Y-%m-%d %H:%M:%S")}','YYYY-MM-DD HH24:MI:SS') d
246
+ FROM dual
247
+ UNION ALL SELECT 'def' a, 123 b, 123.456 c,
248
+ TO_DATE('#{@now.strftime("%Y-%m-%d %H:%M:%S")}','YYYY-MM-DD HH24:MI:SS') d
249
+ FROM dual").should == [{:a=>"abc",:b=>123,:c=>123.456,:d=>@now},{:a=>"def",:b=>123,:c=>123.456,:d=>@now}]
250
+ end
251
+
236
252
  it "should execute SQL statement with bind parameters and return all results" do
237
253
  @now = Time.local(2008,05,31,23,22,11)
238
254
  @conn.select_all("SELECT :1,:2,:3,:4 FROM dual UNION ALL SELECT :1,:2,:3,:4 FROM dual",
@@ -276,9 +292,9 @@ describe "Connection" do
276
292
  @conn.exec(sql).should be_true
277
293
  end
278
294
 
279
- # it "should execute PL/SQL procedure definition" do
280
- # @conn.select_first("SELECT test_add_random(1) FROM dual").should == [@random + 1]
281
- # end
295
+ after(:each) do
296
+ @conn.exec "DROP FUNCTION test_add_random"
297
+ end
282
298
 
283
299
  it "should parse PL/SQL procedure call and bind parameters and exec and get bind parameter value" do
284
300
  sql = <<-EOS
@@ -287,10 +303,10 @@ describe "Connection" do
287
303
  END;
288
304
  EOS
289
305
  cursor = @conn.parse(sql)
290
- cursor.bind_param(":result",nil,Fixnum,nil,'OUT')
291
- cursor.bind_param(":p_number",100,Fixnum,3)
292
- cursor.bind_param(":p_varchar","abc",String,100,'IN/OUT')
293
- cursor.bind_param(":p_date",@now,Time,100,'IN/OUT')
306
+ cursor.bind_param(":result", nil, :data_type => 'NUMBER', :in_out => 'OUT')
307
+ cursor.bind_param(":p_number", 100, :data_type => 'NUMBER', :in_out => 'IN')
308
+ cursor.bind_param(":p_varchar", "abc", :data_type => 'VARCHAR2', :in_out => 'IN/OUT')
309
+ cursor.bind_param(":p_date", @now, :data_type => 'DATE', :in_out => 'IN/OUT')
294
310
  cursor.exec
295
311
  cursor[":result"].should == @random + 100
296
312
  cursor[":p_varchar"].should == "abc"
@@ -2,586 +2,1278 @@
2
2
 
3
3
  require File.dirname(__FILE__) + '/../spec_helper'
4
4
 
5
- require "rubygems"
6
- # require "activerecord"
7
-
8
- describe "Function with string parameters" do
9
-
5
+ describe "Parameter type mapping /" do
10
6
  before(:all) do
11
7
  plsql.connection = get_connection
12
- plsql.connection.exec <<-EOS
13
- CREATE OR REPLACE FUNCTION test_uppercase
14
- ( p_string VARCHAR2 )
15
- RETURN VARCHAR2
16
- IS
17
- BEGIN
18
- RETURN UPPER(p_string);
19
- END test_uppercase;
20
- EOS
21
8
  end
22
-
9
+
23
10
  after(:all) do
24
11
  plsql.logoff
25
12
  end
13
+
14
+ describe "Function with string parameters" do
26
15
 
27
- it "should find existing procedure" do
28
- PLSQL::Procedure.find(plsql, :test_uppercase).should_not be_nil
29
- end
16
+ before(:all) do
17
+ plsql.connection.exec <<-EOS
18
+ CREATE OR REPLACE FUNCTION test_uppercase
19
+ ( p_string VARCHAR2 )
20
+ RETURN VARCHAR2
21
+ IS
22
+ BEGIN
23
+ RETURN UPPER(p_string);
24
+ END test_uppercase;
25
+ EOS
26
+ end
27
+
28
+ after(:all) do
29
+ plsql.connection.exec "DROP FUNCTION test_uppercase"
30
+ end
31
+
32
+ it "should find existing procedure" do
33
+ PLSQL::Procedure.find(plsql, :test_uppercase).should_not be_nil
34
+ end
30
35
 
31
- it "should not find nonexisting procedure" do
32
- PLSQL::Procedure.find(plsql, :qwerty123456).should be_nil
33
- end
36
+ it "should not find nonexisting procedure" do
37
+ PLSQL::Procedure.find(plsql, :qwerty123456).should be_nil
38
+ end
34
39
 
35
- it "should execute function and return correct value" do
36
- plsql.test_uppercase('xxx').should == 'XXX'
37
- end
40
+ it "should execute function and return correct value" do
41
+ plsql.test_uppercase('xxx').should == 'XXX'
42
+ end
38
43
 
39
- it "should execute function with named parameters and return correct value" do
40
- plsql.test_uppercase(:p_string => 'xxx').should == 'XXX'
41
- end
44
+ it "should execute function with named parameters and return correct value" do
45
+ plsql.test_uppercase(:p_string => 'xxx').should == 'XXX'
46
+ end
42
47
 
43
- it "should raise error if wrong number of arguments is passed" do
44
- lambda { plsql.test_uppercase('xxx','yyy') }.should raise_error(ArgumentError)
45
- end
48
+ it "should raise error if wrong number of arguments is passed" do
49
+ lambda { plsql.test_uppercase('xxx','yyy') }.should raise_error(ArgumentError)
50
+ end
46
51
 
47
- it "should raise error if wrong named argument is passed" do
48
- lambda { plsql.test_uppercase(:p_string2 => 'xxx') }.should raise_error(ArgumentError)
49
- end
52
+ it "should raise error if wrong named argument is passed" do
53
+ lambda { plsql.test_uppercase(:p_string2 => 'xxx') }.should raise_error(ArgumentError)
54
+ end
50
55
 
51
- it "should execute function with schema name specified" do
52
- plsql.hr.test_uppercase('xxx').should == 'XXX'
53
- end
56
+ it "should execute function with schema name specified" do
57
+ plsql.hr.test_uppercase('xxx').should == 'XXX'
58
+ end
54
59
 
55
- it "should process nil parameter as NULL" do
56
- plsql.test_uppercase(nil).should be_nil
57
- end
60
+ it "should process nil parameter as NULL" do
61
+ plsql.test_uppercase(nil).should be_nil
62
+ end
58
63
 
59
- end
64
+ end
60
65
 
61
- describe "Function with numeric parameters" do
66
+ describe "Function with numeric parameters" do
62
67
 
63
- before(:all) do
64
- plsql.connection = get_connection
65
- plsql.connection.exec <<-EOS
66
- CREATE OR REPLACE FUNCTION test_sum
67
- ( p_num1 NUMBER, p_num2 NUMBER )
68
- RETURN NUMBER
69
- IS
70
- BEGIN
71
- RETURN p_num1 + p_num2;
72
- END test_sum;
73
- EOS
74
- end
68
+ before(:all) do
69
+ plsql.connection.exec <<-SQL
70
+ CREATE OR REPLACE FUNCTION test_sum
71
+ ( p_num1 NUMBER, p_num2 NUMBER )
72
+ RETURN NUMBER
73
+ IS
74
+ BEGIN
75
+ RETURN p_num1 + p_num2;
76
+ END test_sum;
77
+ SQL
78
+ plsql.connection.exec <<-SQL
79
+ CREATE OR REPLACE FUNCTION test_number_1
80
+ ( p_num NUMBER )
81
+ RETURN VARCHAR2
82
+ IS
83
+ BEGIN
84
+ IF p_num = 1 THEN
85
+ RETURN 'Y';
86
+ ELSIF p_num = 0 THEN
87
+ RETURN 'N';
88
+ ELSIF p_num IS NULL THEN
89
+ RETURN NULL;
90
+ ELSE
91
+ RETURN 'UNKNOWN';
92
+ END IF;
93
+ END test_number_1;
94
+ SQL
95
+ end
75
96
 
76
- after(:all) do
77
- plsql.logoff
78
- end
97
+ after(:all) do
98
+ plsql.connection.exec "DROP FUNCTION test_sum"
99
+ plsql.connection.exec "DROP FUNCTION test_number_1"
100
+ end
79
101
 
80
- it "should process integer parameters" do
81
- plsql.test_sum(123,456).should == 579
82
- end
102
+ it "should process integer parameters" do
103
+ plsql.test_sum(123,456).should == 579
104
+ end
83
105
 
84
- it "should process big integer parameters" do
85
- plsql.test_sum(123123123123,456456456456).should == 579579579579
86
- end
106
+ it "should process big integer parameters" do
107
+ plsql.test_sum(123123123123,456456456456).should == 579579579579
108
+ end
87
109
 
88
- it "should process float parameters and return BigDecimal" do
89
- plsql.test_sum(123.123,456.456).should == BigDecimal("579.579")
90
- end
110
+ it "should process float parameters and return BigDecimal" do
111
+ plsql.test_sum(123.123,456.456).should == BigDecimal("579.579")
112
+ end
91
113
 
92
- it "should process BigDecimal parameters and return BigDecimal" do
93
- plsql.test_sum(:p_num1 => BigDecimal("123.123"), :p_num2 => BigDecimal("456.456")).should == BigDecimal("579.579")
94
- end
114
+ it "should process BigDecimal parameters and return BigDecimal" do
115
+ plsql.test_sum(:p_num1 => BigDecimal("123.123"), :p_num2 => BigDecimal("456.456")).should == BigDecimal("579.579")
116
+ end
95
117
 
96
- it "should process nil parameter as NULL" do
97
- plsql.test_sum(123,nil).should be_nil
98
- end
118
+ it "should process nil parameter as NULL" do
119
+ plsql.test_sum(123,nil).should be_nil
120
+ end
99
121
 
100
- end
122
+ it "should convert true value to 1 for NUMBER parameter" do
123
+ plsql.test_number_1(true).should == 'Y'
124
+ end
125
+
126
+ it "should convert false value to 0 for NUMBER parameter" do
127
+ plsql.test_number_1(false).should == 'N'
128
+ end
101
129
 
102
- describe "Function with date parameters" do
103
-
104
- before(:all) do
105
- plsql.connection = get_connection
106
- plsql.connection.exec <<-EOS
107
- CREATE OR REPLACE FUNCTION test_date
108
- ( p_date DATE )
109
- RETURN DATE
110
- IS
111
- BEGIN
112
- RETURN p_date + 1;
113
- END test_date;
114
- EOS
115
130
  end
131
+
132
+ describe "Function with date parameters" do
116
133
 
117
- before(:each) do
118
- plsql.default_timezone = :local
119
- end
134
+ before(:all) do
135
+ plsql.connection.exec <<-EOS
136
+ CREATE OR REPLACE FUNCTION test_date
137
+ ( p_date DATE )
138
+ RETURN DATE
139
+ IS
140
+ BEGIN
141
+ RETURN p_date + 1;
142
+ END test_date;
143
+ EOS
144
+ end
145
+
146
+ before(:each) do
147
+ plsql.default_timezone = :local
148
+ end
120
149
 
121
- after(:all) do
122
- plsql.logoff
123
- end
150
+ after(:all) do
151
+ plsql.connection.exec "DROP FUNCTION test_date"
152
+ end
124
153
 
125
- it "should process Time parameters" do
126
- now = Time.local(2008,8,12,14,28,0)
127
- plsql.test_date(now).should == now + 60*60*24
128
- end
154
+ it "should process Time parameters" do
155
+ now = Time.local(2008,8,12,14,28,0)
156
+ plsql.test_date(now).should == now + 60*60*24
157
+ end
129
158
 
130
- it "should process UTC Time parameters" do
131
- plsql.default_timezone = :utc
132
- now = Time.utc(2008,8,12,14,28,0)
133
- plsql.test_date(now).should == now + 60*60*24
134
- end
159
+ it "should process UTC Time parameters" do
160
+ plsql.default_timezone = :utc
161
+ now = Time.utc(2008,8,12,14,28,0)
162
+ plsql.test_date(now).should == now + 60*60*24
163
+ end
135
164
 
136
- it "should process DateTime parameters" do
137
- now = DateTime.parse(Time.local(2008,8,12,14,28,0).iso8601)
138
- result = plsql.test_date(now)
139
- result.class.should == Time
140
- result.should == Time.parse((now + 1).strftime("%c"))
141
- end
165
+ it "should process DateTime parameters" do
166
+ now = DateTime.parse(Time.local(2008,8,12,14,28,0).iso8601)
167
+ result = plsql.test_date(now)
168
+ result.class.should == Time
169
+ result.should == Time.parse((now + 1).strftime("%c"))
170
+ end
142
171
 
143
- it "should process old DateTime parameters" do
144
- now = DateTime.civil(1901,1,1,12,0,0,plsql.local_timezone_offset)
145
- result = plsql.test_date(now)
146
- unless defined?(JRUBY_VERSION)
147
- result.class.should == DateTime
148
- result.should == now + 1
149
- else
172
+ it "should process old DateTime parameters" do
173
+ now = DateTime.civil(1901,1,1,12,0,0,plsql.local_timezone_offset)
174
+ result = plsql.test_date(now)
150
175
  result.class.should == Time
151
176
  result.should == Time.parse((now + 1).strftime("%c"))
152
177
  end
153
- end
154
178
 
155
- it "should process Date parameters" do
156
- now = Date.new(2008,8,12)
157
- result = plsql.test_date(now)
158
- result.class.should == Time
159
- result.should == Time.parse((now + 1).strftime("%c"))
160
- end
179
+ it "should process Date parameters" do
180
+ now = Date.new(2008,8,12)
181
+ result = plsql.test_date(now)
182
+ result.class.should == Time
183
+ result.should == Time.parse((now + 1).strftime("%c"))
184
+ end
161
185
 
162
- it "should process old Date parameters" do
163
- now = Date.new(1901,1,1)
164
- result = plsql.test_date(now)
165
- unless defined?(JRUBY_VERSION)
166
- result.class.should == DateTime
167
- result.strftime("%c").should == (now + 1).strftime("%c")
168
- else
186
+ it "should process old Date parameters" do
187
+ now = Date.new(1901,1,1)
188
+ result = plsql.test_date(now)
169
189
  result.class.should == Time
170
190
  result.should == Time.parse((now + 1).strftime("%c"))
171
191
  end
192
+
193
+ it "should process nil date parameter as NULL" do
194
+ plsql.test_date(nil).should be_nil
195
+ end
196
+
172
197
  end
198
+
199
+ describe "Function with timestamp parameters" do
173
200
 
174
- it "should process nil date parameter as NULL" do
175
- plsql.test_date(nil).should be_nil
201
+ before(:all) do
202
+ plsql.connection.exec <<-EOS
203
+ CREATE OR REPLACE FUNCTION test_timestamp
204
+ ( p_time TIMESTAMP )
205
+ RETURN TIMESTAMP
206
+ IS
207
+ BEGIN
208
+ RETURN p_time + NUMTODSINTERVAL(1, 'DAY');
209
+ END test_timestamp;
210
+ EOS
211
+ end
212
+
213
+ after(:all) do
214
+ plsql.connection.exec "DROP FUNCTION test_timestamp"
215
+ end
216
+
217
+ it "should process timestamp parameters" do
218
+ # now = Time.now
219
+ now = Time.local(2008,8,12,14,28,0)
220
+ plsql.test_timestamp(now).should == now + 60*60*24
221
+ end
222
+
176
223
  end
177
224
 
178
- end
225
+ describe "Procedure with output parameters" do
226
+ before(:all) do
227
+ plsql.connection.exec <<-EOS
228
+ CREATE OR REPLACE PROCEDURE test_copy
229
+ ( p_from VARCHAR2, p_to OUT VARCHAR2, p_to_double OUT VARCHAR2 )
230
+ IS
231
+ BEGIN
232
+ p_to := p_from;
233
+ p_to_double := p_from || p_from;
234
+ END test_copy;
235
+ EOS
236
+ end
237
+
238
+ after(:all) do
239
+ plsql.connection.exec "DROP PROCEDURE test_copy"
240
+ end
241
+
242
+ it "should return hash with output parameters" do
243
+ plsql.test_copy("abc", nil, nil).should == { :p_to => "abc", :p_to_double => "abcabc" }
244
+ end
245
+
246
+ it "should return hash with output parameters when called with named parameters" do
247
+ plsql.test_copy(:p_from => "abc", :p_to => nil, :p_to_double => nil).should == { :p_to => "abc", :p_to_double => "abcabc" }
248
+ end
249
+
250
+ it "should substitute output parameters with nil if they are not specified" do
251
+ plsql.test_copy("abc").should == { :p_to => "abc", :p_to_double => "abcabc" }
252
+ end
253
+
254
+ it "should substitute named output parameters with nil if they are not specified" do
255
+ plsql.test_copy(:p_from => "abc").should == { :p_to => "abc", :p_to_double => "abcabc" }
256
+ end
257
+
258
+ end
259
+
260
+ describe "Package with procedures with same name but different argument lists" do
261
+ before(:all) do
262
+ plsql.connection.exec <<-EOS
263
+ CREATE OR REPLACE PACKAGE test_package2 IS
264
+ FUNCTION test_procedure ( p_string VARCHAR2 )
265
+ RETURN VARCHAR2;
266
+ PROCEDURE test_procedure ( p_string VARCHAR2, p_result OUT VARCHAR2 )
267
+ ;
268
+ PROCEDURE test_procedure ( p_number NUMBER, p_result OUT VARCHAR2 )
269
+ ;
270
+ FUNCTION test_procedure2 ( p_string VARCHAR2 )
271
+ RETURN VARCHAR2;
272
+ END;
273
+ EOS
274
+ plsql.connection.exec <<-EOS
275
+ CREATE OR REPLACE PACKAGE BODY test_package2 IS
276
+ FUNCTION test_procedure ( p_string VARCHAR2 )
277
+ RETURN VARCHAR2
278
+ IS
279
+ BEGIN
280
+ RETURN UPPER(p_string);
281
+ END test_procedure;
282
+ PROCEDURE test_procedure ( p_string VARCHAR2, p_result OUT VARCHAR2 )
283
+ IS
284
+ BEGIN
285
+ p_result := UPPER(p_string);
286
+ END test_procedure;
287
+ PROCEDURE test_procedure ( p_number NUMBER, p_result OUT VARCHAR2 )
288
+ IS
289
+ BEGIN
290
+ p_result := LOWER(TO_CHAR(p_number));
291
+ END test_procedure;
292
+ FUNCTION test_procedure2 ( p_string VARCHAR2 )
293
+ RETURN VARCHAR2
294
+ IS
295
+ BEGIN
296
+ RETURN UPPER(p_string);
297
+ END test_procedure2;
298
+ END;
299
+ EOS
179
300
 
180
- describe "Function with timestamp parameters" do
301
+ end
181
302
 
182
- before(:all) do
183
- plsql.connection = get_connection
184
- plsql.connection.exec <<-EOS
185
- CREATE OR REPLACE FUNCTION test_timestamp
186
- ( p_time TIMESTAMP )
187
- RETURN TIMESTAMP
188
- IS
189
- BEGIN
190
- RETURN p_time + 1;
191
- END test_timestamp;
192
- EOS
303
+ after(:all) do
304
+ plsql.connection.exec "DROP PACKAGE test_package2"
305
+ end
306
+
307
+ it "should find existing package" do
308
+ PLSQL::Package.find(plsql, :test_package2).should_not be_nil
309
+ end
310
+
311
+ it "should identify overloaded procedure definition" do
312
+ @procedure = PLSQL::Procedure.find(plsql, :test_procedure, "TEST_PACKAGE2")
313
+ @procedure.should_not be_nil
314
+ @procedure.should be_overloaded
315
+ end
316
+
317
+ it "should identify non-overloaded procedure definition" do
318
+ @procedure = PLSQL::Procedure.find(plsql, :test_procedure2, "TEST_PACKAGE2")
319
+ @procedure.should_not be_nil
320
+ @procedure.should_not be_overloaded
321
+ end
322
+
323
+ it "should execute correct procedures based on number of arguments and return correct value" do
324
+ plsql.test_package2.test_procedure('xxx').should == 'XXX'
325
+ plsql.test_package2.test_procedure('xxx', nil).should == {:p_result => 'XXX'}
326
+ end
327
+
328
+ it "should execute correct procedures based on number of named arguments and return correct value" do
329
+ plsql.test_package2.test_procedure(:p_string => 'xxx').should == 'XXX'
330
+ plsql.test_package2.test_procedure(:p_string => 'xxx', :p_result => nil).should == {:p_result => 'XXX'}
331
+ end
332
+
333
+ it "should raise exception if procedure cannot be found based on number of arguments" do
334
+ lambda { plsql.test_package2.test_procedure() }.should raise_error(ArgumentError)
335
+ end
336
+
337
+ # TODO: should try to implement matching by types of arguments
338
+ # it "should find procedure based on types of arguments" do
339
+ # plsql.test_package2.test_procedure(111, nil).should == {:p_result => '111'}
340
+ # end
341
+
342
+ it "should find procedure based on names of named arguments" do
343
+ plsql.test_package2.test_procedure(:p_number => 111, :p_result => nil).should == {:p_result => '111'}
344
+ end
345
+
193
346
  end
347
+
348
+ describe "Function with output parameters" do
349
+ before(:all) do
350
+ plsql.connection.exec <<-EOS
351
+ CREATE OR REPLACE FUNCTION test_copy_function
352
+ ( p_from VARCHAR2, p_to OUT VARCHAR2, p_to_double OUT VARCHAR2 )
353
+ RETURN NUMBER
354
+ IS
355
+ BEGIN
356
+ p_to := p_from;
357
+ p_to_double := p_from || p_from;
358
+ RETURN LENGTH(p_from);
359
+ END test_copy_function;
360
+ EOS
361
+ end
194
362
 
195
- after(:all) do
196
- plsql.logoff
363
+ after(:all) do
364
+ plsql.connection.exec "DROP FUNCTION test_copy_function"
365
+ end
366
+
367
+ it "should return array with return value and hash of output parameters" do
368
+ plsql.test_copy_function("abc", nil, nil).should == [3, { :p_to => "abc", :p_to_double => "abcabc" }]
369
+ end
370
+
371
+ it "should return array with return value and hash of output parameters when called with named parameters" do
372
+ plsql.test_copy_function(:p_from => "abc", :p_to => nil, :p_to_double => nil).should ==
373
+ [3, { :p_to => "abc", :p_to_double => "abcabc" }]
374
+ end
375
+
376
+ it "should substitute output parameters with nil if they are not specified" do
377
+ plsql.test_copy_function("abc").should == [3, { :p_to => "abc", :p_to_double => "abcabc" }]
378
+ end
379
+
197
380
  end
381
+
382
+ describe "Function or procedure without parameters" do
383
+ before(:all) do
384
+ plsql.connection.exec <<-EOS
385
+ CREATE OR REPLACE FUNCTION test_no_params
386
+ RETURN VARCHAR2
387
+ IS
388
+ BEGIN
389
+ RETURN 'dummy';
390
+ END test_no_params;
391
+ EOS
392
+ plsql.connection.exec <<-EOS
393
+ CREATE OR REPLACE PROCEDURE test_proc_no_params
394
+ IS
395
+ BEGIN
396
+ NULL;
397
+ END test_proc_no_params;
398
+ EOS
399
+ end
198
400
 
199
- it "should process timestamp parameters" do
200
- now = Time.local(2008,8,12,14,28,0)
201
- plsql.test_timestamp(now).should == now + 60*60*24
401
+ after(:all) do
402
+ plsql.connection.exec "DROP FUNCTION test_no_params"
403
+ plsql.connection.exec "DROP PROCEDURE test_proc_no_params"
404
+ end
405
+
406
+ it "should find function" do
407
+ PLSQL::Procedure.find(plsql, :test_no_params).should_not be_nil
408
+ end
409
+
410
+ it "should return function value" do
411
+ plsql.test_no_params.should == "dummy"
412
+ end
413
+
414
+ it "should find procedure" do
415
+ PLSQL::Procedure.find(plsql, :test_proc_no_params).should_not be_nil
416
+ end
417
+
418
+ it "should execute procedure" do
419
+ plsql.test_proc_no_params.should be_nil
420
+ end
421
+
202
422
  end
203
423
 
204
- end
424
+ describe "Function with CLOB parameter and return value" do
425
+
426
+ before(:all) do
427
+ plsql.connection.exec <<-EOS
428
+ CREATE OR REPLACE FUNCTION test_clob
429
+ ( p_clob CLOB )
430
+ RETURN CLOB
431
+ IS
432
+ BEGIN
433
+ RETURN p_clob;
434
+ END test_clob;
435
+ EOS
436
+ end
437
+
438
+ after(:all) do
439
+ plsql.connection.exec "DROP FUNCTION test_clob"
440
+ end
441
+
442
+ it "should find existing procedure" do
443
+ PLSQL::Procedure.find(plsql, :test_clob).should_not be_nil
444
+ end
445
+
446
+ it "should execute function and return correct value" do
447
+ large_text = 'ābčdēfghij' * 10_000
448
+ plsql.test_clob(large_text).should == large_text
449
+ end
450
+
451
+ unless defined?(JRUBY_VERSION)
452
+
453
+ it "should execute function with empty string and return nil (oci8 cannot pass empty CLOB parameter)" do
454
+ text = ''
455
+ plsql.test_clob(text).should be_nil
456
+ end
457
+
458
+ else
459
+
460
+ it "should execute function with empty string and return empty string" do
461
+ text = ''
462
+ plsql.test_clob(text).should == text
463
+ end
464
+
465
+ end
466
+
467
+ it "should execute function with nil and return nil" do
468
+ plsql.test_clob(nil).should be_nil
469
+ end
205
470
 
206
- describe "Procedure with output parameters" do
207
- before(:all) do
208
- plsql.connection = get_connection
209
- plsql.connection.exec <<-EOS
210
- CREATE OR REPLACE PROCEDURE test_copy
211
- ( p_from VARCHAR2, p_to OUT VARCHAR2, p_to_double OUT VARCHAR2 )
212
- IS
213
- BEGIN
214
- p_to := p_from;
215
- p_to_double := p_from || p_from;
216
- END test_copy;
217
- EOS
218
471
  end
472
+
473
+ describe "Procedrue with CLOB parameter and return value" do
219
474
 
220
- after(:all) do
221
- plsql.logoff
475
+ before(:all) do
476
+ plsql.connection.exec <<-EOS
477
+ CREATE OR REPLACE PROCEDURE test_clob_proc
478
+ ( p_clob CLOB,
479
+ p_return OUT CLOB)
480
+ IS
481
+ BEGIN
482
+ p_return := p_clob;
483
+ END test_clob_proc;
484
+ EOS
485
+ end
486
+
487
+ after(:all) do
488
+ plsql.connection.exec "DROP PROCEDURE test_clob_proc"
489
+ end
490
+
491
+ it "should find existing procedure" do
492
+ PLSQL::Procedure.find(plsql, :test_clob_proc).should_not be_nil
493
+ end
494
+
495
+ it "should execute function and return correct value" do
496
+ large_text = 'ābčdēfghij' * 10_000
497
+ plsql.test_clob_proc(large_text)[:p_return].should == large_text
498
+ end
222
499
  end
500
+
501
+ describe "Procedrue with BLOB parameter and return value" do
502
+
503
+ before(:all) do
504
+ plsql.connection.exec <<-EOS
505
+ CREATE OR REPLACE PROCEDURE test_blob_proc
506
+ ( p_blob BLOB,
507
+ p_return OUT BLOB)
508
+ IS
509
+ BEGIN
510
+ p_return := p_blob;
511
+ END test_blob_proc;
512
+ EOS
513
+ end
223
514
 
224
- it "should return hash with output parameters" do
225
- plsql.test_copy("abc", nil, nil).should == { :p_to => "abc", :p_to_double => "abcabc" }
515
+ after(:all) do
516
+ plsql.connection.exec "DROP PROCEDURE test_blob_proc"
517
+ end
518
+
519
+ it "should find existing procedure" do
520
+ PLSQL::Procedure.find(plsql, :test_blob_proc).should_not be_nil
521
+ end
522
+
523
+ it "should execute function and return correct value" do
524
+ large_binary = '\000\001\002\003\004\005\006\007\010\011' * 10_000
525
+ plsql.test_blob_proc(large_binary)[:p_return].should == large_binary
526
+ end
226
527
  end
227
528
 
228
- it "should return hash with output parameters when called with named parameters" do
229
- plsql.test_copy(:p_from => "abc", :p_to => nil, :p_to_double => nil).should == { :p_to => "abc", :p_to_double => "abcabc" }
529
+ describe "Function with record parameter" do
530
+
531
+ before(:all) do
532
+ plsql.connection.exec "DROP TABLE test_employees" rescue nil
533
+ plsql.connection.exec <<-SQL
534
+ CREATE TABLE test_employees (
535
+ employee_id NUMBER(15),
536
+ first_name VARCHAR2(50),
537
+ last_name VARCHAR2(50),
538
+ hire_date DATE
539
+ )
540
+ SQL
541
+ plsql.connection.exec <<-SQL
542
+ CREATE OR REPLACE FUNCTION test_full_name (p_employee test_employees%ROWTYPE)
543
+ RETURN VARCHAR2
544
+ IS
545
+ BEGIN
546
+ RETURN p_employee.first_name || ' ' || p_employee.last_name;
547
+ END test_full_name;
548
+ SQL
549
+ plsql.connection.exec <<-SQL
550
+ CREATE OR REPLACE FUNCTION test_employee_record (p_employee test_employees%ROWTYPE)
551
+ RETURN test_employees%ROWTYPE
552
+ IS
553
+ BEGIN
554
+ RETURN p_employee;
555
+ END test_employee_record;
556
+ SQL
557
+ plsql.connection.exec <<-SQL
558
+ CREATE OR REPLACE FUNCTION test_employee_record2 (p_employee test_employees%ROWTYPE, x_employee OUT test_employees%ROWTYPE)
559
+ RETURN test_employees%ROWTYPE
560
+ IS
561
+ BEGIN
562
+ x_employee.employee_id := p_employee.employee_id;
563
+ x_employee.first_name := p_employee.first_name;
564
+ x_employee.last_name := p_employee.last_name;
565
+ x_employee.hire_date := p_employee.hire_date;
566
+ RETURN p_employee;
567
+ END test_employee_record2;
568
+ SQL
569
+ @p_employee = {
570
+ :employee_id => 1,
571
+ :first_name => 'First',
572
+ :last_name => 'Last',
573
+ :hire_date => Time.local(2000,01,31)
574
+ }
575
+ @p_employee2 = {
576
+ 'employee_id' => 1,
577
+ 'FIRST_NAME' => 'Second',
578
+ 'last_name' => 'Last',
579
+ 'hire_date' => Time.local(2000,01,31)
580
+ }
581
+ end
582
+
583
+ after(:all) do
584
+ plsql.connection.exec "DROP FUNCTION test_full_name"
585
+ plsql.connection.exec "DROP FUNCTION test_employee_record"
586
+ plsql.connection.exec "DROP FUNCTION test_employee_record2"
587
+ plsql.connection.exec "DROP TABLE test_employees"
588
+ end
589
+
590
+ it "should find existing function" do
591
+ PLSQL::Procedure.find(plsql, :test_full_name).should_not be_nil
592
+ end
593
+
594
+ it "should execute function with named parameter and return correct value" do
595
+ plsql.test_full_name(:p_employee => @p_employee).should == 'First Last'
596
+ end
597
+
598
+ it "should execute function with sequential parameter and return correct value" do
599
+ plsql.test_full_name(@p_employee).should == 'First Last'
600
+ end
601
+
602
+ it "should execute function with Hash parameter using strings as keys" do
603
+ plsql.test_full_name(@p_employee2).should == 'Second Last'
604
+ end
605
+
606
+ it "should raise error if wrong field name is passed for record parameter" do
607
+ lambda do
608
+ plsql.test_full_name(@p_employee.merge :xxx => 'xxx').should == 'Second Last'
609
+ end.should raise_error(ArgumentError)
610
+ end
611
+
612
+ it "should return record return value" do
613
+ plsql.test_employee_record(@p_employee).should == @p_employee
614
+ end
615
+
616
+ it "should return record return value and output record parameter value" do
617
+ plsql.test_employee_record2(@p_employee, nil).should == [@p_employee, {:x_employee => @p_employee}]
618
+ end
619
+
230
620
  end
231
621
 
232
- it "should substitute output parameters with nil if they are not specified" do
233
- plsql.test_copy("abc").should == { :p_to => "abc", :p_to_double => "abcabc" }
622
+ describe "Function with boolean parameters" do
623
+
624
+ before(:all) do
625
+ plsql.connection.exec <<-SQL
626
+ CREATE OR REPLACE FUNCTION test_boolean
627
+ ( p_boolean BOOLEAN )
628
+ RETURN BOOLEAN
629
+ IS
630
+ BEGIN
631
+ RETURN p_boolean;
632
+ END test_boolean;
633
+ SQL
634
+ plsql.connection.exec <<-SQL
635
+ CREATE OR REPLACE PROCEDURE test_boolean2
636
+ ( p_boolean BOOLEAN, x_boolean OUT BOOLEAN )
637
+ IS
638
+ BEGIN
639
+ x_boolean := p_boolean;
640
+ END test_boolean2;
641
+ SQL
642
+ end
643
+
644
+ after(:all) do
645
+ plsql.connection.exec "DROP FUNCTION test_boolean"
646
+ plsql.connection.exec "DROP PROCEDURE test_boolean2"
647
+ end
648
+
649
+ it "should accept true value and return true value" do
650
+ plsql.test_boolean(true).should == true
651
+ end
652
+
653
+ it "should accept false value and return false value" do
654
+ plsql.test_boolean(false).should == false
655
+ end
656
+
657
+ it "should accept nil value and return nil value" do
658
+ plsql.test_boolean(nil).should be_nil
659
+ end
660
+
661
+ it "should accept true value and assign true value to output parameter" do
662
+ plsql.test_boolean2(true, nil).should == {:x_boolean => true}
663
+ end
664
+
665
+ it "should accept false value and assign false value to output parameter" do
666
+ plsql.test_boolean2(false, nil).should == {:x_boolean => false}
667
+ end
668
+
669
+ it "should accept nil value and assign nil value to output parameter" do
670
+ plsql.test_boolean2(nil, nil).should == {:x_boolean => nil}
671
+ end
672
+
234
673
  end
235
674
 
236
- it "should substitute all parementers with nil if none are specified" do
237
- plsql.test_copy.should == { :p_to => nil, :p_to_double => nil }
675
+ describe "Function with object type parameter" do
676
+
677
+ before(:all) do
678
+ plsql.connection.exec "DROP TYPE t_employee" rescue nil
679
+ plsql.connection.exec "DROP TYPE t_phones" rescue nil
680
+ plsql.connection.exec <<-SQL
681
+ CREATE OR REPLACE TYPE t_address AS OBJECT (
682
+ street VARCHAR2(50),
683
+ city VARCHAR2(50),
684
+ country VARCHAR2(50)
685
+ )
686
+ SQL
687
+ plsql.connection.exec <<-SQL
688
+ CREATE OR REPLACE TYPE t_phone AS OBJECT (
689
+ type VARCHAR2(10),
690
+ phone_number VARCHAR2(50)
691
+ )
692
+ SQL
693
+ plsql.connection.exec <<-SQL
694
+ CREATE OR REPLACE TYPE t_phones AS TABLE OF T_PHONE
695
+ SQL
696
+ plsql.connection.exec <<-SQL
697
+ CREATE OR REPLACE TYPE t_employee AS OBJECT (
698
+ employee_id NUMBER(15),
699
+ first_name VARCHAR2(50),
700
+ last_name VARCHAR2(50),
701
+ hire_date DATE,
702
+ address t_address,
703
+ phones t_phones
704
+ )
705
+ SQL
706
+ plsql.connection.exec <<-SQL
707
+ CREATE OR REPLACE FUNCTION test_full_name (p_employee t_employee)
708
+ RETURN VARCHAR2
709
+ IS
710
+ BEGIN
711
+ RETURN p_employee.first_name || ' ' || p_employee.last_name;
712
+ END;
713
+ SQL
714
+ plsql.connection.exec <<-SQL
715
+ CREATE OR REPLACE FUNCTION test_employee_object (p_employee t_employee)
716
+ RETURN t_employee
717
+ IS
718
+ BEGIN
719
+ RETURN p_employee;
720
+ END;
721
+ SQL
722
+ plsql.connection.exec <<-SQL
723
+ CREATE OR REPLACE FUNCTION test_employee_object2 (p_employee t_employee, x_employee OUT t_employee)
724
+ RETURN t_employee
725
+ IS
726
+ BEGIN
727
+ x_employee := p_employee;
728
+ RETURN p_employee;
729
+ END;
730
+ SQL
731
+ @p_employee = {
732
+ :employee_id => 1,
733
+ :first_name => 'First',
734
+ :last_name => 'Last',
735
+ :hire_date => Time.local(2000,01,31),
736
+ :address => {:street => 'Main street 1', :city => 'Riga', :country => 'Latvia'},
737
+ :phones => [{:type => 'mobile', :phone_number => '123456'}, {:type => 'home', :phone_number => '654321'}]
738
+ }
739
+ end
740
+
741
+ after(:all) do
742
+ plsql.connection.exec "DROP FUNCTION test_full_name"
743
+ plsql.connection.exec "DROP FUNCTION test_employee_object"
744
+ plsql.connection.exec "DROP FUNCTION test_employee_object2"
745
+ plsql.connection.exec "DROP TYPE t_employee"
746
+ plsql.connection.exec "DROP TYPE t_address"
747
+ plsql.connection.exec "DROP TYPE t_phones"
748
+ plsql.connection.exec "DROP TYPE t_phone"
749
+ end
750
+
751
+ it "should find existing function" do
752
+ PLSQL::Procedure.find(plsql, :test_full_name).should_not be_nil
753
+ end
754
+
755
+ it "should execute function with named parameter and return correct value" do
756
+ plsql.test_full_name(:p_employee => @p_employee).should == 'First Last'
757
+ end
758
+
759
+ it "should execute function with sequential parameter and return correct value" do
760
+ plsql.test_full_name(@p_employee).should == 'First Last'
761
+ end
762
+
763
+ it "should raise error if wrong field name is passed for record parameter" do
764
+ lambda do
765
+ plsql.test_full_name(@p_employee.merge :xxx => 'xxx')
766
+ end.should raise_error(ArgumentError)
767
+ end
768
+
769
+ it "should return object type return value" do
770
+ plsql.test_employee_object(@p_employee).should == @p_employee
771
+ end
772
+
773
+ it "should return object type return value and output object type parameter value" do
774
+ plsql.test_employee_object2(@p_employee, nil).should == [@p_employee, {:x_employee => @p_employee}]
775
+ end
776
+
238
777
  end
239
778
 
240
- end
241
779
 
242
- describe "Package with procedures with same name but different argument lists" do
243
- before(:all) do
244
- plsql.connection = get_connection
245
- plsql.connection.exec <<-EOS
246
- CREATE OR REPLACE PACKAGE test_package2 IS
247
- FUNCTION test_procedure ( p_string VARCHAR2 )
248
- RETURN VARCHAR2;
249
- PROCEDURE test_procedure ( p_string VARCHAR2, p_result OUT VARCHAR2 )
250
- ;
251
- PROCEDURE test_procedure ( p_number NUMBER, p_result OUT VARCHAR2 )
252
- ;
253
- FUNCTION test_procedure2 ( p_string VARCHAR2 )
254
- RETURN VARCHAR2;
255
- END;
256
- EOS
257
- plsql.connection.exec <<-EOS
258
- CREATE OR REPLACE PACKAGE BODY test_package2 IS
259
- FUNCTION test_procedure ( p_string VARCHAR2 )
260
- RETURN VARCHAR2
780
+ describe "Function with table parameter" do
781
+
782
+ before(:all) do
783
+ # Array of numbers
784
+ plsql.connection.exec <<-SQL
785
+ CREATE OR REPLACE TYPE t_numbers AS TABLE OF NUMBER(15)
786
+ SQL
787
+ plsql.connection.exec <<-SQL
788
+ CREATE OR REPLACE FUNCTION test_sum (p_numbers IN t_numbers)
789
+ RETURN NUMBER
261
790
  IS
791
+ l_sum NUMBER(15) := 0;
262
792
  BEGIN
263
- RETURN UPPER(p_string);
264
- END test_procedure;
265
- PROCEDURE test_procedure ( p_string VARCHAR2, p_result OUT VARCHAR2 )
793
+ IF p_numbers.COUNT > 0 THEN
794
+ FOR i IN p_numbers.FIRST..p_numbers.LAST LOOP
795
+ IF p_numbers.EXISTS(i) THEN
796
+ l_sum := l_sum + p_numbers(i);
797
+ END IF;
798
+ END LOOP;
799
+ RETURN l_sum;
800
+ ELSE
801
+ RETURN NULL;
802
+ END IF;
803
+ END;
804
+ SQL
805
+
806
+ plsql.connection.exec <<-SQL
807
+ CREATE OR REPLACE FUNCTION test_increment(p_numbers IN t_numbers, p_increment_by IN NUMBER DEFAULT 1)
808
+ RETURN t_numbers
266
809
  IS
810
+ l_numbers t_numbers := t_numbers();
267
811
  BEGIN
268
- p_result := UPPER(p_string);
269
- END test_procedure;
270
- PROCEDURE test_procedure ( p_number NUMBER, p_result OUT VARCHAR2 )
812
+ FOR i IN p_numbers.FIRST..p_numbers.LAST LOOP
813
+ IF p_numbers.EXISTS(i) THEN
814
+ l_numbers.EXTEND;
815
+ l_numbers(i) := p_numbers(i) + p_increment_by;
816
+ END IF;
817
+ END LOOP;
818
+ RETURN l_numbers;
819
+ END;
820
+ SQL
821
+
822
+ # Array of strings
823
+ plsql.connection.exec <<-SQL
824
+ CREATE OR REPLACE TYPE t_strings AS TABLE OF VARCHAR2(4000)
825
+ SQL
826
+ plsql.connection.exec <<-SQL
827
+ CREATE OR REPLACE FUNCTION test_copy_strings(p_strings IN t_strings, x_strings OUT t_strings)
828
+ RETURN t_strings
271
829
  IS
272
830
  BEGIN
273
- p_result := LOWER(TO_CHAR(p_number));
274
- END test_procedure;
275
- FUNCTION test_procedure2 ( p_string VARCHAR2 )
276
- RETURN VARCHAR2
831
+ x_strings := t_strings();
832
+ FOR i IN p_strings.FIRST..p_strings.LAST LOOP
833
+ IF p_strings.EXISTS(i) THEN
834
+ x_strings.EXTEND;
835
+ x_strings(i) := p_strings(i);
836
+ END IF;
837
+ END LOOP;
838
+ RETURN x_strings;
839
+ END;
840
+ SQL
841
+
842
+ # Wrong type definition inside package
843
+ plsql.connection.exec <<-SQL
844
+ CREATE OR REPLACE PACKAGE test_collections IS
845
+ TYPE t_numbers IS TABLE OF NUMBER(15);
846
+ FUNCTION test_sum (p_numbers IN t_numbers)
847
+ RETURN NUMBER;
848
+ END;
849
+ SQL
850
+ plsql.connection.exec <<-SQL
851
+ CREATE OR REPLACE PACKAGE BODY test_collections IS
852
+ FUNCTION test_sum (p_numbers IN t_numbers)
853
+ RETURN NUMBER
854
+ IS
855
+ l_sum NUMBER(15) := 0;
856
+ BEGIN
857
+ IF p_numbers.COUNT > 0 THEN
858
+ FOR i IN p_numbers.FIRST..p_numbers.LAST LOOP
859
+ IF p_numbers.EXISTS(i) THEN
860
+ l_sum := l_sum + p_numbers(i);
861
+ END IF;
862
+ END LOOP;
863
+ RETURN l_sum;
864
+ ELSE
865
+ RETURN NULL;
866
+ END IF;
867
+ END;
868
+ END;
869
+ SQL
870
+
871
+ # Array of objects
872
+ plsql.connection.exec <<-SQL
873
+ CREATE OR REPLACE TYPE t_phone AS OBJECT (
874
+ type VARCHAR2(10),
875
+ phone_number VARCHAR2(50)
876
+ )
877
+ SQL
878
+ plsql.connection.exec <<-SQL
879
+ CREATE OR REPLACE TYPE t_phones AS TABLE OF T_PHONE
880
+ SQL
881
+ plsql.connection.exec <<-SQL
882
+ CREATE OR REPLACE FUNCTION test_copy_objects(p_phones IN t_phones, x_phones OUT t_phones)
883
+ RETURN t_phones
277
884
  IS
278
885
  BEGIN
279
- RETURN UPPER(p_string);
280
- END test_procedure2;
281
- END;
282
- EOS
886
+ x_phones := p_phones;
887
+ RETURN x_phones;
888
+ END;
889
+ SQL
890
+ end
283
891
 
284
- end
285
-
286
- after(:all) do
287
- plsql.logoff
288
- end
289
-
290
- it "should find existing package" do
291
- PLSQL::Package.find(plsql, :test_package2).should_not be_nil
292
- end
892
+ after(:all) do
893
+ plsql.connection.exec "DROP FUNCTION test_sum"
894
+ plsql.connection.exec "DROP FUNCTION test_increment"
895
+ plsql.connection.exec "DROP FUNCTION test_copy_strings"
896
+ plsql.connection.exec "DROP PACKAGE test_collections"
897
+ plsql.connection.exec "DROP FUNCTION test_copy_objects"
898
+ plsql.connection.exec "DROP TYPE t_numbers"
899
+ plsql.connection.exec "DROP TYPE t_strings"
900
+ plsql.connection.exec "DROP TYPE t_phones"
901
+ plsql.connection.exec "DROP TYPE t_phone"
902
+ end
293
903
 
294
- it "should identify overloaded procedure definition" do
295
- @procedure = PLSQL::Procedure.find(plsql, :test_procedure, "TEST_PACKAGE2")
296
- @procedure.should_not be_nil
297
- @procedure.should be_overloaded
298
- end
904
+ it "should find existing function" do
905
+ PLSQL::Procedure.find(plsql, :test_sum).should_not be_nil
906
+ end
299
907
 
300
- it "should identify non-overloaded procedure definition" do
301
- @procedure = PLSQL::Procedure.find(plsql, :test_procedure2, "TEST_PACKAGE2")
302
- @procedure.should_not be_nil
303
- @procedure.should_not be_overloaded
304
- end
908
+ it "should execute function with number array parameter" do
909
+ plsql.test_sum([1,2,3,4]).should == 10
910
+ end
305
911
 
306
- it "should execute correct procedures based on number of arguments and return correct value" do
307
- plsql.test_package2.test_procedure('xxx').should == 'XXX'
308
- plsql.test_package2.test_procedure('xxx', nil).should == {:p_result => 'XXX'}
309
- end
912
+ it "should return number array return value" do
913
+ plsql.test_increment([1,2,3,4], 1).should == [2,3,4,5]
914
+ end
310
915
 
311
- it "should execute correct procedures based on number of named arguments and return correct value" do
312
- plsql.test_package2.test_procedure(:p_string => 'xxx').should == 'XXX'
313
- plsql.test_package2.test_procedure(:p_string => 'xxx', :p_result => nil).should == {:p_result => 'XXX'}
314
- end
916
+ it "should execute function with string array and return string array output parameter" do
917
+ strings = ['1','2','3','4']
918
+ plsql.test_copy_strings(strings).should == [strings, {:x_strings => strings}]
919
+ end
315
920
 
316
- it "should raise exception if procedure cannot be found based on number of arguments" do
317
- lambda { plsql.test_package2.test_procedure() }.should raise_error(ArgumentError)
318
- end
319
-
320
- # TODO: should try to implement matching by types of arguments
321
- # it "should find procedure based on types of arguments" do
322
- # plsql.test_package2.test_procedure(111, nil).should == {:p_result => '111'}
323
- # end
921
+ it "should raise error if parameter type is defined inside package" do
922
+ lambda do
923
+ plsql.test_collections.test_sum([1,2,3,4])
924
+ end.should raise_error(ArgumentError)
925
+ end
324
926
 
325
- it "should find procedure based on names of named arguments" do
326
- plsql.test_package2.test_procedure(:p_number => 111, :p_result => nil).should == {:p_result => '111'}
327
- end
927
+ it "should execute function with object array and return object array output parameter" do
928
+ phones = [{:type => 'mobile', :phone_number => '123456'}, {:type => 'home', :phone_number => '654321'}]
929
+ plsql.test_copy_objects(phones).should == [phones, {:x_phones => phones}]
930
+ end
328
931
 
329
- end
932
+ it "should execute function with empty object array" do
933
+ phones = []
934
+ plsql.test_copy_objects(phones).should == [phones, {:x_phones => phones}]
935
+ end
330
936
 
331
- describe "Function with output parameters" do
332
- before(:all) do
333
- plsql.connection = get_connection
334
- plsql.connection.exec <<-EOS
335
- CREATE OR REPLACE FUNCTION test_copy_function
336
- ( p_from VARCHAR2, p_to OUT VARCHAR2, p_to_double OUT VARCHAR2 )
337
- RETURN NUMBER
338
- IS
339
- BEGIN
340
- p_to := p_from;
341
- p_to_double := p_from || p_from;
342
- RETURN LENGTH(p_from);
343
- END test_copy_function;
344
- EOS
345
- end
346
-
347
- after(:all) do
348
- plsql.logoff
349
- end
350
-
351
- it "should return array with return value and hash of output parameters" do
352
- plsql.test_copy_function("abc", nil, nil).should == [3, { :p_to => "abc", :p_to_double => "abcabc" }]
353
937
  end
354
938
 
355
- it "should return array with return value and hash of output parameters when called with named parameters" do
356
- plsql.test_copy_function(:p_from => "abc", :p_to => nil, :p_to_double => nil).should ==
357
- [3, { :p_to => "abc", :p_to_double => "abcabc" }]
358
- end
939
+ describe "Function with VARRAY parameter" do
359
940
 
360
- it "should substitute output parameters with nil if they are not specified" do
361
- plsql.test_copy_function("abc").should == [3, { :p_to => "abc", :p_to_double => "abcabc" }]
362
- end
941
+ before(:all) do
942
+ # Array of numbers
943
+ plsql.connection.exec <<-SQL
944
+ CREATE OR REPLACE TYPE t_numbers_array AS VARRAY(100) OF NUMBER(15)
945
+ SQL
946
+ plsql.connection.exec <<-SQL
947
+ CREATE OR REPLACE FUNCTION test_sum (p_numbers IN t_numbers_array)
948
+ RETURN NUMBER
949
+ IS
950
+ l_sum NUMBER(15) := 0;
951
+ BEGIN
952
+ IF p_numbers.COUNT > 0 THEN
953
+ FOR i IN p_numbers.FIRST..p_numbers.LAST LOOP
954
+ l_sum := l_sum + p_numbers(i);
955
+ END LOOP;
956
+ RETURN l_sum;
957
+ ELSE
958
+ RETURN NULL;
959
+ END IF;
960
+ END;
961
+ SQL
962
+
963
+ plsql.connection.exec <<-SQL
964
+ CREATE OR REPLACE FUNCTION test_increment(p_numbers IN t_numbers_array, p_increment_by IN NUMBER DEFAULT 1)
965
+ RETURN t_numbers_array
966
+ IS
967
+ l_numbers t_numbers_array := t_numbers_array();
968
+ BEGIN
969
+ FOR i IN p_numbers.FIRST..p_numbers.LAST LOOP
970
+ l_numbers.EXTEND;
971
+ l_numbers(i) := p_numbers(i) + p_increment_by;
972
+ END LOOP;
973
+ RETURN l_numbers;
974
+ END;
975
+ SQL
976
+
977
+ # Array of strings
978
+ plsql.connection.exec <<-SQL
979
+ CREATE OR REPLACE TYPE t_strings_array AS VARRAY(100) OF VARCHAR2(4000)
980
+ SQL
981
+ plsql.connection.exec <<-SQL
982
+ CREATE OR REPLACE FUNCTION test_copy_strings(p_strings IN t_strings_array, x_strings OUT t_strings_array)
983
+ RETURN t_strings_array
984
+ IS
985
+ BEGIN
986
+ x_strings := t_strings_array();
987
+ FOR i IN p_strings.FIRST..p_strings.LAST LOOP
988
+ x_strings.EXTEND;
989
+ x_strings(i) := p_strings(i);
990
+ END LOOP;
991
+ RETURN x_strings;
992
+ END;
993
+ SQL
994
+
995
+ # Array of objects
996
+ plsql.connection.exec "DROP TYPE t_phones_array" rescue nil
997
+ plsql.connection.exec <<-SQL
998
+ CREATE OR REPLACE TYPE t_phone AS OBJECT (
999
+ type VARCHAR2(10),
1000
+ phone_number VARCHAR2(50)
1001
+ )
1002
+ SQL
1003
+ plsql.connection.exec <<-SQL
1004
+ CREATE OR REPLACE TYPE t_phones_array AS ARRAY(100) OF T_PHONE
1005
+ SQL
1006
+ plsql.connection.exec <<-SQL
1007
+ CREATE OR REPLACE FUNCTION test_copy_objects(p_phones IN t_phones_array, x_phones OUT t_phones_array)
1008
+ RETURN t_phones_array
1009
+ IS
1010
+ BEGIN
1011
+ x_phones := p_phones;
1012
+ RETURN x_phones;
1013
+ END;
1014
+ SQL
1015
+ end
363
1016
 
364
- it "should substitute all parementers with nil if none are specified" do
365
- plsql.test_copy_function.should == [nil, { :p_to => nil, :p_to_double => nil }]
366
- end
1017
+ after(:all) do
1018
+ plsql.connection.exec "DROP FUNCTION test_sum"
1019
+ plsql.connection.exec "DROP FUNCTION test_increment"
1020
+ plsql.connection.exec "DROP FUNCTION test_copy_strings"
1021
+ plsql.connection.exec "DROP FUNCTION test_copy_objects"
1022
+ plsql.connection.exec "DROP TYPE t_numbers_array"
1023
+ plsql.connection.exec "DROP TYPE t_strings_array"
1024
+ plsql.connection.exec "DROP TYPE t_phones_array"
1025
+ plsql.connection.exec "DROP TYPE t_phone"
1026
+ end
367
1027
 
368
- end
1028
+ it "should find existing function" do
1029
+ PLSQL::Procedure.find(plsql, :test_sum).should_not be_nil
1030
+ end
369
1031
 
370
- describe "Function or procedure without parameters" do
371
- before(:all) do
372
- plsql.connection = get_connection
373
- plsql.connection.exec <<-EOS
374
- CREATE OR REPLACE FUNCTION test_no_params
375
- RETURN VARCHAR2
376
- IS
377
- BEGIN
378
- RETURN 'dummy';
379
- END test_no_params;
380
- EOS
381
- plsql.connection.exec <<-EOS
382
- CREATE OR REPLACE PROCEDURE test_proc_no_params
383
- IS
384
- BEGIN
385
- NULL;
386
- END test_proc_no_params;
387
- EOS
388
- end
389
-
390
- after(:all) do
391
- plsql.logoff
392
- end
1032
+ it "should execute function with number array parameter" do
1033
+ plsql.test_sum([1,2,3,4]).should == 10
1034
+ end
393
1035
 
394
- it "should find function" do
395
- PLSQL::Procedure.find(plsql, :test_no_params).should_not be_nil
396
- end
1036
+ it "should return number array return value" do
1037
+ plsql.test_increment([1,2,3,4], 1).should == [2,3,4,5]
1038
+ end
397
1039
 
398
- it "should return function value" do
399
- plsql.test_no_params.should == "dummy"
400
- end
1040
+ it "should execute function with string array and return string array output parameter" do
1041
+ strings = ['1','2','3','4']
1042
+ plsql.test_copy_strings(strings).should == [strings, {:x_strings => strings}]
1043
+ end
401
1044
 
402
- it "should find procedure" do
403
- PLSQL::Procedure.find(plsql, :test_proc_no_params).should_not be_nil
404
- end
1045
+ it "should execute function with object array and return object array output parameter" do
1046
+ phones = [{:type => 'mobile', :phone_number => '123456'}, {:type => 'home', :phone_number => '654321'}]
1047
+ plsql.test_copy_objects(phones).should == [phones, {:x_phones => phones}]
1048
+ end
1049
+
1050
+ it "should execute function with empty object array" do
1051
+ phones = []
1052
+ plsql.test_copy_objects(phones).should == [phones, {:x_phones => phones}]
1053
+ end
405
1054
 
406
- it "should execute procedure" do
407
- plsql.test_proc_no_params.should be_nil
408
1055
  end
409
1056
 
410
- end
1057
+ describe "Function with cursor return value or parameter" do
411
1058
 
412
- describe "Function with CLOB parameter and return value" do
413
-
414
- before(:all) do
415
- plsql.connection = get_connection
416
- plsql.connection.exec <<-EOS
417
- CREATE OR REPLACE FUNCTION test_clob
418
- ( p_clob CLOB )
419
- RETURN CLOB
420
- IS
421
- BEGIN
422
- RETURN p_clob;
423
- END test_clob;
424
- EOS
425
- end
426
-
427
- after(:all) do
428
- plsql.logoff
429
- end
430
-
431
- it "should find existing procedure" do
432
- PLSQL::Procedure.find(plsql, :test_clob).should_not be_nil
433
- end
1059
+ before(:all) do
1060
+ plsql.connection.exec "DROP TABLE test_employees" rescue nil
1061
+ plsql.connection.exec <<-SQL
1062
+ CREATE TABLE test_employees (
1063
+ employee_id NUMBER(15),
1064
+ first_name VARCHAR2(50),
1065
+ last_name VARCHAR2(50),
1066
+ hire_date DATE
1067
+ )
1068
+ SQL
1069
+ plsql.connection.exec <<-SQL
1070
+ CREATE OR REPLACE PROCEDURE test_insert_employee(p_employee test_employees%ROWTYPE)
1071
+ IS
1072
+ BEGIN
1073
+ INSERT INTO test_employees
1074
+ VALUES p_employee;
1075
+ END;
1076
+ SQL
1077
+ plsql.connection.exec <<-SQL
1078
+ CREATE OR REPLACE FUNCTION test_cursor
1079
+ RETURN SYS_REFCURSOR
1080
+ IS
1081
+ l_cursor SYS_REFCURSOR;
1082
+ BEGIN
1083
+ OPEN l_cursor FOR
1084
+ SELECT * FROM test_employees ORDER BY employee_id;
1085
+ RETURN l_cursor;
1086
+ END;
1087
+ SQL
1088
+ plsql.connection.exec <<-SQL
1089
+ CREATE OR REPLACE PROCEDURE test_cursor_out(x_cursor OUT SYS_REFCURSOR)
1090
+ IS
1091
+ BEGIN
1092
+ OPEN x_cursor FOR
1093
+ SELECT * FROM test_employees ORDER BY employee_id;
1094
+ END;
1095
+ SQL
1096
+ plsql.connection.exec <<-SQL
1097
+ CREATE OR REPLACE FUNCTION test_cursor_fetch(p_cursor SYS_REFCURSOR)
1098
+ RETURN test_employees%ROWTYPE
1099
+ IS
1100
+ l_record test_employees%ROWTYPE;
1101
+ BEGIN
1102
+ FETCH p_cursor INTO l_record;
1103
+ RETURN l_record;
1104
+ END;
1105
+ SQL
1106
+ @fields = [:employee_id, :first_name, :last_name, :hire_date]
1107
+ @employees = (1..10).map do |i|
1108
+ {
1109
+ :employee_id => i,
1110
+ :first_name => "First #{i}",
1111
+ :last_name => "Last #{i}",
1112
+ :hire_date => Time.local(2000,01,i)
1113
+ }
1114
+ end
1115
+ @employees.each do |e|
1116
+ plsql.test_insert_employee(e)
1117
+ end
1118
+ plsql.connection.commit
1119
+ end
434
1120
 
435
- it "should execute function and return correct value" do
436
- large_text = 'ābčdēfghij' * 10_000
437
- plsql.test_clob(large_text).should == large_text
438
- end
1121
+ after(:all) do
1122
+ plsql.connection.exec "DROP FUNCTION test_cursor"
1123
+ plsql.connection.exec "DROP PROCEDURE test_cursor_out"
1124
+ plsql.connection.exec "DROP PROCEDURE test_insert_employee"
1125
+ plsql.connection.exec "DROP FUNCTION test_cursor_fetch"
1126
+ plsql.connection.exec "DROP TABLE test_employees"
1127
+ end
439
1128
 
440
- unless defined?(JRUBY_VERSION)
1129
+ it "should find existing function" do
1130
+ PLSQL::Procedure.find(plsql, :test_cursor).should_not be_nil
1131
+ end
441
1132
 
442
- it "should execute function with empty string and return nil (oci8 cannot pass empty CLOB parameter)" do
443
- text = ''
444
- plsql.test_clob(text).should be_nil
1133
+ it "should return cursor and fetch first row" do
1134
+ plsql.test_cursor do |cursor|
1135
+ cursor.fetch.should == @fields.map{|f| @employees[0][f]}
1136
+ end.should be_nil
445
1137
  end
446
-
447
- else
448
1138
 
449
- it "should execute function with empty string and return empty string" do
450
- text = ''
451
- plsql.test_clob(text).should == text
1139
+ it "should close all returned cursors after block is executed" do
1140
+ cursor2 = nil
1141
+ plsql.test_cursor do |cursor|
1142
+ cursor2 = cursor
1143
+ end.should be_nil
1144
+ lambda { cursor2.fetch }.should raise_error
452
1145
  end
453
-
454
- end
455
1146
 
456
- it "should execute function with nil and return nil" do
457
- plsql.test_clob(nil).should be_nil
458
- end
1147
+ it "should not raise error if cursor is closed inside block" do
1148
+ lambda do
1149
+ plsql.test_cursor do |cursor|
1150
+ cursor.close
1151
+ end
1152
+ end.should_not raise_error
1153
+ end
459
1154
 
460
- end
1155
+ it "should fetch hash from returned cursor" do
1156
+ plsql.test_cursor do |cursor|
1157
+ cursor.fetch_hash.should == @employees[0]
1158
+ end
1159
+ end
461
1160
 
462
- describe "Procedrue with CLOB parameter and return value" do
463
-
464
- before(:all) do
465
- plsql.connection = get_connection
466
- plsql.connection.exec <<-EOS
467
- CREATE OR REPLACE PROCEDURE test_clob_proc
468
- ( p_clob CLOB,
469
- p_return OUT CLOB)
470
- IS
471
- BEGIN
472
- p_return := p_clob;
473
- END test_clob_proc;
474
- EOS
475
- end
476
-
477
- after(:all) do
478
- plsql.logoff
479
- end
480
-
481
- it "should find existing procedure" do
482
- PLSQL::Procedure.find(plsql, :test_clob_proc).should_not be_nil
483
- end
1161
+ it "should fetch all rows from returned cursor" do
1162
+ plsql.test_cursor do |cursor|
1163
+ cursor.fetch_all.should == @employees.map{|e| @fields.map{|f| e[f]}}
1164
+ end
1165
+ end
1166
+
1167
+ it "should fetch all rows as hash from returned cursor" do
1168
+ plsql.test_cursor do |cursor|
1169
+ cursor.fetch_hash_all.should == @employees
1170
+ end
1171
+ end
1172
+
1173
+ it "should get field names from returned cursor" do
1174
+ plsql.test_cursor do |cursor|
1175
+ cursor.fields.should == @fields
1176
+ end
1177
+ end
1178
+
1179
+ it "should return output parameter with cursor and fetch first row" do
1180
+ plsql.test_cursor_out do |result|
1181
+ result[:x_cursor].fetch.should == @fields.map{|f| @employees[0][f]}
1182
+ end.should be_nil
1183
+ end
1184
+
1185
+ it "should return output parameter with cursor and fetch all rows as hash" do
1186
+ plsql.test_cursor_out do |result|
1187
+ result[:x_cursor].fetch_hash_all.should == @employees
1188
+ end.should be_nil
1189
+ end
1190
+
1191
+ it "should execute function with cursor parameter and return record" do
1192
+ pending "not possible from JDBC" if defined?(JRUBY_VERSION)
1193
+ plsql.test_cursor do |cursor|
1194
+ plsql.test_cursor_fetch(cursor).should == @employees[0]
1195
+ end
1196
+ end
484
1197
 
485
- it "should execute function and return correct value" do
486
- large_text = 'ābčdēfghij' * 10_000
487
- plsql.test_clob_proc(large_text)[:p_return].should == large_text
488
1198
  end
489
1199
  end
490
1200
 
491
- describe "Procedrue with BLOB parameter and return value" do
492
-
1201
+ describe "Synonyms /" do
1202
+
493
1203
  before(:all) do
494
1204
  plsql.connection = get_connection
495
- plsql.connection.exec <<-EOS
496
- CREATE OR REPLACE PROCEDURE test_blob_proc
497
- ( p_blob BLOB,
498
- p_return OUT BLOB)
499
- IS
500
- BEGIN
501
- p_return := p_blob;
502
- END test_blob_proc;
503
- EOS
504
1205
  end
505
-
1206
+
506
1207
  after(:all) do
507
1208
  plsql.logoff
508
1209
  end
509
-
510
- it "should find existing procedure" do
511
- PLSQL::Procedure.find(plsql, :test_blob_proc).should_not be_nil
512
- end
513
1210
 
514
- it "should execute function and return correct value" do
515
- large_binary = '\000\001\002\003\004\005\006\007\010\011' * 10_000
516
- plsql.test_blob_proc(large_binary)[:p_return].should == large_binary
517
- end
518
- end
519
-
520
- describe "Synonym to function" do
1211
+ describe "Local synonym to function" do
521
1212
 
522
- before(:all) do
523
- plsql.connection = get_connection
524
- plsql.connection.exec <<-EOS
525
- CREATE OR REPLACE FUNCTION hr.test_uppercase
526
- ( p_string VARCHAR2 )
527
- RETURN VARCHAR2
528
- IS
529
- BEGIN
530
- RETURN UPPER(p_string);
531
- END test_uppercase;
532
- EOS
533
- plsql.connection.exec "CREATE SYNONYM test_synonym FOR hr.test_uppercase"
534
- end
1213
+ before(:all) do
1214
+ plsql.connection.exec <<-EOS
1215
+ CREATE OR REPLACE FUNCTION hr.test_uppercase
1216
+ ( p_string VARCHAR2 )
1217
+ RETURN VARCHAR2
1218
+ IS
1219
+ BEGIN
1220
+ RETURN UPPER(p_string);
1221
+ END test_uppercase;
1222
+ EOS
1223
+ plsql.connection.exec "CREATE SYNONYM test_synonym FOR hr.test_uppercase"
1224
+ end
535
1225
 
536
- after(:all) do
537
- plsql.connection.exec "DROP SYNONYM test_synonym" rescue nil
538
- plsql.logoff
539
- end
1226
+ after(:all) do
1227
+ plsql.connection.exec "DROP SYNONYM test_synonym"
1228
+ plsql.connection.exec "DROP FUNCTION hr.test_uppercase"
1229
+ end
540
1230
 
541
- it "should find synonym to function" do
542
- PLSQL::Procedure.find(plsql, :test_synonym).should_not be_nil
543
- end
1231
+ it "should find synonym to function" do
1232
+ PLSQL::Procedure.find(plsql, :test_synonym).should_not be_nil
1233
+ end
544
1234
 
545
- it "should execute function using synonym and return correct value" do
546
- plsql.test_synonym('xxx').should == 'XXX'
547
- end
1235
+ it "should execute function using synonym and return correct value" do
1236
+ plsql.test_synonym('xxx').should == 'XXX'
1237
+ end
548
1238
 
549
- end
1239
+ end
550
1240
 
551
- describe "Public synonym to function" do
1241
+ describe "Public synonym to function" do
552
1242
 
553
- before(:all) do
554
- plsql.connection = get_connection
555
- plsql.connection.exec <<-EOS
556
- CREATE OR REPLACE FUNCTION hr.test_ora_login_user
557
- RETURN VARCHAR2
558
- IS
559
- BEGIN
560
- RETURN 'XXX';
561
- END test_ora_login_user;
562
- EOS
563
- end
1243
+ before(:all) do
1244
+ plsql.connection.exec <<-EOS
1245
+ CREATE OR REPLACE FUNCTION hr.test_ora_login_user
1246
+ RETURN VARCHAR2
1247
+ IS
1248
+ BEGIN
1249
+ RETURN 'XXX';
1250
+ END test_ora_login_user;
1251
+ EOS
1252
+ end
564
1253
 
565
- after(:all) do
566
- plsql.logoff
567
- end
1254
+ after(:all) do
1255
+ plsql.connection.exec "DROP FUNCTION hr.test_ora_login_user"
1256
+ end
568
1257
 
569
- it "should find public synonym to function" do
570
- PLSQL::Procedure.find(plsql, :ora_login_user).should_not be_nil
571
- end
1258
+ it "should find public synonym to function" do
1259
+ PLSQL::Procedure.find(plsql, :ora_login_user).should_not be_nil
1260
+ end
572
1261
 
573
- it "should execute function using public synonym and return correct value" do
574
- plsql.ora_login_user.should == 'HR'
575
- end
1262
+ it "should execute function using public synonym and return correct value" do
1263
+ plsql.ora_login_user.should == 'HR'
1264
+ end
1265
+
1266
+ it "should find private synonym before public synonym" do
1267
+ # should reconnect to force clearing of procedure cache
1268
+ plsql.connection = get_connection
1269
+ plsql.connection.exec "DROP SYNONYM ora_login_user" rescue nil
1270
+ plsql.connection.exec "CREATE SYNONYM ora_login_user FOR hr.test_ora_login_user"
1271
+ plsql.ora_login_user.should == 'XXX'
1272
+ plsql.connection.exec "DROP SYNONYM ora_login_user"
1273
+ plsql.connection = get_connection
1274
+ plsql.ora_login_user.should == 'HR'
1275
+ end
576
1276
 
577
- it "should find private synonym before public synonym" do
578
- # should reconnect to force clearing of procedure cache
579
- plsql.connection = get_connection
580
- plsql.connection.exec "CREATE SYNONYM ora_login_user FOR hr.test_ora_login_user"
581
- plsql.ora_login_user.should == 'XXX'
582
- plsql.connection.exec "DROP SYNONYM ora_login_user"
583
- plsql.connection = get_connection
584
- plsql.ora_login_user.should == 'HR'
585
1277
  end
586
1278
 
587
1279
  end