Skip to content

Schema-dump all user-created functions, not just 'public' #140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion lib/fx/adapters/postgres/functions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@ class Functions
ON pd.objid = pp.oid AND pd.deptype = 'e'
LEFT JOIN pg_aggregate pa
ON pa.aggfnoid = pp.oid
WHERE pn.nspname = 'public' AND pd.objid IS NULL
WHERE pn.nspname
IN (
SELECT replace(
unnest(string_to_array(setting, ', ')),
'"$user"',
current_user
)
FROM pg_settings
WHERE name = 'search_path'
)
AND pd.objid IS NULL
AND pa.aggfnoid IS NULL
ORDER BY pp.oid;
EOS
Expand Down
88 changes: 88 additions & 0 deletions spec/fx/adapters/postgres/functions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,93 @@
$function$
EOS
end

context "when functions are in a different schema" do
it "does not return the `Function` objects" do
connection = ActiveRecord::Base.connection
connection.execute <<-EOS.strip_heredoc
CREATE SCHEMA test_schema;
CREATE OR REPLACE FUNCTION test_schema.test()
RETURNS text AS $$
BEGIN
RETURN 'test';
END;
$$ LANGUAGE plpgsql;
EOS

functions = Fx::Adapters::Postgres::Functions.new(connection).all

expect(functions).to be_empty
end

context "when the other schema is in the search path" do
it "returns the `Function` objects" do
connection = ActiveRecord::Base.connection
connection.execute <<-EOS.strip_heredoc
CREATE SCHEMA test_schema;
SET search_path TO public,test_schema;
CREATE OR REPLACE FUNCTION test_schema.test()
RETURNS text AS $$
BEGIN
RETURN 'test';
END;
$$ LANGUAGE plpgsql;
EOS

functions = Fx::Adapters::Postgres::Functions.new(connection).all

first = functions.first
expect(functions.size).to eq 1
expect(first.name).to eq "test"
expect(first.definition).to eq <<-EOS.strip_heredoc
CREATE OR REPLACE FUNCTION test_schema.test()
RETURNS text
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN 'test';
END;
$function$
EOS
ensure
ActiveRecord::Base.connection.execute 'SET search_path TO "$user", public'
end
end

context 'when the other schema is the "$user" (dynamic) schema' do
it "returns the `Function` objects" do
connection = ActiveRecord::Base.connection
current_user = connection.execute("SELECT current_user").first["current_user"]
connection.execute <<-EOS.strip_heredoc
CREATE SCHEMA #{current_user};
SET search_path TO "$user",public;
CREATE OR REPLACE FUNCTION #{current_user}.test()
RETURNS text AS $$
BEGIN
RETURN 'test';
END;
$$ LANGUAGE plpgsql;
EOS

functions = Fx::Adapters::Postgres::Functions.new(connection).all

first = functions.first
expect(functions.size).to eq 1
expect(first.name).to eq "test"
expect(first.definition).to eq <<-EOS.strip_heredoc
CREATE OR REPLACE FUNCTION #{current_user}.test()
RETURNS text
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN 'test';
END;
$function$
EOS
ensure
ActiveRecord::Base.connection.execute 'SET search_path TO "$user", public'
end
end
end
end
end