ruby-plsql 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -116,7 +116,7 @@ describe "ActiveRecord connection" do
116
116
  plsql.schema_name.should == 'HR'
117
117
  end
118
118
 
119
- it "should user ActiveRecord::Base.default_timezone as default" do
119
+ it "should use ActiveRecord::Base.default_timezone as default" do
120
120
  ActiveRecord::Base.default_timezone = :utc
121
121
  plsql.default_timezone.should == :utc
122
122
  end
@@ -125,3 +125,111 @@ describe "ActiveRecord connection" do
125
125
  plsql.hr.connection.should == plsql.connection
126
126
  end
127
127
  end
128
+
129
+ describe "DBMS_OUTPUT logging" do
130
+
131
+ before(:all) do
132
+ plsql.connection = get_connection
133
+ plsql.execute <<-SQL
134
+ CREATE OR REPLACE PROCEDURE test_dbms_output(p_string VARCHAR2)
135
+ IS
136
+ BEGIN
137
+ DBMS_OUTPUT.PUT_LINE(p_string);
138
+ END;
139
+ SQL
140
+ plsql.execute <<-SQL
141
+ CREATE OR REPLACE PROCEDURE test_dbms_output_large(p_string VARCHAR2, p_times INTEGER)
142
+ IS
143
+ i INTEGER;
144
+ BEGIN
145
+ FOR i IN 1..p_times LOOP
146
+ DBMS_OUTPUT.PUT_LINE(p_string);
147
+ END LOOP;
148
+ END;
149
+ SQL
150
+ @buffer = StringIO.new
151
+ end
152
+
153
+ before(:each) do
154
+ @buffer.rewind
155
+ @buffer.reopen
156
+ end
157
+
158
+ after(:all) do
159
+ plsql.dbms_output_stream = nil
160
+ plsql.execute "DROP PROCEDURE test_dbms_output"
161
+ plsql.logoff
162
+ end
163
+
164
+ describe "with standard connection" do
165
+ before(:all) do
166
+ plsql.dbms_output_stream = @buffer
167
+ end
168
+
169
+ before(:each) do
170
+ plsql.dbms_output_buffer_size = nil
171
+ end
172
+
173
+ it "should log output to specified stream" do
174
+ plsql.test_dbms_output("test_dbms_output")
175
+ @buffer.string.should == "DBMS_OUTPUT: test_dbms_output\n"
176
+ end
177
+
178
+ it "should not log output to stream when output is disabled" do
179
+ plsql.test_dbms_output("enabled")
180
+ plsql.dbms_output_stream = nil
181
+ plsql.test_dbms_output("disabled")
182
+ plsql.dbms_output_stream = @buffer
183
+ plsql.test_dbms_output("enabled again")
184
+ @buffer.string.should == "DBMS_OUTPUT: enabled\nDBMS_OUTPUT: enabled again\n"
185
+ end
186
+
187
+ it "should log 20_000 character output with default buffer size" do
188
+ times = 2_000
189
+ plsql.test_dbms_output_large("1234567890", times)
190
+ @buffer.string.should == "DBMS_OUTPUT: 1234567890\n" * times
191
+ end
192
+
193
+ it "should log 100_000 character output with specified buffer size" do
194
+ times = 10_000
195
+ plsql.dbms_output_buffer_size = 10 * times
196
+ plsql.test_dbms_output_large("1234567890", times)
197
+ @buffer.string.should == "DBMS_OUTPUT: 1234567890\n" * times
198
+ end
199
+
200
+ it "should log output when database version is less than 10.2" do
201
+ plsql.connection.stub!(:database_version).and_return([9, 2])
202
+ times = 2_000
203
+ plsql.test_dbms_output_large("1234567890", times)
204
+ @buffer.string.should == "DBMS_OUTPUT: 1234567890\n" * times
205
+ end
206
+
207
+ it "should log output when calling procedure with schema prefix" do
208
+ plsql.hr.test_dbms_output("test_dbms_output")
209
+ @buffer.string.should == "DBMS_OUTPUT: test_dbms_output\n"
210
+ end
211
+
212
+ end
213
+
214
+ describe "with Activerecord connection" do
215
+
216
+ before(:all) do
217
+ ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
218
+ plsql(:ar).activerecord_class = ActiveRecord::Base
219
+ plsql(:ar).dbms_output_stream = @buffer
220
+ end
221
+
222
+ it "should log output to specified stream" do
223
+ plsql(:ar).test_dbms_output("test_dbms_output")
224
+ @buffer.string.should == "DBMS_OUTPUT: test_dbms_output\n"
225
+ end
226
+
227
+ it "should log output after reconnection" do
228
+ ActiveRecord::Base.connection.reconnect!
229
+ plsql(:ar).test_dbms_output("after reconnection")
230
+ @buffer.string.should == "DBMS_OUTPUT: after reconnection\n"
231
+ end
232
+
233
+ end
234
+
235
+ end
@@ -41,6 +41,7 @@ describe "SQL statements /" do
41
41
  :hire_date => Time.local(2000,01,i)
