Skip to content

Commit 100612b

Browse files
authored
Merge pull request #20425 from jdavcs/25.0_trigger
[25.0] Update triggers
2 parents db86596 + b24d8ae commit 100612b

File tree

5 files changed

+90
-174
lines changed

5 files changed

+90
-174
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""Update postgresql trigger to use clock_timestamp function
2+
3+
NOTE: This migration will not be applied on SQLIte.
4+
5+
Revision ID: a91ea1d97111
6+
Revises: f070559879f1
7+
Create Date: 2025-06-09 12:21:53.427419
8+
9+
"""
10+
11+
from alembic import op
12+
13+
from galaxy.model.migrations.util import _is_sqlite
14+
15+
# revision identifiers, used by Alembic.
16+
revision = "a91ea1d97111"
17+
down_revision = "f070559879f1"
18+
branch_labels = None
19+
depends_on = None
20+
21+
22+
def upgrade():
23+
if not _is_sqlite():
24+
create_functions_and_triggers("clock_timestamp()")
25+
26+
27+
def downgrade():
28+
if not _is_sqlite():
29+
create_functions_and_triggers("CURRENT_TIMESTAMP")
30+
31+
32+
def create_functions_and_triggers(timestamp):
33+
version_info = op.get_bind().engine.dialect.server_version_info
34+
# For offline mode (version_info is None), we assume that version > 10
35+
if version_info and version_info[0] > 10 or not version_info:
36+
trigger_fn = statement_trigger_fn
37+
else:
38+
trigger_fn = row_trigger_fn
39+
40+
for id_field in ["history_id", "id"]:
41+
function_name = f"fn_audit_history_by_{id_field}"
42+
stmt = trigger_fn(function_name, id_field, timestamp)
43+
op.execute(stmt)
44+
45+
46+
def statement_trigger_fn(function_name, id_field, timestamp):
47+
return f"""
48+
CREATE OR REPLACE FUNCTION {function_name}()
49+
RETURNS TRIGGER
50+
LANGUAGE 'plpgsql'
51+
AS $BODY$
52+
BEGIN
53+
INSERT INTO history_audit (history_id, update_time)
54+
SELECT DISTINCT {id_field}, {timestamp} AT TIME ZONE 'UTC'
55+
FROM new_table
56+
WHERE {id_field} IS NOT NULL
57+
ON CONFLICT DO NOTHING;
58+
RETURN NULL;
59+
END;
60+
$BODY$
61+
"""
62+
63+
64+
def row_trigger_fn(function_name, id_field, timestamp):
65+
return f"""
66+
CREATE OR REPLACE FUNCTION {function_name}()
67+
RETURNS TRIGGER
68+
LANGUAGE 'plpgsql'
69+
AS $BODY$
70+
BEGIN
71+
INSERT INTO history_audit (history_id, update_time)
72+
VALUES (NEW.{id_field}, {timestamp} AT TIME ZONE 'UTC')
73+
ON CONFLICT DO NOTHING;
74+
RETURN NULL;
75+
END;
76+
$BODY$
77+
"""

lib/galaxy/model/migrations/dbscript.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
"24.1": "04288b6a5b25",
4747
"release_24.2": "a4c3ef999ab5",
4848
"24.2": "a4c3ef999ab5",
49-
"release_25.0": "f070559879f1",
50-
"25.0": "f070559879f1",
49+
"release_25.0": "a91ea1d97111",
50+
"25.0": "a91ea1d97111",
5151
}
5252

5353

lib/galaxy/model/triggers/history_update_time_field.py

Lines changed: 0 additions & 160 deletions
This file was deleted.

lib/galaxy/model/triggers/update_audit_table.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from galaxy.model.triggers.utils import execute_statements
1+
from sqlalchemy import DDL
22

33
# function name prefix
44
fn_prefix = "fn_audit_history_by"
@@ -56,7 +56,7 @@ def statement_trigger_fn(id_field):
5656
AS $BODY$
5757
BEGIN
5858
INSERT INTO history_audit (history_id, update_time)
59-
SELECT DISTINCT {id_field}, CURRENT_TIMESTAMP AT TIME ZONE 'UTC'
59+
SELECT DISTINCT {id_field}, clock_timestamp() AT TIME ZONE 'UTC'
6060
FROM new_table
6161
WHERE {id_field} IS NOT NULL
6262
ON CONFLICT DO NOTHING;
@@ -75,7 +75,7 @@ def row_trigger_fn(id_field):
7575
AS $BODY$
7676
BEGIN
7777
INSERT INTO history_audit (history_id, update_time)
78-
VALUES (NEW.{id_field}, CURRENT_TIMESTAMP AT TIME ZONE 'UTC')
78+
VALUES (NEW.{id_field}, clock_timestamp() AT TIME ZONE 'UTC')
7979
ON CONFLICT DO NOTHING;
8080
RETURN NULL;
8181
END;
@@ -174,3 +174,11 @@ def get_trigger_name(label, operation, when, statement=False):
174174
when_initial = when.lower()[0]
175175
rs = "s" if statement else "r"
176176
return f"trigger_{label}_{when_initial}{op_initial}{rs}"
177+
178+
179+
def execute_statements(engine, raw_sql):
180+
statements = raw_sql if isinstance(raw_sql, list) else [raw_sql]
181+
with engine.begin() as connection:
182+
for sql in statements:
183+
cmd = DDL(sql)
184+
connection.execute(cmd)

lib/galaxy/model/triggers/utils.py

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)