-//////////////////////////////////////////////////////////////////////////\r
-//\r
-// pgAdmin III - PostgreSQL Tools\r
-// RCS-ID: $Id$\r
-// Copyright (C) 2002 - 2008, The pgAdmin Development Team\r
-// This software is released under the Artistic Licence\r
-//\r
-// dlgRole.cpp - PostgreSQL Role Property\r
-//\r
-//////////////////////////////////////////////////////////////////////////\r
-\r
-#include "pgAdmin3.h"\r
-\r
-// wxWindows headers\r
-#include <wx/wx.h>\r
-\r
-// App headers\r
-#include "utils/misc.h"\r
-#include "dlg/dlgRole.h"\r
-#include "schema/pgRole.h"\r
-\r
-\r
-// pointer to controls\r
-#define txtPasswd CTRL_TEXT("txtPasswd")\r
-#define txtRePasswd CTRL_TEXT("txtRePasswd")\r
-#define datValidUntil CTRL_CALENDAR("datValidUntil")\r
-#define timValidUntil CTRL_TIME("timValidUntil")\r
-#define chkCanLogin CTRL_CHECKBOX("chkCanLogin")\r
-#define chkSuperuser CTRL_CHECKBOX("chkSuperuser")\r
-#define chkInherits CTRL_CHECKBOX("chkInherits")\r
-#define chkCreateDB CTRL_CHECKBOX("chkCreateDB")\r
-#define chkCreateRole CTRL_CHECKBOX("chkCreateRole")\r
-#define chkUpdateCat CTRL_CHECKBOX("chkUpdateCat")\r
-\r
-#define lbRolesNotIn CTRL_LISTBOX("lbRolesNotIn")\r
-#define lbRolesIn CTRL_LISTBOX("lbRolesIn")\r
-#define btnAddRole CTRL_BUTTON("btnAddRole")\r
-#define btnDelRole CTRL_BUTTON("btnDelRole")\r
-#define chkAdminOption CTRL_CHECKBOX("chkAdminOption")\r
-\r
-#define lstVariables CTRL_LISTVIEW("lstVariables")\r
-#define btnAdd CTRL_BUTTON("wxID_ADD")\r
-#define btnRemove CTRL_BUTTON("wxID_REMOVE")\r
-#define cbVarname CTRL_COMBOBOX2("cbVarname")\r
-#define txtValue CTRL_TEXT("txtValue")\r
-#define chkValue CTRL_CHECKBOX("chkValue")\r
-\r
-\r
-\r
-dlgProperty *pgLoginRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)\r
-{\r
- return new dlgRole(this, frame, (pgRole*)node, true);\r
-}\r
-\r
-dlgProperty *pgGroupRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)\r
-{\r
- return new dlgRole(this, frame, (pgRole*)node, false);\r
-}\r
-\r
-BEGIN_EVENT_TABLE(dlgRole, dlgProperty)\r
- EVT_CALENDAR_SEL_CHANGED(XRCID("datValidUntil"),dlgRole::OnChangeCal)\r
- EVT_DATE_CHANGED(XRCID("datValidUntil"), dlgRole::OnChangeDate)\r
- EVT_SPIN(XRCID("timValidUntil"), dlgRole::OnChangeSpin)\r
- \r
- EVT_LISTBOX_DCLICK(XRCID("lbRolesNotIn"), dlgRole::OnRoleAdd)\r
- EVT_LISTBOX_DCLICK(XRCID("lbRolesIn"), dlgRole::OnRoleRemove)\r
- EVT_TEXT(XRCID("txtPasswd"), dlgRole::OnChangePasswd)\r
- EVT_TEXT(XRCID("txtRePasswd"), dlgRole::OnChangePasswd)\r
- EVT_CHECKBOX(XRCID("chkCanLogin"), dlgRole::OnChange)\r
- EVT_CHECKBOX(XRCID("chkInherits"), dlgRole::OnChange)\r
- EVT_CHECKBOX(XRCID("chkCreateDB"), dlgRole::OnChange)\r
- EVT_CHECKBOX(XRCID("chkUpdateCat"), dlgRole::OnChange)\r
- EVT_CHECKBOX(XRCID("chkSuperuser"), dlgRole::OnChangeSuperuser)\r
- EVT_CHECKBOX(XRCID("chkCreateRole"), dlgRole::OnChange)\r
-\r
- EVT_BUTTON(XRCID("btnAddRole"), dlgRole::OnRoleAdd)\r
- EVT_BUTTON(XRCID("btnDelRole"), dlgRole::OnRoleRemove)\r
-\r
- EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgRole::OnVarSelChange)\r
- EVT_BUTTON(wxID_ADD, dlgRole::OnVarAdd)\r
- EVT_BUTTON(wxID_REMOVE, dlgRole::OnVarRemove)\r
- EVT_TEXT(XRCID("cbVarname"), dlgRole::OnVarnameSelChange)\r
- EVT_COMBOBOX(XRCID("cbVarname"), dlgRole::OnVarnameSelChange)\r
-\r
- EVT_BUTTON(wxID_OK, dlgRole::OnOK)\r
-END_EVENT_TABLE();\r
-\r
-\r
-\r
-dlgRole::dlgRole(pgaFactory *f, frmMain *frame, pgRole *node, bool chkLogin)\r
-: dlgProperty(f, frame, wxT("dlgRole"))\r
-{\r
- role=node;\r
- lstVariables->CreateColumns(0, _("Variable"), _("Value"), -1);\r
- btnOK->Disable();\r
- chkValue->Hide();\r
- if (chkLogin)\r
- chkCanLogin->SetValue(true);\r
-}\r
-\r
-\r
-pgObject *dlgRole::GetObject()\r
-{\r
- return role;\r
-}\r
-\r
-\r
-int dlgRole::Go(bool modal)\r
-{\r
- wxString roleSql=\r
- wxT("SELECT rolname\n")\r
- wxT(" FROM pg_roles r\n");\r
-\r
- varInfo.Add(wxT("role"));\r
- cbVarname->Append(wxT("role"));\r
-\r
- pgSet *set;\r
- set=connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n")\r
- wxT(" FROM pg_settings WHERE context in ('user', 'superuser')"));\r
-\r
- if (set)\r
- {\r
- while (!set->Eof())\r
- {\r
- cbVarname->Append(set->GetVal(0));\r
- varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + \r
- set->GetVal(wxT("min_val")) + wxT(" ") +\r
- set->GetVal(wxT("max_val")));\r
- set->MoveNext();\r
- }\r
- delete set;\r
-\r
- cbVarname->SetSelection(0);\r
- }\r
-\r
- if (role)\r
- {\r
- wxArrayString roles=role->GetRolesIn();\r
- size_t i;\r
- for (i=0 ; i < roles.GetCount() ; i++)\r
- lbRolesIn->Append(roles.Item(i));\r
-\r
- roleSql += \r
- wxT(" LEFT JOIN pg_auth_members ON r.oid=roleid AND member = ") + role->GetOidStr() + wxT("\n")\r
- wxT(" WHERE r.oid <> ") + role->GetOidStr() + wxT("\n")\r
- wxT(" AND roleid IS NULL");\r
-\r
- // Edit Mode\r
- if (role->GetServer()->GetSuperUser() || role->GetServer()->GetCreateRole()) \r
- readOnly=false;\r
- else\r
- readOnly=true;\r
-\r
- chkCreateDB->SetValue(role->GetCreateDatabase());\r
- chkCreateRole->SetValue(role->GetCreateRole());\r
- chkSuperuser->SetValue(role->GetSuperuser());\r
- chkInherits->SetValue(role->GetInherits());\r
- chkUpdateCat->SetValue(role->GetUpdateCatalog());\r
- chkCanLogin->SetValue(role->GetCanLogin());\r
- datValidUntil->SetValue(role->GetAccountExpires());\r
- timValidUntil->SetTime(role->GetAccountExpires());\r
- txtComment->SetValue(role->GetComment());\r
-\r
- size_t index;\r
- for (index = 0 ; index < role->GetConfigList().GetCount() ; index++)\r
- {\r
- wxString item=role->GetConfigList().Item(index);\r
- lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('='));\r
- }\r
-\r
- timValidUntil->Enable(!readOnly && role->GetAccountExpires().IsValid());\r
-\r
- if (readOnly)\r
- {\r
- chkCanLogin->Disable();\r
- chkCreateDB->Disable();\r
- chkCreateRole->Disable();\r
- chkSuperuser->Disable();\r
- chkInherits->Disable();\r
- chkUpdateCat->Disable();\r
- datValidUntil->Disable();\r
- timValidUntil->Disable();\r
- txtPasswd->Disable();\r
- txtRePasswd->Disable();\r
- btnAddRole->Disable();\r
- btnDelRole->Disable();\r
- cbVarname->Disable();\r
- txtValue->Disable();\r
- btnAdd->Disable();\r
- btnRemove->Disable();\r
- }\r
- }\r
- else\r
- {\r
- chkCanLogin->Disable();\r
- wxDateTime empty;\r
- datValidUntil->SetValue(empty);\r
- timValidUntil->Disable();\r
- }\r
-\r
- // Role comments are only appropriate in 8.2+\r
- if (!connection->BackendMinimumVersion(8, 2))\r
- txtComment->Disable();\r
-\r
- if (!settings->GetShowUsersForPrivileges())\r
- {\r
- if (role)\r
- roleSql += wxT("\n AND NOT rolcanlogin");\r
- else\r
- roleSql += wxT("\n WHERE NOT rolcanlogin");\r
- }\r
- roleSql += wxT("\n ORDER BY rolname");\r
-\r
- pgSetIterator roles(connection, roleSql);\r
-\r
- while (roles.RowsLeft())\r
- lbRolesNotIn->Append(roles.GetVal(wxT("rolname")));\r
-\r
- return dlgProperty::Go(modal);\r
-}\r
-\r
-\r
-wxString dlgRole::GetHelpPage() const\r
-{\r
- if (nbNotebook->GetSelection() == 2)\r
- return wxT("pg/runtime-config");\r
- else\r
- return wxT("pg/sql-createrole");\r
-}\r
-\r
-\r
-void dlgRole::OnOK(wxCommandEvent &ev)\r
-{\r
- dlgProperty::OnOK(ev);\r
-\r
- if (role && role->GetCanLogin() != chkCanLogin->GetValue() == !btnOK->IsEnabled())\r
- {\r
- // LOGIN attribute changed successfully; need to put object under different collection\r
- }\r
-}\r
-\r
-\r
-void dlgRole::OnChangeCal(wxCalendarEvent &ev)\r
-{\r
- CheckChange();\r
-}\r
-\r
-\r
-void dlgRole::OnChangeDate(wxDateEvent &ev)\r
-{\r
- CheckChange();\r
-\r
- bool timEn=ev.GetDate().IsValid();\r
- timValidUntil->Enable(timEn);\r
- if (!timEn)\r
- timValidUntil->SetTime(wxDefaultDateTime);\r
-}\r
-\r
-void dlgRole::OnChangeSpin(wxSpinEvent &ev)\r
-{\r
- CheckChange();\r
-}\r
-\r
-\r
-void dlgRole::OnChangeSuperuser(wxCommandEvent &ev)\r
-{\r
- if (role && role->GetSuperuser() && !chkSuperuser->GetValue())\r
- {\r
- wxMessageDialog dlg(this,\r
- _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"),\r
- _("Confirm superuser deletion"),\r
- wxICON_EXCLAMATION | wxYES_NO |wxNO_DEFAULT);\r
- if (dlg.ShowModal() != wxID_YES)\r
- {\r
- chkSuperuser->SetValue(true);\r
- return;\r
- }\r
- }\r
- CheckChange();\r
-}\r
-\r
-void dlgRole::OnChangePasswd(wxCommandEvent &ev)\r
-{\r
- CheckChange();\r
-}\r
-\r
-void dlgRole::CheckChange()\r
-{\r
- bool timEn=datValidUntil->GetValue().IsValid();\r
- timValidUntil->Enable(timEn);\r
- if (!timEn)\r
- timValidUntil->SetTime(wxDefaultDateTime);\r
-\r
- if (!readOnly)\r
- chkUpdateCat->Enable(chkSuperuser->GetValue());\r
-\r
- // Check the passwords match\r
- if (txtPasswd->GetValue() != txtRePasswd->GetValue())\r
- {\r
- bool enable=true;\r
- CheckValid(enable, false, _("The passwords entered do not match!"));\r
- EnableOK(enable);\r
- return;\r
- }\r
-\r
- if (!role)\r
- {\r
- wxString name=GetName();\r
-\r
- bool enable=true;\r
- CheckValid(enable, !name.IsEmpty(), _("Please specify name."));\r
- EnableOK(enable);\r
- }\r
- else\r
- {\r
- EnableOK(!GetSql().IsEmpty());\r
- }\r
-}\r
-\r
-\r
-void dlgRole::OnRoleAdd(wxCommandEvent &ev)\r
-{\r
- if (!readOnly)\r
- {\r
- int pos=lbRolesNotIn->GetSelection();\r
- if (pos >= 0)\r
- {\r
- wxString roleName=lbRolesNotIn->GetString(pos);\r
- if (chkAdminOption->GetValue())\r
- roleName += PGROLE_ADMINOPTION;\r
- lbRolesIn->Append(roleName);\r
- lbRolesNotIn->Delete(pos);\r
- }\r
- CheckChange();\r
- }\r
-}\r
-\r
-\r
-void dlgRole::OnRoleRemove(wxCommandEvent &ev)\r
-{\r
- if (!readOnly)\r
- {\r
- int pos=lbRolesIn->GetSelection();\r
- if (pos >= 0)\r
- {\r
- wxString role=lbRolesIn->GetString(pos);\r
- if (role.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION)\r
- role = role.Left(role.Length()-PGROLE_ADMINOPTION_LEN);\r
-\r
- lbRolesNotIn->Append(role);\r
- lbRolesIn->Delete(pos);\r
- }\r
- CheckChange();\r
- }\r
-}\r
-\r
-\r
-void dlgRole::OnVarnameSelChange(wxCommandEvent &ev)\r
-{\r
- int sel=cbVarname->GuessSelection(ev);\r
-\r
- SetupVarEditor(sel);\r
-}\r
-\r
-void dlgRole::SetupVarEditor(int var)\r
-{\r
- if (var >= 0 && varInfo.Count() > 0)\r
- {\r
- wxStringTokenizer vals(varInfo.Item(var));\r
- wxString typ=vals.GetNextToken();\r
-\r
- if (typ == wxT("bool"))\r
- {\r
- txtValue->Hide();\r
- chkValue->Show();\r
- }\r
- else\r
- {\r
- chkValue->Hide();\r
- txtValue->Show();\r
- if (typ == wxT("string"))\r
- txtValue->SetValidator(wxTextValidator());\r
- else\r
- txtValue->SetValidator(numericValidator);\r
- }\r
- }\r
-}\r
-\r
-void dlgRole::OnVarSelChange(wxListEvent &ev)\r
-{\r
- long pos=lstVariables->GetSelection();\r
- if (pos >= 0)\r
- {\r
- wxString value=lstVariables->GetText(pos, 1);\r
- cbVarname->SetValue(lstVariables->GetText(pos));\r
-\r
-\r
- // We used to raise an OnVarnameSelChange() event here, but\r
- // at this point the combo box hasn't necessarily updated.\r
- int sel = cbVarname->FindString(lstVariables->GetText(pos));\r
- SetupVarEditor(sel);\r
-\r
- txtValue->SetValue(value);\r
- chkValue->SetValue(value == wxT("on"));\r
- }\r
-}\r
-\r
-\r
-void dlgRole::OnVarAdd(wxCommandEvent &ev)\r
-{\r
- wxString name=cbVarname->GetValue();\r
- wxString value;\r
- if (chkValue->IsShown())\r
- value = chkValue->GetValue() ? wxT("on") : wxT("off");\r
- else\r
- value = txtValue->GetValue().Strip(wxString::both);\r
-\r
- if (value.IsEmpty())\r
- value = wxT("DEFAULT");\r
-\r
- if (!name.IsEmpty())\r
- {\r
- long pos=lstVariables->FindItem(-1, name);\r
- if (pos < 0)\r
- {\r
- pos = lstVariables->GetItemCount();\r
- lstVariables->InsertItem(pos, name, 0);\r
- }\r
- lstVariables->SetItem(pos, 1, value);\r
- }\r
- CheckChange();\r
-}\r
-\r
-\r
-void dlgRole::OnVarRemove(wxCommandEvent &ev)\r
-{\r
- lstVariables->DeleteCurrentItem();\r
- CheckChange();\r
-}\r
-\r
-\r
-pgObject *dlgRole::CreateObject(pgCollection *collection)\r
-{\r
- wxString name=GetName();\r
-\r
- pgObject *obj=loginRoleFactory.CreateObjects(collection, 0, wxT("\n WHERE rolname=") + qtDbString(name));\r
- return obj;\r
-}\r
-\r
-\r
-wxString dlgRole::GetSql()\r
-{\r
- wxString sql;\r
- wxString name=GetName();\r
- \r
- wxString passwd=txtPasswd->GetValue();\r
- bool createDB=chkCreateDB->GetValue(),\r
- createRole=chkCreateRole->GetValue(),\r
- superuser=chkSuperuser->GetValue(),\r
- inherits=chkInherits->GetValue(),\r
- canLogin=chkCanLogin->GetValue();\r
-\r
- if (role)\r
- {\r
- // Edit Mode\r
-\r
- AppendNameChange(sql, wxT("ROLE ") + role->GetQuotedFullIdentifier());\r
-\r
-\r
- wxString options;\r
- if (canLogin != role->GetCanLogin())\r
- {\r
- if (canLogin)\r
- options = wxT(" LOGIN");\r
- else\r
- options = wxT(" NOLOGIN");\r
- }\r
- if (canLogin && !passwd.IsEmpty())\r
- options += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd));\r
-\r
- if (createDB != role->GetCreateDatabase() || createRole != role->GetCreateRole() \r
- || superuser != role->GetSuperuser() || inherits != role->GetInherits())\r
- {\r
- options += wxT("\n ");\r
- \r
- if (superuser != role->GetSuperuser())\r
- {\r
- if (superuser)\r
- options += wxT(" SUPERUSER");\r
- else\r
- options += wxT(" NOSUPERUSER");\r
- }\r
- if (inherits != role->GetInherits())\r
- {\r
- if (inherits)\r
- options += wxT(" INHERIT");\r
- else\r
- options += wxT(" NOINHERIT");\r
- }\r
- if (createDB != role->GetCreateDatabase())\r
- {\r
- if (createDB)\r
- options += wxT(" CREATEDB");\r
- else\r
- options += wxT(" NOCREATEDB");\r
- }\r
- if (createRole != role->GetCreateRole())\r
- {\r
- if (createRole)\r
- options += wxT(" CREATEROLE");\r
- else\r
- options += wxT(" NOCREATEROLE");\r
- }\r
- }\r
- if (DateToStr(datValidUntil->GetValue()) != DateToStr(role->GetAccountExpires()))\r
- {\r
- if (datValidUntil->GetValue().IsValid())\r
- options += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); \r
- else\r
- options += wxT("\n VALID UNTIL 'infinity'");\r
- }\r
-\r
- if (!options.IsNull())\r
- sql += wxT("ALTER Role ") + qtIdent(name) + options + wxT(";\n");\r
-\r
- if (chkUpdateCat->GetValue() != role->GetUpdateCatalog())\r
- {\r
- if (!connection->HasPrivilege(wxT("Table"), wxT("pg_authid"), wxT("update")))\r
- sql += wxT(" -- Can't update 'UpdateCatalog privilege: can't write to pg_authid.\n")\r
- wxT("-- ");\r
-\r
- sql += wxT("UPDATE pg_authid SET rolcatupdate=") + BoolToStr(chkUpdateCat->GetValue())\r
- + wxT(" WHERE OID=") + role->GetOidStr() + wxT(";\n");\r
- }\r
- int cnt=lbRolesIn->GetCount();\r
- wxArrayString tmpRoles=role->GetRolesIn();\r
-\r
- // check for added roles\r
- for (int pos=0 ; pos < cnt ; pos++)\r
- {\r
- wxString roleName=lbRolesIn->GetString(pos);\r
-\r
- int index=tmpRoles.Index(roleName);\r
- if (index >= 0)\r
- {\r
- // role membership unchanged\r
- tmpRoles.RemoveAt(index);\r
- }\r
- else\r
- {\r
- bool admin=false;\r
- if (roleName.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION)\r
- {\r
- admin=true;\r
- roleName=roleName.Left(roleName.Length()-PGROLE_ADMINOPTION_LEN);\r
- }\r
- else\r
- {\r
- // new role membership without admin option\r
- index=tmpRoles.Index(roleName + PGROLE_ADMINOPTION);\r
- if (index >= 0)\r
- {\r
- // old membership with admin option\r
- tmpRoles.RemoveAt(index);\r
- sql += wxT("REVOKE ADMIN OPTION FOR ") + qtIdent(roleName)\r
- + wxT(" FROM ") + qtIdent(name) + wxT(";\n");\r
- continue;\r
- }\r
- }\r
-\r
- index=tmpRoles.Index(roleName);\r
- if (index >= 0)\r
- {\r
- // admin option added to existing membership\r
- tmpRoles.RemoveAt(index);\r
- }\r
-\r
- sql += wxT("GRANT ") + qtIdent(roleName)\r
- + wxT(" TO ") + qtIdent(name);\r
-\r
- if (admin)\r
- sql += wxT(" WITH ADMIN OPTION");\r
-\r
- sql += wxT(";\n");\r
- }\r
- }\r
- \r
- // check for removed roles\r
- for (int pos=0 ; pos < (int)tmpRoles.GetCount() ; pos++)\r
- {\r
- sql += wxT("REVOKE ") + qtIdent(tmpRoles.Item(pos))\r
- + wxT(" FROM ") + qtIdent(name) + wxT(";\n");\r
- }\r
- }\r
- else\r
- {\r
- // Create Mode\r
- sql = wxT(\r
- "CREATE ROLE ") + qtIdent(name);\r
- if (canLogin)\r
- {\r
- sql += wxT(" LOGIN");\r
- if (!passwd.IsEmpty())\r
- sql += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd));\r
- }\r
-\r
- if (createDB || createRole ||!inherits || superuser)\r
- sql += wxT("\n ");\r
- if (superuser)\r
- sql += wxT(" SUPERUSER");\r
- if (!inherits)\r
- sql += wxT(" NOINHERIT");\r
- if (createDB)\r
- sql += wxT(" CREATEDB");\r
- if (createRole)\r
- sql += wxT(" CREATEROLE");\r
- if (datValidUntil->GetValue().IsValid())\r
- sql += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); \r
- else\r
- sql += wxT("\n VALID UNTIL 'infinity'");\r
- \r
- int cnt = lbRolesIn->GetCount();\r
- int pos;\r
-\r
- if (cnt)\r
- {\r
- sql += wxT("\n IN ROLE ");\r
- for (pos=0 ; pos < cnt ; pos++)\r
- {\r
- if (pos)\r
- sql += wxT(", ");\r
- sql += qtIdent(lbRolesIn->GetString(pos));\r
- }\r
- }\r
- sql += wxT(";\n");\r
-\r
- if (superuser && !chkUpdateCat->GetValue())\r
- sql += wxT("UPDATE pg_authid SET rolcatupdate=false WHERE rolname=") + qtDbString(name) + wxT(";\n");\r
- }\r
-\r
- wxArrayString vars;\r
- size_t index;\r
-\r
- if (role)\r
- {\r
- for (index = 0 ; index < role->GetConfigList().GetCount() ; index++)\r
- vars.Add(role->GetConfigList().Item(index));\r
- }\r
-\r
- int cnt=lstVariables->GetItemCount();\r
- int pos;\r
-\r
- // check for changed or added vars\r
- for (pos=0 ; pos < cnt ; pos++)\r
- {\r
- wxString newVar=lstVariables->GetText(pos);\r
- wxString newVal=lstVariables->GetText(pos, 1);\r
-\r
- wxString oldVal;\r
-\r
- for (index=0 ; index < vars.GetCount() ; index++)\r
- {\r
- wxString var=vars.Item(index);\r
- if (var.BeforeFirst('=').IsSameAs(newVar, false))\r
- {\r
- oldVal = var.Mid(newVar.Length()+1);\r
- vars.RemoveAt(index);\r
- break;\r
- }\r
- }\r
- if (oldVal != newVal)\r
- {\r
- sql += wxT("ALTER ROLE ") + qtIdent(name)\r
- + wxT(" SET ") + newVar\r
- + wxT("=") + newVal\r
- + wxT(";\n");\r
- }\r
- }\r
- \r
- // check for removed vars\r
- for (pos=0 ; pos < (int)vars.GetCount() ; pos++)\r
- {\r
- sql += wxT("ALTER Role ") + qtIdent(name)\r
- + wxT(" RESET ") + vars.Item(pos).BeforeFirst('=')\r
- + wxT(";\n");\r
- }\r
-\r
- AppendComment(sql, wxT("ROLE"), 0, role);\r
-\r
- return sql;\r
-}\r
-\r
-\r
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID: $Id$
+// Copyright (C) 2002 - 2008, The pgAdmin Development Team
+// This software is released under the Artistic Licence
+//
+// dlgRole.cpp - PostgreSQL Role Property
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "pgAdmin3.h"
+
+// wxWindows headers
+#include <wx/wx.h>
+
+// App headers
+#include "utils/misc.h"
+#include "dlg/dlgRole.h"
+#include "schema/pgRole.h"
+
+
+// pointer to controls
+#define txtPasswd CTRL_TEXT("txtPasswd")
+#define txtRePasswd CTRL_TEXT("txtRePasswd")
+#define datValidUntil CTRL_CALENDAR("datValidUntil")
+#define timValidUntil CTRL_TIME("timValidUntil")
+#define chkCanLogin CTRL_CHECKBOX("chkCanLogin")
+#define chkSuperuser CTRL_CHECKBOX("chkSuperuser")
+#define chkInherits CTRL_CHECKBOX("chkInherits")
+#define chkCreateDB CTRL_CHECKBOX("chkCreateDB")
+#define chkCreateRole CTRL_CHECKBOX("chkCreateRole")
+#define chkUpdateCat CTRL_CHECKBOX("chkUpdateCat")
+
+#define lbRolesNotIn CTRL_LISTBOX("lbRolesNotIn")
+#define lbRolesIn CTRL_LISTBOX("lbRolesIn")
+#define btnAddRole CTRL_BUTTON("btnAddRole")
+#define btnDelRole CTRL_BUTTON("btnDelRole")
+#define chkAdminOption CTRL_CHECKBOX("chkAdminOption")
+
+#define lstVariables CTRL_LISTVIEW("lstVariables")
+#define btnAdd CTRL_BUTTON("wxID_ADD")
+#define btnRemove CTRL_BUTTON("wxID_REMOVE")
+#define cbVarname CTRL_COMBOBOX2("cbVarname")
+#define txtValue CTRL_TEXT("txtValue")
+#define chkValue CTRL_CHECKBOX("chkValue")
+
+
+
+dlgProperty *pgLoginRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
+{
+ return new dlgRole(this, frame, (pgRole*)node, true);
+}
+
+dlgProperty *pgGroupRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
+{
+ return new dlgRole(this, frame, (pgRole*)node, false);
+}
+
+BEGIN_EVENT_TABLE(dlgRole, dlgProperty)
+ EVT_CALENDAR_SEL_CHANGED(XRCID("datValidUntil"),dlgRole::OnChangeCal)
+ EVT_DATE_CHANGED(XRCID("datValidUntil"), dlgRole::OnChangeDate)
+ EVT_SPIN(XRCID("timValidUntil"), dlgRole::OnChangeSpin)
+
+ EVT_LISTBOX_DCLICK(XRCID("lbRolesNotIn"), dlgRole::OnRoleAdd)
+ EVT_LISTBOX_DCLICK(XRCID("lbRolesIn"), dlgRole::OnRoleRemove)
+ EVT_TEXT(XRCID("txtPasswd"), dlgRole::OnChangePasswd)
+ EVT_TEXT(XRCID("txtRePasswd"), dlgRole::OnChangePasswd)
+ EVT_CHECKBOX(XRCID("chkCanLogin"), dlgRole::OnChange)
+ EVT_CHECKBOX(XRCID("chkInherits"), dlgRole::OnChange)
+ EVT_CHECKBOX(XRCID("chkCreateDB"), dlgRole::OnChange)
+ EVT_CHECKBOX(XRCID("chkUpdateCat"), dlgRole::OnChange)
+ EVT_CHECKBOX(XRCID("chkSuperuser"), dlgRole::OnChangeSuperuser)
+ EVT_CHECKBOX(XRCID("chkCreateRole"), dlgRole::OnChange)
+
+ EVT_BUTTON(XRCID("btnAddRole"), dlgRole::OnRoleAdd)
+ EVT_BUTTON(XRCID("btnDelRole"), dlgRole::OnRoleRemove)
+
+ EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgRole::OnVarSelChange)
+ EVT_BUTTON(wxID_ADD, dlgRole::OnVarAdd)
+ EVT_BUTTON(wxID_REMOVE, dlgRole::OnVarRemove)
+ EVT_TEXT(XRCID("cbVarname"), dlgRole::OnVarnameSelChange)
+ EVT_COMBOBOX(XRCID("cbVarname"), dlgRole::OnVarnameSelChange)
+
+ EVT_BUTTON(wxID_OK, dlgRole::OnOK)
+END_EVENT_TABLE();
+
+
+
+dlgRole::dlgRole(pgaFactory *f, frmMain *frame, pgRole *node, bool chkLogin)
+: dlgProperty(f, frame, wxT("dlgRole"))
+{
+ role=node;
+ lstVariables->CreateColumns(0, _("Variable"), _("Value"), -1);
+ btnOK->Disable();
+ chkValue->Hide();
+ if (chkLogin)
+ chkCanLogin->SetValue(true);
+}
+
+
+pgObject *dlgRole::GetObject()
+{
+ return role;
+}
+
+
+int dlgRole::Go(bool modal)
+{
+ wxString roleSql=
+ wxT("SELECT rolname\n")
+ wxT(" FROM pg_roles r\n");
+
+ varInfo.Add(wxT("role"));
+ cbVarname->Append(wxT("role"));
+
+ pgSet *set;
+ set=connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n")
+ wxT(" FROM pg_settings WHERE context in ('user', 'superuser')"));
+
+ if (set)
+ {
+ while (!set->Eof())
+ {
+ cbVarname->Append(set->GetVal(0));
+ varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") +
+ set->GetVal(wxT("min_val")) + wxT(" ") +
+ set->GetVal(wxT("max_val")));
+ set->MoveNext();
+ }
+ delete set;
+
+ cbVarname->SetSelection(0);
+ }
+
+ if (role)
+ {
+ wxArrayString roles=role->GetRolesIn();
+ size_t i;
+ for (i=0 ; i < roles.GetCount() ; i++)
+ lbRolesIn->Append(roles.Item(i));
+
+ roleSql +=
+ wxT(" LEFT JOIN pg_auth_members ON r.oid=roleid AND member = ") + role->GetOidStr() + wxT("\n")
+ wxT(" WHERE r.oid <> ") + role->GetOidStr() + wxT("\n")
+ wxT(" AND roleid IS NULL");
+
+ // Edit Mode
+ if (role->GetServer()->GetSuperUser() || role->GetServer()->GetCreateRole())
+ readOnly=false;
+ else
+ readOnly=true;
+
+ chkCreateDB->SetValue(role->GetCreateDatabase());
+ chkCreateRole->SetValue(role->GetCreateRole());
+ chkSuperuser->SetValue(role->GetSuperuser());
+ chkInherits->SetValue(role->GetInherits());
+ chkUpdateCat->SetValue(role->GetUpdateCatalog());
+ chkCanLogin->SetValue(role->GetCanLogin());
+ datValidUntil->SetValue(role->GetAccountExpires());
+ timValidUntil->SetTime(role->GetAccountExpires());
+ txtComment->SetValue(role->GetComment());
+
+ size_t index;
+ for (index = 0 ; index < role->GetConfigList().GetCount() ; index++)
+ {
+ wxString item=role->GetConfigList().Item(index);
+ lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('='));
+ }
+
+ timValidUntil->Enable(!readOnly && role->GetAccountExpires().IsValid());
+
+ if (readOnly)
+ {
+ chkCanLogin->Disable();
+ chkCreateDB->Disable();
+ chkCreateRole->Disable();
+ chkSuperuser->Disable();
+ chkInherits->Disable();
+ chkUpdateCat->Disable();
+ datValidUntil->Disable();
+ timValidUntil->Disable();
+ txtPasswd->Disable();
+ txtRePasswd->Disable();
+ btnAddRole->Disable();
+ btnDelRole->Disable();
+ cbVarname->Disable();
+ txtValue->Disable();
+ btnAdd->Disable();
+ btnRemove->Disable();
+ }
+ }
+ else
+ {
+ chkCanLogin->Disable();
+ wxDateTime empty;
+ datValidUntil->SetValue(empty);
+ timValidUntil->Disable();
+ }
+
+ // Role comments are only appropriate in 8.2+
+ if (!connection->BackendMinimumVersion(8, 2))
+ txtComment->Disable();
+
+ if (!settings->GetShowUsersForPrivileges())
+ {
+ if (role)
+ roleSql += wxT("\n AND NOT rolcanlogin");
+ else
+ roleSql += wxT("\n WHERE NOT rolcanlogin");
+ }
+ roleSql += wxT("\n ORDER BY rolname");
+
+ pgSetIterator roles(connection, roleSql);
+
+ while (roles.RowsLeft())
+ lbRolesNotIn->Append(roles.GetVal(wxT("rolname")));
+
+ return dlgProperty::Go(modal);
+}
+
+
+wxString dlgRole::GetHelpPage() const
+{
+ if (nbNotebook->GetSelection() == 2)
+ return wxT("pg/runtime-config");
+ else
+ return wxT("pg/sql-createrole");
+}
+
+
+void dlgRole::OnOK(wxCommandEvent &ev)
+{
+ dlgProperty::OnOK(ev);
+
+ if (role && role->GetCanLogin() != chkCanLogin->GetValue() == !btnOK->IsEnabled())
+ {
+ // LOGIN attribute changed successfully; need to put object under different collection
+ }
+}
+
+
+void dlgRole::OnChangeCal(wxCalendarEvent &ev)
+{
+ CheckChange();
+}
+
+
+void dlgRole::OnChangeDate(wxDateEvent &ev)
+{
+ CheckChange();
+
+ bool timEn=ev.GetDate().IsValid();
+ timValidUntil->Enable(timEn);
+ if (!timEn)
+ timValidUntil->SetTime(wxDefaultDateTime);
+}
+
+void dlgRole::OnChangeSpin(wxSpinEvent &ev)
+{
+ CheckChange();
+}
+
+
+void dlgRole::OnChangeSuperuser(wxCommandEvent &ev)
+{
+ if (role && role->GetSuperuser() && !chkSuperuser->GetValue())
+ {
+ wxMessageDialog dlg(this,
+ _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"),
+ _("Confirm superuser deletion"),
+ wxICON_EXCLAMATION | wxYES_NO |wxNO_DEFAULT);
+ if (dlg.ShowModal() != wxID_YES)
+ {
+ chkSuperuser->SetValue(true);
+ return;
+ }
+ }
+ CheckChange();
+}
+
+void dlgRole::OnChangePasswd(wxCommandEvent &ev)
+{
+ CheckChange();
+}
+
+void dlgRole::CheckChange()
+{
+ bool timEn=datValidUntil->GetValue().IsValid();
+ timValidUntil->Enable(timEn);
+ if (!timEn)
+ timValidUntil->SetTime(wxDefaultDateTime);
+
+ if (!readOnly)
+ chkUpdateCat->Enable(chkSuperuser->GetValue());
+
+ // Check the passwords match
+ if (txtPasswd->GetValue() != txtRePasswd->GetValue())
+ {
+ bool enable=true;
+ CheckValid(enable, false, _("The passwords entered do not match!"));
+ EnableOK(enable);
+ return;
+ }
+
+ if (!role)
+ {
+ wxString name=GetName();
+
+ bool enable=true;
+ CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
+ EnableOK(enable);
+ }
+ else
+ {
+ EnableOK(!GetSql().IsEmpty());
+ }
+}
+
+
+void dlgRole::OnRoleAdd(wxCommandEvent &ev)
+{
+ if (!readOnly)
+ {
+ int pos=lbRolesNotIn->GetSelection();
+ if (pos >= 0)
+ {
+ wxString roleName=lbRolesNotIn->GetString(pos);
+ if (chkAdminOption->GetValue())
+ roleName += PGROLE_ADMINOPTION;
+ lbRolesIn->Append(roleName);
+ lbRolesNotIn->Delete(pos);
+ }
+ CheckChange();
+ }
+}
+
+
+void dlgRole::OnRoleRemove(wxCommandEvent &ev)
+{
+ if (!readOnly)
+ {
+ int pos=lbRolesIn->GetSelection();
+ if (pos >= 0)
+ {
+ wxString role=lbRolesIn->GetString(pos);
+ if (role.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION)
+ role = role.Left(role.Length()-PGROLE_ADMINOPTION_LEN);
+
+ lbRolesNotIn->Append(role);
+ lbRolesIn->Delete(pos);
+ }
+ CheckChange();
+ }
+}
+
+
+void dlgRole::OnVarnameSelChange(wxCommandEvent &ev)
+{
+ int sel=cbVarname->GuessSelection(ev);
+
+ SetupVarEditor(sel);
+}
+
+void dlgRole::SetupVarEditor(int var)
+{
+ if (var >= 0 && varInfo.Count() > 0)
+ {
+ wxStringTokenizer vals(varInfo.Item(var));
+ wxString typ=vals.GetNextToken();
+
+ if (typ == wxT("bool"))
+ {
+ txtValue->Hide();
+ chkValue->Show();
+ }
+ else
+ {
+ chkValue->Hide();
+ txtValue->Show();
+ if (typ == wxT("string"))
+ txtValue->SetValidator(wxTextValidator());
+ else
+ txtValue->SetValidator(numericValidator);
+ }
+ }
+}
+
+void dlgRole::OnVarSelChange(wxListEvent &ev)
+{
+ long pos=lstVariables->GetSelection();
+ if (pos >= 0)
+ {
+ wxString value=lstVariables->GetText(pos, 1);
+ cbVarname->SetValue(lstVariables->GetText(pos));
+
+
+ // We used to raise an OnVarnameSelChange() event here, but
+ // at this point the combo box hasn't necessarily updated.
+ int sel = cbVarname->FindString(lstVariables->GetText(pos));
+ SetupVarEditor(sel);
+
+ txtValue->SetValue(value);
+ chkValue->SetValue(value == wxT("on"));
+ }
+}
+
+
+void dlgRole::OnVarAdd(wxCommandEvent &ev)
+{
+ wxString name=cbVarname->GetValue();
+ wxString value;
+ if (chkValue->IsShown())
+ value = chkValue->GetValue() ? wxT("on") : wxT("off");
+ else
+ value = txtValue->GetValue().Strip(wxString::both);
+
+ if (value.IsEmpty())
+ value = wxT("DEFAULT");
+
+ if (!name.IsEmpty())
+ {
+ long pos=lstVariables->FindItem(-1, name);
+ if (pos < 0)
+ {
+ pos = lstVariables->GetItemCount();
+ lstVariables->InsertItem(pos, name, 0);
+ }
+ lstVariables->SetItem(pos, 1, value);
+ }
+ CheckChange();
+}
+
+
+void dlgRole::OnVarRemove(wxCommandEvent &ev)
+{
+ lstVariables->DeleteCurrentItem();
+ CheckChange();
+}
+
+
+pgObject *dlgRole::CreateObject(pgCollection *collection)
+{
+ wxString name=GetName();
+
+ pgObject *obj=loginRoleFactory.CreateObjects(collection, 0, wxT("\n WHERE rolname=") + qtDbString(name));
+ return obj;
+}
+
+
+wxString dlgRole::GetSql()
+{
+ int pos;
+ wxString sql;
+ wxString name=GetName();
+
+ wxString passwd=txtPasswd->GetValue();
+ bool createDB=chkCreateDB->GetValue(),
+ createRole=chkCreateRole->GetValue(),
+ superuser=chkSuperuser->GetValue(),
+ inherits=chkInherits->GetValue(),
+ canLogin=chkCanLogin->GetValue();
+
+ if (role)
+ {
+ // Edit Mode
+
+ AppendNameChange(sql, wxT("ROLE ") + role->GetQuotedFullIdentifier());
+
+
+ wxString options;
+ if (canLogin != role->GetCanLogin())
+ {
+ if (canLogin)
+ options = wxT(" LOGIN");
+ else
+ options = wxT(" NOLOGIN");
+ }
+ if (canLogin && !passwd.IsEmpty())
+ options += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd));
+
+ if (createDB != role->GetCreateDatabase() || createRole != role->GetCreateRole()
+ || superuser != role->GetSuperuser() || inherits != role->GetInherits())
+ {
+ options += wxT("\n ");
+
+ if (superuser != role->GetSuperuser())
+ {
+ if (superuser)
+ options += wxT(" SUPERUSER");
+ else
+ options += wxT(" NOSUPERUSER");
+ }
+ if (inherits != role->GetInherits())
+ {
+ if (inherits)
+ options += wxT(" INHERIT");
+ else
+ options += wxT(" NOINHERIT");
+ }
+ if (createDB != role->GetCreateDatabase())
+ {
+ if (createDB)
+ options += wxT(" CREATEDB");
+ else
+ options += wxT(" NOCREATEDB");
+ }
+ if (createRole != role->GetCreateRole())
+ {
+ if (createRole)
+ options += wxT(" CREATEROLE");
+ else
+ options += wxT(" NOCREATEROLE");
+ }
+ }
+ if (DateToStr(datValidUntil->GetValue()) != DateToStr(role->GetAccountExpires()))
+ {
+ if (datValidUntil->GetValue().IsValid())
+ options += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue()));
+ else
+ options += wxT("\n VALID UNTIL 'infinity'");
+ }
+
+ if (!options.IsNull())
+ sql += wxT("ALTER Role ") + qtIdent(name) + options + wxT(";\n");
+
+ if (chkUpdateCat->GetValue() != role->GetUpdateCatalog())
+ {
+ if (!connection->HasPrivilege(wxT("Table"), wxT("pg_authid"), wxT("update")))
+ sql += wxT(" -- Can't update 'UpdateCatalog privilege: can't write to pg_authid.\n")
+ wxT("-- ");
+
+ sql += wxT("UPDATE pg_authid SET rolcatupdate=") + BoolToStr(chkUpdateCat->GetValue())
+ + wxT(" WHERE OID=") + role->GetOidStr() + wxT(";\n");
+ }
+ int cnt=lbRolesIn->GetCount();
+ wxArrayString tmpRoles=role->GetRolesIn();
+
+ // check for added roles
+ for (int pos=0 ; pos < cnt ; pos++)
+ {
+ wxString roleName=lbRolesIn->GetString(pos);
+
+ int index=tmpRoles.Index(roleName);
+ if (index >= 0)
+ {
+ // role membership unchanged
+ tmpRoles.RemoveAt(index);
+ }
+ else
+ {
+ bool admin=false;
+ if (roleName.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION)
+ {
+ admin=true;
+ roleName=roleName.Left(roleName.Length()-PGROLE_ADMINOPTION_LEN);
+ }
+ else
+ {
+ // new role membership without admin option
+ index=tmpRoles.Index(roleName + PGROLE_ADMINOPTION);
+ if (index >= 0)
+ {
+ // old membership with admin option
+ tmpRoles.RemoveAt(index);
+ sql += wxT("REVOKE ADMIN OPTION FOR ") + qtIdent(roleName)
+ + wxT(" FROM ") + qtIdent(name) + wxT(";\n");
+ continue;
+ }
+ }
+
+ index=tmpRoles.Index(roleName);
+ if (index >= 0)
+ {
+ // admin option added to existing membership
+ tmpRoles.RemoveAt(index);
+ }
+
+ sql += wxT("GRANT ") + qtIdent(roleName)
+ + wxT(" TO ") + qtIdent(name);
+
+ if (admin)
+ sql += wxT(" WITH ADMIN OPTION");
+
+ sql += wxT(";\n");
+ }
+ }
+
+ // check for removed roles
+ for (pos=0 ; pos < (int)tmpRoles.GetCount() ; pos++)
+ {
+ sql += wxT("REVOKE ") + qtIdent(tmpRoles.Item(pos))
+ + wxT(" FROM ") + qtIdent(name) + wxT(";\n");
+ }
+ }
+ else
+ {
+ // Create Mode
+ sql = wxT(
+ "CREATE ROLE ") + qtIdent(name);
+ if (canLogin)
+ {
+ sql += wxT(" LOGIN");
+ if (!passwd.IsEmpty())
+ sql += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd));
+ }
+
+ if (createDB || createRole ||!inherits || superuser)
+ sql += wxT("\n ");
+ if (superuser)
+ sql += wxT(" SUPERUSER");
+ if (!inherits)
+ sql += wxT(" NOINHERIT");
+ if (createDB)
+ sql += wxT(" CREATEDB");
+ if (createRole)
+ sql += wxT(" CREATEROLE");
+ if (datValidUntil->GetValue().IsValid())
+ sql += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue()));
+ else
+ sql += wxT("\n VALID UNTIL 'infinity'");
+
+ int cnt = lbRolesIn->GetCount();
+
+ if (cnt)
+ {
+ sql += wxT("\n IN ROLE ");
+ for (pos=0 ; pos < cnt ; pos++)
+ {
+ if (pos)
+ sql += wxT(", ");
+ sql += qtIdent(lbRolesIn->GetString(pos));
+ }
+ }
+ sql += wxT(";\n");
+
+ if (superuser && !chkUpdateCat->GetValue())
+ sql += wxT("UPDATE pg_authid SET rolcatupdate=false WHERE rolname=") + qtDbString(name) + wxT(";\n");
+ }
+
+ wxArrayString vars;
+ size_t index;
+
+ if (role)
+ {
+ for (index = 0 ; index < role->GetConfigList().GetCount() ; index++)
+ vars.Add(role->GetConfigList().Item(index));
+ }
+
+ int cnt=lstVariables->GetItemCount();
+
+ // check for changed or added vars
+ for (pos=0 ; pos < cnt ; pos++)
+ {
+ wxString newVar=lstVariables->GetText(pos);
+ wxString newVal=lstVariables->GetText(pos, 1);
+
+ wxString oldVal;
+
+ for (index=0 ; index < vars.GetCount() ; index++)
+ {
+ wxString var=vars.Item(index);
+ if (var.BeforeFirst('=').IsSameAs(newVar, false))
+ {
+ oldVal = var.Mid(newVar.Length()+1);
+ vars.RemoveAt(index);
+ break;
+ }
+ }
+ if (oldVal != newVal)
+ {
+ sql += wxT("ALTER ROLE ") + qtIdent(name)
+ + wxT(" SET ") + newVar
+ + wxT("=") + newVal
+ + wxT(";\n");
+ }
+ }
+
+ // check for removed vars
+ for (pos=0 ; pos < (int)vars.GetCount() ; pos++)
+ {
+ sql += wxT("ALTER Role ") + qtIdent(name)
+ + wxT(" RESET ") + vars.Item(pos).BeforeFirst('=')
+ + wxT(";\n");
+ }
+
+ AppendComment(sql, wxT("ROLE"), 0, role);
+
+ return sql;
+}
+
+