end
def users
- @users ||= query("SELECT * FROM pg_user").each_with_object({}) do |user, users|
+ @users ||= query("SELECT *, ARRAY(SELECT groname FROM pg_group WHERE usesysid = ANY(grolist)) AS roles FROM pg_user").each_with_object({}) do |user, users|
users[user[:usename]] = {
:superuser => user[:usesuper] == "t",
:createdb => user[:usercreatedb] == "t",
:createrole => user[:usecatupd] == "t",
- :replication => user[:userepl] == "t"
+ :replication => user[:userepl] == "t",
+ :roles => parse_array(user[:roles] || "{}")
}
end
end
def tables(database)
@tables ||= {}
- @tables[database] ||= query("SELECT n.nspname, c.relname, u.usename, c.relacl FROM pg_class AS c INNER JOIN pg_user AS u ON c.relowner = u.usesysid INNER JOIN pg_namespace AS n ON c.relnamespace = n.oid WHERE c.relkind = 'r'", :database => database).each_with_object({}) do |table, tables|
+ @tables[database] ||= query("SELECT n.nspname, c.relname, u.usename, c.relacl FROM pg_class AS c INNER JOIN pg_user AS u ON c.relowner = u.usesysid INNER JOIN pg_namespace AS n ON c.relnamespace = n.oid WHERE n.nspname NOT IN ('pg_catalog', 'information_schema') AND c.relkind = 'r'", :database => database).each_with_object({}) do |table, tables|
name = "#{table[:nspname]}.#{table[:relname]}"
tables[name] = {
def sequences(database)
@sequences ||= {}
- @sequences[database] ||= query("SELECT n.nspname, c.relname, u.usename, c.relacl FROM pg_class AS c INNER JOIN pg_user AS u ON c.relowner = u.usesysid INNER JOIN pg_namespace AS n ON c.relnamespace = n.oid WHERE c.relkind = 'S'", :database => database).each_with_object({}) do |sequence, sequences|
+ @sequences[database] ||= query("SELECT n.nspname, c.relname, u.usename, c.relacl FROM pg_class AS c INNER JOIN pg_user AS u ON c.relowner = u.usesysid INNER JOIN pg_namespace AS n ON c.relnamespace = n.oid WHERE n.nspname NOT IN ('pg_catalog', 'information_schema') AND c.relkind = 'S'", :database => database).each_with_object({}) do |sequence, sequences|
name = "#{sequence[:nspname]}.#{sequence[:relname]}"
sequences[name] = {
private
+ def parse_array(array)
+ array.sub(/^\{(.*)\}$/, "\\1").split(",")
+ end
+
def parse_acl(acl)
- acl.sub(/^\{(.*)\}$/, "\\1").split(",").each_with_object({}) do |entry, permissions|
+ parse_array(acl).each_with_object({}) do |entry, permissions|
entry = entry.sub(/^"(.*)"$/) { Regexp.last_match[1].gsub(/\\"/, '"') }.sub(%r{/.*$}, "")
user, privileges = entry.split("=")