2020-11-02 06:58:23 +00:00
|
|
|
import { Collection } from '../utils/collection.ts'
|
|
|
|
import {
|
|
|
|
connect,
|
|
|
|
Redis,
|
|
|
|
RedisConnectOptions
|
|
|
|
} from 'https://denopkg.com/keroxp/deno-redis/mod.ts'
|
2020-10-31 11:45:33 +00:00
|
|
|
|
|
|
|
export interface ICacheAdapter {
|
2020-11-01 11:22:09 +00:00
|
|
|
get: (cacheName: string, key: string) => Promise<any> | any
|
|
|
|
set: (cacheName: string, key: string, value: any) => Promise<any> | any
|
|
|
|
delete: (cacheName: string, key: string) => Promise<boolean> | boolean
|
2020-11-02 16:31:10 +00:00
|
|
|
array: (cacheName: string) => undefined | any[] | Promise<any[] | undefined>
|
2020-11-02 12:08:38 +00:00
|
|
|
deleteCache: (cacheName: string) => any
|
2020-10-31 11:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export class DefaultCacheAdapter implements ICacheAdapter {
|
|
|
|
data: {
|
|
|
|
[name: string]: Collection<string, any>
|
|
|
|
} = {}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async get (cacheName: string, key: string): Promise<undefined | any> {
|
2020-10-31 13:00:33 +00:00
|
|
|
const cache = this.data[cacheName]
|
2020-11-02 06:58:23 +00:00
|
|
|
if (cache === undefined) return
|
2020-10-31 11:45:33 +00:00
|
|
|
return cache.get(key)
|
|
|
|
}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async set (cacheName: string, key: string, value: any): Promise<any> {
|
2020-10-31 11:45:33 +00:00
|
|
|
let cache = this.data[cacheName]
|
2020-11-02 06:58:23 +00:00
|
|
|
if (cache === undefined) {
|
2020-10-31 11:45:33 +00:00
|
|
|
this.data[cacheName] = new Collection()
|
|
|
|
cache = this.data[cacheName]
|
|
|
|
}
|
2020-11-02 06:58:23 +00:00
|
|
|
return cache.set(key, value)
|
2020-10-31 11:45:33 +00:00
|
|
|
}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async delete (cacheName: string, key: string): Promise<boolean> {
|
2020-10-31 13:00:33 +00:00
|
|
|
const cache = this.data[cacheName]
|
2020-11-02 06:58:23 +00:00
|
|
|
if (cache === undefined) return false
|
2020-10-31 11:45:33 +00:00
|
|
|
return cache.delete(key)
|
|
|
|
}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async array (cacheName: string): Promise<any[] | undefined> {
|
2020-10-31 13:00:33 +00:00
|
|
|
const cache = this.data[cacheName]
|
2020-11-02 06:58:23 +00:00
|
|
|
if (cache === undefined) return
|
2020-10-31 11:45:33 +00:00
|
|
|
return cache.array()
|
|
|
|
}
|
2020-11-02 12:08:38 +00:00
|
|
|
|
2020-11-03 09:21:29 +00:00
|
|
|
async deleteCache(cacheName: string): Promise<boolean> {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
2020-11-02 12:08:38 +00:00
|
|
|
return delete this.data[cacheName]
|
|
|
|
}
|
2020-11-01 11:22:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export class RedisCacheAdapter implements ICacheAdapter {
|
|
|
|
_redis: Promise<Redis>
|
|
|
|
redis?: Redis
|
|
|
|
ready: boolean = false
|
|
|
|
|
2020-11-06 08:27:56 +00:00
|
|
|
constructor (options: RedisConnectOptions) {
|
2020-11-01 11:22:09 +00:00
|
|
|
this._redis = connect(options)
|
2020-11-02 06:58:23 +00:00
|
|
|
this._redis.then(
|
|
|
|
redis => {
|
|
|
|
this.redis = redis
|
|
|
|
this.ready = true
|
|
|
|
},
|
|
|
|
() => {
|
|
|
|
// TODO: Make error for this
|
|
|
|
}
|
|
|
|
)
|
2020-11-01 11:22:09 +00:00
|
|
|
}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async _checkReady (): Promise<void> {
|
|
|
|
if (!this.ready) await this._redis
|
2020-11-01 11:22:09 +00:00
|
|
|
}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async get (cacheName: string, key: string): Promise<string | undefined> {
|
2020-11-01 11:22:09 +00:00
|
|
|
await this._checkReady()
|
2020-11-02 06:58:23 +00:00
|
|
|
const cache = await this.redis?.hget(cacheName, key)
|
|
|
|
if (cache === undefined) return
|
2020-11-01 11:22:09 +00:00
|
|
|
try {
|
2020-11-02 06:58:23 +00:00
|
|
|
return JSON.parse(cache)
|
|
|
|
} catch (e) {
|
|
|
|
return cache
|
|
|
|
}
|
2020-11-01 11:22:09 +00:00
|
|
|
}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async set (
|
|
|
|
cacheName: string,
|
|
|
|
key: string,
|
|
|
|
value: any
|
|
|
|
): Promise<number | undefined> {
|
2020-11-01 11:22:09 +00:00
|
|
|
await this._checkReady()
|
2020-11-02 06:58:23 +00:00
|
|
|
const result = await this.redis?.hset(
|
|
|
|
cacheName,
|
|
|
|
key,
|
|
|
|
typeof value === 'object' ? JSON.stringify(value) : value
|
|
|
|
)
|
|
|
|
return result
|
2020-11-01 11:22:09 +00:00
|
|
|
}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async delete (cacheName: string, key: string): Promise<boolean> {
|
2020-11-01 11:22:09 +00:00
|
|
|
await this._checkReady()
|
2020-11-02 06:58:23 +00:00
|
|
|
const exists = await this.redis?.hexists(cacheName, key)
|
|
|
|
if (exists === 0) return false
|
2020-11-01 11:22:09 +00:00
|
|
|
await this.redis?.hdel(cacheName, key)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2020-11-02 06:58:23 +00:00
|
|
|
async array (cacheName: string): Promise<any[] | undefined> {
|
2020-11-01 11:22:09 +00:00
|
|
|
await this._checkReady()
|
2020-11-02 06:58:23 +00:00
|
|
|
const data = await this.redis?.hvals(cacheName)
|
2020-11-01 11:22:09 +00:00
|
|
|
return data?.map((e: string) => JSON.parse(e))
|
|
|
|
}
|
2020-11-02 12:08:38 +00:00
|
|
|
|
2020-11-03 09:21:29 +00:00
|
|
|
async deleteCache(cacheName: string): Promise<boolean> {
|
2020-11-02 12:08:38 +00:00
|
|
|
await this._checkReady()
|
2020-11-03 09:21:29 +00:00
|
|
|
return await this.redis?.del(cacheName) !== 0
|
2020-11-02 12:08:38 +00:00
|
|
|
}
|
2020-11-02 06:58:23 +00:00
|
|
|
}
|