diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py b/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py index 797a6cb..ee87a1a 100644 --- a/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py @@ -10,6 +10,7 @@ """Implements the pgAgent Jobs Node""" from functools import wraps import json +from datetime import datetime, time from flask import render_template, request, jsonify from flask_babelex import gettext as _ @@ -323,7 +324,8 @@ SELECT EXISTS( row['jobid'], sid, row['jobname'], - icon="icon-pga_job" + icon="icon-pga_job" if row['jobenabled'] + else "icon-pga_job-disabled" ) ) @@ -500,6 +502,10 @@ SELECT EXISTS( if schedule['jexid']: idx = 0 for exc in schedule['jexid']: + # Convert datetime.time object to string + if isinstance(schedule['jextime'][idx], time): + schedule['jextime'][idx] = \ + schedule['jextime'][idx].strftime("%H:%M:%S") schedule['jscexceptions'].append({ 'jexid': exc, 'jexdate': schedule['jexdate'][idx], diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/schedules/__init__.py b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/__init__.py index ad3e7e9..13bd25a 100644 --- a/web/pgadmin/browser/server_groups/servers/pgagent/schedules/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/__init__.py @@ -74,6 +74,23 @@ class JobScheduleModule(CollectionNodeModule): return 'pga_job' @property + def csssnippets(self): + """ + Returns a snippet of css to include in the page + """ + snippets = [ + render_template( + "pga_schedule/css/pga_schedule.css", + node_type=self.node_type + ) + ] + + for submodule in self.submodules: + snippets.extend(submodule.csssnippets) + + return snippets + + @property def module_use_template_javascript(self): """ Returns whether Jinja2 template is used for generating the javascript @@ -245,7 +262,8 @@ class JobScheduleView(PGChildNodeView): row['jscid'], row['jscjobid'], row['jscname'], - icon="icon-pga_schedule", + icon="icon-pga_schedule" if row['jscenabled'] else + "icon-pga_schedule-disabled", enabled=row['jscenabled'] ) ) @@ -256,7 +274,8 @@ class JobScheduleView(PGChildNodeView): row['jscid'], row['jscjobid'], row['jscname'], - icon="icon-pga_schedule", + icon="icon-pga_schedule" if row['jscenabled'] else + "icon-pga_schedule-disabled", enabled=row['jscenabled'] ) ) @@ -359,7 +378,8 @@ class JobScheduleView(PGChildNodeView): row['jscid'], row['jscjobid'], row['jscname'], - icon="icon-pga_schedule", + icon="icon-pga_schedule" if row['jscenabled'] else + "icon-pga_schedule-disabled", enabled=row['jscenabled'] ) ) @@ -422,7 +442,8 @@ class JobScheduleView(PGChildNodeView): jscid, jid, row['jscname'], - icon="icon-pga_schedule", + icon="icon-pga_schedule" if row['jscenabled'] else + "icon-pga_schedule-disabled", enabled=row['jscenabled'] ) ) diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/schedules/static/img/pga_schedule-disabled.svg b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/static/img/pga_schedule-disabled.svg new file mode 100644 index 0000000..8c61a0e --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/static/img/pga_schedule-disabled.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/schedules/static/js/pga_schedule.js b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/static/js/pga_schedule.js index 75413d9..44d3d45 100644 --- a/web/pgadmin/browser/server_groups/servers/pgagent/schedules/static/js/pga_schedule.js +++ b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/static/js/pga_schedule.js @@ -366,13 +366,6 @@ define('pgadmin.node.pga_schedule', [ var res = Backform.FieldsetControl.prototype.render.apply( this, arguments ); - - // $( - // '
' + - // gettext('Schedules are specified using a cron-style format.
') + - // '
' - // ).insertBefore(this.$el); - return res; }, }), @@ -498,7 +491,8 @@ define('pgadmin.node.pga_schedule', [ if (_.isUndefined(val) || _.isNull(val) || String(val).replace(/^\s+|\s+$/g, '') == '') { if (val == '') { - this.set('jscend', undefined); + /* Set the default value used in model initialization */ + this.set('jscend', null); } return; } diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/schedules/templates/pga_schedule/css/pga_schedule.css b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/templates/pga_schedule/css/pga_schedule.css index 5910c5e..c3efe35 100644 --- a/web/pgadmin/browser/server_groups/servers/pgagent/schedules/templates/pga_schedule/css/pga_schedule.css +++ b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/templates/pga_schedule/css/pga_schedule.css @@ -6,3 +6,21 @@ vertical-align: middle; height: 1.3em; } + +.icon-pga_schedule-disabled { + background-image: url('{{ url_for('NODE-pga_schedule.static', filename='img/pga_schedule-disabled.svg') }}') !important; + background-repeat: no-repeat; + background-size: 20px !important; + align-content: center; + vertical-align: middle; + height: 1.3em; +} + +.icon-coll-pga_schedule { + background-image: url('{{ url_for('NODE-pga_schedule.static', filename='img/coll-pga_schedule.svg') }}') !important; + background-repeat: no-repeat; + background-size: 20px !important; + align-content: center; + vertical-align: middle; + height: 1.3em; +} diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/steps/__init__.py b/web/pgadmin/browser/server_groups/servers/pgagent/steps/__init__.py index aa4f7f4..320e621 100644 --- a/web/pgadmin/browser/server_groups/servers/pgagent/steps/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/pgagent/steps/__init__.py @@ -274,7 +274,8 @@ SELECT EXISTS( row['jstid'], row['jstjobid'], row['jstname'], - icon="icon-pga_jobstep", + icon="icon-pga_jobstep" if row['jstenabled'] else + "icon-pga_jobstep-disabled", enabled=row['jstenabled'], kind=row['jstkind'] ) @@ -286,7 +287,8 @@ SELECT EXISTS( row['jstid'], row['jstjobid'], row['jstname'], - icon="icon-pga_jobstep", + icon="icon-pga_jobstep" if row['jstenabled'] else + "icon-pga_jobstep-disabled", enabled=row['jstenabled'], kind=row['jstkind'] ) @@ -383,7 +385,8 @@ SELECT EXISTS( row['jstid'], row['jstjobid'], row['jstname'], - icon="icon-pga_jobstep" + icon="icon-pga_jobstep" if row['jstenabled'] + else "icon-pga_jobstep-disabled" ) ) @@ -469,7 +472,8 @@ SELECT EXISTS( jstid, jid, row['jstname'], - icon="icon-pga_jobstep" + icon="icon-pga_jobstep" if row['jstenabled'] + else "icon-pga_jobstep-disabled" ) ) diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/steps/static/img/coll-pga_jobstep.svg b/web/pgadmin/browser/server_groups/servers/pgagent/steps/static/img/coll-pga_jobstep.svg index e38354d..d347471 100644 --- a/web/pgadmin/browser/server_groups/servers/pgagent/steps/static/img/coll-pga_jobstep.svg +++ b/web/pgadmin/browser/server_groups/servers/pgagent/steps/static/img/coll-pga_jobstep.svg @@ -1 +1,45 @@ -coll-pga_jobstep \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/steps/static/img/pga_jobstep-disabled.svg b/web/pgadmin/browser/server_groups/servers/pgagent/steps/static/img/pga_jobstep-disabled.svg new file mode 100644 index 0000000..3ea6379 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/steps/static/img/pga_jobstep-disabled.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/steps/templates/pga_jobstep/css/pga_step.css b/web/pgadmin/browser/server_groups/servers/pgagent/steps/templates/pga_jobstep/css/pga_step.css index f7a4263..417085c 100644 --- a/web/pgadmin/browser/server_groups/servers/pgagent/steps/templates/pga_jobstep/css/pga_step.css +++ b/web/pgadmin/browser/server_groups/servers/pgagent/steps/templates/pga_jobstep/css/pga_step.css @@ -7,6 +7,15 @@ height: 1.3em; } +.icon-pga_jobstep-disabled { + background-image: url('{{ url_for('NODE-pga_jobstep.static', filename='img/pga_jobstep-disabled.svg') }}') !important; + background-repeat: no-repeat; + background-size: 20px !important; + align-content: center; + vertical-align: middle; + height: 1.3em; +} + .icon-coll-pga_jobstep { background-image: url('{{ url_for('NODE-pga_jobstep.static', filename='img/coll-pga_jobstep.svg') }}') !important; background-repeat: no-repeat; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_schedule_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_schedule_all_options.sql new file mode 100644 index 0000000..7c2665c --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_schedule_all_options.sql @@ -0,0 +1,54 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_batch_job_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 'b'::character(1), + ''::text, ''::name, 'i'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ;-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_2'::text, false , 'b'::character(1), + ''::text, ''::name, 's'::character(1), + 'SELECT 10;'::text, 'job step_2 description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_2'::text, 'test schedule_2 comment'::text, true, + ''::timestamp with time zone, ''::timestamp with time zone, + -- Minutes + ARRAY[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Week days + ARRAY[true,true,false,false,false,false,false]::boolean[], + -- Month days + ARRAY[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[true,true,false,false,false,false,false,false,false,false,false,false]::boolean[] +) RETURNING jscid INTO scid; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_schedule_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_schedule_all_options_msql.sql new file mode 100644 index 0000000..b4a4e7d --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_schedule_all_options_msql.sql @@ -0,0 +1,25 @@ + + +DO $$ +DECLARE + scid integer; +BEGIN +-- Inserting a schedule (jobid: ) +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + , 'schedule_2'::text, 'test schedule_2 comment'::text, true, + '2020-04-15 05:11:31 -07:00'::timestamp with time zone, '2020-04-16 05:11:34 -07:00'::timestamp with time zone, + -- Minutes + ARRAY[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Week days + ARRAY[true,true,false,false,false,false,false]::boolean[], + -- Month days + ARRAY[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[true,true,false,false,false,false,false,false,false,false,false,false]::boolean[] +) RETURNING jscid INTO scid;END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_step_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_step_all_options.sql new file mode 100644 index 0000000..e186d7b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_step_all_options.sql @@ -0,0 +1,33 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_batch_job_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 'b'::character(1), + ''::text, ''::name, 'i'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ;-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_2'::text, false , 'b'::character(1), + ''::text, ''::name, 's'::character(1), + 'SELECT 10;'::text, 'job step_2 description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_step_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_step_all_options_msql.sql new file mode 100644 index 0000000..025ad22 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_batch_job_step_all_options_msql.sql @@ -0,0 +1,11 @@ + +-- Inserting a step (jobid: ) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + , 'step_2'::text, false , 'b'::character(1), + ''::text, ''::name, 's'::character(1), + 'SELECT 10;'::text, 'job step_2 description'::text +) RETURNING jstid; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_all_options.sql new file mode 100644 index 0000000..791e3a7 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_all_options.sql @@ -0,0 +1,66 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 4::integer, 'test_sql_job_local_db_updated_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description updated'::text, 'test_host_updated'::text, false +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 'f'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ;-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_2_added'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 's'::character(1), + 'SELECT 3;'::text, 'job step 2 description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_2'::text, 'test schedule_2 comment'::text, false, + ''::timestamp with time zone, ''::timestamp with time zone, + -- Minutes + ARRAY[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false]::boolean[], + -- Week days + ARRAY[false,false,true,true,true,true,true]::boolean[], + -- Month days + ARRAY[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[false,false,true,true,true,true,true,true,true,true,true,true]::boolean[] +) RETURNING jscid INTO scid; +-- Inserting a schedule exception +INSERT INTO pgagent.pga_exception ( + jexscid, jexdate, jextime +) VALUES ( + scid, to_date('2020-04-22', 'YYYY-MM-DD')::date, '01:22:00'::time without time zone +); +-- Inserting a schedule exception +INSERT INTO pgagent.pga_exception ( + jexscid, jexdate, jextime +) VALUES ( + scid, to_date('2020-04-23', 'YYYY-MM-DD')::date, '01:23:00'::time without time zone +); +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_all_options_msql.sql new file mode 100644 index 0000000..ff79833 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_all_options_msql.sql @@ -0,0 +1,37 @@ + + +DO $$ +DECLARE + scid integer; +BEGIN +-- Inserting a schedule (jobid: ) +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + , 'schedule_2'::text, 'test schedule_2 comment'::text, false, + '2020-04-14 05:11:31 -07:00'::timestamp with time zone, '2020-04-15 05:11:34 -07:00'::timestamp with time zone, + -- Minutes + ARRAY[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false]::boolean[], + -- Week days + ARRAY[false,false,true,true,true,true,true]::boolean[], + -- Month days + ARRAY[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[false,false,true,true,true,true,true,true,true,true,true,true]::boolean[] +) RETURNING jscid INTO scid; +-- Inserting a schedule exception +INSERT INTO pgagent.pga_exception ( + jexscid, jexdate, jextime +) VALUES ( + scid, to_date('2020-04-22', 'YYYY-MM-DD')::date, '01:22:00'::time without time zone +); +-- Inserting a schedule exception +INSERT INTO pgagent.pga_exception ( + jexscid, jexdate, jextime +) VALUES ( + scid, to_date('2020-04-23', 'YYYY-MM-DD')::date, '01:23:00'::time without time zone +);END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_remote_db_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_remote_db_all_options.sql new file mode 100644 index 0000000..ac3730a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_remote_db_all_options.sql @@ -0,0 +1,54 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_remote_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + 'host=localhost port=5432 dbname=postgres connect_timeout=10'::text, ''::name, 's'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ;-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_2'::text, false , 's'::character(1), + 'host=localhost port=5434 dbname=postgres connect_timeout=20'::text, ''::name, 'f'::character(1), + 'SELECT 5;'::text, 'job step_2 description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_2'::text, 'test schedule_2 comment'::text, true, + ''::timestamp with time zone, ''::timestamp with time zone, + -- Minutes + ARRAY[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Week days + ARRAY[false,false,false,false,false,false,false]::boolean[], + -- Month days + ARRAY[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[false,false,false,false,false,false,false,false,false,false,false,false]::boolean[] +) RETURNING jscid INTO scid; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_remote_db_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_remote_db_all_options_msql.sql new file mode 100644 index 0000000..458450c --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_schedule_remote_db_all_options_msql.sql @@ -0,0 +1,25 @@ + + +DO $$ +DECLARE + scid integer; +BEGIN +-- Inserting a schedule (jobid: ) +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + , 'schedule_2'::text, 'test schedule_2 comment'::text, true, + '2020-04-15 05:11:31 -07:00'::timestamp with time zone, '2020-04-16 05:11:34 -07:00'::timestamp with time zone, + -- Minutes + ARRAY[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Week days + ARRAY[false,false,false,false,false,false,false]::boolean[], + -- Month days + ARRAY[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[false,false,false,false,false,false,false,false,false,false,false,false]::boolean[] +) RETURNING jscid INTO scid;END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_all_options.sql new file mode 100644 index 0000000..df33c8f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_all_options.sql @@ -0,0 +1,33 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 4::integer, 'test_sql_job_local_db_updated_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description updated'::text, 'test_host_updated'::text, false +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 'f'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ;-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_2_added'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 's'::character(1), + 'SELECT 3;'::text, 'job step 2 description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_all_options_msql.sql new file mode 100644 index 0000000..ebcb256 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_all_options_msql.sql @@ -0,0 +1,11 @@ + +-- Inserting a step (jobid: ) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + , 'step_2_added'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 's'::character(1), + 'SELECT 3;'::text, 'job step 2 description'::text +) RETURNING jstid; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_remote_db_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_remote_db_all_options.sql new file mode 100644 index 0000000..3c1b24b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_remote_db_all_options.sql @@ -0,0 +1,33 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_remote_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + 'host=localhost port=5432 dbname=postgres connect_timeout=10'::text, ''::name, 's'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ;-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_2'::text, false , 's'::character(1), + 'host=localhost port=5434 dbname=postgres connect_timeout=20'::text, ''::name, 'f'::character(1), + 'SELECT 5;'::text, 'job step_2 description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_remote_db_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_remote_db_all_options_msql.sql new file mode 100644 index 0000000..2fc1052 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_job_step_remote_db_all_options_msql.sql @@ -0,0 +1,11 @@ + +-- Inserting a step (jobid: ) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + , 'step_2'::text, false , 's'::character(1), + 'host=localhost port=5434 dbname=postgres connect_timeout=20'::text, ''::name, 'f'::character(1), + 'SELECT 5;'::text, 'job step_2 description'::text +) RETURNING jstid; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_sql_job_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_sql_job_all_options.sql new file mode 100644 index 0000000..7a941f2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_sql_job_all_options.sql @@ -0,0 +1,24 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 4::integer, 'test_sql_job_local_db_updated_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description updated'::text, 'test_host_updated'::text, false +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 'f'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_sql_job_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_sql_job_all_options_msql.sql new file mode 100644 index 0000000..f28a529 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/alter_sql_job_all_options_msql.sql @@ -0,0 +1,3 @@ +UPDATE pgagent.pga_job +SET jobjclid=4::integer, jobname='test_sql_job_local_db_updated_$%{}[]()&*^!@""''`\/#'::text, jobdesc='test_job_step_schedule description updated'::text, jobhostagent='test_host_updated'::text, jobenabled=false +WHERE jobid = ; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_all_options.sql new file mode 100644 index 0000000..e901cca --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_all_options.sql @@ -0,0 +1,45 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_batch_job_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 'b'::character(1), + ''::text, ''::name, 'i'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_1'::text, 'test schedule comment'::text, true, + ''::timestamp with time zone, ''::timestamp with time zone, + -- Minutes + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false]::boolean[], + -- Week days + ARRAY[true,true,true,true,true,true,true]::boolean[], + -- Month days + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true]::boolean[] +) RETURNING jscid INTO scid; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_all_options_msql.sql new file mode 100644 index 0000000..4f9815a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_all_options_msql.sql @@ -0,0 +1,45 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_batch_job_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 'b'::character(1), + ''::text, ''::name, 'i'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_1'::text, 'test schedule comment'::text, true, + '2020-04-14 01:11:31 -07:00'::timestamp with time zone, '2020-04-15 01:11:34 -07:00'::timestamp with time zone, + -- Minutes + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false]::boolean[], + -- Week days + ARRAY[true,true,true,true,true,true,true]::boolean[], + -- Month days + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true]::boolean[] +) RETURNING jscid INTO scid; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_step.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_step.sql new file mode 100644 index 0000000..454c933 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_step.sql @@ -0,0 +1,24 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_batch_job_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 'b'::character(1), + ''::text, ''::name, 'i'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_step_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_step_msql.sql new file mode 100644 index 0000000..454c933 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_batch_job_with_step_msql.sql @@ -0,0 +1,24 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_batch_job_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 'b'::character(1), + ''::text, ''::name, 'i'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_local_db_with_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_local_db_with_all_options.sql new file mode 100644 index 0000000..1a8af3f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_local_db_with_all_options.sql @@ -0,0 +1,57 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_local_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 'f'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_1'::text, 'test schedule comment'::text, true, + ''::timestamp with time zone, ''::timestamp with time zone, + -- Minutes + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false]::boolean[], + -- Week days + ARRAY[true,true,true,true,true,true,true]::boolean[], + -- Month days + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true]::boolean[] +) RETURNING jscid INTO scid; +-- Inserting a schedule exception +INSERT INTO pgagent.pga_exception ( + jexscid, jexdate, jextime +) VALUES ( + scid, to_date('2020-04-18', 'YYYY-MM-DD')::date, '01:18:00'::time without time zone +); +-- Inserting a schedule exception +INSERT INTO pgagent.pga_exception ( + jexscid, jexdate, jextime +) VALUES ( + scid, to_date('2020-04-19', 'YYYY-MM-DD')::date, '01:19:00'::time without time zone +); +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_local_db_with_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_local_db_with_all_options_msql.sql new file mode 100644 index 0000000..7fa7600 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_local_db_with_all_options_msql.sql @@ -0,0 +1,57 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_local_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 'f'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_1'::text, 'test schedule comment'::text, true, + '2020-04-14 01:11:31 -07:00'::timestamp with time zone, '2020-04-15 01:11:34 -07:00'::timestamp with time zone, + -- Minutes + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false]::boolean[], + -- Week days + ARRAY[true,true,true,true,true,true,true]::boolean[], + -- Month days + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true]::boolean[] +) RETURNING jscid INTO scid; +-- Inserting a schedule exception +INSERT INTO pgagent.pga_exception ( + jexscid, jexdate, jextime +) VALUES ( + scid, to_date('2020-04-18', 'YYYY-MM-DD')::date, '01:18:00'::time without time zone +); +-- Inserting a schedule exception +INSERT INTO pgagent.pga_exception ( + jexscid, jexdate, jextime +) VALUES ( + scid, to_date('2020-04-19', 'YYYY-MM-DD')::date, '01:19:00'::time without time zone +); +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_remote_db_with_all_options.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_remote_db_with_all_options.sql new file mode 100644 index 0000000..2dba473 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_remote_db_with_all_options.sql @@ -0,0 +1,45 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_remote_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + 'host=localhost port=5432 dbname=postgres connect_timeout=10'::text, ''::name, 's'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_1'::text, 'test schedule comment'::text, true, + ''::timestamp with time zone, ''::timestamp with time zone, + -- Minutes + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false]::boolean[], + -- Week days + ARRAY[true,true,true,true,true,true,true]::boolean[], + -- Month days + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true]::boolean[] +) RETURNING jscid INTO scid; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_remote_db_with_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_remote_db_with_all_options_msql.sql new file mode 100644 index 0000000..e8e6a71 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_remote_db_with_all_options_msql.sql @@ -0,0 +1,45 @@ +DO $$ +DECLARE + jid integer; + scid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_remote_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + 'host=localhost port=5432 dbname=postgres connect_timeout=10'::text, ''::name, 's'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; + +-- Schedules +-- Inserting a schedule +INSERT INTO pgagent.pga_schedule( + jscjobid, jscname, jscdesc, jscenabled, + jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths +) VALUES ( + jid, 'schedule_1'::text, 'test schedule comment'::text, true, + '2020-04-14 01:11:31 -07:00'::timestamp with time zone, '2020-04-15 01:11:34 -07:00'::timestamp with time zone, + -- Minutes + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Hours + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false]::boolean[], + -- Week days + ARRAY[true,true,true,true,true,true,true]::boolean[], + -- Month days + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false]::boolean[], + -- Months + ARRAY[true,true,true,true,true,true,true,true,true,true,true,true]::boolean[] +) RETURNING jscid INTO scid; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_step_remote_db.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_step_remote_db.sql new file mode 100644 index 0000000..819c7ba --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_step_remote_db.sql @@ -0,0 +1,24 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_remote_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + 'host=localhost port=5432 dbname=postgres connect_timeout=10'::text, ''::name, 's'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_step_remote_db_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_step_remote_db_msql.sql new file mode 100644 index 0000000..819c7ba --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_step_remote_db_msql.sql @@ -0,0 +1,24 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_remote_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + 'host=localhost port=5432 dbname=postgres connect_timeout=10'::text, ''::name, 's'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_with_step_local_db.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_with_step_local_db.sql new file mode 100644 index 0000000..3a6556e --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_with_step_local_db.sql @@ -0,0 +1,24 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_local_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 'f'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_with_step_local_db_msql.sql b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_with_step_local_db_msql.sql new file mode 100644 index 0000000..3a6556e --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/create_sql_job_with_step_local_db_msql.sql @@ -0,0 +1,24 @@ +DO $$ +DECLARE + jid integer; +BEGIN +-- Creating a new job +INSERT INTO pgagent.pga_job( + jobjclid, jobname, jobdesc, jobhostagent, jobenabled +) VALUES ( + 1::integer, 'test_sql_job_local_db_$%{}[]()&*^!@""''`\/#'::text, 'test_job_step_schedule description'::text, 'test_host'::text, true +) RETURNING jobid INTO jid; + +-- Steps +-- Inserting a step (jobid: NULL) +INSERT INTO pgagent.pga_jobstep ( + jstjobid, jstname, jstenabled, jstkind, + jstconnstr, jstdbname, jstonerror, + jstcode, jstdesc +) VALUES ( + jid, 'step_1'::text, true, 's'::character(1), + ''::text, 'postgres'::name, 'f'::character(1), + 'SELECT 1;'::text, 'job step description'::text +) ; +END +$$; diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/test_pgagent.json b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/test_pgagent.json new file mode 100644 index 0000000..4c42840 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/pgagent/tests/default/test_pgagent.json @@ -0,0 +1,503 @@ +{ + "scenarios": [ + { + "type": "create", + "name": "Create SQL job with job step and schedule on local database", + "endpoint": "NODE-pga_job.obj", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql", + "pgagent_test": "True", + "convert_timestamp_columns": { "jschedules": ["jscstart", "jscend"] }, + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "jobname": "test_sql_job_local_db_$%{}[]()&*^!@\"\"'`\\/#", + "jobenabled": true, + "jobhostagent": "test_host", + "jobjclid": "1", + "jobdesc": "test_job_step_schedule description", + "jsteps": [{ + "jstid":"", + "jstjobid":"", + "jstname":"step_1", + "jstdesc":"job step description", + "jstenabled":true, + "jstkind":true, + "jstconntype":true, + "jstcode":"SELECT 1;", + "jstconnstr":"", + "jstdbname":"postgres", + "jstonerror":"f", + "jstnextrun":"" + }], + "jschedules": [{ + "jscid":"", + "jscjobid":"", + "jscname":"schedule_1", + "jscdesc":"test schedule comment", + "jscenabled":true, + "jscstart":"2020-04-14 01:11:31 -07:00", + "jscend":"2020-04-15 01:11:34 -07:00", + "jscweekdays":[true,true,true,true,true,true,true], + "jscmonthdays":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false], + "jscmonths":[true,true,true,true,true,true,true,true,true,true,true,true], + "jschours":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false], + "jscminutes":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscexceptions":[{"jexdate": "2020-04-18", "jextime": "01:18:00"}, {"jexdate": "2020-04-19", "jextime": "01:19:00"}] + }] + }, + "expected_sql_file": "create_sql_job_local_db_with_all_options.sql", + "expected_msql_file": "create_sql_job_local_db_with_all_options_msql.sql" + }, { + "type": "delete", + "name": "Drop the SQL job scheduled on local database with all the options", + "endpoint": "NODE-pga_job.obj_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "name": "test_sql_job_local_db_$%{}[]()&*^!@\"\"'`\\/#" + } + }, { + "type": "create", + "name": "Create SQL job with job step on local database", + "endpoint": "NODE-pga_job.obj", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "jobname": "test_sql_job_local_db_$%{}[]()&*^!@\"\"'`\\/#", + "jobenabled": true, + "jobhostagent": "test_host", + "jobjclid": "1", + "jobdesc": "test_job_step_schedule description", + "jsteps": [{ + "jstid":"", + "jstjobid":"", + "jstname":"step_1", + "jstdesc":"job step description", + "jstenabled":true, + "jstkind":true, + "jstconntype":true, + "jstcode":"SELECT 1;", + "jstconnstr":"", + "jstdbname":"postgres", + "jstonerror":"f", + "jstnextrun":"" + }] + }, + "expected_sql_file": "create_sql_job_with_step_local_db.sql", + "expected_msql_file": "create_sql_job_with_step_local_db_msql.sql" + }, { + "type": "alter", + "name": "Alter job with all the options on local database", + "endpoint": "NODE-pga_job.obj_id", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "pga_job_id": "", + "data": { + "jobname": "test_sql_job_local_db_updated_$%{}[]()&*^!@\"\"'`\\/#", + "jobenabled": false, + "jobjclid": "4", + "jobhostagent": "test_host_updated", + "jobdesc": "test_job_step_schedule description updated" + }, + "expected_sql_file": "alter_sql_job_all_options.sql", + "expected_msql_file": "alter_sql_job_all_options_msql.sql" + }, { + "type": "alter", + "name": "Alter job steps with all the options on local database", + "endpoint": "NODE-pga_job.obj_id", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "pga_job_id": "", + "data": { + "jsteps": { + "added": [ + { + "jstid":"", + "jstjobid":"", + "jstname": "step_2_added", + "jstdesc": "job step 2 description", + "jstenabled": true, + "jstkind": true, + "jstconntype": true, + "jstcode": "SELECT 3;", + "jstconnstr": "", + "jstdbname": "postgres", + "jstonerror": "s", + "jstnextrun": "" + } + ] + } + }, + "expected_sql_file": "alter_job_step_all_options.sql", + "expected_msql_file": "alter_job_step_all_options_msql.sql" + }, { + "type": "alter", + "name": "Alter job schedule with all the options on local database", + "endpoint": "NODE-pga_job.obj_id", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "pga_job_id": "", + "convert_timestamp_columns": { "jschedules": ["jscstart", "jscend"] }, + "data": { + "jschedules": { + "added": [ + { + "jscid":"", + "jscjobid":"", + "jscname":"schedule_2", + "jscdesc":"test schedule_2 comment", + "jscenabled":false, + "jscstart":"2020-04-14 05:11:31 -07:00", + "jscend":"2020-04-15 05:11:34 -07:00", + "jscweekdays":[false,false,true,true,true,true,true], + "jscmonthdays":[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false], + "jscmonths":[false,false,true,true,true,true,true,true,true,true,true,true], + "jschours":[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false], + "jscminutes":[false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscexceptions":[{"jexdate": "2020-04-22", "jextime": "01:22:00"}, {"jexdate": "2020-04-23", "jextime": "01:23:00"}] + } + ] + } + }, + "expected_sql_file": "alter_job_schedule_all_options.sql", + "expected_msql_file": "alter_job_schedule_all_options_msql.sql" + }, { + "type": "delete", + "name": "Drop the SQL job scheduled on local database with all the options", + "endpoint": "NODE-pga_job.obj_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "name": "test_sql_job_local_db_updated_$%{}[]()&*^!@\"\"'`\\/#" + } + }, { + "type": "create", + "name": "Create SQL job with job step and schedule on remote database", + "endpoint": "NODE-pga_job.obj", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql", + "convert_timestamp_columns": { "jschedules": ["jscstart", "jscend"] }, + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "jobname": "test_sql_job_remote_db_$%{}[]()&*^!@\"\"'`\\/#", + "jobenabled": true, + "jobhostagent": "test_host", + "jobjclid": "1", + "jobdesc": "test_job_step_schedule description", + "jsteps": [{ + "jstid":"", + "jstjobid":"", + "jstname":"step_1", + "jstdesc":"job step description", + "jstenabled":true, + "jstkind":true, + "jstconntype":false, + "jstcode":"SELECT 1;", + "jstconnstr":"host=localhost port=5432 dbname=postgres connect_timeout=10", + "jstdbname":"", + "jstonerror":"s", + "jstnextrun":"" + }], + "jschedules": [{ + "jscid":"", + "jscjobid":"", + "jscname":"schedule_1", + "jscdesc":"test schedule comment", + "jscenabled":true, + "jscstart":"2020-04-14 01:11:31 -07:00", + "jscend":"2020-04-15 01:11:34 -07:00", + "jscweekdays":[true,true,true,true,true,true,true], + "jscmonthdays":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false], + "jscmonths":[true,true,true,true,true,true,true,true,true,true,true,true], + "jschours":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false], + "jscminutes":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscexceptions":[] + }] + }, + "expected_sql_file": "create_sql_job_remote_db_with_all_options.sql", + "expected_msql_file": "create_sql_job_remote_db_with_all_options_msql.sql" + }, { + "type": "delete", + "name": "Drop the SQL job scheduled on remote database with all options", + "endpoint": "NODE-pga_job.obj_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "name": "test_sql_job_remote_db_$%{}[]()&*^!@\"\"'`\\/#" + } + }, { + "type": "create", + "name": "Create SQL job with job step on remote database", + "endpoint": "NODE-pga_job.obj", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "jobname": "test_sql_job_remote_db_$%{}[]()&*^!@\"\"'`\\/#", + "jobenabled": true, + "jobhostagent": "test_host", + "jobjclid": "1", + "jobdesc": "test_job_step_schedule description", + "jsteps": [{ + "jstid":"", + "jstjobid":"", + "jstname":"step_1", + "jstdesc":"job step description", + "jstenabled":true, + "jstkind":true, + "jstconntype":false, + "jstcode":"SELECT 1;", + "jstconnstr":"host=localhost port=5432 dbname=postgres connect_timeout=10", + "jstdbname":"", + "jstonerror":"s", + "jstnextrun":"" + }] + }, + "expected_sql_file": "create_sql_job_step_remote_db.sql", + "expected_msql_file": "create_sql_job_step_remote_db_msql.sql" + }, { + "type": "alter", + "name": "Alter job steps with all the options on remote database", + "endpoint": "NODE-pga_job.obj_id", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "pga_job_id": "", + "data": { + "jsteps": { + "added": [ + { + "jstid":"", + "jstjobid":"", + "jstname":"step_2", + "jstdesc":"job step_2 description", + "jstenabled":false, + "jstkind":true, + "jstconntype":false, + "jstcode":"SELECT 5;", + "jstconnstr":"host=localhost port=5434 dbname=postgres connect_timeout=20", + "jstdbname":"", + "jstonerror":"f", + "jstnextrun":"" + } + ] + } + }, + "expected_sql_file": "alter_job_step_remote_db_all_options.sql", + "expected_msql_file": "alter_job_step_remote_db_all_options_msql.sql" + }, { + "type": "alter", + "name": "Alter job schedule with all the options on remote database", + "endpoint": "NODE-pga_job.obj_id", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql_id", + "convert_timestamp_columns": { "jschedules": ["jscstart", "jscend"] }, + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "pga_job_id": "", + "data": { + "jschedules": { + "added": [ + { + "jscid":"", + "jscjobid":"", + "jscname":"schedule_2", + "jscdesc":"test schedule_2 comment", + "jscenabled":true, + "jscstart":"2020-04-15 05:11:31 -07:00", + "jscend":"2020-04-16 05:11:34 -07:00", + "jscweekdays":[false,false,false,false,false,false,false], + "jscmonthdays":[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscmonths":[false,false,false,false,false,false,false,false,false,false,false,false], + "jschours":[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscminutes":[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscexceptions":[] + } + ] + } + }, + "expected_sql_file": "alter_job_schedule_remote_db_all_options.sql", + "expected_msql_file": "alter_job_schedule_remote_db_all_options_msql.sql" + }, { + "type": "delete", + "name": "Drop the SQL job scheduled on remote database with all options", + "endpoint": "NODE-pga_job.obj_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "name": "test_sql_job_remote_db_$%{}[]()&*^!@\"\"'`\\/#" + } + }, { + "type": "create", + "name": "Create batch job with all the options", + "endpoint": "NODE-pga_job.obj", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql", + "convert_timestamp_columns": { "jschedules": ["jscstart", "jscend"] }, + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "jobname": "test_batch_job_$%{}[]()&*^!@\"\"'`\\/#", + "jobenabled": true, + "jobhostagent": "test_host", + "jobjclid": "1", + "jobdesc": "test_job_step_schedule description", + "jsteps": [{ + "jstid":"", + "jstjobid":"", + "jstname":"step_1", + "jstdesc":"job step description", + "jstenabled":true, + "jstkind":false, + "jstconntype":true, + "jstcode":"SELECT 1;", + "jstconnstr":"", + "jstdbname":"", + "jstonerror":"i", + "jstnextrun":"" + }], + "jschedules": [{ + "jscid":"", + "jscjobid":"", + "jscname":"schedule_1", + "jscdesc":"test schedule comment", + "jscenabled":true, + "jscstart":"2020-04-14 01:11:31 -07:00", + "jscend":"2020-04-15 01:11:34 -07:00", + "jscweekdays":[true,true,true,true,true,true,true], + "jscmonthdays":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false], + "jscmonths":[true,true,true,true,true,true,true,true,true,true,true,true], + "jschours":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false], + "jscminutes":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscexceptions":[] + }] + }, + "expected_sql_file": "create_batch_job_with_all_options.sql", + "expected_msql_file": "create_batch_job_with_all_options_msql.sql" + }, { + "type": "delete", + "name": "Drop the batch job with step and schedule", + "endpoint": "NODE-pga_job.obj_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "name": "test_batch_job_$%{}[]()&*^!@\"\"'`\\/#" + } + }, { + "type": "create", + "name": "Create batch job with job step", + "endpoint": "NODE-pga_job.obj", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "jobname": "test_batch_job_$%{}[]()&*^!@\"\"'`\\/#", + "jobenabled": true, + "jobhostagent": "test_host", + "jobjclid": "1", + "jobdesc": "test_job_step_schedule description", + "jsteps": [{ + "jstid":"", + "jstjobid":"", + "jstname":"step_1", + "jstdesc":"job step description", + "jstenabled":true, + "jstkind":false, + "jstconntype":true, + "jstcode":"SELECT 1;", + "jstconnstr":"", + "jstdbname":"", + "jstonerror":"i", + "jstnextrun":"" + }] + }, + "expected_sql_file": "create_batch_job_with_step.sql", + "expected_msql_file": "create_batch_job_with_step_msql.sql" + }, { + "type": "alter", + "name": "Alter batch job steps with all the options", + "endpoint": "NODE-pga_job.obj_id", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "pga_job_id": "", + "data": { + "jsteps": { + "added": [ + { + "jstid":"", + "jstjobid":"", + "jstname":"step_2", + "jstdesc":"job step_2 description", + "jstenabled":false, + "jstkind":false, + "jstconntype":true, + "jstcode":"SELECT 10;", + "jstconnstr":"", + "jstdbname":"", + "jstonerror":"s", + "jstnextrun":"" + } + ] + } + }, + "expected_sql_file": "alter_batch_job_step_all_options.sql", + "expected_msql_file": "alter_batch_job_step_all_options_msql.sql" + }, { + "type": "alter", + "name": "Alter batch job schedule with all the options", + "endpoint": "NODE-pga_job.obj_id", + "sql_endpoint": "NODE-pga_job.sql_id", + "msql_endpoint": "NODE-pga_job.msql_id", + "convert_timestamp_columns": { "jschedules": ["jscstart", "jscend"] }, + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "pga_job_id": "", + "data": { + "jschedules": { + "added": [ + { + "jscid":"", + "jscjobid":"", + "jscname":"schedule_2", + "jscdesc":"test schedule_2 comment", + "jscenabled":true, + "jscstart":"2020-04-15 05:11:31 -07:00", + "jscend":"2020-04-16 05:11:34 -07:00", + "jscweekdays":[true,true,false,false,false,false,false], + "jscmonthdays":[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscmonths":[true,true,false,false,false,false,false,false,false,false,false,false], + "jschours":[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscminutes":[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false], + "jscexceptions":[] + } + ] + } + }, + "expected_sql_file": "alter_batch_job_schedule_all_options.sql", + "expected_msql_file": "alter_batch_job_schedule_all_options_msql.sql" + }, { + "type": "delete", + "name": "Drop the batch job with all the options", + "endpoint": "NODE-pga_job.obj_id", + "pgagent_test": "True", + "precondition_sql": "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='pgagent' AND table_name='pga_jobstep' AND column_name='jstconnstr'", + "data": { + "name": "test_batch_job_$%{}[]()&*^!@\"\"'`\\/#" + } + } + ] +} diff --git a/web/pgadmin/browser/server_groups/servers/roles/tests/9.4_plus/alter_login_role_options.sql b/web/pgadmin/browser/server_groups/servers/roles/tests/9.4_plus/alter_login_role_options.sql index c04e71d..65008de 100644 --- a/web/pgadmin/browser/server_groups/servers/roles/tests/9.4_plus/alter_login_role_options.sql +++ b/web/pgadmin/browser/server_groups/servers/roles/tests/9.4_plus/alter_login_role_options.sql @@ -10,7 +10,7 @@ CREATE ROLE "Role2_$%{}[]()&*^!@""'`\/#" WITH NOREPLICATION CONNECTION LIMIT 100 ENCRYPTED PASSWORD '' - VALID UNTIL ''; + VALID UNTIL ''; ALTER ROLE "Role2_$%{}[]()&*^!@""'`\/#" IN DATABASE postgres SET application_name TO 'pg4'; diff --git a/web/pgadmin/browser/server_groups/servers/roles/tests/9.4_plus/alter_role_options.sql b/web/pgadmin/browser/server_groups/servers/roles/tests/9.4_plus/alter_role_options.sql index 9dc3704..5123223 100644 --- a/web/pgadmin/browser/server_groups/servers/roles/tests/9.4_plus/alter_role_options.sql +++ b/web/pgadmin/browser/server_groups/servers/roles/tests/9.4_plus/alter_role_options.sql @@ -10,7 +10,7 @@ CREATE ROLE "Role2_$%{}[]()&*^!@""'`\/#" WITH NOREPLICATION CONNECTION LIMIT 100 ENCRYPTED PASSWORD '' - VALID UNTIL ''; + VALID UNTIL ''; ALTER ROLE "Role2_$%{}[]()&*^!@""'`\/#" IN DATABASE postgres SET application_name TO 'pg4'; diff --git a/web/pgadmin/static/js/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid.pgadmin.js index f503048..2258707 100644 --- a/web/pgadmin/static/js/backgrid.pgadmin.js +++ b/web/pgadmin/static/js/backgrid.pgadmin.js @@ -1894,11 +1894,15 @@ define([ this.$el.datetimepicker('destroy'); this.is_closing = false; + /* set the model default value in case of empty or undefined */ + if (_.isUndefined(newValue) || + String(val).replace(/^\s+|\s+$/g, '') == '') { + newValue = null; + } + model.set(column.get('name'), newValue); let command = new Backgrid.Command(ev); - setTimeout(() => { - model.trigger('backgrid:edited', model, column, command); - }, 20); + model.trigger('backgrid:edited', model, column, command); }, }); diff --git a/web/regression/re_sql/tests/test_resql.py b/web/regression/re_sql/tests/test_resql.py index 7666bea..46eeb9e 100644 --- a/web/regression/re_sql/tests/test_resql.py +++ b/web/regression/re_sql/tests/test_resql.py @@ -86,6 +86,14 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): if not self.db_con['info'] == "Database connected.": raise Exception("Could not connect to database.") + self.test_config_db_conn = utils.get_db_connection( + self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port'] + ) + # Get the application path self.apppath = os.getcwd() # Status of the test case @@ -104,8 +112,10 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): # while running the test cases self.JSON_PLACEHOLDERS = {'schema_id': '', 'owner': '', - 'timestamptz': '', - 'password': ''} + 'timestamptz_1': '', + 'password': '', + 'pga_job_id': '', + 'timestamptz_2': ''} resql_module_list = create_resql_module_list( BaseTestGenerator.re_sql_module_list, @@ -150,6 +160,7 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): database_utils.disconnect_database( self, self.server_information['server_id'], self.server_information['db_id']) + self.test_config_db_conn.close() def get_db_connection(self): """Get the database connection.""" @@ -222,8 +233,18 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): object_id = None for scenario in scenarios: - if 'precondition_sql' in scenario and \ - not self.check_precondition(scenario['precondition_sql']): + skip_test_case = True + if 'precondition_sql' in scenario: + if 'pgagent_test' in scenario and self.check_precondition( + scenario['precondition_sql'], True): + skip_test_case = False + elif self.check_precondition( + scenario['precondition_sql'], False): + skip_test_case = False + else: + skip_test_case = False + + if skip_test_case: print(scenario['name'] + "... skipped (pre-condition SQL not satisfied)") continue @@ -418,7 +439,8 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): fp = open(output_file, "r") # Used rstrip to remove trailing \n sql = fp.read().rstrip() - sql = self.preprocess_expected_sql(scenario, sql, resp_sql) + sql = self.preprocess_expected_sql(scenario, sql, resp_sql, + object_id) try: self.assertEquals(sql, resp_sql) except Exception as e: @@ -472,7 +494,8 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): fp = open(output_file, "r") # Used rstrip to remove trailing \n sql = fp.read().rstrip() - sql = self.preprocess_expected_sql(scenario, sql, resp_sql) + sql = self.preprocess_expected_sql(scenario, sql, resp_sql, + object_id) try: self.assertEquals(sql, resp_sql) except Exception as e: @@ -488,7 +511,8 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): return False elif 'expected_sql' in scenario: exp_sql = scenario['expected_sql'] - exp_sql = self.preprocess_expected_sql(scenario, exp_sql, resp_sql) + exp_sql = self.preprocess_expected_sql(scenario, exp_sql, resp_sql, + object_id) try: self.assertEquals(exp_sql, resp_sql) except Exception as e: @@ -498,15 +522,19 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): return True - def check_precondition(self, precondition_sql): + def check_precondition(self, precondition_sql, use_test_config_db_conn): """ This method executes precondition_sql and returns appropriate result :param precondition_sql: SQL query in format select count(*) from ... :return: True/False depending on precondition_sql result """ precondition_flag = False - self.get_db_connection() - pg_cursor = self.connection.cursor() + if not use_test_config_db_conn: + self.get_db_connection() + pg_cursor = self.connection.cursor() + else: + pg_cursor = self.test_config_db_conn.cursor() + try: pg_cursor.execute(precondition_sql) precondition_result = pg_cursor.fetchone() @@ -561,18 +589,49 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): :return: """ if 'convert_timestamp_columns' in scenario: - for col in scenario['convert_timestamp_columns']: - if 'data' in scenario and col in scenario['data']: + col_list = list() + key_attr = '' + is_tz_columns_list = False + tz_index = 0 + if isinstance(scenario['convert_timestamp_columns'], dict): + for key, value in scenario[ + 'convert_timestamp_columns'].items(): + col_list = scenario['convert_timestamp_columns'][key] + key_attr = key + break + else: + col_list = scenario['convert_timestamp_columns'] + is_tz_columns_list = True + + for col in col_list: + if ('data' in scenario and col in scenario['data']) or \ + (key_attr and 'data' in scenario and 'type' in + scenario and scenario['type'] == 'create' and col in + scenario['data'][key_attr][0]) or \ + (key_attr and 'data' in scenario and 'type' in + scenario and scenario['type'] == 'alter' and col in + scenario['data'][key_attr]['added'][0]): self.get_db_connection() pg_cursor = self.connection.cursor() try: - query = "SELECT timestamp with time zone '" \ - + scenario['data'][col] + "'" + if is_tz_columns_list: + query = "SELECT timestamp with time zone '" \ + + scenario['data'][col] + "'" + elif scenario['type'] == 'create': + query = "SELECT timestamp with time zone '" \ + + scenario['data'][key_attr][0][col] + "'" + else: + query = "SELECT timestamp with time zone '" \ + + scenario['data'][key_attr][ + 'added'][0][col] + "'" + pg_cursor.execute(query) converted_tz = pg_cursor.fetchone() if len(converted_tz) >= 1: + tz_index = tz_index + 1 + tz_str = "timestamptz_{0}".format(tz_index) sql = sql.replace( - self.JSON_PLACEHOLDERS['timestamptz'], + self.JSON_PLACEHOLDERS[tz_str], converted_tz[0]) except Exception as e: traceback.print_exc() @@ -624,7 +683,7 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): return data - def preprocess_expected_sql(self, scenario, sql, resp_sql): + def preprocess_expected_sql(self, scenario, sql, resp_sql, object_id): """ This function preprocesses expected sql before comparing it with response sql. @@ -654,6 +713,12 @@ class ReverseEngineeredSQLTestCases(BaseTestGenerator): sql = sql.replace(self.JSON_PLACEHOLDERS['password'], password) + # Replace place holder with the current username + # used to connect to the database + if 'pga_job_id' in scenario: + sql = sql.replace(self.JSON_PLACEHOLDERS['pga_job_id'], + str(object_id)) + return sql def replace_placeholder_with_id(self, value):