dzql 0.5.26 → 0.5.27
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
|
@@ -247,6 +247,38 @@ $$ LANGUAGE plpgsql STABLE SECURITY DEFINER;`;
|
|
|
247
247
|
scopeTables: scopeTables
|
|
248
248
|
});
|
|
249
249
|
|
|
250
|
+
// Dashboard mode: empty paramSchema means aggregate root as array
|
|
251
|
+
if (params.length === 0) {
|
|
252
|
+
return `CREATE OR REPLACE FUNCTION get_${this.name}(
|
|
253
|
+
p_params JSONB,
|
|
254
|
+
p_user_id INT
|
|
255
|
+
) RETURNS JSONB AS $$
|
|
256
|
+
DECLARE
|
|
257
|
+
v_data JSONB;
|
|
258
|
+
BEGIN
|
|
259
|
+
-- Check access control
|
|
260
|
+
IF NOT ${this.name}_can_subscribe(p_user_id, p_params) THEN
|
|
261
|
+
RAISE EXCEPTION 'Permission denied';
|
|
262
|
+
END IF;
|
|
263
|
+
|
|
264
|
+
-- Build document with root as array (dashboard mode)
|
|
265
|
+
SELECT jsonb_build_object(
|
|
266
|
+
'${this.rootEntity}', COALESCE((
|
|
267
|
+
SELECT jsonb_agg(row_to_json(root.*))
|
|
268
|
+
FROM ${this.rootEntity} root
|
|
269
|
+
), '[]'::jsonb)${relationSelects}
|
|
270
|
+
)
|
|
271
|
+
INTO v_data;
|
|
272
|
+
|
|
273
|
+
-- Return data with embedded schema for atomic updates
|
|
274
|
+
RETURN jsonb_build_object(
|
|
275
|
+
'data', v_data,
|
|
276
|
+
'schema', '${schemaJson}'::jsonb
|
|
277
|
+
);
|
|
278
|
+
END;
|
|
279
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER;`;
|
|
280
|
+
}
|
|
281
|
+
|
|
250
282
|
return `CREATE OR REPLACE FUNCTION get_${this.name}(
|
|
251
283
|
p_params JSONB,
|
|
252
284
|
p_user_id INT
|
|
@@ -478,13 +510,19 @@ $$ LANGUAGE plpgsql SECURITY DEFINER;`;
|
|
|
478
510
|
*/
|
|
479
511
|
_generateAffectedDocumentsFunction() {
|
|
480
512
|
const cases = [];
|
|
513
|
+
const seenEntities = new Set();
|
|
481
514
|
|
|
482
515
|
// Case 1: Root entity changed
|
|
483
516
|
cases.push(this._generateRootAffectedCase());
|
|
517
|
+
seenEntities.add(this.rootEntity);
|
|
484
518
|
|
|
485
|
-
// Case 2: Related entities changed
|
|
519
|
+
// Case 2: Related entities changed (skip duplicates)
|
|
486
520
|
for (const [relName, relConfig] of Object.entries(this.relations)) {
|
|
487
|
-
|
|
521
|
+
const relEntity = typeof relConfig === 'string' ? relConfig : relConfig.entity;
|
|
522
|
+
if (!seenEntities.has(relEntity)) {
|
|
523
|
+
cases.push(this._generateRelationAffectedCase(relName, relConfig));
|
|
524
|
+
seenEntities.add(relEntity);
|
|
525
|
+
}
|
|
488
526
|
}
|
|
489
527
|
|
|
490
528
|
const casesSQL = cases.join('\n\n ');
|
|
@@ -515,7 +553,15 @@ $$ LANGUAGE plpgsql IMMUTABLE;`;
|
|
|
515
553
|
*/
|
|
516
554
|
_generateRootAffectedCase() {
|
|
517
555
|
const params = Object.keys(this.paramSchema);
|
|
518
|
-
|
|
556
|
+
|
|
557
|
+
// Dashboard mode: empty paramSchema means notify ALL subscribers
|
|
558
|
+
if (params.length === 0) {
|
|
559
|
+
return `-- Root entity (${this.rootEntity}) changed - dashboard mode, notify all
|
|
560
|
+
WHEN '${this.rootEntity}' THEN
|
|
561
|
+
v_affected := ARRAY['{}'::jsonb];`;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const firstParam = params[0];
|
|
519
565
|
|
|
520
566
|
return `-- Root entity (${this.rootEntity}) changed
|
|
521
567
|
WHEN '${this.rootEntity}' THEN
|