UNPKG

mysql-models-orm

Version:

An ORM packacge based on models.

231 lines (209 loc) 5.83 kB
const DB = require("./mysql"); class Model { #table = ""; #primaryKey = "id"; #searchBy = "id"; #modelProperties = {}; #timestamps = ["updated_at", "created_at"]; #defaultProperties = {}; original = {}; constructor() { this.#setTable(); } getTable() { return this.#table; } #setTable() { if (this.table) { this.#table = this.table; } else { this.#table = this.constructor.name .split(/(?=[A-Z])/) .join("_") .toLowerCase(); if (!this.#table.endsWith("s")) this.#table += "s"; if ("timestamps" in this) { this.#timestamps = this.timestamps; } } } #setDefaultProperties() { const defaults = { ...this.defaultProperties }; const timestamps = this.timestamps ? this.timestamps : this.#timestamps; timestamps.forEach((timestamp) => { if (!defaults[timestamp]) { defaults[timestamp] = "CURRENT_TIMESTAMP()"; } }); this.#defaultProperties = defaults; } #beforeSave() { this.#setDefaultProperties(); this.#modelProperties = this.#defaultProperties; if (!this[this.#primaryKey] && this.original[this.#primaryKey]) { this[this.#primaryKey] = this.original[this.#primaryKey]; } for (const prop in this.properties) { this.#modelProperties[prop] = this.properties[prop]; } for (const prop in this.#modelProperties) { if (this.#modelProperties[prop] instanceof Date) { // Do nothing } else if (typeof this.#modelProperties[prop] === "object") { this.#modelProperties[prop] = JSON.stringify( this.#modelProperties[prop] ); } else if (typeof this.#modelProperties[prop] === "array") { this.#modelProperties[prop] = JSON.stringify( this.#modelProperties[prop] ); } } } static async getAll() { const table = new this().getTable(); const all = await new DB().table(table).selectAll().send(); let models = []; all.forEach((data) => { const model = new this(); model.original = data; model.#postGet(); models.push(model); }); return models; } static async getAllWhere(key, value) { const table = new this().getTable(); const all = await new DB() .table(table) .selectAll() .where(key, value) .send(); if (all.length) { const instances = []; all.forEach((filter) => { const instance = new this(); instance.original = { ...filter }; instances.push(instance); }); return instances; } else { return []; } // return instance; } static async getWhere(key, value) { const instance = new this(); instance.original = await new DB() .table(instance.getTable()) .selectAll() .where(key, value) .limit(1) .send(); return instance; } async save() { this.#setTable(); this.#beforeSave(); } #preGet() { this.#primaryKey = this.primaryKey ? this.primaryKey : this.#primaryKey; } async #postGet() { if (typeof this.postGet === "function") { await this.postGet(); } } async get() { this.#setTable(); this.#preGet(); this.original = await new DB() .table(this.#table) .selectAll() .where(this.#primaryKey, this[this.#primaryKey]) .limit(1) .send(); await this.#postGet(); return this; } #preUpdate() { this.#primaryKey = this.primaryKey ? this.primaryKey : this.#primaryKey; if (typeof this.preUpdate === "function") { this.preUpdate(); } this.#beforeSave(); if ("created_at" in this.#modelProperties) { delete this.#modelProperties.created_at; } } #preCreate() { this.#primaryKey = this.primaryKey ? this.primaryKey : this.#primaryKey; if (typeof this.preCreate === "function") { this.preCreate(); } this.#beforeSave(); } async #postUpdate() { for (const key in this.#modelProperties) { if (key !== "updated_at") { this.original[key] = this.#modelProperties[key]; } } if (typeof this.postUpdate === "function") { await this.postUpdate(); } } async #postCreate() { for (const key in this.#modelProperties) { if (key !== "updated_at") { this.original[key] = this.#modelProperties[key]; } } if (typeof this.postCreate === "function") { await this.postCreate(); } } async update() { this.#setTable(); this.#preUpdate(); await new DB() .table(this.#table) .where(this.#primaryKey, this[this.#primaryKey]) .update(this.#modelProperties) .send(); await this.#postUpdate(); return this; } async updateOrCreate() { this.#setTable(); this.#preUpdate(); const updatedRes = await new DB() .table(this.#table) .where(this.#primaryKey, this[this.#primaryKey]) .update(this.#modelProperties) .send(); // console.log("updatedRes", this.mac); if (updatedRes.affectedRows == 0) { this.#preCreate(); const insertData = { ...{ [this.#primaryKey]: this[this.#primaryKey] }, ...this.#modelProperties, }; await new DB().table(this.#table).insert(insertData).send(); console.log( "Created new row in ", this.#table, ", Key:", this[this.#primaryKey] ); await this.#postCreate(); } else { await this.#postUpdate(); } return this; } toJSON() { return this.original; } } module.exports = Model;