summary refs log tree commit diff
path: root/src/util/cache/EntityCache.ts
diff options
context:
space:
mode:
authorMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2023-03-31 15:26:15 +1100
committerMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2023-03-31 15:26:15 +1100
commit698ad90d3e82a15b85ceb021ad5667109ac0bcdb (patch)
tree7b79fc6d65e79af82b11d89cb1a5502a9f7bff08 /src/util/cache/EntityCache.ts
parentfix: disable cache if multi threaded (diff)
downloadserver-698ad90d3e82a15b85ceb021ad5667109ac0bcdb.tar.xz
Revert "Merge pull request #1008 from spacebarchat/dev/samuel"
This reverts commit 69ea71aa9e0bd2e5a98904a66fba0ad3745707cb, reversing
changes made to 8b2faf0b18336e5dff1eeff4e849bcfd96b09e88.
Diffstat (limited to 'src/util/cache/EntityCache.ts')
-rw-r--r--src/util/cache/EntityCache.ts162
1 files changed, 0 insertions, 162 deletions
diff --git a/src/util/cache/EntityCache.ts b/src/util/cache/EntityCache.ts
deleted file mode 100644

index ba1e5bd8..00000000 --- a/src/util/cache/EntityCache.ts +++ /dev/null
@@ -1,162 +0,0 @@ -/* - 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 */ -import { - DataSource, - FindOneOptions, - EntityNotFoundError, - FindOptionsWhere, -} from "typeorm"; -import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; -import { BaseClassWithId } from "../entities/BaseClass"; -import { Config, getDatabase, RabbitMQ } from "../util"; -import { CacheManager } from "./Cache"; - -function getObjectKeysAsArray(obj?: Record<string, any>) { - if (!obj) return []; - if (Array.isArray(obj)) return obj; - return Object.keys(obj); -} - -export type ThisType<T> = { - new (): T; -} & typeof BaseEntityCache; - -interface BaseEntityCache { - constructor: typeof BaseEntityCache; -} - -// @ts-ignore -class BaseEntityCache extends BaseClassWithId { - static cache: CacheManager; - static cacheEnabled: boolean; - - public get metadata() { - return getDatabase()?.getMetadata(this.constructor)!; - } - - static useDataSource(dataSource: DataSource | null) { - super.useDataSource(dataSource); - const isMultiThreaded = - process.env.EVENT_TRANSMISSION === "process" || RabbitMQ.connection; - this.cacheEnabled = Config.get().cache.enabled ?? !isMultiThreaded; - if (Config.get().cache.redis) return; // TODO: Redis cache - if (!this.cacheEnabled) return; - this.cache = new CacheManager(); - } - - static async findOne<T extends BaseEntityCache>( - this: ThisType<T>, - options: FindOneOptions<T>, - ) { - // @ts-ignore - if (!this.cacheEnabled) return super.findOne(options); - let select = getObjectKeysAsArray(options.select); - - if (!select.length) { - // get all columns that are marked as select - getDatabase() - ?.getMetadata(this) - .columns.forEach((x) => { - if (!x.isSelect) return; - select.push(x.propertyName); - }); - } - if (options.relations) { - select.push(...getObjectKeysAsArray(options.relations)); - } - - const cacheResult = this.cache.find(options.where as never, select); - if (cacheResult) { - const hasAllProps = select.every((key) => { - if (key.includes(".")) return true; // @ts-ignore - return cacheResult[key] !== undefined; - }); - // console.log(`[Cache] get ${cacheResult.id} from ${cacheResult.constructor.name}`,); - if (hasAllProps) return cacheResult; - } - - // @ts-ignore - const result = await super.findOne<T>(options); - if (!result) return null; - - this.cache.insert(result as any); - - return result; - } - - static async findOneOrFail<T extends BaseEntityCache>( - this: ThisType<T>, - options: FindOneOptions<T>, - ) { - const result = await this.findOne<T>(options); - if (!result) throw new EntityNotFoundError(this, options); - return result; - } - - save() { - if (this.constructor.cacheEnabled) this.constructor.cache.insert(this); - return super.save(); - } - - remove() { - if (this.constructor.cacheEnabled) - this.constructor.cache.delete(this.id); - return super.remove(); - } - - static async update<T extends BaseEntityCache>( - this: ThisType<T>, - criteria: FindOptionsWhere<T>, - partialEntity: QueryDeepPartialEntity<T>, - ) { - // @ts-ignore - const result = super.update<T>(criteria, partialEntity); - if (!this.cacheEnabled) return result; - - const entities = this.cache.filter(criteria as never); - for (const entity of entities) { - // @ts-ignore - partialEntity.id = entity.id; - this.cache.insert(partialEntity as never); - } - - return result; - } - - static async delete<T extends BaseEntityCache>( - this: ThisType<T>, - criteria: FindOptionsWhere<T>, - ) { - // @ts-ignore - const result = super.delete<T>(criteria); - if (!this.cacheEnabled) return result; - - const entities = this.cache.filter(criteria as never); - for (const entity of entities) { - this.cache.delete(entity.id); - } - - return result; - } -} - -// needed, because typescript can't infer the type of the static methods with generics -const EntityCache = BaseEntityCache as unknown as typeof BaseClassWithId; - -export { EntityCache };