A new feature patch and a bug fix - Mailing list pgadmin-hackers

From Guillaume Lelarge
Subject A new feature patch and a bug fix
Date
Msg-id 47669958.8080902@lelarge.info
Whole thread Raw
Responses Re: A new feature patch and a bug fix  (Dave Page <dpage@postgresql.org>)
List pgadmin-hackers
Hi,

Let's begin with the bug fix. I've found that I can set the owner of an
object only from login role. pgAdmin doesn't allow me to set ownership
to a group. psql allows it, so I think this is a bug. The patch named
"dlgProperty.patch" fixes this issue.

I found this when I tried to add "reassign owned by" and "drop owned by"
functionalities to pgAdmin. I first thought I would add this with the
drop-user code but I prefer to make it available alone. So I used my
well known way : a new contextual menu (in fact two : "Reassign Owned
To..." and "Drop Owned"). The first one opens a wxSingleChoiceDialog
dialog for the user to choose a role from. The second one waits for a
confirmation and then fires the SQL statement. My problem is here : on a
user contextual menu, the only connection I can get is the maintenance
connection. So I will only be able to reassign or drop objects within
the maintenance database. I was wondering if there was a way to get a
handle to the last open connection ? or if there was another way ? for
example asking the user to choose the database to connect to and fire
the SQL statement ? or asking the user to select a database where he's
already connected to ?

Thanks.

Regards.


--
Guillaume.
 http://www.postgresqlfr.org
 http://dalibo.com
Index: pgadmin/dlg/dlgProperty.cpp
===================================================================
--- pgadmin/dlg/dlgProperty.cpp    (révision 6910)
+++ pgadmin/dlg/dlgProperty.cpp    (copie de travail)
@@ -432,7 +432,14 @@

 void dlgProperty::AddUsers(ctlComboBoxFix *cb1, ctlComboBoxFix *cb2)
 {
-    FillCombobox(wxT("SELECT usename FROM pg_user ORDER BY usename"), cb1, cb2);
+    if (connection->BackendMinimumVersion(8, 2))
+    {
+        FillCombobox(wxT("SELECT rolname FROM pg_roles ORDER BY 1"), cb1, cb2);
+    }
+    else
+    {
+        FillCombobox(wxT("SELECT usename FROM pg_user UNION SELECT groname FROM pg_group ORDER BY 1"), cb1, cb2);
+    }
 }


Index: pgadmin/include/schema/pgRole.h
===================================================================
--- pgadmin/include/schema/pgRole.h    (révision 6910)
+++ pgadmin/include/schema/pgRole.h    (copie de travail)
@@ -75,8 +75,10 @@
     void iSetUpdateCatalog(const bool b) { updateCatalog=b; }
     wxArrayString& GetRolesIn() { return rolesIn; }
     wxArrayString& GetConfigList() { return configList; }
+
+    void ReassignOwnedTo();
+    void DropOwned();

-
     // Tree object creation
     void ShowTreeDetail(ctlTree *browser, frmMain *form=0, ctlListView *properties=0, ctlSQLBox *sqlPane=0);
     void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where);
@@ -89,6 +91,7 @@
     bool HasStats() { return false; }
     bool HasDepends() { return true; }
     bool HasReferences() { return true; }
+
 private:
     wxString password;
     wxDateTime accountExpires;
@@ -112,6 +115,21 @@
     pgGroupRole(const wxString& newName = wxT(""));
 };

+class reassignOwnedFactory : public contextActionFactory
+{
+public:
+    reassignOwnedFactory(menuFactoryList *list, wxMenu *mnu, wxToolBar *toolbar);
+    wxWindow *StartDialog(frmMain *form, pgObject *obj);
+    bool CheckEnable(pgObject *obj);
+};

+class dropOwnedFactory : public contextActionFactory
+{
+public:
+    dropOwnedFactory(menuFactoryList *list, wxMenu *mnu, wxToolBar *toolbar);
+    wxWindow *StartDialog(frmMain *form, pgObject *obj);
+    bool CheckEnable(pgObject *obj);
+};

+
 #endif
Index: pgadmin/frm/frmMain.cpp
===================================================================
--- pgadmin/frm/frmMain.cpp    (révision 6910)
+++ pgadmin/frm/frmMain.cpp    (copie de travail)
@@ -67,6 +67,7 @@
 #include "schema/pgTable.h"
 #include "schema/pgIndex.h"
 #include "schema/pgTrigger.h"
+#include "schema/pgRole.h"
 #include "schema/pgRule.h"
 #include "schema/pgServer.h"
 #include "slony/slCluster.h"
