Skip to content

Commit 7fc1f99

Browse files
authored
Merge pull request rsim#1669 from yahonda/drop_trigger_based_primary_key_support
Drop trigger based primary key support for Rails 6
2 parents 4630a39 + 61f8a30 commit 7fc1f99

File tree

7 files changed

+4
-313
lines changed

7 files changed

+4
-313
lines changed

lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb

-11
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ def tables(stream)
1313
# add table prefix or suffix for schema_migrations
1414
next if ignored? tbl
1515
table(tbl, stream)
16-
# add primary key trigger if table has it
17-
primary_key_trigger(tbl, stream)
1816
end
1917
# following table definitions
2018
# add foreign keys if table has them
@@ -27,15 +25,6 @@ def tables(stream)
2725
synonyms(stream)
2826
end
2927

30-
def primary_key_trigger(table_name, stream)
31-
if @connection.has_primary_key_trigger?(table_name)
32-
pk, _pk_seq = @connection.pk_and_sequence_for(table_name)
33-
stream.print " add_primary_key_trigger #{table_name.inspect}"
34-
stream.print ", primary_key: \"#{pk}\"" if pk != "id"
35-
stream.print "\n\n"
36-
end
37-
end
38-
3928
def synonyms(stream)
4029
syns = @connection.synonyms
4130
syns.each do |syn|

lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb

+2-24
Original file line numberDiff line numberDiff line change
@@ -658,33 +658,11 @@ def column_for(table_name, column_name)
658658
end
659659

660660
def create_sequence_and_trigger(table_name, options)
661+
# TODO: Needs rename since no triggers created
662+
# This method will be removed since sequence will not be created separately
661663
seq_name = options[:sequence_name] || default_sequence_name(table_name)
662664
seq_start_value = options[:sequence_start_value] || default_sequence_start_value
663665
execute "CREATE SEQUENCE #{quote_table_name(seq_name)} START WITH #{seq_start_value}"
664-
665-
create_primary_key_trigger(table_name, options) if options[:primary_key_trigger]
666-
end
667-
668-
def create_primary_key_trigger(table_name, options)
669-
seq_name = options[:sequence_name] || default_sequence_name(table_name)
670-
trigger_name = options[:trigger_name] || default_trigger_name(table_name)
671-
primary_key = options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)
672-
execute <<-SQL
673-
CREATE OR REPLACE TRIGGER #{quote_table_name(trigger_name)}
674-
BEFORE INSERT ON #{quote_table_name(table_name)} FOR EACH ROW
675-
BEGIN
676-
IF inserting THEN
677-
IF :new.#{quote_column_name(primary_key)} IS NULL THEN
678-
SELECT #{quote_table_name(seq_name)}.NEXTVAL INTO :new.#{quote_column_name(primary_key)} FROM dual;
679-
END IF;
680-
END IF;
681-
END;
682-
SQL
683-
end
684-
685-
def default_trigger_name(table_name)
686-
# truncate table name if necessary to fit in max length of identifier
687-
"#{table_name.to_s[0, table_name_length - 4]}_pkt"
688666
end
689667

690668
def rebuild_primary_key_index_to_default_tablespace(table_name, options)

lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb

-28
This file was deleted.

lib/active_record/connection_adapters/oracle_enhanced_adapter.rb

+2-21
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
require "active_record/connection_adapters/oracle_enhanced/schema_definitions"
3939
require "active_record/connection_adapters/oracle_enhanced/schema_dumper"
4040
require "active_record/connection_adapters/oracle_enhanced/schema_statements"
41-
require "active_record/connection_adapters/oracle_enhanced/schema_statements_ext"
4241
require "active_record/connection_adapters/oracle_enhanced/context_index"
4342
require "active_record/connection_adapters/oracle_enhanced/column"
4443
require "active_record/connection_adapters/oracle_enhanced/quoting"
@@ -142,7 +141,6 @@ module ConnectionAdapters #:nodoc:
142141
class OracleEnhancedAdapter < AbstractAdapter
143142
include OracleEnhanced::DatabaseStatements
144143
include OracleEnhanced::SchemaStatements
145-
include OracleEnhanced::SchemaStatementsExt
146144
include OracleEnhanced::ContextIndex
147145
include OracleEnhanced::Quoting
148146
include OracleEnhanced::DatabaseLimits
@@ -415,7 +413,7 @@ def discard!
415413
# when inserting a new database record (see #prefetch_primary_key?).
416414
def next_sequence_value(sequence_name)
417415
# if sequence_name is set to :autogenerated then it means that primary key will be populated by trigger
418-
return nil if sequence_name == AUTOGENERATED_SEQUENCE_NAME
416+
raise ArgumentError "Trigger based primary key is not supported" if sequence_name == AUTOGENERATED_SEQUENCE_NAME
419417
# call directly connection method to avoid prepared statement which causes fetching of next sequence value twice
420418
select_value(<<-SQL.strip.gsub(/\s+/, " "), "next sequence value")
421419
SELECT #{quote_table_name(sequence_name)}.NEXTVAL FROM dual
@@ -428,7 +426,7 @@ def prefetch_primary_key?(table_name = nil)
428426
return true if table_name.nil?
429427
table_name = table_name.to_s
430428
owner, desc_table_name = @connection.describe(table_name)
431-
do_not_prefetch = !has_primary_key?(table_name, owner, desc_table_name) || has_primary_key_trigger?(table_name, owner, desc_table_name)
429+
do_not_prefetch = !has_primary_key?(table_name, owner, desc_table_name)
432430
!do_not_prefetch
433431
end
434432

