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