Repository navigation
Expand file tree
/
Copy paths45_update_patch.sql
More file actions
110 lines (100 loc) · 5.06 KB
/
Copy paths45_update_patch.sql
File metadata and controls
110 lines (100 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
-- s45_update_patch.sql — v0.5 roadmap T4: generic per-declared-shape update patch.
--
-- An adopter patches a typed instance by its declared properties:
-- (1) patch a DECLARED field (crew_size) — re-seals, number preserved, name unchanged, re-verified;
-- (2) THE KEYSTONE — patching an UNDECLARED field is rejected (undeclared_patch_key);
-- (3) the legacy flat {id, …fields} form still routes to task.update (back-compat).
--
-- Run (booted by the smoke): psql … < s45_update_patch.sql
\set ON_ERROR_STOP 1
CALL ckp.bootstrap_kernel();
DO $setup$
DECLARE g bigint;
BEGIN
g := pgrdf.add_graph('urn:ckp:s45-test/kernel/ck');
PERFORM pgrdf.clear_graph(g);
PERFORM pgrdf.parse_turtle($ttl$
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix ship: <urn:ckp:s45-test/type/> .
@prefix p: <urn:ckp:s45-test/prop/> .
ship:ShipShape a sh:NodeShape ;
sh:targetClass ship:Ship ;
sh:property [ sh:path p:crew_size ; sh:minCount 1 ] ;
sh:property [ sh:path p:name ; sh:minCount 1 ] .
$ttl$, g, 'urn:ckp:s45-test/kernel#');
PERFORM pgrdf.materialize(g);
END $setup$;
-- ring repair for the fixture graph (#48/#49): the setup created it as the calling
-- superuser; the seal's definer path reads it as ck_substrate.
GRANT ALL ON ALL TABLES IN SCHEMA pgrdf TO ck_substrate;
GRANT ALL ON ALL SEQUENCES IN SCHEMA pgrdf TO ck_substrate;
SET ckp.project = 's45-test';
-- 0.4.57 legacy-compat fixture (see s38): the scoped type gate requires the project to declare the legacy board vocabulary its task verbs emit.
DO $bfix$ DECLARE g bigint; BEGIN
g := pgrdf.add_graph('urn:ckp:s45-test/kernel/ck');
PERFORM pgrdf.parse_turtle($bttl$
@prefix sh: <http://www.w3.org/ns/shacl#> .
<urn:ckp:board/Task> a <http://www.w3.org/2000/01/rdf-schema#Class> .
<urn:ckp:board/shape/Task> a sh:NodeShape ;
sh:targetClass <urn:ckp:board/Task> ;
sh:property [ sh:path <urn:ckp:board/task_id> ; sh:minCount 1 ; sh:maxCount 1 ] ;
sh:property [ sh:path <urn:ckp:board/title> ; sh:minCount 1 ; sh:maxCount 1 ] ;
sh:property [ sh:path <urn:ckp:board/target_kernel> ; sh:minCount 1 ; sh:maxCount 1 ] ;
sh:property [ sh:path <urn:ckp:board/part_of_goal> ; sh:minCount 1 ; sh:maxCount 1 ] ;
sh:property [ sh:path <urn:ckp:board/lifecycle_state> ; sh:minCount 1 ; sh:maxCount 1 ] ;
sh:property [ sh:path <urn:ckp:board/created_at> ; sh:minCount 1 ; sh:maxCount 1 ] ;
sh:property [ sh:path <urn:ckp:board/created_by> ; sh:maxCount 1 ] ;
sh:property [ sh:path <urn:ckp:board/priority> ; sh:maxCount 1 ] ;
sh:property [ sh:path <urn:ckp:board/queue_seq> ; sh:maxCount 1 ] .
$bttl$, g, 'urn:ckp:boardfix#');
PERFORM pgrdf.materialize(g);
END $bfix$;
GRANT ALL ON ALL TABLES IN SCHEMA pgrdf TO ck_substrate;
GRANT ALL ON ALL SEQUENCES IN SCHEMA pgrdf TO ck_substrate;
DO $$
DECLARE res jsonb;
BEGIN
SET LOCAL ROLE ck_participant;
res := ckp.dispatch('instance.create','{"type":"urn:ckp:s45-test/type/Ship","name":"Endeavour","crew_size":12}'::jsonb);
RESET ROLE;
IF (res->>'ok') IS DISTINCT FROM 'true' THEN RAISE EXCEPTION 's45 FAIL: create rejected: %', res; END IF;
PERFORM set_config('s45.ship', res->>'id', false);
END $$;
-- (1) patch a DECLARED field — re-seals, number preserved, name unchanged, re-verified.
DO $$
DECLARE res jsonb; b jsonb;
BEGIN
SET LOCAL ROLE ck_participant;
res := ckp.dispatch('instance.update',
jsonb_build_object('id', current_setting('s45.ship'), 'patch', jsonb_build_object('crew_size', 20)));
RESET ROLE;
IF (res->>'ok') IS DISTINCT FROM 'true' THEN RAISE EXCEPTION 's45 FAIL (1): patch rejected: %', res; END IF;
IF (res->>'verified') IS DISTINCT FROM 'true' THEN RAISE EXCEPTION 's45 FAIL (1): not re-verified: %', res; END IF;
SELECT body INTO b FROM ckp.instances WHERE id = current_setting('s45.ship');
IF (b->'urn:ckp:s45-test/prop/crew_size') IS DISTINCT FROM '20'::jsonb THEN
RAISE EXCEPTION 's45 FAIL (1): crew_size not patched to number 20 (declared IRI, type-preserved): %', b; END IF;
IF (b->>'urn:ckp:s45-test/prop/name') <> 'Endeavour' THEN
RAISE EXCEPTION 's45 FAIL (1): name should be unchanged by the crew_size patch: %', b; END IF;
END $$;
-- (2) THE KEYSTONE: patching an UNDECLARED field is rejected.
DO $$
DECLARE res jsonb;
BEGIN
SET LOCAL ROLE ck_participant;
res := ckp.dispatch('instance.update',
jsonb_build_object('id', current_setting('s45.ship'), 'patch', jsonb_build_object('warp_core','x')));
RESET ROLE;
IF res->>'error' <> 'undeclared_patch_key' THEN
RAISE EXCEPTION 's45 FAIL (2): undeclared patch key NOT rejected: %', res; END IF;
END $$;
-- (3) the legacy flat {id, …fields} form still routes to task.update (back-compat).
DO $$
DECLARE r jsonb; res jsonb;
BEGIN
SET LOCAL ROLE ck_participant;
r := ckp.dispatch('instance.create','{"task":{"target_kernel":"s45","title":"orig"}}'::jsonb);
res := ckp.dispatch('instance.update', jsonb_build_object('id', r->>'id', 'title', 'renamed'));
RESET ROLE;
IF (res->>'ok') IS DISTINCT FROM 'true' THEN RAISE EXCEPTION 's45 FAIL (3): legacy flat task.update broke: %', res; END IF;
END $$;
\echo s45_update_patch: PASS