dzql 0.5.28 → 0.5.29
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
|
@@ -129,6 +129,8 @@ export class SubscribableParser {
|
|
|
129
129
|
*/
|
|
130
130
|
_cleanString(str) {
|
|
131
131
|
if (!str) return '';
|
|
132
|
+
// Handle SQL NULL keyword - return empty string for null values
|
|
133
|
+
if (str.trim().toUpperCase() === 'NULL') return '';
|
|
132
134
|
// Remove outer quotes, SQL comments, then any remaining quotes and whitespace
|
|
133
135
|
let cleaned = str.replace(/^['"]|['"]$/g, ''); // Remove outer quotes
|
|
134
136
|
cleaned = cleaned.replace(/--[^\n]*/g, ''); // Remove SQL comments
|
|
@@ -11,7 +11,7 @@ CREATE TABLE IF NOT EXISTS dzql.subscribables (
|
|
|
11
11
|
name TEXT PRIMARY KEY,
|
|
12
12
|
permission_paths JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
13
13
|
param_schema JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
14
|
-
root_entity TEXT
|
|
14
|
+
root_entity TEXT, -- NULL allowed for dashboard mode (pure collections)
|
|
15
15
|
relations JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
16
16
|
scope_tables TEXT[] NOT NULL DEFAULT '{}',
|
|
17
17
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
@@ -31,7 +31,7 @@ COMMENT ON COLUMN dzql.subscribables.param_schema IS
|
|
|
31
31
|
'Parameter schema defining subscription key (e.g., {"venue_id": "int"})';
|
|
32
32
|
|
|
33
33
|
COMMENT ON COLUMN dzql.subscribables.root_entity IS
|
|
34
|
-
'Root table for the subscribable document';
|
|
34
|
+
'Root table for the subscribable document. NULL for dashboard mode (pure collections).';
|
|
35
35
|
|
|
36
36
|
COMMENT ON COLUMN dzql.subscribables.relations IS
|
|
37
37
|
'Related entities to include (e.g., {"org": "organisations", "sites": {"entity": "sites", "filter": "venue_id=$venue_id"}})';
|
|
@@ -16,8 +16,12 @@ DECLARE
|
|
|
16
16
|
v_entity TEXT;
|
|
17
17
|
v_nested JSONB;
|
|
18
18
|
BEGIN
|
|
19
|
-
-- Start with root entity
|
|
20
|
-
|
|
19
|
+
-- Start with root entity (may be NULL for dashboard mode)
|
|
20
|
+
IF p_root_entity IS NOT NULL AND p_root_entity != '' THEN
|
|
21
|
+
v_tables := ARRAY[p_root_entity];
|
|
22
|
+
ELSE
|
|
23
|
+
v_tables := ARRAY[]::TEXT[];
|
|
24
|
+
END IF;
|
|
21
25
|
|
|
22
26
|
-- Return early if no relations
|
|
23
27
|
IF p_relations IS NULL OR p_relations = '{}'::jsonb THEN
|
|
@@ -85,8 +89,11 @@ BEGIN
|
|
|
85
89
|
RAISE EXCEPTION 'Subscribable name cannot be empty';
|
|
86
90
|
END IF;
|
|
87
91
|
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
-- NULL root_entity is allowed for dashboard mode (pure collections)
|
|
93
|
+
-- But if relations is also empty, that's an error
|
|
94
|
+
IF (p_root_entity IS NULL OR p_root_entity = '') AND
|
|
95
|
+
(p_relations IS NULL OR p_relations = '{}'::jsonb) THEN
|
|
96
|
+
RAISE EXCEPTION 'Subscribable must have either a root entity or relations';
|
|
90
97
|
END IF;
|
|
91
98
|
|
|
92
99
|
-- Extract scope tables from root entity and relations
|
|
@@ -106,7 +113,7 @@ BEGIN
|
|
|
106
113
|
p_name,
|
|
107
114
|
COALESCE(p_permission_paths, '{}'::jsonb),
|
|
108
115
|
COALESCE(p_param_schema, '{}'::jsonb),
|
|
109
|
-
p_root_entity,
|
|
116
|
+
NULLIF(p_root_entity, ''), -- Store empty string as NULL
|
|
110
117
|
COALESCE(p_relations, '{}'::jsonb),
|
|
111
118
|
v_scope_tables,
|
|
112
119
|
NOW(),
|