You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

140 lines
4.1 KiB

import type { BlankNode, NamedNode } from "@rdfjs/types";
import { literal, namedNode, quad } from "@rdfjs/data-model";
import { _getUnderlyingNode } from "../types";
import type { SubjectProxy } from "../subjectProxy/SubjectProxy";
import { getNodeFromRawObject, getNodeFromRawValue } from "./getNodeFromRaw";
import type { RawObject, RawValue } from "./RawObject";
import type { ProxyContext } from "../ProxyContext";
import { isSubjectProxy } from "../subjectProxy/isSubjectProxy";
import { NodeSet } from "./NodeSet";
import {
getLanguageKeyForWriteOperation,
languageDeleteMatch,
languageKeyToLiteralLanguage,
} from "../language/languageUtils";
export function addRawValueToDatasetRecursive(
subject: NamedNode | BlankNode,
key: string,
value: RawValue,
visitedObjects: NodeSet,
shouldDeleteOldTriples: boolean,
proxyContext: ProxyContext,
): void {
const { dataset, contextUtil } = proxyContext;
const predicate = namedNode(contextUtil.keyToIri(key));
// Get the Object Node
const object = getNodeFromRawValue(key, value, proxyContext);
if (object == undefined) {
dataset.deleteMatches(subject, predicate);
} else if (object.termType === "Literal") {
let languageAppliedObject = object;
// Handle language use case
if (contextUtil.isLangString(key)) {
const languageKey = getLanguageKeyForWriteOperation(
proxyContext.languageOrdering,
);
if (!languageKey) return;
languageAppliedObject = literal(
object.value,
languageKeyToLiteralLanguage(languageKey),
);
}
proxyContext.writeGraphs.forEach((graph) => {
proxyContext.dataset.add(
quad(subject, predicate, languageAppliedObject, graph),
);
});
} else {
// Delete any triples if the id is the same
if (!visitedObjects.has(object) && !isSubjectProxy(value)) {
dataset.deleteMatches(object, undefined, undefined);
}
proxyContext.writeGraphs.forEach((graph) => {
dataset.add(quad(subject, predicate, object, graph));
});
if (!isSubjectProxy(value)) {
const updateData: RawObject = (
typeof value === "object"
? { ...value, "@id": object }
: { "@id": object }
) as RawObject;
addRawObjectToDatasetRecursive(
updateData,
visitedObjects,
shouldDeleteOldTriples,
proxyContext,
);
}
}
}
export function addRawObjectToDatasetRecursive(
item: RawObject,
visitedObjects: NodeSet,
shouldDeleteOldTriples: boolean,
proxyContext: ProxyContext,
): SubjectProxy {
if (isSubjectProxy(item)) {
return item as SubjectProxy;
}
const { dataset } = proxyContext;
const subject = getNodeFromRawObject(item, proxyContext.contextUtil);
if (visitedObjects.has(subject)) {
return proxyContext.createSubjectProxy(subject);
}
visitedObjects.add(subject);
Object.entries(item).forEach(([key, value]) => {
if (key === "@id") {
return;
}
const predicate = namedNode(proxyContext.contextUtil.keyToIri(key));
if (shouldDeleteOldTriples) {
if (proxyContext.contextUtil.isLangString(key)) {
const languageKey = getLanguageKeyForWriteOperation(
proxyContext.languageOrdering,
);
if (languageKey) {
languageDeleteMatch(dataset, subject, predicate, languageKey);
}
} else {
dataset.deleteMatches(subject, predicate);
}
}
if (Array.isArray(value)) {
value.forEach((valueItem) => {
addRawValueToDatasetRecursive(
subject,
key,
valueItem,
visitedObjects,
true,
proxyContext,
);
});
} else {
addRawValueToDatasetRecursive(
subject,
key,
value as RawValue,
visitedObjects,
true,
proxyContext,
);
}
});
return proxyContext.createSubjectProxy(subject);
}
export function addObjectToDataset(
item: RawObject,
shouldDeleteOldTriples: boolean,
proxyContext: ProxyContext,
): SubjectProxy {
return addRawObjectToDatasetRecursive(
item,
new NodeSet(),
shouldDeleteOldTriples,
proxyContext,
);
}