ruby-plsql 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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