1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // dlgEventTrigger.cpp - PostgreSQL Trigger Property
9 //
10 //////////////////////////////////////////////////////////////////////////
11 
12 // wxWindows headers
13 #include <wx/wx.h>
14 
15 // App headers
16 #include "pgAdmin3.h"
17 #include "utils/misc.h"
18 #include "frm/frmMain.h"
19 #include "utils/pgDefs.h"
20 
21 #include "dlg/dlgEventTrigger.h"
22 #include "schema/pgEventTrigger.h"
23 #include "ctl/ctlSeclabelPanel.h"
24 
25 // pointer to controls
26 #define chkEnable		CTRL_CHECKBOX("chkEnable")
27 #define rdbEnableStatus CTRL_RADIOBOX("rdbEnableStatus")
28 #define cbFunction		CTRL_COMBOBOX2("cbFunction")
29 #define rdbEvents		CTRL_RADIOBOX("rdbEvents")
30 #define txtWhen			CTRL_TEXT("txtWhen")
31 #define cbOwner			CTRL_COMBOBOX2("cbOwner")
32 
33 BEGIN_EVENT_TABLE(dlgEventTrigger, dlgProperty)
34 	EVT_CHECKBOX(XRCID("chkEnable"),				dlgEventTrigger::OnChangeEnable)
35 	EVT_RADIOBOX(XRCID("rdbEnableStatus"),			dlgProperty::OnChange)
36 	EVT_COMBOBOX(XRCID("cbFunction"),				dlgProperty::OnChange)
37 	EVT_RADIOBOX(XRCID("rdbEvents"),				dlgProperty::OnChange)
38 	EVT_TEXT(XRCID("txtWhen"),						dlgProperty::OnChange)
39 END_EVENT_TABLE();
40 
dlgEventTrigger(pgaFactory * factory,frmMain * frame,pgEventTrigger * node,pgObject * parent)41 dlgEventTrigger::dlgEventTrigger(pgaFactory *factory, frmMain *frame, pgEventTrigger *node, pgObject *parent)
42 	: dlgProperty(factory, frame, wxT("dlgEventTrigger"))
43 {
44 	seclabelPage = new ctlSeclabelPanel(nbNotebook);
45 	eventTrigger = node;
46 }
47 
CreateDialog(frmMain * frame,pgObject * node,pgObject * parent)48 dlgProperty *pgEventTriggerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
49 {
50 	return new dlgEventTrigger(this, frame, (pgEventTrigger *)node, parent);
51 }
52 
GetSql()53 wxString dlgEventTrigger::GetSql()
54 {
55 	wxString sql = wxEmptyString;
56 	wxString name = GetName();
57 
58 	if (eventTrigger)
59 	{
60 		if (!GetName().IsEmpty() && GetName() != eventTrigger->GetName())
61 			sql = wxT("ALTER EVENT TRIGGER ") + eventTrigger->GetQuotedFullIdentifier() + wxT("\nRENAME TO ") + qtIdent(GetName()) + wxT(";\n\n");
62 
63 		if (!cbOwner->GetValue().IsEmpty() && cbOwner->GetValue() != eventTrigger->GetOwner())
64 			sql += wxT("ALTER EVENT TRIGGER ") + eventTrigger->GetQuotedFullIdentifier() + wxT("\nOWNER TO ") + cbOwner->GetValue() + wxT(";\n\n");
65 
66 		if (rdbEnableStatus->GetSelection() != 0 && chkEnable->GetValue())
67 			sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + ((rdbEnableStatus->GetSelection() == 1) ? wxT(" ENABLE REPLICA ;\n\n") : wxT(" ENABLE ALWAYS ;\n\n"));
68 		else if (!chkEnable->GetValue())
69 			sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + wxT(" DISABLE ;\n\n");
70 	}
71 
72 	if (!eventTrigger ||
73 	        (
74 	            cbFunction->GetValue() != (eventTrigger->GetFunction()) ||
75 	            rdbEvents->GetStringSelection().Lower() != (eventTrigger->GetEventName().Lower()) ||
76 	            txtWhen->GetValue() != (eventTrigger->GetWhen())
77 	        )
78 	   )
79 	{
80 		if (eventTrigger)
81 			sql  = wxT("DROP EVENT TRIGGER IF EXISTS ") + ((eventTrigger) ? qtIdent(eventTrigger->GetName()) : qtIdent(GetName())) + wxT(";\n\n");
82 
83 		sql += wxT("CREATE EVENT TRIGGER ") + qtIdent(name) + wxT(" ON ");
84 
85 		if (rdbEvents->GetSelection() == 0)
86 			sql += wxT(" DDL_COMMAND_START ");
87 		else if (rdbEvents->GetSelection() == 1)
88 			sql += wxT(" DDL_COMMAND_END ");
89 		else
90 			sql += wxT(" SQL_DROP ");
91 
92 		if (!txtWhen->IsEmpty())
93 			sql += wxT("\nWHEN TAG IN (") + txtWhen->GetValue() + wxT(")");
94 
95 		if (!cbFunction->GetValue().IsEmpty())
96 			sql += wxT("\nEXECUTE PROCEDURE ") + (cbFunction->GetValue()) + wxT("();\n\n");
97 
98 		if (rdbEnableStatus->GetSelection() != 0 && chkEnable->GetValue())
99 			sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + ((rdbEnableStatus->GetSelection() == 1) ? wxT(" ENABLE REPLICA ;\n\n") : wxT(" ENABLE ALWAYS ;\n\n"));
100 		else if (!chkEnable->GetValue())
101 			sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + wxT(" DISABLE ;\n\n");
102 
103 		if (!eventTrigger && !cbOwner->GetValue().IsEmpty())
104 			sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) + wxT("\nOWNER TO ") + cbOwner->GetValue() + wxT(";\n\n");
105 	}
106 
107 	AppendComment(sql, wxT("EVENT TRIGGER ") + qtIdent(GetName()), eventTrigger);
108 
109 	if (seclabelPage)
110 		sql += seclabelPage->GetSqlForSecLabels(wxT("EVENT TRIGGER"), qtIdent(name));
111 
112 	return sql;
113 }
114 
CreateObject(pgCollection * pgcol)115 pgObject *dlgEventTrigger::CreateObject(pgCollection *pgcol)
116 {
117 	pgObject *obj = eventTriggerFactory.CreateObjects(pgcol, 0,
118 	                wxT(" \n AND e.evtname = ") + qtDbString(GetName()));
119 	return obj;
120 }
121 
GetObject()122 pgObject *dlgEventTrigger::GetObject()
123 {
124 	return eventTrigger;
125 }
126 
Go(bool modal)127 int dlgEventTrigger::Go(bool modal)
128 {
129 	seclabelPage->SetConnection(connection);
130 	seclabelPage->SetObject(eventTrigger);
131 	this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgEventTrigger::OnChange));
132 
133 	if (eventTrigger)
134 	{
135 		// Edit mode
136 		chkEnable->SetValue(eventTrigger->GetEnabled());
137 
138 		if (eventTrigger->GetEnableStatus() == wxT("enabled"))
139 			rdbEnableStatus->SetSelection(0);
140 		else if(eventTrigger->GetEnableStatus() == wxT("replica"))
141 			rdbEnableStatus->SetSelection(1);
142 		else if(eventTrigger->GetEnableStatus() == wxT("always"))
143 			rdbEnableStatus->SetSelection(2);
144 		else
145 			rdbEnableStatus->Disable();
146 
147 		if(eventTrigger->GetEventName().Lower() == wxT("ddl command start"))
148 			rdbEvents->SetSelection(0);
149 		else if(eventTrigger->GetEventName().Lower() == wxT("ddl command end"))
150 			rdbEvents->SetSelection(1);
151 		else
152 			rdbEvents->SetSelection(2);
153 
154 		cbFunction->SetValue(eventTrigger->GetFunction());
155 		cbOwner->SetValue(eventTrigger->GetOwner());
156 		(!eventTrigger->GetWhen().IsEmpty()) ? txtWhen->SetValue(eventTrigger->GetWhen()) : txtWhen->SetValue(wxEmptyString);
157 	}
158 	else
159 	{
160 		// Create mode
161 		chkEnable->SetValue(true);
162 		rdbEnableStatus->Disable();
163 	}
164 
165 	pgSet *funcSet = connection->ExecuteSet(
166 	                     wxT("SELECT quote_ident(nspname) || '.' || quote_ident(proname)\n")
167 	                     wxT(" FROM pg_proc p, pg_namespace n, pg_language l\n")
168 	                     wxT(" WHERE p.pronamespace = n.oid AND p.prolang = l.oid AND p.pronargs = 0 AND l.lanname != 'sql' AND prorettype::regtype::text = 'event_trigger'\n")
169 	                     wxT(" ORDER BY nspname ASC, proname ASC "));
170 	if (funcSet)
171 	{
172 		while (!funcSet->Eof())
173 		{
174 			cbFunction->Append(funcSet->GetVal(0));
175 			funcSet->MoveNext();
176 		}
177 		delete funcSet;
178 	}
179 
180 	pgSet *userSet = connection->ExecuteSet(
181 	                     wxT("SELECT usename ")
182 	                     wxT("FROM	pg_user ")
183 	                     wxT("WHERE  usesuper IS TRUE"));
184 	if (userSet)
185 	{
186 		while (!userSet->Eof())
187 		{
188 			cbOwner->Append(userSet->GetVal(0));
189 			userSet->MoveNext();
190 		}
191 		delete userSet;
192 	}
193 
194 	return  dlgProperty::Go(modal);
195 }
196 
CheckChange()197 void dlgEventTrigger::CheckChange()
198 {
199 	bool enable = true;
200 
201 	wxString function = cbFunction->GetValue();
202 	wxString name = GetName();
203 	wxString owner = cbOwner->GetValue();
204 
205 	(chkEnable->GetValue()) ? rdbEnableStatus->Enable() : rdbEnableStatus->Disable();
206 
207 	CheckValid(enable, !name.IsEmpty(), _("Please specify event trigger name."));
208 	CheckValid(enable, !owner.IsEmpty(), _("Please specify owner of event trigger."));
209 	CheckValid(enable, !function.IsEmpty(), _("Please specify event trigger function."));
210 
211 	if (eventTrigger)
212 	{
213 		EnableOK(enable &&
214 		         (txtComment->GetValue() != eventTrigger->GetComment() ||
215 		          txtName->GetValue() != eventTrigger->GetName() ||
216 		          txtWhen->GetValue() != eventTrigger->GetWhen() ||
217 		          chkEnable->GetValue() != eventTrigger->GetEnabled() ||
218 		          rdbEvents->GetStringSelection().Lower() != eventTrigger->GetEventName().Lower() ||
219 		          rdbEnableStatus->GetStringSelection().Lower() != eventTrigger->GetEnableStatus().Lower() ||
220 		          !function.IsEmpty() ||
221 		          !owner.IsEmpty()
222 		         )
223 		        );
224 	}
225 	else
226 	{
227 		EnableOK(enable);
228 	}
229 }
230 
IsUpToDate()231 bool dlgEventTrigger::IsUpToDate()
232 {
233 	if (eventTrigger && !eventTrigger->IsUpToDate())
234 		return false;
235 	else
236 		return true;
237 }
238 
OnChange(wxCommandEvent & ev)239 void dlgEventTrigger::OnChange(wxCommandEvent &ev)
240 {
241 	CheckChange();
242 }
243 
OnChangeEnable(wxCommandEvent & ev)244 void dlgEventTrigger::OnChangeEnable(wxCommandEvent &ev)
245 {
246 	CheckChange();
247 }
248