Files
kadi_backend/src/models/utils.ts

109 lines
2.8 KiB
TypeScript

import mongo, {MongoClient, Db} from "mongodb";
import Settings from "../server-config.json";
let SessionDbClient: Db;
export async function initMongoSessionClient() {
if (SessionDbClient === undefined) {
const client = await MongoClient.connect(Settings.mongodb_uri, {useUnifiedTopology: true});
SessionDbClient = client.db();
}
return SessionDbClient;
}
export function getMongoObjectCollection(collectionName: string) {
if (SessionDbClient === undefined) {
throw new MongoError("Cannot retrieve a collection before the session client has been initialised!");
}
else {
return SessionDbClient.collection(collectionName);
}
}
export interface StoredObjectCollection<K> {
findById(id: string): Promise<K>;
}
export abstract class MongoStoredObjectCollection<T extends MongoStoredObject<any>, K extends StoredObject> implements StoredObjectCollection<K> {
protected mongoDbClientCollection: mongo.Collection;
protected constructor(collectionClient: mongo.Collection) {
this.mongoDbClientCollection = collectionClient;
}
protected async findObjectById(id: string): Promise<any | null> {
return this.mongoDbClientCollection!.findOne({_id: id});
}
abstract async findById(id: string): Promise<K>;
async save(...objects: T[]): Promise<void> {
for (const object of objects) {
await this.mongoDbClientCollection.findOneAndUpdate({_id: object.id()}, {...object.rawData()});
}
}
}
export interface StoredObject {
id(): string;
rawData(): any;
}
export abstract class MongoStoredObject<T> implements StoredObject {
protected constructor(protected data: {_id: string} & T) {}
id(): string {
return this.data._id;
}
rawData(): T {
return this.data;
}
}
export class MongoError extends Error {
constructor(message: string) {
super(message);
this.name = "MongoError";
}
}
export class GenericModelError extends MongoError {
constructor(message: string) {
super(message);
this.name = "GenericModelError";
}
}
export class ModelParameterError extends GenericModelError {
constructor(message: string) {
super(message);
this.name = "ModelParameterError";
}
}
type CallbackWrapper = <T>(query: () => T) => Promise<any>;
export const tryQuery: CallbackWrapper = async (cb) => {
try {
return cb();
}
catch (err) {
throw new GenericModelError(err);
}
};
export const globalSchemaOptions = {
toObject: {
transform: function (doc: any, ret: any) {
ret.id = ret._id;
delete ret._id;
delete ret.__v;
}
},
toJSON: {
transform: function (doc: any, ret: any) {
ret.id = ret._id;
delete ret._id;
delete ret.__v;
},
}
};