Skip to content

Commit ad7af74

Browse files
committed
relation to imported wip
1 parent 30e40b2 commit ad7af74

4 files changed

Lines changed: 166 additions & 21 deletions

File tree

apps/obsidian/src/utils/conceptConversion.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,10 @@ export const relationInstanceToLocalConcept = ({
227227
}
228228
const sourceNode = allNodesById[source];
229229
const destinationNode = allNodesById[destination];
230-
if (
231-
sourceNode?.frontmatter.importedFromRid ||
232-
destinationNode?.frontmatter.importedFromRid
233-
)
230+
if (sourceNode === undefined || destinationNode === undefined) {
231+
console.error("Cannot find the nodes");
234232
return null; // punt relation to imported nodes for now.
235-
// otherwise put the importedFromRid in source, dest.
233+
}
236234

237235
/* eslint-disable @typescript-eslint/naming-convention */
238236
const literal_content: Record<string, Json> = {};
@@ -248,8 +246,12 @@ export const relationInstanceToLocalConcept = ({
248246
last_modified: new Date(lastModified ?? created).toISOString(),
249247
literal_content,
250248
local_reference_content: {
251-
source,
252-
destination,
249+
source:
250+
(sourceNode.frontmatter.importedFromRid as string | undefined) ??
251+
source,
252+
destination:
253+
(destinationNode.frontmatter.importedFromRid as string | undefined) ??
254+
destination,
253255
},
254256
/* eslint-enable @typescript-eslint/naming-convention */
255257
};

apps/obsidian/src/utils/syncDgNodesToSupabase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ const convertDgToSupabaseConcepts = async ({
497497
const nodeTypes = plugin.settings.nodeTypes ?? [];
498498
const relationTypes = plugin.settings.relationTypes ?? [];
499499
const discourseRelations = plugin.settings.discourseRelations ?? [];
500-
const allNodes = await collectDiscourseNodesFromVault(plugin);
500+
const allNodes = await collectDiscourseNodesFromVault(plugin, true);
501501
const allNodesById = Object.fromEntries(
502502
allNodes.map((n) => [n.nodeInstanceId, n]),
503503
);
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)