dzql 0.1.2 → 0.1.4

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.
@@ -1,6 +1,90 @@
1
1
  -- DZQL Entity Management - Version 3.0.0
2
2
  -- Entity registration, API functions creation, and graph rules execution
3
3
 
4
+ -- ============================================================================
5
+ -- DYNAMIC TRIGGER CREATION (for "execution": "trigger" actions)
6
+ -- ============================================================================
7
+
8
+ CREATE OR REPLACE FUNCTION dzql.create_event_trigger(
9
+ p_table_name text,
10
+ p_trigger_op text, -- 'on_create', 'on_update', 'on_delete'
11
+ p_action_config jsonb
12
+ ) RETURNS void
13
+ LANGUAGE plpgsql AS $$
14
+ DECLARE
15
+ l_trigger_name text;
16
+ l_function_name text;
17
+ l_target_function text;
18
+ l_params jsonb;
19
+ l_param_key text;
20
+ l_param_value text;
21
+ l_param_list text[];
22
+ l_record_ref text;
23
+ l_sql text;
24
+ BEGIN
25
+ l_target_function := p_action_config->>'function';
26
+ l_params := p_action_config->'params';
27
+
28
+ -- Determine if we should use NEW or OLD record
29
+ IF p_trigger_op = 'on_delete' THEN
30
+ l_record_ref := 'OLD';
31
+ ELSE
32
+ l_record_ref := 'NEW';
33
+ END IF;
34
+
35
+ -- Construct the parameter list for the function call
36
+ l_param_list := array[]::text[];
37
+ IF l_params IS NOT NULL THEN
38
+ FOR l_param_key, l_param_value IN SELECT * FROM jsonb_each_text(l_params)
39
+ LOOP
40
+ -- e.g., p_streak_id => NEW.streak_id
41
+ l_param_list := l_param_list || format('%I => %s.%I', l_param_key, l_record_ref, right(l_param_value, -1));
42
+ END LOOP;
43
+ END IF;
44
+
45
+ -- Generate unique names for the trigger and its function
46
+ l_function_name := format('dzql_trigger_%s_%s_%s', p_table_name, p_trigger_op, l_target_function);
47
+ l_trigger_name := format('dzql_managed_%s_%s', p_table_name, p_trigger_op);
48
+
49
+ -- Create the trigger function
50
+ l_sql := format(
51
+ $SQL$
52
+ CREATE OR REPLACE FUNCTION %I()
53
+ RETURNS TRIGGER AS $trigger_func$
54
+ BEGIN
55
+ PERFORM %I(%s);
56
+ RETURN NULL; -- Result is ignored for AFTER trigger
57
+ END;
58
+ $trigger_func$ LANGUAGE plpgsql;
59
+ $SQL$,
60
+ l_function_name,
61
+ l_target_function,
62
+ array_to_string(l_param_list, ', ')
63
+ );
64
+ EXECUTE l_sql;
65
+
66
+ -- Create the trigger
67
+ l_sql := format(
68
+ $SQL$
69
+ DROP TRIGGER IF EXISTS %I ON %I;
70
+ CREATE TRIGGER %I
71
+ AFTER %s ON %I
72
+ FOR EACH ROW
73
+ EXECUTE FUNCTION %I();
74
+ $SQL$,
75
+ l_trigger_name, p_table_name,
76
+ l_trigger_name,
77
+ CASE p_trigger_op WHEN 'on_create' THEN 'INSERT' WHEN 'on_update' THEN 'UPDATE' ELSE 'DELETE' END,
78
+ p_table_name,
79
+ l_function_name
80
+ );
81
+ EXECUTE l_sql;
82
+
83
+ RAISE NOTICE 'DZQL: Created trigger % on % for % event', l_trigger_name, p_table_name, p_trigger_op;
84
+ END;
85
+ $$;
86
+
87
+
4
88
  -- ============================================================================
5
89
  -- GRAPH RULES EXECUTION ENGINE
6
90
  -- ============================================================================
@@ -326,6 +410,11 @@ BEGIN
326
410
  -- Execute each action in the rule
327
411
  FOR l_action IN SELECT * FROM jsonb_array_elements(l_rule_config->'actions')
328
412
  LOOP
413
+ -- If action is handled by a native trigger, skip it in the immediate executor
414
+ IF l_action->>'execution' = 'trigger' THEN
415
+ CONTINUE;
416
+ END IF;
417
+
329
418
  l_action_type := l_action->>'type';
330
419
 
331
420
  -- Execute the action based on type
@@ -493,6 +582,11 @@ CREATE OR REPLACE FUNCTION dzql.register_entity(
493
582
  p_graph_rules jsonb DEFAULT '{}'
494
583
  ) RETURNS void
495
584
  LANGUAGE plpgsql AS $$
585
+ DECLARE
586
+ l_trigger_op text;
587
+ l_rule_name text;
588
+ l_rule_config jsonb;
589
+ l_action jsonb;
496
590
  BEGIN
497
591
  -- Validate permission paths if provided
498
592
  IF p_permission_paths IS NOT NULL AND p_permission_paths != '{}' THEN
@@ -526,6 +620,24 @@ BEGIN
526
620
  -- Create API functions for this entity
527
621
  PERFORM dzql.create_entity_functions(p_table_name);
528
622
 
623
+ -- Create managed triggers for any 'execution: trigger' actions
624
+ IF p_graph_rules IS NOT NULL AND p_graph_rules != '{}' THEN
625
+ FOREACH l_trigger_op IN ARRAY ARRAY['on_create', 'on_update', 'on_delete']
626
+ LOOP
627
+ IF p_graph_rules ? l_trigger_op THEN
628
+ FOR l_rule_name, l_rule_config IN SELECT * FROM jsonb_each(p_graph_rules->l_trigger_op)
629
+ LOOP
630
+ FOR l_action IN SELECT * FROM jsonb_array_elements(l_rule_config->'actions')
631
+ LOOP
632
+ IF l_action->>'execution' = 'trigger' THEN
633
+ PERFORM dzql.create_event_trigger(p_table_name, l_trigger_op, l_action);
634
+ END IF;
635
+ END LOOP;
636
+ END LOOP;
637
+ END IF;
638
+ END LOOP;
639
+ END IF;
640
+
529
641
  -- Log successful registration
530
642
  RAISE NOTICE 'DZQL: Entity % registered successfully with graph rules support', p_table_name;
531
643
  END $$;