Skip to content

Commit 21b378d

Browse files
committed
eng-1475 sync relations including imported node
1 parent 6aa3c39 commit 21b378d

6 files changed

Lines changed: 179 additions & 25 deletions

File tree

apps/obsidian/src/utils/conceptConversion.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,6 @@ export const relationInstanceToLocalConcept = ({
231231
return null;
232232
}
233233

234-
if (
235-
sourceNode.frontmatter.importedFromRid ||
236-
destinationNode.frontmatter.importedFromRid
237-
)
238-
return null; // punt relation to imported nodes for now.
239-
// otherwise put the importedFromRid in source, dest.
240-
241234
/* eslint-disable @typescript-eslint/naming-convention */
242235
const literal_content: Record<string, Json> = {};
243236
if (importedFromRid) literal_content.importedFromRid = importedFromRid;
@@ -252,8 +245,12 @@ export const relationInstanceToLocalConcept = ({
252245
last_modified: new Date(lastModified ?? created).toISOString(),
253246
literal_content,
254247
local_reference_content: {
255-
source,
256-
destination,
248+
source:
249+
(sourceNode.frontmatter.importedFromRid as string | undefined) ??
250+
source,
251+
destination:
252+
(destinationNode.frontmatter.importedFromRid as string | undefined) ??
253+
destination,
257254
},
258255
/* eslint-enable @typescript-eslint/naming-convention */
259256
};

apps/obsidian/src/utils/publishNode.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ export const publishNodeRelations = async ({
182182
(fm.publishedToGroups as string[]) || [];
183183
if (!publishedToGroups.includes(myGroup)) return;
184184
}
185-
if (fm.importedFromRid) return; // temporary, should be removed after eng-1475
186185
relevantNodeTypeById[id] = fm.nodeTypeId as string;
187186
});
188187
relations.map((relation) => {

apps/obsidian/src/utils/syncDgNodesToSupabase.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ export const syncAllNodesAndRelations = async (
423423
}
424424
console.debug("Supabase client:", supabaseClient);
425425

426-
const allNodes = await collectDiscourseNodesFromVault(plugin);
426+
const allNodes = await collectDiscourseNodesFromVault(plugin, true);
427427

428428
const changedNodeInstances = relationsOnly
429429
? []
@@ -495,7 +495,7 @@ const convertDgToSupabaseConcepts = async ({
495495
const nodeTypes = plugin.settings.nodeTypes ?? [];
496496
const relationTypes = plugin.settings.relationTypes ?? [];
497497
const discourseRelations = plugin.settings.discourseRelations ?? [];
498-
allNodes = allNodes ?? (await collectDiscourseNodesFromVault(plugin));
498+
allNodes = allNodes ?? (await collectDiscourseNodesFromVault(plugin, true));
499499
const allNodesById = Object.fromEntries(
500500
allNodes.map((n) => [n.nodeInstanceId, n]),
501501
);

packages/database/src/dbTypes.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,20 @@ export type Database = {
15861586
}
15871587
Returns: string
15881588
}
1589+
rid_or_local_id_to_concept_db_id: {
1590+
Args: { default_space_id: number; rid: string }
1591+
Returns: number
1592+
}
1593+
rid_to_space_id_and_local_id: {
1594+
Args: { rid: string }
1595+
Returns: Database["public"]["CompositeTypes"]["accessible_resource"]
1596+
SetofOptions: {
1597+
from: "*"
1598+
to: "accessible_resource"
1599+
isOneToOne: true
1600+
isSetofReturn: false
1601+
}
1602+
}
15891603
schema_of_concept:
15901604
| {
15911605
Args: { concept: Database["public"]["Tables"]["Concept"]["Row"] }
@@ -1967,3 +1981,4 @@ export const Constants = {
19671981
},
19681982
},
19691983
} as const
1984+
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
CREATE OR REPLACE FUNCTION public.rid_to_space_id_and_local_id(rid VARCHAR)
2+
RETURNS public.accessible_resource STRICT STABLE
3+
SET search_path = ''
4+
LANGUAGE plpgsql AS $$
5+
DECLARE
6+
uri VARCHAR;
7+
source_local_id VARCHAR;
8+
source_id BIGINT;
9+
BEGIN
10+
source_local_id := split_part(rid, '/', -1);
11+
IF length(source_local_id) = length(rid) THEN
12+
RETURN (null, 'Not a Rid')::public.accessible_resource;
13+
END IF;
14+
uri := substr(rid, 1, length(rid) - length(source_local_id) - 1);
15+
IF rid ~ '^orn:\w+\.\w+:.*$' THEN
16+
uri := concat(split_part(split_part(uri, ':', 2), '.', 1), ':', split_part(uri, ':', 3));
17+
ELSE
18+
IF rid ~ '^orn:\w+:.*$' THEN
19+
uri := substr(uri, 5);
20+
END IF;
21+
END IF;
22+
SELECT id INTO source_id FROM public."Space" where url=uri;
23+
IF source_id IS NULL THEN
24+
RETURN (null, concat('Cannot find ', uri))::public.accessible_resource;
25+
END IF;
26+
RETURN (source_id, source_local_id);
27+
END;
28+
$$;
29+
30+
CREATE OR REPLACE FUNCTION public.rid_or_local_id_to_concept_db_id(rid VARCHAR, default_space_id BIGINT)
31+
RETURNS BIGINT STRICT STABLE
32+
SET search_path = ''
33+
LANGUAGE plpgsql AS $$
34+
DECLARE r public.accessible_resource;
35+
BEGIN
36+
r := (SELECT public.rid_to_space_id_and_local_id(rid));
37+
IF r.space_id IS NULL THEN
38+
RETURN (SELECT id FROM public."Concept" WHERE space_id = default_space_id AND source_local_id = rid);
39+
ELSE
40+
RETURN (SELECT id FROM public."Concept" WHERE space_id = r.space_id AND source_local_id = r.source_local_id);
41+
END IF;
42+
END;
43+
$$;
44+
45+
CREATE OR REPLACE FUNCTION public._local_concept_to_db_concept(data public.concept_local_input)
46+
RETURNS public."Concept" STABLE
47+
SET search_path = ''
48+
LANGUAGE plpgsql
49+
AS $$
50+
DECLARE
51+
concept public."Concept"%ROWTYPE;
52+
reference_content JSONB := jsonb_build_object();
53+
key varchar;
54+
value JSONB;
55+
ref_single_val BIGINT;
56+
ref_array_val BIGINT[];
57+
BEGIN
58+
-- not fan of going through json, but not finding how to populate a record by a different shape record
59+
concept := jsonb_populate_record(NULL::public."Concept", to_jsonb(data));
60+
IF data.author_local_id IS NOT NULL THEN
61+
SELECT id FROM public."PlatformAccount"
62+
WHERE account_local_id = data.author_local_id INTO concept.author_id;
63+
END IF;
64+
IF data.represented_by_id IS NOT NULL THEN
65+
SELECT space_id, source_local_id FROM public."Content"
66+
WHERE id = data.represented_by_id INTO concept.space_id, concept.source_local_id;
67+
END IF;
68+
IF data.space_url IS NOT NULL THEN
69+
SELECT id FROM public."Space"
70+
WHERE url = data.space_url INTO concept.space_id;
71+
END IF;
72+
IF concept.source_local_id = '' THEN
73+
concept.source_local_id := NULL;
74+
END IF;
75+
IF data.represented_by_local_id = '' THEN
76+
data.represented_by_local_id := NULL;
77+
END IF;
78+
IF data.schema_represented_by_local_id IS NOT NULL THEN
79+
SELECT public.rid_or_local_id_to_concept_db_id(
80+
data.schema_represented_by_local_id, concept.space_id) INTO concept.schema_id;
81+
END IF;
82+
concept.source_local_id = COALESCE(concept.source_local_id, data.represented_by_local_id); -- legacy input field
83+
concept.reference_content := coalesce(data.reference_content, '{}'::jsonb);
84+
IF data.local_reference_content IS NOT NULL THEN
85+
FOR key, value IN SELECT * FROM jsonb_each(data.local_reference_content) LOOP
86+
IF jsonb_typeof(value) = 'array' THEN
87+
WITH el AS (SELECT jsonb_array_elements_text(value) as x),
88+
el2 AS (SELECT public.rid_or_local_id_to_concept_db_id(x, concept.space_id) AS id FROM el)
89+
SELECT array_agg(DISTINCT el2.id) INTO STRICT ref_array_val
90+
FROM el2 WHERE el2.id IS NOT NULL;
91+
reference_content := jsonb_set(reference_content, ARRAY[key], to_jsonb(ref_array_val));
92+
ELSIF jsonb_typeof(value) = 'string' THEN
93+
SELECT public.rid_or_local_id_to_concept_db_id(value #>> '{}', concept.space_id) INTO STRICT ref_single_val;
94+
reference_content := jsonb_set(reference_content, ARRAY[key], to_jsonb(ref_single_val));
95+
ELSE
96+
RAISE EXCEPTION 'Invalid value in local_reference_content % %', value, jsonb_typeof(value);
97+
END IF;
98+
END LOOP;
99+
concept.reference_content := concept.reference_content || reference_content;
100+
END IF;
101+
RETURN concept;
102+
END;
103+
$$;

packages/database/supabase/schemas/concept.sql

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,49 @@ $$;
240240
COMMENT ON FUNCTION public.author_of_concept(public.my_concepts)
241241
IS 'Computed one-to-one: returns the PlatformAccount which authored a given Concept.';
242242

243+
CREATE OR REPLACE FUNCTION public.rid_to_space_id_and_local_id(rid VARCHAR)
244+
RETURNS public.accessible_resource STRICT STABLE
245+
SET search_path = ''
246+
LANGUAGE plpgsql AS $$
247+
DECLARE
248+
uri VARCHAR;
249+
source_local_id VARCHAR;
250+
source_id BIGINT;
251+
BEGIN
252+
source_local_id := split_part(rid, '/', -1);
253+
IF length(source_local_id) = length(rid) THEN
254+
RETURN (null, 'Not a Rid')::public.accessible_resource;
255+
END IF;
256+
uri := substr(rid, 1, length(rid) - length(source_local_id) - 1);
257+
IF rid ~ '^orn:\w+\.\w+:.*$' THEN
258+
uri := concat(split_part(split_part(uri, ':', 2), '.', 1), ':', split_part(uri, ':', 3));
259+
ELSE
260+
IF rid ~ '^orn:\w+:.*$' THEN
261+
uri := substr(uri, 5);
262+
END IF;
263+
END IF;
264+
SELECT id INTO source_id FROM public."Space" where url=uri;
265+
IF source_id IS NULL THEN
266+
RETURN (null, concat('Cannot find ', uri))::public.accessible_resource;
267+
END IF;
268+
RETURN (source_id, source_local_id);
269+
END;
270+
$$;
271+
272+
CREATE OR REPLACE FUNCTION public.rid_or_local_id_to_concept_db_id(rid VARCHAR, default_space_id BIGINT)
273+
RETURNS BIGINT STRICT STABLE
274+
SET search_path = ''
275+
LANGUAGE plpgsql AS $$
276+
DECLARE r public.accessible_resource;
277+
BEGIN
278+
r := (SELECT public.rid_to_space_id_and_local_id(rid));
279+
IF r.space_id IS NULL THEN
280+
RETURN (SELECT id FROM public."Concept" WHERE space_id = default_space_id AND source_local_id = rid);
281+
ELSE
282+
RETURN (SELECT id FROM public."Concept" WHERE space_id = r.space_id AND source_local_id = r.source_local_id);
283+
END IF;
284+
END;
285+
$$;
243286

244287
CREATE TYPE public.concept_local_input AS (
245288
-- concept columns
@@ -292,37 +335,34 @@ BEGIN
292335
SELECT id FROM public."Space"
293336
WHERE url = data.space_url INTO concept.space_id;
294337
END IF;
295-
IF data.schema_represented_by_local_id IS NOT NULL THEN
296-
SELECT cpt.id FROM public."Concept" cpt
297-
WHERE cpt.source_local_id = data.schema_represented_by_local_id
298-
AND cpt.space_id = concept.space_id INTO concept.schema_id;
299-
END IF;
300338
IF concept.source_local_id = '' THEN
301339
concept.source_local_id := NULL;
302340
END IF;
303341
IF data.represented_by_local_id = '' THEN
304342
data.represented_by_local_id := NULL;
305343
END IF;
344+
IF data.schema_represented_by_local_id IS NOT NULL THEN
345+
SELECT public.rid_or_local_id_to_concept_db_id(
346+
data.schema_represented_by_local_id, concept.space_id) INTO concept.schema_id;
347+
END IF;
306348
concept.source_local_id = COALESCE(concept.source_local_id, data.represented_by_local_id); -- legacy input field
349+
concept.reference_content := coalesce(data.reference_content, '{}'::jsonb);
307350
IF data.local_reference_content IS NOT NULL THEN
308351
FOR key, value IN SELECT * FROM jsonb_each(data.local_reference_content) LOOP
309352
IF jsonb_typeof(value) = 'array' THEN
310353
WITH el AS (SELECT jsonb_array_elements_text(value) as x),
311-
ela AS (SELECT array_agg(x) AS a FROM el)
312-
SELECT array_agg(DISTINCT cpt.id) INTO STRICT ref_array_val
313-
FROM public."Concept" AS cpt
314-
JOIN ela ON (true) WHERE cpt.source_local_id = ANY(ela.a) AND cpt.space_id=concept.space_id;
354+
el2 AS (SELECT public.rid_or_local_id_to_concept_db_id(x, concept.space_id) AS id FROM el)
355+
SELECT array_agg(DISTINCT el2.id) INTO STRICT ref_array_val
356+
FROM el2 WHERE el2.id IS NOT NULL;
315357
reference_content := jsonb_set(reference_content, ARRAY[key], to_jsonb(ref_array_val));
316358
ELSIF jsonb_typeof(value) = 'string' THEN
317-
SELECT cpt.id INTO STRICT ref_single_val
318-
FROM public."Concept" AS cpt
319-
WHERE cpt.source_local_id = (value #>> '{}') AND cpt.space_id=concept.space_id;
359+
SELECT public.rid_or_local_id_to_concept_db_id(value #>> '{}', concept.space_id) INTO STRICT ref_single_val;
320360
reference_content := jsonb_set(reference_content, ARRAY[key], to_jsonb(ref_single_val));
321361
ELSE
322362
RAISE EXCEPTION 'Invalid value in local_reference_content % %', value, jsonb_typeof(value);
323363
END IF;
324364
END LOOP;
325-
SELECT reference_content INTO concept.reference_content;
365+
concept.reference_content := concept.reference_content || reference_content;
326366
END IF;
327367
RETURN concept;
328368
END;

0 commit comments

Comments
 (0)