feat: Support updating multiple metadata values for a predicate

This commit is contained in:
Joachim Van Herwegen 2021-02-02 13:40:38 +01:00
parent 061c856161
commit f87fc61ab0
2 changed files with 48 additions and 10 deletions

View File

@ -155,7 +155,9 @@ export class RepresentationMetadata {
} }
/** /**
* @param quads - Quad to add to the metadata. * @param subject - Subject of quad to add.
* @param predicate - Predicate of quad to add.
* @param object - Object of quad to add.
*/ */
public addQuad( public addQuad(
subject: NamedNode | BlankNode | string, subject: NamedNode | BlankNode | string,
@ -175,7 +177,9 @@ export class RepresentationMetadata {
} }
/** /**
* @param quads - Quad to remove from the metadata. * @param subject - Subject of quad to remove.
* @param predicate - Predicate of quad to remove.
* @param object - Object of quad to remove.
*/ */
public removeQuad( public removeQuad(
subject: NamedNode | BlankNode | string, subject: NamedNode | BlankNode | string,
@ -197,19 +201,34 @@ export class RepresentationMetadata {
/** /**
* Adds a value linked to the identifier. Strings get converted to literals. * Adds a value linked to the identifier. Strings get converted to literals.
* @param predicate - Predicate linking identifier to value. * @param predicate - Predicate linking identifier to value.
* @param object - Value to add. * @param object - Value(s) to add.
*/ */
public add(predicate: NamedNode | string, object: NamedNode | Literal | string): this { public add(predicate: NamedNode | string, object: MetadataValue): this {
return this.addQuad(this.id, predicate, object); return this.forQuads(predicate, object, (pred, obj): any => this.addQuad(this.id, pred, obj));
} }
/** /**
* Removes the given value from the metadata. Strings get converted to literals. * Removes the given value from the metadata. Strings get converted to literals.
* @param predicate - Predicate linking identifier to value. * @param predicate - Predicate linking identifier to value.
* @param object - Value to remove. * @param object - Value(s) to remove.
*/ */
public remove(predicate: NamedNode | string, object: NamedNode | Literal | string): this { public remove(predicate: NamedNode | string, object: MetadataValue): this {
return this.removeQuad(this.id, predicate, object); return this.forQuads(predicate, object, (pred, obj): any => this.removeQuad(this.id, pred, obj));
}
// TODO: test all 3
/**
* Helper function to simplify add/remove
* Runs the given function on all predicate/object pairs, but only converts the predicate to a named node once.
*/
private forQuads(predicate: NamedNode | string, object: MetadataValue,
forFn: (pred: NamedNode, obj: NamedNode | Literal) => void): this {
const predicateNode = toCachedNamedNode(predicate);
const objects = Array.isArray(object) ? object : [ object ];
for (const obj of objects) {
forFn(predicateNode, toObjectTerm(obj, true));
}
return this;
} }
/** /**
@ -256,9 +275,9 @@ export class RepresentationMetadata {
* Sets the value for the given predicate, removing all other instances. * Sets the value for the given predicate, removing all other instances.
* In case the object is undefined this is identical to `removeAll(predicate)`. * In case the object is undefined this is identical to `removeAll(predicate)`.
* @param predicate - Predicate linking to the value. * @param predicate - Predicate linking to the value.
* @param object - Value to set. * @param object - Value(s) to set.
*/ */
public set(predicate: NamedNode | string, object?: NamedNode | Literal | string): this { public set(predicate: NamedNode | string, object?: MetadataValue): this {
this.removeAll(predicate); this.removeAll(predicate);
if (object) { if (object) {
this.add(predicate, object); this.add(predicate, object);

View File

@ -154,6 +154,15 @@ describe('A RepresentationMetadata', (): void => {
expect(metadata.quads()).toBeRdfIsomorphic([ newQuad ].concat(inputQuads)); expect(metadata.quads()).toBeRdfIsomorphic([ newQuad ].concat(inputQuads));
}); });
it('can add multiple values for a predicate.', async(): Promise<void> => {
const newQuads = [
quad(identifier, namedNode('new'), namedNode('triple')),
quad(identifier, namedNode('new'), namedNode('triple2')),
];
metadata.add(namedNode('new'), [ namedNode('triple'), namedNode('triple2') ]);
expect(metadata.quads()).toBeRdfIsomorphic(newQuads.concat(inputQuads));
});
it('can remove a single value for a predicate.', async(): Promise<void> => { it('can remove a single value for a predicate.', async(): Promise<void> => {
metadata.remove(inputQuads[0].predicate as NamedNode, inputQuads[0].object as Literal); metadata.remove(inputQuads[0].predicate as NamedNode, inputQuads[0].object as Literal);
expect(metadata.quads()).toBeRdfIsomorphic(inputQuads.slice(1)); expect(metadata.quads()).toBeRdfIsomorphic(inputQuads.slice(1));
@ -164,6 +173,11 @@ describe('A RepresentationMetadata', (): void => {
expect(metadata.quads()).toBeRdfIsomorphic(inputQuads.slice(1)); expect(metadata.quads()).toBeRdfIsomorphic(inputQuads.slice(1));
}); });
it('can remove multiple values for a predicate.', async(): Promise<void> => {
metadata.remove(namedNode('has'), [ inputQuads[0].object, inputQuads[1].object ] as NamedNode[]);
expect(metadata.quads()).toBeRdfIsomorphic(inputQuads.slice(2));
});
it('can remove all values for a predicate.', async(): Promise<void> => { it('can remove all values for a predicate.', async(): Promise<void> => {
const pred = namedNode('has'); const pred = namedNode('has');
metadata.removeAll(pred); metadata.removeAll(pred);
@ -194,6 +208,11 @@ describe('A RepresentationMetadata', (): void => {
expect(metadata.get(namedNode('has'))).toEqualRdfTerm(literal('singleValue')); expect(metadata.get(namedNode('has'))).toEqualRdfTerm(literal('singleValue'));
}); });
it('can set multiple values of a predicate.', async(): Promise<void> => {
metadata.set(namedNode('has'), [ literal('value1'), literal('value2') ]);
expect(metadata.getAll(namedNode('has'))).toEqualRdfTermArray([ literal('value1'), literal('value2') ]);
});
it('has a shorthand for content-type.', async(): Promise<void> => { it('has a shorthand for content-type.', async(): Promise<void> => {
expect(metadata.contentType).toBeUndefined(); expect(metadata.contentType).toBeUndefined();
metadata.contentType = 'a/b'; metadata.contentType = 'a/b';