UNPKG

tspace-mysql

Version:

Tspace MySQL is a promise-based ORM for Node.js, designed with modern TypeScript and providing type safety for schema databases.

175 lines 6.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DBCache = void 0; const Model_1 = require("../Model"); const DB_1 = require("../DB"); const Blueprint_1 = require("../Blueprint"); const utils_1 = require("../../utils"); const constants_1 = require("../../constants"); class DBCache { _cacheTable = '$cache'; _v0x = 'v0x'; _maxAddress = 10; _maxLength = 100; _db = () => new DB_1.DB(this._cacheTable); provider() { return 'db'; } async all() { const cacheds = await this._db().get(); const values = []; for (const cached of cacheds) { for (let i = 0; i < this._maxAddress; i++) { const find = cached[this._addressNumber(i)]; if (find == null || find === '') break; if (Number.isNaN(+cached.expiredAt) || new Date() > new Date(+cached.expiredAt)) { await this._db() .where('key', cached.key) .delete(); continue; } const maybeArray = this._safetyJsonParse(find); if (Array.isArray(maybeArray)) { values.push(...this._safetyJsonParse(find)); continue; } values.push(this._safetyJsonParse(find)); } } return values; } async exists(key) { const cached = await this._db().where('key', key).exists(); return cached; } async get(key) { try { const addresses = Array.from({ length: this._maxAddress }, (_, i) => this._addressNumber(i)); const cached = await this._db().select('expiredAt', ...addresses).where('key', key).findOne(); if (!cached) return null; const now = Date.now(); const expiredAt = +cached.expiredAt; if (Number.isNaN(expiredAt) || now > expiredAt) { await this._db() .where('key', key) .deleteMany(); return null; } const value = this._safetyJsonParse(cached[this._addressNumber(0)]); if (!Array.isArray(value)) return value; const values = []; for (let i = 0; i < this._maxAddress; i++) { const find = cached[this._addressNumber(i)]; if (find == null || find === '') break; const parsed = this._safetyJsonParse(find); if (Array.isArray(parsed)) { values.push(...parsed); continue; } values.push(parsed); } return values.length === 1 ? values[0] : values; } catch (err) { const message = String(err?.message ?? ''); if (message.toLocaleLowerCase().includes("doesn't exist")) { await this._checkTableCacheExists(); return await this.get(key); } throw err; } } async set(key, value, ms) { const expiredAt = +new Date() + ms; if (!Array.isArray(value)) { await this._db() .create({ key, [this._addressNumber(0)]: JSON.stringify(value), expiredAt, createdAt: utils_1.utils.timestamp(), updatedAt: utils_1.utils.timestamp() }) .void() .save(); return; } const avg = value.length / this._maxAddress; const chunked = utils_1.utils.chunkArray(value, avg > this._maxLength ? avg : this._maxLength); const caches = {}; for (const [index, value] of chunked.entries()) { caches[this._addressNumber(index)] = JSON.stringify(value); } await this._db() .create({ key, ...caches, expiredAt, createdAt: utils_1.utils.timestamp(), updatedAt: utils_1.utils.timestamp() }) .void() .save(); return; } async clear() { await this._db().truncate({ force: true }); return; } async delete(key) { await this._db().where('key', key).delete(); return; } _addressNumber(number) { const index = `0${number}`.slice(-2); return `${this._v0x}${index}`; } async _checkTableCacheExists() { const table = this._cacheTable; const checkTables = await DB_1.DB.rawQuery(`${constants_1.CONSTANTS.SHOW_TABLES} ${constants_1.CONSTANTS.LIKE} '${table}'`); const existsTables = checkTables.map((c) => Object.values(c)[0])[0]; if (existsTables != null) return; let addresses = {}; for (let i = 0; i < this._maxAddress; i++) { addresses[this._addressNumber(i)] = new Blueprint_1.Blueprint().json().null(); } const schema = { id: new Blueprint_1.Blueprint().int().notNull().primary().autoIncrement(), key: new Blueprint_1.Blueprint().varchar(255).notNull().index(), ...addresses, expiredAt: new Blueprint_1.Blueprint().bigInt().notNull(), createdAt: new Blueprint_1.Blueprint().timestamp().notNull(), updatedAt: new Blueprint_1.Blueprint().timestamp().notNull() }; class Cache extends Model_1.Model { boot() { this.useSchema(schema); this.useTable(table); } } await new Cache().sync({ index: true }); return; } _safetyJsonParse(value) { if (typeof value !== 'string') return value; const v = value.trim(); if (!v || (v[0] !== '{' && v[0] !== '[')) return value; try { return JSON.parse(v); } catch { return value; } } } exports.DBCache = DBCache; exports.default = DBCache; //# sourceMappingURL=DBCache.js.map