Hi, Simple patch to add FDW object support. A new icon would be great.
Comments? -- Guillaume http://www.postgresql.fr http://dalibo.com
From 3bb0af0dc1c26489b723a268eedd722a6a06683f Mon Sep 17 00:00:00 2001 From: Guillaume Lelarge <[email protected]> Date: Sun, 6 Feb 2011 11:59:39 +0100 Subject: [PATCH] Support for Foreign Data Wrapper object. --- pgadmin/dlg/dlgForeignDataWrapper.cpp | 343 ++++++++++++++++++++++ pgadmin/dlg/module.mk | 1 + pgadmin/frm/frmOptions.cpp | 1 + pgadmin/include/dlg/dlgForeignDataWrapper.h | 51 ++++ pgadmin/include/dlg/module.mk | 1 + pgadmin/include/images/foreigndatawrapper-sm.xpm | 57 ++++ pgadmin/include/images/foreigndatawrapper.xpm | 64 ++++ pgadmin/include/images/foreigndatawrappers.xpm | 65 ++++ pgadmin/include/images/module.mk | 1 + pgadmin/include/precomp.h | 2 + pgadmin/include/schema/module.mk | 1 + pgadmin/include/schema/pgForeignDataWrapper.h | 77 +++++ pgadmin/include/utils/pgDefs.h | 1 + pgadmin/schema/module.mk | 1 + pgadmin/schema/pgDatabase.cpp | 5 + pgadmin/schema/pgForeignDataWrapper.cpp | 169 +++++++++++ pgadmin/ui/dlgForeignDataWrapper.xrc | 255 ++++++++++++++++ pgadmin/ui/module.mk | 1 + pgadmin/utils/sysSettings.cpp | 6 + 19 files changed, 1102 insertions(+), 0 deletions(-) create mode 100644 pgadmin/dlg/dlgForeignDataWrapper.cpp create mode 100644 pgadmin/include/dlg/dlgForeignDataWrapper.h create mode 100644 pgadmin/include/images/foreigndatawrapper-sm.xpm create mode 100644 pgadmin/include/images/foreigndatawrapper.xpm create mode 100644 pgadmin/include/images/foreigndatawrappers.xpm create mode 100644 pgadmin/include/schema/pgForeignDataWrapper.h create mode 100644 pgadmin/schema/pgForeignDataWrapper.cpp create mode 100644 pgadmin/ui/dlgForeignDataWrapper.xrc diff --git a/pgadmin/dlg/dlgForeignDataWrapper.cpp b/pgadmin/dlg/dlgForeignDataWrapper.cpp new file mode 100644 index 0000000..3c368d2 --- /dev/null +++ b/pgadmin/dlg/dlgForeignDataWrapper.cpp @@ -0,0 +1,343 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: $Id$ +// Copyright (C) 2002 - 2010, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignDataWrapper.cpp - PostgreSQL ForeignDataWrapper Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include <wx/wx.h> + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgForeignDataWrapper.h" +#include "schema/pgForeignDataWrapper.h" + + +// pointer to controls +#define cbValidator CTRL_COMBOBOX("cbValidator") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +dlgProperty *pgForeignDataWrapperFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignDataWrapper(this, frame, (pgForeignDataWrapper *)node); +} + + +BEGIN_EVENT_TABLE(dlgForeignDataWrapper, dlgSecurityProperty) + EVT_TEXT(XRCID("cbValidator"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbValidator"), dlgProperty::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignDataWrapper::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgForeignDataWrapper::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgForeignDataWrapper::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgForeignDataWrapper::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgForeignDataWrapper::dlgForeignDataWrapper(pgaFactory *f, frmMain *frame, pgForeignDataWrapper *node) + : dlgSecurityProperty(f, frame, node, wxT("dlgForeignDataWrapper"), wxT("USAGE"), "U") +{ + fdw = node; +} + + +pgObject *dlgForeignDataWrapper::GetObject() +{ + return fdw; +} + + +int dlgForeignDataWrapper::Go(bool modal) +{ + // Fill owner combobox + AddGroups(); + AddUsers(cbOwner); + + // Fill validator combobox + cbValidator->Append(wxT("")); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, proname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" WHERE proargtypes[0]=") + NumToStr(PGOID_TYPE_TEXT_ARRAY) + + wxT(" AND proargtypes[1]=") + NumToStr(PGOID_TYPE_OID)); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbValidator->Append(procname); + set->MoveNext(); + } + delete set; + } + cbValidator->SetSelection(0); + + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (fdw) + { + // edit mode + txtName->Disable(); + wxString val = fdw->GetValidatorProc(); + if (!val.IsEmpty()) + { + for (int i = 0 ; i < cbValidator->GetCount() ; i++) + { + if (cbValidator->GetString(i) == val) + cbValidator->SetSelection(i); + } + } + + wxString options = fdw->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + } + else + { + // create mode + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgForeignDataWrapper::CreateObject(pgCollection *collection) +{ + wxString name = txtName->GetValue(); + + pgObject *obj = foreignDataWrapperFactory.CreateObjects(collection, 0, wxT("\n AND fdwname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgForeignDataWrapper::CheckChange() +{ + bool didChange = true; + wxString name = txtName->GetValue(); + if (fdw) + { + didChange = name != fdw->GetName() + || txtComment->GetValue() != fdw->GetComment() + || cbOwner->GetValue() != fdw->GetOwner() + || GetOptionsSql().Length() > 0; + EnableOK(didChange); + } + else + { + + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } +} + + + +void dlgForeignDataWrapper::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgForeignDataWrapper::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgForeignDataWrapper::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgForeignDataWrapper::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgForeignDataWrapper::GetOptionsSql() +{ + wxString options = fdw->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = fdw->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgForeignDataWrapper::GetSql() +{ + wxString sql, name; + name = txtName->GetValue(); + + if (fdw) + { + // edit mode + if (cbValidator->GetValue() != fdw->GetValidatorProc()) + { + sql = wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n VALIDATOR ") + qtIdent(cbValidator->GetValue()); + } + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + name + + wxT(" OPTIONS (") + sqloptions + wxT(")"); + } + + AppendOwnerChange(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + } + else + { + // create mode + sql = wxT("CREATE FOREIGN DATA WRAPPER ") + qtIdent(name); + AppendIfFilled(sql, wxT("\n VALIDATOR "), qtIdent(cbValidator->GetValue())); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + AppendOwnerNew(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + } + + sql += GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + AppendComment(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name), 0, fdw); + + return sql; +} + + diff --git a/pgadmin/dlg/module.mk b/pgadmin/dlg/module.mk index f5eda0b..d1001fc 100644 --- a/pgadmin/dlg/module.mk +++ b/pgadmin/dlg/module.mk @@ -22,6 +22,7 @@ pgadmin3_SOURCES += \ $(srcdir)/dlg/dlgDomain.cpp \ $(srcdir)/dlg/dlgEditGridOptions.cpp \ $(srcdir)/dlg/dlgFindReplace.cpp \ + $(srcdir)/dlg/dlgForeignDataWrapper.cpp \ $(srcdir)/dlg/dlgForeignKey.cpp \ $(srcdir)/dlg/dlgFunction.cpp \ $(srcdir)/dlg/dlgGroup.cpp \ diff --git a/pgadmin/frm/frmOptions.cpp b/pgadmin/frm/frmOptions.cpp index 2f45bf2..46447d4 100644 --- a/pgadmin/frm/frmOptions.cpp +++ b/pgadmin/frm/frmOptions.cpp @@ -327,6 +327,7 @@ frmOptions::frmOptions(frmMain *parent) lstDisplay->Append(_("Resource Queues")); lstDisplay->Append(_("Catalogs")); lstDisplay->Append(_("Casts")); + lstDisplay->Append(_("Foreign Data Wrappers")); lstDisplay->Append(_("Languages")); lstDisplay->Append(_("Synonyms")); lstDisplay->Append(_("Schemas")); diff --git a/pgadmin/include/dlg/dlgForeignDataWrapper.h b/pgadmin/include/dlg/dlgForeignDataWrapper.h new file mode 100644 index 0000000..34919c1 --- /dev/null +++ b/pgadmin/include/dlg/dlgForeignDataWrapper.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: $Id$ +// Copyright (C) 2002 - 2010, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignDataWrapper.h - Foreign Data Wrapper property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNDATAWRAPPERPROP +#define __DLG_FOREIGNDATAWRAPPERPROP + +#include "dlg/dlgProperty.h" + +class pgForeignDataWrapper; + +class dlgForeignDataWrapper : public dlgSecurityProperty +{ +public: + dlgForeignDataWrapper(pgaFactory *factory, frmMain *frame, pgForeignDataWrapper *db); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgForeignDataWrapper *fdw; + + void OnChange(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/pgadmin/include/dlg/module.mk b/pgadmin/include/dlg/module.mk index e21c45f..77ea2c3 100644 --- a/pgadmin/include/dlg/module.mk +++ b/pgadmin/include/dlg/module.mk @@ -22,6 +22,7 @@ pgadmin3_SOURCES += \ $(srcdir)/include/dlg/dlgDomain.h \ $(srcdir)/include/dlg/dlgEditGridOptions.h \ $(srcdir)/include/dlg/dlgFindReplace.h \ + $(srcdir)/include/dlg/dlgForeignDataWrapper.h \ $(srcdir)/include/dlg/dlgForeignKey.h \ $(srcdir)/include/dlg/dlgFunction.h \ $(srcdir)/include/dlg/dlgGroup.h \ diff --git a/pgadmin/include/images/foreigndatawrapper-sm.xpm b/pgadmin/include/images/foreigndatawrapper-sm.xpm new file mode 100644 index 0000000..c4866c6 --- /dev/null +++ b/pgadmin/include/images/foreigndatawrapper-sm.xpm @@ -0,0 +1,57 @@ +/* XPM */ +static const char * foreigndatawrapper_sm_xpm[] = { +"16 16 38 1", +" c None", +". c #EBD986", +"+ c #E0C259", +"@ c #D8B129", +"# c #F7EFD4", +"$ c #D8B31F", +"% c #E3CD39", +"& c #EDE24F", +"* c #F4F25F", +"= c #F4EAC5", +"- c #DAB723", +"; c #ECDE4B", +"> c #F8F967", +", c #E6D069", +"' c #E8D643", +") c #F8FA69", +"! c #E8D180", +"~ c #DAB632", +"{ c #F4EE5F", +"] c #F9FA6B", +"^ c #DAB638", +"/ c #F4EF60", +"( c #FAFB6D", +"_ c #E9D647", +": c #FBFB6F", +"< c #DBB825", +"[ c #EEE053", +"} c #FCFC72", +"| c #D9B320", +"1 c #E6CE3F", +"2 c #F1E559", +"3 c #FAF56C", +"4 c #FDFC74", +"5 c #D6AD1E", +"6 c #D4AA16", +"7 c #FEFD76", +"8 c #E6CD76", +"9 c #FFFD78", +" ", +" ", +" .+@@+ # ", +" $%&**&%$= ", +" -;>>>>>>;- ", +" ,'))))))))'! ", +" ~{]]]]]]]]{^ ", +" ^/((((((((/^ ", +" !_::::::::_! ", +" <[}}}}}}[< ", +" =|123344| ", +" +56776 ", +" 8696 ", +" 68 ", +" ", +" "}; diff --git a/pgadmin/include/images/foreigndatawrapper.xpm b/pgadmin/include/images/foreigndatawrapper.xpm new file mode 100644 index 0000000..7deffbd --- /dev/null +++ b/pgadmin/include/images/foreigndatawrapper.xpm @@ -0,0 +1,64 @@ +/* XPM */ +static const char * foreigndatawrapper_xpm[] = { +"16 16 45 1", +" c None", +". c #E2C561", +"+ c #DAB534", +"@ c #D5AB1A", +"# c #EDDB9C", +"$ c #D9B420", +"% c #E3CB38", +"& c #ECE04C", +"* c #F2EF5C", +"= c #F6F865", +"- c #F0E2B0", +"; c #DFC32F", +"> c #EFE552", +", c #F8F966", +"' c #DDBE2B", +") c #F2EB5A", +"! c #F8F968", +"~ c #E5CB71", +"{ c #EADB48", +"] c #F9FA69", +"^ c #D9B432", +"/ c #F5F061", +"( c #F9FA6B", +"_ c #F5F162", +": c #FAFB6D", +"< c #ECDB4B", +"[ c #FBFB6E", +"} c #DEBF2D", +"| c #F5ED60", +"1 c #FCFB70", +"2 c #EDDC9E", +"3 c #E1C433", +"4 c #F2E75B", +"5 c #FCFC72", +"6 c #D9B522", +"7 c #E5CD3E", +"8 c #F0E256", +"9 c #F8F168", +"0 c #FCFB73", +"a c #FDFC74", +"b c #D4AA16", +"c c #FEFD75", +"d c #E6CD76", +"e c #FEFD77", +"f c #FFFD78", +" .+@+.# ", +" $%&*=*&%$- ", +" ;>,,,,,,,>; ", +" ')!!!!!!!!!)' ", +"~{]]]]]]]]]]]{~ ", +"^/(((((((((((/^ ", +"^_:::::::::::_^ ", +"~<[[[[[[[[[[[<~ ", +" }|111111111|} ", +" 234555555553 ", +" -67890aaaab ", +" #.+@bcccb ", +" dbeeb ", +" dbfb ", +" dbd ", +" "}; diff --git a/pgadmin/include/images/foreigndatawrappers.xpm b/pgadmin/include/images/foreigndatawrappers.xpm new file mode 100644 index 0000000..42a902e --- /dev/null +++ b/pgadmin/include/images/foreigndatawrappers.xpm @@ -0,0 +1,65 @@ +/* XPM */ +static const char * foreigndatawrappers_xpm[] = { +"16 16 46 1", +" c None", +". c #ECDA99", +"+ c #E0C259", +"@ c #D8B129", +"# c #D8B31F", +"$ c #E3CD39", +"% c #EDE24F", +"& c #F4F25F", +"* c #F4EAC5", +"= c #DAB723", +"- c #ECDE4B", +"; c #F8F967", +"> c #F4F05E", +", c #E8D643", +"' c #DEC12D", +") c #D7B11D", +"! c #DBB925", +"~ c #E8D180", +"{ c #F8FA69", +"] c #EFE654", +"^ c #DAB638", +"/ c #F4EE5F", +"( c #F3ED5D", +"_ c #F4EF60", +": c #E5CF3E", +"< c #E9D647", +"[ c #DAB623", +"} c #DBB825", +"| c #D8B21F", +"1 c #D6AE1B", +"2 c #F9FA6B", +"3 c #F4E9C4", +"4 c #FAFB6D", +"5 c #FBFB6F", +"6 c #EEE053", +"7 c #FCFC72", +"8 c #D9B320", +"9 c #E6CE3F", +"0 c #F1E559", +"a c #FAF56C", +"b c #FDFC74", +"c c #D6AD1E", +"d c #D4AA16", +"e c #FEFD76", +"f c #E6CD76", +"g c #FFFD78", +" .+@@+. ", +" #$%&&%$#* ", +" =-;>,'))!) ", +"~,{]#$%&&%$# ", +"^/(=-;>,'))!) ", +"^_:,{]#$%&&%$# ", +"~<[/(=-;;;;;;-= ", +" }|_:,{{{{{{{{,~", +" 1<[/22222222/^", +" 3}|_44444444_^", +" *1<55555555<~", +" }67777776} ", +" *890aabb8 ", +" +cdeed ", +" fdgd ", +" fdf "}; diff --git a/pgadmin/include/images/module.mk b/pgadmin/include/images/module.mk index be7dd53..44472b4 100644 --- a/pgadmin/include/images/module.mk +++ b/pgadmin/include/images/module.mk @@ -107,6 +107,7 @@ pgadmin3_SOURCES += \ $(srcdir)/include/images/file_open.xpm \ $(srcdir)/include/images/file_save.xpm \ $(srcdir)/include/images/folder.xpm \ + $(srcdir)/include/images/foreigndatawrapper.xpm \ $(srcdir)/include/images/foreignkey.xpm \ $(srcdir)/include/images/forward.xpm \ $(srcdir)/include/images/function.xpm \ diff --git a/pgadmin/include/precomp.h b/pgadmin/include/precomp.h index e10eb92..c5bb2ee 100644 --- a/pgadmin/include/precomp.h +++ b/pgadmin/include/precomp.h @@ -78,6 +78,7 @@ #include "dlg/dlgDomain.h" #include "dlg/dlgEditGridOptions.h" #include "dlg/dlgFindReplace.h" +#include "dlg/dlgForeignDataWrapper.h" #include "dlg/dlgForeignKey.h" #include "dlg/dlgFunction.h" #include "dlg/dlgGroup.h" @@ -169,6 +170,7 @@ #include "schema/pgDatabase.h" #include "schema/pgDatatype.h" #include "schema/pgDomain.h" +#include "schema/pgForeignDataWrapper.h" #include "schema/pgForeignKey.h" #include "schema/pgFunction.h" #include "schema/pgGroup.h" diff --git a/pgadmin/include/schema/module.mk b/pgadmin/include/schema/module.mk index d44d6a0..92970dc 100644 --- a/pgadmin/include/schema/module.mk +++ b/pgadmin/include/schema/module.mk @@ -26,6 +26,7 @@ pgadmin3_SOURCES += \ $(srcdir)/include/schema/pgDatabase.h \ $(srcdir)/include/schema/pgDatatype.h \ $(srcdir)/include/schema/pgDomain.h \ + $(srcdir)/include/schema/pgForeignDataWrapper.h \ $(srcdir)/include/schema/pgForeignKey.h \ $(srcdir)/include/schema/pgFunction.h \ $(srcdir)/include/schema/pgGroup.h \ diff --git a/pgadmin/include/schema/pgForeignDataWrapper.h b/pgadmin/include/schema/pgForeignDataWrapper.h new file mode 100644 index 0000000..543103f --- /dev/null +++ b/pgadmin/include/schema/pgForeignDataWrapper.h @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: $Id$ +// Copyright (C) 2002 - 2010, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignDataWrapper.h PostgreSQL Foreign Data Wrapper +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNDATAWRAPPER_H +#define PGFOREIGNDATAWRAPPER_H + +#include "pgDatabase.h" + +class pgCollection; +class pgForeignDataWrapperFactory : public pgDatabaseObjFactory +{ +public: + pgForeignDataWrapperFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgForeignDataWrapperFactory foreignDataWrapperFactory; + +class pgForeignDataWrapper : public pgDatabaseObject +{ +public: + pgForeignDataWrapper(const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + + wxString GetValidatorProc() const + { + return validatorProc; + } + void iSetValidatorProc(const wxString &s) + { + validatorProc = s; + } + wxString GetOptions() const + { + return options; + } + wxString GetCreateOptions(); + void iSetOptions(const wxString &s) + { + options = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString validatorProc, options; +}; + +#endif diff --git a/pgadmin/include/utils/pgDefs.h b/pgadmin/include/utils/pgDefs.h index 38d83d9..893bd03 100644 --- a/pgadmin/include/utils/pgDefs.h +++ b/pgadmin/include/utils/pgDefs.h @@ -36,6 +36,7 @@ #define PGOID_TYPE_FLOAT8 701L #define PGOID_TYPE_MONEY 790L #define PGOID_TYPE_CHAR_ARRAY 1002L +#define PGOID_TYPE_TEXT_ARRAY 1009L #define PGOID_TYPE_BPCHAR_ARRAY 1014L #define PGOID_TYPE_VARCHAR_ARRAY 1015L #define PGOID_TYPE_BPCHAR 1042L diff --git a/pgadmin/schema/module.mk b/pgadmin/schema/module.mk index d193aec..ae6b506 100644 --- a/pgadmin/schema/module.mk +++ b/pgadmin/schema/module.mk @@ -28,6 +28,7 @@ pgadmin3_SOURCES += \ $(subdir)/pgDatabase.cpp \ $(subdir)/pgDatatype.cpp \ $(subdir)/pgDomain.cpp \ + $(subdir)/pgForeignDataWrapper.cpp \ $(subdir)/pgForeignKey.cpp \ $(subdir)/pgFunction.cpp \ $(subdir)/pgGroup.cpp \ diff --git a/pgadmin/schema/pgDatabase.cpp b/pgadmin/schema/pgDatabase.cpp index 3528aa9..6a7492d 100644 --- a/pgadmin/schema/pgDatabase.cpp +++ b/pgadmin/schema/pgDatabase.cpp @@ -19,6 +19,7 @@ #include "frm/frmMain.h" #include "schema/edbSynonym.h" #include "schema/pgCast.h" +#include "schema/pgForeignDataWrapper.h" #include "schema/pgLanguage.h" #include "schema/pgSchema.h" #include "slony/slCluster.h" @@ -130,6 +131,8 @@ wxMenu *pgDatabase::GetNewMenu() { if (settings->GetDisplayOption(_("Casts"))) castFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Foreign Data Wrappers"))) + foreignDataWrapperFactory.AppendMenu(menu); if (settings->GetDisplayOption(_("Languages"))) languageFactory.AppendMenu(menu); if (settings->GetDisplayOption(_("Synonyms")) && GetConnection()->EdbMinimumVersion(8, 0)) @@ -559,6 +562,8 @@ void pgDatabase::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *pr browser->AppendCollection(this, catalogFactory); if (settings->GetDisplayOption(_("Casts"))) browser->AppendCollection(this, castFactory); + if (settings->GetDisplayOption(_("Foreign Data Wrappers"))) + browser->AppendCollection(this, foreignDataWrapperFactory); if (settings->GetDisplayOption(_("Languages"))) browser->AppendCollection(this, languageFactory); if (settings->GetDisplayOption(_("Synonyms")) && connection()->EdbMinimumVersion(8, 0)) diff --git a/pgadmin/schema/pgForeignDataWrapper.cpp b/pgadmin/schema/pgForeignDataWrapper.cpp new file mode 100644 index 0000000..26d4bda --- /dev/null +++ b/pgadmin/schema/pgForeignDataWrapper.cpp @@ -0,0 +1,169 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: $Id$ +// Copyright (C) 2002 - 2010, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignDataWrapper.cpp - Foreign Data Wrapper class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include <wx/wx.h> + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignDataWrapper.h" + + +pgForeignDataWrapper::pgForeignDataWrapper(const wxString &newName) + : pgDatabaseObject(foreignDataWrapperFactory, newName) +{ +} + +bool pgForeignDataWrapper::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgForeignDataWrapper::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Foreign Data Wrapper: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + sql += wxT("FOREIGN DATA WRAPPER ") + GetName(); + + if (!GetValidatorProc().IsEmpty()) + sql += wxT("\n VALIDATOR ") + GetValidatorProc(); + + if (!GetOptions().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetCreateOptions() + wxT(")"); + + sql += wxT(";\n") + + GetOwnerSql(8, 4, wxT("FOREIGN DATA WRAPPER ") + GetName()) + + GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier()); + } + return sql; +} + + +void pgForeignDataWrapper::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Validator"), GetValidatorProc()); + properties->AppendItem(_("Options"), GetOptions()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgForeignDataWrapper::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *fdw = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + fdw = foreignDataWrapperFactory.CreateObjects(coll, 0, wxT("\n WHERE fdw.oid=") + GetOidStr()); + + return fdw; +} + + + +pgObject *pgForeignDataWrapperFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgForeignDataWrapper *fdw = 0; + + sql = wxT("SELECT fdw.oid, fdwname, fdwvalidator, fdwacl, vp.proname as fdwval, description, ") + wxT("array_to_string(fdwoptions, ',') AS fdwoptions, ") + wxT("pg_get_userbyid(fdwowner) as fdwowner\n"); + sql += wxT(" FROM pg_foreign_data_wrapper fdw\n") + wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=fdwvalidator\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=fdw.oid AND des.objsubid=0\n") + + restriction + wxT("\n") + wxT(" ORDER BY fdwname"); + pgSet *fdws = collection->GetDatabase()->ExecuteSet(sql); + + if (fdws) + { + while (!fdws->Eof()) + { + + fdw = new pgForeignDataWrapper(fdws->GetVal(wxT("fdwname"))); + fdw->iSetDatabase(collection->GetDatabase()); + fdw->iSetOid(fdws->GetOid(wxT("oid"))); + fdw->iSetOwner(fdws->GetVal(wxT("fdwowner"))); + fdw->iSetAcl(fdws->GetVal(wxT("fdwacl"))); + fdw->iSetComment(fdws->GetVal(wxT("description"))); + fdw->iSetValidatorProc(fdws->GetVal(wxT("fdwval"))); + fdw->iSetOptions(fdws->GetVal(wxT("fdwoptions"))); + + if (browser) + { + browser->AppendObject(collection, fdw); + + fdws->MoveNext(); + } + else + break; + } + + delete fdws; + } + return fdw; +} + + +wxString pgForeignDataWrapper::GetCreateOptions() +{ + wxString options_create = wxEmptyString; + wxString opt; + wxString val; + + wxStringTokenizer tkz_options(options, wxT(",")); + while (tkz_options.HasMoreTokens()) + { + wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("=")); + opt = tkz_option.GetNextToken(); + val = tkz_option.GetNextToken(); + + if (!options_create.IsEmpty()) + options_create += wxT(","); + + options_create += opt + wxT(" '") + val + wxT("'"); + } + + return options_create; +} + + +/////////////////////////////////////////////////// + +#include "images/foreigndatawrapper.xpm" +#include "images/foreigndatawrapper-sm.xpm" +#include "images/foreigndatawrappers.xpm" + +pgForeignDataWrapperFactory::pgForeignDataWrapperFactory() + : pgDatabaseObjFactory(__("Foreign Data Wrapper"), __("New Foreign Data Wrapper..."), __("Create a new Foreign Data Wrapper."), foreigndatawrapper_xpm, foreigndatawrapper_sm_xpm) +{ +} + + +pgForeignDataWrapperFactory foreignDataWrapperFactory; +static pgaCollectionFactory cf(&foreignDataWrapperFactory, __("Foreign Data Wrappers"), foreigndatawrappers_xpm); diff --git a/pgadmin/ui/dlgForeignDataWrapper.xrc b/pgadmin/ui/dlgForeignDataWrapper.xrc new file mode 100644 index 0000000..190228f --- /dev/null +++ b/pgadmin/ui/dlgForeignDataWrapper.xrc @@ -0,0 +1,255 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<resource> + <object class="wxDialog" name="dlgForeignDataWrapper"> + <title></title> + <size>220,250d</size> + <style>wxDEFAULT_DIALOG_STYLE|wxCAPTION|wxSYSTEM_MENU|wxRESIZE_BORDER|wxRESIZE_BOX|wxTHICK_FRAME</style> + <object class="wxFlexGridSizer"> + <cols>1</cols> + <growablecols>0</growablecols> + <growablerows>0</growablerows> + <object class="sizeritem"> + <object class="wxNotebook" name="nbNotebook"> + <size>216,225d</size> + <selected>0</selected> + <object class="notebookpage"> + <label>Properties</label> + <object class="wxPanel" name="pnlProperties"> + <object class="wxFlexGridSizer"> + <cols>2</cols> + <rows>6</rows> + <vgap>5</vgap> + <hgap>5</hgap> + <growablerows>4</growablerows> + <growablecols>1</growablecols> + <object class="sizeritem"> + <object class="wxStaticText" name="stName"> + <label>Name</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxTextCtrl" name="txtName"> + <size>135,-1d</size> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxStaticText" name="stOID"> + <label>OID</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxTextCtrl" name="txtOID"> + <size>135,-1d</size> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxStaticText" name="stOwner"> + <label>Owner</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="ctlComboBox" name="cbOwner"> + <size>135,-1d</size> + <content/> + <style>wxCB_DROPDOWN</style> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxStaticText" name="stValidator"> + <label>Validator</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="ctlComboBox" name="cbValidator"> + <content/> + <size>135,-1d</size> + <style>wxCB_DROPDOWN</style> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxStaticText" name="stComment"> + <label>Comment</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxTextCtrl" name="txtComment"> + <size>135,-1d</size> + <style>wxTE_MULTILINE</style> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxStaticText" name="stClusterSet"> + <label>Use replication</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL|wxALL</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxComboBox" name="cbClusterSet"> + <content/> + <size>135,-1d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL</flag> + <border>4</border> + </object> + </object> + </object> + </object> + <object class="notebookpage"> + <label>Options</label> + <object class="wxPanel" name="pnlOptions"> + <object class="wxFlexGridSizer"> + <cols>1</cols> + <rows>3</rows> + <growablerows>0</growablerows> + <growablecols>0</growablecols> + <object class="sizeritem"> + <object class="wxListCtrl" name="lstOptions"> + <pos>70,15d</pos> + <style>wxLC_REPORT|wxLC_SINGLE_SEL</style> + </object> + <option>80</option> + <flag>wxALL|wxEXPAND</flag> + <border>5</border> + </object> + <object class="sizeritem"> + <object class="wxFlexGridSizer"> + <cols>2</cols> + <rows>2</rows> + <vgap>5</vgap> + <hgap>5</hgap> + <growablecols>1</growablecols> + <object class="sizeritem"> + <object class="wxStaticText" name="stOption"> + <label>Option</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL</flag> + </object> + <object class="sizeritem"> + <object class="wxTextCtrl" name="txtOption"> + <size>135,-1d</size> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL</flag> + </object> + <object class="sizeritem"> + <object class="wxStaticText" name="stValue"> + <label>Value</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL</flag> + </object> + <object class="sizeritem"> + <object class="wxTextCtrl" name="txtValue"> + <size>135,-1d</size> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL</flag> + </object> + </object> + <flag>wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL</flag> + <border>5</border> + </object> + <object class="sizeritem"> + <object class="wxFlexGridSizer"> + <cols>2</cols> + <rows>1</rows> + <object class="sizeritem"> + <object class="wxButton" name="wxID_REMOVE"> + <label>Remove</label> + <pos>13,58d</pos> + </object> + <flag>wxALL|wxALIGN_RIGHT</flag> + <border>2</border> + </object> + <object class="sizeritem"> + <object class="wxButton" name="wxID_ADD"> + <label>Add/Change</label> + <pos>13,78d</pos> + </object> + <flag>wxALL|wxALIGN_RIGHT</flag> + <border>2</border> + </object> + </object> + <flag>wxALIGN_RIGHT</flag> + </object> + </object> + </object> + </object> + </object> + <flag>wxALL|wxGROW|wxALIGN_CENTRE</flag> + <border>3</border> + </object> + <object class="spacer"> + <size>2,2d</size> + </object> + <object class="sizeritem"> + <object class="wxFlexGridSizer"> + <cols>7</cols> + <growablecols>2</growablecols> + <object class="spacer"> + <size>3,3d</size> + </object> + <object class="sizeritem"> + <object class="wxButton" name="wxID_HELP"> + <label>Help</label> + </object> + </object> + <object class="spacer"> + <size>3,3d</size> + </object> + <object class="sizeritem"> + <object class="wxButton" name="wxID_OK"> + <label>&OK</label> + <default>1</default> + </object> + </object> + <object class="spacer"> + <size>3,3d</size> + </object> + <object class="sizeritem"> + <object class="wxButton" name="wxID_CANCEL"> + <label>&Cancel</label> + </object> + </object> + <object class="spacer"> + <size>3,3d</size> + </object> + </object> + <flag>wxTOP|wxLEFT|wxRIGHT|wxGROW</flag> + </object> + <object class="spacer"> + <size>3,3d</size> + </object> + <object class="sizeritem"> + <object class="wxStatusBar" name="unkStatusBar"> + <style>wxST_SIZEGRIP</style> + </object> + <flag>wxGROW|wxALIGN_CENTRE</flag> + <border>3</border> + </object> + </object> + </object> +</resource> diff --git a/pgadmin/ui/module.mk b/pgadmin/ui/module.mk index b6d77ec..9ff1b6d 100644 --- a/pgadmin/ui/module.mk +++ b/pgadmin/ui/module.mk @@ -26,6 +26,7 @@ TMP_ui += \ $(srcdir)/ui/dlgEditGridOptions.xrc \ $(srcdir)/ui/dlgExtTable.xrc \ $(srcdir)/ui/dlgFindReplace.xrc \ + $(srcdir)/ui/dlgForeignDataWrapper.xrc \ $(srcdir)/ui/dlgForeignKey.xrc \ $(srcdir)/ui/dlgFunction.xrc \ $(srcdir)/ui/dlgGroup.xrc \ diff --git a/pgadmin/utils/sysSettings.cpp b/pgadmin/utils/sysSettings.cpp index 2c16387..7153ca2 100644 --- a/pgadmin/utils/sysSettings.cpp +++ b/pgadmin/utils/sysSettings.cpp @@ -84,6 +84,11 @@ bool sysSettings::GetDisplayOption(const wxString &objtype, bool GetDefault) engtype = wxT("Casts"); def = false; } + else if (objtype == _("Foreign Data Wrappers")) + { + engtype = wxT("Foreign Data Wrappers"); + def = false; + } else if (objtype == _("Languages")) { engtype = wxT("Languages"); @@ -173,6 +178,7 @@ void sysSettings::SetDisplayOption(const wxString &objtype, bool display) else if (objtype == _("Resource Queues")) engtype = wxT("Resource Queues"); else if (objtype == _("Catalogs")) engtype = wxT("Catalogs"); else if (objtype == _("Casts")) engtype = wxT("Casts"); + else if (objtype == _("Foreign Data Wrappers")) engtype = wxT("Foreign Data Wrappers"); else if (objtype == _("Languages")) engtype = wxT("Languages"); else if (objtype == _("Synonyms")) engtype = wxT("Synonyms"); else if (objtype == _("Schemas")) engtype = wxT("Schemas"); -- 1.7.1
-- Sent via pgadmin-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgadmin-hackers