42
42
  }
43
43
  end
44
+ plsql.connection.prefetch_rows = 100
44
45
  end
45
46
 
46
47
  before(:each) do
@@ -52,6 +53,7 @@ describe "SQL statements /" do
52
53
  after(:all) do
53
54
  plsql.execute "DROP PROCEDURE test_insert_employee"
54
55
  plsql.execute "DROP TABLE test_employees"
56
+ plsql.connection.prefetch_rows = 1
55
57
  end
56
58
 
57
59
  it "should select first result" do
@@ -59,6 +61,12 @@ describe "SQL statements /" do
59
61
  @employees.first[:employee_id]).should == @employees.first
60
62
  end
61
63
 
64
+ it "should prefetch only one row when selecting first result" do
65
+ lambda {
66
+ plsql.select(:first, "SELECT 1 FROM dual UNION ALL SELECT 1/0 FROM dual")
67
+ }.should_not raise_error
68
+ end
69
+
62
70
  it "should select one value" do
63
71
  plsql.select_one("SELECT count(*) FROM test_employees").should == @employees.size
64
72
  end
@@ -67,6 +75,12 @@ describe "SQL statements /" do
67
75
  plsql.select_one("SELECT employee_id FROM test_employees WHERE 1=2").should be_nil
68
76
  end
69
77
 
78
+ it "should prefetch only one row when selecting one value" do
79
+ lambda {
80
+ plsql.select_one("SELECT 1 FROM dual UNION ALL SELECT 1/0 FROM dual")
81
+ }.should_not raise_error
82
+ end
83
+
70
84
  it "should select all results" do
71
85
  plsql.select(:all, "SELECT * FROM test_employees ORDER BY employee_id").should == @employees
72
86
  plsql.select("SELECT * FROM test_employees ORDER BY employee_id").should == @employees
@@ -74,36 +88,4 @@ describe "SQL statements /" do
74
88
 
75
89
  end
76
90
 
77
- # describe "INSERT" do
78
- # before(:all) do
79
- # plsql.execute "DROP TABLE test_employees" rescue nil
80
- # plsql.execute <<-SQL
81
- # CREATE TABLE test_employees (
82
- # employee_id NUMBER(15),
83
- # first_name VARCHAR2(50),
84
- # last_name VARCHAR2(50),
85
- # hire_date DATE
86
- # )
87
- # SQL
88
- # @employees = (1..10).map do |i|
89
- # {
90
- # :employee_id => i,
91
- # :first_name => "First #{i}",
92
- # :last_name => "Last #{i}",
93
- # :hire_date => Time.local(2000,01,i)
94
- # }
95
- # end
96
- # end
97
- #
98
- # after(:all) do
99
- # plsql.execute "DROP TABLE test_employees"
100
- # end
101
- #
102
- # # it "should insert a record in table" do
103
- # # plsql.test_employees.insert @employees.first
104
- # # plsql.test_employees.select(:all).should == [@employees.first]
105
- # # end
106
- #
107
- # end
108
-
109
91
  end
