>From 43ef769082f546be8692f0d3d4bf70bb83da28ce Mon Sep 17 00:00:00 2001
From: Guillaume Lelarge <guillaume@lelarge.info>
Date: Wed, 7 May 2014 21:40:44 +0200
Subject: [PATCH] Add a new action menu to refresh a materialized view

It also displays another action menu with 9.4 cluster to refresh concurrently the materialized view.
---
 pgadmin/frm/frmMain.cpp         |  3 ++
 pgadmin/include/schema/pgView.h | 18 +++++++++++
 pgadmin/schema/pgView.cpp       | 67 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+)

diff --git a/pgadmin/frm/frmMain.cpp b/pgadmin/frm/frmMain.cpp
index b9c7c64..b3cab59 100644
--- a/pgadmin/frm/frmMain.cpp
+++ b/pgadmin/frm/frmMain.cpp
@@ -73,6 +73,7 @@
 #include "dlg/dlgDatabase.h"
 #include "dlg/dlgSearchObject.h"
 #include "schema/pgTable.h"
+#include "schema/pgView.h"
 #include "schema/pgFunction.h"
 #include "schema/pgIndex.h"
 #include "schema/pgTrigger.h"
@@ -306,6 +307,8 @@ void frmMain::CreateMenus()
 	viewMenu->AppendSeparator();
 	actionFactory *refFact = new refreshFactory(menuFactories, viewMenu, toolBar);
 	new countRowsFactory(menuFactories, viewMenu, 0);
+	new refreshMatViewFactory(menuFactories, viewMenu, 0);
+	new refreshConcurrentlyMatViewFactory(menuFactories, viewMenu, 0);
 	new executePgstattupleFactory(menuFactories, viewMenu, 0);
 	new executePgstatindexFactory(menuFactories, viewMenu, 0);
 	new enabledisableRuleFactory(menuFactories, toolsMenu, 0);
diff --git a/pgadmin/include/schema/pgView.h b/pgadmin/include/schema/pgView.h
index dac8d67..211023b 100644
--- a/pgadmin/include/schema/pgView.h
+++ b/pgadmin/include/schema/pgView.h
@@ -108,6 +108,7 @@ public:
 	wxString GetInsertSql(ctlTree *browser);
 	wxString GetUpdateSql(ctlTree *browser);
 	pgObject *Refresh(ctlTree *browser, const wxTreeItemId item);
+	void RefreshMatView(bool concurrently);
 
 	bool HasStats()
 	{
@@ -371,4 +372,21 @@ public:
 	wxString GetTranslatedMessage(int kindOfMessage) const;
 };
 
+class refreshMatViewFactory : public contextActionFactory
+{
+public:
+	refreshMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
+	wxWindow *StartDialog(frmMain *form, pgObject *obj);
+	bool CheckEnable(pgObject *obj);
+};
+
+class refreshConcurrentlyMatViewFactory : public contextActionFactory
+{
+public:
+	refreshConcurrentlyMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
+	wxWindow *StartDialog(frmMain *form, pgObject *obj);
+	bool CheckEnable(pgObject *obj);
+};
+
+
 #endif
diff --git a/pgadmin/schema/pgView.cpp b/pgadmin/schema/pgView.cpp
index 5a3e0c5..9e1660f 100644
--- a/pgadmin/schema/pgView.cpp
+++ b/pgadmin/schema/pgView.cpp
@@ -17,6 +17,7 @@
 #include "utils/misc.h"
 #include "schema/pgColumn.h"
 #include "schema/pgView.h"
+#include "frm/frmMain.h"
 #include "frm/frmHint.h"
 #include "schema/pgTrigger.h"
 
@@ -440,6 +441,17 @@ wxString pgView::GetUpdateSql(ctlTree *browser)
 	return sql;
 }
 
+
+void pgView::RefreshMatView(bool concurrently)
+{
+	wxString sql = wxT("REFRESH MATERIALIZED VIEW ");
+	if (concurrently)
+		sql += wxT("CONCURRENTLY ");
+	sql += GetQuotedFullIdentifier();
+	GetDatabase()->ExecuteVoid(sql);
+}
+
+
 void pgView::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
 {
 	if (!expandedKids)
@@ -864,3 +876,58 @@ pgCollection *pgViewFactory::CreateCollection(pgObject *obj)
 
 pgViewFactory viewFactory;
 static pgaCollectionFactory cf(&viewFactory, __("Views"), views_png_img);
+
+refreshMatViewFactory::refreshMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
+{
+	mnu->Append(id, _("&Refresh data"), _("Refresh data for the selected object."));
+}
+
+
+wxWindow *refreshMatViewFactory::StartDialog(frmMain *form, pgObject *obj)
+{
+	form->StartMsg(_("Refreshing data"));
+
+	((pgView *)obj)->RefreshMatView(false);
+	wxTreeItemId item = form->GetBrowser()->GetSelection();
+	if (obj == form->GetBrowser()->GetObject(item))
+		obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties());
+
+	form->EndMsg();
+
+	return 0;
+}
+
+
+bool refreshMatViewFactory::CheckEnable(pgObject *obj)
+{
+	return obj && obj->IsCreatedBy(viewFactory) && ((pgView *)obj)->GetMaterializedView();
+}
+
+
+refreshConcurrentlyMatViewFactory::refreshConcurrentlyMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
+{
+	mnu->Append(id, _("&Refresh data concurrently"), _("Refresh data concurrently for the selected object."));
+}
+
+
+wxWindow *refreshConcurrentlyMatViewFactory::StartDialog(frmMain *form, pgObject *obj)
+{
+	form->StartMsg(_("Refreshing data concurrently"));
+
+	((pgView *)obj)->RefreshMatView(true);
+	wxTreeItemId item = form->GetBrowser()->GetSelection();
+	if (obj == form->GetBrowser()->GetObject(item))
+		obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties());
+
+	form->EndMsg();
+
+	return 0;
+}
+
+
+bool refreshConcurrentlyMatViewFactory::CheckEnable(pgObject *obj)
+{
+	return obj && obj->IsCreatedBy(viewFactory)
+	       && ((pgView *)obj)->GetMaterializedView()
+	       && ((pgView *)obj)->GetConnection()->BackendMinimumVersion(9, 4);;
+}
-- 
1.9.0

