activerecord-oracle_enhanced-adapter 1.1.8 → 1.1.9
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.
- data/History.txt +10 -0
- data/README.txt +7 -66
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +84 -12
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +39 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +149 -798
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +1 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +826 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +85 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +4 -9
- data/spec/spec_helper.rb +31 -6
- metadata +7 -4
@@ -1,9 +1,9 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
-
require "composite_primary_keys"
|
3
2
|
|
4
3
|
describe "OracleEnhancedAdapter composite_primary_keys support" do
|
5
4
|
|
6
5
|
before(:all) do
|
6
|
+
require "composite_primary_keys"
|
7
7
|
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
8
8
|
:database => "xe",
|
9
9
|
:username => "hr",
|
@@ -0,0 +1,826 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "OracleEnhancedAdapter date type detection based on column names" do
|
4
|
+
before(:all) do
|
5
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
6
|
+
:database => "xe",
|
7
|
+
:username => "hr",
|
8
|
+
:password => "hr")
|
9
|
+
@conn = ActiveRecord::Base.connection
|
10
|
+
@conn.execute <<-SQL
|
11
|
+
CREATE TABLE test_employees (
|
12
|
+
employee_id NUMBER(6,0),
|
13
|
+
first_name VARCHAR2(20),
|
14
|
+
last_name VARCHAR2(25),
|
15
|
+
email VARCHAR2(25),
|
16
|
+
phone_number VARCHAR2(20),
|
17
|
+
hire_date DATE,
|
18
|
+
job_id NUMBER(6,0),
|
19
|
+
salary NUMBER(8,2),
|
20
|
+
commission_pct NUMBER(2,2),
|
21
|
+
manager_id NUMBER(6,0),
|
22
|
+
department_id NUMBER(4,0),
|
23
|
+
created_at DATE,
|
24
|
+
updated_at DATE
|
25
|
+
)
|
26
|
+
SQL
|
27
|
+
@conn.execute <<-SQL
|
28
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
29
|
+
INCREMENT BY 1 START WITH 10040 CACHE 20 NOORDER NOCYCLE
|
30
|
+
SQL
|
31
|
+
end
|
32
|
+
|
33
|
+
after(:all) do
|
34
|
+
@conn.execute "DROP TABLE test_employees"
|
35
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should set DATE column type as datetime if emulate_dates_by_column_name is false" do
|
39
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
40
|
+
columns = @conn.columns('test_employees')
|
41
|
+
column = columns.detect{|c| c.name == "hire_date"}
|
42
|
+
column.type.should == :datetime
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should set DATE column type as date if column name contains '_date_' and emulate_dates_by_column_name is true" do
|
46
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
47
|
+
columns = @conn.columns('test_employees')
|
48
|
+
column = columns.detect{|c| c.name == "hire_date"}
|
49
|
+
column.type.should == :date
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should set DATE column type as datetime if column name does not contain '_date_' and emulate_dates_by_column_name is true" do
|
53
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
54
|
+
columns = @conn.columns('test_employees')
|
55
|
+
column = columns.detect{|c| c.name == "created_at"}
|
56
|
+
column.type.should == :datetime
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should set DATE column type as datetime if column name contains 'date' as part of other word and emulate_dates_by_column_name is true" do
|
60
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
61
|
+
columns = @conn.columns('test_employees')
|
62
|
+
column = columns.detect{|c| c.name == "updated_at"}
|
63
|
+
column.type.should == :datetime
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return Time value from DATE column if emulate_dates_by_column_name is false" do
|
67
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
68
|
+
columns = @conn.columns('test_employees')
|
69
|
+
column = columns.detect{|c| c.name == "hire_date"}
|
70
|
+
column.type_cast(Time.now).class.should == Time
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should return Date value from DATE column if column name contains 'date' and emulate_dates_by_column_name is true" do
|
74
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
75
|
+
columns = @conn.columns('test_employees')
|
76
|
+
column = columns.detect{|c| c.name == "hire_date"}
|
77
|
+
column.type_cast(Time.now).class.should == Date
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "/ DATE values from ActiveRecord model" do
|
81
|
+
before(:each) do
|
82
|
+
ActiveRecord::Base.connection.clear_types_for_columns
|
83
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
84
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = false
|
85
|
+
class TestEmployee < ActiveRecord::Base
|
86
|
+
set_table_name "hr.test_employees"
|
87
|
+
set_primary_key :employee_id
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_test_employee
|
92
|
+
@today = Date.new(2008,8,19)
|
93
|
+
@now = Time.local(2008,8,19,17,03,59)
|
94
|
+
@employee = TestEmployee.create(
|
95
|
+
:first_name => "First",
|
96
|
+
:last_name => "Last",
|
97
|
+
:hire_date => @today,
|
98
|
+
:created_at => @now
|
99
|
+
)
|
100
|
+
@employee.reload
|
101
|
+
end
|
102
|
+
|
103
|
+
after(:each) do
|
104
|
+
# @employee.destroy if @employee
|
105
|
+
Object.send(:remove_const, "TestEmployee")
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should return Time value from DATE column if emulate_dates_by_column_name is false" do
|
109
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
110
|
+
create_test_employee
|
111
|
+
@employee.hire_date.class.should == Time
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should return Date value from DATE column if column name contains 'date' and emulate_dates_by_column_name is true" do
|
115
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
116
|
+
create_test_employee
|
117
|
+
@employee.hire_date.class.should == Date
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should return Time value from DATE column if column name does not contain 'date' and emulate_dates_by_column_name is true" do
|
121
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
122
|
+
create_test_employee
|
123
|
+
@employee.created_at.class.should == Time
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should return Date value from DATE column if emulate_dates_by_column_name is false but column is defined as date" do
|
127
|
+
class TestEmployee < ActiveRecord::Base
|
128
|
+
set_date_columns :hire_date
|
129
|
+
end
|
130
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
131
|
+
create_test_employee
|
132
|
+
@employee.hire_date.class.should == Date
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should return Time value from DATE column if emulate_dates_by_column_name is true but column is defined as datetime" do
|
136
|
+
class TestEmployee < ActiveRecord::Base
|
137
|
+
set_datetime_columns :hire_date
|
138
|
+
end
|
139
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
140
|
+
create_test_employee
|
141
|
+
@employee.hire_date.class.should == Time
|
142
|
+
# change to current time with hours, minutes and seconds
|
143
|
+
@employee.hire_date = @now
|
144
|
+
@employee.save!
|
145
|
+
@employee.reload
|
146
|
+
@employee.hire_date.class.should == Time
|
147
|
+
@employee.hire_date.should == @now
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should guess Date or Time value if emulate_dates is true" do
|
151
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = true
|
152
|
+
create_test_employee
|
153
|
+
@employee.hire_date.class.should == Date
|
154
|
+
@employee.created_at.class.should == Time
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "OracleEnhancedAdapter integer type detection based on column names" do
|
162
|
+
before(:all) do
|
163
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
164
|
+
:database => "xe",
|
165
|
+
:username => "hr",
|
166
|
+
:password => "hr")
|
167
|
+
@conn = ActiveRecord::Base.connection
|
168
|
+
@conn.execute <<-SQL
|
169
|
+
CREATE TABLE test2_employees (
|
170
|
+
id NUMBER,
|
171
|
+
first_name VARCHAR2(20),
|
172
|
+
last_name VARCHAR2(25),
|
173
|
+
email VARCHAR2(25),
|
174
|
+
phone_number VARCHAR2(20),
|
175
|
+
hire_date DATE,
|
176
|
+
job_id NUMBER,
|
177
|
+
salary NUMBER,
|
178
|
+
commission_pct NUMBER(2,2),
|
179
|
+
manager_id NUMBER(6),
|
180
|
+
department_id NUMBER(4,0),
|
181
|
+
created_at DATE
|
182
|
+
)
|
183
|
+
SQL
|
184
|
+
@conn.execute <<-SQL
|
185
|
+
CREATE SEQUENCE test2_employees_seq MINVALUE 1
|
186
|
+
INCREMENT BY 1 START WITH 10040 CACHE 20 NOORDER NOCYCLE
|
187
|
+
SQL
|
188
|
+
end
|
189
|
+
|
190
|
+
after(:all) do
|
191
|
+
@conn.execute "DROP TABLE test2_employees"
|
192
|
+
@conn.execute "DROP SEQUENCE test2_employees_seq"
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should set NUMBER column type as decimal if emulate_integers_by_column_name is false" do
|
196
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = false
|
197
|
+
columns = @conn.columns('test2_employees')
|
198
|
+
column = columns.detect{|c| c.name == "job_id"}
|
199
|
+
column.type.should == :decimal
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should set NUMBER column type as integer if emulate_integers_by_column_name is true" do
|
203
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
204
|
+
columns = @conn.columns('test2_employees')
|
205
|
+
column = columns.detect{|c| c.name == "job_id"}
|
206
|
+
column.type.should == :integer
|
207
|
+
column = columns.detect{|c| c.name == "id"}
|
208
|
+
column.type.should == :integer
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should set NUMBER column type as decimal if column name does not contain 'id' and emulate_integers_by_column_name is true" do
|
212
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
213
|
+
columns = @conn.columns('test2_employees')
|
214
|
+
column = columns.detect{|c| c.name == "salary"}
|
215
|
+
column.type.should == :decimal
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should return BigDecimal value from NUMBER column if emulate_integers_by_column_name is false" do
|
219
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = false
|
220
|
+
columns = @conn.columns('test2_employees')
|
221
|
+
column = columns.detect{|c| c.name == "job_id"}
|
222
|
+
column.type_cast(1.0).class.should == BigDecimal
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should return Fixnum value from NUMBER column if column name contains 'id' and emulate_integers_by_column_name is true" do
|
226
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
227
|
+
columns = @conn.columns('test2_employees')
|
228
|
+
column = columns.detect{|c| c.name == "job_id"}
|
229
|
+
column.type_cast(1.0).class.should == Fixnum
|
230
|
+
end
|
231
|
+
|
232
|
+
describe "/ NUMBER values from ActiveRecord model" do
|
233
|
+
before(:each) do
|
234
|
+
class Test2Employee < ActiveRecord::Base
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
after(:each) do
|
239
|
+
Object.send(:remove_const, "Test2Employee")
|
240
|
+
end
|
241
|
+
|
242
|
+
def create_employee2
|
243
|
+
@employee2 = Test2Employee.create(
|
244
|
+
:first_name => "First",
|
245
|
+
:last_name => "Last",
|
246
|
+
:job_id => 1,
|
247
|
+
:salary => 1000
|
248
|
+
)
|
249
|
+
@employee2.reload
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should return BigDecimal value from NUMBER column if emulate_integers_by_column_name is false" do
|
253
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = false
|
254
|
+
create_employee2
|
255
|
+
@employee2.job_id.class.should == BigDecimal
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should return Fixnum value from NUMBER column if column name contains 'id' and emulate_integers_by_column_name is true" do
|
259
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
260
|
+
create_employee2
|
261
|
+
@employee2.job_id.class.should == Fixnum
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should return BigDecimal value from NUMBER column if column name does not contain 'id' and emulate_integers_by_column_name is true" do
|
265
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
266
|
+
create_employee2
|
267
|
+
@employee2.salary.class.should == BigDecimal
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
describe "OracleEnhancedAdapter boolean type detection based on string column types and names" do
|
275
|
+
before(:all) do
|
276
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
277
|
+
:database => "xe",
|
278
|
+
:username => "hr",
|
279
|
+
:password => "hr")
|
280
|
+
@conn = ActiveRecord::Base.connection
|
281
|
+
@conn.execute <<-SQL
|
282
|
+
CREATE TABLE test3_employees (
|
283
|
+
id NUMBER,
|
284
|
+
first_name VARCHAR2(20),
|
285
|
+
last_name VARCHAR2(25),
|
286
|
+
email VARCHAR2(25),
|
287
|
+
phone_number VARCHAR2(20),
|
288
|
+
hire_date DATE,
|
289
|
+
job_id NUMBER,
|
290
|
+
salary NUMBER,
|
291
|
+
commission_pct NUMBER(2,2),
|
292
|
+
manager_id NUMBER(6),
|
293
|
+
department_id NUMBER(4,0),
|
294
|
+
created_at DATE,
|
295
|
+
has_email CHAR(1),
|
296
|
+
has_phone VARCHAR2(1),
|
297
|
+
active_flag VARCHAR2(2),
|
298
|
+
manager_yn VARCHAR2(3),
|
299
|
+
test_boolean VARCHAR2(3)
|
300
|
+
)
|
301
|
+
SQL
|
302
|
+
@conn.execute <<-SQL
|
303
|
+
CREATE SEQUENCE test3_employees_seq MINVALUE 1
|
304
|
+
INCREMENT BY 1 START WITH 10040 CACHE 20 NOORDER NOCYCLE
|
305
|
+
SQL
|
306
|
+
end
|
307
|
+
|
308
|
+
after(:all) do
|
309
|
+
@conn.execute "DROP TABLE test3_employees"
|
310
|
+
@conn.execute "DROP SEQUENCE test3_employees_seq"
|
311
|
+
end
|
312
|
+
|
313
|
+
it "should set CHAR/VARCHAR2 column type as string if emulate_booleans_from_strings is false" do
|
314
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
315
|
+
columns = @conn.columns('test3_employees')
|
316
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
317
|
+
column = columns.detect{|c| c.name == col}
|
318
|
+
column.type.should == :string
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
it "should set CHAR/VARCHAR2 column type as boolean if emulate_booleans_from_strings is true" do
|
323
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
324
|
+
columns = @conn.columns('test3_employees')
|
325
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
326
|
+
column = columns.detect{|c| c.name == col}
|
327
|
+
column.type.should == :boolean
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
it "should set VARCHAR2 column type as string if column name does not contain 'flag' or 'yn' and emulate_booleans_from_strings is true" do
|
332
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
333
|
+
columns = @conn.columns('test3_employees')
|
334
|
+
%w(phone_number email).each do |col|
|
335
|
+
column = columns.detect{|c| c.name == col}
|
336
|
+
column.type.should == :string
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
it "should return string value from VARCHAR2 boolean column if emulate_booleans_from_strings is false" do
|
341
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
342
|
+
columns = @conn.columns('test3_employees')
|
343
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
344
|
+
column = columns.detect{|c| c.name == col}
|
345
|
+
column.type_cast("Y").class.should == String
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
it "should return boolean value from VARCHAR2 boolean column if emulate_booleans_from_strings is true" do
|
350
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
351
|
+
columns = @conn.columns('test3_employees')
|
352
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
353
|
+
column = columns.detect{|c| c.name == col}
|
354
|
+
column.type_cast("Y").class.should == TrueClass
|
355
|
+
column.type_cast("N").class.should == FalseClass
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
it "should translate boolean type to VARCHAR2(1) if emulate_booleans_from_strings is true" do
|
360
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
361
|
+
ActiveRecord::Base.connection.type_to_sql(
|
362
|
+
:boolean, nil, nil, nil).should == "VARCHAR2(1)"
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should translate boolean type to NUMBER(1) if emulate_booleans_from_strings is true" do
|
366
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
367
|
+
ActiveRecord::Base.connection.type_to_sql(
|
368
|
+
:boolean, nil, nil, nil).should == "NUMBER(1)"
|
369
|
+
end
|
370
|
+
|
371
|
+
describe "/ VARCHAR2 boolean values from ActiveRecord model" do
|
372
|
+
before(:each) do
|
373
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
374
|
+
class Test3Employee < ActiveRecord::Base
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
after(:each) do
|
379
|
+
Object.send(:remove_const, "Test3Employee")
|
380
|
+
end
|
381
|
+
|
382
|
+
def create_employee3(params={})
|
383
|
+
@employee3 = Test3Employee.create(
|
384
|
+
{
|
385
|
+
:first_name => "First",
|
386
|
+
:last_name => "Last",
|
387
|
+
:has_email => true,
|
388
|
+
:has_phone => false,
|
389
|
+
:active_flag => true,
|
390
|
+
:manager_yn => false
|
391
|
+
}.merge(params)
|
392
|
+
)
|
393
|
+
@employee3.reload
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should return String value from VARCHAR2 boolean column if emulate_booleans_from_strings is false" do
|
397
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
398
|
+
create_employee3
|
399
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
400
|
+
@employee3.send(col.to_sym).class.should == String
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
it "should return boolean value from VARCHAR2 boolean column if emulate_booleans_from_strings is true" do
|
405
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
406
|
+
create_employee3
|
407
|
+
%w(has_email active_flag).each do |col|
|
408
|
+
@employee3.send(col.to_sym).class.should == TrueClass
|
409
|
+
@employee3.send((col+"_before_type_cast").to_sym).should == "Y"
|
410
|
+
end
|
411
|
+
%w(has_phone manager_yn).each do |col|
|
412
|
+
@employee3.send(col.to_sym).class.should == FalseClass
|
413
|
+
@employee3.send((col+"_before_type_cast").to_sym).should == "N"
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
it "should return string value from VARCHAR2 column if it is not boolean column and emulate_booleans_from_strings is true" do
|
418
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
419
|
+
create_employee3
|
420
|
+
@employee3.first_name.class.should == String
|
421
|
+
end
|
422
|
+
|
423
|
+
it "should return boolean value from VARCHAR2 boolean column if column specified in set_boolean_columns" do
|
424
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
425
|
+
class Test3Employee < ActiveRecord::Base
|
426
|
+
set_boolean_columns :test_boolean
|
427
|
+
end
|
428
|
+
create_employee3(:test_boolean => true)
|
429
|
+
@employee3.test_boolean.class.should == TrueClass
|
430
|
+
@employee3.test_boolean_before_type_cast.should == "Y"
|
431
|
+
create_employee3(:test_boolean => false)
|
432
|
+
@employee3.test_boolean.class.should == FalseClass
|
433
|
+
@employee3.test_boolean_before_type_cast.should == "N"
|
434
|
+
end
|
435
|
+
|
436
|
+
end
|
437
|
+
|
438
|
+
end
|
439
|
+
|
440
|
+
describe "OracleEnhancedAdapter timestamp with timezone support" do
|
441
|
+
before(:all) do
|
442
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
443
|
+
:database => "xe",
|
444
|
+
:username => "hr",
|
445
|
+
:password => "hr")
|
446
|
+
@conn = ActiveRecord::Base.connection
|
447
|
+
@conn.execute <<-SQL
|
448
|
+
CREATE TABLE test_employees (
|
449
|
+
employee_id NUMBER(6,0),
|
450
|
+
first_name VARCHAR2(20),
|
451
|
+
last_name VARCHAR2(25),
|
452
|
+
email VARCHAR2(25),
|
453
|
+
phone_number VARCHAR2(20),
|
454
|
+
hire_date DATE,
|
455
|
+
job_id NUMBER(6,0),
|
456
|
+
salary NUMBER(8,2),
|
457
|
+
commission_pct NUMBER(2,2),
|
458
|
+
manager_id NUMBER(6,0),
|
459
|
+
department_id NUMBER(4,0),
|
460
|
+
created_at TIMESTAMP,
|
461
|
+
created_at_tz TIMESTAMP WITH TIME ZONE,
|
462
|
+
created_at_ltz TIMESTAMP WITH LOCAL TIME ZONE
|
463
|
+
)
|
464
|
+
SQL
|
465
|
+
@conn.execute <<-SQL
|
466
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
467
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
468
|
+
SQL
|
469
|
+
end
|
470
|
+
|
471
|
+
after(:all) do
|
472
|
+
@conn.execute "DROP TABLE test_employees"
|
473
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
474
|
+
end
|
475
|
+
|
476
|
+
it "should set TIMESTAMP columns type as datetime" do
|
477
|
+
columns = @conn.columns('test_employees')
|
478
|
+
ts_columns = columns.select{|c| c.name =~ /created_at/}
|
479
|
+
ts_columns.each {|c| c.type.should == :timestamp}
|
480
|
+
end
|
481
|
+
|
482
|
+
describe "/ TIMESTAMP WITH TIME ZONE values from ActiveRecord model" do
|
483
|
+
before(:all) do
|
484
|
+
class TestEmployee < ActiveRecord::Base
|
485
|
+
set_primary_key :employee_id
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
after(:all) do
|
490
|
+
Object.send(:remove_const, "TestEmployee")
|
491
|
+
end
|
492
|
+
|
493
|
+
it "should return Time value from TIMESTAMP columns" do
|
494
|
+
# currently fractional seconds are not retrieved from database
|
495
|
+
@now = Time.local(2008,5,26,23,11,11,0)
|
496
|
+
@employee = TestEmployee.create(
|
497
|
+
:created_at => @now,
|
498
|
+
:created_at_tz => @now,
|
499
|
+
:created_at_ltz => @now
|
500
|
+
)
|
501
|
+
@employee.reload
|
502
|
+
[:created_at, :created_at_tz, :created_at_ltz].each do |c|
|
503
|
+
@employee.send(c).class.should == Time
|
504
|
+
@employee.send(c).to_f.should == @now.to_f
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
it "should return Time value without fractional seconds from TIMESTAMP columns" do
|
509
|
+
# currently fractional seconds are not retrieved from database
|
510
|
+
@now = Time.local(2008,5,26,23,11,11,10)
|
511
|
+
@employee = TestEmployee.create(
|
512
|
+
:created_at => @now,
|
513
|
+
:created_at_tz => @now,
|
514
|
+
:created_at_ltz => @now
|
515
|
+
)
|
516
|
+
@employee.reload
|
517
|
+
[:created_at, :created_at_tz, :created_at_ltz].each do |c|
|
518
|
+
@employee.send(c).class.should == Time
|
519
|
+
@employee.send(c).to_f.should == @now.to_f.to_i.to_f # remove fractional seconds
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
end
|
524
|
+
|
525
|
+
end
|
526
|
+
|
527
|
+
|
528
|
+
describe "OracleEnhancedAdapter date and timestamp with different NLS date formats" do
|
529
|
+
before(:all) do
|
530
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
531
|
+
:database => "xe",
|
532
|
+
:username => "hr",
|
533
|
+
:password => "hr")
|
534
|
+
@conn = ActiveRecord::Base.connection
|
535
|
+
@conn.execute <<-SQL
|
536
|
+
CREATE TABLE test_employees (
|
537
|
+
employee_id NUMBER(6,0),
|
538
|
+
first_name VARCHAR2(20),
|
539
|
+
last_name VARCHAR2(25),
|
540
|
+
email VARCHAR2(25),
|
541
|
+
phone_number VARCHAR2(20),
|
542
|
+
hire_date DATE,
|
543
|
+
job_id NUMBER(6,0),
|
544
|
+
salary NUMBER(8,2),
|
545
|
+
commission_pct NUMBER(2,2),
|
546
|
+
manager_id NUMBER(6,0),
|
547
|
+
department_id NUMBER(4,0),
|
548
|
+
created_at DATE,
|
549
|
+
created_at_ts TIMESTAMP
|
550
|
+
)
|
551
|
+
SQL
|
552
|
+
@conn.execute <<-SQL
|
553
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
554
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
555
|
+
SQL
|
556
|
+
# @conn.execute %q{alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'}
|
557
|
+
@conn.execute %q{alter session set nls_date_format = 'DD-MON-YYYY HH24:MI:SS'}
|
558
|
+
# @conn.execute %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'}
|
559
|
+
@conn.execute %q{alter session set nls_timestamp_format = 'DD-MON-YYYY HH24:MI:SS'}
|
560
|
+
end
|
561
|
+
|
562
|
+
after(:all) do
|
563
|
+
@conn.execute "DROP TABLE test_employees"
|
564
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
565
|
+
end
|
566
|
+
|
567
|
+
before(:each) do
|
568
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = false
|
569
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
570
|
+
class TestEmployee < ActiveRecord::Base
|
571
|
+
set_primary_key :employee_id
|
572
|
+
end
|
573
|
+
@today = Date.new(2008,6,28)
|
574
|
+
@now = Time.local(2008,6,28,13,34,33)
|
575
|
+
end
|
576
|
+
|
577
|
+
after(:each) do
|
578
|
+
Object.send(:remove_const, "TestEmployee")
|
579
|
+
end
|
580
|
+
|
581
|
+
def create_test_employee
|
582
|
+
@employee = TestEmployee.create(
|
583
|
+
:first_name => "First",
|
584
|
+
:last_name => "Last",
|
585
|
+
:hire_date => @today,
|
586
|
+
:created_at => @now,
|
587
|
+
:created_at_ts => @now
|
588
|
+
)
|
589
|
+
@employee.reload
|
590
|
+
end
|
591
|
+
|
592
|
+
it "should return Time value from DATE column if emulate_dates_by_column_name is false" do
|
593
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
594
|
+
create_test_employee
|
595
|
+
@employee.hire_date.class.should == Time
|
596
|
+
@employee.hire_date.should == @today.to_time
|
597
|
+
end
|
598
|
+
|
599
|
+
it "should return Date value from DATE column if column name contains 'date' and emulate_dates_by_column_name is true" do
|
600
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
601
|
+
create_test_employee
|
602
|
+
@employee.hire_date.class.should == Date
|
603
|
+
@employee.hire_date.should == @today
|
604
|
+
end
|
605
|
+
|
606
|
+
it "should return Time value from DATE column if column name does not contain 'date' and emulate_dates_by_column_name is true" do
|
607
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
608
|
+
create_test_employee
|
609
|
+
@employee.created_at.class.should == Time
|
610
|
+
@employee.created_at.should == @now
|
611
|
+
end
|
612
|
+
|
613
|
+
it "should return Time value from TIMESTAMP columns" do
|
614
|
+
create_test_employee
|
615
|
+
@employee.created_at_ts.class.should == Time
|
616
|
+
@employee.created_at_ts.should == @now
|
617
|
+
end
|
618
|
+
|
619
|
+
it "should quote Date values with TO_DATE" do
|
620
|
+
@conn.quote(@today).should == "TO_DATE('#{@today.year}-#{"%02d" % @today.month}-#{"%02d" % @today.day}','YYYY-MM-DD HH24:MI:SS')"
|
621
|
+
end
|
622
|
+
|
623
|
+
it "should quote Time values with TO_DATE" do
|
624
|
+
@conn.quote(@now).should == "TO_DATE('#{@now.year}-#{"%02d" % @now.month}-#{"%02d" % @now.day} "+
|
625
|
+
"#{"%02d" % @now.hour}:#{"%02d" % @now.min}:#{"%02d" % @now.sec}','YYYY-MM-DD HH24:MI:SS')"
|
626
|
+
end
|
627
|
+
|
628
|
+
it "should quote Time values with TO_TIMESTAMP" do
|
629
|
+
@ts = Time.at(@now.to_f + 0.1)
|
630
|
+
@conn.quote(@ts).should == "TO_TIMESTAMP('#{@ts.year}-#{"%02d" % @ts.month}-#{"%02d" % @ts.day} "+
|
631
|
+
"#{"%02d" % @ts.hour}:#{"%02d" % @ts.min}:#{"%02d" % @ts.sec}.100000','YYYY-MM-DD HH24:MI:SS.FF6')"
|
632
|
+
end
|
633
|
+
|
634
|
+
end
|
635
|
+
|
636
|
+
describe "OracleEnhancedAdapter assign string to :date and :datetime columns" do
|
637
|
+
before(:all) do
|
638
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
639
|
+
:database => "xe",
|
640
|
+
:username => "hr",
|
641
|
+
:password => "hr")
|
642
|
+
@conn = ActiveRecord::Base.connection
|
643
|
+
@conn.execute <<-SQL
|
644
|
+
CREATE TABLE test_employees (
|
645
|
+
employee_id NUMBER(6,0),
|
646
|
+
first_name VARCHAR2(20),
|
647
|
+
last_name VARCHAR2(25),
|
648
|
+
hire_date DATE,
|
649
|
+
last_login_at DATE,
|
650
|
+
last_login_at_ts TIMESTAMP
|
651
|
+
)
|
652
|
+
SQL
|
653
|
+
@conn.execute <<-SQL
|
654
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
655
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
656
|
+
SQL
|
657
|
+
class TestEmployee < ActiveRecord::Base
|
658
|
+
set_primary_key :employee_id
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
after(:all) do
|
663
|
+
Object.send(:remove_const, "TestEmployee")
|
664
|
+
@conn.execute "DROP TABLE test_employees"
|
665
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
666
|
+
end
|
667
|
+
|
668
|
+
before(:each) do
|
669
|
+
@today = Date.new(2008,6,28)
|
670
|
+
@today_iso = "2008-06-28"
|
671
|
+
@today_nls = "28.06.2008"
|
672
|
+
@nls_date_format = "%d.%m.%Y"
|
673
|
+
@now = Time.local(2008,6,28,13,34,33)
|
674
|
+
@now_iso = "2008-06-28 13:34:33"
|
675
|
+
@now_nls = "28.06.2008 13:34:33"
|
676
|
+
@nls_time_format = "%d.%m.%Y %H:%M:%S"
|
677
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
678
|
+
end
|
679
|
+
|
680
|
+
it "should assign ISO string to date column" do
|
681
|
+
@employee = TestEmployee.create(
|
682
|
+
:first_name => "First",
|
683
|
+
:last_name => "Last",
|
684
|
+
:hire_date => @today_iso
|
685
|
+
)
|
686
|
+
@employee.reload
|
687
|
+
@employee.hire_date.should == @today
|
688
|
+
end
|
689
|
+
|
690
|
+
it "should assign NLS string to date column" do
|
691
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = @nls_date_format
|
692
|
+
@employee = TestEmployee.create(
|
693
|
+
:first_name => "First",
|
694
|
+
:last_name => "Last",
|
695
|
+
:hire_date => @today_nls
|
696
|
+
)
|
697
|
+
@employee.reload
|
698
|
+
@employee.hire_date.should == @today
|
699
|
+
end
|
700
|
+
|
701
|
+
it "should assign ISO time string to date column" do
|
702
|
+
@employee = TestEmployee.create(
|
703
|
+
:first_name => "First",
|
704
|
+
:last_name => "Last",
|
705
|
+
:hire_date => @now_iso
|
706
|
+
)
|
707
|
+
@employee.reload
|
708
|
+
@employee.hire_date.should == @today
|
709
|
+
end
|
710
|
+
|
711
|
+
it "should assign NLS time string to date column" do
|
712
|
+
# ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = @nls_date_format
|
713
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = @nls_time_format
|
714
|
+
@employee = TestEmployee.create(
|
715
|
+
:first_name => "First",
|
716
|
+
:last_name => "Last",
|
717
|
+
:hire_date => @now_nls
|
718
|
+
)
|
719
|
+
@employee.reload
|
720
|
+
@employee.hire_date.should == @today
|
721
|
+
end
|
722
|
+
|
723
|
+
it "should assign ISO time string to datetime column" do
|
724
|
+
@employee = TestEmployee.create(
|
725
|
+
:first_name => "First",
|
726
|
+
:last_name => "Last",
|
727
|
+
:last_login_at => @now_iso
|
728
|
+
)
|
729
|
+
@employee.reload
|
730
|
+
@employee.last_login_at.should == @now
|
731
|
+
end
|
732
|
+
|
733
|
+
it "should assign NLS time string to datetime column" do
|
734
|
+
# ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = @nls_date_format
|
735
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = @nls_time_format
|
736
|
+
@employee = TestEmployee.create(
|
737
|
+
:first_name => "First",
|
738
|
+
:last_name => "Last",
|
739
|
+
:last_login_at => @now_nls
|
740
|
+
)
|
741
|
+
@employee.reload
|
742
|
+
@employee.last_login_at.should == @now
|
743
|
+
end
|
744
|
+
|
745
|
+
it "should assign ISO date string to datetime column" do
|
746
|
+
@employee = TestEmployee.create(
|
747
|
+
:first_name => "First",
|
748
|
+
:last_name => "Last",
|
749
|
+
:last_login_at => @today_iso
|
750
|
+
)
|
751
|
+
@employee.reload
|
752
|
+
@employee.last_login_at.should == @today.to_time
|
753
|
+
end
|
754
|
+
|
755
|
+
it "should assign NLS date string to datetime column" do
|
756
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = @nls_date_format
|
757
|
+
# ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = @nls_time_format
|
758
|
+
@employee = TestEmployee.create(
|
759
|
+
:first_name => "First",
|
760
|
+
:last_name => "Last",
|
761
|
+
:last_login_at => @today_nls
|
762
|
+
)
|
763
|
+
@employee.reload
|
764
|
+
@employee.last_login_at.should == @today.to_time
|
765
|
+
end
|
766
|
+
|
767
|
+
end
|
768
|
+
|
769
|
+
describe "OracleEnhancedAdapter handling of CLOB columns" do
|
770
|
+
before(:all) do
|
771
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
772
|
+
:database => "xe",
|
773
|
+
:username => "hr",
|
774
|
+
:password => "hr")
|
775
|
+
@conn = ActiveRecord::Base.connection
|
776
|
+
@conn.execute <<-SQL
|
777
|
+
CREATE TABLE test_employees (
|
778
|
+
employee_id NUMBER(6,0),
|
779
|
+
first_name VARCHAR2(20),
|
780
|
+
last_name VARCHAR2(25),
|
781
|
+
comments CLOB
|
782
|
+
)
|
783
|
+
SQL
|
784
|
+
@conn.execute <<-SQL
|
785
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
786
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
787
|
+
SQL
|
788
|
+
class TestEmployee < ActiveRecord::Base
|
789
|
+
set_primary_key :employee_id
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
793
|
+
after(:all) do
|
794
|
+
Object.send(:remove_const, "TestEmployee")
|
795
|
+
@conn.execute "DROP TABLE test_employees"
|
796
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
797
|
+
end
|
798
|
+
|
799
|
+
before(:each) do
|
800
|
+
end
|
801
|
+
|
802
|
+
it "should create record without CLOB data when attribute is serialized" do
|
803
|
+
TestEmployee.serialize :comments
|
804
|
+
@employee = TestEmployee.create!(
|
805
|
+
:first_name => "First",
|
806
|
+
:last_name => "Last"
|
807
|
+
)
|
808
|
+
@employee.should be_valid
|
809
|
+
end
|
810
|
+
|
811
|
+
it "should order by CLOB column" do
|
812
|
+
@employee = TestEmployee.create!(
|
813
|
+
:first_name => "First",
|
814
|
+
:last_name => "Last",
|
815
|
+
:comments => "comments"
|
816
|
+
)
|
817
|
+
TestEmployee.find(:all, :order => "comments ASC").should_not be_empty
|
818
|
+
TestEmployee.find(:all, :order => " comments ASC ").should_not be_empty
|
819
|
+
TestEmployee.find(:all, :order => "comments").should_not be_empty
|
820
|
+
TestEmployee.find(:all, :order => " comments ").should_not be_empty
|
821
|
+
TestEmployee.find(:all, :order => :comments).should_not be_empty
|
822
|
+
TestEmployee.find(:all, :order => " first_name DESC, last_name ASC ").should_not be_empty
|
823
|
+
end
|
824
|
+
|
825
|
+
end
|
826
|
+
|