From 2655acd8937e42ed8175187ad1131cebf1aa0b74 Mon Sep 17 00:00:00 2001 From: Jackson Morgan Date: Mon, 24 Feb 2025 14:42:29 -0500 Subject: [PATCH] All original tests working --- .../jsonld-dataset-proxy/src/ProxyContext.ts | 3 +- .../src/setProxy/ObjectSetProxy.ts | 7 +- .../src/setProxy/SetProxy.ts | 20 +--- .../src/setProxy/SubjectSetProxy.ts | 21 ++++ .../src/setProxy/WildcardObjectSetProxy.ts | 108 +++++------------- .../src/setProxy/WildcardSubjectSetProxy.ts | 24 +--- .../test/jsonldDatasetProxy.test.ts | 2 +- 7 files changed, 64 insertions(+), 121 deletions(-) diff --git a/packages/jsonld-dataset-proxy/src/ProxyContext.ts b/packages/jsonld-dataset-proxy/src/ProxyContext.ts index 6d20e88..344c0d5 100644 --- a/packages/jsonld-dataset-proxy/src/ProxyContext.ts +++ b/packages/jsonld-dataset-proxy/src/ProxyContext.ts @@ -68,7 +68,7 @@ export class ProxyContext { public createSetProxy( quadMatch: QuadMatch, isSubjectOriented?: boolean, - _isLangStringSet?: boolean, + isLangStringSet?: boolean, ): SetProxy { const key = this.getSetKey(...quadMatch); if (!this.setMap.has(key)) { @@ -76,6 +76,7 @@ export class ProxyContext { quadMatch, isSubjectOriented ?? false, this, + isLangStringSet, ); this.setMap.set(key, proxy); } diff --git a/packages/jsonld-dataset-proxy/src/setProxy/ObjectSetProxy.ts b/packages/jsonld-dataset-proxy/src/setProxy/ObjectSetProxy.ts index 6b99135..5be1c4b 100644 --- a/packages/jsonld-dataset-proxy/src/setProxy/ObjectSetProxy.ts +++ b/packages/jsonld-dataset-proxy/src/setProxy/ObjectSetProxy.ts @@ -59,9 +59,8 @@ export class ObjectSetProxy< */ delete(value: T): boolean { const { dataset } = this.context; - const { subject, predicate, object, graph } = this.getSPOG(value); - const didDelete = dataset.match(subject, predicate, object, graph).size > 0; - dataset.deleteMatches(subject, predicate, object, graph); - return didDelete; + const quads = this.getQuads(value); + quads.forEach((quad) => dataset.delete(quad)); + return quads.size > 0; } } diff --git a/packages/jsonld-dataset-proxy/src/setProxy/SetProxy.ts b/packages/jsonld-dataset-proxy/src/setProxy/SetProxy.ts index 4eb4950..f161eb6 100644 --- a/packages/jsonld-dataset-proxy/src/setProxy/SetProxy.ts +++ b/packages/jsonld-dataset-proxy/src/setProxy/SetProxy.ts @@ -6,7 +6,6 @@ import type { Dataset, Quad } from "@rdfjs/types"; import type { GraphNode, ObjectNode, - PredicateNode, QuadMatch, SubjectNode, } from "@ldo/rdf-utils"; @@ -43,12 +42,7 @@ export abstract class SetProxy< /** * Gets the subject, predicate and object for this set */ - protected abstract getSPOG(value?: T): { - subject?: SubjectNode; - predicate?: PredicateNode; - object?: ObjectNode; - graph?: GraphNode; - }; + protected abstract getQuads(value?: T): Dataset; protected abstract getNodeOfFocus(quad: Quad): SubjectNode | ObjectNode; @@ -86,15 +80,11 @@ export abstract class SetProxy< } has(value: T): boolean { - const { dataset } = this.context; - const { subject, predicate, object, graph } = this.getSPOG(value); - return dataset.match(subject, predicate, object, graph).size > 0; + return this.getQuads(value).size > 0; } get size() { - const { dataset } = this.context; - const { subject, predicate, object, graph } = this.getSPOG(); - return dataset.match(subject, predicate, object, graph).size; + return this.getQuads().size; } entries(): IterableIterator<[T, T]> { @@ -114,9 +104,7 @@ export abstract class SetProxy< } [Symbol.iterator](): IterableIterator { - const { dataset } = this.context; - const { subject, predicate, object, graph } = this.getSPOG(); - const quads = dataset.match(subject, predicate, object, graph); + const quads = this.getQuads(); const collection: T[] = quads.toArray().map((quad) => { const quadSubject = this.getNodeOfFocus(quad); return nodeToJsonldRepresentation(quadSubject, this.context) as T; diff --git a/packages/jsonld-dataset-proxy/src/setProxy/SubjectSetProxy.ts b/packages/jsonld-dataset-proxy/src/setProxy/SubjectSetProxy.ts index 9e18035..f6059f7 100644 --- a/packages/jsonld-dataset-proxy/src/setProxy/SubjectSetProxy.ts +++ b/packages/jsonld-dataset-proxy/src/setProxy/SubjectSetProxy.ts @@ -86,4 +86,25 @@ export class SubjectSetProxy< }); return this; } + + /** + * Clears the set of all values + */ + clear(): void { + for (const value of this) { + this.delete(value); + } + } + + /** + * Deletes an item for the set + * @param value the item to delete + * @returns true if the item was present before deletion + */ + delete(value: T): boolean { + const { dataset } = this.context; + const quads = this.getQuads(value); + quads.forEach((quad) => dataset.delete(quad)); + return quads.size > 0; + } } diff --git a/packages/jsonld-dataset-proxy/src/setProxy/WildcardObjectSetProxy.ts b/packages/jsonld-dataset-proxy/src/setProxy/WildcardObjectSetProxy.ts index 7e4034b..4ea3538 100644 --- a/packages/jsonld-dataset-proxy/src/setProxy/WildcardObjectSetProxy.ts +++ b/packages/jsonld-dataset-proxy/src/setProxy/WildcardObjectSetProxy.ts @@ -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, > extends SetProxy { 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 { + const { dataset } = this.context; + let quads: Dataset; + // 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 { - // 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 { diff --git a/packages/jsonld-dataset-proxy/src/setProxy/WildcardSubjectSetProxy.ts b/packages/jsonld-dataset-proxy/src/setProxy/WildcardSubjectSetProxy.ts index 43a97a2..02b06a2 100644 --- a/packages/jsonld-dataset-proxy/src/setProxy/WildcardSubjectSetProxy.ts +++ b/packages/jsonld-dataset-proxy/src/setProxy/WildcardSubjectSetProxy.ts @@ -4,7 +4,7 @@ import type { ObjectNode, GraphNode, } from "@ldo/rdf-utils"; -import type { Quad } from "@rdfjs/types"; +import type { Dataset, Quad } from "@rdfjs/types"; import type { RawObject } from "../util/RawObject"; import { SetProxy } from "./SetProxy"; import type { ProxyContext } from "../ProxyContext"; @@ -34,32 +34,18 @@ export class WildcardSubjectSetProxy extends SetProxy { this.quadMatch = quadMatch; } - protected getSPOG(value?: T | undefined): { - subject?: SubjectNode; - predicate?: PredicateNode; - object?: ObjectNode; - graph?: GraphNode; - } { + protected getQuads(value?: T | undefined): Dataset { + const { dataset } = this.context; // Get the RDF Node that represents the value, skip is no value const predicate = this.quadMatch[1] ?? undefined; const object = this.quadMatch[2] ?? undefined; const graph = this.quadMatch[3] ?? undefined; if (value) { const valueNode = getNodeFromRawObject(value, this.context.contextUtil); - return { - subject: valueNode, - predicate, - object, - graph, - }; + return dataset.match(valueNode, predicate, object, graph); } // SPO for no value - return { - subject: undefined, - predicate, - object, - graph, - }; + return dataset.match(undefined, predicate, object, graph); } protected getNodeOfFocus(quad: Quad): SubjectNode { diff --git a/packages/jsonld-dataset-proxy/test/jsonldDatasetProxy.test.ts b/packages/jsonld-dataset-proxy/test/jsonldDatasetProxy.test.ts index 4168682..0dff9fd 100644 --- a/packages/jsonld-dataset-proxy/test/jsonldDatasetProxy.test.ts +++ b/packages/jsonld-dataset-proxy/test/jsonldDatasetProxy.test.ts @@ -1264,7 +1264,7 @@ const testJsonldDatasetProxy = (patientContext: LdoJsonldContext) => () => { it("Removes an object completely when using the delete method", async () => { const firstPatient = patients.toArray()[0]; patients.delete(firstPatient); - expect(patients.has(firstPatient)).toBe(true); + expect(patients.has(firstPatient)).toBe(false); }); it("creates a collection that matches only collections in a certain graph", async () => {