diff --git a/Release/pgAdmin3.exe b/Release/pgAdmin3.exe index d0d1d34..d682c8e 100644 Binary files a/Release/pgAdmin3.exe and b/Release/pgAdmin3.exe differ diff --git a/frm/frmMain.cpp b/frm/frmMain.cpp index c2bb2ed..f965d17 100644 --- a/frm/frmMain.cpp +++ b/frm/frmMain.cpp @@ -78,6 +78,7 @@ #include "schema/pgFunction.h" #include "schema/pgIndex.h" #include "schema/pgTrigger.h" +#include "pro_scheduler/pgproJob.h" #include "schema/pgRole.h" #include "schema/pgRule.h" #include "schema/pgServer.h" @@ -317,6 +318,7 @@ void frmMain::CreateMenus() new enabledisableRuleFactory(menuFactories, toolsMenu, 0); new enabledisableTriggerFactory(menuFactories, toolsMenu, 0); new enabledisableEventTriggerFactory(menuFactories, toolsMenu, 0); + new enabledisableJobFactory(menuFactories, toolsMenu, 0); new disableAllTriggersFactory(menuFactories, toolsMenu, 0); new enableAllTriggersFactory(menuFactories, toolsMenu, 0); new validateForeignKeyFactory(menuFactories, toolsMenu, 0); diff --git a/frm/frmOptions.cpp b/frm/frmOptions.cpp index d35756f..c4ad185 100644 --- a/frm/frmOptions.cpp +++ b/frm/frmOptions.cpp @@ -385,6 +385,7 @@ frmOptions::frmOptions(frmMain *parent) lstDisplay->Append(_("Databases")); lstDisplay->Append(_("Tablespaces")); lstDisplay->Append(_("pgAgent Jobs")); + lstDisplay->Append(_("pgpro_scheduler")); lstDisplay->Append(_("Groups/group Roles")); lstDisplay->Append(_("Users/login Roles")); lstDisplay->Append(_("Resource Queues")); diff --git a/frm/frmStatus.cpp b/frm/frmStatus.cpp index a87ee5a..3253cc1 100644 --- a/frm/frmStatus.cpp +++ b/frm/frmStatus.cpp @@ -1725,6 +1725,7 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event) } if (connection->BackendMinimumVersion(9, 6)) { + wait_event_type_col=colpos; statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event_type"))); statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event"))); } @@ -2029,7 +2030,8 @@ void frmStatus::OnRefreshQuerystateTimer(wxTimerEvent &event) return; wxString pid=statusList->GetText(row, 0); wxString dbname=statusList->GetText(row, 2); // dbname - if (dbname.IsEmpty()) return; + wxString wait_event_type= statusList->GetText(row, wait_event_type_col); + if (dbname.IsEmpty()||wait_event_type==wxT("Extension")) return; wxString flags=wxT(""); if (viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)) diff --git a/include/frm/frmStatus.h b/include/frm/frmStatus.h index a41dbc4..9ce32c3 100644 --- a/include/frm/frmStatus.h +++ b/include/frm/frmStatus.h @@ -120,6 +120,7 @@ private: bool showCurrent, isCurrent; long backend_pid; + int wait_event_type_col; bool loaded; long logfileLength; diff --git a/include/images/jobrun.png b/include/images/jobrun.png new file mode 100644 index 0000000..a94176c Binary files /dev/null and b/include/images/jobrun.png differ diff --git a/include/images/jobrun.pngc b/include/images/jobrun.pngc new file mode 100644 index 0000000..1164373 --- /dev/null +++ b/include/images/jobrun.pngc @@ -0,0 +1,93 @@ +#ifndef JOBRUN_PNG_H +#define JOBRUN_PNG_H + +static const unsigned char jobrun_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x01, 0xd9, 0xc9, 0x2c, 0x7f, 0x00, 0x00, +0x00, 0x81, 0x50, 0x4c, 0x54, 0x45, 0xb3, 0xb4, +0xb4, 0x7e, 0x7f, 0x80, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xfd, 0xfe, 0xff, 0xf9, 0xfd, 0xfe, +0xf6, 0xfb, 0xfd, 0xf2, 0xfa, 0xfc, 0xed, 0xf8, +0xfc, 0xe9, 0xf6, 0xfb, 0xe4, 0xf4, 0xfa, 0xde, +0xf2, 0xf9, 0x1e, 0x50, 0xad, 0xd9, 0xf0, 0xf8, +0xd3, 0xed, 0xf6, 0x1e, 0x51, 0xac, 0x12, 0x98, +0x66, 0x1a, 0x65, 0x98, 0xce, 0xeb, 0xf5, 0xcf, +0xfd, 0xd3, 0x00, 0xff, 0x00, 0x06, 0xff, 0x06, +0x5c, 0xfc, 0x62, 0xe2, 0xf6, 0xf3, 0x19, 0x6e, +0x90, 0x04, 0xe8, 0x17, 0x16, 0x7f, 0x7f, 0xc9, +0xfb, 0xd1, 0x2d, 0xfb, 0x34, 0x6d, 0x91, 0x6e, +0x03, 0xfc, 0x03, 0x00, 0xff, 0x00, 0x13, 0xeb, +0x14, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x01, 0x5f, +0xf8, 0x6d, 0x7b, 0x82, 0x7c, 0x45, 0xfb, 0x4d, +0xaa, 0xf3, 0xc2, 0x04, 0xe5, 0x1a, 0x13, 0x8d, +0x71, 0xd3, 0xf9, 0xe0, 0xdd, 0xf6, 0xee, 0xd3, +0x1d, 0xbd, 0x7f, 0x00, 0x00, 0x00, 0x2b, 0x74, +0x52, 0x4e, 0x53, 0xff, 0xff, 0x00, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0x8e, 0xff, 0x4f, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0xe3, +0x0f, 0x5d, 0x00, 0x00, 0x00, 0x78, 0x49, 0x44, +0x41, 0x54, 0x78, 0x9c, 0x65, 0x8f, 0xe9, 0x12, +0x82, 0x20, 0x14, 0x46, 0x41, 0x42, 0xb3, 0xd0, +0xc4, 0xae, 0x4b, 0xae, 0x95, 0x4b, 0xe9, 0xfb, +0x3f, 0xa0, 0xca, 0x20, 0x5c, 0xeb, 0xfc, 0x3c, +0xdc, 0x39, 0xf3, 0x41, 0x08, 0x35, 0x10, 0x67, +0x85, 0x50, 0xc6, 0x4e, 0xdc, 0xf5, 0xce, 0xfe, +0xe5, 0x4a, 0xb5, 0x10, 0x5c, 0x28, 0x02, 0x2d, +0xf6, 0xf7, 0x20, 0xd4, 0x82, 0x0b, 0xef, 0x16, +0xc9, 0xf5, 0x22, 0xa6, 0xa6, 0x71, 0x87, 0x24, +0xcd, 0x70, 0x23, 0x07, 0x80, 0x47, 0x81, 0x1a, +0x25, 0x6c, 0x54, 0xb5, 0x69, 0xe4, 0x4a, 0x40, +0xd3, 0xda, 0x86, 0xe2, 0xf9, 0xc2, 0x0d, 0x78, +0x77, 0xfd, 0xa1, 0x31, 0x8c, 0x68, 0x87, 0x84, +0xcf, 0xd7, 0xee, 0xd8, 0x96, 0x4e, 0xb3, 0x5d, +0xfa, 0xf7, 0x5b, 0xe7, 0x87, 0x05, 0x7d, 0x55, +0x08, 0xe4, 0x94, 0x7a, 0x19, 0xe3, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *jobrun_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_jobrun_png = new wxImage(); + if (!img_jobrun_png || !img_jobrun_png->IsOk()) + { + wxMemoryInputStream img_jobrun_pngIS(jobrun_png_data, sizeof(jobrun_png_data)); + img_jobrun_png->LoadFile(img_jobrun_pngIS, wxBITMAP_TYPE_PNG); + } + return img_jobrun_png; +} +#define jobrun_png_img jobrun_png_img() + +static wxBitmap *jobrun_png_bmp() +{ + static wxBitmap *bmp_jobrun_png; + if (!bmp_jobrun_png || !bmp_jobrun_png->IsOk()) + bmp_jobrun_png = new wxBitmap(*jobrun_png_img); + return bmp_jobrun_png; +} +#define jobrun_png_bmp jobrun_png_bmp() + +static wxIcon *jobrun_png_ico() +{ + static wxIcon *ico_jobrun_png; + if (!ico_jobrun_png || !ico_jobrun_png->IsOk()) + { + ico_jobrun_png = new wxIcon(); + ico_jobrun_png->CopyFromBitmap(*jobrun_png_bmp); + } + return ico_jobrun_png; +} +#define jobrun_png_ico jobrun_png_ico() + +#endif // JOBRUN_PNG_H diff --git a/include/images/jobrun_.png b/include/images/jobrun_.png new file mode 100644 index 0000000..a94e9e6 Binary files /dev/null and b/include/images/jobrun_.png differ diff --git a/include/pro_scheduler/pgproJob.h b/include/pro_scheduler/pgproJob.h new file mode 100644 index 0000000..ff259dd --- /dev/null +++ b/include/pro_scheduler/pgproJob.h @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaJob.h - PostgreSQL Agent Job +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGPROJOB_H +#define PGPROJOB_H + +#include "schema/pgServer.h" + + +class pgproJobFactory : public pgServerObjFactory +{ +public: + pgproJobFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetDisabledId() + { + return disabledId; + } + int GetRunId() + { + return runId; + } + +protected: + int disabledId,runId; +}; +extern pgproJobFactory projobFactory; + +class pgproJob : public pgServerObject +{ +public: + pgproJob(const wxString &newName = wxT("")); + void SetEnabled(ctlTree *browser, const bool b); + int GetIconId(); + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetTranslatedMessage(int kindOfMessage) const; + wxString GetSql(ctlTree *browser); + + wxString GetCrontab() const + { + return crontab; + } + void iSetCrontab(const wxString &s) + { + crontab = s; + } + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + wxDateTime GetFinished() const + { + return finished; + } + void iSetFinished(const wxDateTime &d) + { + finished = d; + } + wxDateTime GetChanged() const + { + return changed; + } + void iSetChanged(const wxDateTime &d) + { + changed = d; + } + wxDateTime GetNextrun() const + { + return nextrun; + } + void iSetNextrun(const wxDateTime &d) + { + nextrun = d; + } + wxDateTime GetStarted() const + { + return lastrun; + } + void iSetStarted(const wxDateTime &d) + { + lastrun = d; + } + wxString GetMessage() const + { + return message; + } + void iSetMessage(const wxString &s) + { + message = s; + } + wxString GetStatus() const + { + return status; + } + void iSetStatus(const wxString &s) + { + status = s; + } + wxString GetRunAs() const + { + return runas; + } + void iSetRunAs(const wxString &s) + { + runas = s; + } + wxString GetRule() const + { + return rule; + } + void iSetRule(const wxString &s) + { + rule = s; + } + wxString GetCommands() const + { + return commands; + } + void iSetCommands(const wxString &s) + { + commands = s; + } + long GetRecId() const + { + return recId; + } + void iSetRecId(const long l) + { + recId = l; + } + bool RunNow(); + + wxMenu *GetNewMenu(); + bool CanCreate() + { + return false; + } + bool CanView() + { + return true; + } + bool CanEdit() + { + return false; + } + bool CanDrop() + { + return true; + } + bool WantDummyChild() + { + return false; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-jobs"); + } + +private: + bool enabled; + wxDateTime finished, changed, nextrun, lastrun; + wxString message, crontab, runas, commands,status,rule; + long recId; +}; + + +class pgproJobObject : public pgServerObject +{ +public: + pgproJobObject(pgproJob *job, pgaFactory &factory, const wxString &newName); + virtual pgproJob *GetJob() + { + return job; + } + + bool CanCreate() + { + return job->CanCreate(); + } + bool CanView() + { + return false; + } + bool CanEdit() + { + return job->CanEdit(); + } + bool CanDrop() + { + return job->CanDrop(); + } + +protected: + pgproJob *job; +}; + + +class pgproJobCollection : public pgServerObjCollection +{ +public: + pgproJobCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class enabledisableJobFactory : public contextActionFactory +{ +public: + enabledisableJobFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + + +class prorunNowFactory : public contextActionFactory +{ +public: + prorunNowFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/utils/misc.h b/include/utils/misc.h index 4afe107..d3d8926 100644 --- a/include/utils/misc.h +++ b/include/utils/misc.h @@ -238,6 +238,7 @@ enum GP_PARTITION, PG_PARTITION, + PGM_PROJOB, PGM_JOB, PGM_SCHEDULE, diff --git a/schema/pgServer.cpp b/schema/pgServer.cpp index 217f4fc..7821b0b 100644 --- a/schema/pgServer.cpp +++ b/schema/pgServer.cpp @@ -32,6 +32,7 @@ #include "schema/pgRole.h" #include "schema/gpResQueue.h" #include "agent/pgaJob.h" +#include "pro_scheduler/pgproJob.h" #include "utils/utffile.h" #include "utils/pgfeatures.h" #include "utils/registry.h" @@ -1130,6 +1131,16 @@ void pgServer::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prop browser->AppendCollection(this, jobFactory); } } + if (settings->GetDisplayOption(_("pgpro_scheduler"))) + { + wxString exists = conn->ExecuteScalar( + wxT("select true ok from pg_extension where extname='pgpro_scheduler'\n")); + + if (!exists.IsNull()) + { + browser->AppendCollection(this, projobFactory); + } + } if (conn->BackendMinimumVersion(8, 1)) { diff --git a/utils/sysSettings.cpp b/utils/sysSettings.cpp index e0276e0..82bb1c7 100644 --- a/utils/sysSettings.cpp +++ b/utils/sysSettings.cpp @@ -81,6 +81,8 @@ bool sysSettings::GetDisplayOption(const wxString &objtype, bool GetDefault) engtype = wxT("Tablespaces"); else if (objtype == _("pgAgent Jobs")) engtype = wxT("pgAgent Jobs"); + else if (objtype == _("pgpro_scheduler")) + engtype = wxT("pgpro_scheduler"); else if (objtype == _("Groups/group Roles")) engtype = wxT("Groups-login Roles"); else if (objtype == _("Users/login Roles")) @@ -208,6 +210,7 @@ void sysSettings::SetDisplayOption(const wxString &objtype, bool display) if (objtype == _("Databases")) engtype = wxT("Databases"); else if (objtype == _("Tablespaces")) engtype = wxT("Tablespaces"); else if (objtype == _("pgAgent Jobs")) engtype = wxT("pgAgent Jobs"); + else if (objtype == _("pgpro_scheduler")) engtype = wxT("pgpro_scheduler"); else if (objtype == _("Groups/group Roles")) engtype = wxT("Groups-login Roles"); else if (objtype == _("Users/login Roles")) engtype = wxT("Users-login Roles"); else if (objtype == _("Resource Queues")) engtype = wxT("Resource Queues");