diff --git a/lib/scenic/adapters/postgres/views.rb b/lib/scenic/adapters/postgres/views.rb index 53736306..036f0f2f 100644 --- a/lib/scenic/adapters/postgres/views.rb +++ b/lib/scenic/adapters/postgres/views.rb @@ -16,15 +16,18 @@ def initialize(connection) # # @return [Array] def all - sort(views_from_postgres).map(&method(:to_scenic_view)) + scenic_views = views_from_postgres.map(&method(:to_scenic_view)) + sort(scenic_views) end private - def sort(existing_views) - tsorted_views(existing_views.map(&:name)).map do |view_name| - existing_views.find do |ev| - ev.name == view_name || ev.name == view_name.split(".").last + def sort(scenic_views) + scenic_view_names = scenic_views.map(&:name) + + tsorted_views(scenic_view_names).map do |view_name| + scenic_views.find do |sv| + sv.name == view_name || sv.name == view_name.split(".").last end end.compact end @@ -39,13 +42,16 @@ def tsorted_views(views_names) relation["source_schema"], relation["source_table"] ].compact.join(".") + dependent = [ relation["dependent_schema"], relation["dependent_view"] ].compact.join(".") + views_hash[dependent] ||= [] views_hash[source_v] ||= [] views_hash[dependent] << source_v + views_names.delete(relation["source_table"]) views_names.delete(relation["dependent_view"]) end @@ -53,7 +59,6 @@ def tsorted_views(views_names) # after dependencies, there might be some views left # that don't have any dependencies views_names.sort.each { |v| views_hash[v] ||= [] } - views_hash.tsort end @@ -107,19 +112,21 @@ def views_from_postgres end def to_scenic_view(result) - namespace, viewname = result.values_at "namespace", "viewname" + Scenic::View.new( + name: namespaced_view_name(result), + definition: result["definition"].strip, + materialized: result["kind"] == "m" + ) + end + + def namespaced_view_name(result) + namespace, viewname = result.values_at("namespace", "viewname") - namespaced_viewname = if namespace != "public" + if namespace != "public" "#{pg_identifier(namespace)}.#{pg_identifier(viewname)}" else pg_identifier(viewname) end - - Scenic::View.new( - name: namespaced_viewname, - definition: result["definition"].strip, - materialized: result["kind"] == "m" - ) end def pg_identifier(name) diff --git a/spec/scenic/adapters/postgres_spec.rb b/spec/scenic/adapters/postgres_spec.rb index 66819aa7..9ef4da0a 100644 --- a/spec/scenic/adapters/postgres_spec.rb +++ b/spec/scenic/adapters/postgres_spec.rb @@ -176,8 +176,8 @@ module Adapters SQL expect(adapter.views.map(&:name)).to eq [ - "parents", "children", + "parents", "people", "people_with_names" ] @@ -193,13 +193,13 @@ module Adapters ActiveRecord::Base.connection.execute <<-SQL CREATE SCHEMA scenic; - CREATE VIEW scenic.parents AS SELECT text 'Maarten' AS name; + CREATE VIEW scenic.more_parents AS SELECT text 'Maarten' AS name; SET search_path TO scenic, public; SQL expect(adapter.views.map(&:name)).to eq [ "parents", - "scenic.parents" + "scenic.more_parents" ] end end