Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
Something went wrong. Try again.
3.6 kB · 98 lines
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798import { childLogger, type Logger } from "@foxxmd/logging";import type { DbConcrete } from "../drizzleUtils.ts";import type { Dayjs } from "dayjs";import { type RelationsFieldFilter, eq, inArray } from "drizzle-orm";import { loggerNoop } from "../../../MaybeLogger.ts";import { capitalize } from "../../../../../core/StringUtils.ts";import { getConfigByTableName, type TableName } from "../schema/schema.ts";import assert from 'node:assert';import type { Cacheable } from "cacheable";import type { DateLike } from "../../../../../core/Atomic.ts";import type { CompareDateBetween, CompareDateSingle } from "../../../../../core/Api.ts";
export interface DrizzleRepositoryOpts { logger?: Logger cache?: Cacheable componentId?: number}
export type CompareDateOp<D extends DateLike = Dayjs> = CompareDateSingle<D> | CompareDateBetween<D>;export interface ComponentConstrainedRepoOpts { componentId?: number}
export abstract class DrizzleBaseRepository<T extends TableName> {
logger: Logger; displayName: string; tableName: TableName; table: ReturnType<typeof getConfigByTableName<T>> db: DbConcrete; componentId?: number cache?: Cacheable
constructor(db: DbConcrete, tableName: TableName, displayName: string, opts: DrizzleRepositoryOpts = {}) { this.db = db; this.displayName = displayName; this.tableName = tableName; this.table = getConfigByTableName(this.tableName); this.logger = childLogger(opts.logger ?? loggerNoop, ['Database', capitalize(displayName)]); this.componentId = opts.componentId; this.cache = opts.cache; }
async deleteByIds(ids: number[]): Promise<void> { await this.db.delete(this.table).where(inArray(this.table.id, ids)); }
async updateById(id: number, data: Partial<typeof this.table.$inferInsert>): Promise<typeof this.table.$inferSelect> { assert(id !== null && id !== undefined, `${id === null ? 'null' : 'undefined'} given for entity id`); return (await this.db.update(this.table).set(data).where(eq(this.table.id, id)).returning())[0]; }
async create(data: typeof this.table.$inferInsert): Promise<typeof this.table.$inferSelect> { const res = await this.db.insert(this.table).values([data]).returning(); return res[0]; }
async createMany(data: typeof this.table.$inferInsert[]): Promise<typeof this.table.$inferSelect[]> { const res = await this.db.insert(this.table).values(data).returning(); return res; }
async findById(id: number): Promise<typeof this.table.$inferSelect | undefined> { // const res = await this.db.query[this.tableName].findFirst({ // where: { // id // } // }); const res = await this.db.select().from(this.table).where(eq(this.table.id, id)); if(res.length === 0) { return undefined; } return res[0]; }}
export class GenericRepository<T extends TableName> extends DrizzleBaseRepository<T> {
}
export const buildDateCompare = (data: CompareDateOp): RelationsFieldFilter<Dayjs> => { if (data.type !== 'between') { return { [data.type]: data.date } } else { return { AND: [ { [data.inclusive ?? true ? 'gte' : 'gt']: data.range[0] }, { [data.inclusive ?? true ? 'lte' : 'lt']: data.range[1] }, ] } }}