prostgles-server 4.2.487 → 4.2.489
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PubSubManager/init/getDataWatchFunctionQuery.d.ts.map +1 -1
- package/dist/PubSubManager/init/getDataWatchFunctionQuery.js +157 -139
- package/dist/PubSubManager/init/getDataWatchFunctionQuery.js.map +1 -1
- package/dist/PubSubManager/notifListener.d.ts.map +1 -1
- package/dist/PubSubManager/notifListener.js +3 -4
- package/dist/PubSubManager/notifListener.js.map +1 -1
- package/lib/PubSubManager/init/getDataWatchFunctionQuery.ts +158 -139
- package/lib/PubSubManager/notifListener.ts +6 -5
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDataWatchFunctionQuery.d.ts","sourceRoot":"","sources":["../../../lib/PubSubManager/init/getDataWatchFunctionQuery.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,iCAAiC,UAAkB,CAAC;AACjE,eAAO,MAAM,yBAAyB,GAAI,WAAW,OAAO,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"getDataWatchFunctionQuery.d.ts","sourceRoot":"","sources":["../../../lib/PubSubManager/init/getDataWatchFunctionQuery.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,iCAAiC,UAAkB,CAAC;AACjE,eAAO,MAAM,yBAAyB,GAAI,WAAW,OAAO,GAAG,SAAS,WAoGvE,CAAC;AAyPF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
|
|
@@ -14,8 +14,7 @@ const getDataWatchFunctionQuery = (debugMode) => {
|
|
|
14
14
|
|
|
15
15
|
CREATE OR REPLACE FUNCTION ${getPubSubManagerInitQuery_1.DB_OBJ_NAMES.data_watch_func}() RETURNS TRIGGER
|
|
16
16
|
AS $$
|
|
17
|
-
|
|
18
|
-
DECLARE t_ids TEXT[];
|
|
17
|
+
|
|
19
18
|
DECLARE c_ids INTEGER[];
|
|
20
19
|
DECLARE err_c_ids INTEGER[];
|
|
21
20
|
DECLARE condition_checks_union_query TEXT := '';
|
|
@@ -32,125 +31,53 @@ const getDataWatchFunctionQuery = (debugMode) => {
|
|
|
32
31
|
DECLARE escaped_table TEXT;
|
|
33
32
|
|
|
34
33
|
DECLARE _columns_info JSONB := NULL;
|
|
35
|
-
|
|
36
|
-
DECLARE changed_columns _TEXT := NULL;
|
|
34
|
+
DECLARE changed_columns_by_trigger_id JSONB := NULL;
|
|
35
|
+
DECLARE changed_columns _TEXT := NULL;
|
|
37
36
|
|
|
38
37
|
BEGIN
|
|
39
38
|
|
|
40
39
|
escaped_table := concat_ws('.', CASE WHEN TG_TABLE_SCHEMA <> CURRENT_SCHEMA THEN format('%I', TG_TABLE_SCHEMA) END, format('%I', TG_TABLE_NAME));
|
|
41
40
|
|
|
42
|
-
${
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
FROM prostgles.v_triggers
|
|
83
|
-
WHERE table_name = escaped_table
|
|
84
|
-
AND related_view_name IS NOT NULL
|
|
85
|
-
AND related_view_def IS NOT NULL
|
|
86
|
-
) t
|
|
87
|
-
), '')
|
|
88
|
-
||
|
|
89
|
-
format(
|
|
90
|
-
$c$
|
|
91
|
-
SELECT ARRAY_AGG(DISTINCT t.t_id)
|
|
92
|
-
FROM (
|
|
93
|
-
%s
|
|
94
|
-
) t
|
|
95
|
-
$c$,
|
|
96
|
-
condition_checks_union_query
|
|
97
|
-
)
|
|
98
|
-
INTO query;
|
|
99
|
-
|
|
100
|
-
BEGIN
|
|
101
|
-
EXECUTE query INTO t_ids;
|
|
102
|
-
|
|
103
|
-
EXCEPTION WHEN OTHERS THEN
|
|
104
|
-
|
|
105
|
-
has_errors := TRUE;
|
|
106
|
-
|
|
107
|
-
GET STACKED DIAGNOSTICS
|
|
108
|
-
err_text = MESSAGE_TEXT,
|
|
109
|
-
err_detail = PG_EXCEPTION_DETAIL,
|
|
110
|
-
err_hint = PG_EXCEPTION_HINT;
|
|
111
|
-
|
|
112
|
-
END;
|
|
113
|
-
|
|
114
|
-
--RAISE NOTICE 'has_errors: % ', has_errors;
|
|
115
|
-
--RAISE NOTICE 'condition_checks_union_query: % , cids: %', condition_checks_union_query, c_ids;
|
|
116
|
-
|
|
117
|
-
IF (t_ids IS NOT NULL OR has_errors) THEN
|
|
118
|
-
|
|
119
|
-
FOR v_trigger IN
|
|
120
|
-
SELECT app_id, string_agg(c_id::text, ',') as cids
|
|
121
|
-
FROM prostgles.v_triggers
|
|
122
|
-
WHERE id = ANY(t_ids)
|
|
123
|
-
OR has_errors
|
|
124
|
-
GROUP BY app_id
|
|
125
|
-
LOOP
|
|
126
|
-
|
|
127
|
-
PERFORM pg_notify(
|
|
128
|
-
${(0, PubSubManagerUtils_1.asValue)(PubSubManagerUtils_1.NOTIF_CHANNEL.preffix)} || v_trigger.app_id ,
|
|
129
|
-
LEFT(concat_ws(
|
|
130
|
-
${(0, PubSubManagerUtils_1.asValue)(PubSubManagerUtils_1.DELIMITER)},
|
|
131
|
-
|
|
132
|
-
${(0, PubSubManagerUtils_1.asValue)(PubSubManagerUtils_1.NOTIF_TYPE.data)},
|
|
133
|
-
COALESCE(escaped_table, 'MISSING'),
|
|
134
|
-
COALESCE(TG_OP, 'MISSING'),
|
|
135
|
-
CASE WHEN has_errors
|
|
136
|
-
THEN concat_ws('; ', 'error', err_text, err_detail, err_hint, 'query: ' || query )
|
|
137
|
-
ELSE COALESCE(v_trigger.cids, '')
|
|
138
|
-
END,
|
|
139
|
-
COALESCE(changed_columns::TEXT, '')
|
|
140
|
-
${debugMode ? ", COALESCE(current_query(), 'current_query ??'), ' ', query" : ""}
|
|
141
|
-
), 7999/4) -- Some chars are 2bytes -> 'Ω'
|
|
142
|
-
);
|
|
143
|
-
END LOOP;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
IF has_errors THEN
|
|
147
|
-
|
|
148
|
-
DELETE FROM prostgles.app_triggers;
|
|
149
|
-
RAISE NOTICE 'trigger dropped due to exception: % % %', err_text, err_detail, err_hint;
|
|
150
|
-
|
|
151
|
-
END IF;
|
|
152
|
-
|
|
153
|
-
END IF;
|
|
41
|
+
${CHANGED_COLUMNS_FOR_EACH_TRIGGER_CHECK}
|
|
42
|
+
|
|
43
|
+
${EACH_TRIGGER_CHECK_ALL_COLUMNS}
|
|
44
|
+
|
|
45
|
+
IF (c_ids IS NOT NULL OR has_errors) THEN
|
|
46
|
+
|
|
47
|
+
FOR v_trigger IN
|
|
48
|
+
SELECT app_id, string_agg(c_id::text, ',') as cids
|
|
49
|
+
FROM prostgles.v_triggers
|
|
50
|
+
WHERE c_id = ANY(c_ids)
|
|
51
|
+
OR has_errors
|
|
52
|
+
GROUP BY app_id
|
|
53
|
+
LOOP
|
|
54
|
+
|
|
55
|
+
PERFORM pg_notify(
|
|
56
|
+
${(0, PubSubManagerUtils_1.asValue)(PubSubManagerUtils_1.NOTIF_CHANNEL.preffix)} || v_trigger.app_id ,
|
|
57
|
+
LEFT(concat_ws(
|
|
58
|
+
${(0, PubSubManagerUtils_1.asValue)(PubSubManagerUtils_1.DELIMITER)},
|
|
59
|
+
|
|
60
|
+
${(0, PubSubManagerUtils_1.asValue)(PubSubManagerUtils_1.NOTIF_TYPE.data)},
|
|
61
|
+
COALESCE(escaped_table, 'MISSING'),
|
|
62
|
+
COALESCE(TG_OP, 'MISSING'),
|
|
63
|
+
CASE WHEN has_errors
|
|
64
|
+
THEN concat_ws('; ', 'error', err_text, err_detail, err_hint, 'query: ' || query )
|
|
65
|
+
ELSE COALESCE(v_trigger.cids, '')
|
|
66
|
+
END,
|
|
67
|
+
COALESCE(changed_columns_by_trigger_id::TEXT, '')
|
|
68
|
+
${debugMode ? ", COALESCE(current_query(), 'current_query ??'), ' ', query" : ""}
|
|
69
|
+
), 7999/4) -- Some chars are 2bytes -> 'Ω'
|
|
70
|
+
);
|
|
71
|
+
END LOOP;
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
IF has_errors THEN
|
|
75
|
+
|
|
76
|
+
DELETE FROM prostgles.app_triggers;
|
|
77
|
+
RAISE NOTICE 'trigger dropped due to exception: % % %', err_text, err_detail, err_hint;
|
|
78
|
+
|
|
79
|
+
END IF;
|
|
80
|
+
|
|
154
81
|
END IF;
|
|
155
82
|
|
|
156
83
|
${(0, orphanTriggerCheck_1.getAppCheckQuery)()}
|
|
@@ -178,10 +105,7 @@ const getDataWatchFunctionQuery = (debugMode) => {
|
|
|
178
105
|
return dataWatchFunctionQuery;
|
|
179
106
|
};
|
|
180
107
|
exports.getDataWatchFunctionQuery = getDataWatchFunctionQuery;
|
|
181
|
-
|
|
182
|
-
* TODO: check columns for specific t_id trigger conditions
|
|
183
|
-
*/
|
|
184
|
-
const CHANGED_COLUMNS_CHECK = `
|
|
108
|
+
const CHANGED_COLUMNS_FOR_EACH_TRIGGER_CHECK = `
|
|
185
109
|
-- Determine changed columns for UPDATE operations
|
|
186
110
|
IF TG_OP = 'UPDATE' THEN
|
|
187
111
|
|
|
@@ -193,32 +117,36 @@ IF TG_OP = 'UPDATE' THEN
|
|
|
193
117
|
AND columns_info IS NULL
|
|
194
118
|
) THEN
|
|
195
119
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
120
|
+
changed_columns_by_trigger_id := COALESCE(changed_columns_by_trigger_id, '{}');
|
|
121
|
+
|
|
122
|
+
FOR v_trigger IN
|
|
123
|
+
SELECT *
|
|
124
|
+
FROM prostgles.v_triggers
|
|
125
|
+
WHERE table_name = escaped_table
|
|
126
|
+
AND columns_info IS NOT NULL
|
|
127
|
+
LOOP
|
|
128
|
+
|
|
203
129
|
query := format(
|
|
204
130
|
$c$
|
|
205
131
|
WITH changed AS (
|
|
206
132
|
SELECT column_name
|
|
207
|
-
FROM jsonb_object_keys(%L) as column_name
|
|
133
|
+
FROM jsonb_object_keys(%1$L) as column_name
|
|
208
134
|
WHERE EXISTS (
|
|
209
135
|
SELECT 1
|
|
210
|
-
FROM old_table o
|
|
211
|
-
LEFT JOIN new_table n
|
|
212
|
-
ON %s
|
|
213
|
-
WHERE %s
|
|
136
|
+
FROM (SELECT * FROM old_table as %5$I WHERE %4$s ) o
|
|
137
|
+
LEFT JOIN (SELECT * FROM new_table as %5$I WHERE %4$s ) n
|
|
138
|
+
ON %2$s
|
|
139
|
+
WHERE %3$s
|
|
214
140
|
)
|
|
215
141
|
)
|
|
216
142
|
SELECT array_agg(column_name)
|
|
217
143
|
FROM changed;
|
|
218
144
|
$c$,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
145
|
+
v_trigger.columns_info->'tracked_columns',
|
|
146
|
+
v_trigger.columns_info->>'join_condition',
|
|
147
|
+
v_trigger.columns_info->>'where_statement',
|
|
148
|
+
v_trigger.condition,
|
|
149
|
+
TG_TABLE_NAME
|
|
222
150
|
);
|
|
223
151
|
|
|
224
152
|
BEGIN
|
|
@@ -232,17 +160,107 @@ IF TG_OP = 'UPDATE' THEN
|
|
|
232
160
|
err_detail = PG_EXCEPTION_DETAIL,
|
|
233
161
|
err_hint = PG_EXCEPTION_HINT;
|
|
234
162
|
END;
|
|
235
|
-
|
|
163
|
+
|
|
236
164
|
/* It is possible to get no changes */
|
|
237
|
-
changed_columns
|
|
238
|
-
|
|
239
|
-
|
|
165
|
+
IF changed_columns IS NOT NULL THEN
|
|
166
|
+
|
|
167
|
+
changed_columns := COALESCE(changed_columns, '{}');
|
|
168
|
+
changed_columns_by_trigger_id := jsonb_set(
|
|
169
|
+
changed_columns_by_trigger_id,
|
|
170
|
+
ARRAY[v_trigger.c_id::TEXT],
|
|
171
|
+
to_jsonb(changed_columns)
|
|
172
|
+
);
|
|
173
|
+
END IF;
|
|
174
|
+
|
|
175
|
+
--PERFORM pg_notify('debug', changed_columns::TEXT || v_trigger.c_id::TEXT || changed_columns_by_trigger_id::TEXT );
|
|
176
|
+
|
|
177
|
+
END LOOP;
|
|
178
|
+
|
|
240
179
|
|
|
241
180
|
END IF;
|
|
242
181
|
END IF;
|
|
243
182
|
|
|
183
|
+
`;
|
|
184
|
+
const EACH_TRIGGER_CHECK_ALL_COLUMNS = `
|
|
185
|
+
|
|
186
|
+
SELECT string_agg(
|
|
187
|
+
format(
|
|
188
|
+
$c$
|
|
189
|
+
SELECT CASE WHEN EXISTS(
|
|
190
|
+
SELECT 1
|
|
191
|
+
FROM %s
|
|
192
|
+
WHERE %s
|
|
193
|
+
) THEN %s::text END AS c_id
|
|
194
|
+
$c$,
|
|
195
|
+
table_name,
|
|
196
|
+
condition,
|
|
197
|
+
c_id
|
|
198
|
+
),
|
|
199
|
+
E' UNION \n '
|
|
200
|
+
)
|
|
201
|
+
INTO condition_checks_union_query
|
|
202
|
+
FROM prostgles.v_triggers
|
|
203
|
+
WHERE table_name = escaped_table;
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
/* condition_checks_union_query = 'old_table union new_table' or any one of the tables */
|
|
207
|
+
IF condition_checks_union_query IS NOT NULL THEN
|
|
208
|
+
|
|
209
|
+
SELECT
|
|
210
|
+
format(
|
|
211
|
+
E'WITH %I AS (\n %s \n) ',
|
|
212
|
+
TG_TABLE_NAME,
|
|
213
|
+
concat_ws(
|
|
214
|
+
E' UNION ALL \n ',
|
|
215
|
+
CASE WHEN (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN ' SELECT * FROM old_table ' END,
|
|
216
|
+
CASE WHEN (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN ' SELECT * FROM new_table ' END
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
||
|
|
220
|
+
COALESCE((
|
|
221
|
+
SELECT ', ' || string_agg(format(E' %s AS ( \n %s \n ) ', related_view_name, related_view_def), ', ')
|
|
222
|
+
FROM (
|
|
223
|
+
SELECT DISTINCT related_view_name, related_view_def
|
|
224
|
+
FROM prostgles.v_triggers
|
|
225
|
+
WHERE table_name = escaped_table
|
|
226
|
+
AND related_view_name IS NOT NULL
|
|
227
|
+
AND related_view_def IS NOT NULL
|
|
228
|
+
) t
|
|
229
|
+
), '')
|
|
230
|
+
||
|
|
231
|
+
format(
|
|
232
|
+
$c$
|
|
233
|
+
SELECT ARRAY_AGG(DISTINCT t.c_id)
|
|
234
|
+
FROM (
|
|
235
|
+
%s
|
|
236
|
+
) t
|
|
237
|
+
$c$,
|
|
238
|
+
condition_checks_union_query
|
|
239
|
+
)
|
|
240
|
+
INTO query;
|
|
241
|
+
|
|
242
|
+
BEGIN
|
|
243
|
+
EXECUTE query INTO c_ids;
|
|
244
|
+
|
|
245
|
+
EXCEPTION WHEN OTHERS THEN
|
|
246
|
+
|
|
247
|
+
has_errors := TRUE;
|
|
248
|
+
|
|
249
|
+
GET STACKED DIAGNOSTICS
|
|
250
|
+
err_text = MESSAGE_TEXT,
|
|
251
|
+
err_detail = PG_EXCEPTION_DETAIL,
|
|
252
|
+
err_hint = PG_EXCEPTION_HINT;
|
|
253
|
+
|
|
254
|
+
END;
|
|
255
|
+
|
|
256
|
+
--RAISE NOTICE 'has_errors: % ', has_errors;
|
|
257
|
+
--RAISE NOTICE 'condition_checks_union_query: % , cids: %', condition_checks_union_query, c_ids;
|
|
258
|
+
END IF;
|
|
259
|
+
|
|
260
|
+
|
|
244
261
|
`;
|
|
245
262
|
/**
|
|
263
|
+
* TODO: test performance and maybe add as an alternative for cases where there are no join clauses
|
|
246
264
|
* Given:
|
|
247
265
|
* 1. two transition tables (old_table and new_table)
|
|
248
266
|
* 2. a list of primary keys
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDataWatchFunctionQuery.js","sourceRoot":"","sources":["../../../lib/PubSubManager/init/getDataWatchFunctionQuery.ts"],"names":[],"mappings":";;;AAAA,2EAA2D;AAC3D,8DAAyD;AACzD,8DAAsF;AAEtF;;;GAGG;AACU,QAAA,iCAAiC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC1D,MAAM,yBAAyB,GAAG,CAAC,SAA8B,EAAE,EAAE;IAC1E,MAAM,sBAAsB,GAAG;;qCAEI,wCAAY,CAAC,eAAe
|
|
1
|
+
{"version":3,"file":"getDataWatchFunctionQuery.js","sourceRoot":"","sources":["../../../lib/PubSubManager/init/getDataWatchFunctionQuery.ts"],"names":[],"mappings":";;;AAAA,2EAA2D;AAC3D,8DAAyD;AACzD,8DAAsF;AAEtF;;;GAGG;AACU,QAAA,iCAAiC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC1D,MAAM,yBAAyB,GAAG,CAAC,SAA8B,EAAE,EAAE;IAC1E,MAAM,sBAAsB,GAAG;;qCAEI,wCAAY,CAAC,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0B/C,sCAAsC;;kBAEtC,8BAA8B;;;;;;;;;;;;;0BAatB,IAAA,4BAAO,EAAC,kCAAa,CAAC,OAAO,CAAC;;4BAE5B,IAAA,4BAAO,EAAC,8BAAS,CAAC;;4BAElB,IAAA,4BAAO,EAAC,+BAAU,CAAC,IAAI,CAAC;;;;;;;;4BAQxB,SAAS,CAAC,CAAC,CAAC,6DAA6D,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;kBAexF,IAAA,qCAAgB,GAAE;;;;;;;8BAON,wCAAY,CAAC,eAAe;;GAEvD,CAAC;IAEF,2GAA2G;IAC3G,MAAM,UAAU,GAAG,sBAAsB;SACtC,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACpB,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE;QACrC,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACjD,IACE,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YACxC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAC/C,CAAC;YACD,MAAM,IAAI,KAAK,CACb,yJAAyJ,IAAI,EAAE,CAChK,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,sBAAsB,CAAC;AAChC,CAAC,CAAC;AApGW,QAAA,yBAAyB,6BAoGpC;AAEF,MAAM,sCAAsC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2E9C,CAAC;AAEF,MAAM,8BAA8B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6EtC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8EhC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifListener.d.ts","sourceRoot":"","sources":["../../lib/PubSubManager/notifListener.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIrD,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"notifListener.d.ts","sourceRoot":"","sources":["../../lib/PubSubManager/notifListener.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIrD,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,iBA0LjF"}
|
|
@@ -60,9 +60,7 @@ async function notifListener(data) {
|
|
|
60
60
|
throw "notifListener: dataArr length < 3";
|
|
61
61
|
}
|
|
62
62
|
const [_, table_name, op_name, condition_ids_str, raw_changed_columns_str = ""] = dataArr;
|
|
63
|
-
const
|
|
64
|
-
: raw_changed_columns_str === "{}" ? []
|
|
65
|
-
: raw_changed_columns_str.slice(1, -1).split(",");
|
|
63
|
+
const changedColumnsByTriggerId = !raw_changed_columns_str ? undefined : JSON.parse(raw_changed_columns_str);
|
|
66
64
|
const conditionIds = condition_ids_str?.split(",").map((v) => +v);
|
|
67
65
|
if (!table_name) {
|
|
68
66
|
throw "table_name undef";
|
|
@@ -95,7 +93,8 @@ async function notifListener(data) {
|
|
|
95
93
|
if (orphanedTableConditions.length) {
|
|
96
94
|
void this.deleteOrphanedTriggers(new Set(table_name));
|
|
97
95
|
}
|
|
98
|
-
firedTableConditions.map(({ subs, syncs }) => {
|
|
96
|
+
firedTableConditions.map(({ idx, subs, syncs }) => {
|
|
97
|
+
const changedColumns = changedColumnsByTriggerId && (changedColumnsByTriggerId[idx] ?? []);
|
|
99
98
|
(0, PubSubManagerUtils_1.log)("notifListener", subs.map((s) => s.channel_name), syncs.map((s) => s.channel_name));
|
|
100
99
|
syncs.map((s) => {
|
|
101
100
|
void this.syncData(s, undefined, "trigger");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifListener.js","sourceRoot":"","sources":["../../lib/PubSubManager/notifListener.ts"],"names":[],"mappings":";;AAMA,
|
|
1
|
+
{"version":3,"file":"notifListener.js","sourceRoot":"","sources":["../../lib/PubSubManager/notifListener.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,8 +12,7 @@ export const getDataWatchFunctionQuery = (debugMode: boolean | undefined) => {
|
|
|
12
12
|
|
|
13
13
|
CREATE OR REPLACE FUNCTION ${DB_OBJ_NAMES.data_watch_func}() RETURNS TRIGGER
|
|
14
14
|
AS $$
|
|
15
|
-
|
|
16
|
-
DECLARE t_ids TEXT[];
|
|
15
|
+
|
|
17
16
|
DECLARE c_ids INTEGER[];
|
|
18
17
|
DECLARE err_c_ids INTEGER[];
|
|
19
18
|
DECLARE condition_checks_union_query TEXT := '';
|
|
@@ -30,125 +29,53 @@ export const getDataWatchFunctionQuery = (debugMode: boolean | undefined) => {
|
|
|
30
29
|
DECLARE escaped_table TEXT;
|
|
31
30
|
|
|
32
31
|
DECLARE _columns_info JSONB := NULL;
|
|
33
|
-
|
|
34
|
-
DECLARE changed_columns _TEXT := NULL;
|
|
32
|
+
DECLARE changed_columns_by_trigger_id JSONB := NULL;
|
|
33
|
+
DECLARE changed_columns _TEXT := NULL;
|
|
35
34
|
|
|
36
35
|
BEGIN
|
|
37
36
|
|
|
38
37
|
escaped_table := concat_ws('.', CASE WHEN TG_TABLE_SCHEMA <> CURRENT_SCHEMA THEN format('%I', TG_TABLE_SCHEMA) END, format('%I', TG_TABLE_NAME));
|
|
39
38
|
|
|
40
|
-
${
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
FROM prostgles.v_triggers
|
|
81
|
-
WHERE table_name = escaped_table
|
|
82
|
-
AND related_view_name IS NOT NULL
|
|
83
|
-
AND related_view_def IS NOT NULL
|
|
84
|
-
) t
|
|
85
|
-
), '')
|
|
86
|
-
||
|
|
87
|
-
format(
|
|
88
|
-
$c$
|
|
89
|
-
SELECT ARRAY_AGG(DISTINCT t.t_id)
|
|
90
|
-
FROM (
|
|
91
|
-
%s
|
|
92
|
-
) t
|
|
93
|
-
$c$,
|
|
94
|
-
condition_checks_union_query
|
|
95
|
-
)
|
|
96
|
-
INTO query;
|
|
97
|
-
|
|
98
|
-
BEGIN
|
|
99
|
-
EXECUTE query INTO t_ids;
|
|
100
|
-
|
|
101
|
-
EXCEPTION WHEN OTHERS THEN
|
|
102
|
-
|
|
103
|
-
has_errors := TRUE;
|
|
104
|
-
|
|
105
|
-
GET STACKED DIAGNOSTICS
|
|
106
|
-
err_text = MESSAGE_TEXT,
|
|
107
|
-
err_detail = PG_EXCEPTION_DETAIL,
|
|
108
|
-
err_hint = PG_EXCEPTION_HINT;
|
|
109
|
-
|
|
110
|
-
END;
|
|
111
|
-
|
|
112
|
-
--RAISE NOTICE 'has_errors: % ', has_errors;
|
|
113
|
-
--RAISE NOTICE 'condition_checks_union_query: % , cids: %', condition_checks_union_query, c_ids;
|
|
114
|
-
|
|
115
|
-
IF (t_ids IS NOT NULL OR has_errors) THEN
|
|
116
|
-
|
|
117
|
-
FOR v_trigger IN
|
|
118
|
-
SELECT app_id, string_agg(c_id::text, ',') as cids
|
|
119
|
-
FROM prostgles.v_triggers
|
|
120
|
-
WHERE id = ANY(t_ids)
|
|
121
|
-
OR has_errors
|
|
122
|
-
GROUP BY app_id
|
|
123
|
-
LOOP
|
|
124
|
-
|
|
125
|
-
PERFORM pg_notify(
|
|
126
|
-
${asValue(NOTIF_CHANNEL.preffix)} || v_trigger.app_id ,
|
|
127
|
-
LEFT(concat_ws(
|
|
128
|
-
${asValue(DELIMITER)},
|
|
129
|
-
|
|
130
|
-
${asValue(NOTIF_TYPE.data)},
|
|
131
|
-
COALESCE(escaped_table, 'MISSING'),
|
|
132
|
-
COALESCE(TG_OP, 'MISSING'),
|
|
133
|
-
CASE WHEN has_errors
|
|
134
|
-
THEN concat_ws('; ', 'error', err_text, err_detail, err_hint, 'query: ' || query )
|
|
135
|
-
ELSE COALESCE(v_trigger.cids, '')
|
|
136
|
-
END,
|
|
137
|
-
COALESCE(changed_columns::TEXT, '')
|
|
138
|
-
${debugMode ? ", COALESCE(current_query(), 'current_query ??'), ' ', query" : ""}
|
|
139
|
-
), 7999/4) -- Some chars are 2bytes -> 'Ω'
|
|
140
|
-
);
|
|
141
|
-
END LOOP;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
IF has_errors THEN
|
|
145
|
-
|
|
146
|
-
DELETE FROM prostgles.app_triggers;
|
|
147
|
-
RAISE NOTICE 'trigger dropped due to exception: % % %', err_text, err_detail, err_hint;
|
|
148
|
-
|
|
149
|
-
END IF;
|
|
150
|
-
|
|
151
|
-
END IF;
|
|
39
|
+
${CHANGED_COLUMNS_FOR_EACH_TRIGGER_CHECK}
|
|
40
|
+
|
|
41
|
+
${EACH_TRIGGER_CHECK_ALL_COLUMNS}
|
|
42
|
+
|
|
43
|
+
IF (c_ids IS NOT NULL OR has_errors) THEN
|
|
44
|
+
|
|
45
|
+
FOR v_trigger IN
|
|
46
|
+
SELECT app_id, string_agg(c_id::text, ',') as cids
|
|
47
|
+
FROM prostgles.v_triggers
|
|
48
|
+
WHERE c_id = ANY(c_ids)
|
|
49
|
+
OR has_errors
|
|
50
|
+
GROUP BY app_id
|
|
51
|
+
LOOP
|
|
52
|
+
|
|
53
|
+
PERFORM pg_notify(
|
|
54
|
+
${asValue(NOTIF_CHANNEL.preffix)} || v_trigger.app_id ,
|
|
55
|
+
LEFT(concat_ws(
|
|
56
|
+
${asValue(DELIMITER)},
|
|
57
|
+
|
|
58
|
+
${asValue(NOTIF_TYPE.data)},
|
|
59
|
+
COALESCE(escaped_table, 'MISSING'),
|
|
60
|
+
COALESCE(TG_OP, 'MISSING'),
|
|
61
|
+
CASE WHEN has_errors
|
|
62
|
+
THEN concat_ws('; ', 'error', err_text, err_detail, err_hint, 'query: ' || query )
|
|
63
|
+
ELSE COALESCE(v_trigger.cids, '')
|
|
64
|
+
END,
|
|
65
|
+
COALESCE(changed_columns_by_trigger_id::TEXT, '')
|
|
66
|
+
${debugMode ? ", COALESCE(current_query(), 'current_query ??'), ' ', query" : ""}
|
|
67
|
+
), 7999/4) -- Some chars are 2bytes -> 'Ω'
|
|
68
|
+
);
|
|
69
|
+
END LOOP;
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
IF has_errors THEN
|
|
73
|
+
|
|
74
|
+
DELETE FROM prostgles.app_triggers;
|
|
75
|
+
RAISE NOTICE 'trigger dropped due to exception: % % %', err_text, err_detail, err_hint;
|
|
76
|
+
|
|
77
|
+
END IF;
|
|
78
|
+
|
|
152
79
|
END IF;
|
|
153
80
|
|
|
154
81
|
${getAppCheckQuery()}
|
|
@@ -182,10 +109,7 @@ export const getDataWatchFunctionQuery = (debugMode: boolean | undefined) => {
|
|
|
182
109
|
return dataWatchFunctionQuery;
|
|
183
110
|
};
|
|
184
111
|
|
|
185
|
-
|
|
186
|
-
* TODO: check columns for specific t_id trigger conditions
|
|
187
|
-
*/
|
|
188
|
-
const CHANGED_COLUMNS_CHECK = `
|
|
112
|
+
const CHANGED_COLUMNS_FOR_EACH_TRIGGER_CHECK = `
|
|
189
113
|
-- Determine changed columns for UPDATE operations
|
|
190
114
|
IF TG_OP = 'UPDATE' THEN
|
|
191
115
|
|
|
@@ -197,32 +121,36 @@ IF TG_OP = 'UPDATE' THEN
|
|
|
197
121
|
AND columns_info IS NULL
|
|
198
122
|
) THEN
|
|
199
123
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
124
|
+
changed_columns_by_trigger_id := COALESCE(changed_columns_by_trigger_id, '{}');
|
|
125
|
+
|
|
126
|
+
FOR v_trigger IN
|
|
127
|
+
SELECT *
|
|
128
|
+
FROM prostgles.v_triggers
|
|
129
|
+
WHERE table_name = escaped_table
|
|
130
|
+
AND columns_info IS NOT NULL
|
|
131
|
+
LOOP
|
|
132
|
+
|
|
207
133
|
query := format(
|
|
208
134
|
$c$
|
|
209
135
|
WITH changed AS (
|
|
210
136
|
SELECT column_name
|
|
211
|
-
FROM jsonb_object_keys(%L) as column_name
|
|
137
|
+
FROM jsonb_object_keys(%1$L) as column_name
|
|
212
138
|
WHERE EXISTS (
|
|
213
139
|
SELECT 1
|
|
214
|
-
FROM old_table o
|
|
215
|
-
LEFT JOIN new_table n
|
|
216
|
-
ON %s
|
|
217
|
-
WHERE %s
|
|
140
|
+
FROM (SELECT * FROM old_table as %5$I WHERE %4$s ) o
|
|
141
|
+
LEFT JOIN (SELECT * FROM new_table as %5$I WHERE %4$s ) n
|
|
142
|
+
ON %2$s
|
|
143
|
+
WHERE %3$s
|
|
218
144
|
)
|
|
219
145
|
)
|
|
220
146
|
SELECT array_agg(column_name)
|
|
221
147
|
FROM changed;
|
|
222
148
|
$c$,
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
149
|
+
v_trigger.columns_info->'tracked_columns',
|
|
150
|
+
v_trigger.columns_info->>'join_condition',
|
|
151
|
+
v_trigger.columns_info->>'where_statement',
|
|
152
|
+
v_trigger.condition,
|
|
153
|
+
TG_TABLE_NAME
|
|
226
154
|
);
|
|
227
155
|
|
|
228
156
|
BEGIN
|
|
@@ -236,18 +164,109 @@ IF TG_OP = 'UPDATE' THEN
|
|
|
236
164
|
err_detail = PG_EXCEPTION_DETAIL,
|
|
237
165
|
err_hint = PG_EXCEPTION_HINT;
|
|
238
166
|
END;
|
|
239
|
-
|
|
167
|
+
|
|
240
168
|
/* It is possible to get no changes */
|
|
241
|
-
changed_columns
|
|
242
|
-
|
|
243
|
-
|
|
169
|
+
IF changed_columns IS NOT NULL THEN
|
|
170
|
+
|
|
171
|
+
changed_columns := COALESCE(changed_columns, '{}');
|
|
172
|
+
changed_columns_by_trigger_id := jsonb_set(
|
|
173
|
+
changed_columns_by_trigger_id,
|
|
174
|
+
ARRAY[v_trigger.c_id::TEXT],
|
|
175
|
+
to_jsonb(changed_columns)
|
|
176
|
+
);
|
|
177
|
+
END IF;
|
|
178
|
+
|
|
179
|
+
--PERFORM pg_notify('debug', changed_columns::TEXT || v_trigger.c_id::TEXT || changed_columns_by_trigger_id::TEXT );
|
|
180
|
+
|
|
181
|
+
END LOOP;
|
|
182
|
+
|
|
244
183
|
|
|
245
184
|
END IF;
|
|
246
185
|
END IF;
|
|
247
186
|
|
|
187
|
+
`;
|
|
188
|
+
|
|
189
|
+
const EACH_TRIGGER_CHECK_ALL_COLUMNS = `
|
|
190
|
+
|
|
191
|
+
SELECT string_agg(
|
|
192
|
+
format(
|
|
193
|
+
$c$
|
|
194
|
+
SELECT CASE WHEN EXISTS(
|
|
195
|
+
SELECT 1
|
|
196
|
+
FROM %s
|
|
197
|
+
WHERE %s
|
|
198
|
+
) THEN %s::text END AS c_id
|
|
199
|
+
$c$,
|
|
200
|
+
table_name,
|
|
201
|
+
condition,
|
|
202
|
+
c_id
|
|
203
|
+
),
|
|
204
|
+
E' UNION \n '
|
|
205
|
+
)
|
|
206
|
+
INTO condition_checks_union_query
|
|
207
|
+
FROM prostgles.v_triggers
|
|
208
|
+
WHERE table_name = escaped_table;
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
/* condition_checks_union_query = 'old_table union new_table' or any one of the tables */
|
|
212
|
+
IF condition_checks_union_query IS NOT NULL THEN
|
|
213
|
+
|
|
214
|
+
SELECT
|
|
215
|
+
format(
|
|
216
|
+
E'WITH %I AS (\n %s \n) ',
|
|
217
|
+
TG_TABLE_NAME,
|
|
218
|
+
concat_ws(
|
|
219
|
+
E' UNION ALL \n ',
|
|
220
|
+
CASE WHEN (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN ' SELECT * FROM old_table ' END,
|
|
221
|
+
CASE WHEN (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN ' SELECT * FROM new_table ' END
|
|
222
|
+
)
|
|
223
|
+
)
|
|
224
|
+
||
|
|
225
|
+
COALESCE((
|
|
226
|
+
SELECT ', ' || string_agg(format(E' %s AS ( \n %s \n ) ', related_view_name, related_view_def), ', ')
|
|
227
|
+
FROM (
|
|
228
|
+
SELECT DISTINCT related_view_name, related_view_def
|
|
229
|
+
FROM prostgles.v_triggers
|
|
230
|
+
WHERE table_name = escaped_table
|
|
231
|
+
AND related_view_name IS NOT NULL
|
|
232
|
+
AND related_view_def IS NOT NULL
|
|
233
|
+
) t
|
|
234
|
+
), '')
|
|
235
|
+
||
|
|
236
|
+
format(
|
|
237
|
+
$c$
|
|
238
|
+
SELECT ARRAY_AGG(DISTINCT t.c_id)
|
|
239
|
+
FROM (
|
|
240
|
+
%s
|
|
241
|
+
) t
|
|
242
|
+
$c$,
|
|
243
|
+
condition_checks_union_query
|
|
244
|
+
)
|
|
245
|
+
INTO query;
|
|
246
|
+
|
|
247
|
+
BEGIN
|
|
248
|
+
EXECUTE query INTO c_ids;
|
|
249
|
+
|
|
250
|
+
EXCEPTION WHEN OTHERS THEN
|
|
251
|
+
|
|
252
|
+
has_errors := TRUE;
|
|
253
|
+
|
|
254
|
+
GET STACKED DIAGNOSTICS
|
|
255
|
+
err_text = MESSAGE_TEXT,
|
|
256
|
+
err_detail = PG_EXCEPTION_DETAIL,
|
|
257
|
+
err_hint = PG_EXCEPTION_HINT;
|
|
258
|
+
|
|
259
|
+
END;
|
|
260
|
+
|
|
261
|
+
--RAISE NOTICE 'has_errors: % ', has_errors;
|
|
262
|
+
--RAISE NOTICE 'condition_checks_union_query: % , cids: %', condition_checks_union_query, c_ids;
|
|
263
|
+
END IF;
|
|
264
|
+
|
|
265
|
+
|
|
248
266
|
`;
|
|
249
267
|
|
|
250
268
|
/**
|
|
269
|
+
* TODO: test performance and maybe add as an alternative for cases where there are no join clauses
|
|
251
270
|
* Given:
|
|
252
271
|
* 1. two transition tables (old_table and new_table)
|
|
253
272
|
* 2. a list of primary keys
|
|
@@ -69,10 +69,10 @@ export async function notifListener(this: PubSubManager, data: { payload: string
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
const [_, table_name, op_name, condition_ids_str, raw_changed_columns_str = ""] = dataArr;
|
|
72
|
-
const
|
|
73
|
-
!raw_changed_columns_str ? undefined
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
const changedColumnsByTriggerId =
|
|
73
|
+
!raw_changed_columns_str ? undefined : (
|
|
74
|
+
(JSON.parse(raw_changed_columns_str) as Record<string, string[]>)
|
|
75
|
+
);
|
|
76
76
|
const conditionIds = condition_ids_str?.split(",").map((v) => +v);
|
|
77
77
|
|
|
78
78
|
if (!table_name) {
|
|
@@ -111,7 +111,8 @@ export async function notifListener(this: PubSubManager, data: { payload: string
|
|
|
111
111
|
void this.deleteOrphanedTriggers(new Set(table_name));
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
firedTableConditions.map(({ subs, syncs }) => {
|
|
114
|
+
firedTableConditions.map(({ idx, subs, syncs }) => {
|
|
115
|
+
const changedColumns = changedColumnsByTriggerId && (changedColumnsByTriggerId[idx] ?? []);
|
|
115
116
|
log(
|
|
116
117
|
"notifListener",
|
|
117
118
|
subs.map((s) => s.channel_name),
|