mysql-models-orm
Version:
An ORM packacge based on models.
231 lines (209 loc) • 5.83 kB
JavaScript
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;