flash-gordons-ruby-plsql 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,371 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Table" do
4
+ before(:all) do
5
+ plsql.connect! CONNECTION_PARAMS
6
+ plsql.connection.autocommit = false
7
+ plsql.execute <<-SQL
8
+ CREATE TABLE test_employees (
9
+ employee_id NUMBER(15) NOT NULL,
10
+ first_name VARCHAR2(50),
11
+ last_name VARCHAR2(50),
12
+ hire_date DATE,
13
+ created_at TIMESTAMP,
14
+ status VARCHAR2(1) DEFAULT 'N'
15
+ )
16
+ SQL
17
+
18
+ plsql.execute <<-SQL
19
+ CREATE OR REPLACE TYPE t_address AS OBJECT (
20
+ street VARCHAR2(50),
21
+ city VARCHAR2(50),
22
+ country VARCHAR2(50)
23
+ )
24
+ SQL
25
+ plsql.execute <<-SQL
26
+ CREATE OR REPLACE TYPE t_phone AS OBJECT (
27
+ type VARCHAR2(10),
28
+ phone_number VARCHAR2(50)
29
+ )
30
+ SQL
31
+ plsql.execute <<-SQL
32
+ CREATE OR REPLACE TYPE t_phones AS VARRAY(10) OF T_PHONE
33
+ SQL
34
+ plsql.execute <<-SQL
35
+ CREATE TABLE test_employees2 (
36
+ employee_id NUMBER(15) NOT NULL,
37
+ first_name VARCHAR2(50),
38
+ last_name VARCHAR2(50),
39
+ hire_date DATE DEFAULT SYSDATE,
40
+ address t_address,
41
+ phones t_phones
42
+ )
43
+ SQL
44
+ @employees = (1..10).map do |i|
45
+ {
46
+ :employee_id => i,
47
+ :first_name => "First #{i}",
48
+ :last_name => "Last #{i}",
49
+ :hire_date => Time.local(2000,01,i),
50
+ :created_at => Time.local(2000,01,i,9,15,30,i),
51
+ :status => 'A'
52
+ }
53
+ end
54
+ @employees_all_fields = [:employee_id, :first_name, :last_name, :hire_date, :created_at, :status]
55
+ @employees_all_values = @employees.map{|e| @employees_all_fields.map{|f| e[f]}}
56
+ @employees_some_fields = [:employee_id, :first_name, :last_name]
57
+ @employees_some_values = @employees.map{|e| @employees_some_fields.map{|f| e[f]}}
58
+ @employee_default_values = {:hire_date => nil, :created_at => nil, :status => 'N'}
59
+
60
+ @employees2 = (1..10).map do |i|
61
+ {
62
+ :employee_id => i,
63
+ :first_name => "First #{i}",
64
+ :last_name => "Last #{i}",
65
+ :hire_date => Time.local(2000,01,i),
66
+ :address => {:street => "Street #{i}", :city => "City #{i}", :country => "County #{i}"},
67
+ :phones => [{:type => "mobile", :phone_number => "Mobile#{i}"}, {:type => "fixed", :phone_number => "Fixed#{i}"}]
68
+ }
69
+ end
70
+ end
71
+
72
+ after(:all) do
73
+ plsql.execute "DROP TABLE test_employees"
74
+ plsql.execute "DROP TABLE test_employees2"
75
+ plsql.execute "DROP TYPE t_phones"
76
+ plsql.execute "DROP TYPE t_phone"
77
+ plsql.execute "DROP TYPE t_address"
78
+ plsql.logoff
79
+ end
80
+
81
+ after(:each) do
82
+ plsql.rollback
83
+ end
84
+
85
+ describe "find" do
86
+
87
+ it "should find existing table" do
88
+ PLSQL::Table.find(plsql, :test_employees).should_not be_nil
89
+ end
90
+
91
+ it "should not find nonexisting table" do
92
+ PLSQL::Table.find(plsql, :qwerty123456).should be_nil
93
+ end
94
+
95
+ it "should find existing table in schema" do
96
+ plsql.test_employees.should be_a(PLSQL::Table)
97
+ end
98
+
99
+ end
100
+
101
+ describe "synonym" do
102
+
103
+ before(:all) do
104
+ plsql.execute "CREATE SYNONYM test_employees_synonym FOR hr.test_employees"
105
+ end
106
+
107
+ after(:all) do
108
+ plsql.execute "DROP SYNONYM test_employees_synonym" rescue nil
109
+ end
110
+
111
+ it "should find synonym to table" do
112
+ PLSQL::Table.find(plsql, :test_employees_synonym).should_not be_nil
113
+ end
114
+
115
+ it "should find table using synonym in schema" do
116
+ plsql.test_employees_synonym.should be_a(PLSQL::Table)
117
+ end
118
+
119
+ end
120
+
121
+ describe "public synonym" do
122
+
123
+ it "should find public synonym to table" do
124
+ PLSQL::Table.find(plsql, :dual).should_not be_nil
125
+ end
126
+
127
+ it "should find table using public synonym in schema" do
128
+ plsql.dual.should be_a(PLSQL::Table)
129
+ end
130
+
131
+ end
132
+
133
+ describe "columns" do
134
+
135
+ it "should get column names for table" do
136
+ plsql.test_employees.column_names.should == @employees_all_fields
137
+ end
138
+
139
+ it "should get columns metadata for table" do
140
+ plsql.test_employees.columns.should == {
141
+ :employee_id => {
142
+ :position=>1, :data_type=>"NUMBER", :data_length=>22, :data_precision=>15, :data_scale=>0, :char_used=>nil,
143
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => false, :data_default => nil},
144
+ :first_name => {
145
+ :position=>2, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :char_used=>"B",
146
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => true, :data_default => nil},
147
+ :last_name => {
148
+ :position=>3, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :char_used=>"B",
149
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => true, :data_default => nil},
150
+ :hire_date => {
151
+ :position=>4, :data_type=>"DATE", :data_length=>7, :data_precision=>nil, :data_scale=>nil, :char_used=>nil,
152
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => true, :data_default => nil},
153
+ :created_at => {
154
+ :position=>5, :data_type=>"TIMESTAMP", :data_length=>11, :data_precision=>nil, :data_scale=>6, :char_used=>nil,
155
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => true, :data_default => nil},
156
+ :status => {
157
+ :position=>6, :data_type=>"VARCHAR2", :data_length=>1, :data_precision=>nil, :data_scale=>nil, :char_used=>"B",
158
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => true, :data_default => "'N'"}
159
+ }
160
+ end
161
+
162
+ it "should get columns metadata for table with object columns" do
163
+ plsql.test_employees2.columns.should == {
164
+ :employee_id => {
165
+ :position=>1, :data_type=>"NUMBER", :data_length=>22, :data_precision=>15, :data_scale=>0, :char_used=>nil,
166
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => false, :data_default => nil},
167
+ :first_name => {
168
+ :position=>2, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :char_used=>"B",
169
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => true, :data_default => nil},
170
+ :last_name => {
171
+ :position=>3, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :char_used=>"B",
172
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => true, :data_default => nil},
173
+ :hire_date => {
174
+ :position=>4, :data_type=>"DATE", :data_length=>7, :data_precision=>nil, :data_scale=>nil, :char_used=>nil,
175
+ :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil, :nullable => true, :data_default => "SYSDATE"},
176
+ :address => {
177
+ :position=>5, :data_type=>"OBJECT", :data_length=>nil, :data_precision=>nil, :data_scale=>nil,
178
+ :char_used=>nil, :type_owner=>"HR", :type_name=>"T_ADDRESS", :sql_type_name=>"HR.T_ADDRESS", :nullable => true, :data_default => nil},
179
+ :phones => {
180
+ :position=>6, :data_type=>"TABLE", :data_length=>nil, :data_precision=>nil, :data_scale=>nil, :char_used=>nil,
181
+ :type_owner=>"HR", :type_name=>"T_PHONES", :sql_type_name=>"HR.T_PHONES", :nullable => true, :data_default => nil}
182
+ }
183
+ end
184
+
185
+ end
186
+
187
+ describe "insert" do
188
+ it "should insert a record in table" do
189
+ plsql.test_employees.insert @employees.first
190
+ plsql.test_employees.all.should == [@employees.first]
191
+ end
192
+
193
+ it "should insert a record in table using partial list of columns" do
194
+ plsql.test_employees.insert @employees.first.except(:hire_date)
195
+ plsql.test_employees.all.should == [@employees.first.merge(:hire_date => nil)]
196
+ end
197
+
198
+ it "should insert default value from table definition if value not provided" do
199
+ plsql.test_employees.insert @employees.first.except(:status)
200
+ plsql.test_employees.all.should == [@employees.first.merge(:status => 'N')]
201
+ end
202
+
203
+ it "should insert array of records in table" do
204
+ plsql.test_employees.insert @employees
205
+ plsql.test_employees.all("ORDER BY employee_id").should == @employees
206
+ end
207
+
208
+ it "should insert a record in table with object types" do
209
+ plsql.test_employees2.insert @employees2.first
210
+ plsql.test_employees2.all.should == [@employees2.first]
211
+ end
212
+
213
+ it "should insert array of records in table with object types" do
214
+ plsql.test_employees2.insert @employees2
215
+ plsql.test_employees2.all("ORDER BY employee_id").should == @employees2
216
+ end
217
+
218
+ end
219
+
220
+ describe "insert values" do
221
+ it "should insert a record with array of values" do
222
+ plsql.test_employees.insert_values @employees_all_values.first
223
+ plsql.test_employees.all.should == [@employees.first]
224
+ end
225
+
226
+ it "should insert a record with list of all fields and array of values" do
227
+ plsql.test_employees.insert_values @employees_all_fields, @employees_all_values.first
228
+ plsql.test_employees.all.should == [@employees.first]
229
+ end
230
+
231
+ it "should insert a record with list of some fields and array of values" do
232
+ plsql.test_employees.insert_values @employees_some_fields, @employees_some_values.first
233
+ plsql.test_employees.all.should == [@employees.first.merge(@employee_default_values)]
234
+ end
235
+
236
+ it "should insert many records with array of values" do
237
+ plsql.test_employees.insert_values *@employees_all_values
238
+ plsql.test_employees.all.should == @employees
239
+ end
240
+
241
+ it "should insert many records with list of all fields and array of values" do
242
+ plsql.test_employees.insert_values @employees_all_fields, *@employees_all_values
243
+ plsql.test_employees.all.should == @employees
244
+ end
245
+
246
+ it "should insert many records with list of some fields and array of values" do
247
+ plsql.test_employees.insert_values @employees_some_fields, *@employees_some_values
248
+ plsql.test_employees.all.should == @employees.map{|e| e.merge(@employee_default_values)}
249
+ end
250
+
251
+ end
252
+
253
+ describe "select" do
254
+ before(:each) do
255
+ plsql.test_employees.insert @employees
256
+ end
257
+
258
+ it "should select first record in table" do
259
+ plsql.test_employees.select(:first, "ORDER BY employee_id").should == @employees.first
260
+ plsql.test_employees.first("ORDER BY employee_id").should == @employees.first
261
+ end
262
+
263
+ it "should select all records in table" do
264
+ plsql.test_employees.select(:all, "ORDER BY employee_id").should == @employees
265
+ plsql.test_employees.all("ORDER BY employee_id").should == @employees
266
+ plsql.test_employees.all(:order_by => :employee_id).should == @employees
267
+ end
268
+
269
+ it "should select record in table using WHERE condition" do
270
+ plsql.test_employees.select(:first, "WHERE employee_id = :1", @employees.first[:employee_id]).should == @employees.first
271
+ plsql.test_employees.first("WHERE employee_id = :1", @employees.first[:employee_id]).should == @employees.first
272
+ plsql.test_employees.first(:employee_id => @employees.first[:employee_id]).should == @employees.first
273
+ end
274
+
275
+ it "should select records in table using WHERE condition and ORDER BY sorting" do
276
+ plsql.test_employees.all(:employee_id => @employees.first[:employee_id], :order_by => :employee_id).should == [@employees.first]
277
+ end
278
+
279
+ it "should select record in table using :column => nil condition" do
280
+ employee = @employees.last.dup
281
+ employee[:employee_id] = employee[:employee_id] + 1
282
+ employee[:hire_date] = nil
283
+ plsql.test_employees.insert employee
284
+ plsql.test_employees.first("WHERE hire_date IS NULL").should == employee
285
+ plsql.test_employees.first(:hire_date => nil).should == employee
286
+ end
287
+
288
+ it "should select record in table using :column => :is_null condition" do
289
+ employee = @employees.last.dup
290
+ employee[:employee_id] = employee[:employee_id] + 1
291
+ employee[:hire_date] = nil
292
+ plsql.test_employees.insert employee
293
+ plsql.test_employees.first(:hire_date => :is_null).should == employee
294
+ end
295
+
296
+ it "should select record in table using :column => :is_not_null condition" do
297
+ employee = @employees.last.dup
298
+ employee[:employee_id] = employee[:employee_id] + 1
299
+ employee[:hire_date] = nil
300
+ plsql.test_employees.insert employee
301
+ plsql.test_employees.all(:hire_date => :is_not_null, :order_by => :employee_id).should == @employees
302
+ end
303
+
304
+ it "should count records in table" do
305
+ plsql.test_employees.select(:count).should == @employees.size
306
+ plsql.test_employees.count.should == @employees.size
307
+ end
308
+
309
+ it "should count records in table using condition" do
310
+ plsql.test_employees.select(:count, "WHERE employee_id <= :1", @employees[2][:employee_id]).should == 3
311
+ plsql.test_employees.count("WHERE employee_id <= :1", @employees[2][:employee_id]).should == 3
312
+ end
313
+
314
+ end
315
+
316
+ describe "update" do
317
+ it "should update a record in table" do
318
+ employee_id = @employees.first[:employee_id]
319
+ plsql.test_employees.insert @employees.first
320
+ plsql.test_employees.update :first_name => 'Test', :where => {:employee_id => employee_id}
321
+ plsql.test_employees.first(:employee_id => employee_id)[:first_name].should == 'Test'
322
+ end
323
+
324
+ it "should update a record in table using String WHERE condition" do
325
+ employee_id = @employees.first[:employee_id]
326
+ plsql.test_employees.insert @employees
327
+ plsql.test_employees.update :first_name => 'Test', :where => "employee_id = #{employee_id}"
328
+ plsql.test_employees.first(:employee_id => employee_id)[:first_name].should == 'Test'
329
+ # all other records should not be changed
330
+ plsql.test_employees.all("WHERE employee_id > :1", employee_id) do |employee|
331
+ employee[:first_name].should_not == 'Test'
332
+ end
333
+ end
334
+
335
+ it "should update all records in table" do
336
+ plsql.test_employees.insert @employees
337
+ plsql.test_employees.update :first_name => 'Test'
338
+ plsql.test_employees.all do |employee|
339
+ employee[:first_name].should == 'Test'
340
+ end
341
+ end
342
+
343
+ it "should update a record in table with object type" do
344
+ employee = @employees2[0]
345
+ employee2 = @employees2[1]
346
+ plsql.test_employees2.insert employee
347
+ plsql.test_employees2.update :address => employee2[:address], :phones => employee2[:phones], :where => {:employee_id => employee[:employee_id]}
348
+ updated_employee = plsql.test_employees2.first(:employee_id => employee[:employee_id])
349
+ updated_employee[:address].should == employee2[:address]
350
+ updated_employee[:phones].should == employee2[:phones]
351
+ end
352
+
353
+ end
354
+
355
+ describe "delete" do
356
+ it "should delete record from table" do
357
+ employee_id = @employees.first[:employee_id]
358
+ plsql.test_employees.insert @employees
359
+ plsql.test_employees.delete :employee_id => employee_id
360
+ plsql.test_employees.first(:employee_id => employee_id).should be_nil
361
+ plsql.test_employees.all(:order_by => :employee_id).should == @employees[1, @employees.size-1]
362
+ end
363
+
364
+ it "should delete all records from table" do
365
+ plsql.test_employees.insert @employees
366
+ plsql.test_employees.delete
367
+ plsql.test_employees.all.should be_empty
368
+ end
369
+ end
370
+
371
+ end
@@ -0,0 +1,304 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Type" do
4
+ before(:all) do
5
+ plsql.connection = get_connection
6
+ plsql.execute "DROP TYPE t_employee" rescue nil
7
+ plsql.execute "DROP TYPE t_phones" rescue nil
8
+ plsql.execute "DROP TYPE t_phone" rescue nil
9
+ plsql.execute <<-SQL
10
+ CREATE OR REPLACE TYPE t_address AS OBJECT (
11
+ street VARCHAR2(50),
12
+ city VARCHAR2(50),
13
+ country VARCHAR2(50),
14
+ CONSTRUCTOR FUNCTION t_address(p_full_address VARCHAR2)
15
+ RETURN SELF AS RESULT,
16
+ MEMBER FUNCTION display_address(p_separator VARCHAR2 DEFAULT ',') RETURN VARCHAR2,
17
+ MEMBER FUNCTION display_address(p_uppercase BOOLEAN, p_separator VARCHAR2 DEFAULT ',') RETURN VARCHAR2,
18
+ MEMBER PROCEDURE set_country(p_country VARCHAR2),
19
+ MEMBER PROCEDURE set_country2(p_country VARCHAR2, x_display_address OUT VARCHAR2),
20
+ STATIC FUNCTION create_address(p_full_address VARCHAR2) RETURN t_address
21
+ );
22
+ SQL
23
+ plsql.execute <<-SQL
24
+ CREATE OR REPLACE TYPE BODY t_address AS
25
+ CONSTRUCTOR FUNCTION t_address(p_full_address VARCHAR2)
26
+ RETURN SELF AS RESULT
27
+ AS
28
+ l_comma1_pos INTEGER;
29
+ l_comma2_pos INTEGER;
30
+ BEGIN
31
+ l_comma1_pos := INSTR(p_full_address, ',', 1, 1);
32
+ l_comma2_pos := INSTR(p_full_address, ',', 1, 2);
33
+ SELF.street := TRIM(SUBSTR(p_full_address, 1, l_comma1_pos - 1));
34
+ SELF.city := TRIM(SUBSTR(p_full_address, l_comma1_pos+1, l_comma2_pos - l_comma1_pos - 1));
35
+ SELF.country := TRIM(SUBSTR(p_full_address, l_comma2_pos+1));
36
+ RETURN;
37
+ END;
38
+ MEMBER FUNCTION display_address(p_separator VARCHAR2) RETURN VARCHAR2 IS
39
+ l_separator VARCHAR2(10) := p_separator;
40
+ BEGIN
41
+ IF SUBSTR(l_separator,-1) != ' ' THEN
42
+ l_separator := l_separator || ' ';
43
+ END IF;
44
+ RETURN SELF.street || l_separator || SELF.city || l_separator || SELF.country;
45
+ END;
46
+ MEMBER FUNCTION display_address(p_uppercase BOOLEAN, p_separator VARCHAR2) RETURN VARCHAR2 IS
47
+ l_separator VARCHAR2(10) := p_separator;
48
+ BEGIN
49
+ IF p_uppercase THEN
50
+ RETURN UPPER(SELF.display_address(p_separator));
51
+ ELSE
52
+ RETURN SELF.display_address(p_separator);
53
+ END IF;
54
+ END;
55
+ MEMBER PROCEDURE set_country(p_country VARCHAR2) IS
56
+ BEGIN
57
+ SELF.country := p_country;
58
+ END;
59
+ MEMBER PROCEDURE set_country2(p_country VARCHAR2, x_display_address OUT VARCHAR2) IS
60
+ BEGIN
61
+ SELF.country := p_country;
62
+ x_display_address := SELF.display_address();
63
+ END;
64
+ STATIC FUNCTION create_address(p_full_address VARCHAR2) RETURN t_address IS
65
+ BEGIN
66
+ RETURN t_address(p_full_address);
67
+ END;
68
+ END;
69
+ SQL
70
+ plsql.execute <<-SQL
71
+ CREATE OR REPLACE TYPE t_phone AS OBJECT (
72
+ type VARCHAR2(10),
73
+ phone_number VARCHAR2(50)
74
+ )
75
+ SQL
76
+ plsql.execute <<-SQL
77
+ CREATE OR REPLACE TYPE t_phones AS VARRAY(10) OF T_PHONE
78
+ SQL
79
+ plsql.execute <<-SQL
80
+ CREATE OR REPLACE TYPE t_employee AS OBJECT (
81
+ employee_id NUMBER(15),
82
+ first_name VARCHAR2(50),
83
+ last_name VARCHAR2(50),
84
+ hire_date DATE,
85
+ address t_address,
86
+ phones t_phones
87
+ )
88
+ SQL
89
+ end
90
+
91
+ after(:all) do
92
+ plsql.execute "DROP TYPE t_employee"
93
+ plsql.execute "DROP TYPE t_address"
94
+ plsql.execute "DROP TYPE t_phones"
95
+ plsql.execute "DROP TYPE t_phone"
96
+ plsql.logoff
97
+ end
98
+
99
+ after(:each) do
100
+ plsql.rollback
101
+ end
102
+
103
+ describe "find" do
104
+
105
+ it "should find existing type" do
106
+ PLSQL::Type.find(plsql, :t_employee).should_not be_nil
107
+ end
108
+
109
+ it "should not find nonexisting type" do
110
+ PLSQL::Type.find(plsql, :qwerty123456).should be_nil
111
+ end
112
+
113
+ it "should find existing type in schema" do
114
+ plsql.t_employee.should be_a(PLSQL::Type)
115
+ end
116
+
117
+ end
118
+
119
+ describe "synonym" do
120
+
121
+ before(:all) do
122
+ plsql.execute "CREATE SYNONYM t_employee_synonym FOR hr.t_employee"
123
+ end
124
+
125
+ after(:all) do
126
+ plsql.execute "DROP SYNONYM t_employee_synonym" rescue nil
127
+ end
128
+
129
+ it "should find synonym to type" do
130
+ PLSQL::Type.find(plsql, :t_employee_synonym).should_not be_nil
131
+ end
132
+
133
+ it "should find type using synonym in schema" do
134
+ plsql.t_employee_synonym.should be_a(PLSQL::Type)
135
+ end
136
+
137
+ end
138
+
139
+ describe "public synonym" do
140
+
141
+ it "should find public synonym to type" do
142
+ PLSQL::Type.find(plsql, :xmltype).should_not be_nil
143
+ end
144
+
145
+ it "should find type using public synonym in schema" do
146
+ plsql.xmltype.should be_a(PLSQL::Type)
147
+ end
148
+
149
+ end
150
+
151
+ describe "typecode" do
152
+
153
+ it "should get typecode of object type" do
154
+ plsql.t_employee.typecode.should == "OBJECT"
155
+ end
156
+
157
+ it "should get typecode of collection type" do
158
+ plsql.t_phones.typecode.should == "COLLECTION"
159
+ end
160
+
161
+ end
162
+
163
+ describe "attributes" do
164
+
165
+ it "should get attribute names" do
166
+ plsql.t_employee.attribute_names.should == [:employee_id, :first_name, :last_name, :hire_date, :address, :phones]
167
+ end
168
+
169
+ it "should get attributes metadata" do
170
+ plsql.t_employee.attributes.should == {
171
+ :employee_id =>
172
+ {:position=>1, :data_type=>"NUMBER", :data_length=>nil, :data_precision=>15, :data_scale=>0, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
173
+ :first_name =>
174
+ {:position=>2, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
175
+ :last_name =>
176
+ {:position=>3, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
177
+ :hire_date =>
178
+ {:position=>4, :data_type=>"DATE", :data_length=>nil, :data_precision=>nil, :data_scale=>nil, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
179
+ :address =>
180
+ {:position=>5, :data_type=>"OBJECT", :data_length=>nil, :data_precision=>nil, :data_scale=>nil, :type_owner=>"HR", :type_name=>"T_ADDRESS", :sql_type_name=>"HR.T_ADDRESS"},
181
+ :phones =>
182
+ {:position=>6, :data_type=>"TABLE", :data_length=>nil, :data_precision=>nil, :data_scale=>nil, :type_owner=>"HR", :type_name=>"T_PHONES", :sql_type_name=>"HR.T_PHONES"}
183
+ }
184
+ end
185
+
186
+ end
187
+
188
+ describe "object instance" do
189
+ before(:all) do
190
+ @phone_attributes = {:type => 'mobile', :phone_number => '123456'}
191
+ @address_attributes = {:street => 'Street', :city => 'City', :country => 'Country'}
192
+ @full_address = "#{@address_attributes[:street]}, #{@address_attributes[:city]}, #{@address_attributes[:country]}"
193
+ end
194
+
195
+ it "should get new object instance using named parameters" do
196
+ plsql.t_phone(@phone_attributes).should == @phone_attributes
197
+ end
198
+
199
+ it "should be an ObjectInstance" do
200
+ plsql.t_phone(@phone_attributes).should be_a(PLSQL::ObjectInstance)
201
+ end
202
+
203
+ it "should get new object instance using sequential parameters" do
204
+ plsql.t_phone(@phone_attributes[:type], @phone_attributes[:phone_number]).should == @phone_attributes
205
+ end
206
+
207
+ it "should get new object instance using custom constructor" do
208
+ plsql.t_address(@full_address).should == @address_attributes
209
+ plsql.t_address(:p_full_address => @full_address).should == @address_attributes
210
+ end
211
+
212
+ it "should get new object instance using default constructor when custom constructor exists" do
213
+ plsql.t_address(@address_attributes).should == @address_attributes
214
+ plsql.t_address(@address_attributes[:street], @address_attributes[:city], @address_attributes[:country]).should == @address_attributes
215
+ end
216
+
217
+ it "should get new empty collection of objects instance" do
218
+ plsql.t_phones.new.should == []
219
+ plsql.t_phones([]).should == []
220
+ end
221
+
222
+ it "should get new collection of objects instances" do
223
+ phone = plsql.t_phone(@phone_attributes)
224
+ plsql.t_phones([phone, phone]).should == [phone, phone]
225
+ plsql.t_phones(phone, phone).should == [phone, phone]
226
+ plsql.t_phones(@phone_attributes, @phone_attributes).should == [phone, phone]
227
+ end
228
+
229
+ end
230
+
231
+ describe "member procedures" do
232
+ before(:all) do
233
+ @address_attributes = {:street => 'Street', :city => 'City', :country => 'Country'}
234
+ @full_address = "#{@address_attributes[:street]}, #{@address_attributes[:city]}, #{@address_attributes[:country]}"
235
+ end
236
+
237
+ it "should call object instance member function without parameters" do
238
+ plsql.t_address(@address_attributes).display_address.should == @full_address
239
+ end
240
+
241
+ it "should call object instance member function with parameters" do
242
+ plsql.t_address(@address_attributes).display_address(',').should == @full_address
243
+ end
244
+
245
+ it "should call object instance member function with named parameters" do
246
+ plsql.t_address(@address_attributes).display_address(:p_separator => ',').should == @full_address
247
+ end
248
+
249
+ it "should call object overloaded instance member function" do
250
+ plsql.t_address(@address_attributes).display_address(true).should == @full_address.upcase
251
+ plsql.t_address(@address_attributes).display_address(true, ',').should == @full_address.upcase
252
+ end
253
+
254
+ it "should call object instance member function with explicit first SELF parameter" do
255
+ plsql.t_address.display_address(@address_attributes, ',').should == @full_address
256
+ end
257
+
258
+ it "should call object instance member function with explicit named SELF parameter" do
259
+ plsql.t_address.display_address(:self => @address_attributes, :p_separator => ',').should == @full_address
260
+ end
261
+
262
+ it "should call object instance member procedure" do
263
+ other_country = "Other"
264
+ plsql.t_address(@address_attributes).set_country(other_country).should == @address_attributes.merge(:country => other_country)
265
+ end
266
+
267
+ it "should call object instance member procedure with output parameters" do
268
+ other_country = "Other"
269
+ plsql.t_address(@address_attributes).set_country2(other_country).should ==
270
+ [@address_attributes.merge(:country => other_country),
271
+ {:x_display_address => "#{@address_attributes[:street]}, #{@address_attributes[:city]}, #{other_country}"}]
272
+ end
273
+
274
+ it "should raise error if invalid member procedure is called" do
275
+ lambda do
276
+ plsql.t_address(@address_attributes).invalid_procedure
277
+ end.should raise_error(ArgumentError)
278
+ end
279
+
280
+ end
281
+
282
+ describe "static procedures" do
283
+ before(:all) do
284
+ @address_attributes = {:street => 'Street', :city => 'City', :country => 'Country'}
285
+ @full_address = "#{@address_attributes[:street]}, #{@address_attributes[:city]}, #{@address_attributes[:country]}"
286
+ end
287
+
288
+ it "should call object type static function" do
289
+ plsql.t_address.create_address(@full_address).should == @address_attributes
290
+ end
291
+
292
+ it "should call object type static function with named parameters" do
293
+ plsql.t_address.create_address(:p_full_address => @full_address).should == @address_attributes
294
+ end
295
+
296
+ it "should raise error if invalid static procedure is called" do
297
+ lambda do
298
+ plsql.t_address.invalid_procedure
299
+ end.should raise_error(ArgumentError)
300
+ end
301
+
302
+ end
303
+
304
+ end