diff options
author | Samuel <34555296+Flam3rboy@users.noreply.github.com> | 2023-03-18 04:11:48 +0100 |
---|---|---|
committer | Samuel <34555296+Flam3rboy@users.noreply.github.com> | 2023-03-18 04:11:48 +0100 |
commit | 366c4935a42d5056c51cdbd7c82c2674f1b8b128 (patch) | |
tree | 7c3cdc444536d8b1065c9f98d96355d0f5276704 /src/util/cache/Cache.ts | |
parent | fix: package-lock.json (diff) | |
download | server-366c4935a42d5056c51cdbd7c82c2674f1b8b128.tar.xz |
feat: Database Query Cache
Diffstat (limited to 'src/util/cache/Cache.ts')
-rw-r--r-- | src/util/cache/Cache.ts | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/util/cache/Cache.ts b/src/util/cache/Cache.ts new file mode 100644 index 00000000..fb66c2e3 --- /dev/null +++ b/src/util/cache/Cache.ts @@ -0,0 +1,85 @@ +/* + Fosscord: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2023 Fosscord and Fosscord Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { EntityMetadata, FindOptionsWhere } from "typeorm"; +import { LocalCache } from "./LocalCache"; + +declare module "typeorm" { + interface BaseEntity { + metadata?: EntityMetadata; + cache: CacheManager; + } +} + +export type BaseEntityWithId = { id: string; [name: string]: any }; +export type Criteria = + | string + | string[] + | number + | number[] + | FindOptionsWhere<never>; + +export interface Cache { + get(id: string): BaseEntityWithId | undefined; + set(id: string, entity: BaseEntityWithId): this; + find(options: Record<string, never>): BaseEntityWithId | undefined; + filter(options: Record<string, never>): BaseEntityWithId[]; + delete(id: string): boolean; +} + +export class CacheManager { + // last access time to automatically remove old entities from cache after 5 minutes of inactivity (to prevent memory leaks) + cache: Cache; + + constructor() { + this.cache = new LocalCache(); + // TODO: Config.get().cache.redis; + } + + delete(id: string) { + return this.cache.delete(id); + } + + insert(entity: BaseEntityWithId) { + if (!entity.id) return; + + return this.cache.set(entity.id, entity); + } + + find(options?: Record<string, never>, select?: string[] | undefined) { + if (!options) return null; + const entity = this.cache.find(options); + if (!entity) return null; + if (!select) return entity; + + const result = {}; + for (const prop of select) { + // @ts-ignore + result[prop] = entity[prop]; + } + + // @ts-ignore + return entity.constructor.create(result); + } + + filter(options: Record<string, never>) { + return this.cache.filter(options); + } +} |