Hi,
Please find attached patch to fix the issues in pgAgent's Schedule and Step
module.
1) Error on clicking SQL panel when Schedule OR Step node is selected in
browser.
RM#1888
2) Error while dropping Schedule OR Step node.
RM#1889
3) Newly created Schedule/Step node was not displaying in browser.
RM#1890
Other misc changes are for PEP-8.
--
Regards,
Murtuza Zabuawala
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py
b/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py
index 912ed02..bd6e248 100644
--- a/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py
@@ -345,7 +345,7 @@ SELECT EXISTS(
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'nodes.sql']),
- jid=res, conn=self.conn
+ jid=jid, conn=self.conn
)
)
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 51ae632..fefcc49 100644
--- a/web/pgadmin/browser/server_groups/servers/pgagent/schedules/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/pgagent/schedules/__init__.py
@@ -12,7 +12,7 @@
import json
from functools import wraps
-from flask import render_template, make_response, request
+from flask import render_template, make_response, request, jsonify
from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView
@@ -64,7 +64,8 @@ class JobScheduleModule(CollectionNodeModule):
@property
def script_load(self):
"""
- Load the module script for language, when any of the database nodes
are initialized.
+ Load the module script for schedule, when any of the pga_job
+ nodes are initialized.
Returns: node type of the server module.
"""
@@ -78,9 +79,9 @@ class JobScheduleView(PGChildNodeView):
"""
class JobScheduleView(PGChildNodeView)
- A view class for JobSchedule node derived from PGChildNodeView. This
class is
- responsible for all the stuff related to view like updating language
- node, showing properties, showing sql in sql pane.
+ A view class for JobSchedule node derived from PGChildNodeView.
+ This class is responsible for all the stuff related to view like
+ updating schedule node, showing properties, showing sql in sql pane.
Methods:
-------
@@ -97,20 +98,28 @@ class JobScheduleView(PGChildNodeView):
manager,conn & template_path properties to self
* list()
- - This function is used to list all the language nodes within that
collection.
+ - This function is used to list all the schedule nodes within that
+ collection.
* nodes()
- - This function will used to create all the child node within that
collection.
- Here it will create all the language node.
+ - This function will used to create all the child node within that
+ collection. Here it will create all the schedule node.
* properties(gid, sid, jid, jscid)
- - This function will show the properties of the selected language node
+ - This function will show the properties of the selected schedule node
* update(gid, sid, jid, jscid)
- - This function will update the data for the selected language node
+ - This function will update the data for the selected schedule node
* msql(gid, sid, jid, jscid)
- - This function is used to return modified SQL for the selected language
node
+ - This function is used to return modified SQL for the
+ selected schedule node
+
+ * sql(gid, sid, jid, jscid)
+ - Dummy response for sql panel
+
+ * delete(gid, sid, jid, jscid)
+ - Drops job schedule
"""
node_type = blueprint.node_type
@@ -126,18 +135,20 @@ class JobScheduleView(PGChildNodeView):
operations = dict({
'obj': [
- {'get': 'properties', 'put': 'update'},
+ {'get': 'properties', 'put': 'update', 'delete': 'delete'},
{'get': 'list', 'post': 'create'}
],
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
'msql': [{'get': 'msql'}, {'get': 'msql'}],
+ 'sql': [{'get': 'sql'}],
'module.js': [{}, {}, {'get': 'module_js'}]
})
def _init_(self, **kwargs):
"""
Method is used to initialize the JobScheduleView and its base view.
- Initialize all the variables create/used dynamically like conn,
template_path.
+ Initialize all the variables create/used dynamically like conn,
+ template_path.
Args:
**kwargs:
@@ -184,7 +195,8 @@ class JobScheduleView(PGChildNodeView):
@check_precondition
def list(self, gid, sid, jid):
"""
- This function is used to list all the language nodes within that
collection.
+ This function is used to list all the language nodes within
+ that collection.
Args:
gid: Server Group ID
@@ -208,8 +220,8 @@ class JobScheduleView(PGChildNodeView):
@check_precondition
def nodes(self, gid, sid, jid, jscid=None):
"""
- This function is used to create all the child nodes within the
collection.
- Here it will create all the language nodes.
+ This function is used to create all the child nodes within
+ the collection. Here it will create all the language nodes.
Args:
gid: Server Group ID
@@ -230,11 +242,13 @@ class JobScheduleView(PGChildNodeView):
if jscid is not None:
if len(result['rows']) == 0:
- return gone(errormsg="Could not find the specified job step.")
+ return gone(
+ errormsg=gettext("Could not find the specified job step.")
+ )
row = result['rows'][0]
return make_json_response(
- self.blueprint.generate_browser_node(
+ data=self.blueprint.generate_browser_node(
row['jscid'],
row['jscjobid'],
row['jscname'],
@@ -280,17 +294,33 @@ class JobScheduleView(PGChildNodeView):
return internal_server_error(errormsg=res)
if len(res['rows']) == 0:
- return gone(errormsg="Could not find the specified job step.")
+ return gone(
+ errormsg=gettext("Could not find the specified job step.")
+ )
return ajax_response(
response=res['rows'][0],
status=200
)
+ @staticmethod
+ def format_list_data(value):
+ """
+ Converts to proper array data for sql
+ Args:
+ value: data to be converted
+
+ Returns:
+ Converted data
+ """
+ if not isinstance(value, list):
+ return value.replace("[", "{").replace("]", "}")
+ return value
+
@check_precondition
def create(self, gid, sid, jid):
"""
- This function will update the data for the selected language node.
+ This function will update the data for the selected schedule node.
Args:
gid: Server Group ID
@@ -309,11 +339,21 @@ class JobScheduleView(PGChildNodeView):
else:
data = json.loads(request.data.decode())
# convert python list literal to postgres array literal.
- data['jscminutes'] = data['jscminutes'].replace("[",
"{").replace("]", "}")
- data['jschours'] = data['jschours'].replace("[", "{").replace("]",
"}")
- data['jscweekdays'] = data['jscweekdays'].replace("[",
"{").replace("]", "}")
- data['jscmonthdays'] = data['jscmonthdays'].replace("[",
"{").replace("]", "}")
- data['jscmonths'] = data['jscmonths'].replace("[",
"{").replace("]", "}")
+ data['jscminutes'] = JobScheduleView.format_list_data(
+ data['jscminutes']
+ )
+ data['jschours'] = JobScheduleView.format_list_data(
+ data['jschours']
+ )
+ data['jscweekdays'] = JobScheduleView.format_list_data(
+ data['jscweekdays']
+ )
+ data['jscmonthdays'] = JobScheduleView.format_list_data(
+ data['jscmonthdays']
+ )
+ data['jscmonths'] = JobScheduleView.format_list_data(
+ data['jscmonths']
+ )
sql = render_template(
"/".join([self.template_path, 'create.sql']),
@@ -335,7 +375,7 @@ class JobScheduleView(PGChildNodeView):
self.conn.execute_void('END')
sql = render_template(
- "/".join([self.template_path, 'nodes.sql']),
+ "/".join([self.template_path, 'properties.sql']),
jscid=res,
jid=jid
)
@@ -344,20 +384,27 @@ class JobScheduleView(PGChildNodeView):
if not status:
return internal_server_error(errormsg=res)
+ if len(res['rows']) == 0:
+ return gone(
+ errormsg=gettext("Job schedule creation failed.")
+ )
row = res['rows'][0]
- return make_json_response(
- data=self.blueprint.generate_browser_node(
+
+ return jsonify(
+ node=self.blueprint.generate_browser_node(
row['jscid'],
row['jscjobid'],
row['jscname'],
- icon="icon-pga_schedule"
+ icon="icon-pga_schedule",
+ enabled=row['jscenabled']
)
)
+
@check_precondition
def update(self, gid, sid, jid, jscid):
"""
- This function will update the data for the selected language node.
+ This function will update the data for the selected schedule node.
Args:
gid: Server Group ID
@@ -377,20 +424,26 @@ class JobScheduleView(PGChildNodeView):
else:
data = json.loads(request.data.decode())
# convert python list literal to postgres array literal.
- if 'jscminutes' in data:
- data['jscminutes'] = data['jscminutes'].replace("[",
"{").replace("]", "}")
-
- if 'jschours' in data:
- data['jschours'] = data['jschours'].replace("[",
"{").replace("]", "}")
-
- if 'jscweekdays' in data:
- data['jscweekdays'] = data['jscweekdays'].replace("[",
"{").replace("]", "}")
-
- if 'jscmonthdays' in data:
- data['jscmonthdays'] = data['jscmonthdays'].replace("[",
"{").replace("]", "}")
-
- if 'jscmonths' in data:
- data['jscmonths'] = data['jscmonths'].replace("[",
"{").replace("]", "}")
+ if 'jscminutes' in data and data['jscminutes'] is not None:
+ data['jscminutes'] = JobScheduleView.format_list_data(
+ data['jscminutes']
+ )
+ if 'jschours' in data and data['jschours'] is not None:
+ data['jschours'] = JobScheduleView.format_list_data(
+ data['jschours']
+ )
+ if 'jscweekdays' in data and data['jscweekdays'] is not None:
+ data['jscweekdays'] = JobScheduleView.format_list_data(
+ data['jscweekdays']
+ )
+ if 'jscmonthdays' in data and data['jscmonthdays'] is not None:
+ data['jscmonthdays'] = JobScheduleView.format_list_data(
+ data['jscmonthdays']
+ )
+ if 'jscmonths' in data and data['jscmonths'] is not None:
+ data['jscmonths'] = JobScheduleView.format_list_data(
+ data['jscmonths']
+ )
sql = render_template(
"/".join([self.template_path, 'update.sql']),
@@ -405,7 +458,7 @@ class JobScheduleView(PGChildNodeView):
return internal_server_error(errormsg=res)
sql = render_template(
- "/".join([self.template_path, 'nodes.sql']),
+ "/".join([self.template_path, 'properties.sql']),
jscid=jscid,
jid=jid
)
@@ -415,19 +468,41 @@ class JobScheduleView(PGChildNodeView):
return internal_server_error(errormsg=res)
row = res['rows'][0]
- return make_json_response(
- self.blueprint.generate_browser_node(
- row['jscid'],
- row['jscjobid'],
+ if len(res['rows']) == 0:
+ return gone(
+ errormsg=gettext("Job schedule update failed.")
+ )
+
+ return jsonify(
+ node=self.blueprint.generate_browser_node(
+ jscid,
+ jid,
row['jscname'],
- icon="icon-pga_schedule"
+ icon="icon-pga_schedule",
+ enabled=row['jscenabled']
+ )
+ )
+
+ @check_precondition
+ def delete(self, gid, sid, jid, jscid):
+ """Delete the Job Schedule."""
+
+ status, res = self.conn.execute_void(
+ render_template(
+ "/".join([self.template_path, 'delete.sql']),
+ jid=jid, jscid=jscid, conn=self.conn
)
)
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ return make_json_response(success=1)
@check_precondition
def msql(self, gid, sid, jid, jscid=None):
"""
- This function is used to return modified SQL for the selected language
node.
+ This function is used to return modified SQL for the
+ selected Schedule node.
Args:
gid: Server Group ID
@@ -465,5 +540,20 @@ class JobScheduleView(PGChildNodeView):
status=200
)
+ @check_precondition
+ def sql(self, gid, sid, jid, jscid):
+ """
+ Dummy response for sql route.
+ As we need to have msql tab for create and edit mode we can not
+ disable it setting hasSQL=false because we have a single 'hasSQL'
+ flag in JS to display both sql & msql tab
+ """
+ return ajax_response(
+ response=gettext(
+ "-- No SQL could be generated for the selected object."
+ ),
+ status=200
+ )
+
JobScheduleView.register_node_view(blueprint)
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 35f1fbb..3aba293 100644
--- a/web/pgadmin/browser/server_groups/servers/pgagent/steps/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/pgagent/steps/__init__.py
@@ -12,7 +12,7 @@
import json
from functools import wraps
-from flask import render_template, make_response, request
+from flask import render_template, make_response, request, jsonify
from flask_babel import gettext
from pgadmin.browser.collection import CollectionNodeModule
from pgadmin.browser.utils import PGChildNodeView
@@ -64,7 +64,8 @@ class JobStepModule(CollectionNodeModule):
@property
def script_load(self):
"""
- Load the module script for language, when any of the database nodes
are initialized.
+ Load the module script for language, when any of the pga_job nodes
+ are initialized.
Returns: node type of the server module.
"""
@@ -78,9 +79,9 @@ class JobStepView(PGChildNodeView):
"""
class JobStepView(PGChildNodeView)
- A view class for JobStep node derived from PGChildNodeView. This class
is
- responsible for all the stuff related to view like updating language
- node, showing properties, showing sql in sql pane.
+ A view class for JobStep node derived from PGChildNodeView.
+ This class is responsible for all the stuff related to view like
+ updating job step node, showing properties, showing sql in sql pane.
Methods:
-------
@@ -97,20 +98,29 @@ class JobStepView(PGChildNodeView):
manager,conn & template_path properties to self
* list()
- - This function is used to list all the language nodes within that
collection.
+ - This function is used to list all the job step nodes within that
+ collection.
* nodes()
- - This function will used to create all the child node within that
collection.
- Here it will create all the language node.
+ - This function will used to create all the child node within that
+ collection.
+ Here it will create all the job step node.
* properties(gid, sid, jid, jstid)
- - This function will show the properties of the selected language node
+ - This function will show the properties of the selected job step node
* update(gid, sid, jid, jstid)
- - This function will update the data for the selected language node
+ - This function will update the data for the selected job step node
* msql(gid, sid, jid, jstid)
- - This function is used to return modified SQL for the selected language
node
+ - This function is used to return modified SQL for the selected
+ job step node
+
+ * sql(gid, sid, jid, jscid)
+ - Dummy response for sql panel
+
+ * delete(gid, sid, jid, jscid)
+ - Drops job step
"""
node_type = blueprint.node_type
@@ -126,11 +136,12 @@ class JobStepView(PGChildNodeView):
operations = dict({
'obj': [
- {'get': 'properties', 'put': 'update'},
+ {'get': 'properties', 'put': 'update', 'delete': 'delete'},
{'get': 'list', 'post': 'create'}
],
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
'msql': [{'get': 'msql'}, {'get': 'msql'}],
+ 'sql': [{'get': 'sql'}],
'stats': [{'get': 'statistics'}],
'module.js': [{}, {}, {'get': 'module_js'}]
})
@@ -138,7 +149,8 @@ class JobStepView(PGChildNodeView):
def _init_(self, **kwargs):
"""
Method is used to initialize the JobStepView and its base view.
- Initialize all the variables create/used dynamically like conn,
template_path.
+ Initialize all the variables create/used dynamically like conn,
+ template_path.
Args:
**kwargs:
@@ -196,7 +208,8 @@ SELECT EXISTS(
@check_precondition
def list(self, gid, sid, jid):
"""
- This function is used to list all the language nodes within that
collection.
+ This function is used to list all the job step nodes within
+ that collection.
Args:
gid: Server Group ID
@@ -221,8 +234,9 @@ SELECT EXISTS(
@check_precondition
def nodes(self, gid, sid, jid, jstid=None):
"""
- This function is used to create all the child nodes within the
collection.
- Here it will create all the language nodes.
+ This function is used to create all the child nodes
+ within the collection.
+ Here it will create all the job step nodes.
Args:
gid: Server Group ID
@@ -277,7 +291,7 @@ SELECT EXISTS(
@check_precondition
def properties(self, gid, sid, jid, jstid):
"""
- This function will show the properties of the selected language node.
+ This function will show the properties of the selected job step node.
Args:
gid: Server Group ID
@@ -307,7 +321,7 @@ SELECT EXISTS(
@check_precondition
def create(self, gid, sid, jid):
"""
- This function will update the data for the selected language node.
+ This function will update the data for the selected job step node.
Args:
gid: Server Group ID
@@ -348,9 +362,15 @@ SELECT EXISTS(
if not status:
return internal_server_error(errormsg=res)
+ if len(res['rows']) == 0:
+ return gone(
+ errormsg=gettext(
+ "Job step creation failed."
+ )
+ )
row = res['rows'][0]
- return make_json_response(
- data=self.blueprint.generate_browser_node(
+ return jsonify(
+ node=self.blueprint.generate_browser_node(
row['jstid'],
row['jstjobid'],
row['jstname'],
@@ -361,7 +381,7 @@ SELECT EXISTS(
@check_precondition
def update(self, gid, sid, jid, jstid):
"""
- This function will update the data for the selected language node.
+ This function will update the data for the selected job step node.
Args:
gid: Server Group ID
@@ -428,20 +448,43 @@ SELECT EXISTS(
if not status:
return internal_server_error(errormsg=res)
+ if len(res['rows']) == 0:
+ return gone(
+ errormsg=gettext(
+ "Job step update failed."
+ )
+ )
row = res['rows'][0]
- return make_json_response(
- self.blueprint.generate_browser_node(
- row['jstid'],
- row['jstjobid'],
+ return jsonify(
+ node=self.blueprint.generate_browser_node(
+ jstid,
+ jid,
row['jstname'],
icon="icon-pga_jobstep"
)
)
@check_precondition
+ def delete(self, gid, sid, jid, jstid):
+ """Delete the Job step."""
+
+ status, res = self.conn.execute_void(
+ render_template(
+ "/".join([self.template_path, 'delete.sql']),
+ jid=jid, jstid=jstid, conn=self.conn
+ )
+ )
+ if not status:
+ return internal_server_error(errormsg=res)
+
+ return make_json_response(success=1)
+
+
+ @check_precondition
def msql(self, gid, sid, jid, jstid=None):
"""
- This function is used to return modified SQL for the selected language
node.
+ This function is used to return modified SQL for the selected
+ job step node.
Args:
gid: Server Group ID
@@ -535,5 +578,20 @@ SELECT EXISTS(
status=200
)
+ @check_precondition
+ def sql(self, gid, sid, jid, jstid):
+ """
+ Dummy response for sql route.
+ As we need to have msql tab for create and edit mode we can not
+ disable it setting hasSQL=false because we have a single 'hasSQL'
+ flag in JS to display both sql & msql tab
+ """
+ return ajax_response(
+ response=gettext(
+ "-- No SQL could be generated for the selected object."
+ ),
+ status=200
+ )
+
JobStepView.register_node_view(blueprint)
--
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers