Index: ctl/ctlDefaultSecurityPanel.cpp =================================================================== --- ctl/ctlDefaultSecurityPanel.cpp (revision 0) +++ ctl/ctlDefaultSecurityPanel.cpp (revision 0) @@ -0,0 +1,783 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: $Id$ +// Copyright (C) 2002 - 2010, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlDefaultSecurityPanel.cpp - Panel with default security information +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlDefaultSecurityPanel.h" +#include "db/pgConn.h" +#include "dlg/dlgProperty.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "utils/sysLogger.h" + +#include + +defaultPrivilegesOn g_defPrivTables('r', wxT("TABLES"), wxT("arwdDxt")), + g_defPrivSequences('S', wxT("SEQUENCES"), wxT("rwU")), + g_defPrivFunctions('f', wxT("FUNCTIONS"), wxT("X")); + +static wxString GetPrivilegeName(wxChar privilege); +static bool findUserPrivs(wxString& , wxString&, wxString&); + +defaultPrivilegesOn::defaultPrivilegesOn(const wxChar privType, const wxString& privOn, const wxString& privileges) + : m_privilegeType(privType), m_privilegesOn(privOn), m_privileges(privileges) {} + +ctlDefaultSecurityPanel::ctlDefaultSecurityPanel(pgConn* conn, wxNotebook* nb, wxImageList* imgList) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize), m_connection(conn) +{ + nb->AddPage(this, _("Default Privileges")); + + wxFlexGridSizer *mainSizer = new wxFlexGridSizer(1, 1, 1, 1); + mainSizer->AddGrowableCol(0); + mainSizer->AddGrowableRow(0); + + wxStaticBox* sb = new wxStaticBox(this, -1, _("PRIVILEGES ON")); + wxBoxSizer* sbSizer = new wxStaticBoxSizer(sb, wxVERTICAL); + + wxFlexGridSizer *notebookSizer = new wxFlexGridSizer(1, 1, 1, 1); + notebookSizer->AddGrowableCol(0); + notebookSizer->AddGrowableRow(0); + + nbNotebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, 0, _("Privileges On")); + + new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivTables, imgList); + new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivSequences, imgList); + new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivFunctions, imgList); + + notebookSizer->Add(nbNotebook, 0, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT, 0); + sbSizer->Add(notebookSizer, 0, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT, 0); + mainSizer->Add(sbSizer, 0, wxEXPAND|wxALL, 2); + + this->SetSizer(mainSizer); + notebookSizer->Fit(this); + +} + + +void ctlDefaultSecurityPanel::UpdatePrivilegePages(const wxString& schemaOid) +{ + int nPageCount = nbNotebook->GetPageCount(); + for (int index=0; index < nPageCount; index++) + { + (dynamic_cast(nbNotebook->GetPage(index)))->Update(schemaOid); + } +} + + +wxString ctlDefaultSecurityPanel::GetDefaultPrivileges(const wxString& schemaName) +{ + wxString strDefPrivs; + int nPageCount = nbNotebook->GetPageCount(); + for (int index=0; index < nPageCount; index++) + { + strDefPrivs += (dynamic_cast(nbNotebook->GetPage(index)))->GetDefaultPrivileges(schemaName); + } + return strDefPrivs; +} + + +/////////////////////////////////////////////////////////////////////////////// +// ctlDefaultPrivilegesPanel +/////////////////////////////////////////////////////////////////////////////// + +BEGIN_EVENT_TABLE(ctlDefaultPrivilegesPanel, wxPanel) + EVT_LIST_ITEM_SELECTED(CTL_DEFLBPRIV, ctlDefaultPrivilegesPanel::OnPrivSelChange) + EVT_BUTTON(CTL_DEFADDPRIV, ctlDefaultPrivilegesPanel::OnAddPriv) + EVT_BUTTON(CTL_DEFDELPRIV, ctlDefaultPrivilegesPanel::OnDelPriv) + EVT_TEXT(CTL_DEFCBGROUP, ctlDefaultPrivilegesPanel::OnGroupChange) + EVT_COMBOBOX(CTL_DEFCBGROUP, ctlDefaultPrivilegesPanel::OnGroupChange) + EVT_CHECKBOX(CTL_DEFALLPRIV, ctlDefaultPrivilegesPanel::OnPrivCheckAll) + EVT_CHECKBOX(CTL_DEFALLPRIVGRANT, ctlDefaultPrivilegesPanel::OnPrivCheckAllGrant) + EVT_CHECKBOX(CTL_DEFPRIVCB, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB+2, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB+4, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB+6, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB+8, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB+10, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB+12, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB+14, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB+16, ctlDefaultPrivilegesPanel::OnPrivCheck) +END_EVENT_TABLE(); + +DEFINE_EVENT_TYPE(EVT_DEFAULTSECURITYPANEL_CHANGE) + +ctlDefaultPrivilegesPanel::ctlDefaultPrivilegesPanel(ctlDefaultSecurityPanel *defSecurityPanel, wxNotebook *nb, + defaultPrivilegesOn &privOn, wxImageList *imgList) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize), m_defPrivChanged(false), + m_privilegeType(privOn), m_defSecurityPanel(defSecurityPanel) +{ + + nb->AddPage(this, m_privilegeType.m_privilegesOn); + + allPrivileges=0; + privCheckboxes=0; + + privilegeCount=m_privilegeType.m_privileges.Length(); + + wxFlexGridSizer *item0 = new wxFlexGridSizer(3, 1, 5, 5); + item0->AddGrowableCol(0); + item0->AddGrowableRow(0); + + privCheckboxes = new wxCheckBox*[privilegeCount*2]; + + wxFlexGridSizer *itemSizer1 = new wxFlexGridSizer(1, 1, 5, 5); + itemSizer1->AddGrowableCol(0); + itemSizer1->AddGrowableRow(0); + + wxString strGroupLabel = settings->GetShowUsersForPrivileges() ? _("Group/User") : _("Group"); + + lbPrivileges = new ctlListView(this, CTL_DEFLBPRIV, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxLC_REPORT); + lbPrivileges->SetImageList(imgList, wxIMAGE_LIST_SMALL); + lbPrivileges->AddColumn(_("User/Group"), 50, wxLIST_FORMAT_LEFT); + lbPrivileges->AddColumn(_("Privileges"), 35, wxLIST_FORMAT_LEFT); + itemSizer1->Add(lbPrivileges, 0, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT, 4); + item0->Add(itemSizer1, 0, wxEXPAND|wxALL, 5); + + wxBoxSizer* itemSizer2 = new wxBoxSizer(wxHORIZONTAL); + btnAddPriv = new wxButton(this, CTL_DEFADDPRIV, _("Add/Change")); + itemSizer2->Add(btnAddPriv, 0, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT, 4); + btnDelPriv = new wxButton(this, CTL_DEFDELPRIV, _("Remove")); + itemSizer2->Add(btnDelPriv, 0, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT, 4); + item0->Add(itemSizer2, 0, wxEXPAND|wxALL, 0); + + wxStaticBox* sb = new wxStaticBox(this, -1, _("Privileges")); + wxBoxSizer* itemSizer3 = new wxStaticBoxSizer( sb, wxVERTICAL ); + item0->Add(itemSizer3, 0, wxEXPAND|wxALL, 5); + + wxBoxSizer* itemSizer4a = new wxBoxSizer(wxHORIZONTAL); + stGroup = new wxStaticText(this, CTL_DEFSTATICGROUP, strGroupLabel); + itemSizer4a->Add(stGroup, 0, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT, 4); + cbGroups = new ctlComboBox(this, CTL_DEFCBGROUP, wxDefaultPosition, wxDefaultSize); + itemSizer4a->Add(cbGroups, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT); + itemSizer3->Add(itemSizer4a, 0, wxEXPAND|wxALL, 0); + + /* border size depends on the plateform */ +#ifdef __WXMSW__ + int bordersize = 4; +#endif +#ifdef __WXMAC__ + int bordersize = 3; +#endif +#ifdef __WXGTK__ + int bordersize = 0; +#endif + + wxBoxSizer* itemSizer5 = new wxBoxSizer(wxHORIZONTAL); + allPrivileges = new wxCheckBox(this, CTL_DEFALLPRIV, wxT("ALL")); + itemSizer5->Add(allPrivileges, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT); + allPrivilegesGrant = new wxCheckBox(this, CTL_DEFALLPRIVGRANT, wxT("WITH GRANT OPTION")); + itemSizer5->Add(allPrivilegesGrant, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT); + allPrivilegesGrant->Disable(); + itemSizer3->Add(itemSizer5, 0, wxALL, bordersize); + + for (int index=0; index < privilegeCount; index++) + { + int i = index * 2; + wxChar privilege = m_privilegeType.m_privileges.GetChar(index); + wxString priv = GetPrivilegeName(privilege); + + wxCheckBox *cb; + wxBoxSizer* itemSizer6 = new wxBoxSizer(wxHORIZONTAL); + cb = new wxCheckBox(this, CTL_DEFPRIVCB + i, priv); + itemSizer6->Add(cb, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT); + privCheckboxes[i++] = cb; + cb = new wxCheckBox(this, CTL_DEFPRIVCB + i, wxT("WITH GRANT OPTION")); + itemSizer6->Add(cb, wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT); + cb->Disable(); + privCheckboxes[i] = cb; + itemSizer3->Add(itemSizer6, 0, wxALL, bordersize); + + } + + this->SetSizer(item0); + item0->Fit(this); +} + +static wxString GetPrivilegeName(wxChar privilege) +{ + switch(privilege) { + case 'a': + return wxT("INSERT"); + case 'r': + return wxT("SELECT"); + case 'w': + return wxT("UPDATE"); + case 'd': + return wxT("DELETE"); + case 'D': + return wxT("TRUNCATE"); + case 'x': + return wxT("REFERENCES"); + case 't': + return wxT("TRIGGER"); + case 'U': + return wxT("USAGE"); + case 'X': + return wxT("EXECUTE"); + default: + return wxT("UNKNOWN"); + } +} + +static bool findUserPrivs(wxString& strDefPrivs, wxString& strUser, wxString& strPriv) +{ + strUser = strPriv = wxT(""); + if (strDefPrivs.IsEmpty()) return false; + + bool startsWithQuote = false; + if (strDefPrivs.StartsWith(wxT("\""))) startsWithQuote = true; + + if (strDefPrivs.StartsWith(wxT("\"\""))) + { + wxChar currChar; + int quoteCount = 0; + int index = 0; + + currChar = strDefPrivs.GetChar(index); + + while (true) + { + if (currChar == wxT('=') && quoteCount%2 == 0) + break; + strUser += currChar; + currChar = strDefPrivs.GetChar(++index); + if (currChar == wxT('"')) quoteCount++; + } + strUser = strUser.SubString(2, strUser.Length() - 2); + strUser.Replace(wxT("\"\""), wxT("\""), true); + strDefPrivs = strDefPrivs.SubString(index + 1, strDefPrivs.Length()); + } + else + { + /* Remove first quote */ + if (startsWithQuote) strDefPrivs = strDefPrivs.SubString(1, strDefPrivs.Length()); + + int equalCharAt = strDefPrivs.Find(wxT('=')); + + if (equalCharAt != 0) + strUser = strDefPrivs.SubString(0, equalCharAt - 1); + else + strUser = wxT("PUBLIC"); + strDefPrivs = strDefPrivs.SubString(equalCharAt + 1, strDefPrivs.Length()); + } + + int slashCharAt = strDefPrivs.Find(wxT('/')); + strPriv = strDefPrivs.SubString(0, slashCharAt - 1); + + strDefPrivs = strDefPrivs.SubString(strPriv.Length() + 2, strDefPrivs.Length()); + + if (!strDefPrivs.StartsWith(wxT("\""))) + { + int commaCharAt = strDefPrivs.Find(wxT(',')); + if (commaCharAt == wxNOT_FOUND) strDefPrivs = wxT(""); + else strDefPrivs = strDefPrivs.SubString(commaCharAt + 1, strDefPrivs.Length()); + } + else + { + wxChar currChar; + int quoteCount = 0; + int index = 0; + + currChar = strDefPrivs.GetChar(index); + while (true) + { + if (currChar == wxT(',') && quoteCount%2 == 0) + break; + currChar = strDefPrivs.GetChar(++index); + if (currChar == wxT('"')) quoteCount++; + } + strDefPrivs = strDefPrivs.SubString(index, strDefPrivs.Length()); + } + + return true; +} + + +ctlDefaultPrivilegesPanel::~ctlDefaultPrivilegesPanel() +{ + cbGroups->Clear(); + if (privCheckboxes) + delete[] privCheckboxes; +} + +// Find the privileges for the selected user from the map +// and select the check-boxes accordingly +bool ctlDefaultPrivilegesPanel::PrivCheckBoxUpdate(wxString& strUser) +{ + int index = 0; + wxString strKey = strUser; + defPrivHash::iterator priv = m_privileges.find(strKey); + bool canGrant = CanGrant(); + + if (priv == m_privileges.end()) + { + m_currentSelectedPriv = NULL; + allPrivileges->SetValue(true); + allPrivilegesGrant->Enable(canGrant); + for (; index < privilegeCount; index++) + { + privCheckboxes[index*2]->Enable(); + privCheckboxes[index*2]->SetValue(true); + privCheckboxes[index*2 + 1]->Enable(canGrant); + } + return false; + } + else + { + allPrivileges->SetValue(false); + allPrivilegesGrant->SetValue(false); + allPrivilegesGrant->Enable(false); + } + + wxString currentPrivileges = priv->second.m_modified ? priv->second.m_newPriv : priv->second.m_origPriv; + m_currentSelectedPriv = &priv->second; + + for (index = 0; index < privilegeCount; index++) + { + int privAt = currentPrivileges.Find(m_privilegeType.m_privileges.GetChar(index)); + if (privAt != wxNOT_FOUND) + { + privCheckboxes[index*2]->SetValue(true); + privCheckboxes[index*2 + 1]->Enable(canGrant); + if (canGrant && (unsigned int)privAt < currentPrivileges.Length() - 1 && currentPrivileges.GetChar(privAt + 1) == wxT('*')) + privCheckboxes[index*2 + 1]->SetValue(true); + else + privCheckboxes[index*2 + 1]->SetValue(false); + } + else + { + privCheckboxes[index*2]->SetValue(false); + privCheckboxes[index*2 + 1]->SetValue(false); + privCheckboxes[index*2 + 1]->Disable(); + } + } + return false; +} + + +bool ctlDefaultPrivilegesPanel::CanGrant() +{ + if (cbGroups->GetValue() == wxT("PUBLIC")) + return false; + return true; +} + + +void ctlDefaultPrivilegesPanel::OnGroupChange(wxCommandEvent &ev) +{ + cbGroups->GuessSelection(ev); + + wxString strRole = cbGroups->GetValue(); + + if (strRole.IsEmpty()) + return; + + btnAddPriv->Enable(!PrivCheckBoxUpdate(strRole)); +} + + +void ctlDefaultPrivilegesPanel::OnPrivCheckAll(wxCommandEvent& ev) +{ + bool all = allPrivileges->GetValue(); + allPrivilegesGrant->Enable(all && CanGrant()); + + for (int i = 0; i < privilegeCount; i++) + { + privCheckboxes[i*2]->SetValue(all); + CheckGrantOpt(i); + } +} + +void ctlDefaultPrivilegesPanel::OnPrivCheckAllGrant(wxCommandEvent& ev) +{ + bool grant=allPrivilegesGrant->GetValue(); + for (int i=0 ; i < privilegeCount ; i++) + privCheckboxes[i*2+1]->SetValue(grant); +} + + +void ctlDefaultPrivilegesPanel::OnPrivCheck(wxCommandEvent& ev) +{ + int id=(ev.GetId()-CTL_DEFPRIVCB) /2; + CheckGrantOpt(id); + btnAddPriv->Enable(); + if (!privCheckboxes[id*2]->GetValue()) + allPrivileges->SetValue(false); +} + + +void ctlDefaultPrivilegesPanel::CheckGrantOpt(int id) +{ + bool canGrant=(privCheckboxes[id*2]->GetValue() && CanGrant()); + if (canGrant) + privCheckboxes[id*2+1]->Enable(true); + else + { + privCheckboxes[id*2+1]->SetValue(false); + privCheckboxes[id*2+1]->Disable(); + } + btnAddPriv->Enable(); +} + + +void ctlDefaultPrivilegesPanel::OnDelPriv(wxCommandEvent &ev) +{ + int pos; + wxString strRole; + if ((pos = lbPrivileges->GetFirstSelected()) == -1) + return; + + wxListItem info; + info.m_itemId = pos; + info.m_col = 0; + info.m_mask = wxLIST_MASK_TEXT; + + if (lbPrivileges->GetItem(info)) + strRole = info.m_text; + + wxString strKey = strRole; + defPrivHash::iterator priv = m_privileges.find(strKey); + + if (priv != m_privileges.end()) + { + priv->second.m_modified = true; + priv->second.m_newPriv = wxT(""); + if (m_currentSelectedPriv == &priv->second) + PrivCheckBoxUpdate(strRole); + } + + lbPrivileges->DeleteCurrentItem(); + + ev.Skip(); +} + + +void ctlDefaultPrivilegesPanel::OnAddPriv(wxCommandEvent &ev) +{ + wxString strRole, strPriv; + bool isPresent = m_currentSelectedPriv != NULL && + ((m_currentSelectedPriv->m_modified && + !m_currentSelectedPriv->m_newPriv.IsEmpty()) || + (!m_currentSelectedPriv->m_modified)); + + if (allPrivileges && allPrivileges->GetValue()) + { + if (allPrivilegesGrant->GetValue()) + { + for (int index = 0; index < privilegeCount; index++) + { + strPriv += m_privilegeType.m_privileges.GetChar(index); + strPriv += wxT('*'); + } + } + else + strPriv = m_privilegeType.m_privileges; + } + else + { + for (int index = 0; index < privilegeCount; index++) + { + if (privCheckboxes[index*2]->GetValue()) + { + strPriv += m_privilegeType.m_privileges.GetChar(index); + if(privCheckboxes[index*2 + 1]->IsEnabled() && privCheckboxes[index*2 + 1]->GetValue()) + strPriv += wxT('*'); + } + } + } + + if (!m_currentSelectedPriv) + { + strRole = cbGroups->GetGuessedStringSelection(); + + defPrivilege priv; + priv.m_username = strRole; + priv.m_origPriv = wxT(""); + priv.m_modified = true; + priv.m_newPriv = strPriv; + + wxString strKey = strRole; + m_privileges[strKey] = priv; + + defPrivHash::iterator itr = m_privileges.find(strKey); + m_currentSelectedPriv = &itr->second; + } + else + { + if (m_currentSelectedPriv->m_modified ? + m_currentSelectedPriv->m_newPriv == strPriv : + m_currentSelectedPriv->m_origPriv == strPriv) + { + ev.Skip(); + return; + } + strRole = m_currentSelectedPriv->m_username; + m_currentSelectedPriv->m_modified = true; + m_currentSelectedPriv->m_newPriv = strPriv; + } + + if (!isPresent) + { + int icon; + if (strRole.IsSameAs(wxT("PUBLIC"), true)) + icon = PGICON_PUBLIC; + else if (strRole.StartsWith(wxT("GROUP "))) + icon = groupFactory.GetIconId(); + else + icon = userFactory.GetIconId(); + long pos = lbPrivileges->GetItemCount(); + + lbPrivileges->InsertItem(pos, strRole, icon); + lbPrivileges->SetItem(pos, 1, strPriv); + } + else + { + long nCount = lbPrivileges->GetItemCount(); + wxListItem info; + + for (int index=0; index < nCount; index++) + { + wxString strTempRole; + + info.m_itemId = index; + info.m_col = 0; + info.m_mask = wxLIST_MASK_TEXT; + + if (lbPrivileges->GetItem(info)) + strTempRole = info.m_text; + + if (strTempRole == strRole) + { + lbPrivileges->SetItem(index, 1, strPriv); + break; + } + } + } + m_defPrivChanged = true; + + ev.Skip(); +} + + +void ctlDefaultPrivilegesPanel::OnPrivSelChange(wxListEvent &ev) +{ + if (!cbGroups) + return; + btnAddPriv->Enable(); +} + + +void ctlDefaultPrivilegesPanel::Update(const wxString& schemaOid) +{ + unsigned int index=0; + + cbGroups->Clear(); + lbPrivileges->DeleteAllItems(); + + m_privileges.clear(); + + cbGroups->Append(wxT("PUBLIC")); + + for (; index < m_defSecurityPanel->m_groups.GetCount(); index++) + cbGroups->Append(m_defSecurityPanel->m_groups[index]); + + if (m_defSecurityPanel->m_connection && !schemaOid.IsEmpty()) + { + pgSet *setPrivileges = m_defSecurityPanel->m_connection->ExecuteSet(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + schemaOid + wxT(" AND defaclobjtype='") + wxString(m_privilegeType.m_privilegeType) + wxT("'")); + if (setPrivileges) + { + while(!setPrivileges->Eof()) + { + wxString strDefPrivs = setPrivileges->GetVal(0); + + wxString strUser, strPriv; + strDefPrivs.Replace(wxT("\\\""), wxT("\""), true); + strDefPrivs.Replace(wxT("\\\\"), wxT("\\"), true); + + // Removing starting brace '{' and ending brace '}' + strDefPrivs = strDefPrivs.SubString(1, strDefPrivs.Length() - 1); + + long pos = 0; + + while (findUserPrivs(strDefPrivs, strUser, strPriv)) + { + int icon; + if (strUser.IsSameAs(wxT("PUBLIC"), true)) + icon = PGICON_PUBLIC; + else if (cbGroups->FindString(strUser) != wxNOT_FOUND) + icon = userFactory.GetIconId(); + else if (cbGroups->FindString(wxT("GROUP ") + strUser) != wxNOT_FOUND) + { + icon = groupFactory.GetIconId(); + strUser = wxT("GROUP ") + strUser; + } + else + continue; + + defPrivilege priv; + priv.m_username = strUser; + priv.m_origPriv = strPriv; + priv.m_modified = false; + priv.m_newPriv = wxT(""); + + /* + fprintf(stdout, " SCHEMA:%s\n\tUSER:%s\n\tPRIV:%s\n", (const char*)strSchema.mb_str(wxConvUTF8), + (const char*)strUser.mb_str(wxConvUTF8), + (const char*)strPriv.mb_str(wxConvUTF8)); + */ + + wxString strKey = strUser; + m_privileges[strKey] = priv; + + pos = lbPrivileges->GetItemCount(); + + lbPrivileges->InsertItem(pos, strUser, icon); + lbPrivileges->SetItem(pos, 1, strPriv); + + strUser = wxT(""); + strPriv = wxT(""); + pos++; + } + + setPrivileges->MoveNext(); + } + delete setPrivileges; + } + } +} + + +wxString ctlDefaultPrivilegesPanel::GetDefaultPrivileges(const wxString& schemaName) +{ + if(!m_defPrivChanged) + return wxT(""); + + wxString strDefPrivs; + defPrivHash::iterator itr = m_privileges.begin(); + + for (; itr != m_privileges.end(); itr++) + { + if(itr->second.m_modified) + { + wxString strGrant, strRevoke, strGrantOption, strRevokeGrantOption; + for (int index=0; index < privilegeCount; index++) + { + bool inOrigPriv = false, inNewPriv = false, grantOptInOrigPriv = false, grantOptInNewPriv = false; + wxChar privChar = m_privilegeType.m_privileges.GetChar(index); + int privAt = itr->second.m_origPriv.Find(privChar); + if (privAt != wxNOT_FOUND) + { + inOrigPriv = true; + if ((unsigned int)privAt < itr->second.m_origPriv.Length() - 1 && + itr->second.m_origPriv.GetChar(privAt + 1) == wxT('*')) + grantOptInOrigPriv = true; + } + + privAt = itr->second.m_newPriv.Find(privChar); + if (privAt != wxNOT_FOUND) + { + inNewPriv = true; + if ((unsigned int)privAt < itr->second.m_newPriv.Length() - 1 && + itr->second.m_newPriv.GetChar(privAt + 1) == wxT('*')) + grantOptInNewPriv = true; + } + if (inOrigPriv || inNewPriv || grantOptInOrigPriv || grantOptInNewPriv) + { + wxString strPrivilege = GetPrivilegeName(privChar); + if (!inOrigPriv && inNewPriv) + { + // GRANT PRIVILEGES + if (!grantOptInNewPriv) + strGrant += strPrivilege + wxT(", "); + // GRANT PRVILEGES WITH GRANT OPTION + else + strGrantOption += strPrivilege + wxT(", "); + } + // REVOKE PRIVILEGES + else if (inOrigPriv && !inNewPriv) + strRevoke += strPrivilege + wxT(", "); + else if (inOrigPriv && inNewPriv) + { + // REVOKE ONLY 'WITH GRANT OPTION' + if(grantOptInOrigPriv && !grantOptInNewPriv) + strRevokeGrantOption += strPrivilege + wxT(", "); + // GRANT PRVILEGES WITH GRANT OPTION + else if (!grantOptInOrigPriv && grantOptInNewPriv) + strGrantOption += strPrivilege + wxT(", "); + } + } + } + + wxString strRole = itr->second.m_username; + if (strRole.StartsWith(wxT("GROUP "))) + { + strRole = strRole.SubString(6, strRole.Length()); + strRole = qtIdent(strRole); + } + else if (strRole != wxT("PUBLIC")) + strRole = qtIdent(strRole); + + bool isModified = false; + wxString strAltDefPriv; + + if (!schemaName.IsEmpty()) + strAltDefPriv = wxT("ALTER DEFAULT PRIVILEGES IN SCHEMA ") + schemaName; + else + strAltDefPriv = wxT("ALTER DEFAULT PRIVILEGES "); + + // Remove trailing comma character + if (!strGrant.IsEmpty()) + { + isModified = true; + + strGrant = strGrant.SubString(0, strGrant.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n GRANT ") + strGrant + wxT(" ON ") + m_privilegeType.m_privilegesOn + + wxT("\n TO ") + strRole + wxT(";\n"); + } + if (!strGrantOption.IsEmpty()) + { + isModified = true; + strGrantOption = strGrantOption.SubString(0, strGrantOption.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n GRANT ") + strGrantOption + wxT(" ON ") + m_privilegeType.m_privilegesOn + + wxT("\n TO ") + strRole + wxT(" WITH GRANT OPTION;\n"); + } + if (!strRevoke.IsEmpty()) + { + isModified = true; + strRevoke = strRevoke.SubString(0, strRevoke.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n REVOKE ") + strRevoke + wxT(" ON ") + m_privilegeType.m_privilegesOn + + wxT("\n FROM ") + strRole + wxT(";\n"); + } + if (!strRevokeGrantOption.IsEmpty()) + { + isModified = true; + strRevokeGrantOption = strRevokeGrantOption.SubString(0, strRevokeGrantOption.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n REVOKE GRANT OPTION FOR ") + strRevokeGrantOption + wxT(" ON ") + m_privilegeType.m_privilegesOn + + wxT("\n FROM ") + strRole + wxT(";\n"); + } + if (isModified) + strDefPrivs += wxT("\n"); + } + } + return strDefPrivs; +} + + Index: ctl/module.mk =================================================================== --- ctl/module.mk (revision 8295) +++ ctl/module.mk (working copy) @@ -19,6 +19,7 @@ $(srcdir)/ctl/ctlSQLBox.cpp \ $(srcdir)/ctl/ctlSQLGrid.cpp \ $(srcdir)/ctl/ctlSQLResult.cpp \ + $(srcdir)/ctl/ctlDefaultSecurityPanel.cpp \ $(srcdir)/ctl/ctlSecurityPanel.cpp \ $(srcdir)/ctl/ctlTree.cpp \ $(srcdir)/ctl/explainCanvas.cpp \ Index: include/ctl/ctlDefaultSecurityPanel.h =================================================================== --- include/ctl/ctlDefaultSecurityPanel.h (revision 0) +++ include/ctl/ctlDefaultSecurityPanel.h (revision 0) @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: $Id$ +// Copyright (C) 2002 - 2010, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlDefaultSecurityPanel.h - Panel with default security information +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef CTL_DEFDEFSECPANEL_H +#define CTL_DEFDEFSECPANEL_H + +#include +#include +#include + +enum +{ + CTL_DEFPROPSQL=500, + CTL_DEFMSG, + CTL_DEFLBPRIV, + CTL_DEFSTATICGROUP, + CTL_DEFCBGROUP, + CTL_DEFADDPRIV, + CTL_DEFDELPRIV, + CTL_DEFALLPRIV, + CTL_DEFALLPRIVGRANT, + CTL_DEFPRIVCB // base for all privilege checkboxes, must be last +}; + +class defaultPrivilegesOn +{ +public: + defaultPrivilegesOn(const wxChar, const wxString&, const wxString&); + + wxChar m_privilegeType; + wxString m_privilegesOn; + wxString m_privileges; + wxArrayString m_privilegesList; +}; + + +DECLARE_EVENT_TYPE(EVT_DEFAULTSECURITYPANEL_CHANGE, -1) + +class pgConn; +class ctlDefaultPrivilegesPanel; +class dlgDefaultSecurityProperty; + +class ctlDefaultSecurityPanel : public wxPanel +{ + +public: + ctlDefaultSecurityPanel(pgConn* , wxNotebook* , wxImageList*); + + wxString GetDefaultPrivileges(const wxString& schemaName); + void UpdatePrivilegePages(const wxString& schemaOid); + +protected: + wxNotebook *nbNotebook; + pgConn *m_connection; + + wxArrayString m_groups; + wxArrayString m_namespaces; + + friend class ctlDefaultPrivilegesPanel; + friend class dlgDefaultSecurityProperty; +}; + +class ctlDefaultPrivilegesPanel : public wxPanel +{ + +public: + + ctlDefaultPrivilegesPanel(ctlDefaultSecurityPanel *, wxNotebook *, defaultPrivilegesOn&, wxImageList *); + ~ctlDefaultPrivilegesPanel(); + + void Update(const wxString& schemaOid); + wxString GetDefaultPrivileges(const wxString& schemaName); + +protected: + + typedef struct { + wxString m_username; + wxString m_origPriv; + wxString m_newPriv; + bool m_modified; + } defPrivilege; + +public: + WX_DECLARE_STRING_HASH_MAP(defPrivilege, defPrivHash); + +protected: + + bool m_defPrivChanged; + int privilegeCount; + defaultPrivilegesOn m_privilegeType; + defPrivHash m_privileges; + defPrivilege *m_currentSelectedPriv; + + ctlDefaultSecurityPanel *m_defSecurityPanel; + wxButton *btnAddPriv, *btnDelPriv; + wxCheckBox **privCheckboxes; + wxCheckBox *allPrivileges, *allPrivilegesGrant; + ctlListView *lbPrivileges; + ctlComboBox *cbGroups; + wxStaticText *stGroup; + + void OnPrivSelChange(wxListEvent &ev); + void OnAddPriv(wxCommandEvent& ev); + void OnGroupChange(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent& ev); + void OnPrivCheck(wxCommandEvent& ev); + void OnPrivCheckAll(wxCommandEvent& ev); + void OnPrivCheckAllGrant(wxCommandEvent& ev); + + bool PrivCheckBoxUpdate(wxString& strUser); + void CheckGrantOpt(int index); + bool CanGrant(); + + DECLARE_EVENT_TABLE() +}; + +#endif + Index: include/ctl/module.mk =================================================================== --- include/ctl/module.mk (revision 8295) +++ include/ctl/module.mk (working copy) @@ -16,6 +16,7 @@ $(srcdir)/include/ctl/ctlComboBox.h \ $(srcdir)/include/ctl/ctlListView.h \ $(srcdir)/include/ctl/ctlMenuToolbar.h \ + $(srcdir)/include/ctl/ctlDefaultSecurityPanel.h \ $(srcdir)/include/ctl/ctlSecurityPanel.h \ $(srcdir)/include/ctl/ctlSQLBox.h \ $(srcdir)/include/ctl/ctlSQLGrid.h \ Index: include/dlg/dlgDatabase.h =================================================================== --- include/dlg/dlgDatabase.h (revision 8295) +++ include/dlg/dlgDatabase.h (working copy) @@ -17,7 +17,7 @@ class pgDatabase; -class dlgDatabase : public dlgSecurityProperty +class dlgDatabase : public dlgDefaultSecurityProperty { public: dlgDatabase(pgaFactory *factory, frmMain *frame, pgDatabase *db); @@ -54,6 +54,7 @@ void OnOK(wxCommandEvent &ev); void SetupVarEditor(int var); + bool executeDDLSql(const wxString& strSql); bool dirtyVars; Index: include/dlg/dlgSchema.h =================================================================== --- include/dlg/dlgSchema.h (revision 8295) +++ include/dlg/dlgSchema.h (working copy) @@ -17,7 +17,7 @@ class pgSchema; -class dlgSchema : public dlgSecurityProperty +class dlgSchema : public dlgDefaultSecurityProperty { public: dlgSchema(pgaFactory *factory, frmMain *frame, pgSchema *db); Index: include/dlg/dlgProperty.h =================================================================== --- include/dlg/dlgProperty.h (revision 8295) +++ include/dlg/dlgProperty.h (working copy) @@ -23,7 +23,6 @@ class pgSchema; class pgTable; class frmMain; -class ctlSecurityPanel; class pgaFactory; #define stComment CTRL_STATIC("stComment") @@ -45,6 +44,23 @@ }; + +/* + * We need the definition of replClientData in dlgDatabase too, to hack + * the execution of default privileges statements (sqls) before getting + * disconnected. + */ +class replClientData : public wxClientData +{ +public: + replClientData(const wxString &c, long s, long ma, long mi) { cluster=c; setId=s; majorVer=ma; minorVer=mi; } + wxString cluster; + long setId; + long majorVer; + long minorVer; +}; + + WX_DEFINE_ARRAY(dataType *, dataTypeCache); class dlgProperty : public DialogWithHelp @@ -67,7 +83,7 @@ virtual void CreateAdditionalPages(); virtual wxString GetHelpPage() const; virtual wxString GetHelpPage(bool forCreate) const { return wxEmptyString; } - void SetConnection(pgConn *conn) { connection=conn; } + virtual void SetConnection(pgConn *conn) { connection=conn; } void SetDatabase(pgDatabase *db); void SetDatatypeCache(dataTypeCache cache); virtual int Go(bool modal=false); @@ -212,20 +228,52 @@ void OnChangeSize(wxSizeEvent &ev); #endif + ctlSecurityPanel *securityPage; + private: void OnAddPriv(wxCommandEvent& ev); void OnDelPriv(wxCommandEvent& ev); bool securityChanged; - ctlSecurityPanel *securityPage; wxArrayString currentAcl; DECLARE_EVENT_TABLE() }; +class ctlDefaultSecurityPanel; +class dlgDefaultSecurityProperty : public dlgSecurityProperty +{ +protected: + dlgDefaultSecurityProperty(pgaFactory *factory, frmMain *frame, pgObject *obj, const wxString &resName, + const wxString& privilegeList, const char *privilegeChar, bool createDefPrivPanel=true); + + virtual int Go(bool modal=false, const wxString& schemaOid=wxT("0::OID")); + virtual wxString GetHelpPage() const; + + void EnableOK(bool enable); + wxString GetDefaultPrivileges(const wxString& schemaName = wxT("")); + void AddGroups(ctlComboBox *comboBox=0); + void AddUsers(ctlComboBox *comboBox=0); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + bool defaultSecurityChanged; + +private: + void OnAddPriv(wxCommandEvent& ev); + void OnDelPriv(wxCommandEvent& ev); + + ctlDefaultSecurityPanel *defaultSecurityPage; + + DECLARE_EVENT_TABLE() +}; + + + class dlgAgentProperty : public dlgProperty { public: Index: pgAdmin3.vcproj =================================================================== --- pgAdmin3.vcproj (revision 8295) +++ pgAdmin3.vcproj (working copy) @@ -404,6 +404,10 @@ > + + @@ -959,6 +963,10 @@ > + + Index: dlg/dlgProperty.cpp =================================================================== --- dlg/dlgProperty.cpp (revision 8295) +++ dlg/dlgProperty.cpp (working copy) @@ -22,6 +22,7 @@ #include "utils/misc.h" #include "utils/pgDefs.h" #include "ctl/ctlSecurityPanel.h" +#include "ctl/ctlDefaultSecurityPanel.h" // Images #include "images/properties.xpm" @@ -59,17 +60,6 @@ #include "schema/pgUser.h" -class replClientData : public wxClientData -{ -public: - replClientData(const wxString &c, long s, long ma, long mi) { cluster=c; setId=s; majorVer=ma; minorVer=mi; } - wxString cluster; - long setId; - long majorVer; - long minorVer; -}; - - void dataType::SetOid(OID id) { oid = id; @@ -240,12 +230,6 @@ } -void dlgSecurityProperty::SetPrivilegesLayout() -{ - securityPage->lbPrivileges->GetParent()->Layout(); -} - - int dlgProperty::Go(bool modal) { wxASSERT(factory != 0); @@ -1522,6 +1506,10 @@ #endif END_EVENT_TABLE(); +void dlgSecurityProperty::SetPrivilegesLayout() +{ + securityPage->lbPrivileges->GetParent()->Layout(); +} dlgSecurityProperty::dlgSecurityProperty(pgaFactory *f, frmMain *frame, pgObject *obj, const wxString &resName, const wxString& privList, const char *privChar) : dlgProperty(f, frame, resName) @@ -1713,14 +1701,12 @@ } - - wxString dlgSecurityProperty::GetGrant(const wxString &allPattern, const wxString &grantObject) { if (securityPage) return securityPage->GetGrant(allPattern, grantObject, ¤tAcl); else - return wxString(); + return wxString(); } bool dlgSecurityProperty::DisablePrivilege(const wxString &priv) @@ -1735,6 +1721,159 @@ ///////////////////////////////////////////////////////////////////////////// +BEGIN_EVENT_TABLE(dlgDefaultSecurityProperty, dlgSecurityProperty) + EVT_BUTTON(CTL_DEFADDPRIV, dlgDefaultSecurityProperty::OnAddPriv) + EVT_BUTTON(CTL_DEFDELPRIV, dlgDefaultSecurityProperty::OnDelPriv) +#ifdef __WXMAC__ + EVT_SIZE( dlgDefaultSecurityProperty::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgDefaultSecurityProperty::dlgDefaultSecurityProperty(pgaFactory *f, frmMain *frame, pgObject *obj, const wxString &resName, const wxString& privList, const char *privChar, bool createDefPrivPanel) + : dlgSecurityProperty(f, frame, obj, resName, privList, privChar), defaultSecurityChanged(false) +{ + pgConn *myConn = obj ? obj->GetConnection() : connection; + if ((!obj || obj->CanCreate()) && createDefPrivPanel && myConn && myConn->BackendMinimumVersion(9, 0)) + defaultSecurityPage = new ctlDefaultSecurityPanel(connection, nbNotebook, frame->GetImageList()); + else + defaultSecurityPage = NULL; +} + + +void dlgDefaultSecurityProperty::AddGroups(ctlComboBox *comboBox) +{ + if (!((securityPage && securityPage->cbGroups) || comboBox || defaultSecurityPage)) + return; + + pgSet *set=connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (set) + { + while (!set->Eof()) + { + if (securityPage && securityPage->cbGroups) + securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0)); + + if (comboBox) + comboBox->Append(set->GetVal(0)); + + if (defaultSecurityPage) + defaultSecurityPage->m_groups.Add(wxT("GROUP ") + set->GetVal(0)); + + set->MoveNext(); + } + delete set; + } +} + + +void dlgDefaultSecurityProperty::AddUsers(ctlComboBox *combobox) +{ + if ((securityPage && securityPage->cbGroups) || defaultSecurityPage || combobox) + { + wxString strFetchUserQuery = + connection->BackendMinimumVersion(8, 1) ? + wxT("SELECT rolname FROM pg_roles WHERE rolcanlogin ORDER BY 1") : + wxT("SELECT usename FROM pg_user ORDER BY 1"); + + pgSet *set=connection->ExecuteSet(strFetchUserQuery); + if (set) + { + while (!set->Eof()) + { + if (settings->GetShowUsersForPrivileges()) + { + if (securityPage && securityPage->cbGroups) + securityPage->cbGroups->Append(set->GetVal(0)); + + if (defaultSecurityPage) + defaultSecurityPage->m_groups.Add(set->GetVal(0)); + } + + if (combobox) + combobox->Append(set->GetVal(0)); + + set->MoveNext(); + } + } + } +} + +#ifdef __WXMAC__ +void dlgDefaultSecurityProperty::OnChangeSize(wxSizeEvent &ev) +{ + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgDefaultSecurityProperty::EnableOK(bool enable) +{ + // Don't enable the OK button if the object isn't yet created, + // leave that to the object dialog. + if (GetObject()) + { + wxString sql=GetSql(); + if (sql.IsEmpty()) + { + enable=false; + } + else + enable=true; + } + dlgSecurityProperty::EnableOK(enable); +} + + +void dlgDefaultSecurityProperty::OnAddPriv(wxCommandEvent &ev) +{ + defaultSecurityChanged=true; + EnableOK(btnOK->IsEnabled()); +} + + +void dlgDefaultSecurityProperty::OnDelPriv(wxCommandEvent &ev) +{ + defaultSecurityChanged=true; + EnableOK(btnOK->IsEnabled()); +} + +wxString dlgDefaultSecurityProperty::GetDefaultPrivileges(const wxString& schemaName) +{ + if (defaultSecurityChanged) + return defaultSecurityPage->GetDefaultPrivileges(schemaName); + return wxT(""); +} + +int dlgDefaultSecurityProperty::Go(bool modal, const wxString& schemaOid) +{ + if (defaultSecurityPage) + defaultSecurityPage->UpdatePrivilegePages(schemaOid); + return dlgSecurityProperty::Go(modal); +} + +wxString dlgDefaultSecurityProperty::GetHelpPage() const +{ + int nDiff = nbNotebook->GetPageCount() - nbNotebook->GetSelection(); + + switch (nDiff) + { + case 3: + return wxT("pg/sql-grant"); + case 2: + return wxT("pg/sql-alterdefaultprivileges"); + default: + return dlgProperty::GetHelpPage(); + } +} + +///////////////////////////////////////////////////////////////////////////// + + BEGIN_EVENT_TABLE(dlgAgentProperty, dlgProperty) EVT_BUTTON (wxID_OK, dlgAgentProperty::OnOK) END_EVENT_TABLE(); @@ -2006,3 +2145,4 @@ // so it's Good Enough (tm) for now. return obj != 0 && !obj->IsCreatedBy(serverFactory.GetCollectionFactory()); } + Index: dlg/dlgDatabase.cpp =================================================================== --- dlg/dlgDatabase.cpp (revision 8295) +++ dlg/dlgDatabase.cpp (working copy) @@ -19,6 +19,7 @@ #include "utils/misc.h" #include "dlg/dlgDatabase.h" #include "schema/pgDatabase.h" +#include "ctl/ctlDefaultSecurityPanel.h" // pointer to controls @@ -47,13 +48,13 @@ if (dlg && !node) { // use the server's connection to avoid "template1 in use" - dlg->connection=parent->GetConnection(); + dlg->SetConnection(parent->GetConnection()); } return dlg; } -BEGIN_EVENT_TABLE(dlgDatabase, dlgSecurityProperty) +BEGIN_EVENT_TABLE(dlgDatabase, dlgDefaultSecurityProperty) EVT_TEXT(XRCID("txtPath"), dlgProperty::OnChange) EVT_TEXT(XRCID("cbTablespace"), dlgProperty::OnChange) EVT_COMBOBOX(XRCID("cbTablespace"), dlgProperty::OnChange) @@ -77,7 +78,7 @@ dlgDatabase::dlgDatabase(pgaFactory *f, frmMain *frame, pgDatabase *node) -: dlgSecurityProperty(f, frame, node, wxT("dlgDatabase"), wxT("CREATE,TEMP,CONNECT"), "CTc") +: dlgDefaultSecurityProperty(f, frame, node, wxT("dlgDatabase"), wxT("CREATE,TEMP,CONNECT"), "CTc", node != NULL ? true : false) { database=node; schemaRestrictionOk=true; @@ -98,7 +99,7 @@ { if (nbNotebook->GetSelection() == 1) return wxT("pg/runtime-config"); - return dlgSecurityProperty::GetHelpPage(); + return dlgDefaultSecurityProperty::GetHelpPage(); } @@ -110,10 +111,12 @@ AddGroups(cbOwner); AddUsers(cbOwner); - if (connection->BackendMinimumVersion(8,5)) + if (connection->BackendMinimumVersion(9, 0)) { cbVarUsername->Append(wxT("")); - AddUsers(cbVarUsername); + // AddUsers function of dlgDefaultSecurity has already been called. + // Hence, calling dlgProperty::AddUsers instead of that. + dlgProperty::AddUsers(cbVarUsername); } else cbVarUsername->Enable(false); @@ -162,7 +165,7 @@ cbVarname->SetSelection(0); - if (connection->BackendMinimumVersion(8,5)) + if (connection->BackendMinimumVersion(9, 0)) { cbVarUsername->SetSelection(0); } @@ -313,7 +316,7 @@ SetupVarEditor(1); - return dlgSecurityProperty::Go(modal); + return dlgDefaultSecurityProperty::Go(modal); } @@ -364,11 +367,75 @@ { database->iSetSchemaRestriction(txtSchemaRestr->GetValue().Trim()); settings->Write(wxString::Format(wxT("Servers/%d/Databases/%s/SchemaRestriction"), database->GetServer()->GetServerIndex(), database->GetName().c_str()), txtSchemaRestr->GetValue().Trim()); + + /* + * The connection from the database will get disconnected before execution of any + * sql statements for the database. + * + * Hence, we need to hack the execution of the default privileges statements(sqls) + * before getting disconnected from this database. So that, these statements will + * run against the current database connection, and not against the server connection. + */ + // defaultSecurityChanged will be true only for PostgreSQL 9.0 or later + if (defaultSecurityChanged) + { + wxString strDefPrivs = GetDefaultPrivileges(); + if (!executeDDLSql(strDefPrivs)) + { + EnableOK(true); + return; + } + defaultSecurityChanged = false; + } } - dlgSecurityProperty::OnOK(ev); + dlgDefaultSecurityProperty::OnOK(ev); } +/* + * Execute any ddl statement (sql) + * + * - Hacked to execute any DDL statement (sql) for dlgDatabse against this database, because + * connection for this database object is getting disconnected, and replaced by the server + * connection, before execution of any statements (sqls) in dlgPropery::apply function called + * from dlgPropery::OnOK event handler. + */ +bool dlgDatabase::executeDDLSql(const wxString& strSql) +{ + pgConn *myConn = connection; + if (!strSql.IsEmpty()) + { + wxString tmp; + if (cbClusterSet && cbClusterSet->GetSelection() > 0) + { + replClientData *data=(replClientData*)cbClusterSet->GetClientData(cbClusterSet->GetSelection()); + + if (data->majorVer > 1 || (data->majorVer == 1 && data->minorVer >= 2)) + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_prepare(") + NumToStr(data->setId) + wxT(", 0);\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(strSql) + wxT(", 0);\n"); + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(strSql) + wxT(", 0);\n"); + } + } + else + tmp = strSql; + + if (!myConn->ExecuteVoid(tmp)) + // error message is displayed inside ExecuteVoid + return false; + } + return true; +} + + void dlgDatabase::CheckChange() { bool enable=true; @@ -690,6 +757,9 @@ + wxT(" RESET ") + varname + wxT(";\n"); } } + + if (connection->BackendMinimumVersion(9, 0) && defaultSecurityChanged) + sql += GetDefaultPrivileges(); } else { Index: dlg/dlgSchema.cpp =================================================================== --- dlg/dlgSchema.cpp (revision 8295) +++ dlg/dlgSchema.cpp (working copy) @@ -21,7 +21,7 @@ // pointer to controls -BEGIN_EVENT_TABLE(dlgSchema, dlgSecurityProperty) +BEGIN_EVENT_TABLE(dlgSchema, dlgDefaultSecurityProperty) END_EVENT_TABLE(); dlgProperty *pgSchemaBaseFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) @@ -30,7 +30,7 @@ } dlgSchema::dlgSchema(pgaFactory *f, frmMain *frame, pgSchema *node) -: dlgSecurityProperty(f, frame, node, wxT("dlgSchema"), wxT("USAGE,CREATE"), "UC") +: dlgDefaultSecurityProperty(f, frame, node, wxT("dlgSchema"), wxT("USAGE,CREATE"), "UC") { schema=node; } @@ -44,6 +44,7 @@ int dlgSchema::Go(bool modal) { + wxString schemaOid; if (!schema) cbOwner->Append(wxT("")); @@ -52,7 +53,6 @@ if (schema) { // edit mode - if (!connection->BackendMinimumVersion(7, 5)) cbOwner->Disable(); @@ -61,13 +61,14 @@ cbOwner->Disable(); txtName->Disable(); } + schemaOid = schema->GetOidStr(); } else { // create mode } - return dlgSecurityProperty::Go(modal); + return dlgDefaultSecurityProperty::Go(modal, schemaOid); } @@ -115,26 +116,29 @@ wxString dlgSchema::GetSql() { wxString sql, name; - name=GetName(); + name = qtIdent(GetName()); if (schema) { // edit mode AppendNameChange(sql); - AppendOwnerChange(sql, wxT("SCHEMA ") + qtIdent(name)); + AppendOwnerChange(sql, wxT("SCHEMA ") + name); } else { // create mode - sql = wxT("CREATE SCHEMA ") + qtIdent(name); + sql = wxT("CREATE SCHEMA ") + name; AppendIfFilled(sql, wxT("\n AUTHORIZATION "), qtIdent(cbOwner->GetValue())); sql += wxT(";\n"); } AppendComment(sql, wxT("SCHEMA"), 0, schema); - sql += GetGrant(wxT("UC"), wxT("SCHEMA ") + qtIdent(name)); + sql += GetGrant(wxT("UC"), wxT("SCHEMA ") + name); + if (connection->BackendMinimumVersion(9, 0) && defaultSecurityChanged) + sql += GetDefaultPrivileges(name); + return sql; } Index: ui/dlgSchema.xrc =================================================================== --- ui/dlgSchema.xrc (revision 8295) +++ ui/dlgSchema.xrc (working copy) @@ -2,7 +2,7 @@ - 220,250d + 220,280d 1 @@ -10,7 +10,7 @@ 0 - 216,225d + 216,260d 0 Index: ui/xrcDialogs.cpp =================================================================== --- ui/xrcDialogs.cpp (revision 8295) +++ ui/xrcDialogs.cpp (working copy) @@ -13,14 +13,6 @@ #include #include -#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 - #define XRC_ADD_FILE(name, data, size, mime) \ - wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) -#else - #define XRC_ADD_FILE(name, data, size, mime) \ - wxMemoryFSHandler::AddFile(name, data, size) -#endif - static size_t xml_res_size_0 = 2378; static unsigned char xml_res_file_0[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, @@ -2352,7 +2344,7 @@ 101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, 107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, 62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50, -53,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +54,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, 115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, 62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, @@ -15666,7 +15658,7 @@ 32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, 101,61,34,100,108,103,83,99,104,101,109,97,34,62,10,32,32,32,32,60,116, 105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44, -50,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +50,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, 101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, 69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, 69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,124,119,120, @@ -15682,7 +15674,7 @@ 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, 34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,50,53, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,54,48, 100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, 108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, @@ -29408,75 +29400,75 @@ else wxFileSystem::AddHandler(new wxMemoryFSHandler); } - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgAddFavourite.xrc"), xml_res_file_0, xml_res_size_0, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgAggregate.xrc"), xml_res_file_1, xml_res_size_1, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgCast.xrc"), xml_res_file_2, xml_res_size_2, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgCheck.xrc"), xml_res_file_3, xml_res_size_3, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgColumn.xrc"), xml_res_file_4, xml_res_size_4, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgConnect.xrc"), xml_res_file_5, xml_res_size_5, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgConversion.xrc"), xml_res_file_6, xml_res_size_6, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgDatabase.xrc"), xml_res_file_7, xml_res_size_7, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgDirectDbg.xrc"), xml_res_file_8, xml_res_size_8, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgDomain.xrc"), xml_res_file_9, xml_res_size_9, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgEditGridOptions.xrc"), xml_res_file_10, xml_res_size_10, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgExtTable.xrc"), xml_res_file_11, xml_res_size_11, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgFindReplace.xrc"), xml_res_file_12, xml_res_size_12, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgForeignKey.xrc"), xml_res_file_13, xml_res_size_13, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgFunction.xrc"), xml_res_file_14, xml_res_size_14, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgGroup.xrc"), xml_res_file_15, xml_res_size_15, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgHbaConfig.xrc"), xml_res_file_16, xml_res_size_16, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgIndex.xrc"), xml_res_file_17, xml_res_size_17, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgIndexConstraint.xrc"), xml_res_file_18, xml_res_size_18, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgJob.xrc"), xml_res_file_19, xml_res_size_19, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgLanguage.xrc"), xml_res_file_20, xml_res_size_20, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgMainConfig.xrc"), xml_res_file_21, xml_res_size_21, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgManageFavourites.xrc"), xml_res_file_22, xml_res_size_22, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgManageMacros.xrc"), xml_res_file_23, xml_res_size_23, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgOperator.xrc"), xml_res_file_24, xml_res_size_24, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgPackage.xrc"), xml_res_file_25, xml_res_size_25, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgPgpassConfig.xrc"), xml_res_file_26, xml_res_size_26, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgReassignDropOwned.xrc"), xml_res_file_27, xml_res_size_27, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepCluster.xrc"), xml_res_file_28, xml_res_size_28, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepClusterUpgrade.xrc"), xml_res_file_29, xml_res_size_29, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepListen.xrc"), xml_res_file_30, xml_res_size_30, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepNode.xrc"), xml_res_file_31, xml_res_size_31, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepPath.xrc"), xml_res_file_32, xml_res_size_32, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSequence.xrc"), xml_res_file_33, xml_res_size_33, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSet.xrc"), xml_res_file_34, xml_res_size_34, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSetMerge.xrc"), xml_res_file_35, xml_res_size_35, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSetMove.xrc"), xml_res_file_36, xml_res_size_36, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSubscription.xrc"), xml_res_file_37, xml_res_size_37, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRepTable.xrc"), xml_res_file_38, xml_res_size_38, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRole.xrc"), xml_res_file_39, xml_res_size_39, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgRule.xrc"), xml_res_file_40, xml_res_size_40, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgSchedule.xrc"), xml_res_file_41, xml_res_size_41, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgSchema.xrc"), xml_res_file_42, xml_res_size_42, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgSelectConnection.xrc"), xml_res_file_43, xml_res_size_43, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgSequence.xrc"), xml_res_file_44, xml_res_size_44, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgServer.xrc"), xml_res_file_45, xml_res_size_45, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgStep.xrc"), xml_res_file_46, xml_res_size_46, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgSynonym.xrc"), xml_res_file_47, xml_res_size_47, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgTable.xrc"), xml_res_file_48, xml_res_size_48, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgTablespace.xrc"), xml_res_file_49, xml_res_size_49, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgTextSearchConfiguration.xrc"), xml_res_file_50, xml_res_size_50, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgTextSearchDictionary.xrc"), xml_res_file_51, xml_res_size_51, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgTextSearchParser.xrc"), xml_res_file_52, xml_res_size_52, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgTextSearchTemplate.xrc"), xml_res_file_53, xml_res_size_53, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgTrigger.xrc"), xml_res_file_54, xml_res_size_54, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgType.xrc"), xml_res_file_55, xml_res_size_55, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgUser.xrc"), xml_res_file_56, xml_res_size_56, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$dlgView.xrc"), xml_res_file_57, xml_res_size_57, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmBackup.xrc"), xml_res_file_58, xml_res_size_58, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmBackupGlobals.xrc"), xml_res_file_59, xml_res_size_59, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmBackupServer.xrc"), xml_res_file_60, xml_res_size_60, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmExport.xrc"), xml_res_file_61, xml_res_size_61, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmGrantWizard.xrc"), xml_res_file_62, xml_res_size_62, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmHint.xrc"), xml_res_file_63, xml_res_size_63, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmMaintenance.xrc"), xml_res_file_64, xml_res_size_64, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmOptions.xrc"), xml_res_file_65, xml_res_size_65, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmPassword.xrc"), xml_res_file_66, xml_res_size_66, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmReport.xrc"), xml_res_file_67, xml_res_size_67, _T("text/xml")); - XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$frmRestore.xrc"), xml_res_file_68, xml_res_size_68, _T("text/xml")); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgAddFavourite.xrc"), xml_res_file_0, xml_res_size_0); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgAggregate.xrc"), xml_res_file_1, xml_res_size_1); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgCast.xrc"), xml_res_file_2, xml_res_size_2); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgCheck.xrc"), xml_res_file_3, xml_res_size_3); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgColumn.xrc"), xml_res_file_4, xml_res_size_4); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgConnect.xrc"), xml_res_file_5, xml_res_size_5); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgConversion.xrc"), xml_res_file_6, xml_res_size_6); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgDatabase.xrc"), xml_res_file_7, xml_res_size_7); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgDirectDbg.xrc"), xml_res_file_8, xml_res_size_8); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgDomain.xrc"), xml_res_file_9, xml_res_size_9); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgEditGridOptions.xrc"), xml_res_file_10, xml_res_size_10); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgExtTable.xrc"), xml_res_file_11, xml_res_size_11); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgFindReplace.xrc"), xml_res_file_12, xml_res_size_12); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgForeignKey.xrc"), xml_res_file_13, xml_res_size_13); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgFunction.xrc"), xml_res_file_14, xml_res_size_14); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgGroup.xrc"), xml_res_file_15, xml_res_size_15); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgHbaConfig.xrc"), xml_res_file_16, xml_res_size_16); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgIndex.xrc"), xml_res_file_17, xml_res_size_17); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgIndexConstraint.xrc"), xml_res_file_18, xml_res_size_18); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgJob.xrc"), xml_res_file_19, xml_res_size_19); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgLanguage.xrc"), xml_res_file_20, xml_res_size_20); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgMainConfig.xrc"), xml_res_file_21, xml_res_size_21); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgManageFavourites.xrc"), xml_res_file_22, xml_res_size_22); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgManageMacros.xrc"), xml_res_file_23, xml_res_size_23); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgOperator.xrc"), xml_res_file_24, xml_res_size_24); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgPackage.xrc"), xml_res_file_25, xml_res_size_25); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgPgpassConfig.xrc"), xml_res_file_26, xml_res_size_26); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgReassignDropOwned.xrc"), xml_res_file_27, xml_res_size_27); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepCluster.xrc"), xml_res_file_28, xml_res_size_28); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepClusterUpgrade.xrc"), xml_res_file_29, xml_res_size_29); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepListen.xrc"), xml_res_file_30, xml_res_size_30); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepNode.xrc"), xml_res_file_31, xml_res_size_31); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepPath.xrc"), xml_res_file_32, xml_res_size_32); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSequence.xrc"), xml_res_file_33, xml_res_size_33); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSet.xrc"), xml_res_file_34, xml_res_size_34); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSetMerge.xrc"), xml_res_file_35, xml_res_size_35); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSetMove.xrc"), xml_res_file_36, xml_res_size_36); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepSubscription.xrc"), xml_res_file_37, xml_res_size_37); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRepTable.xrc"), xml_res_file_38, xml_res_size_38); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRole.xrc"), xml_res_file_39, xml_res_size_39); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgRule.xrc"), xml_res_file_40, xml_res_size_40); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgSchedule.xrc"), xml_res_file_41, xml_res_size_41); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgSchema.xrc"), xml_res_file_42, xml_res_size_42); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgSelectConnection.xrc"), xml_res_file_43, xml_res_size_43); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgSequence.xrc"), xml_res_file_44, xml_res_size_44); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgServer.xrc"), xml_res_file_45, xml_res_size_45); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgStep.xrc"), xml_res_file_46, xml_res_size_46); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgSynonym.xrc"), xml_res_file_47, xml_res_size_47); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgTable.xrc"), xml_res_file_48, xml_res_size_48); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgTablespace.xrc"), xml_res_file_49, xml_res_size_49); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgTextSearchConfiguration.xrc"), xml_res_file_50, xml_res_size_50); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgTextSearchDictionary.xrc"), xml_res_file_51, xml_res_size_51); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgTextSearchParser.xrc"), xml_res_file_52, xml_res_size_52); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgTextSearchTemplate.xrc"), xml_res_file_53, xml_res_size_53); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgTrigger.xrc"), xml_res_file_54, xml_res_size_54); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgType.xrc"), xml_res_file_55, xml_res_size_55); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgUser.xrc"), xml_res_file_56, xml_res_size_56); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$dlgView.xrc"), xml_res_file_57, xml_res_size_57); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmBackup.xrc"), xml_res_file_58, xml_res_size_58); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmBackupGlobals.xrc"), xml_res_file_59, xml_res_size_59); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmBackupServer.xrc"), xml_res_file_60, xml_res_size_60); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmExport.xrc"), xml_res_file_61, xml_res_size_61); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmGrantWizard.xrc"), xml_res_file_62, xml_res_size_62); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmHint.xrc"), xml_res_file_63, xml_res_size_63); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmMaintenance.xrc"), xml_res_file_64, xml_res_size_64); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmOptions.xrc"), xml_res_file_65, xml_res_size_65); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmPassword.xrc"), xml_res_file_66, xml_res_size_66); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmReport.xrc"), xml_res_file_67, xml_res_size_67); + wxMemoryFSHandler::AddFile(wxT("XRC_resource/xrcDialogs.cpp$frmRestore.xrc"), xml_res_file_68, xml_res_size_68); wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$dlgAddFavourite.xrc")); wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$dlgAggregate.xrc")); wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$dlgCast.xrc")); Index: ui/dlgDatabase.xrc =================================================================== --- ui/dlgDatabase.xrc (revision 8295) +++ ui/dlgDatabase.xrc (working copy) @@ -10,7 +10,7 @@ 0 - 216,255d + 216,260d 0