saberma-activerecord-oracle_enhanced-adapter-nvarchar2 1.2.1

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