activerecord-oracle_enhanced-adapter 8.1.0.rc3-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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +1971 -0
  3. data/License.txt +20 -0
  4. data/README.md +947 -0
  5. data/VERSION +1 -0
  6. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +7 -0
  7. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +24 -0
  8. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +137 -0
  9. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +359 -0
  10. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +47 -0
  11. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +325 -0
  12. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +63 -0
  13. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +71 -0
  14. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +629 -0
  15. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +38 -0
  16. data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +57 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +465 -0
  18. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +44 -0
  19. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +195 -0
  20. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +186 -0
  21. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +95 -0
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +99 -0
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +197 -0
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +739 -0
  25. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +394 -0
  26. data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +34 -0
  27. data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +3 -0
  28. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +886 -0
  29. data/lib/active_record/type/oracle_enhanced/boolean.rb +19 -0
  30. data/lib/active_record/type/oracle_enhanced/character_string.rb +36 -0
  31. data/lib/active_record/type/oracle_enhanced/integer.rb +14 -0
  32. data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
  33. data/lib/active_record/type/oracle_enhanced/national_character_string.rb +26 -0
  34. data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
  35. data/lib/active_record/type/oracle_enhanced/raw.rb +25 -0
  36. data/lib/active_record/type/oracle_enhanced/string.rb +29 -0
  37. data/lib/active_record/type/oracle_enhanced/text.rb +32 -0
  38. data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
  39. data/lib/active_record/type/oracle_enhanced/timestamptz.rb +25 -0
  40. data/lib/activerecord-oracle_enhanced-adapter.rb +25 -0
  41. data/lib/arel/visitors/oracle.rb +216 -0
  42. data/lib/arel/visitors/oracle12.rb +121 -0
  43. data/lib/arel/visitors/oracle_common.rb +51 -0
  44. data/spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb +24 -0
  45. data/spec/active_record/connection_adapters/oracle_enhanced/compatibility_spec.rb +40 -0
  46. data/spec/active_record/connection_adapters/oracle_enhanced/composite_spec.rb +84 -0
  47. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +589 -0
  48. data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +431 -0
  49. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +122 -0
  50. data/spec/active_record/connection_adapters/oracle_enhanced/dbconsole_spec.rb +63 -0
  51. data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +69 -0
  52. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +362 -0
  53. data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +181 -0
  54. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +492 -0
  55. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +1318 -0
  56. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +485 -0
  57. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +815 -0
  58. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +230 -0
  59. data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
  60. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +206 -0
  61. data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +67 -0
  62. data/spec/active_record/oracle_enhanced/type/custom_spec.rb +90 -0
  63. data/spec/active_record/oracle_enhanced/type/decimal_spec.rb +56 -0
  64. data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +141 -0
  65. data/spec/active_record/oracle_enhanced/type/float_spec.rb +48 -0
  66. data/spec/active_record/oracle_enhanced/type/integer_spec.rb +101 -0
  67. data/spec/active_record/oracle_enhanced/type/json_spec.rb +56 -0
  68. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +55 -0
  69. data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +230 -0
  70. data/spec/active_record/oracle_enhanced/type/raw_spec.rb +137 -0
  71. data/spec/active_record/oracle_enhanced/type/text_spec.rb +295 -0
  72. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +111 -0
  73. data/spec/spec_config.yaml.template +11 -0
  74. data/spec/spec_helper.rb +225 -0
  75. data/spec/support/alter_system_set_open_cursors.sql +1 -0
  76. data/spec/support/alter_system_user_password.sql +2 -0
  77. data/spec/support/create_oracle_enhanced_users.sql +31 -0
  78. metadata +181 -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,295 @@
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
+
245
+ describe "with prepared_statements disabled" do
246
+ around(:each) do |example|
247
+ old_prepared_statements = @conn.prepared_statements
248
+ @conn.instance_variable_set(:@prepared_statements, false)
249
+ example.run
250
+ @conn.instance_variable_set(:@prepared_statements, old_prepared_statements)
251
+ end
252
+
253
+ it "should create record with CLOB data when prepared_statements is false" do
254
+ @employee = TestEmployee.create!(
255
+ first_name: "First",
256
+ last_name: "Last",
257
+ comments: @char_data
258
+ )
259
+ @employee.reload
260
+ expect(@employee.comments).to eq(@char_data)
261
+ end
262
+
263
+ it "should create record with short CLOB data when prepared_statements is false" do
264
+ short_data = "Short CLOB content"
265
+ @employee = TestEmployee.create!(
266
+ first_name: "First",
267
+ last_name: "Last",
268
+ comments: short_data
269
+ )
270
+ @employee.reload
271
+ expect(@employee.comments).to eq(short_data)
272
+ end
273
+
274
+ it "should create record with empty CLOB when prepared_statements is false" do
275
+ @employee = TestEmployee.create!(
276
+ first_name: "First",
277
+ last_name: "Last",
278
+ comments: ""
279
+ )
280
+ @employee.reload
281
+ expect(@employee.comments).to eq("")
282
+ end
283
+
284
+ it "should create record with serialized CLOB data when prepared_statements is false" do
285
+ ruby_data = { "test" => ["ruby", :data, 123] }
286
+ @employee = Test2Employee.create!(
287
+ first_name: "First",
288
+ last_name: "Last",
289
+ comments: ruby_data
290
+ )
291
+ @employee.reload
292
+ expect(@employee.comments).to eq(ruby_data)
293
+ end
294
+ end
295
+ end
@@ -0,0 +1,111 @@
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
+
77
+ it "should return Time value with millisecond fractional seconds from TIMESTAMP columns" do
78
+ @now = Time.local(2008, 5, 26, 23, 11, 11, 123_000) # 123 ms = 123_000 μs
79
+ @employee = TestEmployee.create(
80
+ created_at: @now,
81
+ created_at_tz: @now,
82
+ created_at_ltz: @now
83
+ )
84
+ @employee.reload
85
+ [:created_at, :created_at_tz, :created_at_ltz].each do |c|
86
+ expect(@employee.send(c).class).to eq(Time)
87
+ expect(@employee.send(c).to_f).to eq(@now.to_f)
88
+ end
89
+ end
90
+
91
+ it "should preserve microsecond precision when binding Time values" do
92
+ # Guard against the JDBC bind path going through Float (which can drift
93
+ # by 1 ms for current epoch values). Assert on Time#to_i and Time#usec
94
+ # directly instead of Time#to_f, which is too coarse to catch drift.
95
+ # Note: the TIMESTAMP columns above use the default fractional precision
96
+ # of 6, so the round-trip is truncated to microseconds.
97
+ @now = Time.local(2008, 5, 26, 23, 11, 11, 123_456)
98
+ @employee = TestEmployee.create(
99
+ created_at: @now,
100
+ created_at_tz: @now,
101
+ created_at_ltz: @now
102
+ )
103
+ @employee.reload
104
+ [:created_at, :created_at_tz, :created_at_ltz].each do |c|
105
+ expect(@employee.send(c).to_i).to eq(@now.to_i)
106
+ expect(@employee.send(c).usec).to eq(@now.usec)
107
+ expect(@employee.send(c).nsec).to eq(@now.nsec)
108
+ end
109
+ end
110
+ end
111
+ 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'