|
|
|
@ -10,6 +10,7 @@ import { SetProxy } from "./SetProxy"; |
|
|
|
|
import type { ProxyContext } from "../ProxyContext"; |
|
|
|
|
import { getNodeFromRawValue } from "../util/getNodeFromRaw"; |
|
|
|
|
import { _isSubjectOriented } from "../types"; |
|
|
|
|
import { filterQuadsByLanguageOrdering } from "../language/languageUtils"; |
|
|
|
|
|
|
|
|
|
export type WildcardObjectSetProxyQuadMatch = [ |
|
|
|
|
SubjectNode | undefined | null, |
|
|
|
@ -27,25 +28,22 @@ export class WildcardObjectSetProxy< |
|
|
|
|
T extends NonNullable<RawValue>, |
|
|
|
|
> extends SetProxy<T> { |
|
|
|
|
protected quadMatch: WildcardObjectSetProxyQuadMatch; |
|
|
|
|
protected isLangSet: boolean; |
|
|
|
|
protected isLangStringSet: boolean; |
|
|
|
|
|
|
|
|
|
constructor( |
|
|
|
|
context: ProxyContext, |
|
|
|
|
quadMatch: WildcardObjectSetProxyQuadMatch, |
|
|
|
|
isLangSet?: boolean, |
|
|
|
|
isLangStringSet?: boolean, |
|
|
|
|
) { |
|
|
|
|
super(context, quadMatch); |
|
|
|
|
this.quadMatch = quadMatch; |
|
|
|
|
this.isLangSet = isLangSet ?? false; |
|
|
|
|
this.isLangStringSet = isLangStringSet ?? false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
protected getQuads(value?: T | undefined): Dataset<Quad, Quad> { |
|
|
|
|
const { dataset } = this.context; |
|
|
|
|
let quads: Dataset<Quad, Quad>; |
|
|
|
|
// Get the RDF Node that represents the value, skip if no value
|
|
|
|
|
const subject = this.quadMatch[0] ?? undefined; |
|
|
|
|
const predicate = this.quadMatch[1] ?? undefined; |
|
|
|
|
const graph = this.quadMatch[3] ?? undefined; |
|
|
|
@ -58,81 +56,31 @@ export class WildcardObjectSetProxy< |
|
|
|
|
datatype = this.context.contextUtil.getDataType(key, rdfType); |
|
|
|
|
} |
|
|
|
|
const valueNode = getNodeFromRawValue(value, this.context, datatype); |
|
|
|
|
return { |
|
|
|
|
subject, |
|
|
|
|
predicate, |
|
|
|
|
object: valueNode, |
|
|
|
|
graph, |
|
|
|
|
}; |
|
|
|
|
quads = dataset.match(subject, predicate, valueNode, graph); |
|
|
|
|
// If there is no valueNode, we must filter by value manually as we
|
|
|
|
|
// weren't able to deduce the datatype.
|
|
|
|
|
if (!valueNode) { |
|
|
|
|
quads = quads.filter( |
|
|
|
|
(quad) => |
|
|
|
|
quad.object.termType === "Literal" && quad.object.value === value, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
// SPO for no value
|
|
|
|
|
quads = dataset.match(subject, predicate, undefined, 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, |
|
|
|
|
// If this is a langStringSet, filter by language preferences
|
|
|
|
|
if (this.isLangStringSet) { |
|
|
|
|
return filterQuadsByLanguageOrdering( |
|
|
|
|
quads, |
|
|
|
|
this.context.languageOrdering, |
|
|
|
|
); |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
return quads; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
protected getNodeOfFocus(quad: Quad): ObjectNode { |
|
|
|
|
return quad.object as ObjectNode; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
get [_isSubjectOriented](): false { |
|
|
|
|