dzql 0.5.16 → 0.5.18
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/package.json
CHANGED
|
@@ -318,7 +318,7 @@ $$ LANGUAGE plpgsql SECURITY DEFINER;`;
|
|
|
318
318
|
if (relIncludes) {
|
|
319
319
|
const nestedFields = Object.entries(relIncludes).map(([nestedName, nestedEntity]) => {
|
|
320
320
|
return `'${nestedName}', (
|
|
321
|
-
SELECT jsonb_agg(row_to_json(nested.*))
|
|
321
|
+
SELECT COALESCE(jsonb_agg(row_to_json(nested.*)), '[]'::jsonb)
|
|
322
322
|
FROM ${nestedEntity} nested
|
|
323
323
|
WHERE nested.${relEntity}_id = rel.id
|
|
324
324
|
)`;
|
|
@@ -334,23 +334,23 @@ $$ LANGUAGE plpgsql SECURITY DEFINER;`;
|
|
|
334
334
|
if (relVia) {
|
|
335
335
|
const { joinClause, whereClause } = this._generateViaJoin(relConfig);
|
|
336
336
|
return `,
|
|
337
|
-
'${relName}', (
|
|
337
|
+
'${relName}', COALESCE((
|
|
338
338
|
SELECT jsonb_agg(${nestedSelect})
|
|
339
339
|
FROM ${relEntity} rel
|
|
340
340
|
${joinClause}
|
|
341
341
|
WHERE ${whereClause}
|
|
342
|
-
)`;
|
|
342
|
+
), '[]'::jsonb)`;
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
// Direct relation (no via)
|
|
346
346
|
let filterSQL = this._generateRelationFilter(relFilter, relEntity, relConfig);
|
|
347
347
|
|
|
348
348
|
return `,
|
|
349
|
-
'${relName}', (
|
|
349
|
+
'${relName}', COALESCE((
|
|
350
350
|
SELECT jsonb_agg(${nestedSelect})
|
|
351
351
|
FROM ${relEntity} rel
|
|
352
352
|
WHERE ${filterSQL}
|
|
353
|
-
)`;
|
|
353
|
+
), '[]'::jsonb)`;
|
|
354
354
|
}).join('');
|
|
355
355
|
|
|
356
356
|
return selects;
|
package/src/server/index.js
CHANGED
|
@@ -18,6 +18,23 @@ export { createMCPRoute } from "./mcp.js";
|
|
|
18
18
|
async function processSubscriptionUpdates(event, broadcast) {
|
|
19
19
|
const { table, op, pk, data } = event;
|
|
20
20
|
|
|
21
|
+
// Map data to p_old/p_new based on operation type
|
|
22
|
+
// INSERT: new data only, UPDATE: both (we only have current), DELETE: old data only
|
|
23
|
+
let p_old = null;
|
|
24
|
+
let p_new = null;
|
|
25
|
+
switch (op.toUpperCase()) {
|
|
26
|
+
case 'INSERT':
|
|
27
|
+
p_new = data;
|
|
28
|
+
break;
|
|
29
|
+
case 'UPDATE':
|
|
30
|
+
p_old = data;
|
|
31
|
+
p_new = data;
|
|
32
|
+
break;
|
|
33
|
+
case 'DELETE':
|
|
34
|
+
p_old = data;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
|
|
21
38
|
// Get all active subscriptions grouped by subscribable
|
|
22
39
|
const subscriptionsByName = getSubscriptionsBySubscribable();
|
|
23
40
|
|
|
@@ -39,10 +56,9 @@ async function processSubscriptionUpdates(event, broadcast) {
|
|
|
39
56
|
}
|
|
40
57
|
|
|
41
58
|
// Ask PostgreSQL which subscription instances are affected
|
|
42
|
-
// Pass data for both old/new - COALESCE in the function handles it
|
|
43
59
|
const result = await sql.unsafe(
|
|
44
60
|
`SELECT ${subscribableName}_affected_documents($1, $2, $3, $4) as affected`,
|
|
45
|
-
[table, op,
|
|
61
|
+
[table, op, p_old, p_new]
|
|
46
62
|
);
|
|
47
63
|
|
|
48
64
|
const affectedParamSets = result[0]?.affected;
|