mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 06:05:49 -06:00
Это была непонятная реализация самих разработчиков. Там есть и другие не понятные для меня решения, к примеру нет явного указания ENABLE [ REPLICA | ALWAYS ].
350 lines
No EOL
11 KiB
C++
350 lines
No EOL
11 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// pgEventTrigger.cpp - EventTrigger class
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// wxWindows headers
|
|
#include <wx/wx.h>
|
|
|
|
// App headers
|
|
#include "pgAdmin3.h"
|
|
#include "frm/frmMain.h"
|
|
#include "utils/misc.h"
|
|
#include "schema/pgEventTrigger.h"
|
|
#include "schema/pgFunction.h"
|
|
#include "schema/pgSchema.h"
|
|
|
|
pgEventTrigger::pgEventTrigger(const wxString &newName)
|
|
: pgDatabaseObject(eventTriggerFactory, newName)
|
|
{
|
|
eventTriggerFunction = 0;
|
|
eventTriggerFunctionSchema = 0;
|
|
}
|
|
|
|
pgEventTrigger::~pgEventTrigger()
|
|
{
|
|
if (!expandedKids && eventTriggerFunction)
|
|
{
|
|
// eventTriggerFunction wasn't appended to tree, so we need to delete it manually.
|
|
delete eventTriggerFunction;
|
|
}
|
|
|
|
delete eventTriggerFunctionSchema;
|
|
}
|
|
|
|
pgCollection *pgEventTriggerFactory::CreateCollection(pgObject *obj)
|
|
{
|
|
return new pgEventTriggerCollection(GetCollectionFactory(), (pgDatabase *)obj);
|
|
}
|
|
|
|
pgObject *pgEventTriggerFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
|
|
{
|
|
wxString sql;
|
|
pgEventTrigger *eventTrigger = 0;
|
|
|
|
sql = wxT("SELECT e.oid, e.xmin, e.evtname AS name, e.evtevent AS eventname, pg_catalog.pg_get_userbyid(e.evtowner) AS eventowner, ")
|
|
wxT(" CASE e.evtenabled WHEN 'O' THEN 'enabled' WHEN 'R' THEN 'replica' WHEN 'A' THEN 'always' WHEN 'D' THEN 'disabled' END AS enabled, ")
|
|
wxT(" e.evtfoid AS eventfuncoid, e.evtfoid::regproc AS eventfunname, array_to_string(array(select quote_literal(x) from unnest(evttags) as t(x)), ', ') AS when, ")
|
|
wxT(" pg_catalog.obj_description(e.oid, 'pg_event_trigger') AS comment, ")
|
|
wxT(" p.prosrc AS source, p.pronamespace AS schemaoid, l.lanname AS language")
|
|
wxT(" FROM pg_event_trigger e\n")
|
|
wxT(" LEFT OUTER JOIN pg_proc p ON p.oid=e.evtfoid\n")
|
|
wxT(" LEFT OUTER JOIN pg_language l ON l.oid=p.prolang\n")
|
|
wxT(" WHERE 1=1 ");
|
|
|
|
if (!restriction.IsEmpty())
|
|
sql += restriction + wxT("\n");
|
|
sql += wxT(" ORDER BY e.evtname ");
|
|
|
|
pgSet *eventTriggers = collection->GetDatabase()->ExecuteSet(sql);
|
|
|
|
if (eventTriggers)
|
|
{
|
|
while (!eventTriggers->Eof())
|
|
{
|
|
eventTrigger = new pgEventTrigger(eventTriggers->GetVal(wxT("name")));
|
|
eventTrigger->iSetDatabase(collection->GetDatabase());
|
|
eventTrigger->iSetOid(eventTriggers->GetOid(wxT("oid")));
|
|
eventTrigger->iSetXid(eventTriggers->GetOid(wxT("xmin")));
|
|
eventTrigger->iSetOwner(eventTriggers->GetVal(wxT("eventowner")));
|
|
eventTrigger->iSetFunctionOid(eventTriggers->GetOid(wxT("eventfuncoid")));
|
|
eventTrigger->iSetLanguage(eventTriggers->GetVal(wxT("language")));
|
|
eventTrigger->iSetSource(eventTriggers->GetVal(wxT("source")));
|
|
eventTrigger->iSetEventName(eventTriggers->GetVal(wxT("eventname")));
|
|
eventTrigger->iSetFunction(eventTriggers->GetVal(wxT("eventfunname")));
|
|
(eventTriggers->GetVal(wxT("enabled")) == wxT("disabled")) ? eventTrigger->iSetEnabled(false), eventTrigger->iSetEnableStatus(wxT("disabled"))
|
|
: eventTrigger->iSetEnabled(true), eventTrigger->iSetEnableStatus(eventTriggers->GetVal(wxT("enabled")));
|
|
eventTrigger->iSetComment(eventTriggers->GetVal(wxT("comment")));
|
|
eventTrigger->iSetWhen(eventTriggers->GetVal(wxT("when")));
|
|
eventTrigger->iSetSchemaOid(eventTriggers->GetOid(wxT("schemaoid")));
|
|
|
|
if (browser)
|
|
{
|
|
browser->AppendObject(collection, eventTrigger);
|
|
eventTriggers->MoveNext();
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
delete eventTriggers;
|
|
}
|
|
return eventTrigger;
|
|
}
|
|
|
|
pgObject *pgEventTrigger::Refresh(ctlTree *browser, const wxTreeItemId item)
|
|
{
|
|
pgObject *eventTrigger = 0;
|
|
pgCollection *coll = browser->GetParentCollection(item);
|
|
|
|
if (coll)
|
|
{
|
|
wxString restr = wxT(" \n AND e.oid = ") + GetOidStr();
|
|
eventTrigger = eventTriggerFactory.CreateObjects(coll, 0, restr);
|
|
}
|
|
return eventTrigger;
|
|
}
|
|
|
|
void pgEventTrigger::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
|
|
{
|
|
if (!expandedKids && GetLanguage() != wxT("edbspl") && GetLanguage() != wxT("sql"))
|
|
{
|
|
if (browser)
|
|
{
|
|
// if no browser present, function will not be appended to tree
|
|
expandedKids = true;
|
|
}
|
|
|
|
if (eventTriggerFunction)
|
|
delete eventTriggerFunction;
|
|
|
|
wxString restr = wxT(" WHERE nsp.oid= ") + NumToStr(GetSchemaOid()) + wxT("::oid\n");
|
|
eventTriggerFunctionSchema = (pgSchema *)schemaFactory.CreateObjects((pgCollection *)browser->GetObject(GetId()), 0, restr);
|
|
|
|
// append function here
|
|
eventTriggerFunction = functionFactory.AppendFunctions(this, eventTriggerFunctionSchema, browser, wxT(" WHERE pr.oid = ") + NumToStr(functionOid) + wxT("::oid\n"));
|
|
if (eventTriggerFunction)
|
|
{
|
|
iSetFunction(eventTriggerFunction->GetQuotedFullIdentifier());
|
|
}
|
|
|
|
}
|
|
|
|
if (properties)
|
|
{
|
|
CreateListColumns(properties);
|
|
|
|
properties->AppendItem(_("Name"), GetName());
|
|
properties->AppendItem(_("OID"), GetOid());
|
|
properties->AppendItem(_("Event"), GetEventName());
|
|
properties->AppendItem(_("Function"), GetFunction());
|
|
properties->AppendItem(_("When?"), GetWhen());
|
|
properties->AppendItem(_("Enabled?"), GetEnabled() ? wxT("Yes") : wxT("No"));
|
|
properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));
|
|
}
|
|
}
|
|
|
|
void pgEventTrigger::SetDirty()
|
|
{
|
|
if (expandedKids)
|
|
eventTriggerFunction = 0;
|
|
pgObject::SetDirty();
|
|
}
|
|
|
|
wxString pgEventTrigger::GetSql(ctlTree *browser)
|
|
{
|
|
if (sql.IsNull() && (this->eventTriggerFunction))
|
|
{
|
|
sql = wxT("-- Event Trigger: ") + qtIdent(GetName()) + wxT(" on database ")
|
|
+ qtIdent(((pgCollection *)browser->GetObject(GetId()))->GetDatabase()->GetName()) + wxT("\n\n")
|
|
+ wxT("-- DROP EVENT TRIGGER ") + qtIdent(GetName()) + wxT(";\n\n");
|
|
|
|
sql += wxT("CREATE EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" ON ")
|
|
+ GetEventName() + (GetWhen().IsEmpty() ? wxT("") : (wxT(" WHEN TAG IN (") + GetWhen() + wxT(")\n\n")));
|
|
|
|
// Event trigger backend function don't accept any arguments.
|
|
// Hence, it's not required to get/set empty arguments.
|
|
|
|
sql += wxT(" EXECUTE PROCEDURE ") + eventTriggerFunction->GetQuotedFullIdentifier() + wxT("();\n\n");
|
|
|
|
if (!GetEnabled())
|
|
{
|
|
sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" DISABLE;\n");
|
|
}
|
|
|
|
if (!GetComment().IsEmpty())
|
|
sql += wxT("COMMENT ON EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n");
|
|
}
|
|
return sql;
|
|
}
|
|
|
|
wxString pgEventTrigger::GetTranslatedMessage(int kindOfMessage) const
|
|
{
|
|
wxString message = wxEmptyString;
|
|
|
|
switch (kindOfMessage)
|
|
{
|
|
case RETRIEVINGDETAILS:
|
|
message = _("Retrieving details on event trigger");
|
|
message += wxT(" ") + GetName();
|
|
break;
|
|
case REFRESHINGDETAILS:
|
|
message = _("Refreshing event trigger");
|
|
message += wxT(" ") + GetName();
|
|
break;
|
|
case DROPCASCADETITLE:
|
|
message = _("Drop event trigger cascaded?");
|
|
break;
|
|
case DROPTITLE:
|
|
message = _("Drop event trigger?");
|
|
break;
|
|
case DROPINCLUDINGDEPS:
|
|
message = wxString::Format(_("Are you sure you wish to drop event trigger \"%s\" including all objects that depend on it?"),
|
|
GetFullIdentifier().c_str());
|
|
break;
|
|
case DROPEXCLUDINGDEPS:
|
|
message = wxString::Format(_("Are you sure you wish to drop event trigger \"%s\"?"),
|
|
GetFullIdentifier().c_str());
|
|
break;
|
|
case PROPERTIESREPORT:
|
|
message = _("Event trigger properties report");
|
|
message += wxT(" - ") + GetName();
|
|
break;
|
|
case DDLREPORT:
|
|
message = _("Event trigger DDL report");
|
|
message += wxT(" - ") + GetName();
|
|
break;
|
|
case DDL:
|
|
message = _("Event trigger DDL");
|
|
break;
|
|
}
|
|
return message;
|
|
}
|
|
|
|
int pgEventTrigger::GetIconId()
|
|
{
|
|
if (GetEnabled())
|
|
return eventTriggerFactory.GetIconId();
|
|
else
|
|
return eventTriggerFactory.GetClosedIconId();
|
|
}
|
|
|
|
|
|
wxString pgEventTriggerCollection::GetTranslatedMessage(int kindOfMessage) const
|
|
{
|
|
wxString message = wxEmptyString;
|
|
|
|
switch (kindOfMessage)
|
|
{
|
|
case RETRIEVINGDETAILS:
|
|
message = _("Retrieving details on event triggers");
|
|
break;
|
|
case REFRESHINGDETAILS:
|
|
message = _("Refreshing event triggers");
|
|
break;
|
|
case OBJECTSLISTREPORT:
|
|
message = _("Event triggers list report");
|
|
break;
|
|
}
|
|
return message;
|
|
}
|
|
|
|
bool pgEventTrigger::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
|
|
{
|
|
wxString sql = wxT("DROP EVENT TRIGGER ") + qtIdent(GetName());
|
|
if (cascaded)
|
|
sql += wxT(" CASCADE");
|
|
sql += wxT(" ;");
|
|
|
|
return GetDatabase()->ExecuteVoid(sql);
|
|
}
|
|
|
|
void pgEventTrigger::SetEnabled(ctlTree *browser, const bool b)
|
|
{
|
|
if (qtIdent(GetName()).Len() > 0 && ((enabled && !b) || (!enabled && b)))
|
|
{
|
|
wxString sql = wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) ;
|
|
if (enabled && !b)
|
|
sql += wxT(" DISABLE");
|
|
else if (!enabled && b)
|
|
sql += wxT(" ENABLE");
|
|
GetDatabase()->ExecuteVoid(sql);
|
|
}
|
|
enabled = b;
|
|
UpdateIcon(browser);
|
|
}
|
|
|
|
bool pgEventTrigger::IsUpToDate()
|
|
{
|
|
wxString sql = wxT("SELECT xmin FROM pg_event_trigger WHERE oid = ") + this->GetOidStr();
|
|
if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid()))
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
/////////////////////////////
|
|
|
|
pgEventTriggerCollection::pgEventTriggerCollection(pgaFactory *factory, pgDatabase *db)
|
|
: pgDatabaseObjCollection(factory, db)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////
|
|
|
|
#include "images/trigger.pngc"
|
|
#include "images/triggerbad.pngc"
|
|
#include "images/triggers.pngc"
|
|
|
|
pgEventTriggerFactory::pgEventTriggerFactory()
|
|
: pgDatabaseObjFactory(__("Event Trigger"), __("New Event Trigger..."), __("Create a new Event Trigger."), trigger_png_img)
|
|
{
|
|
metaType = PGM_EVENTTRIGGER;
|
|
closedId = addIcon(triggerbad_png_img);
|
|
}
|
|
|
|
pgEventTriggerFactory eventTriggerFactory;
|
|
static pgaCollectionFactory cf(&eventTriggerFactory, __("Event Triggers"), triggers_png_img);
|
|
|
|
enabledisableEventTriggerFactory::enabledisableEventTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
|
|
{
|
|
mnu->Append(id, _("Event trigger enabled?"), _("Enable or disable selected event trigger."), wxITEM_CHECK);
|
|
}
|
|
|
|
wxWindow *enabledisableEventTriggerFactory::StartDialog(frmMain *form, pgObject *obj)
|
|
{
|
|
((pgEventTrigger *)obj)->SetEnabled(form->GetBrowser(), !((pgEventTrigger *)obj)->GetEnabled());
|
|
((pgEventTrigger *)obj)->SetDirty();
|
|
|
|
wxTreeItemId item = form->GetBrowser()->GetSelection();
|
|
if (obj == form->GetBrowser()->GetObject(item))
|
|
{
|
|
form->GetBrowser()->DeleteChildren(item);
|
|
obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties());
|
|
form->GetSqlPane()->SetReadOnly(false);
|
|
form->GetSqlPane()->SetText(((pgEventTrigger *)obj)->GetSql(form->GetBrowser()));
|
|
form->GetSqlPane()->SetReadOnly(true);
|
|
}
|
|
form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar());
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool enabledisableEventTriggerFactory::CheckEnable(pgObject *obj)
|
|
{
|
|
return obj && obj->IsCreatedBy(eventTriggerFactory) && obj->CanEdit()
|
|
&& ((pgEventTrigger *)obj)->GetConnection()->BackendMinimumVersion(9, 3);
|
|
}
|
|
|
|
bool enabledisableEventTriggerFactory::CheckChecked(pgObject *obj)
|
|
{
|
|
return obj && obj->IsCreatedBy(eventTriggerFactory) && ((pgEventTrigger *)obj)->GetEnabled();
|
|
} |