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.
138 lines
3.8 KiB
138 lines
3.8 KiB
import type {
|
|
SubjectNode,
|
|
PredicateNode,
|
|
ObjectNode,
|
|
GraphNode,
|
|
} from "@ldo/rdf-utils";
|
|
import type { Dataset, Quad } from "@rdfjs/types";
|
|
import type { RawValue } from "../util/RawObject";
|
|
import { SetProxy } from "./SetProxy";
|
|
import type { ProxyContext } from "../ProxyContext";
|
|
import { getNodeFromRawValue } from "../util/getNodeFromRaw";
|
|
import { _isSubjectOriented } from "../types";
|
|
|
|
export type WildcardObjectSetProxyQuadMatch = [
|
|
SubjectNode | undefined | null,
|
|
PredicateNode | undefined | null,
|
|
undefined | null,
|
|
GraphNode | undefined | null,
|
|
];
|
|
|
|
/**
|
|
* A WildcardObjectProxy represents a set of nodes in a dataset that are all the
|
|
* object of a given subject and predicate. Because this is a wildcard, the
|
|
* subject and predicate don't necissarily need to be defined.
|
|
*/
|
|
export class WildcardObjectSetProxy<
|
|
T extends NonNullable<RawValue>,
|
|
> extends SetProxy<T> {
|
|
protected quadMatch: WildcardObjectSetProxyQuadMatch;
|
|
|
|
constructor(
|
|
context: ProxyContext,
|
|
quadMatch: WildcardObjectSetProxyQuadMatch,
|
|
) {
|
|
super(context, quadMatch);
|
|
this.quadMatch = quadMatch;
|
|
}
|
|
|
|
protected getSPOG(value?: T | undefined): {
|
|
subject?: SubjectNode;
|
|
predicate?: PredicateNode;
|
|
object?: ObjectNode;
|
|
graph?: GraphNode;
|
|
} {
|
|
// Get the RDF Node that represents the value, skip is no value
|
|
const subject = this.quadMatch[0] ?? undefined;
|
|
const predicate = this.quadMatch[1] ?? undefined;
|
|
const graph = this.quadMatch[3] ?? undefined;
|
|
if (value) {
|
|
// Get datatype if applicable
|
|
let datatype: string | undefined = undefined;
|
|
if (this.quadMatch[0] && predicate) {
|
|
const rdfType = this.context.getRdfType(this.quadMatch[0]);
|
|
const key = this.context.contextUtil.iriToKey(predicate.value, rdfType);
|
|
datatype = this.context.contextUtil.getDataType(key, rdfType);
|
|
}
|
|
const valueNode = getNodeFromRawValue(value, this.context, datatype);
|
|
return {
|
|
subject,
|
|
predicate,
|
|
object: valueNode,
|
|
graph,
|
|
};
|
|
}
|
|
// SPO for no value
|
|
return {
|
|
subject,
|
|
predicate,
|
|
object: undefined,
|
|
graph,
|
|
};
|
|
}
|
|
|
|
protected getNodeOfFocus(quad: Quad): ObjectNode {
|
|
return quad.object as ObjectNode;
|
|
}
|
|
|
|
private manuallyMatchWithUnknownObjectNode(
|
|
subject: SubjectNode | undefined,
|
|
predicate: PredicateNode | undefined,
|
|
graph: GraphNode | undefined,
|
|
value: T,
|
|
): Dataset<Quad, Quad> {
|
|
// If there's not an object, that means that we don't know the object node
|
|
// and need to find it manually.
|
|
const matchingQuads = this.context.dataset.match(
|
|
subject,
|
|
predicate,
|
|
null,
|
|
graph,
|
|
);
|
|
return matchingQuads.filter(
|
|
(quad) =>
|
|
quad.object.termType === "Literal" && quad.object.value === value,
|
|
);
|
|
}
|
|
|
|
delete(value: T): boolean {
|
|
const { dataset } = this.context;
|
|
const { subject, predicate, object, graph } = this.getSPOG(value);
|
|
if (!object) {
|
|
const matchedQuads = this.manuallyMatchWithUnknownObjectNode(
|
|
subject,
|
|
predicate,
|
|
graph,
|
|
value,
|
|
);
|
|
matchedQuads.forEach((quad) => dataset.delete(quad));
|
|
return matchedQuads.size > 0;
|
|
} else {
|
|
const willDelete =
|
|
dataset.match(subject, predicate, object, graph).size > 0;
|
|
dataset.deleteMatches(subject, predicate, object, graph);
|
|
return willDelete;
|
|
}
|
|
}
|
|
|
|
has(value: T): boolean {
|
|
const { dataset } = this.context;
|
|
const { subject, predicate, object, graph } = this.getSPOG(value);
|
|
if (!object) {
|
|
return (
|
|
this.manuallyMatchWithUnknownObjectNode(
|
|
subject,
|
|
predicate,
|
|
graph,
|
|
value,
|
|
).size > 0
|
|
);
|
|
} else {
|
|
return dataset.match(subject, predicate, object, graph).size > 0;
|
|
}
|
|
}
|
|
|
|
get [_isSubjectOriented](): false {
|
|
return false;
|
|
}
|
|
}
|
|
|