Hi,

Here is a patch that adds support for the constraint trigger, a feature
available since 8.2.

This patch adds a Constraint checkbox and the deferrable and deferred
checkboxes. Note that the "FROM referenced_table_name" clause is not
implemented as it "is not recommended for general use" according to the
manual.

I'm not sure the design is really good as I had to increase the dialog's
height quite a lot. It would probably be a good idea to add a new tab
and push some controls over there.

Comments?


-- 
Guillaume
 http://www.postgresql.fr
 http://dalibo.com
>From e2f031889723c06848f9e1a426a17d1f46a07caf Mon Sep 17 00:00:00 2001
From: Guillaume Lelarge <[email protected]>
Date: Sun, 20 Mar 2011 17:05:25 +0100
Subject: [PATCH] Implements support for constraint trigger

This patch adds a Constraint checkbox and the deferrable and deferred
checkboxes. Note that the "FROM referenced_table_name" clause is not
implemented as it "is not recommended for general use" according to the
manual.

Report from Dan S.
---
 pgadmin/dlg/dlgTrigger.cpp         |   59 +++++++++++++++++++++++++++++++++--
 pgadmin/include/dlg/dlgTrigger.h   |    1 +
 pgadmin/include/schema/pgTrigger.h |   26 +++++++++++++++-
 pgadmin/schema/pgTrigger.cpp       |   36 +++++++++++++++++++---
 pgadmin/ui/dlgTrigger.xrc          |   51 ++++++++++++++++++++++++++++--
 5 files changed, 159 insertions(+), 14 deletions(-)

diff --git a/pgadmin/dlg/dlgTrigger.cpp b/pgadmin/dlg/dlgTrigger.cpp
index 19d4389..9eb41e7 100644
--- a/pgadmin/dlg/dlgTrigger.cpp
+++ b/pgadmin/dlg/dlgTrigger.cpp
@@ -26,6 +26,9 @@
 
 // pointer to controls
 #define chkRow          CTRL_CHECKBOX("chkRow")
+#define chkConstraint   CTRL_CHECKBOX("chkConstraint")
+#define chkDeferrable   CTRL_CHECKBOX("chkDeferrable")
+#define chkDeferred     CTRL_CHECKBOX("chkDeferred")
 #define cbFunction      CTRL_COMBOBOX2("cbFunction")
 #define txtArguments    CTRL_TEXT("txtArguments")
 #define rdbFires        CTRL_RADIOBOX("rdbFires")
@@ -42,6 +45,8 @@
 
 BEGIN_EVENT_TABLE(dlgTrigger, dlgCollistProperty)
 	EVT_RADIOBOX(XRCID("rdbFires"),                 dlgProperty::OnChange)
+	EVT_CHECKBOX(XRCID("chkConstraint"),            dlgTrigger::OnChangeConstraint)
+	EVT_CHECKBOX(XRCID("chkDeferrable"),            dlgProperty::OnChange)
 	EVT_CHECKBOX(XRCID("chkRow"),                   dlgProperty::OnChange)
 	EVT_CHECKBOX(XRCID("chkInsert"),                dlgProperty::OnChange)
 	EVT_CHECKBOX(XRCID("chkUpdate"),                dlgTrigger::OnChange)
@@ -164,6 +169,16 @@ int dlgTrigger::Go(bool modal)
 		{
 			lstColumns->InsertItem(colIdx, colsArr.Item(colIdx));
 		}
+
+		if (connection->BackendMinimumVersion(8, 2))
+		{
+			chkConstraint->SetValue(trigger->GetIsConstraint());
+			chkDeferrable->SetValue(trigger->GetDeferrable());
+			chkDeferred->SetValue(trigger->GetDeferred());
+		}
+		chkConstraint->Enable(false);
+		chkDeferrable->Enable(false);
+		chkDeferred->Enable(false);
 	}
 	else
 	{
@@ -202,6 +217,10 @@ int dlgTrigger::Go(bool modal)
 
 		if (!connection->BackendMinimumVersion(9, 1) || table->GetMetaType() != PGM_VIEW)
 			rdbFires->Enable(2, false);
+
+		chkConstraint->Enable(connection->BackendMinimumVersion(8, 2));
+		chkDeferrable->Disable();
+		chkDeferred->Disable();
 	}
 
 	cbColumns->Disable();
@@ -268,9 +287,12 @@ wxString dlgTrigger::GetSql()
 	        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);
+			sql += wxT("CREATE OR REPLACE TRIGGER ");
+		else if (chkConstraint->GetValue())
+			sql += wxT("CREATE CONSTRAINT TRIGGER ");
 		else
