Skip to content

Commit a77ebcd

Browse files
authored
ensure multi-schema dumping in Rails 8.1.0 doesn't dump the same objects for all schemas (#177)
In Rails 8.1.0, `bin/rails db:schema:dump` now knows how to dump multiple schemas (rails/rails#50020). To ensure we don't dump the same functions / triggers for each schema, we need to stop memoizing `Fx.database.{functions,triggers}`. This should be fully backwards compatible to previous Rails versions, as we still only call each of those methods once per schema dumping invocation, it just now works if schema dumping is invoked multiple times.
1 parent 84b286d commit a77ebcd

File tree

2 files changed

+60
-14
lines changed

2 files changed

+60
-14
lines changed

lib/fx/schema_dumper.rb

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,32 @@ module SchemaDumper
44
def tables(stream)
55
if Fx.configuration.dump_functions_at_beginning_of_schema
66
functions(stream)
7-
empty_line(stream)
87
end
98

109
super
1110

1211
unless Fx.configuration.dump_functions_at_beginning_of_schema
1312
functions(stream)
14-
empty_line(stream)
1513
end
1614

1715
triggers(stream)
1816
end
1917

2018
private
2119

22-
def empty_line(stream)
23-
stream.puts if dumpable_functions_in_database.any?
24-
end
25-
2620
def functions(stream)
21+
dumpable_functions_in_database = Fx.database.functions
22+
2723
dumpable_functions_in_database.each do |function|
2824
stream.puts(function.to_schema)
2925
end
26+
27+
stream.puts if dumpable_functions_in_database.any?
3028
end
3129

3230
def triggers(stream)
31+
dumpable_triggers_in_database = Fx.database.triggers
32+
3333
if dumpable_triggers_in_database.any?
3434
stream.puts
3535
end
@@ -38,13 +38,5 @@ def triggers(stream)
3838
stream.puts(trigger.to_schema)
3939
end
4040
end
41-
42-
def dumpable_functions_in_database
43-
@_dumpable_functions_in_database ||= Fx.database.functions
44-
end
45-
46-
def dumpable_triggers_in_database
47-
@_dumpable_triggers_in_database ||= Fx.database.triggers
48-
end
4941
end
5042
end

spec/fx/schema_dumper_spec.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,60 @@
113113
expect(output).to include("EXECUTE FUNCTION uppercase_users_name()")
114114
end
115115

116+
context "when there are functions / triggers in multiple schemas" do
117+
before { connection.schema_search_path = "public,test_schema" }
118+
119+
after { connection.schema_search_path = "public" }
120+
121+
it "dumps functions and triggers for multiple schemas" do
122+
connection.create_table :my_table
123+
124+
connection.create_function :test1, sql_definition: <<~EOS
125+
CREATE OR REPLACE FUNCTION test_public_func()
126+
RETURNS TRIGGER AS $$
127+
BEGIN
128+
RETURN 1;
129+
END;
130+
$$ LANGUAGE plpgsql;
131+
EOS
132+
connection.create_trigger :test1_trigger, sql_definition: <<~EOS
133+
CREATE TRIGGER test_public_trigger
134+
BEFORE INSERT ON my_table
135+
FOR EACH ROW
136+
EXECUTE FUNCTION test_public_func();
137+
EOS
138+
139+
connection.execute("CREATE SCHEMA test_schema;")
140+
141+
connection.create_table "test_schema.my_table2"
142+
143+
connection.execute <<~EOS
144+
CREATE OR REPLACE FUNCTION test_schema.test_schema_func()
145+
RETURNS TRIGGER AS $$
146+
BEGIN
147+
RETURN 'test_schema';
148+
END;
149+
$$ LANGUAGE plpgsql;
150+
EOS
151+
connection.execute <<~EOS
152+
CREATE TRIGGER test_schema_trigger
153+
BEFORE INSERT ON test_schema.my_table2
154+
FOR EACH ROW
155+
EXECUTE FUNCTION test_schema.test_schema_func();
156+
EOS
157+
158+
stream = StringIO.new
159+
dump(connection: connection, stream: stream)
160+
output = stream.string
161+
162+
expect(output.scan("create_function :test_public_func").size).to eq(1)
163+
expect(output.scan("create_trigger :test_public_trigger").size).to eq(1)
164+
165+
expect(output.scan("create_function :test_schema_func").size).to eq(1)
166+
expect(output.scan("create_trigger :test_schema_trigger").size).to eq(1)
167+
end
168+
end
169+
116170
def dump(connection:, stream:)
117171
if Rails.version >= "7.2"
118172
ActiveRecord::SchemaDumper.dump(connection.pool, stream)

0 commit comments

Comments
 (0)