@@ -326,6 +327,8 @@
     new dropCascadedFactory(menuFactories, editMenu, 0);
     new truncateFactory(menuFactories, editMenu, 0);
     new truncateCascadedFactory(menuFactories, editMenu, 0);
+    new reassignOwnedFactory(menuFactories, editMenu, 0);
+    new dropOwnedFactory(menuFactories, editMenu, 0);
     editMenu->AppendSeparator();

     new separatorFactory(menuFactories);
Index: pgadmin/schema/pgRole.cpp
===================================================================
--- pgadmin/schema/pgRole.cpp    (révision 6910)
+++ pgadmin/schema/pgRole.cpp    (copie de travail)
@@ -11,6 +11,7 @@

 // wxWindows headers
 #include <wx/wx.h>
+#include <wx/choicdlg.h>

 // App headers
 #include "pgAdmin3.h"
@@ -51,7 +52,7 @@

 bool pgRole::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
 {
-    if (GetUpdateCatalog())
+    if (GetUpdateCatalog())
     {
         wxMessageDialog dlg(frame,
             _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you
sure?"),
@@ -277,7 +278,38 @@
 }


+void pgRole::ReassignOwnedTo()
+{
+    wxArrayString rolesList;
+    wxString rolesquery;
+
+    rolesquery = wxT("SELECT rolname FROM pg_roles ORDER BY rolname");
+    pgSetIterator roles(GetConnection(), rolesquery);
+    while (roles.RowsLeft())
+    {
+        rolesList.Add(roles.GetVal(wxT("rolname")));
+    }
+
+    wxSingleChoiceDialog dialog(0,
+      wxT("Choose the user that will own all objects owned by the selected role."),
+      wxT("Please select a role"),
+      rolesList);
+
+    if (dialog.ShowModal() == wxID_OK)
+    {
+        rolesquery = wxT("REASSIGN OWNED BY ") + GetQuotedFullIdentifier() + wxT(" TO ") +
dialog.GetStringSelection();
+        GetConnection()->ExecuteVoid(rolesquery);
+    }
+}

+
+void pgRole::DropOwned()
+{
+    wxString query = wxT("DROP OWNED BY ") + GetQuotedFullIdentifier();
+    GetConnection()->ExecuteVoid(query);
+}
+
+
 pgObject *pgRole::Refresh(ctlTree *browser, const wxTreeItemId item)
 {
     pgObject *role=0;
@@ -394,3 +426,43 @@

 pgGroupRoleFactory groupRoleFactory;
 static pgaCollectionFactory gcf(&groupRoleFactory, __("Group Roles"), roles_xpm);
+
+
+reassignOwnedFactory::reassignOwnedFactory(menuFactoryList *list, wxMenu *mnu, wxToolBar *toolbar) :
contextActionFactory(list)
+{
+    mnu->Append(id, _("Reassign Owned To..."), _("Reassigned objects owned by this role to another one."));
+}
+
+
+wxWindow *reassignOwnedFactory::StartDialog(frmMain *form, pgObject *obj)
+{
+    ((pgRole*)obj)->ReassignOwnedTo();
+
+    return 0;
+}
+
+bool reassignOwnedFactory::CheckEnable(pgObject *obj)
+{
+    return obj && obj->IsCreatedBy(loginRoleFactory) && ((pgRole*)obj)->GetConnection()->BackendMinimumVersion(8, 2);
+}
+
+
+dropOwnedFactory::dropOwnedFactory(menuFactoryList *list, wxMenu *mnu, wxToolBar *toolbar) :
contextActionFactory(list)
+{
+    mnu->Append(id, _("Drop Owned"), _("Drop objects owned by the selected role."));
+}
+
+wxWindow *dropOwnedFactory::StartDialog(frmMain *form, pgObject *obj)
+{
+    if (wxMessageBox(_("Are you sure you wish to drop all objets owned by the selected role?"), _("Drop objects"),
wxYES_NO)== wxNO) 
+        return 0;
+
+    ((pgRole*)obj)->DropOwned();
+
+    return 0;
+}
+
+bool dropOwnedFactory::CheckEnable(pgObject *obj)
+{
+    return obj && obj->IsCreatedBy(loginRoleFactory) && ((pgRole*)obj)->GetConnection()->BackendMinimumVersion(8, 2);
+}

pgadmin-hackers by date:

Previous
From: svn@pgadmin.org
Date:
Subject: SVN Commit by dpage: r6910 - in trunk/pgadmin3: . pgadmin/dlg pgadmin/schema
Next
From: Dave Page
Date:
Subject: Re: A new feature patch and a bug fix