diff --git a/dlg/dlgProJob.cpp b/dlg/dlgProJob.cpp new file mode 100644 index 0000000..bbb7661 --- /dev/null +++ b/dlg/dlgProJob.cpp @@ -0,0 +1,290 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtension.cpp - PostgreSQL Extension Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgProJob.h" +#include "pro_scheduler/pgproJob.h" + + +// pointer to controls +//#define cbName CTRL_COMBOBOX("cbName") +#define cbRunAs CTRL_COMBOBOX2("cbRunAs") +#define txtID CTRL_TEXT("txtID") +#define txtCron CTRL_TEXT("txtCron") +#define txtNextrun CTRL_TEXT("txtNextrun") +#define txtLastrun CTRL_TEXT("txtLastrun") + +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define chkSameTran CTRL_CHECKBOX("chkSameTran") + + + + +dlgProperty *pgproJobFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgProJob(this, frame, (pgproJob *)node); +} + + +BEGIN_EVENT_TABLE(dlgProJob, dlgProperty) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) + EVT_TEXT(XRCID("txtCron"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtName"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtComment"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSameTran"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbRunAs"), dlgProperty::OnChange) + +END_EVENT_TABLE(); + + +dlgProJob::dlgProJob(pgaFactory *f, frmMain *frame, pgproJob *node) + : dlgProperty(f, frame, wxT("dlgProJob")) +{ + job = node; +} + + +pgObject *dlgProJob::GetObject() +{ + return job; +} + + +int dlgProJob::Go(bool modal) +{ + //txtComment->Disable(); + + // add all schemas + //cbObjectsSchema->Append(wxEmptyString); + //pgSetIterator schemas(connection, + // wxT("SELECT nspname FROM pg_namespace\n") + // wxT(" ORDER BY nspname")); + + //while (schemas.RowsLeft()) + // cbObjectsSchema->Append(schemas.GetVal(wxT("nspname"))); + //cbObjectsSchema->SetSelection(0); + + if (job) + { + // edit mode + //txtName->Append(job->GetName()); + //txtName->SetValue(job->GetTryName()); + ctlComboBoxFix* cbowner = (ctlComboBoxFix*)cbOwner; + AddUsers(cbowner); + cbowner->SetValue(job->GetOwner()); + ctlComboBoxFix* cbRunas = (ctlComboBoxFix*)cbRunAs; + AddUsers(cbRunas); + if (cbRunas) + cbRunas->SetValue(job->GetRunAs()); + + chkEnabled->SetValue(job->GetEnabled()); + txtID->SetValue(NumToStr(job->GetRecId())); + txtID->Disable(); + wxString t2 = job->GetCrontab(); + txtCron->SetValue(t2); + chkSameTran->SetValue(job->GetSameTransaction()); + + int pos = 0; + pgSetIterator cmds(connection, wxT("select unnest(commands) from schedule.get_cron() c where c.id=")+NumToStr(job->GetRecId())); + wxString src; + while (cmds.RowsLeft()) + { + wxString cmd=cmds.GetVal(0); + if (!src.IsEmpty()) src += "\n"; + src += cmd; + + } + + txtSqlBox->SetEOLMode(2); + txtSqlBox->SetText(src); + oldsrc = src; + + wxDateTime lr = job->GetStarted(); + wxDateTime nr = job->GetNextSchedule_At(lr, 1); + if (lr.IsValid()) { + wxString str = lr.FormatISODate() + wxT(" ") + lr.FormatISOTime(); + wxTimeSpan sp=nr- wxDateTime::Now(); + wxLongLong d=sp.GetMilliseconds(); + txtLastrun->SetValue(str); + str = nr.FormatISODate() + wxT(" ") + nr.FormatISOTime()+" [ "+ ElapsedTimeToStr(d) +" ]"; + txtNextrun->SetValue(str); + } + } + else + { + // create mode + txtCron->SetValue("00 * * * *"); + } + + return dlgProperty::Go(modal); +} +void fillarray(wxArrayString &arr,wxString &src) +{ + int l = src.Length(); + wxUniChar ln = '\n'; + int pos = 0; + int h = pos; + bool en = false; + while (posGetValue(); + + pgObject *obj = projobFactory.CreateObjects(collection, 0, wxT("\n AND extname ILIKE ") + qtDbString(name)); + return obj; +} + +void dlgProJob::OnSelChangeCmds(wxListEvent& ev) { +} +void dlgProJob::OnAdd(wxCommandEvent& ev) { + +} +void dlgProJob::OnChange(wxCommandEvent& ev) { + +} +void dlgProJob::OnRemove(wxCommandEvent& ev) { + +} + +void dlgProJob::OnChangeName(wxCommandEvent &ev) +{ + bool relocatable; + + // add all versions + //cbVersion->Clear(); + //cbVersion->Append(wxEmptyString); + //pgSetIterator versions(connection, + // wxT("SELECT version, relocatable FROM pg_available_extension_versions\n") + // wxT(" WHERE name=") + qtDbString(cbName->GetValue()) + wxT(" ") + // wxT(" ORDER BY version")); + + //while (versions.RowsLeft()) + //{ + // relocatable = versions.GetBool(wxT("relocatable")); + // cbVersion->Append(versions.GetVal(wxT("version"))); + //} + + + OnChange(ev); +} + + +void dlgProJob::CheckChange() +{ + bool didChange = true; + if (job && cbRunAs->GetCount()>0) + { + didChange = chkEnabled->GetValue() != job->GetEnabled() + || txtCron->GetValue() != job->GetCrontab() + || chkSameTran->GetValue() != job->GetSameTransaction() + || txtName->GetValue() != job->GetName() + || txtComment->GetValue() != job->GetComment() + || cbRunAs->GetValue() != job->GetRunAs() + || txtSqlBox->GetText()!=oldsrc + ; + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !txtName->GetValue().IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } +} + +wxString dlgProJob::StrAttribute(const wxString &name,wxString &value) +{ + wxString tmp = value; + //tmp.Replace("\'", "\'\'"); + return "\"" + name + "\": \"" + tmp+"\""; +} +void dlgProJob::append(wxString& str, const wxString& delimiter, const wxString& what) +{ + if (!what.IsNull()) + if(str.IsNull()) str += what; + else + str += delimiter + what; +} +wxString dlgProJob::GetSql() +{ + wxString sql; + + if (job) + { + // edit mode + if (chkEnabled->GetValue() != job->GetEnabled()) + if (chkEnabled->GetValue()) sql = wxT("select schedule.activate_job(") + NumToStr(job->GetRecId()) + wxT(");\n"); + else + sql = wxT("select schedule.deactivate_job(") + NumToStr(job->GetRecId()) + wxT(");\n"); + + + wxString att; + if (txtCron->GetValue() != job->GetCrontab()) att= StrAttribute(wxT("cron"),txtCron->GetValue()); + if (txtName->GetValue() != job->GetName()) append(att, ",\n", StrAttribute(wxT("name"), txtName->GetValue())); + if (txtComment->GetValue() != job->GetComment()) append(att, ",\n", StrAttribute(wxT("comments"), txtComment->GetValue())); + if (cbRunAs->GetValue() != job->GetRunAs()) append(att, ",\n", StrAttribute(wxT("run_as"), cbRunAs->GetValue())); + if (chkSameTran->GetValue() != job->GetSameTransaction()) append(att, ",\n", StrAttribute(wxT("use_same_transaction"), BoolToStr(chkSameTran->GetValue()))); + + + if (txtSqlBox->GetText() != oldsrc) { + wxArrayString a; + wxString tmp; + fillarray(a, txtSqlBox->GetText()); + if (a.GetCount() > 0) { + for (int i = 0; i < a.GetCount(); i++) append(tmp, ",\n", "\"" + a[i] + "\""); + tmp = "[" + tmp + "]"; + } + else tmp = ""; + tmp = "\"commands\": " + tmp; + if (!att.IsEmpty()) att += ",\n"; + att += tmp; + } + if (!att.IsEmpty()) { + sql += wxT("select schedule.set_job_attributes(") + NumToStr(job->GetRecId()) + "\n"; + att.Replace("\'", "\'\'"); + sql += wxT(",'{") + att + wxT("}');\n"); + } + } + else + { + //sql = wxT("CREATE EXTENSION ") + qtIdent(cbName->GetValue()); + //AppendIfFilled(sql, wxT("\n SCHEMA "), qtIdent(cbObjectsSchema->GetValue())); + //AppendIfFilled(sql, wxT("\n VERSION "), qtIdent(cbVersion->GetValue())); + } + + return sql; +} diff --git a/include/dlg/dlgProJob.h b/include/dlg/dlgProJob.h new file mode 100644 index 0000000..d7fe230 --- /dev/null +++ b/include/dlg/dlgProJob.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtension.h - Extension property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_EXTENSIONPROP +#define __DLG_EXTENSIONPROP + +#include "dlg/dlgProperty.h" + +class pgproJob; + +class dlgProJob : public dlgProperty +{ +public: + dlgProJob(pgaFactory *factory, frmMain *frame, pgproJob *job); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgproJob *job; + wxString oldsrc; + ctlComboBox* cbRunas; + wxString StrAttribute(const wxString& name, wxString& value); + void append(wxString& str, const wxString& delimiter, const wxString& what); + void OnChangeName(wxCommandEvent &ev); + void OnSelChangeCmds(wxListEvent& ev); + void OnAdd(wxCommandEvent& ev); + void OnChange(wxCommandEvent& ev); + void OnRemove(wxCommandEvent& ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/pro_scheduler/pgproJob.h b/include/pro_scheduler/pgproJob.h index b7eb6ce..8f56706 100644 --- a/include/pro_scheduler/pgproJob.h +++ b/include/pro_scheduler/pgproJob.h @@ -50,10 +50,6 @@ public: wxString GetSql(ctlTree *browser); bool NeedRefresh(); - wxString GetCrontab() const - { - return crontab; - } void iSetSched(int cron, wxString &mi, wxString& h, wxString& d, wxString& wd, wxString& mon) { for (int i = 0; i < 60; i++) _mi[i] = false; @@ -193,6 +189,10 @@ public: { sched_min = d; } + wxString GetCrontab() const + { + return crontab; + } void iSetCrontab(const wxString &s) { crontab = s; @@ -261,11 +261,24 @@ public: { runas = s; } - + void iSetSameTransaction(bool b) + { + use_same_transaction = b; + } + bool GetSameTransaction() + { + return use_same_transaction; + } + wxString GetTryName() const { return tryname; } + wxString GetFullName() + { + return GetName() + wxT("(") + NumToStr(recId) + wxT(")"); + } + void iSetTryName(const wxString &s) { tryname = s; @@ -308,7 +321,7 @@ public: } bool CanEdit() { - return false; + return true; } bool CanDrop() { @@ -325,7 +338,7 @@ public: } private: - bool enabled; + bool enabled, use_same_transaction; wxDateTime finished, changed, nextrun, lastrun,sched_min; wxDateTime nextrefresh; wxString message, crontab, runas, commands,status,rule,tryname; diff --git a/pgAdmin3.vcxproj b/pgAdmin3.vcxproj index e76af1d..a55b119 100644 --- a/pgAdmin3.vcxproj +++ b/pgAdmin3.vcxproj @@ -868,6 +868,7 @@ + @@ -1525,6 +1526,7 @@ + diff --git a/pgAdmin3.vcxproj.filters b/pgAdmin3.vcxproj.filters index d18d8cf..58372cf 100644 --- a/pgAdmin3.vcxproj.filters +++ b/pgAdmin3.vcxproj.filters @@ -1632,6 +1632,9 @@ utils + + dlg + @@ -3485,6 +3488,9 @@ utils + + include\dlg + diff --git a/pro_scheduler/pgproJob.cpp b/pro_scheduler/pgproJob.cpp index 9517dc1..006ad0f 100644 --- a/pro_scheduler/pgproJob.cpp +++ b/pro_scheduler/pgproJob.cpp @@ -132,7 +132,7 @@ void pgproJob::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prop { CreateListColumns(properties); - properties->AppendItem(_("Name"), GetTryName()); + properties->AppendItem(_("Name"), GetName()); properties->AppendItem(_("ID"), GetRecId()); properties->AppendYesNoItem(_("Enabled"), GetEnabled()); //properties->AppendItem(_("Host agent"), GetHostAgent()); @@ -142,6 +142,7 @@ void pgproJob::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prop properties->AppendItem(_("Result"), GetStatus()); properties->AppendItem(_("Crontab"), GetCrontab()); //properties->AppendItem(_("Last result"), GetLastresult()); + properties->AppendItem(_("Owner"), GetOwner()); properties->AppendItem(_("Runas"), GetRunAs()); properties->AppendItem(_("Message"), GetMessage()); properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); @@ -249,10 +250,11 @@ pgObject *pgproJobFactory::CreateObjects(pgCollection *collection, ctlTree *brow status=jobs->GetVal(wxT("status")); if (status.IsNull()) status = _("Not run"); - wxString name=jobs->GetVal(wxT("name"))+wxT("(")+jobs->GetVal(wxT("id"))+wxT(")"); - job = new pgproJob(name); + ///wxString name=jobs->GetVal(wxT("name"))+wxT("(")+jobs->GetVal(wxT("id"))+wxT(")"); + + job = new pgproJob(jobs->GetVal(wxT("name"))); job->iSetStatus(status); - job->iSetTryName(jobs->GetVal(wxT("name"))); + job->iSetOwner(jobs->GetVal(wxT("owner"))); job->iSetServer(collection->GetServer()); job->iSetRecId(jobs->GetLong(wxT("id"))); job->iSetComment(jobs->GetVal(wxT("comments"))); @@ -270,6 +272,8 @@ pgObject *pgproJobFactory::CreateObjects(pgCollection *collection, ctlTree *brow job->iSetCommands(tmp); job->iSetRunAs(jobs->GetVal(wxT("run_as"))); job->iSetStarted(jobs->GetDateTime(wxT("started"))); + job->iSetSameTransaction(jobs->GetBool(wxT("use_same_transaction"))); + job->iSetFinished(jobs->GetDateTime(wxT("finished"))); job->iSetCrontab(jobs->GetVal(wxT("crontab"))); @@ -291,6 +295,7 @@ pgObject *pgproJobFactory::CreateObjects(pgCollection *collection, ctlTree *brow ||colname == wxT("days") ||colname == wxT("wdays") ||colname == wxT("hours") + || colname == wxT("active") ||colname == wxT("months") ||colname == wxT("scheduled_at_min") ||colname==wxT("owner")) continue; @@ -298,9 +303,9 @@ pgObject *pgproJobFactory::CreateObjects(pgCollection *collection, ctlTree *brow if (colname==wxT("broken")) break; if (columnCount) { - tmp += wxT(", "); + tmp += wxT("\n,"); } - if (colname==wxT("commands")) vl=vl.Mid(1,vl.Length()-2); + if (colname==wxT("commands")) vl="["+vl.Mid(1,vl.Length()-2)+"]"; else vl=wxT("\"")+vl+wxT("\""); tmp += wxT("\"")+colname+wxT("\"")+wxT(": ")+vl; @@ -425,10 +430,10 @@ void pgproJob::SetEnabled(ctlTree *browser, const bool b) UpdateIcon(browser); } -dlgProperty *pgproJobFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) -{ - return 0; -} +//dlgProperty *pgproJobFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +//{ +// return 0; +//} ///////////////////////////// @@ -440,7 +445,7 @@ dlgProperty *pgproJobFactory::CreateDialog(frmMain *frame, pgObject *node, pgObj #include "images/jobrun.pngc" pgproJobFactory::pgproJobFactory() - : pgServerObjFactory(__("pgAgent Job"), __("New Job"), __("Create a new Job."), job_png_img) + : pgServerObjFactory(__("pgpro_Scheduler Job"), __("New Job"), __("Create a new Job."), job_png_img) { metaType = PGM_PROJOB; disabledId = addIcon(jobdisabled_png_img); diff --git a/ui/dlgProJob.xrc b/ui/dlgProJob.xrc new file mode 100644 index 0000000..4037cfb --- /dev/null +++ b/ui/dlgProJob.xrc @@ -0,0 +1,299 @@ + + + + + + + 0 + 1 + 0 + 0 + 0 + 0 + + + wxEXPAND|wxALIGN_CENTER|wxALL + 3 + + + + 1 + + + + 0 + 2 + 5 + 5 + 1 + 8 + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + wxALL + 5 + + + + + + + + + wxALL + 5 + + + 0 + + + + wxALL + 5 + + + + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + 0 + + + + + + + + 0 + + + + 0 + 1 + 5 + 5 + 0 + 0 + + + + + wxALL|wxEXPAND + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + 0 + 5 + 3 + 3 + 0 + + + + + 0 + 0,0 + + + + wxALL + 5 + + + 0 + + + + + + + + + + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + 0 + + 0 + 4 + 0 + 0 + 1 + + + + wxEXPAND|wxALL + 3 + + + 0 + 0 + + + + + + + 0 + 0,0 + + + + wxEXPAND|wxALL + 3 + + + 1 + 0 + + + + + + wxEXPAND|wxALL + 3 + + + 0 + 0 + + + + + + + +