activerecord-oracle_enhanced-adapter 8.1.0-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 +1971 -0
- data/License.txt +20 -0
- data/README.md +947 -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 +359 -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 +325 -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 +629 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +38 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +57 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +465 -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 +95 -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 +739 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +394 -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 +886 -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 +40 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/composite_spec.rb +84 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +589 -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/dbconsole_spec.rb +63 -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 +1318 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +485 -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 +101 -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 +55 -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 +295 -0
- data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +107 -0
- data/spec/spec_config.yaml.template +11 -0
- data/spec/spec_helper.rb +225 -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 +181 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ruby-plsql"
|
|
4
|
+
|
|
5
|
+
describe "OracleEnhancedAdapter custom methods for create, update and destroy" do
|
|
6
|
+
include LoggerSpecHelper
|
|
7
|
+
include SchemaSpecHelper
|
|
8
|
+
|
|
9
|
+
before(:all) do
|
|
10
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
|
11
|
+
@conn = ActiveRecord::Base.connection
|
|
12
|
+
plsql.activerecord_class = ActiveRecord::Base
|
|
13
|
+
schema_define do
|
|
14
|
+
create_table :test_employees, force: true do |t|
|
|
15
|
+
t.string :first_name, limit: 20
|
|
16
|
+
t.string :last_name, limit: 25
|
|
17
|
+
t.date :hire_date
|
|
18
|
+
t.decimal :salary, scale: 2, precision: 8
|
|
19
|
+
t.text :description
|
|
20
|
+
t.decimal :version, scale: 0, precision: 15
|
|
21
|
+
t.date :create_time
|
|
22
|
+
t.date :update_time
|
|
23
|
+
t.timestamps null: true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
@conn.execute <<~SQL
|
|
27
|
+
CREATE OR REPLACE PACKAGE test_employees_pkg IS
|
|
28
|
+
PROCEDURE create_employee(
|
|
29
|
+
p_first_name VARCHAR2,
|
|
30
|
+
p_last_name VARCHAR2,
|
|
31
|
+
p_hire_date DATE,
|
|
32
|
+
p_salary NUMBER,
|
|
33
|
+
p_description VARCHAR2,
|
|
34
|
+
p_employee_id OUT NUMBER);
|
|
35
|
+
PROCEDURE update_employee(
|
|
36
|
+
p_employee_id NUMBER,
|
|
37
|
+
p_first_name VARCHAR2,
|
|
38
|
+
p_last_name VARCHAR2,
|
|
39
|
+
p_hire_date DATE,
|
|
40
|
+
p_salary NUMBER,
|
|
41
|
+
p_description VARCHAR2);
|
|
42
|
+
PROCEDURE delete_employee(
|
|
43
|
+
p_employee_id NUMBER);
|
|
44
|
+
END;
|
|
45
|
+
SQL
|
|
46
|
+
@conn.execute <<~SQL
|
|
47
|
+
CREATE OR REPLACE PACKAGE BODY test_employees_pkg IS
|
|
48
|
+
PROCEDURE create_employee(
|
|
49
|
+
p_first_name VARCHAR2,
|
|
50
|
+
p_last_name VARCHAR2,
|
|
51
|
+
p_hire_date DATE,
|
|
52
|
+
p_salary NUMBER,
|
|
53
|
+
p_description VARCHAR2,
|
|
54
|
+
p_employee_id OUT NUMBER)
|
|
55
|
+
IS
|
|
56
|
+
BEGIN
|
|
57
|
+
SELECT test_employees_seq.NEXTVAL INTO p_employee_id FROM dual;
|
|
58
|
+
INSERT INTO test_employees (id, first_name, last_name, hire_date, salary, description,
|
|
59
|
+
version, create_time, update_time)
|
|
60
|
+
VALUES (p_employee_id, p_first_name, p_last_name, p_hire_date, p_salary, p_description,
|
|
61
|
+
1, SYSDATE, SYSDATE);
|
|
62
|
+
END create_employee;
|
|
63
|
+
|
|
64
|
+
PROCEDURE update_employee(
|
|
65
|
+
p_employee_id NUMBER,
|
|
66
|
+
p_first_name VARCHAR2,
|
|
67
|
+
p_last_name VARCHAR2,
|
|
68
|
+
p_hire_date DATE,
|
|
69
|
+
p_salary NUMBER,
|
|
70
|
+
p_description VARCHAR2)
|
|
71
|
+
IS
|
|
72
|
+
v_version NUMBER;
|
|
73
|
+
BEGIN
|
|
74
|
+
SELECT version INTO v_version FROM test_employees WHERE id = p_employee_id FOR UPDATE;
|
|
75
|
+
UPDATE test_employees
|
|
76
|
+
SET first_name = p_first_name, last_name = p_last_name,
|
|
77
|
+
hire_date = p_hire_date, salary = p_salary, description = p_description,
|
|
78
|
+
version = v_version + 1, update_time = SYSDATE
|
|
79
|
+
WHERE id = p_employee_id;
|
|
80
|
+
END update_employee;
|
|
81
|
+
|
|
82
|
+
PROCEDURE delete_employee(
|
|
83
|
+
p_employee_id NUMBER)
|
|
84
|
+
IS
|
|
85
|
+
BEGIN
|
|
86
|
+
DELETE FROM test_employees WHERE id = p_employee_id;
|
|
87
|
+
END delete_employee;
|
|
88
|
+
END;
|
|
89
|
+
SQL
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
after(:all) do
|
|
93
|
+
@conn = ActiveRecord::Base.connection
|
|
94
|
+
@conn.drop_table :test_employees, if_exists: true
|
|
95
|
+
@conn.execute "DROP PACKAGE test_employees_pkg"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
before(:each) do
|
|
99
|
+
class ::TestEmployee < ActiveRecord::Base
|
|
100
|
+
include ActiveRecord::OracleEnhancedProcedures
|
|
101
|
+
|
|
102
|
+
validates_presence_of :first_name, :last_name, :hire_date
|
|
103
|
+
|
|
104
|
+
# should return ID of new record
|
|
105
|
+
set_create_method do
|
|
106
|
+
plsql.test_employees_pkg.create_employee(
|
|
107
|
+
p_first_name: first_name,
|
|
108
|
+
p_last_name: last_name,
|
|
109
|
+
p_hire_date: hire_date,
|
|
110
|
+
p_salary: salary,
|
|
111
|
+
p_description: "#{first_name} #{last_name}",
|
|
112
|
+
p_employee_id: nil
|
|
113
|
+
)[:p_employee_id]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# return value is ignored
|
|
117
|
+
set_update_method do
|
|
118
|
+
plsql.test_employees_pkg.update_employee(
|
|
119
|
+
p_employee_id: id,
|
|
120
|
+
p_first_name: first_name,
|
|
121
|
+
p_last_name: last_name,
|
|
122
|
+
p_hire_date: hire_date,
|
|
123
|
+
p_salary: salary,
|
|
124
|
+
p_description: "#{first_name} #{last_name}"
|
|
125
|
+
)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# return value is ignored
|
|
129
|
+
set_delete_method do
|
|
130
|
+
plsql.test_employees_pkg.delete_employee(
|
|
131
|
+
p_employee_id: id
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
def raise_make_transaction_rollback
|
|
137
|
+
raise "Make the transaction rollback"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
@today = Date.new(2008, 6, 28)
|
|
142
|
+
@buffer = StringIO.new
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
after(:each) do
|
|
146
|
+
Object.send(:remove_const, "TestEmployee")
|
|
147
|
+
ActiveRecord::Base.clear_cache!
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "should create record" do
|
|
151
|
+
@employee = TestEmployee.create(
|
|
152
|
+
first_name: "First",
|
|
153
|
+
last_name: "Last",
|
|
154
|
+
hire_date: @today
|
|
155
|
+
)
|
|
156
|
+
@employee.reload
|
|
157
|
+
expect(@employee.first_name).to eq("First")
|
|
158
|
+
expect(@employee.last_name).to eq("Last")
|
|
159
|
+
expect(@employee.hire_date).to eq(@today)
|
|
160
|
+
expect(@employee.description).to eq("First Last")
|
|
161
|
+
expect(@employee.create_time).not_to be_nil
|
|
162
|
+
expect(@employee.update_time).not_to be_nil
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should rollback record when exception is raised in after_create callback" do
|
|
166
|
+
TestEmployee.after_create :raise_make_transaction_rollback
|
|
167
|
+
|
|
168
|
+
@employee = TestEmployee.new(
|
|
169
|
+
first_name: "First",
|
|
170
|
+
last_name: "Last",
|
|
171
|
+
hire_date: @today
|
|
172
|
+
)
|
|
173
|
+
employees_count = TestEmployee.count
|
|
174
|
+
expect {
|
|
175
|
+
@employee.save
|
|
176
|
+
}.to raise_error("Make the transaction rollback")
|
|
177
|
+
expect(@employee.new_record?).to be_truthy
|
|
178
|
+
expect(TestEmployee.count).to eq(employees_count)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "should update record" do
|
|
182
|
+
@employee = TestEmployee.create(
|
|
183
|
+
first_name: "First",
|
|
184
|
+
last_name: "Last",
|
|
185
|
+
hire_date: @today,
|
|
186
|
+
description: "description"
|
|
187
|
+
)
|
|
188
|
+
@employee.reload
|
|
189
|
+
@employee.first_name = "Second"
|
|
190
|
+
@employee.save!
|
|
191
|
+
@employee.reload
|
|
192
|
+
expect(@employee.description).to eq("Second Last")
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "should rollback record when exception is raised in after_update callback" do
|
|
196
|
+
TestEmployee.after_update :raise_make_transaction_rollback
|
|
197
|
+
|
|
198
|
+
@employee = TestEmployee.create(
|
|
199
|
+
first_name: "First",
|
|
200
|
+
last_name: "Last",
|
|
201
|
+
hire_date: @today,
|
|
202
|
+
description: "description"
|
|
203
|
+
)
|
|
204
|
+
@employee.reload
|
|
205
|
+
@employee.first_name = "Second"
|
|
206
|
+
expect {
|
|
207
|
+
@employee.save
|
|
208
|
+
}.to raise_error("Make the transaction rollback")
|
|
209
|
+
@employee.reload
|
|
210
|
+
expect(@employee.first_name).to eq("First")
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "should not update record if nothing is changed and partial updates are enabled" do
|
|
214
|
+
TestEmployee.partial_updates = true
|
|
215
|
+
@employee = TestEmployee.create(
|
|
216
|
+
first_name: "First",
|
|
217
|
+
last_name: "Last",
|
|
218
|
+
hire_date: @today
|
|
219
|
+
)
|
|
220
|
+
@employee.reload
|
|
221
|
+
@employee.save!
|
|
222
|
+
@employee.reload
|
|
223
|
+
expect(@employee.version).to eq(1)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it "should update record if nothing is changed and partial updates are disabled" do
|
|
227
|
+
TestEmployee.partial_updates = false
|
|
228
|
+
@employee = TestEmployee.create(
|
|
229
|
+
first_name: "First",
|
|
230
|
+
last_name: "Last",
|
|
231
|
+
hire_date: @today
|
|
232
|
+
)
|
|
233
|
+
@employee.reload
|
|
234
|
+
@employee.save!
|
|
235
|
+
@employee.reload
|
|
236
|
+
expect(@employee.version).to eq(2)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it "should delete record" do
|
|
240
|
+
@employee = TestEmployee.create(
|
|
241
|
+
first_name: "First",
|
|
242
|
+
last_name: "Last",
|
|
243
|
+
hire_date: @today
|
|
244
|
+
)
|
|
245
|
+
@employee.reload
|
|
246
|
+
empl_id = @employee.id
|
|
247
|
+
@employee.destroy
|
|
248
|
+
expect(@employee).to be_frozen
|
|
249
|
+
expect(TestEmployee.find_by_id(empl_id)).to be_nil
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "should delete record and set destroyed flag" do
|
|
253
|
+
@employee = TestEmployee.create(
|
|
254
|
+
first_name: "First",
|
|
255
|
+
last_name: "Last",
|
|
256
|
+
hire_date: @today
|
|
257
|
+
)
|
|
258
|
+
@employee.reload
|
|
259
|
+
@employee.destroy
|
|
260
|
+
expect(@employee).to be_destroyed
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it "should rollback record when exception is raised in after_destroy callback" do
|
|
264
|
+
set_logger
|
|
265
|
+
TestEmployee.after_destroy :raise_make_transaction_rollback
|
|
266
|
+
|
|
267
|
+
@employee = TestEmployee.create(
|
|
268
|
+
first_name: "First",
|
|
269
|
+
last_name: "Last",
|
|
270
|
+
hire_date: @today
|
|
271
|
+
)
|
|
272
|
+
@employee.reload
|
|
273
|
+
empl_id = @employee.id
|
|
274
|
+
expect {
|
|
275
|
+
@employee.destroy
|
|
276
|
+
}.to raise_error("Make the transaction rollback")
|
|
277
|
+
expect(@employee.id).to eq(empl_id)
|
|
278
|
+
expect(TestEmployee.find_by_id(empl_id)).not_to be_nil
|
|
279
|
+
clear_logger
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "should set timestamps when creating record" do
|
|
283
|
+
@employee = TestEmployee.create(
|
|
284
|
+
first_name: "First",
|
|
285
|
+
last_name: "Last",
|
|
286
|
+
hire_date: @today
|
|
287
|
+
)
|
|
288
|
+
expect(@employee.created_at).not_to be_nil
|
|
289
|
+
expect(@employee.updated_at).not_to be_nil
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "should set timestamps when updating record" do
|
|
293
|
+
@employee = TestEmployee.create(
|
|
294
|
+
first_name: "First",
|
|
295
|
+
last_name: "Last",
|
|
296
|
+
hire_date: @today
|
|
297
|
+
)
|
|
298
|
+
@employee.reload
|
|
299
|
+
expect(@employee.created_at).to be_nil
|
|
300
|
+
expect(@employee.updated_at).to be_nil
|
|
301
|
+
@employee.first_name = "Second"
|
|
302
|
+
@employee.save!
|
|
303
|
+
expect(@employee.created_at).to be_nil
|
|
304
|
+
expect(@employee.updated_at).not_to be_nil
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
it "should log create record" do
|
|
308
|
+
set_logger
|
|
309
|
+
@employee = TestEmployee.create(
|
|
310
|
+
first_name: "First",
|
|
311
|
+
last_name: "Last",
|
|
312
|
+
hire_date: @today
|
|
313
|
+
)
|
|
314
|
+
expect(@logger.logged(:debug).last).to match(/^TestEmployee Create \(\d+\.\d+(ms)?\) custom create method$/)
|
|
315
|
+
clear_logger
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it "should log update record" do
|
|
319
|
+
(TestEmployee.partial_updates = false) rescue nil
|
|
320
|
+
@employee = TestEmployee.create(
|
|
321
|
+
first_name: "First",
|
|
322
|
+
last_name: "Last",
|
|
323
|
+
hire_date: @today
|
|
324
|
+
)
|
|
325
|
+
set_logger
|
|
326
|
+
@employee.save!
|
|
327
|
+
expect(@logger.logged(:debug).last).to match(/^TestEmployee Update \(\d+\.\d+(ms)?\) custom update method with id=#{@employee.id}$/)
|
|
328
|
+
clear_logger
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
it "should log delete record" do
|
|
332
|
+
@employee = TestEmployee.create(
|
|
333
|
+
first_name: "First",
|
|
334
|
+
last_name: "Last",
|
|
335
|
+
hire_date: @today
|
|
336
|
+
)
|
|
337
|
+
set_logger
|
|
338
|
+
@employee.destroy
|
|
339
|
+
expect(@logger.logged(:debug).last).to match(/^TestEmployee Destroy \(\d+\.\d+(ms)?\) custom delete method with id=#{@employee.id}$/)
|
|
340
|
+
clear_logger
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
it "should validate new record before creation" do
|
|
344
|
+
@employee = TestEmployee.new(
|
|
345
|
+
last_name: "Last",
|
|
346
|
+
hire_date: @today
|
|
347
|
+
)
|
|
348
|
+
expect(@employee.save).to be_falsey
|
|
349
|
+
expect(@employee.errors[:first_name]).not_to be_blank
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
it "should validate existing record before update" do
|
|
353
|
+
@employee = TestEmployee.create(
|
|
354
|
+
first_name: "First",
|
|
355
|
+
last_name: "Last",
|
|
356
|
+
hire_date: @today
|
|
357
|
+
)
|
|
358
|
+
@employee.first_name = nil
|
|
359
|
+
expect(@employee.save).to be_falsey
|
|
360
|
+
expect(@employee.errors[:first_name]).not_to be_blank
|
|
361
|
+
end
|
|
362
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe "OracleEnhancedAdapter quoting" do
|
|
4
|
+
include LoggerSpecHelper
|
|
5
|
+
include SchemaSpecHelper
|
|
6
|
+
|
|
7
|
+
before(:all) do
|
|
8
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "reserved words column quoting" do
|
|
12
|
+
before(:all) do
|
|
13
|
+
schema_define do
|
|
14
|
+
create_table :test_reserved_words do |t|
|
|
15
|
+
t.string :varchar2
|
|
16
|
+
t.integer :integer
|
|
17
|
+
t.text :comment
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
class ::TestReservedWord < ActiveRecord::Base; end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
after(:all) do
|
|
24
|
+
schema_define do
|
|
25
|
+
drop_table :test_reserved_words
|
|
26
|
+
end
|
|
27
|
+
Object.send(:remove_const, "TestReservedWord")
|
|
28
|
+
ActiveRecord::Base.table_name_prefix = nil
|
|
29
|
+
ActiveRecord::Base.clear_cache!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
before(:each) do
|
|
33
|
+
set_logger
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
after(:each) do
|
|
37
|
+
clear_logger
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should create table" do
|
|
41
|
+
[:varchar2, :integer, :comment].each do |attr|
|
|
42
|
+
expect(TestReservedWord.columns_hash[attr.to_s].name).to eq(attr.to_s)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should create record" do
|
|
47
|
+
attrs = {
|
|
48
|
+
varchar2: "dummy",
|
|
49
|
+
integer: 1,
|
|
50
|
+
comment: "dummy"
|
|
51
|
+
}
|
|
52
|
+
record = TestReservedWord.create!(attrs)
|
|
53
|
+
record.reload
|
|
54
|
+
attrs.each do |k, v|
|
|
55
|
+
expect(record.send(k)).to eq(v)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should remove double quotes in column quoting" do
|
|
60
|
+
expect(ActiveRecord::Base.connection.quote_column_name('aaa "bbb" ccc')).to eq('"aaa bbb ccc"')
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "valid table names" do
|
|
65
|
+
before(:all) do
|
|
66
|
+
@adapter = ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should be valid with letters and digits" do
|
|
70
|
+
expect(@adapter.valid_table_name?("abc_123")).to be_truthy
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should be valid with schema name" do
|
|
74
|
+
expect(@adapter.valid_table_name?("abc_123.def_456")).to be_truthy
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should be valid with schema name and object name in different case" do
|
|
78
|
+
expect(@adapter.valid_table_name?("TEST_DBA.def_456")).to be_truthy
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should be valid with $ in name" do
|
|
82
|
+
expect(@adapter.valid_table_name?("sys.v$session")).to be_truthy
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should be valid with upcase schema name" do
|
|
86
|
+
expect(@adapter.valid_table_name?("ABC_123.DEF_456")).to be_truthy
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should not be valid with two dots in name" do
|
|
90
|
+
expect(@adapter.valid_table_name?("abc_123.def_456.ghi_789")).to be_falsey
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should not be valid with invalid characters" do
|
|
94
|
+
expect(@adapter.valid_table_name?("warehouse-things")).to be_falsey
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should not be valid with for camel-case" do
|
|
98
|
+
expect(@adapter.valid_table_name?("Abc")).to be_falsey
|
|
99
|
+
expect(@adapter.valid_table_name?("aBc")).to be_falsey
|
|
100
|
+
expect(@adapter.valid_table_name?("abC")).to be_falsey
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should not be valid for names > 30 characters" do
|
|
104
|
+
expect(@adapter.valid_table_name?("a" * 31)).to be_falsey
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should not be valid for schema names > 30 characters" do
|
|
108
|
+
expect(@adapter.valid_table_name?(("a" * 31) + ".validname")).to be_falsey
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should not be valid for names that do not begin with alphabetic characters" do
|
|
112
|
+
expect(@adapter.valid_table_name?("1abc")).to be_falsey
|
|
113
|
+
expect(@adapter.valid_table_name?("_abc")).to be_falsey
|
|
114
|
+
expect(@adapter.valid_table_name?("abc.1xyz")).to be_falsey
|
|
115
|
+
expect(@adapter.valid_table_name?("abc._xyz")).to be_falsey
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "table quoting" do
|
|
120
|
+
def create_warehouse_things_table
|
|
121
|
+
ActiveRecord::Schema.define do
|
|
122
|
+
suppress_messages do
|
|
123
|
+
create_table "warehouse-things" do |t|
|
|
124
|
+
t.string :name
|
|
125
|
+
t.integer :foo
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def create_camel_case_table
|
|
132
|
+
ActiveRecord::Schema.define do
|
|
133
|
+
suppress_messages do
|
|
134
|
+
create_table "CamelCase" do |t|
|
|
135
|
+
t.string :name
|
|
136
|
+
t.integer :foo
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
before(:all) do
|
|
143
|
+
@conn = ActiveRecord::Base.connection
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
after(:each) do
|
|
147
|
+
ActiveRecord::Schema.define do
|
|
148
|
+
suppress_messages do
|
|
149
|
+
drop_table "warehouse-things", if_exists: true
|
|
150
|
+
drop_table "CamelCase", if_exists: true
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
Object.send(:remove_const, "WarehouseThing") rescue nil
|
|
154
|
+
Object.send(:remove_const, "CamelCase") rescue nil
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should allow creation of a table with non alphanumeric characters" do
|
|
158
|
+
create_warehouse_things_table
|
|
159
|
+
class ::WarehouseThing < ActiveRecord::Base
|
|
160
|
+
self.table_name = "warehouse-things"
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
wh = WarehouseThing.create!(name: "Foo", foo: 2)
|
|
164
|
+
expect(wh.id).not_to be_nil
|
|
165
|
+
|
|
166
|
+
expect(@conn.tables).to include("warehouse-things")
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "should allow creation of a table with CamelCase name" do
|
|
170
|
+
create_camel_case_table
|
|
171
|
+
class ::CamelCase < ActiveRecord::Base
|
|
172
|
+
self.table_name = "CamelCase"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
cc = CamelCase.create!(name: "Foo", foo: 2)
|
|
176
|
+
expect(cc.id).not_to be_nil
|
|
177
|
+
|
|
178
|
+
expect(@conn.tables).to include("CamelCase")
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|