import { 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 = CompareDateSingle | CompareDateBetween; export interface ComponentConstrainedRepoOpts { componentId?: number } export abstract class DrizzleBaseRepository { logger: Logger; displayName: string; tableName: TableName; table: ReturnType> 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 { await this.db.delete(this.table).where(inArray(this.table.id, ids)); } async updateById(id: number, data: Partial): Promise { 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 { const res = await this.db.insert(this.table).values([data]).returning(); return res[0]; } async createMany(data: typeof this.table.$inferInsert[]): Promise { const res = await this.db.insert(this.table).values(data).returning(); return res; } async findById(id: number): Promise { // 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 extends DrizzleBaseRepository { } export const buildDateCompare = (data: CompareDateOp): RelationsFieldFilter => { 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] }, ] } } }