@@ -494,23 +492,6 @@ def default_tablespace
494492
SQL
495493
end
496494

497-
# check if table has primary key trigger with _pkt suffix
498-
def has_primary_key_trigger?(table_name, owner = nil, desc_table_name = nil)
499-
(owner, desc_table_name) = @connection.describe(table_name) unless owner
500-
501-
trigger_name = default_trigger_name(table_name).upcase
502-
503-
!!select_value(<<-SQL.strip.gsub(/\s+/, " "), "Primary Key Trigger", [bind_string("owner", owner), bind_string("trigger_name", trigger_name), bind_string("owner", owner), bind_string("table_name", desc_table_name)])
504-
SELECT trigger_name
505-
FROM all_triggers
506-
WHERE owner = :owner
507-
AND trigger_name = :trigger_name
508-
AND table_owner = :owner
509-
AND table_name = :table_name
510-
AND status = 'ENABLED'
511-
SQL
512-
end
513-
514495
def column_definitions(table_name)
515496
(owner, desc_table_name) = @connection.describe(table_name)
516497

spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb

-18
Original file line numberDiff line numberDiff line change
@@ -110,24 +110,6 @@ def drop_test_posts_table
110110
end
111111
end
112112

113-
describe "table with primary key trigger" do
114-
115-
after(:each) do
116-
drop_test_posts_table
117-
end
118-
119-
it "should include primary key trigger in schema dump" do
120-
create_test_posts_table(primary_key_trigger: true)
121-
expect(standard_dump).to match(/create_table "test_posts".*add_primary_key_trigger "test_posts"/m)
122-
end
123-
124-
it "should include primary key trigger with non-default primary key in schema dump" do
125-
create_test_posts_table(primary_key_trigger: true, primary_key: "post_id")
126-
expect(standard_dump).to match(/create_table "test_posts", primary_key: "post_id".*add_primary_key_trigger "test_posts", primary_key: "post_id"/m)
127-
end
128-
129-
end
130-
131113
describe "foreign key constraints" do
132114
before(:all) do
133115
schema_define do

spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb

-204
Original file line numberDiff line numberDiff line change
@@ -153,172 +153,6 @@ class ::TestEmployee < ActiveRecord::Base; end
153153

154154
end
155155

