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.
@@ -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
+