Hi,

This patchs allows the user to add/change/drop an extension. It's a
fairly simple patch, nothing more to add.

Any comments?


-- 
Guillaume
 http://www.postgresql.fr
 http://dalibo.com
From f66bc520ea7554ec9054372a49924f9b3f19ea3d Mon Sep 17 00:00:00 2001
From: Guillaume Lelarge <[email protected]>
Date: Sun, 27 Mar 2011 10:01:26 +0200
Subject: [PATCH] Support for extension object.

---
 pgadmin/dlg/dlgExtension.cpp            |  198 +++++++++++++++++++++++++++
 pgadmin/dlg/module.mk                   |    1 +
 pgadmin/frm/frmOptions.cpp              |    1 +
 pgadmin/include/dlg/dlgExtension.h      |   42 ++++++
 pgadmin/include/dlg/module.mk           |    1 +
 pgadmin/include/images/extension-sm.png |  Bin 0 -> 423 bytes
 pgadmin/include/images/extension.png    |  Bin 0 -> 996 bytes
 pgadmin/include/images/extensions.png   |  Bin 0 -> 1017 bytes
 pgadmin/include/images/module.mk        |    3 +
 pgadmin/include/schema/module.mk        |    1 +
 pgadmin/include/schema/pgExtension.h    |   93 +++++++++++++
 pgadmin/schema/module.mk                |    1 +
 pgadmin/schema/pgDatabase.cpp           |    5 +
 pgadmin/schema/pgExtension.cpp          |  225 +++++++++++++++++++++++++++++++
 pgadmin/ui/dlgExtension.xrc             |  160 ++++++++++++++++++++++
 pgadmin/ui/module.mk                    |    1 +
 16 files changed, 732 insertions(+), 0 deletions(-)
 create mode 100644 pgadmin/dlg/dlgExtension.cpp
 create mode 100644 pgadmin/include/dlg/dlgExtension.h
 create mode 100755 pgadmin/include/images/extension-sm.png
 create mode 100755 pgadmin/include/images/extension.png
 create mode 100755 pgadmin/include/images/extensions.png
 create mode 100644 pgadmin/include/schema/pgExtension.h
 create mode 100644 pgadmin/schema/pgExtension.cpp
 create mode 100644 pgadmin/ui/dlgExtension.xrc

