Hi, It was much easier than I previously thought. This patch adds a Triggers node in the each view object node if you're connected to a 9.1 PostgreSQL server. You can add and see triggers on views.
It's not ready to be commited. I still have a bug to fix. I tried since two days, and I can't make it work. My issue is with the Triggers node. I should have the "Create a new object..." button enabled in the toolbar and a "New trigger" (or whatever it's labelled) item in the contextual menu. But I don't have them. I really don't understand why. View objects seem to be treated differently than others but, despite many tests, I can't make it work. You can still test the patch because you have the capacity to create a trigger on a view with a contextual menu available on the view object node. If someone has a pointer to help me fix this patch, I would really appreciate it. -- Guillaume http://www.postgresql.fr http://dalibo.com
>From 6faa81d364f44f15bc0f63936c767e0f5ac42d52 Mon Sep 17 00:00:00 2001 From: Guillaume Lelarge <[email protected]> Date: Fri, 22 Oct 2010 17:15:44 -0700 Subject: [PATCH] New kind of trigger: INSTEAD OF This patch adds support to INSTEAD OF triggers. This is part of the 9.1 PostgreSQL release. It's only available for views. Implements #256. --- pgadmin/dlg/dlgTrigger.cpp | 26 +++++++++++++++++--------- pgadmin/include/schema/pgTrigger.h | 1 + pgadmin/include/schema/pgView.h | 1 + pgadmin/include/utils/pgDefs.h | 1 + pgadmin/schema/pgTrigger.cpp | 13 +++++++++++-- pgadmin/schema/pgView.cpp | 8 +++++++- pgadmin/ui/dlgTrigger.xrc | 1 + 7 files changed, 39 insertions(+), 12 deletions(-) diff --git a/pgadmin/dlg/dlgTrigger.cpp b/pgadmin/dlg/dlgTrigger.cpp index 3661d5b..65e89f4 100644 --- a/pgadmin/dlg/dlgTrigger.cpp +++ b/pgadmin/dlg/dlgTrigger.cpp @@ -66,14 +66,13 @@ dlgProperty *pgTriggerFactory::CreateDialog(frmMain *frame, pgObject *node, pgOb } - - dlgTrigger::dlgTrigger(pgaFactory *f, frmMain *frame, pgTrigger *node, pgTable *parentNode) : dlgCollistProperty(f, frame, wxT("dlgTrigger"), parentNode) { trigger=node; table=parentNode; - wxASSERT(!table || table->GetMetaType() == PGM_TABLE || table->GetMetaType() == GP_PARTITION); + wxASSERT(!table || table->GetMetaType() == PGM_TABLE || table->GetMetaType() == PGM_VIEW + || table->GetMetaType() == GP_PARTITION); bool bVal; settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); @@ -120,7 +119,12 @@ int dlgTrigger::Go(bool modal) chkUpdate->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE) != 0); chkDelete->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_DELETE) != 0); chkTruncate->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE) != 0); - rdbFires->SetSelection(trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : 1); + if (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE) + rdbFires->SetSelection(0); + else if (trigger->GetTriggerType() & TRIGGER_TYPE_INSTEAD) + rdbFires->SetSelection(2); + else + rdbFires->SetSelection(1); txtArguments->SetValue(trigger->GetArguments()); txtWhen->SetValue(trigger->GetWhen()); if (!connection->BackendMinimumVersion(7, 4)) @@ -196,6 +200,8 @@ int dlgTrigger::Go(bool modal) if (!connection->BackendMinimumVersion(8, 4)) chkTruncate->Disable(); + if (!connection->BackendMinimumVersion(9, 1) || table->GetMetaType() != PGM_VIEW) + rdbFires->Enable(2, false); } cbColumns->Disable(); @@ -259,15 +265,17 @@ wxString dlgTrigger::GetSql() chkUpdate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE ? true : false) || chkDelete->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_DELETE ? true : false) || chkTruncate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE ? true : false) || - rdbFires->GetSelection() != (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : 1)) + rdbFires->GetSelection() != (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : TRIGGER_TYPE_INSTEAD ? 2 : 1)) { if (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) sql += wxT("CREATE OR REPLACE TRIGGER ") + qtIdent(name); else sql += wxT("CREATE TRIGGER ") + qtIdent(name); - if (rdbFires->GetSelection()) + if (rdbFires->GetSelection() == 1) sql += wxT(" AFTER"); + else if (rdbFires->GetSelection() == 2) + sql += wxT(" INSTEAD OF"); else sql += wxT(" BEFORE"); int actionCount=0; @@ -400,14 +408,14 @@ void dlgTrigger::CheckChange() wxString name=GetName(); // We can only have per-statement TRUNCATE triggers - if (connection->BackendMinimumVersion(8, 4)) + if (trigger || connection->BackendMinimumVersion(8, 4)) { if (chkRow->GetValue()) { chkTruncate->Disable(); chkTruncate->SetValue(false); } - else + else if (connection->EdbMinimumVersion(8,0)) chkTruncate->Enable(); } @@ -432,7 +440,7 @@ void dlgTrigger::CheckChange() chkUpdate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE ? true : false) || chkDelete->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_DELETE ? true : false) || chkTruncate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE ? true : false) || - rdbFires->GetSelection() != (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : 1))); + rdbFires->GetSelection() != (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : (trigger->GetTriggerType() & TRIGGER_TYPE_INSTEAD ? 2 : 1)))); } else { diff --git a/pgadmin/include/schema/pgTrigger.h b/pgadmin/include/schema/pgTrigger.h index 8e6c9b5..0637056 100644 --- a/pgadmin/include/schema/pgTrigger.h +++ b/pgadmin/include/schema/pgTrigger.h @@ -64,6 +64,7 @@ public: wxArrayString GetColumnList() const { return columnList; } long GetColumnCount() const { return columnCount; } void iSetColumnCount(const long l) { columnCount=l; } + bool GetParentIsTable() { return table && table->GetMetaType() == PGM_TABLE; } void SetDirty(); diff --git a/pgadmin/include/schema/pgView.h b/pgadmin/include/schema/pgView.h index 0863374..9704a7d 100644 --- a/pgadmin/include/schema/pgView.h +++ b/pgadmin/include/schema/pgView.h @@ -37,6 +37,7 @@ public: bool CanDropCascaded() { return !GetSystemObject() && pgSchemaObject::CanDrop(); } bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool CanCreate() { return GetSchema()->CanCreate(); } bool CanView() { return true; } bool WantDummyChild() { return true; } diff --git a/pgadmin/include/utils/pgDefs.h b/pgadmin/include/utils/pgDefs.h index bd55d06..f26d4c5 100644 --- a/pgadmin/include/utils/pgDefs.h +++ b/pgadmin/include/utils/pgDefs.h @@ -71,5 +71,6 @@ #define TRIGGER_TYPE_DELETE (1 << 3) #define TRIGGER_TYPE_UPDATE (1 << 4) #define TRIGGER_TYPE_TRUNCATE (1 << 5) +#define TRIGGER_TYPE_INSTEAD (1 << 6) #endif diff --git a/pgadmin/schema/pgTrigger.cpp b/pgadmin/schema/pgTrigger.cpp index 222e248..5a24af8 100644 --- a/pgadmin/schema/pgTrigger.cpp +++ b/pgadmin/schema/pgTrigger.cpp @@ -195,7 +195,15 @@ wxString pgTrigger::GetSql(ctlTree *browser) wxString pgTrigger::GetFireWhen() const { - return (triggerType & TRIGGER_TYPE_BEFORE) ? wxT("BEFORE") : wxT("AFTER"); + wxString when = wxEmptyString; + + if (triggerType & TRIGGER_TYPE_BEFORE) + when = wxT("BEFORE"); + else if (triggerType & TRIGGER_TYPE_INSTEAD) + when = wxT("INSTEAD OF"); + else + when = wxT("AFTER"); + return when; } @@ -503,7 +511,8 @@ wxWindow *enabledisableTriggerFactory::StartDialog(frmMain *form, pgObject *obj) bool enabledisableTriggerFactory::CheckEnable(pgObject *obj) { return obj && obj->IsCreatedBy(triggerFactory) && obj->CanEdit() - && ((pgTrigger*)obj)->GetConnection()->BackendMinimumVersion(8, 1); + && ((pgTrigger*)obj)->GetConnection()->BackendMinimumVersion(8, 1) + && ((pgTrigger*)obj)->GetParentIsTable(); } bool enabledisableTriggerFactory::CheckChecked(pgObject *obj) diff --git a/pgadmin/schema/pgView.cpp b/pgadmin/schema/pgView.cpp index f97466f..33272f2 100644 --- a/pgadmin/schema/pgView.cpp +++ b/pgadmin/schema/pgView.cpp @@ -18,6 +18,7 @@ #include "schema/pgColumn.h" #include "schema/pgView.h" #include "frm/frmHint.h" +#include "schema/pgTrigger.h" pgView::pgView(pgSchema *newSchema, const wxString& newName) @@ -107,8 +108,10 @@ wxMenu *pgView::GetNewMenu() { wxMenu *menu=pgObject::GetNewMenu(); if (schema->GetCreatePrivilege()) + { ruleFactory.AppendMenu(menu); - + triggerFactory.AppendMenu(menu); + } return menu; } @@ -172,6 +175,7 @@ wxString pgView::GetSql(ctlTree *browser) } AppendStuff(sql, browser, ruleFactory); + AppendStuff(sql, browser, triggerFactory); } return sql; } @@ -280,6 +284,8 @@ void pgView::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *proper hasDeleteRule = true; } + if (GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, triggerFactory); } if (properties) { diff --git a/pgadmin/ui/dlgTrigger.xrc b/pgadmin/ui/dlgTrigger.xrc index 7af64e9..091803c 100644 --- a/pgadmin/ui/dlgTrigger.xrc +++ b/pgadmin/ui/dlgTrigger.xrc @@ -104,6 +104,7 @@ <content> <item>BEFORE</item> <item>AFTER</item> + <item>INSTEAD OF</item> </content> <selection>0</selection> <dimension>1</dimension> -- 1.7.1
-- Sent via pgadmin-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgadmin-hackers
