rsim-activerecord-oracle_enhanced-adapter 1.1.9.90

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