@@ -9,27 +9,28 @@ describe "Table" do
9
9
  employee_id NUMBER(15),
10
10
  first_name VARCHAR2(50),
11
11
  last_name VARCHAR2(50),
12
- hire_date DATE
12
+ hire_date DATE,
13
+ status VARCHAR2(1) DEFAULT 'N'
13
14
  )
14
15
  SQL
15
16
 
16
- plsql.connection.exec <<-SQL
17
+ plsql.execute <<-SQL
17
18
  CREATE OR REPLACE TYPE t_address AS OBJECT (
18
19
  street VARCHAR2(50),
19
20
  city VARCHAR2(50),
20
21
  country VARCHAR2(50)
21
22
  )
22
23
  SQL
23
- plsql.connection.exec <<-SQL
24
+ plsql.execute <<-SQL
24
25
  CREATE OR REPLACE TYPE t_phone AS OBJECT (
25
26
  type VARCHAR2(10),
26
27
  phone_number VARCHAR2(50)
27
28
  )
28
29
  SQL
29
- plsql.connection.exec <<-SQL
30
+ plsql.execute <<-SQL
30
31
  CREATE OR REPLACE TYPE t_phones AS VARRAY(10) OF T_PHONE
31
32
  SQL
32
- plsql.connection.exec <<-SQL
33
+ plsql.execute <<-SQL
33
34
  CREATE TABLE test_employees2 (
34
35
  employee_id NUMBER(15),
35
36
  first_name VARCHAR2(50),
@@ -44,9 +45,16 @@ describe "Table" do
44
45
  :employee_id => i,
45
46
  :first_name => "First #{i}",
46
47
  :last_name => "Last #{i}",
47
- :hire_date => Time.local(2000,01,i)
48
+ :hire_date => Time.local(2000,01,i),
49
+ :status => 'A'
48
50
  }
49
51
  end
52
+ @employees_all_fields = [:employee_id, :first_name, :last_name, :hire_date, :status]
53
+ @employees_all_values = @employees.map{|e| @employees_all_fields.map{|f| e[f]}}
54
+ @employees_some_fields = [:employee_id, :first_name, :last_name]
55
+ @employees_some_values = @employees.map{|e| @employees_some_fields.map{|f| e[f]}}
56
+ @employee_default_values = {:hire_date => nil, :status => 'N'}
57
+
50
58
  @employees2 = (1..10).map do |i|
