flash-gordons-ruby-plsql 0.5.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.
@@ -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