-			sql += wxT("CREATE TRIGGER ") + qtIdent(name);
+			sql += wxT("CREATE TRIGGER ");
+		sql += qtIdent(name);
 
 		if (rdbFires->GetSelection() == 1)
 			sql += wxT(" AFTER");
@@ -305,8 +327,14 @@ wxString dlgTrigger::GetSql()
 				sql += wxT(" OR");
 			sql += wxT(" TRUNCATE");
 		}
-		sql += wxT("\n   ON ") + table->GetQuotedFullIdentifier()
-		       + wxT(" FOR EACH ");
+		sql += wxT("\n   ON ") + table->GetQuotedFullIdentifier();
+		if (chkDeferrable->GetValue())
+		{
+			sql += wxT(" DEFERRABLE");
+			if (chkDeferred->GetValue())
+				sql += wxT(" INITIALLY DEFERRED");
+		}
+		sql += wxT(" FOR EACH ");
 		if (chkRow->GetValue())
 			sql += wxT("ROW");
 		else
@@ -400,6 +428,29 @@ void dlgTrigger::OnChangeFunc(wxCommandEvent &ev)
 }
 
 
+void dlgTrigger::OnChangeConstraint(wxCommandEvent &ev)
+{
+	if (chkConstraint->GetValue())
+	{
+		rdbFires->SetSelection(1);
+		rdbFires->Disable();
+		chkRow->SetValue(true);
+		chkRow->Disable();
+		chkDeferrable->Enable();
+		chkDeferred->Enable();
+	}
+	else
+	{
+		rdbFires->Enable();
+		chkRow->Enable();
+		chkDeferrable->Disable();
+		chkDeferred->Disable();
+	}
+
+	CheckChange();
+}
+
+
 void dlgTrigger::CheckChange()
 {
 	bool enable = true;
diff --git a/pgadmin/include/dlg/dlgTrigger.h b/pgadmin/include/dlg/dlgTrigger.h
index d8d8056..0c05fb8 100644
--- a/pgadmin/include/dlg/dlgTrigger.h
+++ b/pgadmin/include/dlg/dlgTrigger.h
@@ -41,6 +41,7 @@ private:
 
 	void OnChange(wxCommandEvent &ev);
 	void OnChangeFunc(wxCommandEvent &ev);
+	void OnChangeConstraint(wxCommandEvent &ev);
 	void OnSelectComboCol(wxCommandEvent &ev);
 	void OnSelectListCol(wxListEvent &ev);
 	void OnSelectCol();
diff --git a/pgadmin/include/schema/pgTrigger.h b/pgadmin/include/schema/pgTrigger.h
index d26bd9a..60e83ca 100644
--- a/pgadmin/include/schema/pgTrigger.h
+++ b/pgadmin/include/schema/pgTrigger.h
@@ -97,6 +97,30 @@ public:
 	{
 		return when;
 	}
+	bool GetIsConstraint() const
+	{
+		return isconstraint;
+	}
+	void SetIsConstraint(const bool b)
+	{
+		isconstraint = b;
+	}
+	bool GetDeferrable() const
+	{
+		return deferrable;
+	}
+	void iSetDeferrable(const bool b)
+	{
+		deferrable = b;
+	}
+	bool GetDeferred() const
+	{
+		return deferred;
+	}
+	void iSetDeferred(const bool b)
+	{
+		deferred = b;
+	}
 	wxString GetLanguage() const
 	{
 		return language;
@@ -213,7 +237,7 @@ private:
 	long columnCount;
 	OID functionOid;
 	long triggerType;
-	bool enabled, parentistable;
+	bool enabled, parentistable, isconstraint, deferrable, deferred;
 	pgFunction *triggerFunction;
 };
 
diff --git a/pgadmin/schema/pgTrigger.cpp b/pgadmin/schema/pgTrigger.cpp
index c21626a..797889d 100644
--- a/pgadmin/schema/pgTrigger.cpp
+++ b/pgadmin/schema/pgTrigger.cpp
@@ -165,15 +165,26 @@ wxString pgTrigger::GetSql(ctlTree *browser)
 		      + wxT(" ON ") + GetQuotedFullTable() + wxT(";\n\n");
 
 		if (GetLanguage() == wxT("edbspl"))
-			sql += wxT("CREATE OR REPLACE TRIGGER ") + qtIdent(GetName());
+			sql += wxT("CREATE OR REPLACE TRIGGER ");
+		else if (GetConnection()->BackendMinimumVersion(8, 2) && GetIsConstraint())
+			sql += wxT("CREATE CONSTRAINT TRIGGER ");
 		else
-			sql += wxT("CREATE TRIGGER ") + qtIdent(GetName());
+			sql += wxT("CREATE TRIGGER ");
 
-		sql += wxT("\n  ") + GetFireWhen()
+		sql += qtIdent(GetName()) + wxT("\n  ")
+			   + GetFireWhen()
 		       + wxT(" ") + GetEvent();
 
-		sql += wxT("\n  ON ") + GetQuotedFullTable()
-		       + wxT("\n  FOR EACH ") + GetForEach();
+		sql += wxT("\n  ON ") + GetQuotedFullTable();
+		if (GetDeferrable())
+		{
+			sql += wxT("\n  DEFERRABLE INITIALLY ");
+			if (GetDeferred())
+				sql += wxT("DEFERRED");
+			else
+				sql += wxT("IMMEDIATE");
+		}
+		sql += wxT("\n  FOR EACH ") + GetForEach();
 
 		if (GetConnection()->BackendMinimumVersion(8, 5)
 		        && !GetWhen().IsEmpty())
@@ -327,6 +338,8 @@ void pgTrigger::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *pro
 
 		properties->AppendItem(_("Name"), GetName());
 		properties->AppendItem(_("OID"), GetOid());
+		if (GetConnection()->BackendMinimumVersion(8, 2))
+			properties->AppendYesNoItem(_("Constraint?"), GetIsConstraint());
 		properties->AppendItem(_("Fires"), GetFireWhen());
 		properties->AppendItem(_("Event"), GetEvent());
 		if (!GetQuotedColumns().IsEmpty())
@@ -412,6 +425,19 @@ pgObject *pgTriggerFactory::CreateObjects(pgCollection *coll, ctlTree *browser,
 			else
 				trigger->iSetEnabled(triggers->GetBool(wxT("tgenabled")));
 
+			if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 2))
+			{
+				trigger->SetIsConstraint(triggers->GetLong(wxT("tgconstraint")) > 0);
+				trigger->iSetDeferrable(triggers->GetBool(wxT("tgdeferrable")));
+				trigger->iSetDeferred(triggers->GetBool(wxT("tginitdeferred")));
+			}
+			else
+			{
+				trigger->SetIsConstraint(false);
+				trigger->iSetDeferrable(false);
+				trigger->iSetDeferred(false);
+			}
+
 			trigger->iSetTriggerType(triggers->GetLong(wxT("tgtype")));
 			trigger->iSetParentIsTable(triggers->GetBool(wxT("parentistable")));
 
