@melchyore/adonis-cache
Version:
Cache package for AdonisJS V5
196 lines (195 loc) • 6.69 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 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;