activerecord-oracle_enhanced-adapter-with-schema 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +2 -0
- data/Gemfile +52 -0
- data/History.md +301 -0
- data/License.txt +20 -0
- data/README.md +123 -0
- data/RUNNING_TESTS.md +45 -0
- data/Rakefile +59 -0
- data/VERSION +1 -0
- data/activerecord-oracle_enhanced-adapter-with-schema.gemspec +130 -0
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +5 -0
- data/lib/active_record/connection_adapters/oracle_enhanced.rake +105 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb +41 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +1399 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +121 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +146 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +119 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +359 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +25 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +21 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +46 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +565 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +494 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +260 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +227 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +260 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +428 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +258 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +294 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +17 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -0
- data/lib/activerecord-oracle_enhanced-adapter-with-schema.rb +25 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +778 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +332 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +427 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +19 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +113 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +1388 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +69 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +141 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +25 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +378 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +440 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +1385 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +339 -0
- data/spec/spec_helper.rb +189 -0
- metadata +260 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe "OracleEnhancedAdapter to_d method" do
|
5
|
+
it "BigDecimal#to_d returns the same decimal number" do
|
6
|
+
d = BigDecimal.new("12345678901234567890.0123456789")
|
7
|
+
d.to_d.should == d
|
8
|
+
end
|
9
|
+
|
10
|
+
it "Bignum#to_d translates large integer to decimal" do
|
11
|
+
n = 12345678901234567890
|
12
|
+
n.to_d.should == BigDecimal.new(n.to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "Fixnum#to_d translates small integer to decimal" do
|
16
|
+
n = 123456
|
17
|
+
n.to_d.should == BigDecimal.new(n.to_s)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
unless defined?(NO_COMPOSITE_PRIMARY_KEYS)
|
4
|
+
|
5
|
+
describe "OracleEnhancedAdapter composite_primary_keys support" do
|
6
|
+
include SchemaSpecHelper
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
if defined?(::ActiveRecord::ConnectionAdapters::OracleAdapter)
|
10
|
+
@old_oracle_adapter = ::ActiveRecord::ConnectionAdapters::OracleAdapter
|
11
|
+
::ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
|
12
|
+
end
|
13
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
14
|
+
if $cpk_oracle_adapter
|
15
|
+
::ActiveRecord::ConnectionAdapters::OracleAdapter = $cpk_oracle_adapter
|
16
|
+
$cpk_oracle_adapter = nil
|
17
|
+
end
|
18
|
+
require 'composite_primary_keys'
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:all) do
|
22
|
+
# Object.send(:remove_const, 'CompositePrimaryKeys') if defined?(CompositePrimaryKeys)
|
23
|
+
if defined?(::ActiveRecord::ConnectionAdapters::OracleAdapter)
|
24
|
+
$cpk_oracle_adapter = ::ActiveRecord::ConnectionAdapters::OracleAdapter
|
25
|
+
::ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
|
26
|
+
end
|
27
|
+
if @old_oracle_adapter
|
28
|
+
::ActiveRecord::ConnectionAdapters::OracleAdapter = @old_oracle_adapter
|
29
|
+
@old_oracle_adapter = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "do not use count distinct" do
|
34
|
+
before(:all) do
|
35
|
+
schema_define do
|
36
|
+
create_table :job_history, :primary_key => [:employee_id, :start_date], :force => true do |t|
|
37
|
+
t.integer :employee_id
|
38
|
+
t.date :start_date
|
39
|
+
end
|
40
|
+
end
|
41
|
+
class ::JobHistory < ActiveRecord::Base
|
42
|
+
set_table_name "job_history"
|
43
|
+
set_primary_keys :employee_id, :start_date
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
after(:all) do
|
48
|
+
Object.send(:remove_const, 'JobHistory') if defined?(JobHistory)
|
49
|
+
schema_define do
|
50
|
+
drop_table :job_history
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should tell ActiveRecord that count distinct is not supported" do
|
55
|
+
ActiveRecord::Base.connection.supports_count_distinct?.should be_false
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should execute correct SQL COUNT DISTINCT statement on table with composite primary keys" do
|
59
|
+
lambda { JobHistory.count(:distinct => true) }.should_not raise_error
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "table with LOB" do
|
64
|
+
before(:all) do
|
65
|
+
schema_define do
|
66
|
+
create_table :cpk_write_lobs_test, :primary_key => [:type_category, :date_value], :force => true do |t|
|
67
|
+
t.string :type_category, :limit => 15, :null => false
|
68
|
+
t.date :date_value, :null => false
|
69
|
+
t.text :results, :null => false
|
70
|
+
t.timestamps
|
71
|
+
end
|
72
|
+
create_table :non_cpk_write_lobs_test, :force => true do |t|
|
73
|
+
t.date :date_value, :null => false
|
74
|
+
t.text :results, :null => false
|
75
|
+
t.timestamps
|
76
|
+
end
|
77
|
+
end
|
78
|
+
class ::CpkWriteLobsTest < ActiveRecord::Base
|
79
|
+
set_table_name 'cpk_write_lobs_test'
|
80
|
+
set_primary_keys :type_category, :date_value
|
81
|
+
end
|
82
|
+
class ::NonCpkWriteLobsTest < ActiveRecord::Base
|
83
|
+
set_table_name 'non_cpk_write_lobs_test'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
after(:all) do
|
88
|
+
schema_define do
|
89
|
+
drop_table :cpk_write_lobs_test
|
90
|
+
drop_table :non_cpk_write_lobs_test
|
91
|
+
end
|
92
|
+
Object.send(:remove_const, "CpkWriteLobsTest")
|
93
|
+
Object.send(:remove_const, "NonCpkWriteLobsTest")
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should create new record in table with CPK and LOB" do
|
97
|
+
lambda {
|
98
|
+
CpkWriteLobsTest.create(:type_category => 'AAA', :date_value => Date.today, :results => 'DATA '*10)
|
99
|
+
}.should_not raise_error
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should create new record in table without CPK and with LOB" do
|
103
|
+
lambda {
|
104
|
+
NonCpkWriteLobsTest.create(:date_value => Date.today, :results => 'DATA '*10)
|
105
|
+
}.should_not raise_error
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Other testing was done based on composite_primary_keys tests
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,1388 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe "OracleEnhancedAdapter date type detection based on column names" do
|
5
|
+
before(:all) do
|
6
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
7
|
+
@conn = ActiveRecord::Base.connection
|
8
|
+
@conn.execute "DROP TABLE test_employees" rescue nil
|
9
|
+
@conn.execute "DROP SEQUENCE test_employees_seq" rescue nil
|
10
|
+
@conn.execute <<-SQL
|
11
|
+
CREATE TABLE test_employees (
|
12
|
+
employee_id NUMBER(6,0) PRIMARY KEY,
|
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
|
+
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
|
81
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
82
|
+
columns = @conn.columns('test_employees')
|
83
|
+
column = columns.detect{|c| c.name == "hire_date"}
|
84
|
+
column.type_cast(DateTime.new(1900,1,1)).class.should == Date
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "/ DATE values from ActiveRecord model" do
|
88
|
+
before(:each) do
|
89
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
90
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = false
|
91
|
+
class ::TestEmployee < ActiveRecord::Base
|
92
|
+
if self.respond_to?(:primary_key=)
|
93
|
+
self.primary_key = "employee_id"
|
94
|
+
else
|
95
|
+
set_primary_key "employee_id"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def create_test_employee(params={})
|
101
|
+
@today = params[:today] || Date.new(2008,8,19)
|
102
|
+
@now = params[:now] || Time.local(2008,8,19,17,03,59)
|
103
|
+
@employee = TestEmployee.create(
|
104
|
+
:first_name => "First",
|
105
|
+
:last_name => "Last",
|
106
|
+
:hire_date => @today,
|
107
|
+
:created_at => @now
|
108
|
+
)
|
109
|
+
@employee.reload
|
110
|
+
end
|
111
|
+
|
112
|
+
after(:each) do
|
113
|
+
# @employee.destroy if @employee
|
114
|
+
Object.send(:remove_const, "TestEmployee")
|
115
|
+
@conn.clear_types_for_columns
|
116
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should return Time value from DATE column if emulate_dates_by_column_name is false" do
|
120
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
121
|
+
create_test_employee
|
122
|
+
@employee.hire_date.class.should == Time
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should return Date value from DATE column if column name contains 'date' and emulate_dates_by_column_name is true" do
|
126
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
127
|
+
create_test_employee
|
128
|
+
@employee.hire_date.class.should == Date
|
129
|
+
end
|
130
|
+
|
131
|
+
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
|
132
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
133
|
+
create_test_employee(:today => Date.new(1900,1,1))
|
134
|
+
@employee.hire_date.class.should == Date
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should return Time value from DATE column if column name does not contain 'date' and emulate_dates_by_column_name is true" do
|
138
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
139
|
+
create_test_employee
|
140
|
+
@employee.created_at.class.should == Time
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should return Date value from DATE column if emulate_dates_by_column_name is false but column is defined as date" do
|
144
|
+
class ::TestEmployee < ActiveRecord::Base
|
145
|
+
set_date_columns :hire_date
|
146
|
+
end
|
147
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
148
|
+
create_test_employee
|
149
|
+
@employee.hire_date.class.should == Date
|
150
|
+
end
|
151
|
+
|
152
|
+
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
|
153
|
+
class ::TestEmployee < ActiveRecord::Base
|
154
|
+
set_date_columns :hire_date
|
155
|
+
end
|
156
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
157
|
+
create_test_employee(:today => Date.new(1900,1,1))
|
158
|
+
@employee.hire_date.class.should == Date
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should see set_date_columns values in different connection" do
|
162
|
+
class ::TestEmployee < ActiveRecord::Base
|
163
|
+
set_date_columns :hire_date
|
164
|
+
end
|
165
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
166
|
+
# establish other connection
|
167
|
+
other_conn = ActiveRecord::Base.oracle_enhanced_connection(CONNECTION_PARAMS)
|
168
|
+
other_conn.get_type_for_column('test_employees', 'hire_date').should == :date
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should return Time value from DATE column if emulate_dates_by_column_name is true but column is defined as datetime" do
|
172
|
+
class ::TestEmployee < ActiveRecord::Base
|
173
|
+
set_datetime_columns :hire_date
|
174
|
+
end
|
175
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
176
|
+
create_test_employee
|
177
|
+
@employee.hire_date.class.should == Time
|
178
|
+
# change to current time with hours, minutes and seconds
|
179
|
+
@employee.hire_date = @now
|
180
|
+
@employee.save!
|
181
|
+
@employee.reload
|
182
|
+
@employee.hire_date.class.should == Time
|
183
|
+
@employee.hire_date.should == @now
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should guess Date or Time value if emulate_dates is true" do
|
187
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = true
|
188
|
+
create_test_employee
|
189
|
+
@employee.hire_date.class.should == Date
|
190
|
+
@employee.created_at.class.should == Time
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "OracleEnhancedAdapter integer type detection based on column names" do
|
198
|
+
before(:all) do
|
199
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
200
|
+
@conn = ActiveRecord::Base.connection
|
201
|
+
@conn.execute "DROP TABLE test2_employees" rescue nil
|
202
|
+
@conn.execute <<-SQL
|
203
|
+
CREATE TABLE test2_employees (
|
204
|
+
id NUMBER PRIMARY KEY,
|
205
|
+
first_name VARCHAR2(20),
|
206
|
+
last_name VARCHAR2(25),
|
207
|
+
email VARCHAR2(25),
|
208
|
+
phone_number VARCHAR2(20),
|
209
|
+
hire_date DATE,
|
210
|
+
job_id NUMBER,
|
211
|
+
salary NUMBER,
|
212
|
+
commission_pct NUMBER(2,2),
|
213
|
+
manager_id NUMBER(6),
|
214
|
+
is_manager NUMBER(1),
|
215
|
+
department_id NUMBER(4,0),
|
216
|
+
created_at DATE
|
217
|
+
)
|
218
|
+
SQL
|
219
|
+
@conn.execute "DROP SEQUENCE test2_employees_seq" rescue nil
|
220
|
+
@conn.execute <<-SQL
|
221
|
+
CREATE SEQUENCE test2_employees_seq MINVALUE 1
|
222
|
+
INCREMENT BY 1 START WITH 10040 CACHE 20 NOORDER NOCYCLE
|
223
|
+
SQL
|
224
|
+
end
|
225
|
+
|
226
|
+
after(:all) do
|
227
|
+
@conn.execute "DROP TABLE test2_employees"
|
228
|
+
@conn.execute "DROP SEQUENCE test2_employees_seq"
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should set NUMBER column type as decimal if emulate_integers_by_column_name is false" do
|
232
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = false
|
233
|
+
columns = @conn.columns('test2_employees')
|
234
|
+
column = columns.detect{|c| c.name == "job_id"}
|
235
|
+
column.type.should == :decimal
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should set NUMBER column type as integer if emulate_integers_by_column_name is true" do
|
239
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
240
|
+
columns = @conn.columns('test2_employees')
|
241
|
+
column = columns.detect{|c| c.name == "job_id"}
|
242
|
+
column.type.should == :integer
|
243
|
+
column = columns.detect{|c| c.name == "id"}
|
244
|
+
column.type.should == :integer
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should set NUMBER column type as decimal if column name does not contain 'id' and emulate_integers_by_column_name is true" do
|
248
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
249
|
+
columns = @conn.columns('test2_employees')
|
250
|
+
column = columns.detect{|c| c.name == "salary"}
|
251
|
+
column.type.should == :decimal
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should return BigDecimal value from NUMBER column if emulate_integers_by_column_name is false" do
|
255
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = false
|
256
|
+
columns = @conn.columns('test2_employees')
|
257
|
+
column = columns.detect{|c| c.name == "job_id"}
|
258
|
+
column.type_cast(1.0).class.should == BigDecimal
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should return Fixnum value from NUMBER column if column name contains 'id' and emulate_integers_by_column_name is true" do
|
262
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
263
|
+
columns = @conn.columns('test2_employees')
|
264
|
+
column = columns.detect{|c| c.name == "job_id"}
|
265
|
+
column.type_cast(1.0).class.should == Fixnum
|
266
|
+
end
|
267
|
+
|
268
|
+
describe "/ NUMBER values from ActiveRecord model" do
|
269
|
+
before(:each) do
|
270
|
+
class ::Test2Employee < ActiveRecord::Base
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
after(:each) do
|
275
|
+
Object.send(:remove_const, "Test2Employee")
|
276
|
+
@conn.clear_types_for_columns
|
277
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = true
|
278
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
279
|
+
end
|
280
|
+
|
281
|
+
def create_employee2
|
282
|
+
@employee2 = Test2Employee.create(
|
283
|
+
:first_name => "First",
|
284
|
+
:last_name => "Last",
|
285
|
+
:job_id => 1,
|
286
|
+
:is_manager => 1,
|
287
|
+
:salary => 1000
|
288
|
+
)
|
289
|
+
@employee2.reload
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should return BigDecimal value from NUMBER column if emulate_integers_by_column_name is false" do
|
293
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = false
|
294
|
+
create_employee2
|
295
|
+
@employee2.job_id.class.should == BigDecimal
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should return Fixnum value from NUMBER column if column name contains 'id' and emulate_integers_by_column_name is true" do
|
299
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
300
|
+
create_employee2
|
301
|
+
@employee2.job_id.class.should == Fixnum
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should return Fixnum value from NUMBER column with integer value using _before_type_cast method" do
|
305
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
306
|
+
create_employee2
|
307
|
+
@employee2.job_id_before_type_cast.class.should == Fixnum
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should return BigDecimal value from NUMBER column if column name does not contain 'id' and emulate_integers_by_column_name is true" do
|
311
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
312
|
+
create_employee2
|
313
|
+
@employee2.salary.class.should == BigDecimal
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should return Fixnum value from NUMBER column if column specified in set_integer_columns" do
|
317
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = false
|
318
|
+
Test2Employee.set_integer_columns :job_id
|
319
|
+
create_employee2
|
320
|
+
@employee2.job_id.class.should == Fixnum
|
321
|
+
end
|
322
|
+
|
323
|
+
it "should return Boolean value from NUMBER(1) column if emulate booleans is used" do
|
324
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = true
|
325
|
+
create_employee2
|
326
|
+
@employee2.is_manager.class.should == TrueClass
|
327
|
+
end
|
328
|
+
|
329
|
+
it "should return Fixnum value from NUMBER(1) column if emulate booleans is not used" do
|
330
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = false
|
331
|
+
create_employee2
|
332
|
+
@employee2.is_manager.class.should == Fixnum
|
333
|
+
end
|
334
|
+
|
335
|
+
it "should return Fixnum value from NUMBER(1) column if column specified in set_integer_columns" do
|
336
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = true
|
337
|
+
Test2Employee.set_integer_columns :is_manager
|
338
|
+
create_employee2
|
339
|
+
@employee2.is_manager.class.should == Fixnum
|
340
|
+
end
|
341
|
+
|
342
|
+
end
|
343
|
+
|
344
|
+
end
|
345
|
+
|
346
|
+
describe "OracleEnhancedAdapter boolean type detection based on string column types and names" do
|
347
|
+
before(:all) do
|
348
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
349
|
+
@conn = ActiveRecord::Base.connection
|
350
|
+
@conn.execute <<-SQL
|
351
|
+
CREATE TABLE test3_employees (
|
352
|
+
id NUMBER PRIMARY KEY,
|
353
|
+
first_name VARCHAR2(20),
|
354
|
+
last_name VARCHAR2(25),
|
355
|
+
email VARCHAR2(25),
|
356
|
+
phone_number VARCHAR2(20),
|
357
|
+
hire_date DATE,
|
358
|
+
job_id NUMBER,
|
359
|
+
salary NUMBER,
|
360
|
+
commission_pct NUMBER(2,2),
|
361
|
+
manager_id NUMBER(6),
|
362
|
+
department_id NUMBER(4,0),
|
363
|
+
created_at DATE,
|
364
|
+
has_email CHAR(1),
|
365
|
+
has_phone VARCHAR2(1) DEFAULT 'Y',
|
366
|
+
active_flag VARCHAR2(2),
|
367
|
+
manager_yn VARCHAR2(3) DEFAULT 'N',
|
368
|
+
test_boolean VARCHAR2(3)
|
369
|
+
)
|
370
|
+
SQL
|
371
|
+
@conn.execute <<-SQL
|
372
|
+
CREATE SEQUENCE test3_employees_seq MINVALUE 1
|
373
|
+
INCREMENT BY 1 START WITH 10040 CACHE 20 NOORDER NOCYCLE
|
374
|
+
SQL
|
375
|
+
end
|
376
|
+
|
377
|
+
after(:all) do
|
378
|
+
@conn.execute "DROP TABLE test3_employees"
|
379
|
+
@conn.execute "DROP SEQUENCE test3_employees_seq"
|
380
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
381
|
+
end
|
382
|
+
|
383
|
+
it "should set CHAR/VARCHAR2 column type as string if emulate_booleans_from_strings is false" do
|
384
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
385
|
+
columns = @conn.columns('test3_employees')
|
386
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
387
|
+
column = columns.detect{|c| c.name == col}
|
388
|
+
column.type.should == :string
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
it "should set CHAR/VARCHAR2 column type as boolean if emulate_booleans_from_strings is true" do
|
393
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
394
|
+
columns = @conn.columns('test3_employees')
|
395
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
396
|
+
column = columns.detect{|c| c.name == col}
|
397
|
+
column.type.should == :boolean
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
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
|
402
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
403
|
+
columns = @conn.columns('test3_employees')
|
404
|
+
%w(phone_number email).each do |col|
|
405
|
+
column = columns.detect{|c| c.name == col}
|
406
|
+
column.type.should == :string
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
it "should return string value from VARCHAR2 boolean column if emulate_booleans_from_strings is false" do
|
411
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
412
|
+
columns = @conn.columns('test3_employees')
|
413
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
414
|
+
column = columns.detect{|c| c.name == col}
|
415
|
+
column.type_cast("Y").class.should == String
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
it "should return boolean value from VARCHAR2 boolean column if emulate_booleans_from_strings is true" do
|
420
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
421
|
+
columns = @conn.columns('test3_employees')
|
422
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
423
|
+
column = columns.detect{|c| c.name == col}
|
424
|
+
column.type_cast("Y").class.should == TrueClass
|
425
|
+
column.type_cast("N").class.should == FalseClass
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
it "should translate boolean type to VARCHAR2(1) if emulate_booleans_from_strings is true" do
|
430
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
431
|
+
ActiveRecord::Base.connection.type_to_sql(
|
432
|
+
:boolean, nil, nil, nil).should == "VARCHAR2(1)"
|
433
|
+
end
|
434
|
+
|
435
|
+
it "should translate boolean type to NUMBER(1) if emulate_booleans_from_strings is false" do
|
436
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
437
|
+
ActiveRecord::Base.connection.type_to_sql(
|
438
|
+
:boolean, nil, nil, nil).should == "NUMBER(1)"
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should get default value from VARCHAR2 boolean column if emulate_booleans_from_strings is true" do
|
442
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
443
|
+
columns = @conn.columns('test3_employees')
|
444
|
+
columns.detect{|c| c.name == 'has_phone'}.default.should be_true
|
445
|
+
columns.detect{|c| c.name == 'manager_yn'}.default.should be_false
|
446
|
+
end
|
447
|
+
|
448
|
+
describe "/ VARCHAR2 boolean values from ActiveRecord model" do
|
449
|
+
before(:each) do
|
450
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
451
|
+
class ::Test3Employee < ActiveRecord::Base
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
after(:each) do
|
456
|
+
Object.send(:remove_const, "Test3Employee")
|
457
|
+
@conn.clear_types_for_columns
|
458
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
459
|
+
end
|
460
|
+
|
461
|
+
def create_employee3(params={})
|
462
|
+
@employee3 = Test3Employee.create(
|
463
|
+
{
|
464
|
+
:first_name => "First",
|
465
|
+
:last_name => "Last",
|
466
|
+
:has_email => true,
|
467
|
+
:has_phone => false,
|
468
|
+
:active_flag => true,
|
469
|
+
:manager_yn => false
|
470
|
+
}.merge(params)
|
471
|
+
)
|
472
|
+
@employee3.reload
|
473
|
+
end
|
474
|
+
|
475
|
+
it "should return String value from VARCHAR2 boolean column if emulate_booleans_from_strings is false" do
|
476
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
|
477
|
+
create_employee3
|
478
|
+
%w(has_email has_phone active_flag manager_yn).each do |col|
|
479
|
+
@employee3.send(col.to_sym).class.should == String
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
it "should return boolean value from VARCHAR2 boolean column if emulate_booleans_from_strings is true" do
|
484
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
485
|
+
create_employee3
|
486
|
+
%w(has_email active_flag).each do |col|
|
487
|
+
@employee3.send(col.to_sym).class.should == TrueClass
|
488
|
+
@employee3.send((col+"_before_type_cast").to_sym).should == "Y"
|
489
|
+
end
|
490
|
+
%w(has_phone manager_yn).each do |col|
|
491
|
+
@employee3.send(col.to_sym).class.should == FalseClass
|
492
|
+
@employee3.send((col+"_before_type_cast").to_sym).should == "N"
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
it "should return string value from VARCHAR2 column if it is not boolean column and emulate_booleans_from_strings is true" do
|
497
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
498
|
+
create_employee3
|
499
|
+
@employee3.first_name.class.should == String
|
500
|
+
end
|
501
|
+
|
502
|
+
it "should return boolean value from VARCHAR2 boolean column if column specified in set_boolean_columns" do
|
503
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
504
|
+
Test3Employee.set_boolean_columns :test_boolean
|
505
|
+
create_employee3(:test_boolean => true)
|
506
|
+
@employee3.test_boolean.class.should == TrueClass
|
507
|
+
@employee3.test_boolean_before_type_cast.should == "Y"
|
508
|
+
create_employee3(:test_boolean => false)
|
509
|
+
@employee3.test_boolean.class.should == FalseClass
|
510
|
+
@employee3.test_boolean_before_type_cast.should == "N"
|
511
|
+
create_employee3(:test_boolean => nil)
|
512
|
+
@employee3.test_boolean.class.should == NilClass
|
513
|
+
@employee3.test_boolean_before_type_cast.should == nil
|
514
|
+
create_employee3(:test_boolean => "")
|
515
|
+
@employee3.test_boolean.class.should == NilClass
|
516
|
+
@employee3.test_boolean_before_type_cast.should == nil
|
517
|
+
end
|
518
|
+
|
519
|
+
it "should return string value from VARCHAR2 column with boolean column name but is specified in set_string_columns" do
|
520
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
521
|
+
Test3Employee.set_string_columns :active_flag
|
522
|
+
create_employee3
|
523
|
+
@employee3.active_flag.class.should == String
|
524
|
+
end
|
525
|
+
|
526
|
+
end
|
527
|
+
|
528
|
+
end
|
529
|
+
|
530
|
+
describe "OracleEnhancedAdapter timestamp with timezone support" do
|
531
|
+
before(:all) do
|
532
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
533
|
+
@conn = ActiveRecord::Base.connection
|
534
|
+
@conn.execute <<-SQL
|
535
|
+
CREATE TABLE test_employees (
|
536
|
+
employee_id NUMBER(6,0) PRIMARY KEY,
|
537
|
+
first_name VARCHAR2(20),
|
538
|
+
last_name VARCHAR2(25),
|
539
|
+
email VARCHAR2(25),
|
540
|
+
phone_number VARCHAR2(20),
|
541
|
+
hire_date DATE,
|
542
|
+
job_id NUMBER(6,0),
|
543
|
+
salary NUMBER(8,2),
|
544
|
+
commission_pct NUMBER(2,2),
|
545
|
+
manager_id NUMBER(6,0),
|
546
|
+
department_id NUMBER(4,0),
|
547
|
+
created_at TIMESTAMP,
|
548
|
+
created_at_tz TIMESTAMP WITH TIME ZONE,
|
549
|
+
created_at_ltz TIMESTAMP WITH LOCAL TIME ZONE
|
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
|
+
end
|
557
|
+
|
558
|
+
after(:all) do
|
559
|
+
@conn.execute "DROP TABLE test_employees"
|
560
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
561
|
+
end
|
562
|
+
|
563
|
+
it "should set TIMESTAMP columns type as datetime" do
|
564
|
+
columns = @conn.columns('test_employees')
|
565
|
+
ts_columns = columns.select{|c| c.name =~ /created_at/}
|
566
|
+
ts_columns.each {|c| c.type.should == :timestamp}
|
567
|
+
end
|
568
|
+
|
569
|
+
describe "/ TIMESTAMP WITH TIME ZONE values from ActiveRecord model" do
|
570
|
+
before(:all) do
|
571
|
+
class ::TestEmployee < ActiveRecord::Base
|
572
|
+
if self.respond_to?(:primary_key=)
|
573
|
+
self.primary_key = "employee_id"
|
574
|
+
else
|
575
|
+
set_primary_key "employee_id"
|
576
|
+
end
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
after(:all) do
|
581
|
+
Object.send(:remove_const, "TestEmployee")
|
582
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
583
|
+
end
|
584
|
+
|
585
|
+
it "should return Time value from TIMESTAMP columns" do
|
586
|
+
@now = Time.local(2008,5,26,23,11,11,0)
|
587
|
+
@employee = TestEmployee.create(
|
588
|
+
:created_at => @now,
|
589
|
+
:created_at_tz => @now,
|
590
|
+
:created_at_ltz => @now
|
591
|
+
)
|
592
|
+
@employee.reload
|
593
|
+
[:created_at, :created_at_tz, :created_at_ltz].each do |c|
|
594
|
+
@employee.send(c).class.should == Time
|
595
|
+
@employee.send(c).to_f.should == @now.to_f
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
it "should return Time value with fractional seconds from TIMESTAMP columns" do
|
600
|
+
@now = Time.local(2008,5,26,23,11,11,10)
|
601
|
+
@employee = TestEmployee.create(
|
602
|
+
:created_at => @now,
|
603
|
+
:created_at_tz => @now,
|
604
|
+
:created_at_ltz => @now
|
605
|
+
)
|
606
|
+
@employee.reload
|
607
|
+
[:created_at, :created_at_tz, :created_at_ltz].each do |c|
|
608
|
+
@employee.send(c).class.should == Time
|
609
|
+
@employee.send(c).to_f.should == @now.to_f
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
end
|
614
|
+
|
615
|
+
end
|
616
|
+
|
617
|
+
|
618
|
+
describe "OracleEnhancedAdapter date and timestamp with different NLS date formats" do
|
619
|
+
before(:all) do
|
620
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
621
|
+
@conn = ActiveRecord::Base.connection
|
622
|
+
@conn.execute <<-SQL
|
623
|
+
CREATE TABLE test_employees (
|
624
|
+
employee_id NUMBER(6,0) PRIMARY KEY,
|
625
|
+
first_name VARCHAR2(20),
|
626
|
+
last_name VARCHAR2(25),
|
627
|
+
email VARCHAR2(25),
|
628
|
+
phone_number VARCHAR2(20),
|
629
|
+
hire_date DATE,
|
630
|
+
job_id NUMBER(6,0),
|
631
|
+
salary NUMBER(8,2),
|
632
|
+
commission_pct NUMBER(2,2),
|
633
|
+
manager_id NUMBER(6,0),
|
634
|
+
department_id NUMBER(4,0),
|
635
|
+
created_at DATE,
|
636
|
+
created_at_ts TIMESTAMP
|
637
|
+
)
|
638
|
+
SQL
|
639
|
+
@conn.execute <<-SQL
|
640
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
641
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
642
|
+
SQL
|
643
|
+
# @conn.execute %q{alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'}
|
644
|
+
@conn.execute %q{alter session set nls_date_format = 'DD-MON-YYYY HH24:MI:SS'}
|
645
|
+
# @conn.execute %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'}
|
646
|
+
@conn.execute %q{alter session set nls_timestamp_format = 'DD-MON-YYYY HH24:MI:SS'}
|
647
|
+
end
|
648
|
+
|
649
|
+
after(:all) do
|
650
|
+
@conn.execute "DROP TABLE test_employees"
|
651
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
652
|
+
end
|
653
|
+
|
654
|
+
before(:each) do
|
655
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = false
|
656
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
657
|
+
class ::TestEmployee < ActiveRecord::Base
|
658
|
+
if self.respond_to?(:primary_key=)
|
659
|
+
self.primary_key = "employee_id"
|
660
|
+
else
|
661
|
+
set_primary_key "employee_id"
|
662
|
+
end
|
663
|
+
end
|
664
|
+
@today = Date.new(2008,6,28)
|
665
|
+
@now = Time.local(2008,6,28,13,34,33)
|
666
|
+
end
|
667
|
+
|
668
|
+
after(:each) do
|
669
|
+
Object.send(:remove_const, "TestEmployee")
|
670
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
671
|
+
end
|
672
|
+
|
673
|
+
def create_test_employee
|
674
|
+
@employee = TestEmployee.create(
|
675
|
+
:first_name => "First",
|
676
|
+
:last_name => "Last",
|
677
|
+
:hire_date => @today,
|
678
|
+
:created_at => @now,
|
679
|
+
:created_at_ts => @now
|
680
|
+
)
|
681
|
+
@employee.reload
|
682
|
+
end
|
683
|
+
|
684
|
+
it "should return Time value from DATE column if emulate_dates_by_column_name is false" do
|
685
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
686
|
+
create_test_employee
|
687
|
+
@employee.hire_date.class.should == Time
|
688
|
+
@employee.hire_date.should == @today.to_time
|
689
|
+
end
|
690
|
+
|
691
|
+
it "should return Date value from DATE column if column name contains 'date' and emulate_dates_by_column_name is true" do
|
692
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
693
|
+
create_test_employee
|
694
|
+
@employee.hire_date.class.should == Date
|
695
|
+
@employee.hire_date.should == @today
|
696
|
+
end
|
697
|
+
|
698
|
+
it "should return Time value from DATE column if column name does not contain 'date' and emulate_dates_by_column_name is true" do
|
699
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
700
|
+
create_test_employee
|
701
|
+
@employee.created_at.class.should == Time
|
702
|
+
@employee.created_at.should == @now
|
703
|
+
end
|
704
|
+
|
705
|
+
it "should return Time value from TIMESTAMP columns" do
|
706
|
+
create_test_employee
|
707
|
+
@employee.created_at_ts.class.should == Time
|
708
|
+
@employee.created_at_ts.should == @now
|
709
|
+
end
|
710
|
+
|
711
|
+
it "should quote Date values with TO_DATE" do
|
712
|
+
@conn.quote(@today).should == "TO_DATE('#{@today.year}-#{"%02d" % @today.month}-#{"%02d" % @today.day}','YYYY-MM-DD HH24:MI:SS')"
|
713
|
+
end
|
714
|
+
|
715
|
+
it "should quote Time values with TO_DATE" do
|
716
|
+
@conn.quote(@now).should == "TO_DATE('#{@now.year}-#{"%02d" % @now.month}-#{"%02d" % @now.day} "+
|
717
|
+
"#{"%02d" % @now.hour}:#{"%02d" % @now.min}:#{"%02d" % @now.sec}','YYYY-MM-DD HH24:MI:SS')"
|
718
|
+
end
|
719
|
+
|
720
|
+
it "should quote Time values with TO_TIMESTAMP" do
|
721
|
+
@ts = @now + 0.1
|
722
|
+
@conn.quote(@ts).should == "TO_TIMESTAMP('#{@ts.year}-#{"%02d" % @ts.month}-#{"%02d" % @ts.day} "+
|
723
|
+
"#{"%02d" % @ts.hour}:#{"%02d" % @ts.min}:#{"%02d" % @ts.sec}:100000','YYYY-MM-DD HH24:MI:SS:FF6')"
|
724
|
+
end
|
725
|
+
|
726
|
+
end
|
727
|
+
|
728
|
+
describe "OracleEnhancedAdapter assign string to :date and :datetime columns" do
|
729
|
+
before(:all) do
|
730
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
731
|
+
@conn = ActiveRecord::Base.connection
|
732
|
+
@conn.execute <<-SQL
|
733
|
+
CREATE TABLE test_employees (
|
734
|
+
employee_id NUMBER(6,0) PRIMARY KEY,
|
735
|
+
first_name VARCHAR2(20),
|
736
|
+
last_name VARCHAR2(25),
|
737
|
+
hire_date DATE,
|
738
|
+
last_login_at DATE,
|
739
|
+
last_login_at_ts TIMESTAMP
|
740
|
+
)
|
741
|
+
SQL
|
742
|
+
@conn.execute <<-SQL
|
743
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
744
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
745
|
+
SQL
|
746
|
+
class ::TestEmployee < ActiveRecord::Base
|
747
|
+
if self.respond_to?(:primary_key=)
|
748
|
+
self.primary_key = "employee_id"
|
749
|
+
else
|
750
|
+
set_primary_key "employee_id"
|
751
|
+
end
|
752
|
+
end
|
753
|
+
@today = Date.new(2008,6,28)
|
754
|
+
@today_iso = "2008-06-28"
|
755
|
+
@today_nls = "28.06.2008"
|
756
|
+
@nls_date_format = "%d.%m.%Y"
|
757
|
+
@now = Time.local(2008,6,28,13,34,33)
|
758
|
+
@now_iso = "2008-06-28 13:34:33"
|
759
|
+
@now_nls = "28.06.2008 13:34:33"
|
760
|
+
@nls_time_format = "%d.%m.%Y %H:%M:%S"
|
761
|
+
@now_nls_with_tz = "28.06.2008 13:34:33+05:00"
|
762
|
+
@nls_with_tz_time_format = "%d.%m.%Y %H:%M:%S%Z"
|
763
|
+
@now_with_tz = Time.parse @now_nls_with_tz
|
764
|
+
end
|
765
|
+
|
766
|
+
after(:all) do
|
767
|
+
Object.send(:remove_const, "TestEmployee")
|
768
|
+
@conn.execute "DROP TABLE test_employees"
|
769
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
770
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
771
|
+
end
|
772
|
+
|
773
|
+
before(:each) do
|
774
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
775
|
+
end
|
776
|
+
|
777
|
+
it "should assign ISO string to date column" do
|
778
|
+
@employee = TestEmployee.create(
|
779
|
+
:first_name => "First",
|
780
|
+
:last_name => "Last",
|
781
|
+
:hire_date => @today_iso
|
782
|
+
)
|
783
|
+
@employee.hire_date.should == @today
|
784
|
+
@employee.reload
|
785
|
+
@employee.hire_date.should == @today
|
786
|
+
end
|
787
|
+
|
788
|
+
it "should assign NLS string to date column" do
|
789
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = @nls_date_format
|
790
|
+
@employee = TestEmployee.create(
|
791
|
+
:first_name => "First",
|
792
|
+
:last_name => "Last",
|
793
|
+
:hire_date => @today_nls
|
794
|
+
)
|
795
|
+
@employee.hire_date.should == @today
|
796
|
+
@employee.reload
|
797
|
+
@employee.hire_date.should == @today
|
798
|
+
end
|
799
|
+
|
800
|
+
it "should assign ISO time string to date column" do
|
801
|
+
@employee = TestEmployee.create(
|
802
|
+
:first_name => "First",
|
803
|
+
:last_name => "Last",
|
804
|
+
:hire_date => @now_iso
|
805
|
+
)
|
806
|
+
@employee.hire_date.should == @today
|
807
|
+
@employee.reload
|
808
|
+
@employee.hire_date.should == @today
|
809
|
+
end
|
810
|
+
|
811
|
+
it "should assign NLS time string to date column" do
|
812
|
+
# ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = @nls_date_format
|
813
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = @nls_time_format
|
814
|
+
@employee = TestEmployee.create(
|
815
|
+
:first_name => "First",
|
816
|
+
:last_name => "Last",
|
817
|
+
:hire_date => @now_nls
|
818
|
+
)
|
819
|
+
@employee.hire_date.should == @today
|
820
|
+
@employee.reload
|
821
|
+
@employee.hire_date.should == @today
|
822
|
+
end
|
823
|
+
|
824
|
+
it "should assign ISO time string to datetime column" do
|
825
|
+
@employee = TestEmployee.create(
|
826
|
+
:first_name => "First",
|
827
|
+
:last_name => "Last",
|
828
|
+
:last_login_at => @now_iso
|
829
|
+
)
|
830
|
+
@employee.last_login_at.should == @now
|
831
|
+
@employee.reload
|
832
|
+
@employee.last_login_at.should == @now
|
833
|
+
end
|
834
|
+
|
835
|
+
it "should assign NLS time string to datetime column" do
|
836
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = @nls_time_format
|
837
|
+
@employee = TestEmployee.create(
|
838
|
+
:first_name => "First",
|
839
|
+
:last_name => "Last",
|
840
|
+
:last_login_at => @now_nls
|
841
|
+
)
|
842
|
+
@employee.last_login_at.should == @now
|
843
|
+
@employee.reload
|
844
|
+
@employee.last_login_at.should == @now
|
845
|
+
end
|
846
|
+
|
847
|
+
it "should assign NLS time string with time zone to datetime column" do
|
848
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = @nls_with_tz_time_format
|
849
|
+
@employee = TestEmployee.create(
|
850
|
+
:first_name => "First",
|
851
|
+
:last_name => "Last",
|
852
|
+
:last_login_at => @now_nls_with_tz
|
853
|
+
)
|
854
|
+
@employee.last_login_at.should == @now_with_tz
|
855
|
+
@employee.reload
|
856
|
+
@employee.last_login_at.should == @now_with_tz
|
857
|
+
end
|
858
|
+
|
859
|
+
it "should assign ISO date string to datetime column" do
|
860
|
+
@employee = TestEmployee.create(
|
861
|
+
:first_name => "First",
|
862
|
+
:last_name => "Last",
|
863
|
+
:last_login_at => @today_iso
|
864
|
+
)
|
865
|
+
@employee.last_login_at.should == @today.to_time
|
866
|
+
@employee.reload
|
867
|
+
@employee.last_login_at.should == @today.to_time
|
868
|
+
end
|
869
|
+
|
870
|
+
it "should assign NLS date string to datetime column" do
|
871
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = @nls_date_format
|
872
|
+
# ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = @nls_time_format
|
873
|
+
@employee = TestEmployee.create(
|
874
|
+
:first_name => "First",
|
875
|
+
:last_name => "Last",
|
876
|
+
:last_login_at => @today_nls
|
877
|
+
)
|
878
|
+
@employee.last_login_at.should == @today.to_time
|
879
|
+
@employee.reload
|
880
|
+
@employee.last_login_at.should == @today.to_time
|
881
|
+
end
|
882
|
+
|
883
|
+
end
|
884
|
+
|
885
|
+
describe "OracleEnhancedAdapter handling of CLOB columns" do
|
886
|
+
before(:all) do
|
887
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
888
|
+
@conn = ActiveRecord::Base.connection
|
889
|
+
@conn.execute <<-SQL
|
890
|
+
CREATE TABLE test_employees (
|
891
|
+
id NUMBER(6,0) PRIMARY KEY,
|
892
|
+
first_name VARCHAR2(20),
|
893
|
+
last_name VARCHAR2(25),
|
894
|
+
comments CLOB
|
895
|
+
)
|
896
|
+
SQL
|
897
|
+
@conn.execute <<-SQL
|
898
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
899
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
900
|
+
SQL
|
901
|
+
@conn.execute <<-SQL
|
902
|
+
CREATE TABLE test2_employees (
|
903
|
+
id NUMBER(6,0) PRIMARY KEY,
|
904
|
+
first_name VARCHAR2(20),
|
905
|
+
last_name VARCHAR2(25),
|
906
|
+
comments CLOB
|
907
|
+
)
|
908
|
+
SQL
|
909
|
+
@conn.execute <<-SQL
|
910
|
+
CREATE SEQUENCE test2_employees_seq MINVALUE 1
|
911
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
912
|
+
SQL
|
913
|
+
@char_data = (0..127).to_a.pack("C*") * 800
|
914
|
+
@char_data2 = ((1..127).to_a.pack("C*") + "\0") * 800
|
915
|
+
|
916
|
+
class ::TestEmployee < ActiveRecord::Base; end
|
917
|
+
class ::Test2Employee < ActiveRecord::Base
|
918
|
+
serialize :comments
|
919
|
+
end
|
920
|
+
class ::TestEmployeeReadOnlyClob < ActiveRecord::Base
|
921
|
+
set_table_name :test_employees
|
922
|
+
attr_readonly :comments
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
after(:all) do
|
927
|
+
@conn.execute "DROP TABLE test_employees"
|
928
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
929
|
+
@conn.execute "DROP TABLE test2_employees"
|
930
|
+
@conn.execute "DROP SEQUENCE test2_employees_seq"
|
931
|
+
Object.send(:remove_const, "TestEmployee")
|
932
|
+
Object.send(:remove_const, "Test2Employee")
|
933
|
+
Object.send(:remove_const, "TestEmployeeReadOnlyClob")
|
934
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
935
|
+
end
|
936
|
+
|
937
|
+
it "should create record without CLOB data when attribute is serialized" do
|
938
|
+
@employee = Test2Employee.create!(
|
939
|
+
:first_name => "First",
|
940
|
+
:last_name => "Last"
|
941
|
+
)
|
942
|
+
@employee.should be_valid
|
943
|
+
end
|
944
|
+
|
945
|
+
it "should accept Symbol value for CLOB column" do
|
946
|
+
@employee = TestEmployee.create!(
|
947
|
+
:comments => :test_comment
|
948
|
+
)
|
949
|
+
@employee.should be_valid
|
950
|
+
end
|
951
|
+
|
952
|
+
it "should respect attr_readonly setting for CLOB column" do
|
953
|
+
@employee = TestEmployeeReadOnlyClob.create!(
|
954
|
+
:first_name => "First",
|
955
|
+
:comments => "initial"
|
956
|
+
)
|
957
|
+
@employee.should be_valid
|
958
|
+
@employee.reload
|
959
|
+
@employee.comments.should == 'initial'
|
960
|
+
@employee.comments = "changed"
|
961
|
+
@employee.save.should == true
|
962
|
+
@employee.reload
|
963
|
+
@employee.comments.should == 'initial'
|
964
|
+
end
|
965
|
+
|
966
|
+
|
967
|
+
it "should create record with CLOB data" do
|
968
|
+
@employee = TestEmployee.create!(
|
969
|
+
:first_name => "First",
|
970
|
+
:last_name => "Last",
|
971
|
+
:comments => @char_data
|
972
|
+
)
|
973
|
+
@employee.reload
|
974
|
+
@employee.comments.should == @char_data
|
975
|
+
end
|
976
|
+
|
977
|
+
it "should update record with CLOB data" do
|
978
|
+
@employee = TestEmployee.create!(
|
979
|
+
:first_name => "First",
|
980
|
+
:last_name => "Last"
|
981
|
+
)
|
982
|
+
@employee.reload
|
983
|
+
@employee.comments.should be_nil
|
984
|
+
@employee.comments = @char_data
|
985
|
+
@employee.save!
|
986
|
+
@employee.reload
|
987
|
+
@employee.comments.should == @char_data
|
988
|
+
end
|
989
|
+
|
990
|
+
it "should update record with zero-length CLOB data" do
|
991
|
+
@employee = TestEmployee.create!(
|
992
|
+
:first_name => "First",
|
993
|
+
:last_name => "Last"
|
994
|
+
)
|
995
|
+
@employee.reload
|
996
|
+
@employee.comments.should be_nil
|
997
|
+
@employee.comments = ''
|
998
|
+
@employee.save!
|
999
|
+
@employee.reload
|
1000
|
+
@employee.comments.should == ''
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
it "should update record that has existing CLOB data with different CLOB data" do
|
1004
|
+
@employee = TestEmployee.create!(
|
1005
|
+
:first_name => "First",
|
1006
|
+
:last_name => "Last",
|
1007
|
+
:comments => @char_data
|
1008
|
+
)
|
1009
|
+
@employee.reload
|
1010
|
+
@employee.comments = @char_data2
|
1011
|
+
@employee.save!
|
1012
|
+
@employee.reload
|
1013
|
+
@employee.comments.should == @char_data2
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
it "should update record that has existing CLOB data with nil" do
|
1017
|
+
@employee = TestEmployee.create!(
|
1018
|
+
:first_name => "First",
|
1019
|
+
:last_name => "Last",
|
1020
|
+
:comments => @char_data
|
1021
|
+
)
|
1022
|
+
@employee.reload
|
1023
|
+
@employee.comments = nil
|
1024
|
+
@employee.save!
|
1025
|
+
@employee.reload
|
1026
|
+
@employee.comments.should be_nil
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
it "should update record that has existing CLOB data with zero-length CLOB data" do
|
1030
|
+
@employee = TestEmployee.create!(
|
1031
|
+
:first_name => "First",
|
1032
|
+
:last_name => "Last",
|
1033
|
+
:comments => @char_data
|
1034
|
+
)
|
1035
|
+
@employee.reload
|
1036
|
+
@employee.comments = ''
|
1037
|
+
@employee.save!
|
1038
|
+
@employee.reload
|
1039
|
+
@employee.comments.should == ''
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
it "should update record that has zero-length CLOB data with non-empty CLOB data" do
|
1043
|
+
@employee = TestEmployee.create!(
|
1044
|
+
:first_name => "First",
|
1045
|
+
:last_name => "Last",
|
1046
|
+
:comments => ''
|
1047
|
+
)
|
1048
|
+
@employee.reload
|
1049
|
+
@employee.comments.should == ''
|
1050
|
+
@employee.comments = @char_data
|
1051
|
+
@employee.save!
|
1052
|
+
@employee.reload
|
1053
|
+
@employee.comments.should == @char_data
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
it "should keep unchanged serialized data when other columns changed" do
|
1057
|
+
@employee = Test2Employee.create!(
|
1058
|
+
:first_name => "First",
|
1059
|
+
:last_name => "Last",
|
1060
|
+
:comments => "initial serialized data"
|
1061
|
+
)
|
1062
|
+
@employee.first_name = "Steve"
|
1063
|
+
@employee.save
|
1064
|
+
@employee.reload
|
1065
|
+
@employee.comments.should == "initial serialized data"
|
1066
|
+
end
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
describe "OracleEnhancedAdapter handling of BLOB columns" do
|
1070
|
+
before(:all) do
|
1071
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
1072
|
+
@conn = ActiveRecord::Base.connection
|
1073
|
+
@conn.execute <<-SQL
|
1074
|
+
CREATE TABLE test_employees (
|
1075
|
+
employee_id NUMBER(6,0) PRIMARY KEY,
|
1076
|
+
first_name VARCHAR2(20),
|
1077
|
+
last_name VARCHAR2(25),
|
1078
|
+
binary_data BLOB
|
1079
|
+
)
|
1080
|
+
SQL
|
1081
|
+
@conn.execute <<-SQL
|
1082
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
1083
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
1084
|
+
SQL
|
1085
|
+
@binary_data = "\0\1\2\3\4\5\6\7\8\9"*10000
|
1086
|
+
@binary_data2 = "\1\2\3\4\5\6\7\8\9\0"*10000
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
after(:all) do
|
1090
|
+
@conn.execute "DROP TABLE test_employees"
|
1091
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
before(:each) do
|
1095
|
+
class ::TestEmployee < ActiveRecord::Base
|
1096
|
+
if self.respond_to?(:primary_key=)
|
1097
|
+
self.primary_key = "employee_id"
|
1098
|
+
else
|
1099
|
+
set_primary_key "employee_id"
|
1100
|
+
end
|
1101
|
+
end
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
after(:each) do
|
1105
|
+
Object.send(:remove_const, "TestEmployee")
|
1106
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
it "should create record with BLOB data" do
|
1110
|
+
@employee = TestEmployee.create!(
|
1111
|
+
:first_name => "First",
|
1112
|
+
:last_name => "Last",
|
1113
|
+
:binary_data => @binary_data
|
1114
|
+
)
|
1115
|
+
@employee.reload
|
1116
|
+
@employee.binary_data.should == @binary_data
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
it "should update record with BLOB data" do
|
1120
|
+
@employee = TestEmployee.create!(
|
1121
|
+
:first_name => "First",
|
1122
|
+
:last_name => "Last"
|
1123
|
+
)
|
1124
|
+
@employee.reload
|
1125
|
+
@employee.binary_data.should be_nil
|
1126
|
+
@employee.binary_data = @binary_data
|
1127
|
+
@employee.save!
|
1128
|
+
@employee.reload
|
1129
|
+
@employee.binary_data.should == @binary_data
|
1130
|
+
end
|
1131
|
+
|
1132
|
+
it "should update record with zero-length BLOB data" do
|
1133
|
+
@employee = TestEmployee.create!(
|
1134
|
+
:first_name => "First",
|
1135
|
+
:last_name => "Last"
|
1136
|
+
)
|
1137
|
+
@employee.reload
|
1138
|
+
@employee.binary_data.should be_nil
|
1139
|
+
@employee.binary_data = ''
|
1140
|
+
@employee.save!
|
1141
|
+
@employee.reload
|
1142
|
+
@employee.binary_data.should == ''
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
it "should update record that has existing BLOB data with different BLOB data" do
|
1146
|
+
@employee = TestEmployee.create!(
|
1147
|
+
:first_name => "First",
|
1148
|
+
:last_name => "Last",
|
1149
|
+
:binary_data => @binary_data
|
1150
|
+
)
|
1151
|
+
@employee.reload
|
1152
|
+
@employee.binary_data = @binary_data2
|
1153
|
+
@employee.save!
|
1154
|
+
@employee.reload
|
1155
|
+
@employee.binary_data.should == @binary_data2
|
1156
|
+
end
|
1157
|
+
|
1158
|
+
it "should update record that has existing BLOB data with nil" do
|
1159
|
+
@employee = TestEmployee.create!(
|
1160
|
+
:first_name => "First",
|
1161
|
+
:last_name => "Last",
|
1162
|
+
:binary_data => @binary_data
|
1163
|
+
)
|
1164
|
+
@employee.reload
|
1165
|
+
@employee.binary_data = nil
|
1166
|
+
@employee.save!
|
1167
|
+
@employee.reload
|
1168
|
+
@employee.binary_data.should be_nil
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
it "should update record that has existing BLOB data with zero-length BLOB data" do
|
1172
|
+
@employee = TestEmployee.create!(
|
1173
|
+
:first_name => "First",
|
1174
|
+
:last_name => "Last",
|
1175
|
+
:binary_data => @binary_data
|
1176
|
+
)
|
1177
|
+
@employee.reload
|
1178
|
+
@employee.binary_data = ''
|
1179
|
+
@employee.save!
|
1180
|
+
@employee.reload
|
1181
|
+
@employee.binary_data.should == ''
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
it "should update record that has zero-length BLOB data with non-empty BLOB data" do
|
1185
|
+
@employee = TestEmployee.create!(
|
1186
|
+
:first_name => "First",
|
1187
|
+
:last_name => "Last",
|
1188
|
+
:binary_data => ''
|
1189
|
+
)
|
1190
|
+
@employee.reload
|
1191
|
+
@employee.binary_data.should == ''
|
1192
|
+
@employee.binary_data = @binary_data
|
1193
|
+
@employee.save!
|
1194
|
+
@employee.reload
|
1195
|
+
@employee.binary_data.should == @binary_data
|
1196
|
+
end
|
1197
|
+
end
|
1198
|
+
|
1199
|
+
describe "OracleEnhancedAdapter handling of RAW columns" do
|
1200
|
+
before(:all) do
|
1201
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
1202
|
+
@conn = ActiveRecord::Base.connection
|
1203
|
+
@conn.execute <<-SQL
|
1204
|
+
CREATE TABLE test_employees (
|
1205
|
+
employee_id NUMBER(6,0) PRIMARY KEY,
|
1206
|
+
first_name VARCHAR2(20),
|
1207
|
+
last_name VARCHAR2(25),
|
1208
|
+
binary_data RAW(1024)
|
1209
|
+
)
|
1210
|
+
SQL
|
1211
|
+
@conn.execute <<-SQL
|
1212
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
1213
|
+
INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
|
1214
|
+
SQL
|
1215
|
+
@binary_data = "\0\1\2\3\4\5\6\7\8\9"*100
|
1216
|
+
@binary_data2 = "\1\2\3\4\5\6\7\8\9\0"*100
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
after(:all) do
|
1220
|
+
@conn.execute "DROP TABLE test_employees"
|
1221
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
before(:each) do
|
1225
|
+
class ::TestEmployee < ActiveRecord::Base
|
1226
|
+
if self.respond_to?(:primary_key=)
|
1227
|
+
self.primary_key = "employee_id"
|
1228
|
+
else
|
1229
|
+
set_primary_key "employee_id"
|
1230
|
+
end
|
1231
|
+
end
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
after(:each) do
|
1235
|
+
Object.send(:remove_const, "TestEmployee")
|
1236
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
it "should create record with RAW data" do
|
1240
|
+
@employee = TestEmployee.create!(
|
1241
|
+
:first_name => "First",
|
1242
|
+
:last_name => "Last",
|
1243
|
+
:binary_data => @binary_data
|
1244
|
+
)
|
1245
|
+
@employee.reload
|
1246
|
+
@employee.binary_data.should == @binary_data
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
it "should update record with RAW data" do
|
1250
|
+
@employee = TestEmployee.create!(
|
1251
|
+
:first_name => "First",
|
1252
|
+
:last_name => "Last"
|
1253
|
+
)
|
1254
|
+
@employee.reload
|
1255
|
+
@employee.binary_data.should be_nil
|
1256
|
+
@employee.binary_data = @binary_data
|
1257
|
+
@employee.save!
|
1258
|
+
@employee.reload
|
1259
|
+
@employee.binary_data.should == @binary_data
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
it "should update record with zero-length RAW data" do
|
1263
|
+
@employee = TestEmployee.create!(
|
1264
|
+
:first_name => "First",
|
1265
|
+
:last_name => "Last"
|
1266
|
+
)
|
1267
|
+
@employee.reload
|
1268
|
+
@employee.binary_data.should be_nil
|
1269
|
+
@employee.binary_data = ''
|
1270
|
+
@employee.save!
|
1271
|
+
@employee.reload
|
1272
|
+
@employee.binary_data.should.nil?
|
1273
|
+
end
|
1274
|
+
|
1275
|
+
it "should update record that has existing RAW data with different RAW data" do
|
1276
|
+
@employee = TestEmployee.create!(
|
1277
|
+
:first_name => "First",
|
1278
|
+
:last_name => "Last",
|
1279
|
+
:binary_data => @binary_data
|
1280
|
+
)
|
1281
|
+
@employee.reload
|
1282
|
+
@employee.binary_data = @binary_data2
|
1283
|
+
@employee.save!
|
1284
|
+
@employee.reload
|
1285
|
+
@employee.binary_data.should == @binary_data2
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
it "should update record that has existing RAW data with nil" do
|
1289
|
+
@employee = TestEmployee.create!(
|
1290
|
+
:first_name => "First",
|
1291
|
+
:last_name => "Last",
|
1292
|
+
:binary_data => @binary_data
|
1293
|
+
)
|
1294
|
+
@employee.reload
|
1295
|
+
@employee.binary_data = nil
|
1296
|
+
@employee.save!
|
1297
|
+
@employee.reload
|
1298
|
+
@employee.binary_data.should be_nil
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
it "should update record that has existing RAW data with zero-length RAW data" do
|
1302
|
+
@employee = TestEmployee.create!(
|
1303
|
+
:first_name => "First",
|
1304
|
+
:last_name => "Last",
|
1305
|
+
:binary_data => @binary_data
|
1306
|
+
)
|
1307
|
+
@employee.reload
|
1308
|
+
@employee.binary_data = ''
|
1309
|
+
@employee.save!
|
1310
|
+
@employee.reload
|
1311
|
+
@employee.binary_data.should.nil?
|
1312
|
+
end
|
1313
|
+
|
1314
|
+
it "should update record that has zero-length BLOB data with non-empty RAW data" do
|
1315
|
+
@employee = TestEmployee.create!(
|
1316
|
+
:first_name => "First",
|
1317
|
+
:last_name => "Last",
|
1318
|
+
:binary_data => ''
|
1319
|
+
)
|
1320
|
+
@employee.reload
|
1321
|
+
@employee.binary_data = @binary_data
|
1322
|
+
@employee.save!
|
1323
|
+
@employee.reload
|
1324
|
+
@employee.binary_data.should == @binary_data
|
1325
|
+
end
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
|
1329
|
+
describe "OracleEnhancedAdapter quoting of NCHAR and NVARCHAR2 columns" do
|
1330
|
+
before(:all) do
|
1331
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
1332
|
+
@conn = ActiveRecord::Base.connection
|
1333
|
+
@conn.execute <<-SQL
|
1334
|
+
CREATE TABLE test_items (
|
1335
|
+
id NUMBER(6,0) PRIMARY KEY,
|
1336
|
+
nchar_column NCHAR(20),
|
1337
|
+
nvarchar2_column NVARCHAR2(20),
|
1338
|
+
char_column CHAR(20),
|
1339
|
+
varchar2_column VARCHAR2(20)
|
1340
|
+
)
|
1341
|
+
SQL
|
1342
|
+
@conn.execute "CREATE SEQUENCE test_items_seq"
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
after(:all) do
|
1346
|
+
@conn.execute "DROP TABLE test_items"
|
1347
|
+
@conn.execute "DROP SEQUENCE test_items_seq"
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
before(:each) do
|
1351
|
+
class ::TestItem < ActiveRecord::Base
|
1352
|
+
end
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
after(:each) do
|
1356
|
+
Object.send(:remove_const, "TestItem")
|
1357
|
+
ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
it "should set nchar instance variable" do
|
1361
|
+
columns = @conn.columns('test_items')
|
1362
|
+
%w(nchar_column nvarchar2_column char_column varchar2_column).each do |col|
|
1363
|
+
column = columns.detect{|c| c.name == col}
|
1364
|
+
column.type.should == :string
|
1365
|
+
column.nchar.should == (col[0,1] == 'n' ? true : nil)
|
1366
|
+
end
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
it "should quote with N prefix" do
|
1370
|
+
columns = @conn.columns('test_items')
|
1371
|
+
%w(nchar_column nvarchar2_column char_column varchar2_column).each do |col|
|
1372
|
+
column = columns.detect{|c| c.name == col}
|
1373
|
+
@conn.quote('abc', column).should == (column.nchar ? "N'abc'" : "'abc'")
|
1374
|
+
@conn.quote(nil, column).should == 'NULL'
|
1375
|
+
end
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
it "should create record" do
|
1379
|
+
nchar_data = 'āčē'
|
1380
|
+
item = TestItem.create(
|
1381
|
+
:nchar_column => nchar_data,
|
1382
|
+
:nvarchar2_column => nchar_data
|
1383
|
+
).reload
|
1384
|
+
item.nchar_column.should == nchar_data + ' '*17
|
1385
|
+
item.nvarchar2_column.should == nchar_data
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
end
|