Skip to content

Commit cbc371e

Browse files
committed
More fixes addressing coderabbitai review
- Address status failures on tuple updates in _process_ctasks(), _upsert_task_params(), _upsert_task_params() - Do not return ok on partial chain-field UPDATE failures - Unguarded query status before indexing res['rows'][0] in check_precondition() - kind should not be represented as boolean, should be cast to text - Only insert to database_connection column if has_connstr
1 parent c34bb52 commit cbc371e

4 files changed

Lines changed: 50 additions & 32 deletions

File tree

web/pgadmin/browser/server_groups/servers/pg_timetable/__init__.py

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ def update(self, gid, sid, chain_id):
359359
request.data.decode('utf-8')
360360
)
361361

362+
status, res = self.conn.execute_void('BEGIN')
363+
if not status:
364+
return internal_server_error(errormsg=res)
365+
362366
chain_fields = {k: data[k] for k in ['chain_name', 'live', 'max_instances', 'timeout', 'self_destruct', 'exclusive_execution', 'client_name', 'on_error', 'run_at'] if k in data}
363367
if chain_fields:
364368
sets = []
@@ -374,9 +378,13 @@ def update(self, gid, sid, chain_id):
374378
sql = f"UPDATE timetable.chain SET {', '.join(sets)} WHERE chain_id = %s"
375379
status, res = self.conn.execute_void(sql, params)
376380
if not status:
381+
self.conn.execute_void('ROLLBACK')
377382
return internal_server_error(errormsg=res)
378383

379-
self._process_ctasks(chain_id, data.get('ctasks', {}))
384+
status, res = self._process_ctasks(chain_id, data.get('ctasks', {}))
385+
if not status:
386+
self.conn.execute_void('ROLLBACK')
387+
return internal_server_error(errormsg=res)
380388

