Skip to content

Commit

Permalink
Add view namespaces to SchemaDumper
Browse files Browse the repository at this point in the history
Add non-public namespaces to view names when dumping to db/schema.rb.
This is useful when views live in another schema than `public`. Before
this change the dumper would dump `thoughtbot.scenic` as `scenic`. In
our case this would collide with our `scenic` view that's living in the
`public` namespace.
  • Loading branch information
Willianvdv authored and calebhearth committed May 27, 2016
1 parent 2dd948d commit 621cba4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 3 deletions.
13 changes: 11 additions & 2 deletions lib/scenic/adapters/postgres/views.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ def views_from_postgres
SELECT
c.relname as viewname,
pg_get_viewdef(c.oid) AS definition,
c.relkind AS kind
c.relkind AS kind,
n.nspname AS namespace
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE
Expand All @@ -39,8 +40,16 @@ def views_from_postgres
end

def to_scenic_view(result)
namespace, viewname = result.values_at "namespace", "viewname"

if namespace != "public"
namespaced_viewname = "#{namespace}.#{viewname}"
else
namespaced_viewname = viewname
end

Scenic::View.new(
name: result["viewname"],
name: namespaced_viewname,
definition: result["definition"].strip,
materialized: result["kind"] == "m",
)
Expand Down
4 changes: 3 additions & 1 deletion lib/scenic/view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ def ==(other)
# @api private
def to_schema
materialized_option = materialized ? "materialized: true, " : ""
safe_to_symbolize_name = name.include?(".") ? "'#{name}'" : name

<<-DEFINITION
create_view :#{name}, #{materialized_option} sql_definition: <<-\SQL
create_view :#{safe_to_symbolize_name}, #{materialized_option} sql_definition: <<-\SQL
#{definition.indent(2)}
SQL
Expand Down
21 changes: 21 additions & 0 deletions spec/scenic/adapters/postgres_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,27 @@ module Adapters
"people_with_names",
]
end

context "with views in non public schemas" do
it "returns also the non public views" do
adapter = Postgres.new

ActiveRecord::Base.connection.execute <<-SQL
CREATE VIEW parents AS SELECT text 'Joe' AS name
SQL

ActiveRecord::Base.connection.execute <<-SQL
CREATE SCHEMA scenic;
CREATE VIEW scenic.parents AS SELECT text 'Maarten' AS name;
SET search_path TO scenic, public;
SQL

expect(adapter.views.map(&:name)).to eq [
"parents",
"scenic.parents",
]
end
end
end
end
end
Expand Down
16 changes: 16 additions & 0 deletions spec/scenic/schema_dumper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,20 @@ class Search < ActiveRecord::Base; end

expect(Search.first.haystack).to eq "needle"
end

context "with views in non public schemas" do
it "dumps a create_view including namespace for a view in the database" do
view_definition = "SELECT 'needle'::text AS haystack"
Search.connection.execute "CREATE SCHEMA scenic; SET search_path TO scenic, public"
Search.connection.create_view :"scenic.searches", sql_definition: view_definition
stream = StringIO.new

ActiveRecord::SchemaDumper.dump(Search.connection, stream)

output = stream.string
expect(output).to include "create_view :'scenic.searches',"

Search.connection.drop_view :'scenic.searches'
end
end
end

0 comments on commit 621cba4

Please sign in to comment.