UNPKG

@melchyore/adonis-cache

Version:
196 lines (195 loc) 6.69 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const luxon_1 = require("luxon"); const BaseStore_1 = __importDefault(require("./BaseStore")); class Database extends BaseStore_1.default { constructor(connection, table) { super(); this.connection = connection; this.table = table; } async get(key) { try { const record = (await this.connection .from(this.table) .where('key', this.buildKey(key)) .firstOrFail()); if (this.isStaleRecord(record)) { await this.forget(key); return null; } return this.deserialize(record.value); } catch { return null; } } async many(keys) { const records = await this.connection .from(this.table) .whereIn('key', keys.map((key) => this.buildKey(key))) .andWhere('expiration', '>', luxon_1.DateTime.now().toISO()) .orWhereNull('expiration'); const values = records.reduce((accumulator, record) => { accumulator[record.key.replace(this.prefix, '')] = this.deserialize(record.value); return accumulator; }, {}); const result = {}; keys.forEach((key) => { result[key] = values[key] ?? null; }); return result; } async has(key) { try { const record = await this.connection .from(this.table) .where('key', this.buildKey(key)) .firstOrFail(); if (this.isStaleRecord(record)) { await this.forget(key); return false; } return true; } catch { return false; } } async put(key, value, ttl) { return ((await this.insert(key, value, luxon_1.DateTime.now().plus({ milliseconds: ttl }).toISO())) >= 1); } /** * Store a new item in the cache if the key doesn't exist. * Otherwise, update a stale item with a value and a new TTL. */ async add(_key, value, ttl) { const key = this.buildKey(_key); const val = this.serialize(value); const expiration = luxon_1.DateTime.now().plus({ milliseconds: ttl }).toISO(); let result = []; try { result = await this.connection.table(this.table).insert({ key, value: val, expiration }); } catch { result = await this.connection .from(this.table) .where('key', key) .andWhere('expiration', '<', luxon_1.DateTime.now().toISO()) .update({ value: val, expiration }); } return this.getResultNumber(result) >= 1; } async putMany(list, ttl) { const promiseArray = []; for (const [key, value] of Object.entries(list)) { promiseArray.push(this.put(key, value, ttl)); } return Promise.all(promiseArray); } async increment(key, value) { return await this.incrementValue(key, value); } async decrement(key, value) { return await this.decrementValue(key, value); } async putManyForever(list) { const promiseArray = []; for (const [key, value] of Object.entries(list)) { promiseArray.push(this.forever(key, value)); } return Promise.all(promiseArray); } async forever(key, value) { return (await this.insert(key, value)) === 1; } async forget(key) { return (this.getResultNumber(await this.connection.from(this.table).where('key', this.buildKey(key)).delete()) > 0); } async flush() { await this.connection.from(this.table).delete(); return true; } async insert(_key, val, expiration) { const key = this.buildKey(_key); const value = this.serialize(val); let result; try { result = await this.connection.table(this.table).insert({ key, value, expiration }); } catch { result = await this.connection.from(this.table).where('key', key).update({ value, expiration }); } return this.getResultNumber(result); } async incrementValue(_key, value) { const key = this.buildKey(_key); const incrementedValue = await this.connection.transaction(async (trx) => { try { const record = await trx.from(this.table).where('key', key).firstOrFail(); const previousValue = this.deserialize(record.value); if (isNaN(previousValue)) { return false; } const newValue = previousValue + value; await trx.from(this.table).where('key', key).update({ value: newValue }); return newValue; } catch { return false; } }); return incrementedValue; } async decrementValue(_key, value) { const key = this.buildKey(_key); const decrementedValue = await this.connection.transaction(async (trx) => { try { const record = await trx.from(this.table).where('key', key).firstOrFail(); const previousValue = this.deserialize(record.value); if (isNaN(previousValue)) { return false; } const newValue = previousValue - value; await trx.from(this.table).where('key', key).update({ value: newValue }); return newValue; } catch { return false; } }); return decrementedValue; } /** * Check if query result is an Array or a number. * If it's an array, return its length. */ getResultNumber(result) { if (Array.isArray(result)) { return result.length; } return result; } } exports.default = Database;