mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 06:05:49 -06:00
init
This commit is contained in:
commit
9c6f9f3405
1784 changed files with 440662 additions and 0 deletions
513
agent/dlgJob.cpp
Normal file
513
agent/dlgJob.cpp
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin III - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// dlgJob.cpp - PostgreSQL Job Property
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// App headers
|
||||
#include "pgAdmin3.h"
|
||||
#include "utils/misc.h"
|
||||
#include "agent/dlgJob.h"
|
||||
#include "agent/dlgStep.h"
|
||||
#include "agent/dlgSchedule.h"
|
||||
#include "agent/pgaJob.h"
|
||||
#include "agent/pgaStep.h"
|
||||
#include "agent/pgaSchedule.h"
|
||||
#include "frm/frmMain.h"
|
||||
|
||||
|
||||
// pointer to controls
|
||||
#define txtID CTRL_TEXT("txtID")
|
||||
#define chkEnabled CTRL_CHECKBOX("chkEnabled")
|
||||
#define cbJobclass CTRL_COMBOBOX("cbJobclass")
|
||||
#define txtHostAgent CTRL_TEXT("txtHostAgent")
|
||||
#define txtCreated CTRL_TEXT("txtCreated")
|
||||
#define txtChanged CTRL_TEXT("txtChanged")
|
||||
#define txtNextrun CTRL_TEXT("txtNextrun")
|
||||
#define txtLastrun CTRL_TEXT("txtLastrun")
|
||||
#define txtLastresult CTRL_TEXT("txtLastResult")
|
||||
|
||||
#define lstSteps CTRL_LISTVIEW("lstSteps")
|
||||
#define btnChangeStep CTRL_BUTTON("btnChangeStep")
|
||||
#define btnAddStep CTRL_BUTTON("btnAddStep")
|
||||
#define btnRemoveStep CTRL_BUTTON("btnRemoveStep")
|
||||
|
||||
#define lstSchedules CTRL_LISTVIEW("lstSchedules")
|
||||
#define btnChangeSchedule CTRL_BUTTON("btnChangeSchedule")
|
||||
#define btnAddSchedule CTRL_BUTTON("btnAddSchedule")
|
||||
#define btnRemoveSchedule CTRL_BUTTON("btnRemoveSchedule")
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE(dlgJob, dlgAgentProperty)
|
||||
EVT_CHECKBOX(XRCID("chkEnabled"), dlgProperty::OnChange)
|
||||
EVT_COMBOBOX(XRCID("cbJobclass"), dlgProperty::OnChange)
|
||||
EVT_TEXT(XRCID("txtHostAgent"), dlgProperty::OnChange)
|
||||
|
||||
EVT_LIST_ITEM_SELECTED(XRCID("lstSteps"), dlgJob::OnSelChangeStep)
|
||||
EVT_BUTTON(XRCID("btnChangeStep"), dlgJob::OnChangeStep)
|
||||
EVT_BUTTON(XRCID("btnAddStep"), dlgJob::OnAddStep)
|
||||
EVT_BUTTON(XRCID("btnRemoveStep"), dlgJob::OnRemoveStep)
|
||||
|
||||
EVT_LIST_ITEM_SELECTED(XRCID("lstSchedules"), dlgJob::OnSelChangeSchedule)
|
||||
EVT_BUTTON(XRCID("btnChangeSchedule"), dlgJob::OnChangeSchedule)
|
||||
EVT_BUTTON(XRCID("btnAddSchedule"), dlgJob::OnAddSchedule)
|
||||
EVT_BUTTON(XRCID("btnRemoveSchedule"), dlgJob::OnRemoveSchedule)
|
||||
|
||||
#ifdef __WXMAC__
|
||||
EVT_SIZE( dlgJob::OnChangeSize)
|
||||
#endif
|
||||
END_EVENT_TABLE();
|
||||
|
||||
|
||||
dlgProperty *pgaJobFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
|
||||
{
|
||||
return new dlgJob(this, frame, (pgaJob *)node);
|
||||
}
|
||||
|
||||
|
||||
dlgJob::dlgJob(pgaFactory *f, frmMain *frame, pgaJob *node)
|
||||
: dlgAgentProperty(f, frame, wxT("dlgJob"))
|
||||
{
|
||||
job = node;
|
||||
|
||||
txtID->Disable();
|
||||
txtCreated->Disable();
|
||||
txtChanged->Disable();
|
||||
txtNextrun->Disable();
|
||||
txtLastrun->Disable();
|
||||
txtLastresult->Disable();
|
||||
lstSteps->CreateColumns(0, _("Step"), _("Comment"), 90);
|
||||
lstSteps->AddColumn(wxT("cmd"), 0);
|
||||
lstSteps->AddColumn(wxT("id"), 0);
|
||||
|
||||
lstSchedules->CreateColumns(0, _("Schedule"), _("Comment"), 90);
|
||||
lstSchedules->AddColumn(wxT("cmd"), 0);
|
||||
lstSchedules->AddColumn(wxT("id"), 0);
|
||||
btnChangeStep->Disable();
|
||||
btnRemoveStep->Disable();
|
||||
btnChangeSchedule->Disable();
|
||||
btnRemoveSchedule->Disable();
|
||||
}
|
||||
|
||||
|
||||
pgObject *dlgJob::GetObject()
|
||||
{
|
||||
return job;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __WXMAC__
|
||||
void dlgJob::OnChangeSize(wxSizeEvent &ev)
|
||||
{
|
||||
lstSteps->SetSize(wxDefaultCoord, wxDefaultCoord,
|
||||
ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
|
||||
lstSchedules->SetSize(wxDefaultCoord, wxDefaultCoord,
|
||||
ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
|
||||
if (GetAutoLayout())
|
||||
{
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int dlgJob::Go(bool modal)
|
||||
{
|
||||
int returncode;
|
||||
|
||||
pgSet *jcl = connection->ExecuteSet(wxT("SELECT jclname FROM pgagent.pga_jobclass"));
|
||||
if (jcl)
|
||||
{
|
||||
while (!jcl->Eof())
|
||||
{
|
||||
cbJobclass->Append(jcl->GetVal(0));
|
||||
jcl->MoveNext();
|
||||
}
|
||||
delete jcl;
|
||||
}
|
||||
|
||||
if (job)
|
||||
{
|
||||
// edit mode
|
||||
recId = job->GetRecId();
|
||||
txtID->SetValue(NumToStr(recId));
|
||||
cbJobclass->SetValue(job->GetJobclass());
|
||||
chkEnabled->SetValue(job->GetEnabled());
|
||||
txtHostAgent->SetValue(job->GetHostAgent());
|
||||
txtCreated->SetValue(DateToStr(job->GetCreated()));
|
||||
txtChanged->SetValue(DateToStr(job->GetChanged()));
|
||||
txtNextrun->SetValue(DateToStr(job->GetNextrun()));
|
||||
txtLastrun->SetValue(DateToStr(job->GetLastrun()));
|
||||
txtLastresult->SetValue(job->GetLastresult());
|
||||
|
||||
wxCookieType cookie;
|
||||
pgObject *data = 0;
|
||||
|
||||
wxTreeItemId item, stepsItem, schedulesItem;
|
||||
item = mainForm->GetBrowser()->GetFirstChild(job->GetId(), cookie);
|
||||
while (item)
|
||||
{
|
||||
data = mainForm->GetBrowser()->GetObject(item);
|
||||
if (data->GetMetaType() == PGM_STEP)
|
||||
stepsItem = item;
|
||||
else if (data->GetMetaType() == PGM_SCHEDULE)
|
||||
schedulesItem = item;
|
||||
|
||||
item = mainForm->GetBrowser()->GetNextChild(job->GetId(), cookie);
|
||||
}
|
||||
|
||||
if (stepsItem)
|
||||
{
|
||||
pgCollection *coll = (pgCollection *)data;
|
||||
// make sure all columns are appended
|
||||
coll->ShowTreeDetail(mainForm->GetBrowser());
|
||||
// this is the columns collection
|
||||
item = mainForm->GetBrowser()->GetFirstChild(stepsItem, cookie);
|
||||
|
||||
// add columns
|
||||
while (item)
|
||||
{
|
||||
data = mainForm->GetBrowser()->GetObject(item);
|
||||
if (data->IsCreatedBy(stepFactory))
|
||||
{
|
||||
pgaStep *step = (pgaStep *)data;
|
||||
int pos = lstSteps->AppendItem(stepFactory.GetIconId(), step->GetName(), step->GetComment());
|
||||
lstSteps->SetItem(pos, 3, NumToStr((long)step));
|
||||
previousSteps.Add(NumToStr((long)step));
|
||||
}
|
||||
item = mainForm->GetBrowser()->GetNextChild(stepsItem, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
if (schedulesItem)
|
||||
{
|
||||
pgCollection *coll = (pgCollection *)data;
|
||||
// make sure all columns are appended
|
||||
coll->ShowTreeDetail(mainForm->GetBrowser());
|
||||
// this is the columns collection
|
||||
item = mainForm->GetBrowser()->GetFirstChild(schedulesItem, cookie);
|
||||
|
||||
// add columns
|
||||
while (item)
|
||||
{
|
||||
data = mainForm->GetBrowser()->GetObject(item);
|
||||
if (data->IsCreatedBy(scheduleFactory))
|
||||
{
|
||||
pgaSchedule *schedule = (pgaSchedule *)data;
|
||||
int pos = lstSchedules->AppendItem(scheduleFactory.GetIconId(), schedule->GetName(), schedule->GetComment());
|
||||
lstSchedules->SetItem(pos, 3, NumToStr((long)schedule));
|
||||
previousSchedules.Add(NumToStr((long)schedule));
|
||||
}
|
||||
item = mainForm->GetBrowser()->GetNextChild(schedulesItem, cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// create mode
|
||||
cbJobclass->SetSelection(0);
|
||||
btnChangeStep->Hide();
|
||||
btnChangeSchedule->Hide();
|
||||
}
|
||||
|
||||
returncode = dlgProperty::Go(modal);
|
||||
|
||||
SetSqlReadOnly(true);
|
||||
|
||||
// This fixes a UI glitch on MacOS X
|
||||
// Because of the new layout code, the Columns pane doesn't size itself properly
|
||||
SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight());
|
||||
SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight());
|
||||
|
||||
return returncode;
|
||||
}
|
||||
|
||||
|
||||
pgObject *dlgJob::CreateObject(pgCollection *collection)
|
||||
{
|
||||
pgObject *obj = jobFactory.CreateObjects(collection, 0, wxT(" WHERE jobid=") + NumToStr(recId) + wxT("\n"));
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::CheckChange()
|
||||
{
|
||||
bool enable = true;
|
||||
wxString name = GetName();
|
||||
if (job)
|
||||
{
|
||||
enable = txtComment->GetValue() != job->GetComment()
|
||||
|| name != job->GetName()
|
||||
|| chkEnabled->GetValue() != job->GetEnabled()
|
||||
|| txtHostAgent->GetValue() != job->GetHostAgent();
|
||||
if (!enable)
|
||||
{
|
||||
enable = !GetUpdateSql().IsEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
if (statusBar)
|
||||
statusBar->SetStatusText(wxEmptyString);
|
||||
|
||||
CheckValid(enable, !txtName->GetValue().IsEmpty(), _("Please specify name."));
|
||||
|
||||
EnableOK(enable);
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::OnChangeStep(wxCommandEvent &ev)
|
||||
{
|
||||
long pos = lstSteps->GetSelection();
|
||||
pgaStep *obj = (pgaStep *) StrToLong(lstSteps->GetText(pos, 3));
|
||||
|
||||
dlgStep step(&stepFactory, mainForm, obj, job);
|
||||
step.CenterOnParent();
|
||||
step.SetConnection(connection);
|
||||
|
||||
if (step.Go(true) != wxID_CANCEL)
|
||||
{
|
||||
lstSteps->SetItem(pos, 0, step.GetName());
|
||||
lstSteps->SetItem(pos, 1, step.GetComment());
|
||||
|
||||
if (lstSteps->GetText(pos, 3).IsEmpty())
|
||||
{
|
||||
wxString *stepSql = new wxString(step.GetInsertSql());
|
||||
lstSteps->SetItemData(pos, (long)stepSql);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString *stepSql = new wxString(step.GetUpdateSql());
|
||||
lstSteps->SetItemData(pos, (long)stepSql);
|
||||
}
|
||||
|
||||
CheckChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::OnSelChangeStep(wxListEvent &ev)
|
||||
{
|
||||
btnChangeStep->Enable();
|
||||
btnRemoveStep->Enable();
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::OnAddStep(wxCommandEvent &ev)
|
||||
{
|
||||
dlgStep step(&stepFactory, mainForm, NULL, job);
|
||||
step.CenterOnParent();
|
||||
step.SetConnection(connection);
|
||||
if (step.Go(true) != wxID_CANCEL)
|
||||
{
|
||||
int pos = lstSteps->AppendItem(stepFactory.GetIconId(), step.GetName(), step.GetComment());
|
||||
wxString *stepSql = new wxString(step.GetInsertSql());
|
||||
lstSteps->SetItemData(pos, (long)stepSql);
|
||||
CheckChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::OnRemoveStep(wxCommandEvent &ev)
|
||||
{
|
||||
delete (wxString *)lstSteps->GetItemData(lstSteps->GetSelection());
|
||||
lstSteps->DeleteCurrentItem();
|
||||
|
||||
btnChangeStep->Disable();
|
||||
btnRemoveStep->Disable();
|
||||
|
||||
CheckChange();
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::OnSelChangeSchedule(wxListEvent &ev)
|
||||
{
|
||||
btnChangeSchedule->Enable();
|
||||
btnRemoveSchedule->Enable();
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::OnChangeSchedule(wxCommandEvent &ev)
|
||||
{
|
||||
long pos = lstSchedules->GetSelection();
|
||||
pgaSchedule *obj = (pgaSchedule *) StrToLong(lstSchedules->GetText(pos, 3));
|
||||
|
||||
dlgSchedule schedule(&scheduleFactory, mainForm, obj, job);
|
||||
schedule.CenterOnParent();
|
||||
schedule.SetConnection(connection);
|
||||
|
||||
if (schedule.Go(true) != wxID_CANCEL)
|
||||
{
|
||||
lstSchedules->SetItem(pos, 0, schedule.GetName());
|
||||
lstSchedules->SetItem(pos, 1, schedule.GetComment());
|
||||
|
||||
if (lstSchedules->GetText(pos, 3).IsEmpty())
|
||||
{
|
||||
wxString *scheduleSql = new wxString(schedule.GetInsertSql());
|
||||
lstSchedules->SetItemData(pos, (long)scheduleSql);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString *scheduleSql = new wxString(schedule.GetUpdateSql());
|
||||
lstSchedules->SetItemData(pos, (long)scheduleSql);
|
||||
}
|
||||
|
||||
CheckChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::OnAddSchedule(wxCommandEvent &ev)
|
||||
{
|
||||
dlgSchedule schedule(&scheduleFactory, mainForm, NULL, job);
|
||||
schedule.CenterOnParent();
|
||||
schedule.SetConnection(connection);
|
||||
if (schedule.Go(true) != wxID_CANCEL)
|
||||
{
|
||||
int pos = lstSchedules->AppendItem(scheduleFactory.GetIconId(), schedule.GetName(), schedule.GetComment());
|
||||
wxString *scheduleSql = new wxString(schedule.GetInsertSql());
|
||||
lstSchedules->SetItemData(pos, (long)scheduleSql);
|
||||
CheckChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dlgJob::OnRemoveSchedule(wxCommandEvent &ev)
|
||||
{
|
||||
delete (wxString *)lstSchedules->GetItemData(lstSchedules->GetSelection());
|
||||
lstSchedules->DeleteCurrentItem();
|
||||
|
||||
btnChangeSchedule->Disable();
|
||||
btnRemoveSchedule->Disable();
|
||||
|
||||
CheckChange();
|
||||
}
|
||||
|
||||
|
||||
wxString dlgJob::GetInsertSql()
|
||||
{
|
||||
wxString sql;
|
||||
|
||||
if (!job)
|
||||
{
|
||||
sql = wxT("INSERT INTO pgagent.pga_job (jobid, jobjclid, jobname, jobdesc, jobenabled, jobhostagent)\n")
|
||||
wxT("SELECT <JobId>, jcl.jclid, ") + qtDbString(GetName()) +
|
||||
wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ") + BoolToStr(chkEnabled->GetValue()) +
|
||||
wxT(", ") + qtDbString(txtHostAgent->GetValue()) + wxT("\n")
|
||||
wxT(" FROM pgagent.pga_jobclass jcl WHERE jclname=") + qtDbString(cbJobclass->GetValue()) + wxT(";\n");
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
wxString dlgJob::GetUpdateSql()
|
||||
{
|
||||
wxString sql, name;
|
||||
name = GetName();
|
||||
|
||||
if (job)
|
||||
{
|
||||
// edit mode
|
||||
wxString vars;
|
||||
|
||||
if (name != job->GetName())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jobname = ") + qtDbString(name));
|
||||
}
|
||||
if (cbJobclass->GetValue().Trim() != job->GetJobclass())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jobjclid= (SELECT jclid FROM pgagent.pga_jobclass WHERE jclname=") + qtDbString(cbJobclass->GetValue()) + wxT(")"));
|
||||
}
|
||||
if (chkEnabled->GetValue() != job->GetEnabled())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jobenabled = ") + BoolToStr(chkEnabled->GetValue()));
|
||||
}
|
||||
if (txtHostAgent->GetValue() != job->GetHostAgent())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jobhostagent = ") + qtDbString(txtHostAgent->GetValue()));
|
||||
}
|
||||
if (txtComment->GetValue() != job->GetComment())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jobdesc = ") + qtDbString(txtComment->GetValue()));
|
||||
}
|
||||
|
||||
if (!vars.IsEmpty())
|
||||
sql = wxT("UPDATE pgagent.pga_job SET ") + vars + wxT("\n")
|
||||
wxT(" WHERE jobid=") + NumToStr(recId) + wxT(";\n");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// create mode
|
||||
// done by GetInsertSql
|
||||
}
|
||||
|
||||
int pos, index;
|
||||
|
||||
wxArrayString tmpSteps = previousSteps;
|
||||
for (pos = 0 ; pos < lstSteps->GetItemCount() ; pos++)
|
||||
{
|
||||
wxString str = lstSteps->GetText(pos, 3);
|
||||
if (!str.IsEmpty())
|
||||
{
|
||||
index = tmpSteps.Index(str);
|
||||
if (index >= 0)
|
||||
tmpSteps.RemoveAt(index);
|
||||
}
|
||||
|
||||
if(lstSteps->GetItemData(pos))
|
||||
{
|
||||
str = *(wxString *)lstSteps->GetItemData(pos);
|
||||
if (!str.IsEmpty())
|
||||
sql += str;
|
||||
}
|
||||
}
|
||||
|
||||
for (index = 0 ; index < (int)tmpSteps.GetCount() ; index++)
|
||||
{
|
||||
sql += wxT("DELETE FROM pgagent.pga_jobstep WHERE jstid=")
|
||||
+ NumToStr(((pgaStep *)StrToLong(tmpSteps.Item(index)))->GetRecId()) + wxT(";\n");
|
||||
}
|
||||
|
||||
wxArrayString tmpSchedules = previousSchedules;
|
||||
for (pos = 0 ; pos < lstSchedules->GetItemCount() ; pos++)
|
||||
{
|
||||
wxString str = lstSchedules->GetText(pos, 3);
|
||||
if (!str.IsEmpty())
|
||||
{
|
||||
index = tmpSchedules.Index(str);
|
||||
if (index >= 0)
|
||||
tmpSchedules.RemoveAt(index);
|
||||
}
|
||||
if(lstSchedules->GetItemData(pos))
|
||||
{
|
||||
str = *(wxString *)lstSchedules->GetItemData(pos);
|
||||
if (!str.IsEmpty())
|
||||
sql += str;
|
||||
}
|
||||
}
|
||||
|
||||
for (index = 0 ; index < (int)tmpSchedules.GetCount() ; index++)
|
||||
{
|
||||
sql += wxT("DELETE FROM pgagent.pga_schedule WHERE jscid=")
|
||||
+ NumToStr(((pgaStep *)StrToLong(tmpSchedules.Item(index)))->GetRecId()) + wxT(";\n");
|
||||
}
|
||||
|
||||
return sql;
|
||||
|
||||
}
|
||||
859
agent/dlgSchedule.cpp
Normal file
859
agent/dlgSchedule.cpp
Normal file
|
|
@ -0,0 +1,859 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin III - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// dlgSchedule.cpp - PostgreSQL Schedule Property
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
|
||||
// App headers
|
||||
#include "utils/misc.h"
|
||||
#include "agent/dlgSchedule.h"
|
||||
#include "agent/pgaSchedule.h"
|
||||
|
||||
// image for de/-select all
|
||||
#include "images/check.pngc"
|
||||
#include "images/uncheck.pngc"
|
||||
|
||||
// pointer to controls
|
||||
#define txtID CTRL_TEXT("txtID")
|
||||
#define chkEnabled CTRL_CHECKBOX("chkEnabled")
|
||||
#define calStart CTRL_CALENDAR("calStart")
|
||||
#define timStart CTRL_TIME("timStart")
|
||||
#define calEnd CTRL_CALENDAR("calEnd")
|
||||
#define timEnd CTRL_TIME("timEnd")
|
||||
#define chkWeekdays CTRL_CHECKLISTBOX("chkWeekdays")
|
||||
#define chkMonthdays CTRL_CHECKLISTBOX("chkMonthdays")
|
||||
#define chkMonths CTRL_CHECKLISTBOX("chkMonths")
|
||||
#define chkHours CTRL_CHECKLISTBOX("chkHours")
|
||||
#define chkMinutes CTRL_CHECKLISTBOX("chkMinutes")
|
||||
#define lstExceptions CTRL_LISTVIEW("lstExceptions")
|
||||
#define timException CTRL_TIME("timException")
|
||||
#define calException CTRL_CALENDAR("calException")
|
||||
#define btnAddException CTRL_BUTTON("btnAddException")
|
||||
#define btnChangeException CTRL_BUTTON("btnChangeException")
|
||||
#define btnRemoveException CTRL_BUTTON("btnRemoveException")
|
||||
#define btnWeekdays CTRL_BUTTON("btnWeekdays")
|
||||
#define btnMonthdays CTRL_BUTTON("btnMonthdays")
|
||||
#define btnMonths CTRL_BUTTON("btnMonths")
|
||||
#define btnHours CTRL_BUTTON("btnHours")
|
||||
#define btnMinutes CTRL_BUTTON("btnMinutes")
|
||||
|
||||
BEGIN_EVENT_TABLE(dlgSchedule, dlgAgentProperty)
|
||||
EVT_CHECKBOX(XRCID("chkEnabled"), dlgSchedule::OnChangeCom)
|
||||
EVT_CALENDAR_SEL_CHANGED(XRCID("calStart"), dlgSchedule::OnChangeCal)
|
||||
EVT_TEXT(XRCID("timStart"), dlgSchedule::OnChangeCom)
|
||||
EVT_CALENDAR_SEL_CHANGED(XRCID("calEnd"), dlgSchedule::OnChangeCal)
|
||||
EVT_TEXT(XRCID("timEnd"), dlgSchedule::OnChangeCom)
|
||||
EVT_LIST_ITEM_SELECTED(XRCID("lstExceptions"), dlgSchedule::OnSelChangeException)
|
||||
EVT_BUTTON(XRCID("btnAddException"), dlgSchedule::OnAddException)
|
||||
EVT_BUTTON(XRCID("btnChangeException"), dlgSchedule::OnChangeException)
|
||||
EVT_BUTTON(XRCID("btnRemoveException"), dlgSchedule::OnRemoveException)
|
||||
EVT_BUTTON(XRCID("btnWeekdays"), dlgSchedule::OnSelectAllWeekdays)
|
||||
EVT_BUTTON(XRCID("btnMonthdays"), dlgSchedule::OnSelectAllMonthdays)
|
||||
EVT_BUTTON(XRCID("btnMonths"), dlgSchedule::OnSelectAllMonths)
|
||||
EVT_BUTTON(XRCID("btnHours"), dlgSchedule::OnSelectAllHours)
|
||||
EVT_BUTTON(XRCID("btnMinutes"), dlgSchedule::OnSelectAllMinutes)
|
||||
EVT_CHECKLISTBOX(XRCID("chkWeekdays"), dlgSchedule::OnChangeCom)
|
||||
EVT_CHECKLISTBOX(XRCID("chkMonthdays"), dlgSchedule::OnChangeCom)
|
||||
EVT_CHECKLISTBOX(XRCID("chkMonths"), dlgSchedule::OnChangeCom)
|
||||
EVT_CHECKLISTBOX(XRCID("chkHours"), dlgSchedule::OnChangeCom)
|
||||
EVT_CHECKLISTBOX(XRCID("chkMinutes"), dlgSchedule::OnChangeCom)
|
||||
#ifdef __WXMAC__
|
||||
EVT_SIZE( dlgSchedule::OnChangeSize)
|
||||
#endif
|
||||
END_EVENT_TABLE();
|
||||
|
||||
|
||||
dlgProperty *pgaScheduleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
|
||||
{
|
||||
return new dlgSchedule(this, frame, (pgaSchedule *)node, (pgaJob *)parent);
|
||||
}
|
||||
|
||||
|
||||
dlgSchedule::dlgSchedule(pgaFactory *f, frmMain *frame, pgaSchedule *node, pgaJob *j)
|
||||
: dlgAgentProperty(f, frame, wxT("dlgSchedule"))
|
||||
{
|
||||
schedule = node;
|
||||
job = j;
|
||||
if (job)
|
||||
jobId = job->GetRecId();
|
||||
else
|
||||
jobId = 0;
|
||||
|
||||
lstExceptions->CreateColumns(0, _("Date"), _("Time"), 90);
|
||||
lstExceptions->AddColumn(wxT("dirty"), 0);
|
||||
lstExceptions->AddColumn(wxT("id"), 0);
|
||||
|
||||
txtID->Disable();
|
||||
|
||||
btnChangeException->Disable();
|
||||
btnRemoveException->Disable();
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < 24 ; i++)
|
||||
chkHours->Append(wxString::Format(wxT("%02d"), i));
|
||||
|
||||
for (i = 0 ; i < 60 ; i++)
|
||||
chkMinutes->Append(wxString::Format(wxT("%02d"), i));
|
||||
}
|
||||
|
||||
|
||||
pgObject *dlgSchedule::GetObject()
|
||||
{
|
||||
return schedule;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __WXMAC__
|
||||
void dlgSchedule::OnChangeSize(wxSizeEvent &ev)
|
||||
{
|
||||
lstExceptions->SetSize(wxDefaultCoord, wxDefaultCoord,
|
||||
ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
|
||||
if (GetAutoLayout())
|
||||
{
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int dlgSchedule::Go(bool modal)
|
||||
{
|
||||
int returncode;
|
||||
|
||||
if (schedule)
|
||||
{
|
||||
// edit mode
|
||||
recId = schedule->GetRecId();
|
||||
txtID->SetValue(NumToStr(recId));
|
||||
chkEnabled->SetValue(schedule->GetEnabled());
|
||||
calStart->SetValue(schedule->GetStart().GetDateOnly());
|
||||
timStart->SetTime(schedule->GetStart());
|
||||
if (schedule->GetEnd().IsValid())
|
||||
{
|
||||
calEnd->SetValue(schedule->GetEnd().GetDateOnly());
|
||||
timEnd->SetTime(schedule->GetEnd());
|
||||
}
|
||||
else
|
||||
{
|
||||
calEnd->SetValue(wxInvalidDateTime);
|
||||
timEnd->SetTime(wxInvalidDateTime);
|
||||
timEnd->Disable();
|
||||
}
|
||||
|
||||
unsigned int x;
|
||||
for (x = 0; x < schedule->GetMonths().Length(); x++ )
|
||||
if (schedule->GetMonths()[x] == 't') chkMonths->Check(x, true);
|
||||
|
||||
for (x = 0; x < schedule->GetMonthdays().Length(); x++ )
|
||||
if (schedule->GetMonthdays()[x] == 't') chkMonthdays->Check(x, true);
|
||||
|
||||
for (x = 0; x < schedule->GetWeekdays().Length(); x++ )
|
||||
if (schedule->GetWeekdays()[x] == 't') chkWeekdays->Check(x, true);
|
||||
|
||||
for (x = 0; x < schedule->GetHours().Length(); x++ )
|
||||
if (schedule->GetHours()[x] == 't') chkHours->Check(x, true);
|
||||
|
||||
for (x = 0; x < schedule->GetMinutes().Length(); x++ )
|
||||
if (schedule->GetMinutes()[x] == 't') chkMinutes->Check(x, true);
|
||||
|
||||
wxString id, dateToken, timeToken;
|
||||
wxDateTime val;
|
||||
long pos = 0;
|
||||
wxStringTokenizer tkz(schedule->GetExceptions(), wxT("|"));
|
||||
|
||||
while (tkz.HasMoreTokens() )
|
||||
{
|
||||
dateToken.Empty();
|
||||
timeToken.Empty();
|
||||
|
||||
// First is the ID
|
||||
id = tkz.GetNextToken();
|
||||
|
||||
// Look for a date
|
||||
if (tkz.HasMoreTokens())
|
||||
dateToken = tkz.GetNextToken();
|
||||
|
||||
// Look for a time
|
||||
if (tkz.HasMoreTokens())
|
||||
timeToken = tkz.GetNextToken();
|
||||
|
||||
if (!dateToken.IsEmpty() && !timeToken.IsEmpty())
|
||||
{
|
||||
val.ParseDate(dateToken);
|
||||
val.ParseTime(timeToken);
|
||||
pos = lstExceptions->AppendItem(0, val.FormatDate(), val.FormatTime());
|
||||
}
|
||||
else if (!dateToken.IsEmpty() && timeToken.IsEmpty())
|
||||
{
|
||||
val.ParseDate(dateToken);
|
||||
pos = lstExceptions->AppendItem(0, val.FormatDate(), _("<any>"));
|
||||
}
|
||||
else if (dateToken.IsEmpty() && !timeToken.IsEmpty())
|
||||
{
|
||||
val.ParseTime(timeToken);
|
||||
pos = lstExceptions->AppendItem(0, _("<any>"), val.FormatTime());
|
||||
}
|
||||
|
||||
lstExceptions->SetItem(pos, 2, BoolToStr(false));
|
||||
lstExceptions->SetItem(pos, 3, id);
|
||||
|
||||
}
|
||||
|
||||
wxNotifyEvent ev;
|
||||
}
|
||||
else
|
||||
{
|
||||
// create mode
|
||||
}
|
||||
|
||||
// setup de-/select buttons
|
||||
InitSelectAll();
|
||||
|
||||
returncode = dlgProperty::Go(modal);
|
||||
|
||||
SetSqlReadOnly(true);
|
||||
|
||||
return returncode;
|
||||
}
|
||||
|
||||
|
||||
pgObject *dlgSchedule::CreateObject(pgCollection *collection)
|
||||
{
|
||||
pgObject *obj = scheduleFactory.CreateObjects(collection, 0, wxT(" AND jscid=") + NumToStr(recId) + wxT("\n"));
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::OnChangeCal(wxCalendarEvent &ev)
|
||||
{
|
||||
CheckChange();
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::OnChangeCom(wxCommandEvent &ev)
|
||||
{
|
||||
CheckChange();
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::CheckChange()
|
||||
{
|
||||
timEnd->Enable(calEnd->GetValue().IsValid());
|
||||
|
||||
wxString name = GetName();
|
||||
bool enable = true;
|
||||
|
||||
if (statusBar)
|
||||
statusBar->SetStatusText(wxEmptyString);
|
||||
|
||||
InitSelectAll();
|
||||
|
||||
CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
|
||||
CheckValid(enable, calStart->GetValue().IsValid(), _("Please specify start date."));
|
||||
|
||||
if (enable)
|
||||
{
|
||||
EnableOK(!GetSql().IsEmpty());
|
||||
}
|
||||
else
|
||||
EnableOK(false);
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::OnSelChangeException(wxListEvent &ev)
|
||||
{
|
||||
int sel = lstExceptions->GetSelection();
|
||||
if (sel >= 0)
|
||||
{
|
||||
wxString exDate = lstExceptions->GetText(sel, 0);
|
||||
wxString exTime = lstExceptions->GetText(sel, 1);
|
||||
wxDateTime val, null;
|
||||
|
||||
if (exDate == _("<any>"))
|
||||
calException->SetValue(null);
|
||||
else
|
||||
{
|
||||
val.ParseDate(exDate);
|
||||
calException->SetValue(val);
|
||||
}
|
||||
if (exTime == _("<any>"))
|
||||
timException->SetTime(null);
|
||||
else
|
||||
{
|
||||
val.ParseTime(exTime);
|
||||
timException->SetTime(val);
|
||||
}
|
||||
|
||||
btnChangeException->Enable();
|
||||
btnRemoveException->Enable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::OnAddException(wxCommandEvent &ev)
|
||||
{
|
||||
if (!calException->GetValue().IsValid() && timException->GetValue().IsNull())
|
||||
{
|
||||
wxMessageBox(_("You must enter a valid date and/or time!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
|
||||
return;
|
||||
}
|
||||
|
||||
wxString exDate, exTime;
|
||||
|
||||
if (calException->GetValue().IsValid())
|
||||
exDate = calException->GetValue().FormatDate();
|
||||
else
|
||||
exDate = _("<any>");
|
||||
|
||||
if (!timException->GetValue().IsNull())
|
||||
exTime = timException->GetValue().Format();
|
||||
else
|
||||
exTime = _("<any>");
|
||||
|
||||
for (int pos = 0; pos < lstExceptions->GetItemCount(); pos++)
|
||||
{
|
||||
|
||||
if (lstExceptions->GetText(pos, 0) == exDate &&
|
||||
lstExceptions->GetText(pos, 1) == exTime)
|
||||
{
|
||||
wxMessageBox(_("The specified exception already exists!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lstExceptions->GetText(pos, 0) == exDate &&
|
||||
lstExceptions->GetText(pos, 1) == _("<any>"))
|
||||
{
|
||||
wxMessageBox(_("An exception already exists for any time on this date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lstExceptions->GetText(pos, 1) == exTime &&
|
||||
lstExceptions->GetText(pos, 0) == _("<any>"))
|
||||
{
|
||||
wxMessageBox(_("An exception already exists for this time on any date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lstExceptions->AppendItem(0, exDate, exTime);
|
||||
CheckChange();
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::OnChangeException(wxCommandEvent &ev)
|
||||
{
|
||||
if (!calException->GetValue().IsValid() && timException->GetValue().IsNull())
|
||||
{
|
||||
wxMessageBox(_("You must enter a valid date and/or time!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
|
||||
return;
|
||||
}
|
||||
|
||||
wxString exDate, exTime;
|
||||
|
||||
if (calException->GetValue().IsValid())
|
||||
exDate = calException->GetValue().FormatDate();
|
||||
else
|
||||
exDate = _("<any>");
|
||||
|
||||
if (!timException->GetValue().IsNull())
|
||||
exTime = timException->GetValue().Format();
|
||||
else
|
||||
exTime = _("<any>");
|
||||
|
||||
long item = lstExceptions->GetFocusedItem();
|
||||
|
||||
for (int pos = 0; pos < lstExceptions->GetItemCount(); pos++)
|
||||
{
|
||||
if (item != pos)
|
||||
{
|
||||
if (lstExceptions->GetText(pos, 0) == exDate &&
|
||||
lstExceptions->GetText(pos, 1) == exTime)
|
||||
{
|
||||
wxMessageBox(_("The specified exception already exists!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lstExceptions->GetText(pos, 0) == exDate &&
|
||||
lstExceptions->GetText(pos, 1) == _("<any>"))
|
||||
{
|
||||
wxMessageBox(_("An exception already exists for any time on this date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lstExceptions->GetText(pos, 1) == exTime &&
|
||||
lstExceptions->GetText(pos, 0) == _("<any>"))
|
||||
{
|
||||
wxMessageBox(_("An exception already exists for this time on any date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lstExceptions->SetItem(item, 0, exDate);
|
||||
lstExceptions->SetItem(item, 1, exTime);
|
||||
lstExceptions->SetItem(item, 2, BoolToStr(true));
|
||||
CheckChange();
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::OnRemoveException(wxCommandEvent &ev)
|
||||
{
|
||||
if (lstExceptions->GetText(lstExceptions->GetFocusedItem(), 3) != wxEmptyString)
|
||||
{
|
||||
deleteExceptions.Add(lstExceptions->GetText(lstExceptions->GetFocusedItem(), 3));
|
||||
}
|
||||
lstExceptions->DeleteCurrentItem();
|
||||
|
||||
btnChangeException->Disable();
|
||||
btnRemoveException->Disable();
|
||||
|
||||
CheckChange();
|
||||
}
|
||||
|
||||
|
||||
wxString dlgSchedule::GetComment()
|
||||
{
|
||||
return txtComment->GetValue();
|
||||
}
|
||||
|
||||
|
||||
wxString dlgSchedule::GetInsertSql()
|
||||
{
|
||||
wxString sql;
|
||||
if (!schedule)
|
||||
{
|
||||
wxString name = GetName();
|
||||
wxString jscjobid, list = wxT("NULL");
|
||||
if (jobId)
|
||||
jscjobid = NumToStr(jobId);
|
||||
else
|
||||
jscjobid = wxT("<JobId>");
|
||||
|
||||
// Build the various arrays of values
|
||||
sql = wxT("INSERT INTO pgagent.pga_schedule (jscid, jscjobid, jscname, jscdesc, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths, jscenabled, jscstart, jscend)\n")
|
||||
wxT("VALUES(<SchId>, ") + jscjobid + wxT(", ") + qtDbString(name) + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ")
|
||||
+ wxT("'") + ChkListBox2PgArray(chkMinutes) + wxT("', ")
|
||||
+ wxT("'") + ChkListBox2PgArray(chkHours) + wxT("', ")
|
||||
+ wxT("'") + ChkListBox2PgArray(chkWeekdays) + wxT("', ")
|
||||
+ wxT("'") + ChkListBox2PgArray(chkMonthdays) + wxT("', ")
|
||||
+ wxT("'") + ChkListBox2PgArray(chkMonths) + wxT("', ")
|
||||
+ BoolToStr(chkEnabled->GetValue()) + wxT(", ")
|
||||
+ wxT("'") + DateToAnsiStr(calStart->GetValue() + timStart->GetValue()) + wxT("'");
|
||||
|
||||
if (calEnd->GetValue().IsValid())
|
||||
sql += wxT(", '") + DateToAnsiStr(calEnd->GetValue() + timEnd->GetValue()) + wxT("'");
|
||||
else
|
||||
sql += wxT(", NULL");
|
||||
|
||||
sql += wxT(");\n");
|
||||
}
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
wxString dlgSchedule::GetUpdateSql()
|
||||
{
|
||||
wxString sql, name;
|
||||
name = GetName();
|
||||
|
||||
if (schedule)
|
||||
{
|
||||
// edit mode
|
||||
wxString vars;
|
||||
|
||||
if (name != schedule->GetName())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscname = ") + qtDbString(name));
|
||||
}
|
||||
if (txtComment->GetValue() != schedule->GetComment())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscdesc = ") + qtDbString(txtComment->GetValue()));
|
||||
}
|
||||
|
||||
if ((!chkEnabled->IsChecked() && schedule->GetEnabled()) || (chkEnabled->IsChecked() && !schedule->GetEnabled()))
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscenabled = ") + BoolToStr(chkEnabled->IsChecked()));
|
||||
}
|
||||
|
||||
if (calStart->GetValue() + timStart->GetValue() != schedule->GetStart())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscstart = '") + DateToAnsiStr(calStart->GetValue() + timStart->GetValue()) + wxT("'"));
|
||||
}
|
||||
|
||||
if (calEnd->GetValue().IsValid())
|
||||
{
|
||||
if (schedule->GetEnd().IsValid())
|
||||
{
|
||||
if (calEnd->GetValue() + timEnd->GetValue() != schedule->GetEnd())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscend = '") + DateToAnsiStr(calEnd->GetValue() + timEnd->GetValue()) + wxT("'"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscend = '") + DateToAnsiStr(calEnd->GetValue() + wxTimeSpan()) + wxT("'"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (schedule->GetEnd().IsValid())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscend = NULL"));
|
||||
}
|
||||
}
|
||||
|
||||
if (ChkListBox2StrArray(chkMinutes) != schedule->GetMinutes())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscminutes = '") + ChkListBox2PgArray(chkMinutes) + wxT("'"));
|
||||
}
|
||||
|
||||
if (ChkListBox2StrArray(chkHours) != schedule->GetHours())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jschours = '") + ChkListBox2PgArray(chkHours) + wxT("'"));
|
||||
}
|
||||
|
||||
if (ChkListBox2StrArray(chkWeekdays) != schedule->GetWeekdays())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscweekdays = '") + ChkListBox2PgArray(chkWeekdays) + wxT("'"));
|
||||
}
|
||||
|
||||
if (ChkListBox2StrArray(chkMonthdays) != schedule->GetMonthdays())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscmonthdays = '") + ChkListBox2PgArray(chkMonthdays) + wxT("'"));
|
||||
}
|
||||
|
||||
if (ChkListBox2StrArray(chkMonths) != schedule->GetMonths())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jscmonths = '") + ChkListBox2PgArray(chkMonths) + wxT("'"));
|
||||
}
|
||||
|
||||
if (!vars.IsEmpty())
|
||||
sql = wxT("UPDATE pgagent.pga_schedule SET ") + vars + wxT("\n")
|
||||
wxT(" WHERE jscid=") + NumToStr(recId) + wxT(";\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// create mode
|
||||
// Handled by GetInsertSQL
|
||||
}
|
||||
|
||||
unsigned int x = 0;
|
||||
int y = 0;
|
||||
wxDateTime tmpDateTime;
|
||||
wxString newDate, newTime;
|
||||
|
||||
// Remove old exceptions
|
||||
for (x = 0; x < deleteExceptions.Count(); x++)
|
||||
{
|
||||
sql += wxT("DELETE FROM pgagent.pga_exception\n WHERE jexid = ") + deleteExceptions[x] + wxT(";\n");
|
||||
}
|
||||
|
||||
// Update dirty exceptions
|
||||
for (y = 0; y < lstExceptions->GetItemCount(); y++)
|
||||
{
|
||||
if (lstExceptions->GetText(y, 2) == BoolToStr(true) &&
|
||||
lstExceptions->GetText(y, 3) != wxEmptyString)
|
||||
{
|
||||
if (lstExceptions->GetText(y, 0) == _("<any>"))
|
||||
newDate = wxT("null");
|
||||
else
|
||||
{
|
||||
tmpDateTime.ParseFormat(lstExceptions->GetText(y, 0), wxT("%x"));
|
||||
newDate = wxT("'") + tmpDateTime.FormatISODate() + wxT("'");
|
||||
}
|
||||
|
||||
if (lstExceptions->GetText(y, 1) == _("<any>"))
|
||||
newTime = wxT("null");
|
||||
else
|
||||
{
|
||||
tmpDateTime.ParseTime(lstExceptions->GetText(y, 1));
|
||||
newTime = wxT("'") + tmpDateTime.FormatISOTime() + wxT("'");
|
||||
}
|
||||
|
||||
sql += wxT("UPDATE pgagent.pga_exception SET jexdate = ") + newDate +
|
||||
wxT(", jextime = ") + newTime + wxT("\n WHERE jexid = ") +
|
||||
lstExceptions->GetText(y, 3) + wxT(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Insert new exceptions
|
||||
for (y = 0; y < lstExceptions->GetItemCount(); y++)
|
||||
{
|
||||
if (lstExceptions->GetText(y, 2) == wxEmptyString &&
|
||||
lstExceptions->GetText(y, 3) == wxEmptyString)
|
||||
{
|
||||
if (lstExceptions->GetText(y, 0) == _("<any>"))
|
||||
newDate = wxT("null");
|
||||
else
|
||||
{
|
||||
tmpDateTime.ParseFormat(lstExceptions->GetText(y, 0), wxT("%x"));
|
||||
newDate = wxT("'") + tmpDateTime.FormatISODate() + wxT("'");
|
||||
}
|
||||
|
||||
if (lstExceptions->GetText(y, 1) == _("<any>"))
|
||||
newTime = wxT("null");
|
||||
else
|
||||
{
|
||||
tmpDateTime.ParseTime(lstExceptions->GetText(y, 1));
|
||||
newTime = wxT("'") + tmpDateTime.FormatISOTime() + wxT("'");
|
||||
}
|
||||
|
||||
sql += wxT("INSERT INTO pgagent.pga_exception (jexscid, jexdate, jextime)\n VALUES (")
|
||||
+ NumToStr(recId) + wxT(", ") + newDate + wxT(", ") + newTime + wxT(");\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
const wxString dlgSchedule::ChkListBox2PgArray(wxCheckListBox *lb)
|
||||
{
|
||||
wxString res = wxT("{");
|
||||
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
if (lb->IsChecked(x))
|
||||
res += wxT("t,");
|
||||
else
|
||||
res += wxT("f,");
|
||||
}
|
||||
if (res.Length() > 1)
|
||||
res.RemoveLast();
|
||||
|
||||
res += wxT("}");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
const wxString dlgSchedule::ChkListBox2StrArray(wxCheckListBox *lb)
|
||||
{
|
||||
wxString res;
|
||||
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
if (lb->IsChecked(x))
|
||||
res += wxT("t");
|
||||
else
|
||||
res += wxT("f");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::OnSelectAll(wxCommandEvent &ev, int origin)
|
||||
{
|
||||
bool check = false;
|
||||
wxBitmapButton *btn;
|
||||
wxCheckListBox *lb;
|
||||
wxString tooltip;
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
case 1:
|
||||
btn = ((wxBitmapButton *)btnWeekdays);
|
||||
lb = chkWeekdays;
|
||||
break;
|
||||
case 2:
|
||||
btn = ((wxBitmapButton *)btnMonthdays);
|
||||
lb = chkMonthdays;
|
||||
break;
|
||||
case 3:
|
||||
btn = ((wxBitmapButton *)btnMonths);
|
||||
lb = chkMonths;
|
||||
break;
|
||||
case 4:
|
||||
btn = ((wxBitmapButton *)btnHours);
|
||||
lb = chkHours;
|
||||
break;
|
||||
case 5:
|
||||
btn = ((wxBitmapButton *)btnMinutes);
|
||||
lb = chkMinutes;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
if (!lb->IsChecked(x))
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
lb->Check(x, check);
|
||||
}
|
||||
|
||||
CheckChange();
|
||||
}
|
||||
|
||||
|
||||
void dlgSchedule::InitSelectAll()
|
||||
{
|
||||
bool check = false;
|
||||
wxBitmapButton *btn;
|
||||
wxCheckListBox *lb;
|
||||
wxString tooltip;
|
||||
|
||||
btn = ((wxBitmapButton *)btnWeekdays);
|
||||
lb = chkWeekdays;
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
if (!lb->IsChecked(x))
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check)
|
||||
{
|
||||
btn->SetBitmapLabel(*check_png_bmp);
|
||||
tooltip = _("Select all week days");
|
||||
}
|
||||
else
|
||||
{
|
||||
btn->SetBitmapLabel(*uncheck_png_bmp);
|
||||
tooltip = _("Deselect all week days");
|
||||
}
|
||||
btn->SetToolTip(tooltip);
|
||||
|
||||
check = false;
|
||||
btn = ((wxBitmapButton *)btnMonthdays);
|
||||
lb = chkMonthdays;
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
if (!lb->IsChecked(x))
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check)
|
||||
{
|
||||
btn->SetBitmapLabel(*check_png_bmp);
|
||||
tooltip = _("Select all month days");
|
||||
}
|
||||
else
|
||||
{
|
||||
btn->SetBitmapLabel(*uncheck_png_bmp);
|
||||
tooltip = _("Deselect all month days");
|
||||
}
|
||||
btn->SetToolTip(tooltip);
|
||||
|
||||
check = false;
|
||||
btn = ((wxBitmapButton *)btnMonths);
|
||||
lb = chkMonths;
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
if (!lb->IsChecked(x))
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check)
|
||||
{
|
||||
btn->SetBitmapLabel(*check_png_bmp);
|
||||
tooltip = _("Select all months");
|
||||
}
|
||||
else
|
||||
{
|
||||
btn->SetBitmapLabel(*uncheck_png_bmp);
|
||||
tooltip = _("Deselect all months");
|
||||
}
|
||||
btn->SetToolTip(tooltip);
|
||||
|
||||
check = false;
|
||||
btn = ((wxBitmapButton *)btnHours);
|
||||
lb = chkHours;
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
if (!lb->IsChecked(x))
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check)
|
||||
{
|
||||
btn->SetBitmapLabel(*check_png_bmp);
|
||||
tooltip = _("Select all hours");
|
||||
}
|
||||
else
|
||||
{
|
||||
btn->SetBitmapLabel(*uncheck_png_bmp);
|
||||
tooltip = _("Deselect all hours");
|
||||
}
|
||||
btn->SetToolTip(tooltip);
|
||||
|
||||
|
||||
check = false;
|
||||
btn = ((wxBitmapButton *)btnMinutes);
|
||||
lb = chkMinutes;
|
||||
for (unsigned int x = 0; x < lb->GetCount(); x++)
|
||||
{
|
||||
if (!lb->IsChecked(x))
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check)
|
||||
{
|
||||
btn->SetBitmapLabel(*check_png_bmp);
|
||||
tooltip = _("Select all minutes");
|
||||
}
|
||||
else
|
||||
{
|
||||
btn->SetBitmapLabel(*uncheck_png_bmp);
|
||||
tooltip = _("Deselect all minutes");
|
||||
}
|
||||
btn->SetToolTip(tooltip);
|
||||
}
|
||||
483
agent/dlgStep.cpp
Normal file
483
agent/dlgStep.cpp
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin III - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// dlgStep.cpp - PostgreSQL Step Property
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// App headers
|
||||
#include "pgAdmin3.h"
|
||||
#include "utils/misc.h"
|
||||
#include "agent/dlgStep.h"
|
||||
#include "agent/pgaStep.h"
|
||||
#include "dlg/dlgSelectDatabase.h"
|
||||
#include "schema/pgTable.h"
|
||||
|
||||
|
||||
// pointer to controls
|
||||
#define txtID CTRL_TEXT("txtID")
|
||||
#define chkEnabled CTRL_CHECKBOX("chkEnabled")
|
||||
#define rbxKind CTRL_RADIOBOX("rbxKind")
|
||||
#define rbxOnError CTRL_RADIOBOX("rbxOnError")
|
||||
#define pnlDefinition CTRL_PANEL("pnlDefinition")
|
||||
#define txtSqlBox CTRL_TEXT("txtSqlBox")
|
||||
#define cbDatabase CTRL_COMBOBOX2("cbDatabase")
|
||||
#define txtConnStr CTRL_TEXT("txtConnStr")
|
||||
#define btnSelDatabase CTRL_BUTTON("btnSelDatabase")
|
||||
#define rbRemoteConn CTRL_RADIOBUTTON("rbRemoteConn")
|
||||
#define rbLocalConn CTRL_RADIOBUTTON("rbLocalConn")
|
||||
|
||||
#define CTL_SQLBOX 188
|
||||
|
||||
BEGIN_EVENT_TABLE(dlgStep, dlgAgentProperty)
|
||||
EVT_CHECKBOX(XRCID("chkEnabled"), dlgProperty::OnChange)
|
||||
EVT_COMBOBOX(XRCID("cbDatabase"), dlgProperty::OnChange)
|
||||
EVT_RADIOBOX(XRCID("rbxKind"), dlgProperty::OnChange)
|
||||
EVT_RADIOBOX(XRCID("rbxOnError"), dlgProperty::OnChange)
|
||||
EVT_TEXT(XRCID("txtConnStr"), dlgProperty::OnChange)
|
||||
EVT_STC_MODIFIED(CTL_SQLBOX, dlgProperty::OnChangeStc)
|
||||
EVT_BUTTON(XRCID("btnSelDatabase"), dlgStep::OnSelectDatabase)
|
||||
EVT_RADIOBUTTON(XRCID("rbRemoteConn"), dlgStep::OnSelRemoteConn)
|
||||
EVT_RADIOBUTTON(XRCID("rbLocalConn"), dlgStep::OnSelLocalConn)
|
||||
END_EVENT_TABLE();
|
||||
|
||||
|
||||
dlgProperty *pgaStepFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
|
||||
{
|
||||
return new dlgStep(this, frame, (pgaStep *)node, (pgaJob *)parent);
|
||||
}
|
||||
|
||||
|
||||
dlgStep::dlgStep(pgaFactory *f, frmMain *frame, pgaStep *node, pgaJob *j)
|
||||
: dlgAgentProperty(f, frame, wxT("dlgStep"))
|
||||
{
|
||||
step = node;
|
||||
job = j;
|
||||
if (job)
|
||||
jobId = job->GetRecId();
|
||||
else
|
||||
jobId = 0;
|
||||
|
||||
sqlBox = new ctlSQLBox(pnlDefinition, CTL_SQLBOX, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2);
|
||||
|
||||
wxWindow *placeholder = CTRL_TEXT("txtSqlBox");
|
||||
wxSizer *sizer = placeholder->GetContainingSizer();
|
||||
sizer->Add(sqlBox, 1, wxRIGHT | wxGROW, 5);
|
||||
sizer->Detach(placeholder);
|
||||
delete placeholder;
|
||||
sizer->Layout();
|
||||
|
||||
|
||||
txtID->Disable();
|
||||
}
|
||||
|
||||
|
||||
pgObject *dlgStep::GetObject()
|
||||
{
|
||||
return step;
|
||||
}
|
||||
|
||||
|
||||
int dlgStep::Go(bool modal)
|
||||
{
|
||||
int returncode;
|
||||
|
||||
hasConnStrSupport = connection->TableHasColumn(wxT("pgagent"), wxT("pga_jobstep"), wxT("jstconnstr"));
|
||||
cbDatabase->Append(wxT(" "));
|
||||
cbDatabase->SetSelection(0);
|
||||
|
||||
pgSet *db = connection->ExecuteSet(wxT("SELECT datname FROM pg_database"));
|
||||
if (db)
|
||||
{
|
||||
while (!db->Eof())
|
||||
{
|
||||
cbDatabase->Append(db->GetVal(0));
|
||||
db->MoveNext();
|
||||
}
|
||||
delete db;
|
||||
}
|
||||
|
||||
if (step)
|
||||
{
|
||||
// edit mode
|
||||
recId = step->GetRecId();
|
||||
txtID->SetValue(NumToStr(recId));
|
||||
|
||||
if (step->HasConnectionString())
|
||||
{
|
||||
rbRemoteConn->SetValue(true);
|
||||
txtConnStr->Enable(true);
|
||||
txtConnStr->ChangeValue(step->GetConnStr());
|
||||
btnSelDatabase->Enable(true);
|
||||
cbDatabase->Enable(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
rbLocalConn->SetValue(true);
|
||||
if (step->GetDbname().IsEmpty())
|
||||
cbDatabase->SetSelection(0);
|
||||
else
|
||||
cbDatabase->SetValue(step->GetDbname());
|
||||
}
|
||||
|
||||
rbxKind->SetSelection(wxString(wxT("sb")).Find(step->GetKindChar()));
|
||||
rbxOnError->SetSelection(wxString(wxT("fsi")).Find(step->GetOnErrorChar()));
|
||||
sqlBox->SetText(step->GetCode());
|
||||
|
||||
chkEnabled->SetValue(step->GetEnabled());
|
||||
}
|
||||
else
|
||||
{
|
||||
// create mode
|
||||
rbLocalConn->SetValue(true);
|
||||
cbDatabase->Enable(true);
|
||||
btnSelDatabase->Enable(false);
|
||||
txtConnStr->Enable(false);
|
||||
if (!hasConnStrSupport)
|
||||
rbLocalConn->Enable(false);
|
||||
}
|
||||
|
||||
returncode = dlgProperty::Go(modal);
|
||||
|
||||
SetSqlReadOnly(true);
|
||||
|
||||
return returncode;
|
||||
}
|
||||
|
||||
|
||||
pgObject *dlgStep::CreateObject(pgCollection *collection)
|
||||
{
|
||||
wxString name = GetName();
|
||||
|
||||
pgObject *obj = stepFactory.CreateObjects(collection, 0, wxT(" AND jstid=") + NumToStr(recId) + wxT("\n"));
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void dlgStep::CheckChange()
|
||||
{
|
||||
wxString name = GetName();
|
||||
bool enable;
|
||||
if (step)
|
||||
{
|
||||
enable = name != step->GetName()
|
||||
|| chkEnabled->GetValue() != step->GetEnabled()
|
||||
|| rbxKind->GetSelection() != wxString(wxT("sb")).Find(step->GetKindChar())
|
||||
|| rbxOnError->GetSelection() != wxString(wxT("fsi")).Find(step->GetOnErrorChar())
|
||||
|| txtComment->GetValue() != step->GetComment()
|
||||
|| sqlBox->GetText() != step->GetCode();
|
||||
|
||||
if (!enable && rbxKind->GetSelection() == 0)
|
||||
{
|
||||
if (hasConnStrSupport)
|
||||
{
|
||||
if (step->HasConnectionString())
|
||||
{
|
||||
if (rbRemoteConn->GetValue())
|
||||
enable = txtConnStr->GetValue().Trim() != step->GetConnStr();
|
||||
else
|
||||
enable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rbRemoteConn->GetValue())
|
||||
enable = true;
|
||||
else
|
||||
enable = cbDatabase->GetValue().Trim() != step->GetDbname();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
enable = cbDatabase->GetValue().Trim() != step->GetDbname();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
enable = true;
|
||||
}
|
||||
|
||||
if (statusBar)
|
||||
statusBar->SetStatusText(wxEmptyString);
|
||||
|
||||
CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
|
||||
CheckValid(enable, sqlBox->GetLength() > 0, _("Please specify code to execute."));
|
||||
|
||||
// Disable/enable the database combo
|
||||
if (rbxKind->GetSelection() == 1)
|
||||
{
|
||||
rbRemoteConn->Enable(false);
|
||||
rbLocalConn->Enable(false);
|
||||
// I don't see any reason to make
|
||||
// the database combobox selection to 0
|
||||
//cbDatabase->SetSelection(0);
|
||||
txtConnStr->Enable(false);
|
||||
btnSelDatabase->Enable(false);
|
||||
cbDatabase->Enable(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasConnStrSupport)
|
||||
{
|
||||
rbRemoteConn->Enable(true);
|
||||
rbLocalConn->Enable(true);
|
||||
if (rbRemoteConn->GetValue())
|
||||
{
|
||||
wxString validConnStr;
|
||||
|
||||
btnSelDatabase->Enable(true);
|
||||
txtConnStr->Enable(true);
|
||||
cbDatabase->Enable(false);
|
||||
CheckValid(enable, !txtConnStr->GetValue().Trim().IsEmpty(), _("Please select a connection string."));
|
||||
CheckValid(enable, dlgSelectDatabase::getValidConnectionString(txtConnStr->GetValue().Trim(), validConnStr), _("Please enter a valid connection string"));
|
||||
}
|
||||
else
|
||||
{
|
||||
cbDatabase->Enable(true);
|
||||
btnSelDatabase->Enable(false);
|
||||
txtConnStr->Enable(false);
|
||||
CheckValid(enable, !cbDatabase->GetValue().Trim().IsEmpty(), _("Please select a database."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cbDatabase->Enable(true);
|
||||
// Make sure both radio buttons are disabled
|
||||
rbRemoteConn->Enable(false);
|
||||
rbLocalConn->Enable(false);
|
||||
CheckValid(enable, !cbDatabase->GetValue().Trim().IsEmpty(), _("Please select a database."));
|
||||
}
|
||||
}
|
||||
|
||||
EnableOK(enable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
wxString dlgStep::GetComment()
|
||||
{
|
||||
return txtComment->GetValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
wxString dlgStep::GetInsertSql()
|
||||
{
|
||||
wxString sql;
|
||||
|
||||
if (!step)
|
||||
{
|
||||
wxString name = GetName();
|
||||
wxString kind = wxT("sb")[rbxKind->GetSelection()];
|
||||
wxString onerror = wxT("fsi")[rbxOnError->GetSelection()];
|
||||
wxString db, connstr;
|
||||
wxString jstjobid;
|
||||
if (jobId)
|
||||
jstjobid = NumToStr(jobId);
|
||||
else
|
||||
jstjobid = wxT("<JobId>");
|
||||
// SQL script expected
|
||||
if (rbxKind->GetSelection() == 0)
|
||||
{
|
||||
if (hasConnStrSupport && rbRemoteConn->GetValue())
|
||||
{
|
||||
connstr = qtDbString(txtConnStr->GetValue().Trim());
|
||||
db = wxT("''");
|
||||
}
|
||||
else
|
||||
{
|
||||
db = qtDbString(cbDatabase->GetValue().Trim());
|
||||
connstr = wxT("''");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
db = wxT("''");
|
||||
connstr = wxT("''");
|
||||
}
|
||||
|
||||
sql = wxT("INSERT INTO pgagent.pga_jobstep (jstid, jstjobid, jstname, jstdesc, jstenabled, jstkind, jstonerror, jstcode, jstdbname");
|
||||
if (hasConnStrSupport)
|
||||
sql += wxT(", jstconnstr");
|
||||
sql += wxT(")\n ") \
|
||||
wxT("SELECT <StpId>, ") + jstjobid + wxT(", ") + qtDbString(name) + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ")
|
||||
+ BoolToStr(chkEnabled->GetValue()) + wxT(", ") + qtDbString(kind) + wxT(", ")
|
||||
+ qtDbString(onerror) + wxT(", ") + qtDbString(sqlBox->GetText()) + wxT(", ") + db;
|
||||
if (hasConnStrSupport)
|
||||
{
|
||||
sql += wxT(", ") + connstr;
|
||||
}
|
||||
sql += wxT(";\n");
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
wxString dlgStep::GetUpdateSql()
|
||||
{
|
||||
wxString sql;
|
||||
|
||||
if (step)
|
||||
{
|
||||
// edit mode
|
||||
wxString name = GetName();
|
||||
wxString kind = wxT("sb")[rbxKind->GetSelection()];
|
||||
|
||||
wxString vars;
|
||||
if (name != step->GetName())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstname=") + qtDbString(name));
|
||||
}
|
||||
if (chkEnabled->GetValue() != step->GetEnabled())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstenabled=") + BoolToStr(chkEnabled->GetValue()));
|
||||
}
|
||||
if (hasConnStrSupport && kind == wxT("s"))
|
||||
{
|
||||
if (rbRemoteConn->GetValue())
|
||||
{
|
||||
if (step->HasConnectionString())
|
||||
{
|
||||
if (txtConnStr->GetValue().Trim() != step->GetConnStr())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstconnstr=") + qtDbString(txtConnStr->GetValue().Trim()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstconnstr=") + qtDbString(txtConnStr->GetValue().Trim()) + wxT(", "));
|
||||
vars.Append(wxT("jstdbname=''"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (step->HasConnectionString())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim()) + wxT(", "));
|
||||
vars.Append(wxT("jstconnstr=''"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cbDatabase->GetValue().Trim() != step->GetDbname())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (kind == wxT("s"))
|
||||
{
|
||||
if (cbDatabase->GetValue().Trim() != step->GetDbname())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstdbname=''"));
|
||||
if (hasConnStrSupport)
|
||||
vars.Append(wxT(", jstconnstr=''"));
|
||||
}
|
||||
if (rbxKind->GetSelection() != kind)
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstkind=") + qtDbString(kind));
|
||||
}
|
||||
if (rbxOnError->GetSelection() != wxString(wxT("fsi")).Find(step->GetOnErrorChar()))
|
||||
{
|
||||
wxString onerror = wxT("fsi")[rbxOnError->GetSelection()];
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstonerror='") + onerror + wxT("'"));
|
||||
}
|
||||
if (txtComment->GetValue() != step->GetComment())
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstdesc=") + qtDbString(txtComment->GetValue()));
|
||||
}
|
||||
if (sqlBox->GetText() != step->GetCode())
|
||||
{
|
||||
{
|
||||
if (!vars.IsEmpty())
|
||||
vars.Append(wxT(", "));
|
||||
vars.Append(wxT("jstcode=") + qtDbString(sqlBox->GetText()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!vars.IsEmpty())
|
||||
sql = wxT("UPDATE pgagent.pga_jobstep\n")
|
||||
wxT(" SET ") + vars + wxT("\n")
|
||||
wxT(" WHERE jstid=") + NumToStr(step->GetRecId()) +
|
||||
wxT(";\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// create mode; handled by GetInsertSql()
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
bool dlgStep::IsUpToDate()
|
||||
{
|
||||
if (step && !step->IsUpToDate())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void dlgStep::OnSelectDatabase(wxCommandEvent &ev)
|
||||
{
|
||||
dlgSelectDatabase dlgSD(this, wxID_ANY);
|
||||
if (dlgSD.ShowModal() == wxID_OK)
|
||||
{
|
||||
wxString strConnStr = dlgSD.getConnInfo();
|
||||
if (!strConnStr.IsEmpty())
|
||||
txtConnStr->SetValue(strConnStr);
|
||||
}
|
||||
}
|
||||
|
||||
void dlgStep::OnSelRemoteConn(wxCommandEvent &ev)
|
||||
{
|
||||
if (rbRemoteConn->GetValue())
|
||||
{
|
||||
cbDatabase->Enable(false);
|
||||
btnSelDatabase->Enable(true);
|
||||
txtConnStr->Enable(true);
|
||||
}
|
||||
dlgProperty::OnChange(ev);
|
||||
}
|
||||
|
||||
void dlgStep::OnSelLocalConn(wxCommandEvent &ev)
|
||||
{
|
||||
if (rbLocalConn->GetValue())
|
||||
{
|
||||
cbDatabase->Enable(true);
|
||||
btnSelDatabase->Enable(false);
|
||||
txtConnStr->Enable(false);
|
||||
}
|
||||
dlgProperty::OnChange(ev);
|
||||
}
|
||||
|
||||
|
||||
23
agent/module.mk
Normal file
23
agent/module.mk
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#######################################################################
|
||||
#
|
||||
# pgAdmin III - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
# module.mk - pgadmin/agent/ Makefile fragment
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
pgadmin3_SOURCES += \
|
||||
agent/dlgJob.cpp \
|
||||
agent/dlgSchedule.cpp \
|
||||
agent/dlgStep.cpp \
|
||||
agent/pgaJob.cpp \
|
||||
agent/pgaSchedule.cpp \
|
||||
agent/pgaStep.cpp
|
||||
|
||||
EXTRA_DIST += \
|
||||
agent/module.mk
|
||||
|
||||
|
||||
397
agent/pgaJob.cpp
Normal file
397
agent/pgaJob.cpp
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// wxWindows headers
|
||||
#include <wx/wx.h>
|
||||
|
||||
// App headers
|
||||
#include "pgAdmin3.h"
|
||||
#include "utils/misc.h"
|
||||
#include "frm/frmMain.h"
|
||||
#include "schema/pgObject.h"
|
||||
#include "schema/pgCollection.h"
|
||||
#include "schema/pgDatabase.h"
|
||||
#include "agent/pgaJob.h"
|
||||
#include "agent/pgaStep.h"
|
||||
#include "agent/pgaSchedule.h"
|
||||
|
||||
pgaJob::pgaJob(const wxString &newName)
|
||||
: pgServerObject(jobFactory, newName)
|
||||
{
|
||||
}
|
||||
|
||||
wxString pgaJob::GetTranslatedMessage(int kindOfMessage) const
|
||||
{
|
||||
wxString message = wxEmptyString;
|
||||
|
||||
switch (kindOfMessage)
|
||||
{
|
||||
case RETRIEVINGDETAILS:
|
||||
message = _("Retrieving details on pgAgent job");
|
||||
break;
|
||||
case REFRESHINGDETAILS:
|
||||
message = _("Refreshing pgAgent job");
|
||||
break;
|
||||
case PROPERTIESREPORT:
|
||||
message = _("pgAgent job properties report");
|
||||
break;
|
||||
case PROPERTIES:
|
||||
message = _("pgAgent job properties");
|
||||
break;
|
||||
case DDLREPORT:
|
||||
message = _("pgAgent job DDL report");
|
||||
break;
|
||||
case DEPENDENCIESREPORT:
|
||||
message = _("pgAgent job dependencies report");
|
||||
break;
|
||||
case DEPENDENCIES:
|
||||
message = _("pgAgent job dependencies");
|
||||
break;
|
||||
case DEPENDENTSREPORT:
|
||||
message = _("pgAgent job dependents report");
|
||||
break;
|
||||
case DEPENDENTS:
|
||||
message = _("pgAgent job dependents");
|
||||
break;
|
||||
case DROPEXCLUDINGDEPS:
|
||||
message = wxString::Format(_("Are you sure you wish to drop job \"%s\"?"),
|
||||
GetFullIdentifier().c_str());
|
||||
break;
|
||||
case DROPTITLE:
|
||||
message = _("Drop job?");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE))
|
||||
message += wxT(" - ") + GetName();
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
int pgaJob::GetIconId()
|
||||
{
|
||||
if (GetEnabled())
|
||||
return jobFactory.GetIconId();
|
||||
else
|
||||
return jobFactory.GetDisabledId();
|
||||
}
|
||||
|
||||
|
||||
wxMenu *pgaJob::GetNewMenu()
|
||||
{
|
||||
wxMenu *menu = pgObject::GetNewMenu();
|
||||
if (1) // check priv.
|
||||
{
|
||||
stepFactory.AppendMenu(menu);
|
||||
scheduleFactory.AppendMenu(menu);
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
bool pgaJob::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
|
||||
{
|
||||
return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_job WHERE jobid=") + NumToStr(GetRecId()));
|
||||
}
|
||||
|
||||
|
||||
void pgaJob::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
|
||||
{
|
||||
if (!expandedKids)
|
||||
{
|
||||
expandedKids = true;
|
||||
|
||||
browser->RemoveDummyChild(this);
|
||||
|
||||
// Log
|
||||
wxLogInfo(wxT("Adding child objects to Job."));
|
||||
|
||||
browser->AppendCollection(this, scheduleFactory);
|
||||
browser->AppendCollection(this, stepFactory);
|
||||
}
|
||||
|
||||
if (properties)
|
||||
{
|
||||
CreateListColumns(properties);
|
||||
|
||||
properties->AppendItem(_("Name"), GetName());
|
||||
properties->AppendItem(_("ID"), GetRecId());
|
||||
properties->AppendYesNoItem(_("Enabled"), GetEnabled());
|
||||
properties->AppendItem(_("Host agent"), GetHostAgent());
|
||||
properties->AppendItem(_("Job class"), GetJobclass());
|
||||
properties->AppendItem(_("Created"), GetCreated());
|
||||
properties->AppendItem(_("Changed"), GetChanged());
|
||||
properties->AppendItem(_("Next run"), GetNextrun());
|
||||
properties->AppendItem(_("Last run"), GetLastrun());
|
||||
properties->AppendItem(_("Last result"), GetLastresult());
|
||||
if (!GetCurrentAgent().IsEmpty())
|
||||
properties->AppendItem(_("Running at"), GetCurrentAgent());
|
||||
else
|
||||
properties->AppendItem(_("Running at"), _("Not currently running"));
|
||||
|
||||
properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
pgObject *pgaJob::Refresh(ctlTree *browser, const wxTreeItemId item)
|
||||
{
|
||||
pgObject *job = 0;
|
||||
|
||||
pgObject *obj = browser->GetObject(browser->GetItemParent(item));
|
||||
if (obj && obj->IsCollection())
|
||||
job = jobFactory.CreateObjects((pgCollection *)obj, 0, wxT("\n WHERE j.jobid=") + NumToStr(GetRecId()));
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pgObject *pgaJobFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
|
||||
{
|
||||
pgaJob *job = 0;
|
||||
|
||||
pgSet *jobs = collection->GetConnection()->ExecuteSet(
|
||||
wxT("SELECT j.*, cl.*, ag.*, sub.jlgstatus AS joblastresult ")
|
||||
wxT(" FROM pgagent.pga_job j JOIN")
|
||||
wxT(" pgagent.pga_jobclass cl ON cl.jclid=jobjclid LEFT OUTER JOIN")
|
||||
wxT(" pgagent.pga_jobagent ag ON ag.jagpid=jobagentid LEFT OUTER JOIN")
|
||||
wxT(" (SELECT DISTINCT ON (jlgjobid) jlgstatus, jlgjobid")
|
||||
wxT(" FROM pgagent.pga_joblog")
|
||||
wxT(" ORDER BY jlgjobid, jlgid desc) sub ON sub.jlgjobid = j.jobid ")
|
||||
+ restriction +
|
||||
wxT("ORDER BY jobname;"));
|
||||
|
||||
if (jobs)
|
||||
{
|
||||
while (!jobs->Eof())
|
||||
{
|
||||
wxString status;
|
||||
if (jobs->GetVal(wxT("joblastresult")) == wxT("r"))
|
||||
status = _("Running");
|
||||
else if (jobs->GetVal(wxT("joblastresult")) == wxT("s"))
|
||||
status = _("Successful");
|
||||
else if (jobs->GetVal(wxT("joblastresult")) == wxT("f"))
|
||||
status = _("Failed");
|
||||
else if (jobs->GetVal(wxT("joblastresult")) == wxT("d"))
|
||||
status = _("Aborted");
|
||||
else if (jobs->GetVal(wxT("joblastresult")) == wxT("i"))
|
||||
status = _("No steps");
|
||||
else
|
||||
status = _("Unknown");
|
||||
|
||||
job = new pgaJob(jobs->GetVal(wxT("jobname")));
|
||||
job->iSetServer(collection->GetServer());
|
||||
job->iSetRecId(jobs->GetLong(wxT("jobid")));
|
||||
job->iSetComment(jobs->GetVal(wxT("jobdesc")));
|
||||
|
||||
job->iSetEnabled(jobs->GetBool(wxT("jobenabled")));
|
||||
job->iSetJobclass(jobs->GetVal(wxT("jclname")));
|
||||
job->iSetHostAgent(jobs->GetVal(wxT("jobhostagent")));
|
||||
job->iSetCreated(jobs->GetDateTime(wxT("jobcreated")));
|
||||
job->iSetChanged(jobs->GetDateTime(wxT("jobchanged")));
|
||||
job->iSetNextrun(jobs->GetDateTime(wxT("jobnextrun")));
|
||||
job->iSetLastrun(jobs->GetDateTime(wxT("joblastrun")));
|
||||
job->iSetLastresult(status);
|
||||
job->iSetCurrentAgent(jobs->GetVal(wxT("jagstation")));
|
||||
|
||||
if (browser)
|
||||
{
|
||||
browser->AppendObject(collection, job);
|
||||
jobs->MoveNext();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
delete jobs;
|
||||
}
|
||||
return job;
|
||||
}
|
||||
|
||||
void pgaJob::ShowStatistics(frmMain *form, ctlListView *statistics)
|
||||
{
|
||||
wxString sql =
|
||||
wxT("SELECT jlgid")
|
||||
wxT(", jlgstatus")
|
||||
wxT(", jlgstart")
|
||||
wxT(", jlgduration")
|
||||
wxT(", (jlgstart + jlgduration) AS endtime")
|
||||
wxT(" FROM pgagent.pga_joblog\n")
|
||||
wxT(" WHERE jlgjobid = ") + NumToStr(GetRecId()) +
|
||||
wxT(" ORDER BY jlgstart DESC") +
|
||||
wxT(" LIMIT ") + NumToStr(settings->GetMaxRows());
|
||||
|
||||
if (statistics)
|
||||
{
|
||||
wxLogInfo(wxT("Displaying statistics for job %s"), GetFullIdentifier().c_str());
|
||||
|
||||
// Add the statistics view columns
|
||||
statistics->ClearAll();
|
||||
statistics->AddColumn(_("Run"), 50);
|
||||
statistics->AddColumn(_("Status"), 60);
|
||||
statistics->AddColumn(_("Start time"), 95);
|
||||
statistics->AddColumn(_("End time"), 95);
|
||||
statistics->AddColumn(_("Duration"), 70);
|
||||
|
||||
pgSet *stats = GetConnection()->ExecuteSet(sql);
|
||||
wxString status;
|
||||
wxDateTime startTime;
|
||||
wxDateTime endTime;
|
||||
|
||||
if (stats)
|
||||
{
|
||||
while (!stats->Eof())
|
||||
{
|
||||
if (stats->GetVal(1) == wxT("r"))
|
||||
status = _("Running");
|
||||
else if (stats->GetVal(1) == wxT("s"))
|
||||
status = _("Successful");
|
||||
else if (stats->GetVal(1) == wxT("f"))
|
||||
status = _("Failed");
|
||||
else if (stats->GetVal(1) == wxT("d"))
|
||||
status = _("Aborted");
|
||||
else if (stats->GetVal(1) == wxT("i"))
|
||||
status = _("No steps");
|
||||
else
|
||||
status = _("Unknown");
|
||||
|
||||
startTime.ParseDateTime(stats->GetVal(2));
|
||||
endTime.ParseDateTime(stats->GetVal(4));
|
||||
|
||||
long pos = statistics->AppendItem(stats->GetVal(0), status, startTime.Format());
|
||||
if (stats->GetVal(4).Length() > 0)
|
||||
statistics->SetItem(pos, 3, endTime.Format());
|
||||
statistics->SetItem(pos, 4, stats->GetVal(3));
|
||||
|
||||
stats->MoveNext();
|
||||
}
|
||||
delete stats;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool pgaJob::RunNow()
|
||||
{
|
||||
if (!GetConnection()->ExecuteVoid(wxT("UPDATE pgagent.pga_job SET jobnextrun = now() WHERE jobid=") + NumToStr(GetRecId())))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
pgaJobCollection::pgaJobCollection(pgaFactory *factory, pgServer *sv)
|
||||
: pgServerObjCollection(factory, sv)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
wxString pgaJobCollection::GetTranslatedMessage(int kindOfMessage) const
|
||||
{
|
||||
wxString message = wxEmptyString;
|
||||
|
||||
switch (kindOfMessage)
|
||||
{
|
||||
case RETRIEVINGDETAILS:
|
||||
message = _("Retrieving details on pgAgent jobs");
|
||||
break;
|
||||
case REFRESHINGDETAILS:
|
||||
message = _("Refreshing pgAgent jobs");
|
||||
break;
|
||||
case OBJECTSLISTREPORT:
|
||||
message = _("pgAgent jobs list report");
|
||||
break;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
pgaJobObject::pgaJobObject(pgaJob *_job, pgaFactory &factory, const wxString &newName)
|
||||
: pgServerObject(factory, newName)
|
||||
{
|
||||
job = _job;
|
||||
server = job->GetServer();
|
||||
}
|
||||
|
||||
|
||||
pgaJobObjCollection::pgaJobObjCollection(pgaFactory *factory, pgaJob *_job)
|
||||
: pgServerObjCollection(factory, _job->GetServer())
|
||||
{
|
||||
job = _job;
|
||||
}
|
||||
|
||||
|
||||
bool pgaJobObjCollection::CanCreate()
|
||||
{
|
||||
return job->CanCreate();
|
||||
}
|
||||
|
||||
|
||||
pgCollection *pgaJobObjFactory::CreateCollection(pgObject *obj)
|
||||
{
|
||||
return new pgaJobObjCollection(GetCollectionFactory(), (pgaJob *)obj);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
#include "images/job.pngc"
|
||||
#include "images/jobs.pngc"
|
||||
#include "images/jobdisabled.pngc"
|
||||
|
||||
pgaJobFactory::pgaJobFactory()
|
||||
: pgServerObjFactory(__("pgAgent Job"), __("New Job"), __("Create a new Job."), job_png_img)
|
||||
{
|
||||
metaType = PGM_JOB;
|
||||
disabledId = addIcon(jobdisabled_png_img);
|
||||
}
|
||||
|
||||
|
||||
pgCollection *pgaJobFactory::CreateCollection(pgObject *obj)
|
||||
{
|
||||
return new pgaJobCollection(GetCollectionFactory(), (pgServer *)obj);
|
||||
}
|
||||
|
||||
|
||||
pgaJobFactory jobFactory;
|
||||
static pgaCollectionFactory cf(&jobFactory, __("Jobs"), jobs_png_img);
|
||||
|
||||
runNowFactory::runNowFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
|
||||
{
|
||||
mnu->Append(id, _("&Run now"), _("Reschedule the job to run now."));
|
||||
}
|
||||
|
||||
|
||||
wxWindow *runNowFactory::StartDialog(frmMain *form, pgObject *obj)
|
||||
{
|
||||
if (!((pgaJob *)(obj))->RunNow())
|
||||
{
|
||||
wxLogError(_("Failed to reschedule the job."));
|
||||
}
|
||||
|
||||
form->Refresh(obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool runNowFactory::CheckEnable(pgObject *obj)
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
if (obj->GetMetaType() == PGM_JOB && !obj->IsCollection())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
576
agent/pgaSchedule.cpp
Normal file
576
agent/pgaSchedule.cpp
Normal file
|
|
@ -0,0 +1,576 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin III - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// pgaSchedule.cpp - PostgreSQL Agent Schedule
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
|
||||
// wxWindows headers
|
||||
#include <wx/wx.h>
|
||||
#include <wx/arrimpl.cpp>
|
||||
|
||||
// App headers
|
||||
#include "utils/misc.h"
|
||||
#include "schema/pgObject.h"
|
||||
#include "schema/pgDatabase.h"
|
||||
#include "schema/pgCollection.h"
|
||||
#include "agent/pgaSchedule.h"
|
||||
#include "agent/pgaStep.h"
|
||||
#include "agent/pgaSchedule.h"
|
||||
|
||||
|
||||
pgaSchedule::pgaSchedule(pgCollection *_collection, const wxString &newName)
|
||||
: pgaJobObject(_collection->GetJob(), scheduleFactory, newName)
|
||||
{
|
||||
}
|
||||
|
||||
wxString pgaSchedule::GetTranslatedMessage(int kindOfMessage) const
|
||||
{
|
||||
wxString message = wxEmptyString;
|
||||
|
||||
switch (kindOfMessage)
|
||||
{
|
||||
case RETRIEVINGDETAILS:
|
||||
message = _("Retrieving details on pgAgent schedule");
|
||||
break;
|
||||
case REFRESHINGDETAILS:
|
||||
message = _("Refreshing pgAgent schedule");
|
||||
break;
|
||||
case PROPERTIESREPORT:
|
||||
message = _("pgAgent schedule properties report");
|
||||
break;
|
||||
case PROPERTIES:
|
||||
message = _("pgAgent schedule properties");
|
||||
break;
|
||||
case DDLREPORT:
|
||||
message = _("pgAgent schedule DDL report");
|
||||
break;
|
||||
case DEPENDENCIESREPORT:
|
||||
message = _("pgAgent schedule dependencies report");
|
||||
break;
|
||||
case DEPENDENCIES:
|
||||
message = _("pgAgent schedule dependencies");
|
||||
break;
|
||||
case DEPENDENTSREPORT:
|
||||
message = _("pgAgent schedule dependents report");
|
||||
break;
|
||||
case DEPENDENTS:
|
||||
message = _("pgAgent schedule dependents");
|
||||
break;
|
||||
case DROPEXCLUDINGDEPS:
|
||||
message = wxString::Format(_("Are you sure you wish to drop schedule \"%s\"?"),
|
||||
GetFullIdentifier().c_str());
|
||||
break;
|
||||
case DROPTITLE:
|
||||
message = _("Drop schedule?");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE))
|
||||
message += wxT(" - ") + GetName();
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
bool pgaSchedule::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
|
||||
{
|
||||
return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_schedule WHERE jscid=") + NumToStr(GetRecId()));
|
||||
}
|
||||
|
||||
|
||||
void pgaSchedule::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
|
||||
{
|
||||
if (!expandedKids)
|
||||
{
|
||||
expandedKids = true;
|
||||
}
|
||||
|
||||
if (properties)
|
||||
{
|
||||
CreateListColumns(properties);
|
||||
|
||||
properties->AppendItem(_("Name"), GetName());
|
||||
properties->AppendItem(_("ID"), GetRecId());
|
||||
properties->AppendYesNoItem(_("Enabled"), GetEnabled());
|
||||
|
||||
properties->AppendItem(_("Start date"), GetStart());
|
||||
properties->AppendItem(_("End date"), GetEnd());
|
||||
properties->AppendItem(_("Minutes"), GetMinutesString());
|
||||
properties->AppendItem(_("Hours"), GetHoursString());
|
||||
properties->AppendItem(_("Weekdays"), GetWeekdaysString());
|
||||
properties->AppendItem(_("Monthdays"), GetMonthdaysString());
|
||||
properties->AppendItem(_("Months"), GetMonthsString());
|
||||
properties->AppendItem(_("Exceptions"), GetExceptionsString());
|
||||
|
||||
properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
pgObject *pgaSchedule::Refresh(ctlTree *browser, const wxTreeItemId item)
|
||||
{
|
||||
pgObject *schedule = 0;
|
||||
|
||||
pgCollection *coll = browser->GetParentCollection(item);
|
||||
if (coll)
|
||||
schedule = scheduleFactory.CreateObjects(coll, 0, wxT("\n AND jscid=") + NumToStr(GetRecId()));
|
||||
|
||||
return schedule;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pgObject *pgaScheduleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
|
||||
{
|
||||
pgaSchedule *schedule = 0;
|
||||
wxString tmp;
|
||||
|
||||
pgSet *schedules = collection->GetConnection()->ExecuteSet(
|
||||
wxT("SELECT * FROM pgagent.pga_schedule\n")
|
||||
wxT(" WHERE jscjobid=") + NumToStr(collection->GetJob()->GetRecId()) + wxT("\n")
|
||||
+ restriction +
|
||||
wxT(" ORDER BY jscname"));
|
||||
|
||||
if (schedules)
|
||||
{
|
||||
while (!schedules->Eof())
|
||||
{
|
||||
|
||||
schedule = new pgaSchedule(collection, schedules->GetVal(wxT("jscname")));
|
||||
schedule->iSetRecId(schedules->GetLong(wxT("jscid")));
|
||||
schedule->iSetStart(schedules->GetDateTime(wxT("jscstart")));
|
||||
schedule->iSetEnd(schedules->GetDateTime(wxT("jscend")));
|
||||
schedule->iSetEnabled(schedules->GetBool(wxT("jscenabled")));
|
||||
|
||||
tmp = schedules->GetVal(wxT("jscminutes"));
|
||||
tmp.Replace(wxT("{"), wxT(""));
|
||||
tmp.Replace(wxT("}"), wxT(""));
|
||||
tmp.Replace(wxT(","), wxT(""));
|
||||
schedule->iSetMinutes(tmp);
|
||||
|
||||
tmp = schedules->GetVal(wxT("jschours"));
|
||||
tmp.Replace(wxT("{"), wxT(""));
|
||||
tmp.Replace(wxT("}"), wxT(""));
|
||||
tmp.Replace(wxT(","), wxT(""));
|
||||
schedule->iSetHours(tmp);
|
||||
|
||||
tmp = schedules->GetVal(wxT("jscweekdays"));
|
||||
tmp.Replace(wxT("{"), wxT(""));
|
||||
tmp.Replace(wxT("}"), wxT(""));
|
||||
tmp.Replace(wxT(","), wxT(""));
|
||||
schedule->iSetWeekdays(tmp);
|
||||
|
||||
tmp = schedules->GetVal(wxT("jscmonthdays"));
|
||||
tmp.Replace(wxT("{"), wxT(""));
|
||||
tmp.Replace(wxT("}"), wxT(""));
|
||||
tmp.Replace(wxT(","), wxT(""));
|
||||
schedule->iSetMonthdays(tmp);
|
||||
|
||||
tmp = schedules->GetVal(wxT("jscmonths"));
|
||||
tmp.Replace(wxT("{"), wxT(""));
|
||||
tmp.Replace(wxT("}"), wxT(""));
|
||||
tmp.Replace(wxT(","), wxT(""));
|
||||
schedule->iSetMonths(tmp);
|
||||
|
||||
schedule->iSetComment(schedules->GetVal(wxT("jscdesc")));
|
||||
|
||||
pgSet *exceptions = collection->GetConnection()->ExecuteSet(
|
||||
wxT("SELECT * FROM pgagent.pga_exception\n")
|
||||
wxT(" WHERE jexscid=") + NumToStr(schedule->GetRecId()) + wxT("\n"));
|
||||
|
||||
tmp.Empty();
|
||||
if (exceptions)
|
||||
{
|
||||
while (!exceptions->Eof())
|
||||
{
|
||||
tmp += exceptions->GetVal(wxT("jexid"));
|
||||
tmp += wxT("|");
|
||||
tmp += exceptions->GetVal(wxT("jexdate"));
|
||||
tmp += wxT("|");
|
||||
tmp += exceptions->GetVal(wxT("jextime"));
|
||||
tmp += wxT("|");
|
||||
|
||||
exceptions->MoveNext();
|
||||
}
|
||||
}
|
||||
schedule->iSetExceptions(tmp);
|
||||
delete exceptions;
|
||||
|
||||
if (browser)
|
||||
{
|
||||
browser->AppendObject(collection, schedule);
|
||||
schedules->MoveNext();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
delete schedules;
|
||||
}
|
||||
return schedule;
|
||||
}
|
||||
|
||||
wxString pgaSchedule::GetMinutesString()
|
||||
{
|
||||
size_t x = 0;
|
||||
bool isWildcard = true;
|
||||
wxString res, tmp;
|
||||
|
||||
for (x = 0; x <= minutes.Length(); x++)
|
||||
{
|
||||
if (minutes[x] == 't')
|
||||
{
|
||||
tmp.Printf(wxT("%.2d, "), (int)x);
|
||||
res += tmp;
|
||||
isWildcard = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isWildcard)
|
||||
{
|
||||
res = _("Every minute");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.Length() > 2)
|
||||
{
|
||||
res.RemoveLast();
|
||||
res.RemoveLast();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
wxString pgaSchedule::GetHoursString()
|
||||
{
|
||||
size_t x = 0;
|
||||
bool isWildcard = true;
|
||||
wxString res, tmp;
|
||||
|
||||
for (x = 0; x <= hours.Length(); x++)
|
||||
{
|
||||
if (hours[x] == 't')
|
||||
{
|
||||
tmp.Printf(wxT("%.2d, "), (int)x);
|
||||
res += tmp;
|
||||
isWildcard = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isWildcard)
|
||||
{
|
||||
res = _("Every hour");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.Length() > 2)
|
||||
{
|
||||
res.RemoveLast();
|
||||
res.RemoveLast();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
wxString pgaSchedule::GetWeekdaysString()
|
||||
{
|
||||
size_t x = 0;
|
||||
bool isWildcard = true;
|
||||
wxString res;
|
||||
|
||||
for (x = 0; x <= weekdays.Length(); x++)
|
||||
{
|
||||
if (weekdays[x] == 't')
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
case 0:
|
||||
res += _("Sunday");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 1:
|
||||
res += _("Monday");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 2:
|
||||
res += _("Tuesday");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 3:
|
||||
res += _("Wednesday");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 4:
|
||||
res += _("Thursday");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 5:
|
||||
res += _("Friday");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 6:
|
||||
res += _("Saturday");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
default:
|
||||
res += _("The mythical 8th day!");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
}
|
||||
isWildcard = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isWildcard)
|
||||
{
|
||||
res = _("Any day of the week");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.Length() > 2)
|
||||
{
|
||||
res.RemoveLast();
|
||||
res.RemoveLast();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
wxString pgaSchedule::GetMonthdaysString()
|
||||
{
|
||||
size_t x = 0;
|
||||
bool isWildcard = true;
|
||||
wxString res, tmp;
|
||||
|
||||
for (x = 0; x <= monthdays.Length(); x++)
|
||||
{
|
||||
if (monthdays[x] == 't')
|
||||
{
|
||||
if (x < 31)
|
||||
{
|
||||
tmp.Printf(wxT("%.2d, "), (int)(x + 1));
|
||||
res += tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
res += _("Last day");
|
||||
res += wxT(", ");
|
||||
}
|
||||
isWildcard = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isWildcard)
|
||||
{
|
||||
res = _("Every day");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.Length() > 2)
|
||||
{
|
||||
res.RemoveLast();
|
||||
res.RemoveLast();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
wxString pgaSchedule::GetMonthsString()
|
||||
{
|
||||
size_t x = 0;
|
||||
bool isWildcard = true;
|
||||
wxString res;
|
||||
|
||||
for (x = 0; x <= months.Length(); x++)
|
||||
{
|
||||
if (months[x] == 't')
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
case 0:
|
||||
res += _("January");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 1:
|
||||
res += _("February");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 2:
|
||||
res += _("March");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 3:
|
||||
res += _("April");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 4:
|
||||
res += _("May");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 5:
|
||||
res += _("June");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 6:
|
||||
res += _("July");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 7:
|
||||
res += _("August");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 8:
|
||||
res += _("September");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 9:
|
||||
res += _("October");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 10:
|
||||
res += _("November");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
case 11:
|
||||
res += _("December");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
default:
|
||||
res += _("The mythical 13th month!");
|
||||
res += wxT(", ");
|
||||
break;
|
||||
}
|
||||
isWildcard = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isWildcard)
|
||||
{
|
||||
res = _("Every month");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.Length() > 2)
|
||||
{
|
||||
res.RemoveLast();
|
||||
res.RemoveLast();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
wxString pgaSchedule::GetExceptionsString()
|
||||
{
|
||||
wxString tmp, token, dateToken, timeToken;
|
||||
wxDateTime val;
|
||||
wxStringTokenizer tkz(exceptions, wxT("|"));
|
||||
|
||||
while (tkz.HasMoreTokens() )
|
||||
{
|
||||
|
||||
dateToken.Empty();
|
||||
timeToken.Empty();
|
||||
|
||||
// First is the ID which can be ignored
|
||||
token = tkz.GetNextToken();
|
||||
|
||||
// Look for a date
|
||||
if (tkz.HasMoreTokens())
|
||||
dateToken = tkz.GetNextToken();
|
||||
|
||||
// Look for a time
|
||||
if (tkz.HasMoreTokens())
|
||||
timeToken = tkz.GetNextToken();
|
||||
|
||||
if (tmp.IsEmpty())
|
||||
tmp += wxT("[");
|
||||
else
|
||||
tmp += wxT(", [");
|
||||
|
||||
if (!dateToken.IsEmpty() && !timeToken.IsEmpty())
|
||||
{
|
||||
val.ParseDate(dateToken);
|
||||
val.ParseTime(timeToken);
|
||||
tmp += val.Format();
|
||||
}
|
||||
else if (!dateToken.IsEmpty() && timeToken.IsEmpty())
|
||||
{
|
||||
val.ParseDate(dateToken);
|
||||
tmp += val.FormatDate();
|
||||
}
|
||||
else if (dateToken.IsEmpty() && !timeToken.IsEmpty())
|
||||
{
|
||||
val.ParseTime(timeToken);
|
||||
tmp += val.FormatTime();
|
||||
}
|
||||
|
||||
tmp += wxT("]");
|
||||
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
pgaScheduleCollection::pgaScheduleCollection(pgaFactory *factory, pgaJob *job)
|
||||
: pgaJobObjCollection(factory, job)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
wxString pgaScheduleCollection::GetTranslatedMessage(int kindOfMessage) const
|
||||
{
|
||||
wxString message = wxEmptyString;
|
||||
|
||||
switch (kindOfMessage)
|
||||
{
|
||||
case RETRIEVINGDETAILS:
|
||||
message = _("Retrieving details on pgAgent schedules");
|
||||
break;
|
||||
case REFRESHINGDETAILS:
|
||||
message = _("Refreshing pgAgent schedules");
|
||||
break;
|
||||
case OBJECTSLISTREPORT:
|
||||
message = _("pgAgent schedules list report");
|
||||
break;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
#include "images/schedule.pngc"
|
||||
#include "images/schedules.pngc"
|
||||
|
||||
pgaScheduleFactory::pgaScheduleFactory()
|
||||
: pgaJobObjFactory(__("Schedule"), __("New Schedule"), __("Create a new Schedule."), schedule_png_img)
|
||||
{
|
||||
metaType = PGM_SCHEDULE;
|
||||
}
|
||||
|
||||
|
||||
pgCollection *pgaScheduleFactory::CreateCollection(pgObject *obj)
|
||||
{
|
||||
return new pgaScheduleCollection(GetCollectionFactory(), (pgaJob *)obj);
|
||||
}
|
||||
|
||||
|
||||
pgaScheduleFactory scheduleFactory;
|
||||
static pgaCollectionFactory cf(&scheduleFactory, __("Schedules"), schedules_png_img);
|
||||
327
agent/pgaStep.cpp
Normal file
327
agent/pgaStep.cpp
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin III - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// pgaStep.cpp - PostgreSQL Agent Step
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// wxWindows headers
|
||||
#include <wx/wx.h>
|
||||
|
||||
// App headers
|
||||
#include "pgAdmin3.h"
|
||||
#include "utils/misc.h"
|
||||
#include "schema/pgObject.h"
|
||||
#include "schema/pgDatabase.h"
|
||||
#include "schema/pgCollection.h"
|
||||
#include "agent/pgaStep.h"
|
||||
#include "agent/pgaSchedule.h"
|
||||
|
||||
pgaStep::pgaStep(pgCollection *_collection, const wxString &newName)
|
||||
: pgaJobObject(_collection->GetJob(), stepFactory, newName)
|
||||
{
|
||||
}
|
||||
|
||||
wxString pgaStep::GetTranslatedMessage(int kindOfMessage) const
|
||||
{
|
||||
wxString message = wxEmptyString;
|
||||
|
||||
switch (kindOfMessage)
|
||||
{
|
||||
case RETRIEVINGDETAILS:
|
||||
message = _("Retrieving details on pgAgent step");
|
||||
break;
|
||||
case REFRESHINGDETAILS:
|
||||
message = _("Refreshing pgAgent step");
|
||||
break;
|
||||
case PROPERTIESREPORT:
|
||||
message = _("pgAgent step properties report");
|
||||
break;
|
||||
case PROPERTIES:
|
||||
message = _("pgAgent step properties");
|
||||
break;
|
||||
case DDLREPORT:
|
||||
message = _("pgAgent step DDL report");
|
||||
break;
|
||||
case DEPENDENCIESREPORT:
|
||||
message = _("pgAgent step dependencies report");
|
||||
break;
|
||||
case DEPENDENCIES:
|
||||
message = _("pgAgent step dependencies");
|
||||
break;
|
||||
case DEPENDENTSREPORT:
|
||||
message = _("pgAgent step dependents report");
|
||||
break;
|
||||
case DEPENDENTS:
|
||||
message = _("pgAgent step dependents");
|
||||
break;
|
||||
case DROPEXCLUDINGDEPS:
|
||||
message = wxString::Format(_("Are you sure you wish to drop step \"%s\"?"),
|
||||
GetFullIdentifier().c_str());
|
||||
break;
|
||||
case DROPTITLE:
|
||||
message = _("Drop step?");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE))
|
||||
message += wxT(" - ") + GetName();
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
bool pgaStep::IsUpToDate()
|
||||
{
|
||||
wxString sql = wxT("SELECT xmin FROM pgagent.pga_jobstep WHERE jstid = ") + NumToStr(GetRecId());
|
||||
if (!GetConnection() || GetConnection()->ExecuteScalar(sql) != NumToStr(GetXid()))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pgaStep::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
|
||||
{
|
||||
return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_jobstep WHERE jstid=") + NumToStr(GetRecId()));
|
||||
}
|
||||
|
||||
|
||||
void pgaStep::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
|
||||
{
|
||||
if (!expandedKids)
|
||||
{
|
||||
expandedKids = true;
|
||||
}
|
||||
|
||||
if (properties)
|
||||
{
|
||||
CreateListColumns(properties);
|
||||
|
||||
properties->AppendItem(_("Name"), GetName());
|
||||
properties->AppendItem(_("ID"), GetRecId());
|
||||
properties->AppendYesNoItem(_("Enabled"), GetEnabled());
|
||||
properties->AppendItem(_("Kind"), GetKind());
|
||||
if (GetConnStr().IsEmpty())
|
||||
properties->AppendItem(_("Database"), GetDbname());
|
||||
else
|
||||
properties->AppendItem(_("Connection String"), GetConnStr());
|
||||
properties->AppendItem(_("Code"), GetCode());
|
||||
properties->AppendItem(_("On error"), GetOnError());
|
||||
|
||||
properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
pgObject *pgaStep::Refresh(ctlTree *browser, const wxTreeItemId item)
|
||||
{
|
||||
pgObject *step = 0;
|
||||
|
||||
pgCollection *coll = browser->GetParentCollection(item);
|
||||
if (coll)
|
||||
step = stepFactory.CreateObjects(coll, 0, wxT("\n AND jstid=") + NumToStr(GetRecId()));
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pgObject *pgaStepFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
|
||||
{
|
||||
pgaStep *step = 0;
|
||||
|
||||
pgSet *steps = collection->GetConnection()->ExecuteSet(
|
||||
wxT("SELECT xmin, * FROM pgagent.pga_jobstep\n")
|
||||
wxT(" WHERE jstjobid=") + NumToStr(collection->GetJob()->GetRecId()) + wxT("\n")
|
||||
+ restriction +
|
||||
wxT(" ORDER BY jstname"));
|
||||
|
||||
if (steps)
|
||||
{
|
||||
while (!steps->Eof())
|
||||
{
|
||||
|
||||
step = new pgaStep(collection, steps->GetVal(wxT("jstname")));
|
||||
step->iSetRecId(steps->GetLong(wxT("jstid")));
|
||||
step->iSetXid(steps->GetOid(wxT("xmin")));
|
||||
step->iSetDbname(steps->GetVal(wxT("jstdbname")));
|
||||
if (steps->HasColumn(wxT("jstconnstr")))
|
||||
step->iSetConnStr(steps->GetVal(wxT("jstconnstr")));
|
||||
step->iSetCode(steps->GetVal(wxT("jstcode")));
|
||||
step->iSetEnabled(steps->GetBool(wxT("jstenabled")));
|
||||
|
||||
wxChar kindc = *steps->GetVal(wxT("jstkind")).c_str();
|
||||
wxString kinds;
|
||||
switch (kindc)
|
||||
{
|
||||
case 'b':
|
||||
kinds = _("Batch");
|
||||
break;
|
||||
case 's':
|
||||
kinds = wxT("SQL");
|
||||
break;
|
||||
}
|
||||
step->iSetKindChar(kindc);
|
||||
step->iSetKind(kinds);
|
||||
|
||||
wxChar onerrc = *steps->GetVal(wxT("jstonerror")).c_str();
|
||||
wxString onerrs;
|
||||
switch (onerrc)
|
||||
{
|
||||
case 's':
|
||||
onerrs = _("Succeed");
|
||||
break;
|
||||
case 'f':
|
||||
onerrs = _("Fail");
|
||||
break;
|
||||
case 'i':
|
||||
onerrs = _("Ignore");
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
step->iSetOnErrorChar(onerrc);
|
||||
step->iSetOnError(onerrs);
|
||||
step->iSetComment(steps->GetVal(wxT("jstdesc")));
|
||||
|
||||
|
||||
if (browser)
|
||||
{
|
||||
browser->AppendObject(collection, step);
|
||||
steps->MoveNext();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
delete steps;
|
||||
}
|
||||
return step;
|
||||
}
|
||||
|
||||
|
||||
void pgaStep::ShowStatistics(frmMain *form, ctlListView *statistics)
|
||||
{
|
||||
wxString sql =
|
||||
wxT("SELECT jsljlgid")
|
||||
wxT(", jslstatus")
|
||||
wxT(", jslresult")
|
||||
wxT(", jslstart")
|
||||
wxT(", jslduration")
|
||||
wxT(", (jslstart + jslduration) AS endtime")
|
||||
wxT(", jsloutput")
|
||||
wxT(" FROM pgagent.pga_jobsteplog\n")
|
||||
wxT(" WHERE jsljstid = ") + NumToStr(GetRecId()) +
|
||||
wxT(" ORDER BY jslstart DESC")
|
||||
wxT(" LIMIT ") + NumToStr(settings->GetMaxRows());
|
||||
|
||||
if (statistics)
|
||||
{
|
||||
wxLogInfo(wxT("Displaying statistics for job %s"), GetFullIdentifier().c_str());
|
||||
|
||||
// Add the statistics view columns
|
||||
statistics->ClearAll();
|
||||
statistics->AddColumn(_("Run"), 50);
|
||||
statistics->AddColumn(_("Status"), 60);
|
||||
statistics->AddColumn(_("Result"), 60);
|
||||
statistics->AddColumn(_("Start time"), 95);
|
||||
statistics->AddColumn(_("End time"), 95);
|
||||
statistics->AddColumn(_("Duration"), 70);
|
||||
statistics->AddColumn(_("Output"), 200);
|
||||
|
||||
pgSet *stats = GetConnection()->ExecuteSet(sql);
|
||||
wxString status;
|
||||
wxDateTime startTime;
|
||||
wxDateTime endTime;
|
||||
|
||||
if (stats)
|
||||
{
|
||||
while (!stats->Eof())
|
||||
{
|
||||
if (stats->GetVal(1) == wxT("r"))
|
||||
status = _("Running");
|
||||
else if (stats->GetVal(1) == wxT("s"))
|
||||
status = _("Successful");
|
||||
else if (stats->GetVal(1) == wxT("f"))
|
||||
status = _("Failed");
|
||||
else if (stats->GetVal(1) == wxT("i"))
|
||||
status = _("Ignored");
|
||||
else if (stats->GetVal(1) == wxT("d"))
|
||||
status = _("Aborted");
|
||||
else
|
||||
status = _("Unknown");
|
||||
|
||||
startTime.ParseDateTime(stats->GetVal(3));
|
||||
endTime.ParseDateTime(stats->GetVal(5));
|
||||
|
||||
long pos = statistics->AppendItem(stats->GetVal(0), status, stats->GetVal(2));
|
||||
statistics->SetItem(pos, 3, startTime.Format());
|
||||
if (stats->GetVal(5).Length() > 0)
|
||||
statistics->SetItem(pos, 4, endTime.Format());
|
||||
statistics->SetItem(pos, 5, stats->GetVal(4));
|
||||
statistics->SetItem(pos, 6, stats->GetVal(6));
|
||||
|
||||
stats->MoveNext();
|
||||
}
|
||||
delete stats;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
pgaStepCollection::pgaStepCollection(pgaFactory *factory, pgaJob *job)
|
||||
: pgaJobObjCollection(factory, job)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
wxString pgaStepCollection::GetTranslatedMessage(int kindOfMessage) const
|
||||
{
|
||||
wxString message = wxEmptyString;
|
||||
|
||||
switch (kindOfMessage)
|
||||
{
|
||||
case RETRIEVINGDETAILS:
|
||||
message = _("Retrieving details on pgAgent steps");
|
||||
break;
|
||||
case REFRESHINGDETAILS:
|
||||
message = _("Refreshing pgAgent steps");
|
||||
break;
|
||||
case OBJECTSLISTREPORT:
|
||||
message = _("pgAgent steps list report");
|
||||
break;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
#include "images/step.pngc"
|
||||
#include "images/steps.pngc"
|
||||
|
||||
pgaStepFactory::pgaStepFactory()
|
||||
: pgaJobObjFactory(__("Step"), __("New Step"), __("Create a new Step."), step_png_img)
|
||||
{
|
||||
metaType = PGM_STEP;
|
||||
}
|
||||
|
||||
|
||||
pgCollection *pgaStepFactory::CreateCollection(pgObject *obj)
|
||||
{
|
||||
return new pgaStepCollection(GetCollectionFactory(), (pgaJob *)obj);
|
||||
}
|
||||
|
||||
|
||||
pgaStepFactory stepFactory;
|
||||
static pgaCollectionFactory cf(&stepFactory, __("Steps"), steps_png_img);
|
||||
Loading…
Add table
Add a link
Reference in a new issue