diff --git a/pgadmin/dlg/dlgExtension.cpp b/pgadmin/dlg/dlgExtension.cpp
new file mode 100644
index 0000000..9ca56d2
--- /dev/null
+++ b/pgadmin/dlg/dlgExtension.cpp
@@ -0,0 +1,198 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+//
+// Copyright (C) 2002 - 2011, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// dlgExtension.cpp - PostgreSQL Extension Property
+//
+//////////////////////////////////////////////////////////////////////////
+
+// wxWindows headers
+#include <wx/wx.h>
+
+// App headers
+#include "pgAdmin3.h"
+#include "utils/misc.h"
+#include "utils/pgDefs.h"
+
+#include "dlg/dlgExtension.h"
+#include "schema/pgExtension.h"
+
+
+// pointer to controls
+#define cbName          CTRL_COMBOBOX("cbName")
+#define cbSchema        CTRL_COMBOBOX("cbSchema")
+#define cbVersion       CTRL_COMBOBOX("cbVersion")
+
+
+dlgProperty *pgExtensionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
+{
+	return new dlgExtension(this, frame, (pgExtension *)node);
+}
+
+
+BEGIN_EVENT_TABLE(dlgExtension, dlgProperty)
+	EVT_TEXT(XRCID("cbName"),                       dlgExtension::OnChangeName)
+	EVT_COMBOBOX(XRCID("cbName"),                   dlgExtension::OnChangeName)
+	EVT_TEXT(XRCID("cbSchema"),                     dlgProperty::OnChange)
+	EVT_COMBOBOX(XRCID("cbSchema"),                 dlgProperty::OnChange)
+	EVT_TEXT(XRCID("cbVersion"),                    dlgProperty::OnChange)
+	EVT_COMBOBOX(XRCID("cbVersion"),                dlgProperty::OnChange)
+END_EVENT_TABLE();
+
+
+dlgExtension::dlgExtension(pgaFactory *f, frmMain *frame, pgExtension *node)
+	: dlgProperty(f, frame, wxT("dlgExtension"))
+{
+	extension = node;
+}
+
+
+pgObject *dlgExtension::GetObject()
+{
+	return extension;
+}
+
+
+int dlgExtension::Go(bool modal)
+{
+	txtComment->Disable();
+
+    // add all schemas
+    cbSchema->Append(wxEmptyString);
+    pgSetIterator schemas(connection,
+                            wxT("SELECT nspname FROM pg_namespace\n")
+                            wxT(" ORDER BY nspname"));
+
+    while (schemas.RowsLeft())
+        cbSchema->Append(schemas.GetVal(wxT("nspname")));
+    cbSchema->SetSelection(0);
+
+	if (extension)
+	{
+		// edit mode
+        cbName->Append(extension->GetName());
+        cbName->SetSelection(0);
+        cbName->Disable();
+        
+        cbSchema->SetValue(extension->GetSchemaStr());
+        cbSchema->Enable(extension->GetIsRelocatable());
+        
+        // add all versions
+        cbVersion->Clear();
+        cbVersion->Append(wxEmptyString);
+        pgSetIterator versions(connection,
+                                wxT("SELECT version, relocatable FROM pg_available_extension_versions\n")
+                                wxT(" WHERE name=") + qtDbString(cbName->GetValue()) + wxT(" ")
+                                wxT(" ORDER BY version"));
+
+        while (versions.RowsLeft())
+            cbVersion->Append(versions.GetVal(wxT("version")));
+        cbVersion->SetValue(extension->GetVersion());
+	}
+	else
+	{
+		// create mode
+        
+        // add available extensions (but not the installed ones)
+        cbName->Append(wxEmptyString);
+        pgSetIterator extensions(connection,
+                                wxT("SELECT name FROM pg_available_extensions\n")
+                                wxT(" WHERE installed_version IS NULL\n")
+                                wxT(" ORDER BY name"));
+
+        while (extensions.RowsLeft())
+            cbName->Append(extensions.GetVal(wxT("name")));
+        cbName->SetSelection(0);
+	}
+
+	return dlgProperty::Go(modal);
+}
+
+
+pgObject *dlgExtension::CreateObject(pgCollection *collection)
+{
+	wxString name = cbName->wxComboBox::GetValue();
+
+	pgObject *obj = extensionFactory.CreateObjects(collection, 0, wxT("\n   AND extname ILIKE ") + qtDbString(name));
+	return obj;
+}
+
+
+void dlgExtension::OnChangeName(wxCommandEvent &ev)
+{
+    bool relocatable;
+    
+    // add all versions
+    cbVersion->Clear();
+    cbVersion->Append(wxEmptyString);
+    pgSetIterator versions(connection,
+                            wxT("SELECT version, relocatable FROM pg_available_extension_versions\n")
+                            wxT(" WHERE name=") + qtDbString(cbName->GetValue()) + wxT(" ")
+                            wxT(" ORDER BY version"));
+
+    while (versions.RowsLeft())
+    {
+        relocatable = versions.GetBool(wxT("relocatable"));
+        cbVersion->Append(versions.GetVal(wxT("version")));
+    }
+    cbVersion->SetSelection(0);
+    
+    if (relocatable)
+    {
+        cbSchema->Enable();
+    }
+    else
+    {
+        cbSchema->SetSelection(0);
+        cbSchema->Disable();
+    }
+
+	OnChange(ev);
+}
+
+
+void dlgExtension::CheckChange()
+{
+	bool didChange = true;
+	if (extension)
+	{
+		didChange = cbSchema->GetValue() != extension->GetSchemaStr()
+                    || cbVersion->GetValue() != extension->GetVersion();
+		EnableOK(didChange);
+	}
+	else
+	{
+		bool enable = true;
+
+		CheckValid(enable, !cbName->GetValue().IsEmpty(), _("Please specify name."));
+		EnableOK(enable);
+	}
+}
+
+
+wxString dlgExtension::GetSql()
+{
+	wxString sql;
+
+	if (extension)
+	{
+		// edit mode
+		if (cbSchema->GetValue() != extension->GetSchemaStr())
+			sql += wxT("ALTER EXTENSION ") + qtIdent(extension->GetName())
+			       +  wxT(" SET SCHEMA ") + qtIdent(cbSchema->GetValue()) + wxT(";\n");
+		if (cbVersion->GetValue() != extension->GetVersion())
+			sql += wxT("ALTER EXTENSION ") + qtIdent(extension->GetName())
+			       +  wxT(" UPDATE TO ") + qtIdent(cbVersion->GetValue()) + wxT(";\n");
+	}
+	else
+	{
+        sql = wxT("CREATE EXTENSION ") + qtIdent(cbName->GetValue());
+        AppendIfFilled(sql, wxT("\n   SCHEMA "), qtIdent(cbSchema->GetValue()));
+        AppendIfFilled(sql, wxT("\n   VERSION "), qtIdent(cbVersion->GetValue()));
+	}
+    
+	return sql;
+}
diff --git a/pgadmin/dlg/module.mk b/pgadmin/dlg/module.mk
index 2252957..c7ab4cc 100644
--- a/pgadmin/dlg/module.mk
+++ b/pgadmin/dlg/module.mk
@@ -20,6 +20,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/dlg/dlgConversion.cpp \
 	$(srcdir)/dlg/dlgDatabase.cpp \
 	$(srcdir)/dlg/dlgDomain.cpp \
