////////////////////////////////////////////////////////////////////////// // // pgAdmin III - PostgreSQL Tools // // Copyright (C) 2002 - 2016, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // // dlgRole.cpp - PostgreSQL Role Property // ////////////////////////////////////////////////////////////////////////// #include "pgAdmin3.h" // wxWindows headers #include // App headers #include "utils/misc.h" #include "dlg/dlgRole.h" #include "schema/pgRole.h" #include "ctl/ctlSeclabelPanel.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 chkReplication CTRL_CHECKBOX("chkReplication") #define txtConnectionLimit CTRL_TEXT("txtConnectionLimit") #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 cbVarDbname CTRL_COMBOBOX2("cbVarDbname") #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_TEXT(XRCID("timValidUntil"), dlgRole::OnChange) 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_CHECKBOX(XRCID("chkReplication"), dlgRole::OnChange) EVT_TEXT(XRCID("txtConnectionLimit"), 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_TEXT(XRCID("cbVarDbname"), dlgRole::OnVarnameSelChange) EVT_COMBOBOX(XRCID("cbVarname"), dlgRole::OnVarnameSelChange) EVT_BUTTON(wxID_OK, dlgRole::OnOK) #ifdef __WXMAC__ EVT_SIZE( dlgRole::OnChangeSize) #endif END_EVENT_TABLE(); dlgRole::dlgRole(pgaFactory *f, frmMain *frame, pgRole *node, bool chkLogin) : dlgProperty(f, frame, wxT("dlgRole")) { role = node; lstVariables->CreateColumns(0, _("Database"), _("Variable"), _("Value"), -1); btnOK->Disable(); chkValue->Hide(); if (chkLogin) chkCanLogin->SetValue(true); seclabelPage = new ctlSeclabelPanel(nbNotebook); } pgObject *dlgRole::GetObject() { return role; } #ifdef __WXMAC__ void dlgRole::OnChangeSize(wxSizeEvent &ev) { lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord, ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); if (GetAutoLayout()) { Layout(); } } #endif int dlgRole::Go(bool modal) { // In wxMac, the text deletion of "calenderBox" is not raising the EVT_CALENDAR_SEL_CHANGED, EVT_DATE_CHANGED events properly. // Hence, raising these events with wxEVT_CHILD_FOCUS events. // #ifdef __WXMAC__ datValidUntil->Connect(wxEVT_CHILD_FOCUS, wxCommandEventHandler(dlgRole::OnChange), NULL, this); timValidUntil->Connect(wxEVT_CHILD_FOCUS, wxCommandEventHandler(dlgRole::OnChange), NULL, this); #endif if (connection->BackendMinimumVersion(9, 0)) { cbVarDbname->Append(wxT("")); AddDatabases(cbVarDbname); } else { cbVarDbname->Enable(false); } if (connection->BackendMinimumVersion(9, 2)) { seclabelPage->SetConnection(connection); seclabelPage->SetObject(role); this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgRole::OnChange)); } else seclabelPage->Disable(); 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 (connection->BackendMinimumVersion(9, 0)) { cbVarDbname->SetSelection(0); } SetupVarEditor(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()); if (!connection->BackendMinimumVersion(9, 5)) chkUpdateCat->SetValue(role->GetUpdateCatalog()); else chkUpdateCat->Disable(); chkCanLogin->SetValue(role->GetCanLogin()); chkReplication->SetValue(role->GetReplication()); if (role->GetAccountExpires().IsValid() && role->GetAccountExpires().GetValue() != -1) { datValidUntil->SetValue(role->GetAccountExpires().GetDateOnly()); timValidUntil->SetTime(role->GetAccountExpires()); } else { wxDateTime empty; datValidUntil->SetValue(empty); } txtConnectionLimit->SetValue(NumToStr(role->GetConnectionLimit())); txtComment->SetValue(role->GetComment()); size_t index; wxString dbname; wxString parameter; wxString value; for (index = 0 ; index < role->GetVariables().GetCount() ; index += 3) { dbname = role->GetVariables().Item(index); parameter = role->GetVariables().Item(index + 1); value = role->GetVariables().Item(index + 2); lstVariables->AppendItem(0, dbname, parameter, value); } timValidUntil->Enable(!readOnly && role->GetAccountExpires().IsValid()); if (readOnly) { chkCanLogin->Disable(); chkCreateDB->Disable(); chkCreateRole->Disable(); chkSuperuser->Disable(); chkInherits->Disable(); chkUpdateCat->Disable(); chkReplication->Disable(); datValidUntil->Disable(); timValidUntil->Disable(); btnAddRole->Disable(); btnDelRole->Disable(); cbVarname->Disable(); cbVarDbname->Disable(); txtValue->Disable(); txtConnectionLimit->Disable(); btnRemove->Disable(); /* Its own password can be changed. */ if (connection->GetUser() != role->GetName()) { txtPasswd->Disable(); txtRePasswd->Disable(); btnAdd->Disable(); } else { txtPasswd->Enable(); txtRePasswd->Enable(); btnAdd->Enable(); } } } 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(); // Replication roles added in 9.1 if (!connection->BackendMinimumVersion(9, 1)) { chkReplication->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) { bool timEn = ev.GetDate().IsValid(); timValidUntil->Enable(timEn); if (!timEn) timValidUntil->SetTime(wxDefaultDateTime); else timValidUntil->SetTime(wxDateTime::Today()); CheckChange(); } void dlgRole::OnChangeDate(wxDateEvent &ev) { bool timEn = ev.GetDate().IsValid(); timValidUntil->Enable(timEn); if (!timEn) timValidUntil->SetTime(wxDefaultDateTime); else timValidUntil->SetTime(wxDateTime::Today()); CheckChange(); } 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; } } chkUpdateCat->SetValue(chkSuperuser->GetValue() && !connection->BackendMinimumVersion(9, 5)); CheckChange(); } void dlgRole::OnChangePasswd(wxCommandEvent &ev) { CheckChange(); } void dlgRole::CheckChange() { bool enable = true; bool timEn = datValidUntil->GetValue().IsValid(); timValidUntil->Enable(timEn); if (!timEn) timValidUntil->SetTime(wxDefaultDateTime); if (!readOnly) chkUpdateCat->Enable(chkSuperuser->GetValue() && !connection->BackendMinimumVersion(9, 5)); // 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(); CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); } else { enable = !GetSql().IsEmpty(); if (seclabelPage && connection->BackendMinimumVersion(9, 2)) enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); } EnableOK(enable); } void dlgRole::OnRoleAdd(wxCommandEvent &ev) { if (!readOnly) { int pos = lbRolesNotIn->GetSelection(); if (pos >= 0) { wxString roleName = lbRolesNotIn->GetString(pos); if (chkAdminOption->GetValue()) roleName += "(A)"; lbRolesIn->Append(roleName); lbRolesNotIn->Delete(pos); } CheckChange(); } } void dlgRole::OnRoleRemove(wxCommandEvent &ev) { if (!readOnly) { int pos = lbRolesIn->GetSelection(); if (pos >= 0) { wxString roleName = lbRolesIn->GetString(pos); if (!pgRole::GetOptStr(roleName).IsEmpty()) roleName = roleName.BeforeLast('('); lbRolesNotIn->Append(roleName); 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(); chkValue->GetParent()->Layout(); } else { chkValue->Hide(); txtValue->Show(); txtValue->GetParent()->Layout(); if (typ == wxT("string") || typ == wxT("enum")) txtValue->SetValidator(wxTextValidator()); else txtValue->SetValidator(numericValidator); } } } void dlgRole::OnVarSelChange(wxListEvent &ev) { long pos = lstVariables->GetSelection(); if (pos >= 0) { cbVarDbname->SetValue(lstVariables->GetText(pos)); cbVarname->SetValue(lstVariables->GetText(pos, 1)); // We used to raise an OnVarnameSelChange() event here, but // at this point the combo box hasn't necessarily updated. wxString value = lstVariables->GetText(pos, 2); int sel = cbVarname->FindString(lstVariables->GetText(pos, 1)); txtValue->SetValue(value); chkValue->SetValue(value == wxT("on")); } } void dlgRole::OnVarAdd(wxCommandEvent &ev) { wxString dbname = cbVarDbname->GetValue(); 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()) { bool found = false; long prevpos = -1; for (long item = 0; item < lstVariables->GetItemCount(); item++) { if (name == lstVariables->GetText(item, 1)) { if (dbname == lstVariables->GetText(item)) { found = true; lstVariables->SetItem(item, 2, value); } else { prevpos = item; } } } if (!found) { if (prevpos != -1) { lstVariables->InsertItem(prevpos, dbname, 1); lstVariables->SetItem(prevpos, 1, name); lstVariables->SetItem(prevpos, 2, value); } else { long pos = lstVariables->GetItemCount(); lstVariables->InsertItem(pos, dbname, 1); lstVariables->SetItem(pos, 1, name); lstVariables->SetItem(pos, 2, value); } } } CheckChange(); } void dlgRole::OnVarRemove(wxCommandEvent &ev) { if (lstVariables->GetSelection() == wxNOT_FOUND) return; 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(), replication = chkReplication->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() || replication != role->GetReplication()) { 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 (connection->BackendMinimumVersion(9, 1)) { if (replication != role->GetReplication()) { if (replication) options += wxT(" REPLICATION"); else options += wxT(" NOREPLICATION"); } } } if (!datValidUntil->GetValue().IsValid() || DateToStr(datValidUntil->GetValue() + timValidUntil->GetValue()) != DateToStr(role->GetAccountExpires())) { if (datValidUntil->GetValue().IsValid()) options += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); else if (!role->GetIsValidInfinity() && role->GetAccountExpires().GetValue() != -1) options += wxT("\n VALID UNTIL 'infinity'"); } if (txtConnectionLimit->GetValue().Length() == 0) { if (role->GetConnectionLimit() != -1) { options += wxT(" CONNECTION LIMIT -1"); } } else { if (txtConnectionLimit->GetValue() != NumToStr(role->GetConnectionLimit())) { options += wxT(" CONNECTION LIMIT ") + txtConnectionLimit->GetValue(); } } if (!options.IsNull()) sql += wxT("ALTER ROLE ") + qtIdent(name) + options + wxT(";\n"); if (!connection->BackendMinimumVersion(9, 5) && 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 (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; wxString opt = pgRole::GetOptStr(roleName); if (!opt.IsEmpty()) { admin = true; roleName = roleName.BeforeLast('('); } else { // new role membership without admin option index = tmpRoles.Index(roleName + "("); 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 += opt; sql += wxT(";\n"); } } // check for removed roles for (pos = 0 ; pos < (int)tmpRoles.GetCount() ; pos++) { wxString roleName = tmpRoles.Item(pos); wxString opt=pgRole::GetOptStr(roleName); if (!opt.IsEmpty()) roleName = roleName.BeforeLast('('); sql += wxT("REVOKE ") + qtIdent(roleName) + 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 (connection->BackendMinimumVersion(9, 1)) { if (replication) sql += wxT(" REPLICATION"); } if (datValidUntil->GetValue().IsValid()) sql += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); else sql += wxT("\n VALID UNTIL 'infinity'"); if (txtConnectionLimit->GetValue().Length() > 0) { sql += wxT(" CONNECTION LIMIT ") + txtConnectionLimit->GetValue(); } int cnt = lbRolesIn->GetCount(); wxString grants; if (cnt) { wxString roleName; for (pos = 0 ; pos < cnt ; pos++) { bool admin = false; roleName = lbRolesIn->GetString(pos); wxString opt = pgRole::GetOptStr(roleName); if (!opt.IsEmpty()) { roleName = roleName.BeforeLast('('); admin = true; } grants += wxT("GRANT ") + qtIdent(roleName) + wxT(" TO ") + qtIdent(name); if (admin) grants += opt; else grants += wxT(";\n"); } } sql += wxT(";\n") + grants; if (superuser && !chkUpdateCat->GetValue() && !connection->BackendMinimumVersion(9, 5)) sql += wxT("UPDATE pg_authid SET rolcatupdate=false WHERE rolname=") + qtDbString(name) + wxT(";\n"); } wxArrayString vars; wxString dbname; wxString parameter; wxString value; size_t index; if (role) { for (index = 0 ; index < role->GetVariables().GetCount() ; index++) vars.Add(role->GetVariables().Item(index)); } int cnt = lstVariables->GetItemCount(); // check for changed or added vars for (pos = 0 ; pos < cnt ; pos++) { wxString newDb = lstVariables->GetText(pos); wxString newVar = lstVariables->GetText(pos, 1); wxString newVal = lstVariables->GetText(pos, 2); wxString oldVal; for (index = 0 ; index < vars.GetCount() ; index += 3) { dbname = vars.Item(index); parameter = vars.Item(index + 1); value = vars.Item(index + 2); if (newDb == dbname && newVar == parameter) { oldVal = value; vars.RemoveAt(index); vars.RemoveAt(index); vars.RemoveAt(index); break; } } if (oldVal != newVal) { if (newDb.Length() == 0) sql += wxT("ALTER ROLE ") + qtIdent(name); else sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" IN DATABASE ") + newDb; if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) { sql += wxT("\n SET ") + newVar + wxT(" = '") + newVal + wxT("';\n"); } else { sql += wxT("\n SET ") + newVar + wxT(" = ") + newVal + wxT(";\n"); } } } // check for removed vars for (pos = 0 ; pos < (int)vars.GetCount() ; pos += 3) { dbname = vars.Item(pos); parameter = vars.Item(pos + 1); value = vars.Item(pos + 2); if (dbname.Length() == 0) { sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" RESET ") + parameter + wxT(";\n"); } else { sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" IN DATABASE ") + dbname + wxT(" RESET ") + parameter + wxT(";\n"); } } AppendComment(sql, wxT("ROLE"), 0, role); if (seclabelPage && connection->BackendMinimumVersion(9, 2)) sql += seclabelPage->GetSqlForSecLabels(wxT("ROLE"), qtIdent(name)); return sql; } void dlgRole::OnChange(wxCommandEvent &event) { CheckChange(); }