diff --git a/pgadmin/ui/dlgTrigger.xrc b/pgadmin/ui/dlgTrigger.xrc
index c6ac6c0..5c99f12 100644
--- a/pgadmin/ui/dlgTrigger.xrc
+++ b/pgadmin/ui/dlgTrigger.xrc
@@ -2,7 +2,7 @@
 <resource>
   <object class="wxDialog" name="dlgTrigger">
     <title></title>
-    <size>220,280d</size>
+    <size>220,360d</size>
     <style>wxDEFAULT_DIALOG_STYLE|wxCAPTION|wxSYSTEM_MENU|wxRESIZE_BORDER</style>
     <object class="wxFlexGridSizer">
       <cols>1</cols>
@@ -10,17 +10,17 @@
       <growablecols>0</growablecols>
       <object class="sizeritem">
         <object class="wxNotebook" name="nbNotebook">
-          <size>216,255d</size>
+          <size>216,335d</size>
           <selected>0</selected>
           <object class="notebookpage">
             <label>Properties</label>
             <object class="wxPanel" name="pnlProperties">
               <object class="wxFlexGridSizer">
                 <cols>2</cols>
-                <rows>10</rows>
+                <rows>13</rows>
                 <vgap>5</vgap>
                 <hgap>5</hgap>
-                <growablerows>7,8</growablerows>
+                <growablerows>10,11</growablerows>
                 <growablecols>1</growablecols>
                 <object class="sizeritem">
                   <object class="wxStaticText" name="stName">
@@ -64,6 +64,49 @@
                   <border>4</border>
                 </object>
                 <object class="sizeritem">
+                  <object class="wxStaticText" name="stConstraint">
+                    <label>Constraint trigger</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxCheckBox" name="chkConstraint">
+                    <label></label>
+                    <checked>0</checked>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stDeferrable">
+                    <label>Deferrable</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxCheckBox" name="chkDeferrable">
+                    <label></label>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stDeferred">
+                    <label>Deferred</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxCheckBox" name="chkDeferred">
+                    <label></label>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
                   <object class="wxStaticText" name="stFunction">
                     <label>Trigger function</label>
                   </object>
-- 
1.7.1

-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

Reply via email to