+	$(srcdir)/dlg/dlgExtension.cpp \
 	$(srcdir)/dlg/dlgEditGridOptions.cpp \
 	$(srcdir)/dlg/dlgFindReplace.cpp \
 	$(srcdir)/dlg/dlgForeignDataWrapper.cpp \
diff --git a/pgadmin/frm/frmOptions.cpp b/pgadmin/frm/frmOptions.cpp
index 6762b6b..b1588c3 100644
--- a/pgadmin/frm/frmOptions.cpp
+++ b/pgadmin/frm/frmOptions.cpp
@@ -335,6 +335,7 @@ frmOptions::frmOptions(frmMain *parent)
 	lstDisplay->Append(_("Aggregates"));
 	lstDisplay->Append(_("Conversions"));
 	lstDisplay->Append(_("Domains"));
+	lstDisplay->Append(_("Extensions"));
 	lstDisplay->Append(_("Functions"));
 	lstDisplay->Append(_("Trigger Functions"));
 	lstDisplay->Append(_("Packages"));
diff --git a/pgadmin/include/dlg/dlgExtension.h b/pgadmin/include/dlg/dlgExtension.h
new file mode 100644
index 0000000..6bece0b
--- /dev/null
+++ b/pgadmin/include/dlg/dlgExtension.h
@@ -0,0 +1,42 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+//
+// Copyright (C) 2002 - 2011, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// dlgExtension.h - Extension property
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __DLG_EXTENSIONPROP
+#define __DLG_EXTENSIONPROP
+
+#include "dlg/dlgProperty.h"
+
+class pgExtension;
+
+class dlgExtension : public dlgProperty
+{
+public:
+	dlgExtension(pgaFactory *factory, frmMain *frame, pgExtension *ext);
+	int Go(bool modal);
+
+	void CheckChange();
+	wxString GetSql();
+	pgObject *CreateObject(pgCollection *collection);
+	pgObject *GetObject();
+
+private:
+	pgExtension *extension;
+	void OnChangeName(wxCommandEvent &ev);
+#ifdef __WXMAC__
+	void OnChangeSize(wxSizeEvent &ev);
+#endif
+
+	DECLARE_EVENT_TABLE()
+};
+
+
+#endif
diff --git a/pgadmin/include/dlg/module.mk b/pgadmin/include/dlg/module.mk
index 4bf7cd1..673e095 100644
--- a/pgadmin/include/dlg/module.mk
+++ b/pgadmin/include/dlg/module.mk
@@ -20,6 +20,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/include/dlg/dlgConversion.h \
 	$(srcdir)/include/dlg/dlgDatabase.h \
 	$(srcdir)/include/dlg/dlgDomain.h \
+	$(srcdir)/include/dlg/dlgExtension.h \
 	$(srcdir)/include/dlg/dlgEditGridOptions.h \
 	$(srcdir)/include/dlg/dlgFindReplace.h \
 	$(srcdir)/include/dlg/dlgForeignDataWrapper.h \
