import mongo from "mongodb"; import {tryQuery} from "../database"; import {InvalidIdError, MongoError} from "../errors"; import ActiveRecord, {ActiveRecordId} from "../Objects/ActiveRecord"; abstract class MongoStoredObjectCollection { protected constructor(protected mongoDbClientCollection: mongo.Collection) {} protected async mongoCreate(objectData: Omit): Promise { return tryQuery(async () => { const insertOneWriteOpResult = await this.mongoDbClientCollection.insertOne(objectData); if (insertOneWriteOpResult.result.ok === 1) { return insertOneWriteOpResult.ops[0] } else { throw new MongoError(`Error creating the object: ${JSON.stringify(objectData)}`); } }); } protected async mongoRead(id: string): Promise { return tryQuery(async () => { const result = await this.mongoDbClientCollection.findOne({_id: id}); if (result) { return result; } else { throw new InvalidIdError(`Object in collection "${typeof this}" with id ${JSON.stringify(id)} not found!`); } }); } protected async mongoFindByAttribute(attribute: string, value: any): Promise { return tryQuery(async () => await this.mongoDbClientCollection.findOne({[attribute]: value}) ); } protected async mongoDelete(objectId: ActiveRecordId, returnObject?: boolean): Promise { let deletedObject; if (returnObject ?? true) { deletedObject = await this.mongoRead(objectId); } const deleteWriteOpResult = await this.mongoDbClientCollection.deleteOne({_id: objectId}); if (deleteWriteOpResult.result.ok === 1) { return deletedObject; } else { throw new MongoError(`Error deleting the object in collection "${typeof this}" with id: ${JSON.stringify(objectId)}`); } } protected async mongoUpdate(object: Partial & {id: ActiveRecordId}) { await tryQuery(() => this.mongoDbClientCollection.findOneAndUpdate({_id: object.id}, {$set: {...object, id: undefined}}) ); } protected idFromRecordOrId(recordOrRecordId: T | ActiveRecordId): ActiveRecordId { return typeof recordOrRecordId === "string" ? recordOrRecordId : recordOrRecordId.getId(); } } export default MongoStoredObjectCollection;