pgadmin3/agent/dlgJob.cpp
levinsv 4af765213c support PG11
Поддержка PostgreSQL 11 только для Windows
2018-10-10 22:59:25 +05:00

513 lines
14 KiB
C++

//////////////////////////////////////////////////////////////////////////
//
// 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;
}