diff --git a/pgadmin/include/images/extension-sm.png b/pgadmin/include/images/extension-sm.png
new file mode 100755
index 0000000000000000000000000000000000000000..432d2f44231c1f88e787091060efc5125d80ef64
GIT binary patch
literal 423
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E0BJDv+cp5$Qv6qzrVk7
zW3&9@vzBik`G5Ho|K-)uTicc2-1GkNGyU0x%oo?3fBedPak1gnHlr`^;(z|izO~Kb
z%lm|1zjI$+bN~H2|Mm{mcMpR9{3*J*S>f3^`;Si}e|^pQ`={jETDdE$#Qyy)dv><$
z|KAGswyocQwlbCk`2{mLJiCzw<Zu>vL>2>S4={E+nQaGT<aoL`hDcoQ?f2wsP!M2o
z7l{eDQ+~(c|9@BE84^1Kx361bY|Bu`qQb-J62DBxZ_<p5BE`pwna}6wxpa1%>e!Vz
zahdU=*X&ESFOpJE*&;e)`qd3*DpaT5u9JDLS%3P((k)@<ZbaLzV+h!Of4=?`KK92q
z=3fE@l4^--L`h0wNvc(HQ7VvPFfuSS&^0vDH82b@GO#i+wlXo*HZZj^FqrpFZxxD$
o-29Zxv`UBu152<5plTB<12c$*Q`1A&05vdpy85}Sb4q9e01}k2!2kdN

literal 0
HcmV?d00001

diff --git a/pgadmin/include/images/extension.png b/pgadmin/include/images/extension.png
new file mode 100755
index 0000000000000000000000000000000000000000..e3c533347883fc1dec73bcb21b32fc54e3c31732
GIT binary patch
literal 996
zcmV<A0~`E_P)<h;3K|Lk000e1NJLTq000mG000mO0{{R3C@l|D00001b5ch_0Itp)
z=>Px%`cO<%MQ2zLf_6I6&9|zdd99>-@a*2m!Junh7N)|bRf|-bx|zVboSKha_w(lG
z;mc-L4XVVcQjb)R!IoN>UTm6cdTlP+)48aeY_F(+!qvh)fIq$I$ak@QM1Demb2p-y
zZNIpg%*U?Z+|0eUmR?Q)@#@yLtA3u9XFhv8mdv0tb~C!Ok)4xckc3Wsa4?*aUD?pH
z@afX-<;s|gP-<HecxWLITMn+{ye)Dq{QLL&`11Mo?Dg>A^X%E{;lk+My5`xk<JGC)
z(V?J^Pa0qr9%URUZYXJ}aH`|EXsd7=V;MkvKHbcisFznYY9*e@qsi^kq0p+c;k~!#
z!?5MPqv5li->#6?p?1NAale3n)0NuDkgb|nMQ$vEwur;)&X(P%klLe(*qwsbn0(Ze
z&%lqBg+*3S1ZY?dnutTImr{GNfpyZ2etkM9XCNqTCtr9wihVOAV;iN_u6D(TK#xcf
zTn`v!7(bOtw4`b=XCQ>Lht=`it<|(#mtSF?W<QQcm$;T>m1BZ;G0*SUx8%WGt7&4B
zV3D+tb8RIwgF3Luu#bN^7G4v==*yVRp-_@kjmeoSdoaG!zSzWv!K`UHUKC!MVuZSj
zaIAJVdpAyF9vxyClh&g+jY8GGe$u;klYuouT@*iVD?w)>Y;7EsekVC?DRR1gZ_tQZ
zyKv99ZOyY~z@}84hBK{_JHn(!l6fLVbTnhFZfMSfV$6Lul0qhGC2*Z?NP<TvhBL~q
zUB|0c#ivccpg)Ro98G#WT*`P>$a6}(W;2>aI;l}Wz+t|fIeljlScFSfreaXWZ%f2#
zMZ#t~zg?k^OOAUphI1*4cr3V}Qns8&igY1@Y#D@Y7H?b$T8UCtsbn_2S%i2!rk!)h
z!>EaMCcvamyR?(W!KK8$qF<3+9BCaAUJ)8<9X6LmEss1DV->ZTL3e2=8EP9)hfaum
zLy>wXERsEdsDEo(3zmE$ex`jsyImG&7=LOOfol~TcO*%INEmJ%7i}B|YRn1%0004W
zQchC<K<3zH00001VoOIv0Eh)0NB{r;32;bRa{vGf6951U69E94oEQKA00(qQO+^RW
z0~-xG4!&HBF8}}lR!KxbR2b7^U?3j2xS;VvLXbtwTz~>0W=QhVA)yH_FkL{}1;huk
zpaKCQKz@=7s`{i97i0@vl2TS8w1C7?R&G7y;)1Nm<<OZkC{A-h<6}A<CjbDaP8qDe
SR_4e60000<MNUMnLSTaX-^L37

literal 0
HcmV?d00001

diff --git a/pgadmin/include/images/extensions.png b/pgadmin/include/images/extensions.png
new file mode 100755
index 0000000000000000000000000000000000000000..eed7ca97a33ef595f448b8621168d531f86d51d5
GIT binary patch
literal 1017
zcmV<V0|xwwP)<h;3K|Lk000e1NJLTq000mG000mO0{{R3C@l|D00001b5ch_0Itp)
z=>Px%_fSk!MS^xZ(#^N3p?R&Od+_Yu$ibj%T^6RorB#bmn!1_5x}2JiUH9|m=i$p{
zRt>7esZx(rkHMB&m|kp}YkF-i+S9qHoNTYCfx^|oK7c>H>Bx7neMEjjfO9vZnQgzg
znaszo-`vc-ww7K_0rBeAwyS=gm1jPCJeJI$Gj=n&vyq*XV~~VSeQ+?GkzLu)v+(KC
z?&Zpui%@D?5_o7K5L*te<Gd|$E&TiU`}p$t_U!fW;PdR+>*2!a-MZ%4vg6gM;L)L=
zk53w479M3BDQ+lfsBo&|xoE3!8)F$jd_LXGn5dUmHEJcE$)m~b(xK3*v*EqB=fkk&
zzN6u@o!_pI*P(X7g>k=tf76xP$dIj?SVe9ugSLpn>&}+lsF2#DiP)Wj)|h<Mlh449
zm4!uCPy}dL4Vs8UtCv!Hv4M5cjedPPC}$ujZ6{xNJBocXBx4(;)vk8Mhd_@=5nK-#
zWf(t|O0=YEF=rrzvxn93+^yBLT$f*Ao@PIeN0+#kWR+urcQMcJ*SF-sT&rnflVFjw
zkaKM%G=n;@$*_-qITl_M!syGG&7n||RE^1*D|;}$)4tfmhrz6AIbIZAnqq{yi*T%V
zHhVWtV;&u18I#tdIE_NpzkbrYc9VfMLtPX<ZYx1&B5Z9Om3}8VZ7FiPes9o-TDx%1
zw{6X{Wx%FXorW{5k~_krMv{3VMsze|t!`+}gJR5mHj+XnY9(-;Zb*VhCx$c1uU*Hh
zRmG=Gz@R^havV*1JY33nR>*Toyk;|+MLMZbK)_+XojHAH5m<yvR;FT5#&1i+YDL0k
zJHK6_k4uhwGlp|1i+C)!pi;J+M~ZYIf@~RtZ5D4_30jF#R;gq*y;+2KJ*J&=$it|K
zbtb^1PrI~}#=)h;zM@}|T^wm05?&D+Y8^J0MJ<m!6k`>&nL&4HC>d%SP=`*4d_$3X
zCoGaZfT(|KS__tZB7UZQKD%8OXc&KL7J+LO8+Rm0f=C!{9T#mJ7UDFE00001bW%=J
z06^y0W&i*H0b)x>L;#2d9Y_EG010qNS#tmY3ljhU3ljkVnw%H_000McNliru+XEXB
z6Cp(Rbcp}}0B%V{K~xyiU68R2z#t3+nS(tt!3~hY^vGg42FL=`EENNm0{M!6-y1;)
zQxFazvL_cK*b<_okFg0d8Hc#V=Eh`)h+yZmplehnlNZEdtgQ@hX0CNeIWEpxw!oyN
ndc~tsp9TlidOzOC&-)*|KH)3pD2ngr00000NkvXXu0mjf<KNUz

literal 0
HcmV?d00001

diff --git a/pgadmin/include/images/module.mk b/pgadmin/include/images/module.mk
index 6a666b2..7990691 100644
--- a/pgadmin/include/images/module.mk
+++ b/pgadmin/include/images/module.mk
@@ -58,6 +58,9 @@ pgadmin3_SOURCES += \
 	$(srcdir)/include/images/domain-sm.png \
 	$(srcdir)/include/images/domain.png \
 	$(srcdir)/include/images/domains.png \
+	$(srcdir)/include/images/extension-sm.png \
+	$(srcdir)/include/images/extension.png \
+	$(srcdir)/include/images/extensions.png \
 	$(srcdir)/include/images/down.png \
 	$(srcdir)/include/images/drop.png \
 	$(srcdir)/include/images/edit_clear.png \
diff --git a/pgadmin/include/schema/module.mk b/pgadmin/include/schema/module.mk
index e897e37..a2d23bf 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/pgExtension.h \
 	$(srcdir)/include/schema/pgForeignDataWrapper.h \
 	$(srcdir)/include/schema/pgForeignKey.h \
     $(subdir)/pgForeignServer.h \
diff --git a/pgadmin/include/schema/pgExtension.h b/pgadmin/include/schema/pgExtension.h
new file mode 100644
index 0000000..1c7db9a
--- /dev/null
+++ b/pgadmin/include/schema/pgExtension.h
@@ -0,0 +1,93 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+//
+// Copyright (C) 2002 - 2011, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// pgExtension.h PostgreSQL Extension
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef PGEXTENSION_H
+#define PGEXTENSION_H
+
+#include "pgDatabase.h"
+
+class pgCollection;
+class pgExtensionFactory : public pgDatabaseObjFactory
+{
+public:
+	pgExtensionFactory();
+	virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent);
+	virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString);
+};
+extern pgExtensionFactory extensionFactory;
+
+class pgExtension : public pgDatabaseObject
+{
+public:
+	pgExtension(const wxString &newName = wxT(""));
+
+	wxString GetTranslatedMessage(int kindOfMessage) const;
+	void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0);
+	bool CanDropCascaded()
+	{
+		return true;
+	}
+
+	wxString GetSchemaStr() const
+	{
+		return schema;
+	}
+	void iSetSchemaStr(const wxString &s)
+	{
+		schema = s;
+	}
+	wxString GetVersion() const
+	{
+		return version;
+	}
+	void iSetVersion(const wxString &s)
+	{
+		version = s;
+	}
+	bool GetIsRelocatable() const
+	{
+		return isrelocatable;
+	}
+	void iSetIsRelocatable(const bool b)
+	{
+		isrelocatable = b;
+	}
+
+	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 false;
+	}
+	bool HasReferences()
+	{
+		return false;
+	}
+
+private:
+	wxString schema, version;
+    bool isrelocatable;
+};
+
+class pgExtensionCollection : public pgDatabaseObjCollection
+{
+public:
+	pgExtensionCollection(pgaFactory *factory, pgDatabase *db);
+	wxString GetTranslatedMessage(int kindOfMessage) const;
+};
+
+#endif
diff --git a/pgadmin/schema/module.mk b/pgadmin/schema/module.mk
index bbcd106..f6b7a6f 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)/pgExtension.cpp \
         $(subdir)/pgForeignDataWrapper.cpp \
         $(subdir)/pgForeignKey.cpp \
         $(subdir)/pgForeignServer.cpp \
diff --git a/pgadmin/schema/pgDatabase.cpp b/pgadmin/schema/pgDatabase.cpp
index 02555fb..7388d73 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/pgExtension.h"
 #include "schema/pgForeignDataWrapper.h"
 #include "schema/pgLanguage.h"
 #include "schema/pgSchema.h"
@@ -131,6 +132,8 @@ wxMenu *pgDatabase::GetNewMenu()
 	{
 		if (settings->GetDisplayOption(_("Casts")))
 			castFactory.AppendMenu(menu);
+		if (settings->GetDisplayOption(_("Extensions")))
+			extensionFactory.AppendMenu(menu);
 		if (settings->GetDisplayOption(_("Foreign Data Wrappers")))
 			foreignDataWrapperFactory.AppendMenu(menu);
 		if (settings->GetDisplayOption(_("Languages")))
@@ -563,6 +566,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(_("Extensions")))
+				browser->AppendCollection(this, extensionFactory);
 			if (settings->GetDisplayOption(_("Foreign Data Wrappers")))
 				browser->AppendCollection(this, foreignDataWrapperFactory);
 			if (settings->GetDisplayOption(_("Languages")))
diff --git a/pgadmin/schema/pgExtension.cpp b/pgadmin/schema/pgExtension.cpp
new file mode 100644
index 0000000..1e14104
--- /dev/null
+++ b/pgadmin/schema/pgExtension.cpp
@@ -0,0 +1,225 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+//
+// Copyright (C) 2002 - 2011, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// pgExtension.cpp - Extension class
+//
+//////////////////////////////////////////////////////////////////////////
+
+// wxWindows headers
+#include <wx/wx.h>
+
+// App headers
+#include "pgAdmin3.h"
+#include "utils/misc.h"
+#include "schema/pgExtension.h"
+
+
+pgExtension::pgExtension(const wxString &newName)
+	: pgDatabaseObject(extensionFactory, newName)
+{
+}
+
+wxString pgExtension::GetTranslatedMessage(int kindOfMessage) const
+{
+	wxString message = wxEmptyString;
+
+	switch (kindOfMessage)
+	{
+		case RETRIEVINGDETAILS:
+			message = _("Retrieving details on extension");
+			message += wxT(" ") + GetName();
+			break;
+		case REFRESHINGDETAILS:
+			message = _("Refreshing extension");
+			message += wxT(" ") + GetName();
+			break;
+		case DROPINCLUDINGDEPS:
+			message = wxString::Format(_("Are you sure you wish to drop extension \"%s\" including all objects that depend on it?"),
+			                           GetFullIdentifier().c_str());
+			break;
+		case DROPEXCLUDINGDEPS:
+			message = wxString::Format(_("Are you sure you wish to drop extension \"%s?\""),
+			                           GetFullIdentifier().c_str());
+			break;
+		case DROPCASCADETITLE:
+			message = _("Drop extension cascaded?");
+			break;
+		case DROPTITLE:
+			message = _("Drop extension?");
+			break;
+		case PROPERTIESREPORT:
+			message = _("Extension properties report");
+			message += wxT(" - ") + GetName();
+			break;
+		case PROPERTIES:
+			message = _("Extension properties");
+			break;
+		case DDLREPORT:
+			message = _("Extension DDL report");
+			message += wxT(" - ") + GetName();
+			break;
+		case DDL:
+			message = _("Extension DDL");
+			break;
+		case DEPENDENCIESREPORT:
+			message = _("Extension dependencies report");
+			message += wxT(" - ") + GetName();
+			break;
+		case DEPENDENCIES:
+			message = _("Extension dependencies");
+			break;
+		case DEPENDENTSREPORT:
+			message = _("Extension dependents report");
+			message += wxT(" - ") + GetName();
+			break;
+		case DEPENDENTS:
+			message = _("Extension dependents");
+			break;
+	}
+
+	return message;
+}
+
+bool pgExtension::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
+{
+	wxString sql = wxT("DROP EXTENSION ") + GetQuotedIdentifier();
+	if (cascaded)
+		sql += wxT(" CASCADE");
+	return GetDatabase()->ExecuteVoid(sql);
+}
+
+
+wxString pgExtension::GetSql(ctlTree *browser)
+{
+	if (sql.IsNull())
+	{
+		sql = wxT("-- Extension: ") + GetQuotedIdentifier() + wxT("\n\n")
+		      + wxT("-- DROP EXTENSION ") + GetQuotedIdentifier() + wxT(";")
+		      + wxT("\n\n CREATE EXTENSION ") + GetName();
+
+		if (!GetSchemaStr().IsEmpty())
+			sql += wxT("\n  SCHEMA ") + GetSchemaStr();
+		if (!GetVersion().IsEmpty())
+			sql += wxT("\n  VERSION ") + GetVersion();
+
+		sql += wxT(";\n")
+		       +  GetOwnerSql(9, 1, wxT("EXTENSION ") + GetName());
+	}
+	return sql;
+}
+
+
+void pgExtension::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(_("Schema"), GetSchemaStr());
+		properties->AppendYesNoItem(_("Relocatable?"), GetIsRelocatable());
+		properties->AppendItem(_("Version"), GetVersion());
+        properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));
+	}
+}
+
+
+
+pgObject *pgExtension::Refresh(ctlTree *browser, const wxTreeItemId item)
+{
+	pgObject *language = 0;
+	pgCollection *coll = browser->GetParentCollection(item);
+	if (coll)
+		language = extensionFactory.CreateObjects(coll, 0, wxT("\n   AND x.oid=") + GetOidStr());
+
+	return language;
+}
+
+
+
+pgObject *pgExtensionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
+{
+	wxString sql;
+	pgExtension *extension = 0;
+
+	sql = wxT("select x.oid, x.extname, r.rolname, n.nspname, x.extrelocatable, x.extversion, e.comment")
+           wxT("  FROM pg_extension x\n")
+	       wxT("  JOIN pg_roles r on x.extowner=r.oid \n")
+	       wxT("  JOIN pg_namespace n on x.extnamespace=n.oid\n")
+           wxT("  join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name\n")
+	       + restriction + wxT("\n")
+	       wxT(" ORDER BY x.extname");
+	pgSet *extensions = collection->GetDatabase()->ExecuteSet(sql);
+
+	if (extensions)
+	{
+		while (!extensions->Eof())
+		{
+
+			extension = new pgExtension(extensions->GetVal(wxT("extname")));
+			extension->iSetDatabase(collection->GetDatabase());
+			extension->iSetOid(extensions->GetOid(wxT("oid")));
+			extension->iSetOwner(extensions->GetVal(wxT("rolname")));
+			extension->iSetSchemaStr(extensions->GetVal(wxT("nspname")));
+			extension->iSetIsRelocatable(extensions->GetBool(wxT("extrelocatable")));
+			extension->iSetVersion(extensions->GetVal(wxT("extversion")));
+			extension->iSetComment(extensions->GetVal(wxT("comment")));
+
+			if (browser)
+			{
+				browser->AppendObject(collection, extension);
+
+				extensions->MoveNext();
+			}
+			else
+				break;
+		}
+
+		delete extensions;
+	}
+	return extension;
+}
+
+
+/////////////////////////////
+
+wxString pgExtensionCollection::GetTranslatedMessage(int kindOfMessage) const
+{
+	wxString message = wxEmptyString;
+
+	switch (kindOfMessage)
+	{
+		case RETRIEVINGDETAILS:
+			message = _("Retrieving details on extensions");
+			break;
+		case REFRESHINGDETAILS:
+			message = _("Refreshing extensions");
+			break;
+		case OBJECTSLISTREPORT:
+			message = _("Extensions list report");
+			break;
+	}
+
+	return message;
+}
+
+///////////////////////////////////////////////////
+
+#include "images/extension.pngc"
+#include "images/extension-sm.pngc"
+#include "images/extensions.pngc"
+
+pgExtensionFactory::pgExtensionFactory()
+	: pgDatabaseObjFactory(__("Extension"), __("New Extension..."), __("Create a new Extension."), extension_png_img, extension_sm_png_img)
+{
+}
+
+
+pgExtensionFactory extensionFactory;
+static pgaCollectionFactory cf(&extensionFactory, __("Extensions"), extensions_png_img);
diff --git a/pgadmin/ui/dlgExtension.xrc b/pgadmin/ui/dlgExtension.xrc
new file mode 100644
index 0000000..baaae05
--- /dev/null
+++ b/pgadmin/ui/dlgExtension.xrc
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<resource>
+  <object class="wxDialog" name="dlgExtension">
+    <title></title>
+    <size>220,250d</size>
+    <style>wxDEFAULT_DIALOG_STYLE|wxCAPTION|wxSYSTEM_MENU|wxRESIZE_BORDER</style>
+    <object class="wxFlexGridSizer">
+      <cols>1</cols>
+      <growablerows>0</growablerows>
+      <growablecols>0</growablecols>
+      <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="wxComboBox" name="cbName">
+                    <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="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">
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stSchema">
+                    <label>Schema</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="ctlComboBox" name="cbSchema">
+                    <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="stVersion">
+                    <label>Version</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="ctlComboBox" name="cbVersion">
+                    <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="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">
+                    <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/>
+                    <style>wxCB_READONLY|wxCB_DROPDOWN</style>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL</flag>
+                  <border>4</border>
+                </object>
+              </object>
+            </object>
+          </object>
+        </object>
+        <flag>wxALL|wxGROW|wxALIGN_CENTRE</flag>
+        <border>3</border>
+      </object>
+      <object class="sizeritem">
+        <object class="wxFlexGridSizer">
+          <cols>4</cols>
+          <growablecols>1</growablecols>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_HELP">
+              <label>Help</label>
+            </object>
+            <flag>wxEXPAND|wxALL</flag>
+            <border>3</border>
+          </object>
+          <object class="spacer">
+            <size>0,0d</size>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_OK">
+              <label>&amp;OK</label>
+              <default>1</default>
+            </object>
+            <flag>wxEXPAND|wxALL</flag>
+            <border>3</border>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_CANCEL">
+              <label>&amp;Cancel</label>
+            </object>
+            <flag>wxEXPAND|wxALL</flag>
+            <border>3</border>
+          </object>
+        </object>
+        <flag>wxEXPAND|wxTOP|wxLEFT|wxRIGHT</flag>
+      </object>
+      <object class="sizeritem">
+        <object class="wxStatusBar" name="unkStatusBar">
+          <style>wxST_SIZEGRIP</style>
+        </object>
+        <flag>wxEXPAND|wxALIGN_CENTRE</flag>
+        <border>3</border>
+      </object>
+    </object>
+  </object>
+</resource>
diff --git a/pgadmin/ui/module.mk b/pgadmin/ui/module.mk
index 79da290..0956c57 100644
--- a/pgadmin/ui/module.mk
+++ b/pgadmin/ui/module.mk
@@ -23,6 +23,7 @@ TMP_ui += \
 	$(srcdir)/ui/dlgDatabase.xrc \
 	$(srcdir)/ui/dlgDirectDbg.xrc \
 	$(srcdir)/ui/dlgDomain.xrc \
+	$(srcdir)/ui/dlgExtension.xrc \
 	$(srcdir)/ui/dlgEditGridOptions.xrc \
 	$(srcdir)/ui/dlgExtTable.xrc \
 	$(srcdir)/ui/dlgFindReplace.xrc \
-- 
1.7.1

-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

Reply via email to