@smallprod/models
Version:
254 lines (253 loc) • 12.2 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const global_sql_1 = __importDefault(require("./global.sql"));
const mysql_1 = __importDefault(require("mysql"));
const getPool = async (config) => {
return new Promise((resolve, reject) => {
const pool = mysql_1.default.createPool(config);
pool.getConnection((err, connection) => {
if (err)
return reject(err);
resolve(pool);
});
});
};
class GlobalMariaModel extends global_sql_1.default {
constructor() {
super(...arguments);
this.pool = null;
this.transactionConnection = null;
this.disconnect = async () => {
var _a;
(_a = this.pool) === null || _a === void 0 ? void 0 : _a.end();
return Promise.resolve();
};
this.query = async (query, params, throwErrors = false) => {
return new Promise(async (resolve) => {
if (!this.pool) {
if (GlobalMariaModel.debug)
console.error('No pool');
if (throwErrors)
throw Error('No pool');
return resolve(null);
}
let connection;
if (this.transactionConnection) {
connection = this.transactionConnection;
}
else {
connection = await this.getConnection();
}
if (!connection) {
if (GlobalMariaModel.debug)
console.error('Cannot get connection');
if (throwErrors) {
throw Error('Cannot get connection');
}
return resolve(null);
}
connection.query(query, params, (error, results, fields) => {
if (connection && !this.transactionConnection)
connection.release();
if (error) {
if (GlobalMariaModel.debug) {
console.error(error);
}
if (throwErrors) {
throw error;
}
return resolve(null);
}
resolve(results);
});
});
};
this.insert = async (tableName, attributes) => {
var _a;
const columns = attributes.map((a) => `\`${a.column}\``).join(', ');
const params = attributes.map((a, index) => `?`).join(', ');
const query = `INSERT INTO \`${tableName}\` (${columns}) VALUES (${params})`;
return (_a = (await this.query(query, attributes.map((a) => a.value)))) === null || _a === void 0 ? void 0 : _a.insertId;
};
this.select = async (tableName, distinct = false, attributes = [], wheres = [], sorts = [], tableAlias = '', limit = -1, offset = 0, joins = [], groups = [], havings = []) => {
const query = `SELECT${distinct ? ' DISTINCT' : ''}${this.computeAttributes(attributes, '`')} FROM \`${tableName}\` ${tableAlias ? `AS ${tableAlias}` : ''} ${this.computeJoins(joins, '`', 'AS')}${this.computeWhere(wheres, '?', false, '`')}${this.computeGroupBy(groups)}${this.computeWhere(havings, '?', false, '`', 'HAVING')}${this.computeSort(sorts, '`')}${limit !== -1 ? ` LIMIT ${offset}, ${limit}` : ''}`;
const havingAttr = this.getWhereAttributes(havings);
return await this.query(query, havingAttr.concat(this.getWhereAttributes(wheres)));
};
this.update = async (tableName, attributes, wheres) => {
var _a;
const columns = attributes.map((a) => `\`${a.column}\` = ?`).join(', ');
const query = `UPDATE \`${tableName}\` SET ${columns} ${this.computeWhere(wheres, '?', false, '`')}`;
return (_a = (await this.query(query, attributes.map((a) => a.value).concat(this.getWhereAttributes(wheres))))) === null || _a === void 0 ? void 0 : _a.affectedRows;
};
this.delete = async (tableName, wheres) => {
const query = `DELETE FROM \`${tableName}\` ${this.computeWhere(wheres, '?', false, '`')}`;
return (await this.query(query, this.getWhereAttributes(wheres)))
.affectedRows;
};
this.createTable = async (tableName, fields) => {
const query = `CREATE TABLE ${tableName} (${fields
.map((f) => this.formatFieldForTableManagement(f))
.join(', ')})`;
await this.query(query);
await fields.reduce(async (prevField, curField) => {
await prevField;
const constraints = this.getFieldConstraintsForTableManagement(curField, tableName);
await constraints.reduce(async (prevConst, curConst) => {
await prevConst;
await this.query(curConst);
}, Promise.resolve());
}, Promise.resolve());
};
this.removeTable = async (tableName) => {
const query = `DROP TABLE ${tableName}`;
return await this.query(query);
};
this.alterTable = async (tableName, fieldsToAdd, fieldsToRemove) => {
await fieldsToRemove.reduce(async (prev, cur) => {
await prev;
const query = `ALTER TABLE ${tableName} DROP COLUMN ${cur}`;
await this.query(query);
}, Promise.resolve());
await fieldsToAdd.reduce(async (prev, cur) => {
await prev;
const query = `ALTER TABLE ${tableName} ADD ${this.formatFieldForTableManagement(cur)}`;
await this.query(query);
const constraints = this.getFieldConstraintsForTableManagement(cur, tableName);
await constraints.reduce(async (prevConst, curConst) => {
await prevConst;
await this.query(curConst);
}, Promise.resolve());
}, Promise.resolve());
};
this.startTransaction = async () => {
return new Promise((resolve, reject) => {
if (this.transactionConnection) {
if (GlobalMariaModel.debug)
console.error('Already in a transaction');
return resolve(false);
}
if (!this.pool) {
if (GlobalMariaModel.debug)
console.error('No pool');
return resolve(false);
}
this.pool.getConnection((err, connection) => {
if (err) {
if (GlobalMariaModel.debug)
console.error(err);
return resolve(false);
}
connection.beginTransaction((error) => {
if (error) {
return resolve(false);
}
this.transactionConnection = connection;
return resolve(true);
});
});
});
};
this.commit = async () => {
return new Promise((resolve, reject) => {
if (!this.transactionConnection) {
if (GlobalMariaModel.debug)
console.error('Not in a transaction');
return resolve();
}
this.transactionConnection.commit((err) => {
var _a, _b;
if (err) {
if (GlobalMariaModel.debug)
console.error(err);
(_a = this.transactionConnection) === null || _a === void 0 ? void 0 : _a.rollback(() => {
var _a;
(_a = this.transactionConnection) === null || _a === void 0 ? void 0 : _a.release();
this.transactionConnection = null;
resolve();
});
}
else {
(_b = this.transactionConnection) === null || _b === void 0 ? void 0 : _b.release();
}
this.transactionConnection = null;
resolve();
});
});
};
this.rollback = async () => {
return new Promise((resolve) => {
if (!this.transactionConnection) {
if (GlobalMariaModel.debug)
console.error('Not in a transaction');
return resolve();
}
this.transactionConnection.rollback((err) => {
var _a;
(_a = this.transactionConnection) === null || _a === void 0 ? void 0 : _a.release();
this.transactionConnection = null;
if (err) {
if (GlobalMariaModel.debug)
console.error(err);
}
resolve();
});
});
};
this.checkMigrationTable = async () => {
const res = await this.query('SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = "migrations"');
return res && res.length;
};
this.setPool = async (config) => {
try {
const p = await getPool(config);
if (p) {
this.pool = p;
}
}
catch (err) {
console.error('Cannot connect to database');
console.error(err);
console.log(config);
}
};
this.getConnection = () => {
return new Promise((resolve, reject) => {
var _a;
(_a = this.pool) === null || _a === void 0 ? void 0 : _a.getConnection((err, connection) => {
if (err) {
return resolve(null);
}
return resolve(connection);
});
});
};
this.formatFieldForTableManagement = (field) => {
const fInfos = field.getAll();
return `${fInfos.name} ${fInfos.type}${fInfos.len !== 0 ? `(${fInfos.len})` : ''}${fInfos.null ? '' : ' NOT NULL'}${fInfos.ai ? ' AUTO_INCREMENT' : ''}${fInfos.primaryKey ? ' PRIMARY KEY' : ''}`;
};
this.getFieldConstraintsForTableManagement = (field, tableName) => {
const fieldInfos = field.getAll();
const constraints = [];
if (fieldInfos.mustBeUnique || fieldInfos.primaryKey) {
constraints.push(`ALTER TABLE ${tableName} ADD CONSTRAINT unique_${tableName.toLowerCase()}_${fieldInfos.name.toLowerCase()} UNIQUE (${fieldInfos.name})`);
}
if (fieldInfos.checkValue) {
constraints.push(`ALTER TABLE ${tableName} ADD CONSTRAINT check_${tableName.toLowerCase()}_${fieldInfos.name.toLowerCase()} CHECK(${fieldInfos.name}${fieldInfos.checkValue})`);
}
if (fieldInfos.defaultValue) {
constraints.push(`ALTER TABLE ${tableName} ALTER ${fieldInfos.name} SET DEFAULT ${fieldInfos.defaultValue.isSystem
? `${fieldInfos.defaultValue.value}`
: `'${fieldInfos.defaultValue.value}'`};`);
}
if (fieldInfos.foreignKey) {
constraints.push(`ALTER TABLE ${tableName} ADD CONSTRAINT fk_${tableName.toLowerCase()}_${fieldInfos.name.toLowerCase()} FOREIGN KEY (${fieldInfos.name}) REFERENCES ${fieldInfos.foreignKey.table}(${fieldInfos.foreignKey.column})`);
}
return constraints;
};
}
}
exports.default = GlobalMariaModel;