Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 2x 8x 8x 1x 7x 7x 5x 4x 5x 3x 6x 3x 2x 4x 4x 1x 1x 1x 2x 1x 1x 1x 1x 2x 1x | import { Schema, mongoose } from "mongoose";
import { ModelException } from "@common/exceptions/appExceptions.js";
import { newLogger } from "@common/utils/logger.js";
const logger = newLogger("Model|BaseModel");
// This class and all its children are instantiated as a promise
export default class BaseModel {
#model; // Mongoose Model class see: https://mongoosejs.com/docs/models.html
#doc; // Mongoose Document class see: https://mongoosejs.com/docs/documents.html
constructor(id) {
// Immediately Invoked Async Function Expression ;)
return (async () => {
// Throw an exception for models without schema
if (!(this.constructor.SCHEMA instanceof Schema)) {
throw new ModelException({ message: `Model "${this.constructor.name}" must have a valid schema` });
}
// Create and store the Mongoose model for this collection
this.#model = mongoose.model(this.constructor.name, this.constructor.SCHEMA);
// Existing document
if (id) {
if (mongoose.isValidObjectId(id)) {
// Don't try to find if it's not even a validObjectId
this.#doc = await this.#model.findById(id);
}
// Copy the properties from the Mongoose doc to the model object
if (this.#doc) {
for (let k in this.#doc._doc) {
this[k] = this.#doc._doc[k];
}
return this;
}
logger.info("Document not found. Creating a new one.");
}
// New document
this.#doc = new this.#model();
return this;
})().catch((err) => {
logger.error("%s", err);
throw new ModelException({ message: err });
});
}
async save() {
// Copy the model object properties back to Moongose doc
for (let k in this) {
this.#doc[k] = this[k];
}
await this.#doc.save();
this._id = this.#doc._id;
}
async delete() {
await this.#doc.deleteOne();
for (let k in this) {
delete this[k];
}
this.#doc = this.#model = null;
}
async find(filter) {
return await this.#model.find(filter);
}
// Returns all distinct data in the specified field and returns in an array
async distinct(field) {
return await this.#model.distinct(field);
}
}
|