381389
status, res = self.conn.execute_dict(
382390
render_template(
@@ -386,8 +394,13 @@ def update(self, gid, sid, chain_id):
386394
)
387395

388396
if not status:
397+
self.conn.execute_void('ROLLBACK')
389398
return internal_server_error(errormsg=res)
390399

400+
status, commit_res = self.conn.execute_void('COMMIT')
401+
if not status:
402+
return internal_server_error(errormsg=commit_res)
403+
391404
row = res['rows'][0]
392405

393406
return jsonify(
@@ -403,15 +416,17 @@ def update(self, gid, sid, chain_id):
403416

404417
def _process_ctasks(self, chain_id, ctasks):
405418
if not isinstance(ctasks, dict):
406-
return
419+
return True, None
407420

408421
for task in ctasks.get('deleted', []):
409422
tid = task.get('task_id') if isinstance(task, dict) else task
410423
if tid:
411-
self.conn.execute_void(
424+
status, res = self.conn.execute_void(
412425
"DELETE FROM timetable.task WHERE task_id = %s AND chain_id = %s",
413426
(tid, chain_id)
414427
)
428+
if not status:
429+
return status, res
415430

416431
has_connstr = self.manager.db_info['timetable']['has_connstr']
417432
for task in ctasks.get('changed', []):
@@ -440,9 +455,13 @@ def _process_ctasks(self, chain_id, ctasks):
440455
if sets:
441456
params.extend([tid, chain_id])
442457
sql = f"UPDATE timetable.task SET {', '.join(sets)} WHERE task_id = %s AND chain_id = %s"
443-
self.conn.execute_void(sql, params)
458+
status, res = self.conn.execute_void(sql, params)
459+
if not status:
460+
return status, res
444461
if 'parameters' in task:
445-
self._upsert_task_params(tid, task['parameters'])
462+
status, res = self._upsert_task_params(tid, task['parameters'])
463+
if not status:
464+
return status, res
446465

447466
for task in ctasks.get('added', []):
448467
if not isinstance(task, dict):
@@ -461,19 +480,27 @@ def _process_ctasks(self, chain_id, ctasks):
461480
placeholders = ', '.join(['%s'] * len(values))
462481
sql = f"INSERT INTO timetable.task ({', '.join(fields)}) VALUES ({placeholders}) RETURNING task_id"
463482
status, tid = self.conn.execute_scalar(sql, values)
464-
if status and tid:
465-
self._upsert_task_params(tid, task.get('parameters', []))
483+
if not status:
484+
return status, tid
485+
if tid:
486+
status, res = self._upsert_task_params(tid, task.get('parameters', []))
487+
if not status:
488+
return status, res
489+
490+
return True, None
466491

467492
def _upsert_task_params(self, task_id, parameters):
468493
if not parameters:
469-
return
494+
return True, None
470495
if isinstance(parameters, dict):
471496
parameters = parameters.get('added', []) + parameters.get('changed', [])
472497
if not parameters:
473-
return
474-
self.conn.execute_void(
498+
return True, None
499+
status, res = self.conn.execute_void(
475500
"DELETE FROM timetable.parameter WHERE task_id = %s", (task_id,)
476501
)
502+
if not status:
503+
return status, res
477504
for idx, param in enumerate(parameters):
478505
if not isinstance(param, dict):
479506
param = {'order_id': idx + 1, 'value': str(param)}
@@ -490,7 +517,10 @@ def _upsert_task_params(self, task_id, parameters):
490517
except (ValueError, TypeError):
491518
sql = "INSERT INTO timetable.parameter(task_id, order_id, value) VALUES (%s, %s, to_jsonb(%s::text))"
492519
params = (task_id, order_id, val)
493-
self.conn.execute_void(sql, params)
520+
status, res = self.conn.execute_void(sql, params)
521+
if not status:
522+
return status, res
523+
return True, None
494524

495525
@check_precondition
496526
def delete(self, gid, sid, chain_id=None):

web/pgadmin/browser/server_groups/servers/pg_timetable/tasks/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,16 @@ def wrap(*args, **kwargs):
201201
self.template_path = 'pgt_chaintask/sql/default'
202202

203203
if 'timetable' not in self.manager.db_info:
204-
_, res = self.conn.execute_dict("""
204+
status, res = self.conn.execute_dict("""
205205
SELECT EXISTS(
206206
SELECT 1 FROM information_schema.columns
207207
WHERE
208208
table_schema='timetable' AND table_name='task' AND
209209
column_name='database_connection'
210210
) has_connstr""")
211211

212+
if not status:
213+
return internal_server_error(errormsg=res)
212214
self.manager.db_info['timetable'] = res['rows'][0]
213215

214216
return f(*args, **kwargs)

web/pgadmin/browser/server_groups/servers/pg_timetable/templates/macros/pgt_chaintask.macros

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
{% macro INSERT(has_connstr, chain_id, data, conn) -%}
22
INSERT INTO timetable.task(
3-
chain_id, task_name, task_order, command, kind, database_connection
3+
chain_id, task_name, task_order, command, kind{% if has_connstr %}, database_connection{% endif %}
44
{% if data.ignore_error is defined %}, ignore_error{% endif %}
55
) VALUES (
66
{{ chain_id|qtLiteral(conn) }}::integer,
77
{{ data.task_name|qtLiteral(conn) }}::text,
88
{{ data.task_order|qtLiteral(conn) }}::integer,
99
{{ data.command|qtLiteral(conn) }}::text,
10-
{{ data.kind|qtLiteral(conn) }}::timetable.command_kind
11-
{% if has_connstr and data.database_connection %},
12-
{{ data.database_connection|qtLiteral(conn) }}::text{% else %}NULL{% endif %}
10+
{{ data.kind|qtLiteral(conn) }}::timetable.command_kind,
11+
{% if has_connstr %}, {% if data.database_connection %}{{ data.database_connection|qtLiteral(conn) }}::text{% else %}NULL{% endif %}{% endif %}
1312
{% if data.ignore_error is defined %},
1413
{% if data.ignore_error %}true{% else %}false{% endif %}{% endif %}
15-
) RETURNING task_id;
14+
) RETURNING task_id
1615
{%- endmacro %}
1716
{% macro UPDATE(has_connstr, chain_id, task_id, data, conn) -%}
1817
{% set has_task_fields = 'task_name' in data or 'task_order' in data or 'command' in data or 'kind' in data or 'ignore_error' in data or 'database_connection' in data %}
@@ -47,20 +46,7 @@ SELECT
4746
t.task_id, t.chain_id, t.task_name, t.task_order,
4847
t.kind::text AS kind,
4948
t.command, t.database_connection, t.ignore_error,
50-
COALESCE(
51-
(
52-
SELECT jsonb_agg(
53-
jsonb_build_object(
54-
'order_id', p.order_id,
55-
'value', p.value #>> '{}'
56-
)
57-
ORDER BY p.order_id
58-
)
59-
FROM timetable.parameter p
60-
WHERE p.task_id = t.task_id
61-
),
62-
'[]'::jsonb
63-
) AS parameters
49+
NULL AS parameters
6450
FROM
6551
timetable.task t
6652
WHERE

web/pgadmin/browser/server_groups/servers/pg_timetable/templates/pgt_chaintask/sql/default/nodes.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
SELECT
22
task_id, chain_id, task_name, task_order,
3-
CASE WHEN kind::text = 'SQL' THEN true ELSE false END AS kind
3+
kind::text AS kind
44
FROM
55
timetable.task
66
WHERE

0 commit comments

Comments
 (0)