On Fri, 2011-07-22 at 23:55 +0100, Thom Brown wrote: > On 22 July 2011 23:43, Guillaume Lelarge <[email protected]> wrote: > > Hi, > > > > In 9.2, domains and check constraints can be declared not valid. Their > > validity can be forced later. This patch adds support for this new > > feature. > > > > Comments? > > I can't get the patch to apply as I get several errors. I'm using > latest master. >
Here is a rebased patch. Sorry for the inconvenience. -- Guillaume http://blog.guillaume.lelarge.info http://www.dalibo.com
>From 8df46f5a329fa1663b6a37494772603588cf7700 Mon Sep 17 00:00:00 2001 From: Guillaume Lelarge <[email protected]> Date: Sat, 23 Jul 2011 08:25:52 +0200 Subject: [PATCH] Support for not valid domain and check constraints In 9.2, domains and check constraints can be declared not valid. Their validity can be forced later. This patch adds support for this. --- pgadmin/dlg/dlgCheck.cpp | 32 +++++++++++++- pgadmin/dlg/dlgDomain.cpp | 63 ++++++++++++++++++++++++--- pgadmin/dlg/dlgTable.cpp | 6 +- pgadmin/frm/frmMain.cpp | 4 ++ pgadmin/include/dlg/dlgCheck.h | 2 + pgadmin/include/dlg/dlgDomain.h | 1 + pgadmin/include/schema/pgCheck.h | 28 ++++++++++++ pgadmin/include/schema/pgDomain.h | 29 +++++++++++- pgadmin/schema/pgCheck.cpp | 88 ++++++++++++++++++++++++++++++++----- pgadmin/schema/pgDomain.cpp | 60 +++++++++++++++++++++++++- pgadmin/schema/pgTable.cpp | 2 + pgadmin/ui/dlgCheck.xrc | 16 ++++++- pgadmin/ui/dlgDomain.xrc | 16 ++++++- 13 files changed, 320 insertions(+), 27 deletions(-) diff --git a/pgadmin/dlg/dlgCheck.cpp b/pgadmin/dlg/dlgCheck.cpp index c388ef9..5306938 100644 --- a/pgadmin/dlg/dlgCheck.cpp +++ b/pgadmin/dlg/dlgCheck.cpp @@ -21,10 +21,12 @@ #include "dlg/dlgCheck.h" #define txtWhere CTRL_TEXT("txtWhere") +#define chkDontValidate CTRL_CHECKBOX("chkDontValidate") BEGIN_EVENT_TABLE(dlgCheck, dlgProperty) EVT_TEXT(XRCID("txtWhere"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDontValidate"), dlgCheck::OnChangeValidate) END_EVENT_TABLE(); @@ -43,13 +45,16 @@ dlgCheck::dlgCheck(pgaFactory *f, frmMain *frame, pgCheck *node, pgTable *parent void dlgCheck::CheckChange() { + bool enable = true; if (check) { - EnableOK(txtComment->GetValue() != check->GetComment()); + enable = txtComment->GetValue() != check->GetComment(); + if (connection->BackendMinimumVersion(9, 2) && !check->GetValid() && !chkDontValidate->GetValue()) + enable = true; + EnableOK(enable); } else { - bool enable = true; txtComment->Enable(!GetName().IsEmpty()); CheckValid(enable, !txtWhere->GetValue().IsEmpty(), _("Please specify condition.")); EnableOK(enable); @@ -86,6 +91,12 @@ int dlgCheck::Go(bool modal) txtWhere->SetValue(check->GetDefinition()); txtWhere->Disable(); + + if (connection->BackendMinimumVersion(9, 2)) + chkDontValidate->SetValue(!check->GetValid()); + else + chkDontValidate->SetValue(true); + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 2) && !check->GetDefinition().IsEmpty() && !check->GetValid()); } else { @@ -96,11 +107,19 @@ int dlgCheck::Go(bool modal) cbClusterSet->Disable(); cbClusterSet = 0; } + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 2)); } + return dlgProperty::Go(modal); } +void dlgCheck::OnChangeValidate(wxCommandEvent &ev) +{ + CheckChange(); +} + + wxString dlgCheck::GetSql() { wxString sql; @@ -114,6 +133,12 @@ wxString dlgCheck::GetSql() sql += wxT("\n CHECK ") + GetDefinition() + wxT(";\n"); } + else if (!chkDontValidate->GetValue()) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT(" VALIDATE CONSTRAINT ") + qtIdent(name) + wxT(";\n"); + } + if (!name.IsEmpty()) AppendComment(sql, wxT("CONSTRAINT ") + qtIdent(name) + wxT(" ON ") + table->GetQuotedFullIdentifier(), check); @@ -127,5 +152,8 @@ wxString dlgCheck::GetDefinition() sql = wxT("(") + txtWhere->GetValue() + wxT(")"); + if (chkDontValidate->GetValue()) + sql += wxT(" NOT VALID"); + return sql; } diff --git a/pgadmin/dlg/dlgDomain.cpp b/pgadmin/dlg/dlgDomain.cpp index a7e0896..71a5b8d 100644 --- a/pgadmin/dlg/dlgDomain.cpp +++ b/pgadmin/dlg/dlgDomain.cpp @@ -28,6 +28,7 @@ #define txtDefault CTRL_TEXT("txtDefault") #define txtCheck CTRL_TEXT("txtCheck") #define cbCollation CTRL_COMBOBOX("cbCollation") +#define chkDontValidate CTRL_CHECKBOX("chkDontValidate") BEGIN_EVENT_TABLE(dlgDomain, dlgTypeProperty) EVT_TEXT(XRCID("txtLength"), dlgProperty::OnChange) @@ -37,6 +38,8 @@ BEGIN_EVENT_TABLE(dlgDomain, dlgTypeProperty) EVT_TEXT(XRCID("txLength"), dlgProperty::OnChange) EVT_TEXT(XRCID("txtDefault"), dlgProperty::OnChange) EVT_CHECKBOX(XRCID("chkNotNull"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDontValidate"), dlgDomain::OnChangeValidate) + EVT_TEXT(XRCID("txtCheck"), dlgProperty::OnChange) END_EVENT_TABLE(); @@ -84,7 +87,6 @@ int dlgDomain::Go(bool modal) txtName->Disable(); cbDatatype->Disable(); - txtCheck->Disable(); cbCollation->SetValue(domain->GetQuotedCollation()); cbCollation->Disable(); @@ -95,6 +97,9 @@ int dlgDomain::Go(bool modal) txtDefault->Disable(); chkNotNull->Disable(); } + + if (connection->BackendMinimumVersion(9, 2)) + chkDontValidate->SetValue(!domain->GetValid()); } else { @@ -126,6 +131,11 @@ int dlgDomain::Go(bool modal) cbCollation->SetSelection(0); } } + + if (connection->BackendMinimumVersion(9, 2)) + chkDontValidate->Enable(!domain || (domain && !domain->GetValid())); + else + chkDontValidate->Enable(false); return dlgProperty::Go(modal); } @@ -145,13 +155,18 @@ pgObject *dlgDomain::CreateObject(pgCollection *collection) void dlgDomain::CheckChange() { + bool enable; + if (domain) { - EnableOK(txtDefault->GetValue() != domain->GetDefault() - || cbSchema->GetValue() != domain->GetSchema()->GetName() - || chkNotNull->GetValue() != domain->GetNotNull() - || cbOwner->GetValue() != domain->GetOwner() - || txtComment->GetValue() != domain->GetComment()); + enable = txtDefault->GetValue() != domain->GetDefault() + || chkNotNull->GetValue() != domain->GetNotNull() + || txtCheck->GetValue() != domain->GetCheck() + || cbOwner->GetValue() != domain->GetOwner() + || txtComment->GetValue() != domain->GetComment(); + if (connection->BackendMinimumVersion(9, 2) && !domain->GetValid() && !chkDontValidate->GetValue()) + enable = true; + EnableOK(enable); } else { @@ -189,6 +204,12 @@ void dlgDomain::OnSelChangeTyp(wxCommandEvent &ev) } +void dlgDomain::OnChangeValidate(wxCommandEvent &ev) +{ + CheckChange(); +} + + wxString dlgDomain::GetSql() { wxString sql, name; @@ -214,6 +235,28 @@ wxString dlgDomain::GetSql() else sql += wxT("\n SET DEFAULT ") + txtDefault->GetValue() + wxT(";\n"); } + if (txtCheck->GetValue() != domain->GetCheck()) + { + if (!domain->GetCheck().IsEmpty()) + sql += wxT("ALTER DOMAIN ") + schema->GetQuotedPrefix() + qtIdent(name) + + wxT(" DROP CONSTRAINT ") + qtIdent(domain->GetCheckConstraintName()); + + if (!txtCheck->GetValue().IsEmpty()) + { + sql += wxT("ALTER DOMAIN ") + schema->GetQuotedPrefix() + qtIdent(name) + + wxT(" ADD "); + if (!domain->GetCheck().IsEmpty()) + sql += wxT("CONSTRAINT ") + qtIdent(domain->GetCheckConstraintName()); + sql += wxT("\n CHECK (") + txtCheck->GetValue() + wxT(")"); + if (chkDontValidate->GetValue()) + sql += wxT(" NOT VALID"); + } + } + if (chkDontValidate->IsEnabled() && !domain->GetValid() && !chkDontValidate->GetValue()) + { + sql += wxT("ALTER DOMAIN ") + schema->GetQuotedPrefix() + qtIdent(name) + + wxT(" VALIDATE CONSTRAINT ") + qtIdent(domain->GetCheckConstraintName()) + wxT(";\n"); + } AppendOwnerChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier()); AppendSchemaChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier()); } @@ -226,16 +269,24 @@ wxString dlgDomain::GetSql() if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) sql += wxT("\n COLLATE ") + cbCollation->GetValue(); + + if (chkDontValidate->GetValue()) + sql += wxT(";\nALTER DOMAIN ") + schema->GetQuotedPrefix() + qtIdent(name) + wxT(" ADD "); AppendIfFilled(sql, wxT("\n DEFAULT "), txtDefault->GetValue()); if (chkNotNull->GetValue()) sql += wxT("\n NOT NULL"); if (!txtCheck->GetValue().IsEmpty()) sql += wxT("\n CHECK (") + txtCheck->GetValue() + wxT(")"); + + if (chkDontValidate->GetValue()) + sql += wxT(" NOT VALID"); + sql += wxT(";\n"); AppendOwnerNew(sql, wxT("DOMAIN ") + name); } + AppendComment(sql, wxT("DOMAIN ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), domain); return sql; diff --git a/pgadmin/dlg/dlgTable.cpp b/pgadmin/dlg/dlgTable.cpp index 746566e..aa76522 100644 --- a/pgadmin/dlg/dlgTable.cpp +++ b/pgadmin/dlg/dlgTable.cpp @@ -1291,9 +1291,9 @@ wxString dlgTable::GetSql() needComma = true; sql += wxT("\n "); - AppendIfFilled(sql, wxT("CONSTRAINT "), qtIdent(name)); - - sql += wxT(" ") + GetItemConstraintType(lstConstraints, pos) + wxT(" ") + definition; + if (!name.IsEmpty()) + sql += wxT("CONSTRAINT ") + qtIdent(name) + wxT(" "); + sql += GetItemConstraintType(lstConstraints, pos) + wxT(" ") + definition; } if (!typedTable || (typedTable && lstConstraints->GetItemCount() > 0)) diff --git a/pgadmin/frm/frmMain.cpp b/pgadmin/frm/frmMain.cpp index 809a7ee..77b1b8b 100644 --- a/pgadmin/frm/frmMain.cpp +++ b/pgadmin/frm/frmMain.cpp @@ -79,6 +79,8 @@ #include "slony/slCluster.h" #include "slony/slSet.h" #include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "schema/pgDomain.h" #if wxDIALOG_UNIT_COMPATIBILITY @@ -291,6 +293,8 @@ void frmMain::CreateMenus() new disableAllTriggersFactory(menuFactories, toolsMenu, 0); new enableAllTriggersFactory(menuFactories, toolsMenu, 0); new validateForeignKeyFactory(menuFactories, toolsMenu, 0); + new validateCheckFactory(menuFactories, toolsMenu, 0); + new validateDomainCheckFactory(menuFactories, toolsMenu, 0); toolsMenu->AppendSeparator(); //-------------------------- diff --git a/pgadmin/include/dlg/dlgCheck.h b/pgadmin/include/dlg/dlgCheck.h index bfea4a2..e55ca95 100644 --- a/pgadmin/include/dlg/dlgCheck.h +++ b/pgadmin/include/dlg/dlgCheck.h @@ -37,6 +37,8 @@ public: private: pgCheck *check; pgTable *table; + + void OnChangeValidate(wxCommandEvent &ev); DECLARE_EVENT_TABLE() }; diff --git a/pgadmin/include/dlg/dlgDomain.h b/pgadmin/include/dlg/dlgDomain.h index 497e4f7..91f3ff9 100644 --- a/pgadmin/include/dlg/dlgDomain.h +++ b/pgadmin/include/dlg/dlgDomain.h @@ -31,6 +31,7 @@ public: private: void OnSelChangeTyp(wxCommandEvent &ev); + void OnChangeValidate(wxCommandEvent &ev); pgSchema *schema; pgDomain *domain; diff --git a/pgadmin/include/schema/pgCheck.h b/pgadmin/include/schema/pgCheck.h index b73e00b..7f37d1f 100644 --- a/pgadmin/include/schema/pgCheck.h +++ b/pgadmin/include/schema/pgCheck.h @@ -24,6 +24,14 @@ public: pgCheckFactory(); virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; }; extern pgCheckFactory checkFactory; @@ -34,6 +42,8 @@ public: pgCheck(pgTable *newTable, const wxString &newName = wxT("")); ~pgCheck(); + int GetIconId(); + wxString GetTranslatedMessage(int kindOfMessage) const; void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); @@ -61,6 +71,14 @@ public: { definition = s; } + bool GetValid() const + { + return valid; + } + void iSetValid(const bool b) + { + valid = b; + } bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); wxString GetConstraint(); @@ -83,9 +101,11 @@ public: { return true; } + void Validate(frmMain *form); private: wxString definition, fkTable, fkSchema; + bool valid; }; class pgCheckCollection : public pgSchemaObjCollection @@ -95,4 +115,12 @@ public: wxString GetTranslatedMessage(int kindOfMessage) const; }; +class validateCheckFactory : public contextActionFactory +{ +public: + validateCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + #endif diff --git a/pgadmin/include/schema/pgDomain.h b/pgadmin/include/schema/pgDomain.h index 08a8f18..5fc3a02 100644 --- a/pgadmin/include/schema/pgDomain.h +++ b/pgadmin/include/schema/pgDomain.h @@ -164,6 +164,22 @@ public: { typmod = l; } + bool GetValid() const + { + return constraintvalid; + } + void iSetValid(const bool b) + { + constraintvalid = b; + } + wxString GetCheckConstraintName() const + { + return checkconstraintname; + } + void iSetCheckConstraintName(const wxString &s) + { + checkconstraintname = s; + } bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); wxString GetSql(ctlTree *browser); @@ -181,12 +197,13 @@ public: { return true; } + void Validate(frmMain *form); private: - wxString basetype, quotedBasetype, defaultVal, delimiter, check, collation, quotedCollation; + wxString basetype, quotedBasetype, defaultVal, delimiter, check, collation, quotedCollation, checkconstraintname; long length, precision, dimensions; long typlen, typmod; - bool notNull, isDup; + bool notNull, isDup, constraintvalid; OID basetypeOid, collationOid; }; @@ -197,4 +214,12 @@ public: wxString GetTranslatedMessage(int kindOfMessage) const; }; +class validateDomainCheckFactory : public contextActionFactory +{ +public: + validateDomainCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + #endif diff --git a/pgadmin/schema/pgCheck.cpp b/pgadmin/schema/pgCheck.cpp index b98b618..c5a9cd6 100644 --- a/pgadmin/schema/pgCheck.cpp +++ b/pgadmin/schema/pgCheck.cpp @@ -14,6 +14,7 @@ // App headers #include "pgAdmin3.h" +#include "frm/frmMain.h" #include "utils/misc.h" #include "schema/pgCheck.h" @@ -94,6 +95,15 @@ wxString pgCheck::GetTranslatedMessage(int kindOfMessage) const } +int pgCheck::GetIconId() +{ + if (!GetDatabase()->BackendMinimumVersion(9, 2) || GetValid()) + return checkFactory.GetIconId(); + else + return checkFactory.GetClosedIconId(); +} + + bool pgCheck::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) { wxString sql = wxT("ALTER TABLE ") + qtIdent(fkSchema) + wxT(".") + qtIdent(fkTable) @@ -106,7 +116,12 @@ bool pgCheck::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) wxString pgCheck::GetConstraint() { - return GetQuotedIdentifier() + wxT(" CHECK (") + GetDefinition() + wxT(")"); + sql = GetQuotedIdentifier() + wxT(" CHECK (") + GetDefinition() + wxT(")"); + + if (GetDatabase()->BackendMinimumVersion(9, 2) && !GetValid()) + sql += wxT(" NOT VALID"); + + return sql; } @@ -141,6 +156,8 @@ void pgCheck::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prope properties->AppendItem(_("Name"), GetName()); properties->AppendItem(_("OID"), GetOid()); properties->AppendItem(_("Definition"), GetDefinition()); + if (GetDatabase()->BackendMinimumVersion(9, 2)) + properties->AppendItem(_("Valid?"), BoolToYesNo(GetValid())); properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); } } @@ -158,21 +175,34 @@ pgObject *pgCheck::Refresh(ctlTree *browser, const wxTreeItemId item) } +void pgCheck::Validate(frmMain *form) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT("\n VALIDATE CONSTRAINT ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + + iSetValid(true); + UpdateIcon(form->GetBrowser()); +} + pgObject *pgCheckFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) { pgTableObjCollection *collection = (pgTableObjCollection *)coll; pgCheck *check = 0; - pgSet *checks = collection->GetDatabase()->ExecuteSet( - wxT("SELECT c.oid, conname, relname, nspname, description,\n") - wxT(" pg_get_expr(conbin, conrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as consrc\n") - wxT(" FROM pg_constraint c\n") - wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") - wxT(" JOIN pg_namespace nl ON nl.oid=relnamespace\n") - wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=c.oid\n") - wxT(" WHERE contype = 'c' AND conrelid = ") + NumToStr(collection->GetOid()) - + restriction + wxT("::oid\n") - wxT(" ORDER BY conname")); + wxString sql = wxT("SELECT c.oid, conname, relname, nspname, description,\n") + wxT(" pg_get_expr(conbin, conrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as consrc\n"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 2)) + sql += wxT(", convalidated"); + sql += wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=c.oid\n") + wxT(" WHERE contype = 'c' AND conrelid = ") + NumToStr(collection->GetOid()) + + restriction + wxT("::oid\n") + wxT(" ORDER BY conname"); + + pgSet *checks = collection->GetDatabase()->ExecuteSet(sql); if (checks) { @@ -184,6 +214,8 @@ pgObject *pgCheckFactory::CreateObjects(pgCollection *coll, ctlTree *browser, co check->iSetDefinition(checks->GetVal(wxT("consrc"))); check->iSetFkTable(checks->GetVal(wxT("relname"))); check->iSetFkSchema(checks->GetVal(wxT("nspname"))); + if (collection->GetDatabase()->BackendMinimumVersion(9, 2)) + check->iSetValid(checks->GetBool(wxT("convalidated"))); check->iSetComment(checks->GetVal(wxT("description"))); if (browser) @@ -225,13 +257,47 @@ wxString pgCheckCollection::GetTranslatedMessage(int kindOfMessage) const ///////////////////////////// #include "images/check.pngc" +#include "images/checkbad.pngc" pgCheckFactory::pgCheckFactory() : pgTableObjFactory(__("Check"), __("New Check..."), __("Create a new Check constraint."), check_png_img) { metaType = PGM_CHECK; collectionFactory = &constraintCollectionFactory; + closedId = addIcon(checkbad_png_img); } pgCheckFactory checkFactory; + +validateCheckFactory::validateCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Validate check constraint"), _("Validate the selected check constraint.")); +} + + +wxWindow *validateCheckFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgCheck *)obj)->Validate(form); + ((pgCheck *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgCheck *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool validateCheckFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(checkFactory) && obj->CanEdit() + && ((pgCheck *)obj)->GetConnection()->BackendMinimumVersion(9, 2) + && !((pgCheck *)obj)->GetValid(); +} diff --git a/pgadmin/schema/pgDomain.cpp b/pgadmin/schema/pgDomain.cpp index 2a2bb2f..71a35e1 100644 --- a/pgadmin/schema/pgDomain.cpp +++ b/pgadmin/schema/pgDomain.cpp @@ -14,6 +14,7 @@ // App headers #include "pgAdmin3.h" +#include "frm/frmMain.h" #include "utils/misc.h" #include "schema/pgDomain.h" #include "schema/pgDatatype.h" @@ -132,7 +133,8 @@ void pgDomain::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prop if (GetConnection()->BackendMinimumVersion(7, 4)) { pgSet *set = ExecuteSet( - wxT("SELECT conname, pg_get_constraintdef(oid) AS consrc FROM pg_constraint WHERE contypid=") + GetOidStr()); + wxT("SELECT conname, convalidated, pg_get_constraintdef(oid) AS consrc FROM pg_constraint WHERE contypid=") + GetOidStr()); + check = wxEmptyString; if (set) { while (!set->Eof()) @@ -145,6 +147,14 @@ void pgDomain::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prop if (!conname.StartsWith(wxT("$"))) check += wxT("CONSTRAINT ") + qtIdent(conname) + wxT(" "); check += set->GetVal(wxT("consrc")); + + // there may be more than one constraint + // but there is only one check constraint + if (!set->GetBool(wxT("convalidated"))) + { + iSetCheckConstraintName(set->GetVal(wxT("conname"))); + iSetValid(false); + } set->MoveNext(); } @@ -186,6 +196,17 @@ pgObject *pgDomain::Refresh(ctlTree *browser, const wxTreeItemId item) } +void pgDomain::Validate(frmMain *form) +{ + wxString sql = wxT("ALTER DOMAIN ") + GetQuotedFullIdentifier() + + wxT("\n VALIDATE CONSTRAINT ") + GetCheckConstraintName(); + GetDatabase()->ExecuteVoid(sql); + + iSetValid(true); + UpdateIcon(form->GetBrowser()); +} + + //////////////////////////////////////////////////// @@ -250,6 +271,10 @@ pgObject *pgDomainFactory::CreateObjects(pgCollection *collection, ctlTree *brow } else domain->iSetCollationOid(0); + + // we suppose the constraint valid now + // this is checked in ShowTreeDetail for each domain + domain->iSetValid(true); if (browser) { @@ -312,3 +337,36 @@ pgCollection *pgDomainFactory::CreateCollection(pgObject *obj) pgDomainFactory domainFactory; static pgaCollectionFactory cf(&domainFactory, __("Domains"), domains_png_img); + +validateDomainCheckFactory::validateDomainCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Validate domain check constraint"), _("Validate the selected domain check constraint.")); +} + + +wxWindow *validateDomainCheckFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgDomain *)obj)->Validate(form); + ((pgDomain *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgDomain *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool validateDomainCheckFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(domainFactory) && obj->CanEdit() + && ((pgDomain *)obj)->GetConnection()->BackendMinimumVersion(9, 2) + && !((pgDomain *)obj)->GetValid(); +} + diff --git a/pgadmin/schema/pgTable.cpp b/pgadmin/schema/pgTable.cpp index a08798d..3aab612 100644 --- a/pgadmin/schema/pgTable.cpp +++ b/pgadmin/schema/pgTable.cpp @@ -444,6 +444,8 @@ wxString pgTable::GetSql(ctlTree *browser) break; case PGM_CHECK: cols_sql += wxT("(") + ((pgCheck *)data)->GetDefinition() + wxT(")"); + if (GetDatabase()->BackendMinimumVersion(9, 2) && !((pgCheck *)data)->GetValid()) + cols_sql += wxT(" NOT VALID"); break; } } diff --git a/pgadmin/ui/dlgCheck.xrc b/pgadmin/ui/dlgCheck.xrc index d583e77..1c5ece4 100644 --- a/pgadmin/ui/dlgCheck.xrc +++ b/pgadmin/ui/dlgCheck.xrc @@ -73,7 +73,7 @@ <object class="wxPanel" name="pnlDefinition"> <object class="wxFlexGridSizer"> <cols>2</cols> - <rows>1</rows> + <rows>2</rows> <vgap>5</vgap> <hgap>5</hgap> <growablerows>0</growablerows> @@ -92,6 +92,20 @@ <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL</flag> <border>4</border> </object> + <object class="sizeritem"> + <object class="wxStaticText" name="stDontValidate"> + <label>Don't validate</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxCheckBox" name="chkDontValidate"> + <label></label> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> <flag>wxEXPAND|wxTOP|wxLEFT|wxRIGHT</flag> </object> </object> diff --git a/pgadmin/ui/dlgDomain.xrc b/pgadmin/ui/dlgDomain.xrc index e594ab7..0871a57 100644 --- a/pgadmin/ui/dlgDomain.xrc +++ b/pgadmin/ui/dlgDomain.xrc @@ -115,7 +115,7 @@ <object class="wxPanel" name="pnlDefinition"> <object class="wxFlexGridSizer"> <cols>2</cols> - <rows>6</rows> + <rows>7</rows> <vgap>5</vgap> <hgap>5</hgap> <growablerows>2</growablerows> @@ -162,6 +162,20 @@ <border>4</border> </object> <object class="sizeritem"> + <object class="wxStaticText" name="stDontValidate"> + <label>Don't validate</label> + </object> + <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> + <object class="wxCheckBox" name="chkDontValidate"> + <label></label> + </object> + <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag> + <border>4</border> + </object> + <object class="sizeritem"> <object class="wxStaticText" name="stLength"> <label>Length</label> </object> -- 1.7.6
-- Sent via pgadmin-hackers mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgadmin-hackers
