activerecord-oracle_enhanced-adapter 7.2.1-java
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.
- checksums.yaml +7 -0
- data/History.md +1977 -0
- data/License.txt +20 -0
- data/README.md +863 -0
- data/VERSION +1 -0
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +7 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +24 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +137 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +344 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +47 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +295 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +63 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +71 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +561 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +38 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +45 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +457 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +44 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +195 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +186 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +94 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +99 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +197 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +738 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +366 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +3 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +865 -0
- data/lib/active_record/type/oracle_enhanced/boolean.rb +19 -0
- data/lib/active_record/type/oracle_enhanced/character_string.rb +36 -0
- data/lib/active_record/type/oracle_enhanced/integer.rb +14 -0
- data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
- data/lib/active_record/type/oracle_enhanced/national_character_string.rb +26 -0
- data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
- data/lib/active_record/type/oracle_enhanced/raw.rb +25 -0
- data/lib/active_record/type/oracle_enhanced/string.rb +29 -0
- data/lib/active_record/type/oracle_enhanced/text.rb +32 -0
- data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
- data/lib/active_record/type/oracle_enhanced/timestamptz.rb +25 -0
- data/lib/activerecord-oracle_enhanced-adapter.rb +25 -0
- data/lib/arel/visitors/oracle.rb +216 -0
- data/lib/arel/visitors/oracle12.rb +121 -0
- data/lib/arel/visitors/oracle_common.rb +51 -0
- data/spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb +24 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/compatibility_spec.rb +36 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +574 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +431 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +122 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +69 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +362 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +181 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +492 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +1289 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +474 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +815 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +230 -0
- data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
- data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +206 -0
- data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +67 -0
- data/spec/active_record/oracle_enhanced/type/custom_spec.rb +90 -0
- data/spec/active_record/oracle_enhanced/type/decimal_spec.rb +56 -0
- data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +141 -0
- data/spec/active_record/oracle_enhanced/type/float_spec.rb +48 -0
- data/spec/active_record/oracle_enhanced/type/integer_spec.rb +99 -0
- data/spec/active_record/oracle_enhanced/type/json_spec.rb +56 -0
- data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +56 -0
- data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +230 -0
- data/spec/active_record/oracle_enhanced/type/raw_spec.rb +137 -0
- data/spec/active_record/oracle_enhanced/type/text_spec.rb +244 -0
- data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +77 -0
- data/spec/spec_config.yaml.template +11 -0
- data/spec/spec_helper.rb +214 -0
- data/spec/support/alter_system_set_open_cursors.sql +1 -0
- data/spec/support/alter_system_user_password.sql +2 -0
- data/spec/support/create_oracle_enhanced_users.sql +31 -0
- metadata +177 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe "OracleEnhancedAdapter handling of RAW columns" do
|
|
4
|
+
include SchemaSpecHelper
|
|
5
|
+
|
|
6
|
+
before(:all) do
|
|
7
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
|
8
|
+
schema_define do
|
|
9
|
+
create_table :test_employees, force: true do |t|
|
|
10
|
+
t.string :first_name, limit: 20
|
|
11
|
+
t.string :last_name, limit: 25
|
|
12
|
+
t.raw :binary_data, limit: 1024
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
@binary_data = "\0\1\2\3\4\5\6\7\8\9" * 100
|
|
16
|
+
@binary_data2 = "\1\2\3\4\5\6\7\8\9\0" * 100
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
after(:all) do
|
|
20
|
+
schema_define do
|
|
21
|
+
drop_table :test_employees
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
before(:each) do
|
|
26
|
+
class ::TestEmployee < ActiveRecord::Base
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
after(:each) do
|
|
31
|
+
Object.send(:remove_const, "TestEmployee")
|
|
32
|
+
ActiveRecord::Base.clear_cache!
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should create record with RAW data" do
|
|
36
|
+
@employee = TestEmployee.create!(
|
|
37
|
+
first_name: "First",
|
|
38
|
+
last_name: "Last",
|
|
39
|
+
binary_data: @binary_data
|
|
40
|
+
)
|
|
41
|
+
@employee.reload
|
|
42
|
+
expect(@employee.binary_data).to eq(@binary_data)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should update record with RAW data" do
|
|
46
|
+
@employee = TestEmployee.create!(
|
|
47
|
+
first_name: "First",
|
|
48
|
+
last_name: "Last"
|
|
49
|
+
)
|
|
50
|
+
@employee.reload
|
|
51
|
+
expect(@employee.binary_data).to be_nil
|
|
52
|
+
@employee.binary_data = @binary_data
|
|
53
|
+
@employee.save!
|
|
54
|
+
@employee.reload
|
|
55
|
+
expect(@employee.binary_data).to eq(@binary_data)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should update record with zero-length RAW data" do
|
|
59
|
+
@employee = TestEmployee.create!(
|
|
60
|
+
first_name: "First",
|
|
61
|
+
last_name: "Last"
|
|
62
|
+
)
|
|
63
|
+
@employee.reload
|
|
64
|
+
expect(@employee.binary_data).to be_nil
|
|
65
|
+
@employee.binary_data = ""
|
|
66
|
+
@employee.save!
|
|
67
|
+
@employee.reload
|
|
68
|
+
expect(@employee.binary_data).to be_nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should update record that has existing RAW data with different RAW data" do
|
|
72
|
+
@employee = TestEmployee.create!(
|
|
73
|
+
first_name: "First",
|
|
74
|
+
last_name: "Last",
|
|
75
|
+
binary_data: @binary_data
|
|
76
|
+
)
|
|
77
|
+
@employee.reload
|
|
78
|
+
@employee.binary_data = @binary_data2
|
|
79
|
+
@employee.save!
|
|
80
|
+
@employee.reload
|
|
81
|
+
expect(@employee.binary_data).to eq(@binary_data2)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should update record that has existing RAW data with nil" do
|
|
85
|
+
@employee = TestEmployee.create!(
|
|
86
|
+
first_name: "First",
|
|
87
|
+
last_name: "Last",
|
|
88
|
+
binary_data: @binary_data
|
|
89
|
+
)
|
|
90
|
+
@employee.reload
|
|
91
|
+
@employee.binary_data = nil
|
|
92
|
+
@employee.save!
|
|
93
|
+
@employee.reload
|
|
94
|
+
expect(@employee.binary_data).to be_nil
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should update record that has existing RAW data with zero-length RAW data" do
|
|
98
|
+
@employee = TestEmployee.create!(
|
|
99
|
+
first_name: "First",
|
|
100
|
+
last_name: "Last",
|
|
101
|
+
binary_data: @binary_data
|
|
102
|
+
)
|
|
103
|
+
@employee.reload
|
|
104
|
+
@employee.binary_data = ""
|
|
105
|
+
@employee.save!
|
|
106
|
+
@employee.reload
|
|
107
|
+
expect(@employee.binary_data).to be_nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should update record that has zero-length BLOB data with non-empty RAW data" do
|
|
111
|
+
@employee = TestEmployee.create!(
|
|
112
|
+
first_name: "First",
|
|
113
|
+
last_name: "Last",
|
|
114
|
+
binary_data: ""
|
|
115
|
+
)
|
|
116
|
+
@employee.reload
|
|
117
|
+
@employee.binary_data = @binary_data
|
|
118
|
+
@employee.save!
|
|
119
|
+
@employee.reload
|
|
120
|
+
expect(@employee.binary_data).to eq(@binary_data)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should allow equality on select" do
|
|
124
|
+
TestEmployee.delete_all
|
|
125
|
+
TestEmployee.create!(
|
|
126
|
+
first_name: "First",
|
|
127
|
+
last_name: "Last",
|
|
128
|
+
binary_data: @binary_data,
|
|
129
|
+
)
|
|
130
|
+
TestEmployee.create!(
|
|
131
|
+
first_name: "First1",
|
|
132
|
+
last_name: "Last1",
|
|
133
|
+
binary_data: @binary_data2,
|
|
134
|
+
)
|
|
135
|
+
expect(TestEmployee.where(binary_data: @binary_data)).to have_attributes(count: 1)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe "OracleEnhancedAdapter handling of CLOB columns" do
|
|
4
|
+
include SchemaSpecHelper
|
|
5
|
+
|
|
6
|
+
before(:all) do
|
|
7
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
|
8
|
+
@conn = ActiveRecord::Base.connection
|
|
9
|
+
schema_define do
|
|
10
|
+
create_table :test_employees, force: true do |t|
|
|
11
|
+
t.string :first_name, limit: 20
|
|
12
|
+
t.string :last_name, limit: 25
|
|
13
|
+
t.text :comments
|
|
14
|
+
end
|
|
15
|
+
create_table :test2_employees, force: true do |t|
|
|
16
|
+
t.string :first_name, limit: 20
|
|
17
|
+
t.string :last_name, limit: 25
|
|
18
|
+
t.text :comments
|
|
19
|
+
end
|
|
20
|
+
create_table :test_serialize_employees, force: true do |t|
|
|
21
|
+
t.string :first_name, limit: 20
|
|
22
|
+
t.string :last_name, limit: 25
|
|
23
|
+
end
|
|
24
|
+
add_column :test_serialize_employees, :comments, :text
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@char_data = (0..127).to_a.pack("C*") * 800
|
|
28
|
+
@char_data2 = ((1..127).to_a.pack("C*") + "\0") * 800
|
|
29
|
+
|
|
30
|
+
class ::TestEmployee < ActiveRecord::Base; end
|
|
31
|
+
class ::Test2Employee < ActiveRecord::Base
|
|
32
|
+
serialize :comments
|
|
33
|
+
end
|
|
34
|
+
class ::TestEmployeeReadOnlyClob < ActiveRecord::Base
|
|
35
|
+
self.table_name = "test_employees"
|
|
36
|
+
attr_readonly :comments
|
|
37
|
+
end
|
|
38
|
+
class ::TestSerializeEmployee < ActiveRecord::Base
|
|
39
|
+
serialize :comments
|
|
40
|
+
attr_readonly :comments
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
after(:all) do
|
|
45
|
+
@conn.drop_table :test_employees, if_exists: true
|
|
46
|
+
@conn.drop_table :test2_employees, if_exists: true
|
|
47
|
+
@conn.drop_table :test_serialize_employees, if_exists: true
|
|
48
|
+
Object.send(:remove_const, "TestEmployee")
|
|
49
|
+
Object.send(:remove_const, "Test2Employee")
|
|
50
|
+
Object.send(:remove_const, "TestEmployeeReadOnlyClob")
|
|
51
|
+
Object.send(:remove_const, "TestSerializeEmployee")
|
|
52
|
+
ActiveRecord::Base.clear_cache!
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should create record without CLOB data when attribute is serialized" do
|
|
56
|
+
@employee = Test2Employee.create!(
|
|
57
|
+
first_name: "First",
|
|
58
|
+
last_name: "Last"
|
|
59
|
+
)
|
|
60
|
+
expect(@employee).to be_valid
|
|
61
|
+
@employee.reload
|
|
62
|
+
expect(@employee.comments).to be_nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should accept Symbol value for CLOB column" do
|
|
66
|
+
@employee = TestEmployee.create!(
|
|
67
|
+
comments: :test_comment
|
|
68
|
+
)
|
|
69
|
+
expect(@employee).to be_valid
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should respect attr_readonly setting for CLOB column" do
|
|
73
|
+
@employee = TestEmployeeReadOnlyClob.create!(
|
|
74
|
+
first_name: "First",
|
|
75
|
+
comments: "initial"
|
|
76
|
+
)
|
|
77
|
+
expect(@employee).to be_valid
|
|
78
|
+
@employee.reload
|
|
79
|
+
expect(@employee.comments).to eq("initial")
|
|
80
|
+
@employee.comments = "changed"
|
|
81
|
+
expect(@employee.save).to be(true)
|
|
82
|
+
@employee.reload
|
|
83
|
+
expect(@employee.comments).to eq("initial")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should work for serialized readonly CLOB columns", serialized: true do
|
|
87
|
+
@employee = TestSerializeEmployee.new(
|
|
88
|
+
first_name: "First",
|
|
89
|
+
comments: nil
|
|
90
|
+
)
|
|
91
|
+
expect(@employee.comments).to be_nil
|
|
92
|
+
expect(@employee.save).to be(true)
|
|
93
|
+
expect(@employee).to be_valid
|
|
94
|
+
@employee.reload
|
|
95
|
+
expect(@employee.comments).to be_nil
|
|
96
|
+
@employee.comments = {}
|
|
97
|
+
expect(@employee.save).to be(true)
|
|
98
|
+
@employee.reload
|
|
99
|
+
# should not set readonly
|
|
100
|
+
expect(@employee.comments).to be_nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should create record with CLOB data" do
|
|
104
|
+
@employee = TestEmployee.create!(
|
|
105
|
+
first_name: "First",
|
|
106
|
+
last_name: "Last",
|
|
107
|
+
comments: @char_data
|
|
108
|
+
)
|
|
109
|
+
@employee.reload
|
|
110
|
+
expect(@employee.comments).to eq(@char_data)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should update record with CLOB data" do
|
|
114
|
+
@employee = TestEmployee.create!(
|
|
115
|
+
first_name: "First",
|
|
116
|
+
last_name: "Last"
|
|
117
|
+
)
|
|
118
|
+
@employee.reload
|
|
119
|
+
expect(@employee.comments).to be_nil
|
|
120
|
+
@employee.comments = @char_data
|
|
121
|
+
@employee.save!
|
|
122
|
+
@employee.reload
|
|
123
|
+
expect(@employee.comments).to eq(@char_data)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "should update record with zero-length CLOB data" do
|
|
127
|
+
@employee = TestEmployee.create!(
|
|
128
|
+
first_name: "First",
|
|
129
|
+
last_name: "Last"
|
|
130
|
+
)
|
|
131
|
+
@employee.reload
|
|
132
|
+
expect(@employee.comments).to be_nil
|
|
133
|
+
@employee.comments = ""
|
|
134
|
+
@employee.save!
|
|
135
|
+
@employee.reload
|
|
136
|
+
expect(@employee.comments).to eq("")
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "should update record that has existing CLOB data with different CLOB data" do
|
|
140
|
+
@employee = TestEmployee.create!(
|
|
141
|
+
first_name: "First",
|
|
142
|
+
last_name: "Last",
|
|
143
|
+
comments: @char_data
|
|
144
|
+
)
|
|
145
|
+
@employee.reload
|
|
146
|
+
@employee.comments = @char_data2
|
|
147
|
+
@employee.save!
|
|
148
|
+
@employee.reload
|
|
149
|
+
expect(@employee.comments).to eq(@char_data2)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should update record that has existing CLOB data with nil" do
|
|
153
|
+
@employee = TestEmployee.create!(
|
|
154
|
+
first_name: "First",
|
|
155
|
+
last_name: "Last",
|
|
156
|
+
comments: @char_data
|
|
157
|
+
)
|
|
158
|
+
@employee.reload
|
|
159
|
+
@employee.comments = nil
|
|
160
|
+
@employee.save!
|
|
161
|
+
@employee.reload
|
|
162
|
+
expect(@employee.comments).to be_nil
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should update record that has existing CLOB data with zero-length CLOB data" do
|
|
166
|
+
@employee = TestEmployee.create!(
|
|
167
|
+
first_name: "First",
|
|
168
|
+
last_name: "Last",
|
|
169
|
+
comments: @char_data
|
|
170
|
+
)
|
|
171
|
+
@employee.reload
|
|
172
|
+
@employee.comments = ""
|
|
173
|
+
@employee.save!
|
|
174
|
+
@employee.reload
|
|
175
|
+
expect(@employee.comments).to eq("")
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "should update record that has zero-length CLOB data with non-empty CLOB data" do
|
|
179
|
+
@employee = TestEmployee.create!(
|
|
180
|
+
first_name: "First",
|
|
181
|
+
last_name: "Last",
|
|
182
|
+
comments: ""
|
|
183
|
+
)
|
|
184
|
+
@employee.reload
|
|
185
|
+
expect(@employee.comments).to eq("")
|
|
186
|
+
@employee.comments = @char_data
|
|
187
|
+
@employee.save!
|
|
188
|
+
@employee.reload
|
|
189
|
+
expect(@employee.comments).to eq(@char_data)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it "should store serializable ruby data structures" do
|
|
193
|
+
ruby_data1 = { "arbitrary1" => ["ruby", :data, 123] }
|
|
194
|
+
ruby_data2 = { "arbitrary2" => ["ruby", :data, 123] }
|
|
195
|
+
@employee = Test2Employee.create!(
|
|
196
|
+
comments: ruby_data1
|
|
197
|
+
)
|
|
198
|
+
@employee.reload
|
|
199
|
+
expect(@employee.comments).to eq(ruby_data1)
|
|
200
|
+
@employee.comments = ruby_data2
|
|
201
|
+
@employee.save
|
|
202
|
+
@employee.reload
|
|
203
|
+
expect(@employee.comments).to eq(ruby_data2)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "should keep unchanged serialized data when other columns changed" do
|
|
207
|
+
@employee = Test2Employee.create!(
|
|
208
|
+
first_name: "First",
|
|
209
|
+
last_name: "Last",
|
|
210
|
+
comments: "initial serialized data"
|
|
211
|
+
)
|
|
212
|
+
@employee.first_name = "Steve"
|
|
213
|
+
@employee.save
|
|
214
|
+
@employee.reload
|
|
215
|
+
expect(@employee.comments).to eq("initial serialized data")
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "should keep serialized data after save" do
|
|
219
|
+
@employee = Test2Employee.new
|
|
220
|
+
@employee.comments = { length: { is: 1 } }
|
|
221
|
+
@employee.save
|
|
222
|
+
@employee.reload
|
|
223
|
+
expect(@employee.comments).to eq(length: { is: 1 })
|
|
224
|
+
@employee.comments = { length: { is: 2 } }
|
|
225
|
+
@employee.save
|
|
226
|
+
@employee.reload
|
|
227
|
+
expect(@employee.comments).to eq(length: { is: 2 })
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it "should allow equality on select" do
|
|
231
|
+
search_data = "text search CLOB"
|
|
232
|
+
Test2Employee.create!(
|
|
233
|
+
first_name: "First",
|
|
234
|
+
last_name: "Last",
|
|
235
|
+
comments: search_data,
|
|
236
|
+
)
|
|
237
|
+
Test2Employee.create!(
|
|
238
|
+
first_name: "First1",
|
|
239
|
+
last_name: "Last1",
|
|
240
|
+
comments: "other data",
|
|
241
|
+
)
|
|
242
|
+
expect(Test2Employee.where(comments: search_data)).to have_attributes(count: 1)
|
|
243
|
+
end
|
|
244
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe "OracleEnhancedAdapter timestamp with timezone support" do
|
|
4
|
+
include SchemaSpecHelper
|
|
5
|
+
|
|
6
|
+
before(:all) do
|
|
7
|
+
skip if ENV["DATABASE_SERVER_AND_CLIENT_VERSION_DO_NOT_MATCH"] == "true"
|
|
8
|
+
if ENV["DATABASE_VERSION"] == "11.2.0.2" && ENV["ORACLE_HOME"] == "/usr/lib/oracle/21/client64"
|
|
9
|
+
skip
|
|
10
|
+
end
|
|
11
|
+
ActiveRecord.default_timezone = :local
|
|
12
|
+
ActiveRecord::Base.establish_connection(CONNECTION_WITH_TIMEZONE_PARAMS)
|
|
13
|
+
@conn = ActiveRecord::Base.connection
|
|
14
|
+
schema_define do
|
|
15
|
+
create_table :test_employees, force: true do |t|
|
|
16
|
+
t.string :first_name, limit: 20
|
|
17
|
+
t.string :last_name, limit: 25
|
|
18
|
+
t.string :email, limit: 25
|
|
19
|
+
t.string :phone_number, limit: 20
|
|
20
|
+
t.date :hire_date
|
|
21
|
+
t.decimal :job_id, scale: 0, precision: 6
|
|
22
|
+
t.decimal :salary, scale: 2, precision: 8
|
|
23
|
+
t.decimal :commission_pct, scale: 2, precision: 2
|
|
24
|
+
t.decimal :manager_id, scale: 0, precision: 6
|
|
25
|
+
t.decimal :department_id, scale: 0, precision: 4
|
|
26
|
+
t.timestamp :created_at
|
|
27
|
+
t.timestamptz :created_at_tz
|
|
28
|
+
t.timestampltz :created_at_ltz
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
after(:all) do
|
|
34
|
+
@conn.drop_table :test_employees, if_exists: true rescue nil
|
|
35
|
+
ActiveRecord.default_timezone = :utc
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "/ TIMESTAMP WITH TIME ZONE values from ActiveRecord model" do
|
|
39
|
+
before(:all) do
|
|
40
|
+
class ::TestEmployee < ActiveRecord::Base
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
after(:all) do
|
|
45
|
+
Object.send(:remove_const, "TestEmployee")
|
|
46
|
+
ActiveRecord::Base.clear_cache!
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should return Time value from TIMESTAMP columns" do
|
|
50
|
+
@now = Time.local(2008, 5, 26, 23, 11, 11, 0)
|
|
51
|
+
@employee = TestEmployee.create(
|
|
52
|
+
created_at: @now,
|
|
53
|
+
created_at_tz: @now,
|
|
54
|
+
created_at_ltz: @now
|
|
55
|
+
)
|
|
56
|
+
@employee.reload
|
|
57
|
+
[:created_at, :created_at_tz, :created_at_ltz].each do |c|
|
|
58
|
+
expect(@employee.send(c).class).to eq(Time)
|
|
59
|
+
expect(@employee.send(c).to_f).to eq(@now.to_f)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should return Time value with fractional seconds from TIMESTAMP columns" do
|
|
64
|
+
@now = Time.local(2008, 5, 26, 23, 11, 11, 10)
|
|
65
|
+
@employee = TestEmployee.create(
|
|
66
|
+
created_at: @now,
|
|
67
|
+
created_at_tz: @now,
|
|
68
|
+
created_at_ltz: @now
|
|
69
|
+
)
|
|
70
|
+
@employee.reload
|
|
71
|
+
[:created_at, :created_at_tz, :created_at_ltz].each do |c|
|
|
72
|
+
expect(@employee.send(c).class).to eq(Time)
|
|
73
|
+
expect(@employee.send(c).to_f).to eq(@now.to_f)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# copy this file to spec/spec_config.yaml and set appropriate values
|
|
2
|
+
# you can also use environment variables, see spec_helper.rb
|
|
3
|
+
database:
|
|
4
|
+
name: 'FREEPDB1'
|
|
5
|
+
host: '127.0.0.1'
|
|
6
|
+
port: 1521
|
|
7
|
+
user: 'oracle_enhanced'
|
|
8
|
+
password: 'oracle_enhanced'
|
|
9
|
+
sys_password: 'oracle'
|
|
10
|
+
non_default_tablespace: 'SYSTEM'
|
|
11
|
+
timezone: 'Europe/Riga'
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rubygems"
|
|
4
|
+
require "bundler"
|
|
5
|
+
require "yaml"
|
|
6
|
+
Bundler.setup(:default, :development)
|
|
7
|
+
|
|
8
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
|
9
|
+
config_path = File.expand_path("../spec_config.yaml", __FILE__)
|
|
10
|
+
if File.exist?(config_path)
|
|
11
|
+
puts "==> Loading config from #{config_path}"
|
|
12
|
+
config = YAML.load_file(config_path)
|
|
13
|
+
else
|
|
14
|
+
puts "==> Loading config from ENV or use default"
|
|
15
|
+
config = { "rails" => {}, "database" => {} }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
require "rspec"
|
|
19
|
+
|
|
20
|
+
if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby"
|
|
21
|
+
puts "==> Running specs with ruby version #{RUBY_VERSION}"
|
|
22
|
+
require "oci8"
|
|
23
|
+
elsif RUBY_ENGINE == "jruby"
|
|
24
|
+
puts "==> Running specs with JRuby version #{JRUBY_VERSION}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
require "active_record"
|
|
28
|
+
|
|
29
|
+
require "active_support/core_ext/module/attribute_accessors"
|
|
30
|
+
require "active_support/core_ext/class/attribute_accessors"
|
|
31
|
+
|
|
32
|
+
require "active_support/log_subscriber"
|
|
33
|
+
require "active_record/log_subscriber"
|
|
34
|
+
|
|
35
|
+
require "logger"
|
|
36
|
+
require "ruby-plsql"
|
|
37
|
+
|
|
38
|
+
require "active_record/connection_adapters/oracle_enhanced_adapter"
|
|
39
|
+
|
|
40
|
+
puts "==> Effective ActiveRecord version #{ActiveRecord::VERSION::STRING}"
|
|
41
|
+
|
|
42
|
+
module LoggerSpecHelper
|
|
43
|
+
def set_logger
|
|
44
|
+
@logger = MockLogger.new
|
|
45
|
+
@old_logger = ActiveRecord::Base.logger
|
|
46
|
+
|
|
47
|
+
@notifier = ActiveSupport::Notifications::Fanout.new
|
|
48
|
+
|
|
49
|
+
ActiveSupport::LogSubscriber.colorize_logging = false
|
|
50
|
+
|
|
51
|
+
ActiveRecord::Base.logger = @logger
|
|
52
|
+
@old_notifier = ActiveSupport::Notifications.notifier
|
|
53
|
+
ActiveSupport::Notifications.notifier = @notifier
|
|
54
|
+
|
|
55
|
+
ActiveRecord::LogSubscriber.attach_to(:active_record)
|
|
56
|
+
ActiveSupport::Notifications.subscribe("sql.active_record", ActiveRecord::ExplainSubscriber.new)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class MockLogger
|
|
60
|
+
LEVELS = %i[debug info warn error fatal unknown]
|
|
61
|
+
|
|
62
|
+
attr_reader :flush_count
|
|
63
|
+
|
|
64
|
+
def initialize
|
|
65
|
+
@flush_count = 0
|
|
66
|
+
@logged = Hash.new { |h, k| h[k] = [] }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# used in ActiveRecord 2.x
|
|
70
|
+
def debug?
|
|
71
|
+
true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def level
|
|
75
|
+
0
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def method_missing(*args)
|
|
79
|
+
if LEVELS.include?(args[0])
|
|
80
|
+
level, message = args
|
|
81
|
+
@logged[level] << message
|
|
82
|
+
else
|
|
83
|
+
super
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def logged(level)
|
|
88
|
+
@logged[level].compact.map { |l| l.to_s.strip }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def output(level)
|
|
92
|
+
logged(level).join("\n")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def flush
|
|
96
|
+
@flush_count += 1
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def clear(level)
|
|
100
|
+
@logged[level] = []
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def clear_logger
|
|
105
|
+
ActiveRecord::Base.logger = @old_logger
|
|
106
|
+
@logger = nil
|
|
107
|
+
|
|
108
|
+
ActiveSupport::Notifications.notifier = @old_notifier
|
|
109
|
+
@notifier = nil
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Wait notifications to be published (for Rails 3.0)
|
|
113
|
+
# should not be currently used with sync queues in tests
|
|
114
|
+
def wait
|
|
115
|
+
@notifier.wait if @notifier
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
ActiveRecord::LogSubscriber::IGNORE_PAYLOAD_NAMES.replace(["EXPLAIN"])
|
|
120
|
+
|
|
121
|
+
module SchemaSpecHelper
|
|
122
|
+
def schema_define(&block)
|
|
123
|
+
ActiveRecord::Schema.define do
|
|
124
|
+
suppress_messages do
|
|
125
|
+
instance_eval(&block)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
module SchemaDumpingHelper
|
|
132
|
+
def dump_table_schema(table, connection = ActiveRecord::Base.connection)
|
|
133
|
+
old_ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
|
134
|
+
ActiveRecord::SchemaDumper.ignore_tables = connection.data_sources - [table]
|
|
135
|
+
stream = StringIO.new
|
|
136
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection_pool, stream)
|
|
137
|
+
stream.string
|
|
138
|
+
ensure
|
|
139
|
+
ActiveRecord::SchemaDumper.ignore_tables = old_ignore_tables
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
DATABASE_NAME = config["database"]["name"] || ENV["DATABASE_NAME"] || "orcl"
|
|
144
|
+
DATABASE_HOST = config["database"]["host"] || ENV["DATABASE_HOST"] || "127.0.0.1"
|
|
145
|
+
DATABASE_PORT = config["database"]["port"] || ENV["DATABASE_PORT"] || 1521
|
|
146
|
+
DATABASE_USER = config["database"]["user"] || ENV["DATABASE_USER"] || "oracle_enhanced"
|
|
147
|
+
DATABASE_PASSWORD = config["database"]["password"] || ENV["DATABASE_PASSWORD"] || "oracle_enhanced"
|
|
148
|
+
DATABASE_SCHEMA = config["database"]["schema"] || ENV["DATABASE_SCHEMA"] || "oracle_enhanced_schema"
|
|
149
|
+
DATABASE_SYS_PASSWORD = config["database"]["sys_password"] || ENV["DATABASE_SYS_PASSWORD"] || "admin"
|
|
150
|
+
|
|
151
|
+
CONNECTION_PARAMS = {
|
|
152
|
+
adapter: "oracle_enhanced",
|
|
153
|
+
database: DATABASE_NAME,
|
|
154
|
+
host: DATABASE_HOST,
|
|
155
|
+
port: DATABASE_PORT,
|
|
156
|
+
username: DATABASE_USER,
|
|
157
|
+
password: DATABASE_PASSWORD
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
CONNECTION_WITH_SCHEMA_PARAMS = {
|
|
161
|
+
adapter: "oracle_enhanced",
|
|
162
|
+
database: DATABASE_NAME,
|
|
163
|
+
host: DATABASE_HOST,
|
|
164
|
+
port: DATABASE_PORT,
|
|
165
|
+
username: DATABASE_USER,
|
|
166
|
+
password: DATABASE_PASSWORD,
|
|
167
|
+
schema: DATABASE_SCHEMA
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
CONNECTION_WITH_TIMEZONE_PARAMS = {
|
|
171
|
+
adapter: "oracle_enhanced",
|
|
172
|
+
database: DATABASE_NAME,
|
|
173
|
+
host: DATABASE_HOST,
|
|
174
|
+
port: DATABASE_PORT,
|
|
175
|
+
username: DATABASE_USER,
|
|
176
|
+
password: DATABASE_PASSWORD,
|
|
177
|
+
time_zone: "Europe/Riga"
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
SYS_CONNECTION_PARAMS = {
|
|
181
|
+
adapter: "oracle_enhanced",
|
|
182
|
+
database: DATABASE_NAME,
|
|
183
|
+
host: DATABASE_HOST,
|
|
184
|
+
port: DATABASE_PORT,
|
|
185
|
+
username: "sys",
|
|
186
|
+
password: DATABASE_SYS_PASSWORD,
|
|
187
|
+
privilege: "SYSDBA"
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
SYSTEM_CONNECTION_PARAMS = {
|
|
191
|
+
adapter: "oracle_enhanced",
|
|
192
|
+
database: DATABASE_NAME,
|
|
193
|
+
host: DATABASE_HOST,
|
|
194
|
+
port: DATABASE_PORT,
|
|
195
|
+
username: "system",
|
|
196
|
+
password: DATABASE_SYS_PASSWORD
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
SERVICE_NAME_CONNECTION_PARAMS = {
|
|
200
|
+
adapter: "oracle_enhanced",
|
|
201
|
+
database: "/#{DATABASE_NAME}",
|
|
202
|
+
host: DATABASE_HOST,
|
|
203
|
+
port: DATABASE_PORT,
|
|
204
|
+
username: DATABASE_USER,
|
|
205
|
+
password: DATABASE_PASSWORD
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
DATABASE_NON_DEFAULT_TABLESPACE = config["database"]["non_default_tablespace"] || ENV["DATABASE_NON_DEFAULT_TABLESPACE"] || "SYSTEM"
|
|
209
|
+
|
|
210
|
+
# set default time zone in TZ environment variable
|
|
211
|
+
# which will be used to set session time zone
|
|
212
|
+
ENV["TZ"] ||= config["timezone"] || "Europe/Riga"
|
|
213
|
+
|
|
214
|
+
ActiveRecord::Base.logger = ActiveSupport::Logger.new("debug.log", 0, 100 * 1024 * 1024)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
alter system set open_cursors = 1200 scope = both;
|