mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Added resourceExists method to ResourceStore
* feat: added resourceExists method to ResourceStore * Merge remote-tracking branch 'origin/main' into feat/add-resourceExists-method-to-ResourceStore * fix: adapted to review * fix: adapted to review
This commit is contained in:
committed by
GitHub
parent
e5b7d99da4
commit
b3f292d718
@@ -4,7 +4,6 @@ import { BasicRepresentation } from '../ldp/representation/BasicRepresentation';
|
||||
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { ResourceStore } from '../storage/ResourceStore';
|
||||
import { containsResource } from '../storage/StoreUtil';
|
||||
import { TEXT_TURTLE } from '../util/ContentTypes';
|
||||
import { ensureTrailingSlash, joinFilePath } from '../util/PathUtil';
|
||||
import { Initializer } from './Initializer';
|
||||
@@ -39,7 +38,7 @@ export class AclInitializer extends Initializer {
|
||||
// https://solid.github.io/specification/protocol#storage
|
||||
public async handle(): Promise<void> {
|
||||
const rootAcl = this.aclStrategy.getAuxiliaryIdentifier(this.root);
|
||||
if (await containsResource(this.store, rootAcl)) {
|
||||
if (await this.store.resourceExists(rootAcl)) {
|
||||
this.logger.debug(`Existing root ACL document found at ${rootAcl.path}`);
|
||||
} else {
|
||||
this.logger.debug(`Installing root ACL document at ${rootAcl.path}`);
|
||||
|
||||
@@ -4,7 +4,6 @@ import { RepresentationMetadata } from '../ldp/representation/RepresentationMeta
|
||||
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { ResourceStore } from '../storage/ResourceStore';
|
||||
import { containsResource } from '../storage/StoreUtil';
|
||||
import { TEXT_TURTLE } from '../util/ContentTypes';
|
||||
import { ensureTrailingSlash } from '../util/PathUtil';
|
||||
import { generateResourceQuads } from '../util/ResourceUtil';
|
||||
@@ -32,7 +31,7 @@ export class RootContainerInitializer extends Initializer {
|
||||
|
||||
public async handle(): Promise<void> {
|
||||
this.logger.debug(`Checking for root container at ${this.baseId.path}`);
|
||||
if (!await containsResource(this.store, this.baseId)) {
|
||||
if (!await this.store.resourceExists(this.baseId)) {
|
||||
await this.createRootContainer();
|
||||
} else {
|
||||
this.logger.debug(`Existing root container found at ${this.baseId.path}`);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { getLoggerFor } from '../logging/LogUtil';
|
||||
import type { ResourceStore } from '../storage/ResourceStore';
|
||||
import { containsResource } from '../storage/StoreUtil';
|
||||
import { ConflictHttpError } from '../util/errors/ConflictHttpError';
|
||||
import type { Agent } from './agent/Agent';
|
||||
import type { IdentifierGenerator } from './generate/IdentifierGenerator';
|
||||
@@ -33,7 +32,7 @@ export class GeneratedPodManager implements PodManager {
|
||||
public async createPod(agent: Agent): Promise<ResourceIdentifier> {
|
||||
const podIdentifier = this.idGenerator.generate(agent.login);
|
||||
this.logger.info(`Creating pod ${podIdentifier.path}`);
|
||||
if (await containsResource(this.store, podIdentifier)) {
|
||||
if (await this.store.resourceExists(podIdentifier)) {
|
||||
throw new ConflictHttpError(`There already is a resource at ${podIdentifier.path}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@ import type { ResourceStore } from './ResourceStore';
|
||||
*/
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
export class BaseResourceStore implements ResourceStore {
|
||||
public async resourceExists(identifier: ResourceIdentifier, conditions?: Conditions): Promise<boolean> {
|
||||
throw new NotImplementedHttpError();
|
||||
}
|
||||
|
||||
public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences,
|
||||
conditions?: Conditions): Promise<Representation> {
|
||||
throw new NotImplementedHttpError();
|
||||
|
||||
@@ -67,6 +67,19 @@ export class DataAccessorBasedStore implements ResourceStore {
|
||||
this.auxiliaryStrategy = auxiliaryStrategy;
|
||||
}
|
||||
|
||||
public async resourceExists(identifier: ResourceIdentifier): Promise<boolean> {
|
||||
try {
|
||||
this.validateIdentifier(identifier);
|
||||
await this.accessor.getMetadata(identifier);
|
||||
return true;
|
||||
} catch (error: unknown) {
|
||||
if (NotFoundHttpError.isInstance(error)) {
|
||||
return false;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public async getRepresentation(identifier: ResourceIdentifier): Promise<Representation> {
|
||||
this.validateIdentifier(identifier);
|
||||
|
||||
|
||||
@@ -35,6 +35,11 @@ export class LockingResourceStore implements AtomicResourceStore {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
public async resourceExists(identifier: ResourceIdentifier, conditions?: Conditions): Promise<boolean> {
|
||||
return this.locks.withReadLock(this.getLockIdentifier(identifier),
|
||||
async(): Promise<boolean> => this.source.resourceExists(identifier, conditions));
|
||||
}
|
||||
|
||||
public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences,
|
||||
conditions?: Conditions): Promise<Representation> {
|
||||
return this.lockedRepresentationRun(this.getLockIdentifier(identifier),
|
||||
|
||||
@@ -19,6 +19,10 @@ export class MonitoringStore<T extends ResourceStore = ResourceStore>
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public async resourceExists(identifier: ResourceIdentifier, conditions?: Conditions): Promise<boolean> {
|
||||
return this.source.resourceExists(identifier, conditions);
|
||||
}
|
||||
|
||||
public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences,
|
||||
conditions?: Conditions): Promise<Representation> {
|
||||
return this.source.getRepresentation(identifier, preferences, conditions);
|
||||
|
||||
@@ -17,6 +17,15 @@ export class PassthroughStore<T extends ResourceStore = ResourceStore> implement
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public async resourceExists(identifier: ResourceIdentifier, conditions?: Conditions): Promise<boolean> {
|
||||
return this.source.resourceExists(identifier, conditions);
|
||||
}
|
||||
|
||||
public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences,
|
||||
conditions?: Conditions): Promise<Representation> {
|
||||
return this.source.getRepresentation(identifier, preferences, conditions);
|
||||
}
|
||||
|
||||
public async addResource(container: ResourceIdentifier, representation: Representation,
|
||||
conditions?: Conditions): Promise<ResourceIdentifier> {
|
||||
return this.source.addResource(container, representation, conditions);
|
||||
@@ -27,11 +36,6 @@ export class PassthroughStore<T extends ResourceStore = ResourceStore> implement
|
||||
return this.source.deleteResource(identifier, conditions);
|
||||
}
|
||||
|
||||
public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences,
|
||||
conditions?: Conditions): Promise<Representation> {
|
||||
return this.source.getRepresentation(identifier, preferences, conditions);
|
||||
}
|
||||
|
||||
public async modifyResource(identifier: ResourceIdentifier, patch: Patch,
|
||||
conditions?: Conditions): Promise<ResourceIdentifier[]> {
|
||||
return this.source.modifyResource(identifier, patch, conditions);
|
||||
|
||||
@@ -16,6 +16,15 @@ import type { Conditions } from './Conditions';
|
||||
* should those be relevant to the store.
|
||||
*/
|
||||
export interface ResourceStore {
|
||||
|
||||
/**
|
||||
* Check if a resource exists.
|
||||
* @param identifier - Identifier of resource to check.
|
||||
*
|
||||
* @returns A promise resolving if the resource already exists
|
||||
*/
|
||||
resourceExists: (identifier: ResourceIdentifier, conditions?: Conditions) => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Retrieves a representation of a resource.
|
||||
* @param identifier - Identifier of the resource to read.
|
||||
|
||||
@@ -20,6 +20,11 @@ export class RoutingResourceStore implements ResourceStore {
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
public async resourceExists(identifier: ResourceIdentifier, conditions?: Conditions):
|
||||
Promise<boolean> {
|
||||
return (await this.getStore(identifier)).resourceExists(identifier, conditions);
|
||||
}
|
||||
|
||||
public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences,
|
||||
conditions?: Conditions): Promise<Representation> {
|
||||
return (await this.getStore(identifier)).getRepresentation(identifier, preferences, conditions);
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { NotFoundHttpError } from '../util/errors/NotFoundHttpError';
|
||||
import type { ResourceStore } from './ResourceStore';
|
||||
|
||||
export async function containsResource(store: ResourceStore, identifier: ResourceIdentifier): Promise<boolean> {
|
||||
try {
|
||||
const result = await store.getRepresentation(identifier, {});
|
||||
result.data.destroy();
|
||||
return true;
|
||||
} catch (error: unknown) {
|
||||
if (NotFoundHttpError.isInstance(error)) {
|
||||
return false;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Representation } from '../../ldp/representation/Representation';
|
||||
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
|
||||
import { containsResource } from '../../storage/StoreUtil';
|
||||
import type { ResourceStore } from '../ResourceStore';
|
||||
import type { PreferenceSupport } from './PreferenceSupport';
|
||||
import { RouterRule } from './RouterRule';
|
||||
@@ -40,8 +39,7 @@ export class ConvertingRouterRule extends RouterRule {
|
||||
entry.supportChecker.supports({ identifier, representation }));
|
||||
} else {
|
||||
// No content-type given so we can only check if one of the stores has data for the identifier
|
||||
store = await this.findStore(async(entry): Promise<boolean> =>
|
||||
containsResource(entry.store, input.identifier));
|
||||
store = await this.findStore(async(entry): Promise<boolean> => entry.store.resourceExists(input.identifier));
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user