156-
describe "create table with primary key trigger" do
157-
def create_table_with_trigger(options = {})
158-
options.merge! primary_key_trigger: true, force: true
159-
schema_define do
160-
create_table :test_employees, options do |t|
161-
t.string :first_name
162-
t.string :last_name
163-
end
164-
end
165-
end
166-
167-
def create_table_and_separately_trigger(options = {})
168-
options.merge! force: true
169-
schema_define do
170-
create_table :test_employees, options do |t|
171-
t.string :first_name
172-
t.string :last_name
173-
end
174-
add_primary_key_trigger :test_employees, options
175-
end
176-
end
177-
178-
def drop_table_with_trigger(options = {})
179-
seq_name = options[:sequence_name]
180-
schema_define do
181-
drop_table :test_employees, (seq_name ? { sequence_name: seq_name } : {})
182-
end
183-
Object.send(:remove_const, "TestEmployee")
184-
ActiveRecord::Base.clear_cache!
185-
end
186-
187-
describe "with default primary key" do
188-
before(:all) do
189-
@conn = ActiveRecord::Base.connection
190-
create_table_with_trigger
191-
class ::TestEmployee < ActiveRecord::Base
192-
end
193-
end
194-
195-
after(:all) do
196-
drop_table_with_trigger
197-
end
198-
199-
it "should populate primary key using trigger" do
200-
expect do
201-
@conn.execute "INSERT INTO test_employees (first_name) VALUES ('Raimonds')"
202-
end.not_to raise_error
203-
end
204-
205-
it "should return new key value using connection insert method" do
206-
insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, "id")
207-
expect(@conn.select_value("SELECT test_employees_seq.currval FROM dual")).to eq(insert_id)
208-
end
209-
210-
it "should create new record for model" do
211-
e = TestEmployee.create!(first_name: "Raimonds")
212-
expect(@conn.select_value("SELECT test_employees_seq.currval FROM dual")).to eq(e.id)
213-
end
214-
215-
it "should not generate NoMethodError for :returning_id:Symbol" do
216-
set_logger
217-
@conn.reconnect! unless @conn.active?
218-
@conn.insert("INSERT INTO test_employees (first_name) VALUES ('Yasuo')", nil, "id")
219-
expect(@logger.output(:error)).not_to match(/^Could not log "sql.active_record" event. NoMethodError: undefined method `name' for :returning_id:Symbol/)
220-
clear_logger
221-
end
222-
223-
end
224-
225-
describe "with separate creation of primary key trigger" do
226-
before(:all) do
227-
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
228-
@conn = ActiveRecord::Base.connection
229-
create_table_and_separately_trigger
230-
class ::TestEmployee < ActiveRecord::Base
231-
end
232-
end
233-
234-
after(:all) do
235-
drop_table_with_trigger
236-
end
237-
238-
it "should populate primary key using trigger" do
239-
expect do
240-
@conn.execute "INSERT INTO test_employees (first_name) VALUES ('Raimonds')"
241-
end.not_to raise_error
242-
end
243-
244-
it "should return new key value using connection insert method" do
245-
insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, "id")
246-
expect(@conn.select_value("SELECT test_employees_seq.currval FROM dual")).to eq(insert_id)
247-
end
248-
249-
it "should create new record for model" do
250-
e = TestEmployee.create!(first_name: "Raimonds")
251-
expect(@conn.select_value("SELECT test_employees_seq.currval FROM dual")).to eq(e.id)
252-
end
253-
end
254-
255-
describe "with non-default primary key and non-default sequence name" do
256-
before(:all) do
257-
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
258-
@conn = ActiveRecord::Base.connection
259-
@primary_key = "employee_id"
260-
@sequence_name = "test_employees_s"
261-
create_table_with_trigger(primary_key: @primary_key, sequence_name: @sequence_name)
262-
class ::TestEmployee < ActiveRecord::Base
263-
self.primary_key = "employee_id"
264-
end
265-
end
266-
267-
after(:all) do
268-
drop_table_with_trigger(sequence_name: @sequence_name)
269-
end
270-
271-
it "should populate primary key using trigger" do
272-
expect do
273-
@conn.execute "INSERT INTO test_employees (first_name) VALUES ('Raimonds')"
274-
end.not_to raise_error
275-
end
276-
277-
it "should return new key value using connection insert method" do
278-
insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, @primary_key)
279-
expect(@conn.select_value("SELECT #{@sequence_name}.currval FROM dual")).to eq(insert_id)
280-
end
281-
282-
it "should create new record for model with autogenerated sequence option" do
283-
e = TestEmployee.create!(first_name: "Raimonds")
284-
expect(@conn.select_value("SELECT #{@sequence_name}.currval FROM dual")).to eq(e.id)
285-
end
286-
end
287-
288-
describe "with non-default sequence name and non-default trigger name" do
289-
before(:all) do
290-
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
291-
@conn = ActiveRecord::Base.connection
292-
@sequence_name = "test_employees_s"
293-
create_table_with_trigger(sequence_name: @sequence_name, trigger_name: "test_employees_t1")
294-
class ::TestEmployee < ActiveRecord::Base
295-
self.sequence_name = :autogenerated
296-
end
297-
end
298-
299-
after(:all) do
300-
drop_table_with_trigger(sequence_name: @sequence_name)
301-
end
302-
303-
it "should populate primary key using trigger" do
304-
expect do
305-
@conn.execute "INSERT INTO test_employees (first_name) VALUES ('Raimonds')"
306-
end.not_to raise_error
307-
end
308-
309-
it "should return new key value using connection insert method" do
310-
insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, "id")
311-
expect(@conn.select_value("SELECT #{@sequence_name}.currval FROM dual")).to eq(insert_id)
312-
end
313-
314-
it "should create new record for model with autogenerated sequence option" do
315-
e = TestEmployee.create!(first_name: "Raimonds")
316-
expect(@conn.select_value("SELECT #{@sequence_name}.currval FROM dual")).to eq(e.id)
317-
end
318-
end
319-
320-
end
321-
322156
describe "table and column comments" do
323157

324158
def create_test_employees_table(table_comment = nil, column_comments = {})
@@ -474,44 +308,6 @@ class ::TestEmployee < ActiveRecord::Base; end
474308

475309
end
476310

477-
describe "create triggers" do
478-
479-
before(:all) do
480-
@conn = ActiveRecord::Base.connection
481-
schema_define do
482-
create_table :test_employees do |t|
483-
t.string :first_name
484-
t.string :last_name
485-
end
486-
end
487-
class ::TestEmployee < ActiveRecord::Base; end
488-
end
489-
490-
after(:all) do
491-
schema_define do
492-
drop_table :test_employees
493-
end
494-
Object.send(:remove_const, "TestEmployee")
495-
ActiveRecord::Base.clear_cache!
496-
end
497-
498-
it "should create table trigger with :new reference" do
499-
expect do
500-
@conn.execute <<-SQL
501-
CREATE OR REPLACE TRIGGER test_employees_pkt
502-
BEFORE INSERT ON test_employees FOR EACH ROW
503-
BEGIN
504-
IF inserting THEN
505-
IF :new.id IS NULL THEN
506-
SELECT test_employees_seq.NEXTVAL INTO :new.id FROM dual;
507-
END IF;
508-
END IF;
509-
END;
510-
SQL
511-
end.not_to raise_error
512-
end
513-
end
514-
515311
describe "add index" do
516312
before(:all) do
517313
@conn = ActiveRecord::Base.connection

0 commit comments

Comments
 (0)