51
59
  {
52
60
  :employee_id => i,
@@ -91,11 +99,11 @@ describe "Table" do
91
99
  describe "synonym" do
92
100
 
93
101
  before(:all) do
94
- plsql.connection.exec "CREATE SYNONYM test_employees_synonym FOR hr.test_employees"
102
+ plsql.execute "CREATE SYNONYM test_employees_synonym FOR hr.test_employees"
95
103
  end
96
104
 
97
105
  after(:all) do
98
- plsql.connection.exec "DROP SYNONYM test_employees_synonym" rescue nil
106
+ plsql.execute "DROP SYNONYM test_employees_synonym" rescue nil
99
107
  end
100
108
 
101
109
  it "should find synonym to table" do
@@ -122,6 +130,10 @@ describe "Table" do
122
130
 
123
131
  describe "columns" do
124
132
 
133
+ it "should get column names for table" do
134
+ plsql.test_employees.column_names.should == [:employee_id, :first_name, :last_name, :hire_date, :status]
135
+ end
136
+
125
137
  it "should get columns metadata for table" do
126
138
  plsql.test_employees.columns.should == {
127
139
  :employee_id =>
@@ -131,7 +143,9 @@ describe "Table" do
131
143
  :last_name =>
132
144
  {:position=>3, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :char_used=>"B", :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
133
145
  :hire_date =>
134
- {:position=>4, :data_type=>"DATE", :data_length=>7, :data_precision=>nil, :data_scale=>nil, :char_used=>nil, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil}
146
+ {:position=>4, :data_type=>"DATE", :data_length=>7, :data_precision=>nil, :data_scale=>nil, :char_used=>nil, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
147
+ :status =>
148
+ {:position=>5, :data_type=>"VARCHAR2", :data_length=>1, :data_precision=>nil, :data_scale=>nil, :char_used=>"B", :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil}
135
149
  }
136
150
  end
137
151
 
@@ -160,6 +174,16 @@ describe "Table" do
160
174
  plsql.test_employees.all.should == [@employees.first]
161
175
  end
162
176
 
177
+ it "should insert a record in table using partial list of columns" do
178
+ plsql.test_employees.insert @employees.first.except(:hire_date)
179
+ plsql.test_employees.all.should == [@employees.first.merge(:hire_date => nil)]
180
+ end
181
+
182
+ it "should insert default value from table definition if value not provided" do
183
+ plsql.test_employees.insert @employees.first.except(:status)
184
+ plsql.test_employees.all.should == [@employees.first.merge(:status => 'N')]
185
+ end
186
+
163
187
  it "should insert array of records in table" do
164
188
  plsql.test_employees.insert @employees
165
189
  plsql.test_employees.all("ORDER BY employee_id").should == @employees
@@ -177,6 +201,39 @@ describe "Table" do
177
201
 
178
202
  end
179
203
 
204
+ describe "insert values" do
205
+ it "should insert a record with array of values" do
206
+ plsql.test_employees.insert_values @employees_all_values.first
207
+ plsql.test_employees.all.should == [@employees.first]
208
+ end
209
+
210
+ it "should insert a record with list of all fields and array of values" do
211
+ plsql.test_employees.insert_values @employees_all_fields, @employees_all_values.first
212
+ plsql.test_employees.all.should == [@employees.first]
213
+ end
214
+
215
+ it "should insert a record with list of some fields and array of values" do
216
+ plsql.test_employees.insert_values @employees_some_fields, @employees_some_values.first
217
+ plsql.test_employees.all.should == [@employees.first.merge(@employee_default_values)]
218
+ end
219
+
220
+ it "should insert many records with array of values" do
221
+ plsql.test_employees.insert_values *@employees_all_values
222
+ plsql.test_employees.all.should == @employees
223
+ end
224
+
225
+ it "should insert many records with list of all fields and array of values" do
226
+ plsql.test_employees.insert_values @employees_all_fields, *@employees_all_values
227
+ plsql.test_employees.all.should == @employees
228
+ end
229
+
230
+ it "should insert many records with list of some fields and array of values" do
231
+ plsql.test_employees.insert_values @employees_some_fields, *@employees_some_values
232
+ plsql.test_employees.all.should == @employees.map{|e| e.merge(@employee_default_values)}
233
+ end
234
+
235
+ end
236
+
180
237
  describe "select" do
181
238
  before(:each) do
182
239
  plsql.test_employees.insert @employees
@@ -199,6 +256,15 @@ describe "Table" do
199
256
  plsql.test_employees.first(:employee_id => @employees.first[:employee_id]).should == @employees.first
200
257
  end
201
258
 
259
+ it "should select record in table using :column => nil condition" do
260
+ employee = @employees.last
261
+ employee[:employee_id] = employee[:employee_id] + 1
262
+ employee[:hire_date] = nil
263
+ plsql.test_employees.insert employee
264
+ plsql.test_employees.first("WHERE hire_date IS NULL").should == employee
265
+ plsql.test_employees.first(:hire_date => nil).should == employee
266
+ end
267
+
202
268
  it "should count records in table" do
203
269
  plsql.test_employees.select(:count).should == @employees.size
204
270
  plsql.test_employees.count.should == @employees.size
@@ -0,0 +1,133 @@
1
+ require File.dirname(__FILE__) + '/../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 <<-SQL
9
+ CREATE OR REPLACE TYPE t_address AS OBJECT (
10
+ street VARCHAR2(50),
11
+ city VARCHAR2(50),
12
+ country VARCHAR2(50)
13
+ )
14
+ SQL
15
+ plsql.execute <<-SQL
16
+ CREATE OR REPLACE TYPE t_phone AS OBJECT (
17
+ type VARCHAR2(10),
18
+ phone_number VARCHAR2(50)
19
+ )
20
+ SQL
21
+ plsql.execute <<-SQL
22
+ CREATE OR REPLACE TYPE t_phones AS VARRAY(10) OF T_PHONE
23
+ SQL
24
+ plsql.execute <<-SQL
25
+ CREATE OR REPLACE TYPE t_employee AS OBJECT (
26
+ employee_id NUMBER(15),
27
+ first_name VARCHAR2(50),
28
+ last_name VARCHAR2(50),
29
+ hire_date DATE,
30
+ address t_address,
31
+ phones t_phones
32
+ )
33
+ SQL
34
+ end
35
+
36
+ after(:all) do
37
+ plsql.execute "DROP TYPE t_employee"
38
+ plsql.execute "DROP TYPE t_address"
39
+ plsql.execute "DROP TYPE t_phones"
40
+ plsql.execute "DROP TYPE t_phone"
41
+ plsql.logoff
42
+ end
43
+
44
+ after(:each) do
45
+ plsql.rollback
46
+ end
47
+
48
+ describe "find" do
49
+
50
+ it "should find existing type" do
51
+ PLSQL::Type.find(plsql, :t_employee).should_not be_nil
52
+ end
53
+
54
+ it "should not find nonexisting type" do
55
+ PLSQL::Type.find(plsql, :qwerty123456).should be_nil
56
+ end
57
+
58
+ it "should find existing type in schema" do
59
+ plsql.t_employee.should be_a(PLSQL::Type)
60
+ end
61
+
62
+ end
63
+
64
+ describe "synonym" do
65
+
66
+ before(:all) do
67
+ plsql.execute "CREATE SYNONYM t_employee_synonym FOR hr.t_employee"
68
+ end
69
+
70
+ after(:all) do
71
+ plsql.execute "DROP SYNONYM t_employee_synonym" rescue nil
72
+ end
73
+
74
+ it "should find synonym to type" do
75
+ PLSQL::Type.find(plsql, :t_employee_synonym).should_not be_nil
76
+ end
77
+
78
+ it "should find type using synonym in schema" do
79
+ plsql.t_employee_synonym.should be_a(PLSQL::Type)
80
+ end
81
+
82
+ end
83
+
84
+ describe "public synonym" do
85
+
86
+ it "should find public synonym to type" do
87
+ PLSQL::Type.find(plsql, :xmltype).should_not be_nil
88
+ end
89
+
90
+ it "should find type using public synonym in schema" do
91
+ plsql.xmltype.should be_a(PLSQL::Type)
92
+ end
93
+
94
+ end
95
+
96
+ describe "typecode" do
97
+
98
+ it "should get typecode of object type" do
99
+ plsql.t_employee.typecode.should == "OBJECT"
100
+ end
101
+
102
+ it "should get typecode of collection type" do
103
+ plsql.t_phones.typecode.should == "COLLECTION"
104
+ end
105
+
106
+ end
107
+
108
+ describe "attributes" do
109
+
110
+ it "should get attribute names" do
111
+ plsql.t_employee.attribute_names.should == [:employee_id, :first_name, :last_name, :hire_date, :address, :phones]
112
+ end
113
+
114
+ it "should get attributes metadata" do
115
+ plsql.t_employee.attributes.should == {
116
+ :employee_id =>
117
+ {:position=>1, :data_type=>"NUMBER", :data_length=>nil, :data_precision=>15, :data_scale=>0, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
118
+ :first_name =>
119
+ {:position=>2, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
120
+ :last_name =>
121
+ {:position=>3, :data_type=>"VARCHAR2", :data_length=>50, :data_precision=>nil, :data_scale=>nil, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
122
+ :hire_date =>
123
+ {:position=>4, :data_type=>"DATE", :data_length=>nil, :data_precision=>nil, :data_scale=>nil, :type_owner=>nil, :type_name=>nil, :sql_type_name=>nil},
124
+ :address =>
125
+ {: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"},
126
+ :phones =>
127
+ {: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"}
128
+ }
129
+ end
130
+
131
+ end
132
+
133
+ end