33 *
44 * Copyright (c) 2000-2008, PostgreSQL Global Development Group
55 *
6- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.172 2008/05/13 00:14:11 alvherre Exp $
6+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.173 2008/05/13 00:23:17 alvherre Exp $
77 */
88#include "postgres_fe.h"
99
@@ -24,6 +24,7 @@ static bool describeOneTableDetails(const char *schemaname,
2424bool verbose );
2525static void add_tablespace_footer (printTableContent * const cont ,char relkind ,
2626Oid tablespace ,const bool newline );
27+ static void add_role_attribute (PQExpBuffer buf ,const char * const str );
2728static bool listTSParsersVerbose (const char * pattern );
2829static bool describeOneTSParser (const char * oid ,const char * nspname ,
2930const char * prsname );
@@ -1560,34 +1561,31 @@ describeRoles(const char *pattern, bool verbose)
15601561{
15611562PQExpBufferData buf ;
15621563PGresult * res ;
1563- printQueryOpt myopt = pset .popt ;
1564- static const bool trans_columns []= {false, true, true, true, true, false, false};
1564+ printTableContent cont ;
1565+ printTableOpt myopt = pset .popt .topt ;
1566+ int ncols = 3 ;
1567+ int nrows = 0 ;
1568+ int i ;
1569+ int conns ;
1570+ const char align = 'l' ;
1571+ char * * attr ;
15651572
15661573initPQExpBuffer (& buf );
15671574
1568- printfPQExpBuffer (& buf ,
1569- "SELECT r.rolname AS \"%s\",\n"
1570- " CASE WHEN r.rolsuper THEN '%s' ELSE '%s' END AS \"%s\",\n"
1571- " CASE WHEN r.rolcreaterole THEN '%s' ELSE '%s' END AS \"%s\",\n"
1572- " CASE WHEN r.rolcreatedb THEN '%s' ELSE '%s' END AS \"%s\",\n"
1573- " CASE WHEN r.rolconnlimit < 0 THEN CAST('%s' AS pg_catalog.text)\n"
1574- " ELSE CAST(r.rolconnlimit AS pg_catalog.text)\n"
1575- " END AS \"%s\", \n"
1576- " ARRAY(SELECT b.rolname FROM pg_catalog.pg_auth_members m JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid) WHERE m.member = r.oid) as \"%s\"" ,
1577- gettext_noop ("Role name" ),
1578- gettext_noop ("yes" ),gettext_noop ("no" ),
1579- gettext_noop ("Superuser" ),
1580- gettext_noop ("yes" ),gettext_noop ("no" ),
1581- gettext_noop ("Create role" ),
1582- gettext_noop ("yes" ),gettext_noop ("no" ),
1583- gettext_noop ("Create DB" ),
1584- gettext_noop ("no limit" ),
1585- gettext_noop ("Connections" ),
1586- gettext_noop ("Member of" ));
1575+ appendPQExpBufferStr (& buf ,
1576+ "SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
1577+ " r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
1578+ " r.rolconnlimit,\n"
1579+ " ARRAY(SELECT b.rolname\n"
1580+ " FROM pg_catalog.pg_auth_members m\n"
1581+ " JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
1582+ " WHERE m.member = r.oid) as memberof" );
15871583
15881584if (verbose )
1589- appendPQExpBuffer (& buf ,"\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS \"%s\"" ,
1590- gettext_noop ("Description" ));
1585+ {
1586+ appendPQExpBufferStr (& buf ,"\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description" );
1587+ ncols ++ ;
1588+ }
15911589
15921590appendPQExpBuffer (& buf ,"\nFROM pg_catalog.pg_roles r\n" );
15931591
@@ -1597,21 +1595,86 @@ describeRoles(const char *pattern, bool verbose)
15971595appendPQExpBuffer (& buf ,"ORDER BY 1;" );
15981596
15991597res = PSQLexec (buf .data , false);
1600- termPQExpBuffer (& buf );
16011598if (!res )
16021599return false;
16031600
1604- myopt .nullPrint = NULL ;
1605- myopt .title = _ ("List of roles" );
1606- myopt .trans_headers = true;
1607- myopt .trans_columns = trans_columns ;
1601+ nrows = PQntuples (res );
1602+ attr = pg_malloc_zero ((nrows + 1 )* sizeof (* attr ));
16081603
1609- printQuery (res ,& myopt ,pset .queryFout ,pset .logfile );
1604+ printTableInit (& cont ,& myopt ,_ ("List of roles" ),ncols ,nrows );
1605+
1606+ printTableAddHeader (& cont ,gettext_noop ("Role name" ), true,align );
1607+ printTableAddHeader (& cont ,gettext_noop ("Attributes" ), true,align );
1608+ printTableAddHeader (& cont ,gettext_noop ("Member of" ), true,align );
1609+
1610+ if (verbose )
1611+ printTableAddHeader (& cont ,gettext_noop ("Description" ), true,align );
1612+
1613+ for (i = 0 ;i < nrows ;i ++ )
1614+ {
1615+ printTableAddCell (& cont ,PQgetvalue (res ,i ,0 ), false);
1616+
1617+ resetPQExpBuffer (& buf );
1618+ if (strcmp (PQgetvalue (res ,i ,1 ),"t" )== 0 )
1619+ add_role_attribute (& buf ,_ ("Superuser" ));
1620+
1621+ if (strcmp (PQgetvalue (res ,i ,2 ),"t" )!= 0 )
1622+ add_role_attribute (& buf ,_ ("No inheritance" ));
1623+
1624+ if (strcmp (PQgetvalue (res ,i ,3 ),"t" )== 0 )
1625+ add_role_attribute (& buf ,_ ("Create role" ));
1626+
1627+ if (strcmp (PQgetvalue (res ,i ,4 ),"t" )== 0 )
1628+ add_role_attribute (& buf ,_ ("Create DB" ));
1629+
1630+ if (strcmp (PQgetvalue (res ,i ,5 ),"t" )!= 0 )
1631+ add_role_attribute (& buf ,_ ("Cannot login" ));
1632+
1633+ conns = atoi (PQgetvalue (res ,i ,6 ));
1634+ if (conns >=0 )
1635+ {
1636+ if (buf .len > 0 )
1637+ appendPQExpBufferStr (& buf ,"\n" );
1638+
1639+ if (conns == 0 )
1640+ appendPQExpBuffer (& buf ,_ ("No connections" ));
1641+ else if (conns == 1 )
1642+ appendPQExpBuffer (& buf ,_ ("1 connection" ));
1643+ else
1644+ appendPQExpBuffer (& buf ,_ ("%d connections" ),conns );
1645+ }
1646+
1647+ attr [i ]= pg_strdup (buf .data );
1648+
1649+ printTableAddCell (& cont ,attr [i ], false);
1650+
1651+ printTableAddCell (& cont ,PQgetvalue (res ,i ,7 ), false);
1652+
1653+ if (verbose )
1654+ printTableAddCell (& cont ,PQgetvalue (res ,i ,8 ), false);
1655+ }
1656+ termPQExpBuffer (& buf );
1657+
1658+ printTable (& cont ,pset .queryFout ,pset .logfile );
1659+ printTableCleanup (& cont );
1660+
1661+ for (i = 0 ;i < nrows ;i ++ )
1662+ free (attr [i ]);
1663+ free (attr );
16101664
16111665PQclear (res );
16121666return true;
16131667}
16141668
1669+ void
1670+ add_role_attribute (PQExpBuffer buf ,const char * const str )
1671+ {
1672+ if (buf -> len > 0 )
1673+ appendPQExpBufferStr (buf ,"\n" );
1674+
1675+ appendPQExpBufferStr (buf ,str );
1676+ }
1677+
16151678
16161679/*
16171680 * listTables()