Code review, building a generic DAO for DB ops
Hi all, for my SvelteKit application I was building a generic DAO for common CRUD operations as below
pretty new to Drizzle so was wondering if this approach seems alright, feel like typing could be improved, would really appreciate any guidance.
Cheers!
import * as schema from "$lib/server/db/schemas/index";
import { eq } from "drizzle-orm";
import type { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
import type { SQLiteColumn, SQLiteTable } from "drizzle-orm/sqlite-core";
type Database = BetterSQLite3Database<typeof schema>;
type TableWithId = SQLiteTable & { id: SQLiteColumn };
export class BaseDao<T extends TableWithId> {
constructor(
protected db: Database,
protected table: T,
) {}
async create(data: T["$inferInsert"]) {
const result = await this.db.insert(this.table).values(data).returning();
return result[0] as T["$inferSelect"];
}
async findById(id: T["$inferSelect"]["id"]) {
return this.db
.select()
.from(this.table)
.where(eq(this.table.id, id))
.then((result) => result[0]) as Promise<T["$inferSelect"] | undefined>;
}
async update(id: T["$inferSelect"]["id"], data: Partial<T["$inferInsert"]>) {
const result = await this.db
.update(this.table)
.set(data)
.where(eq(this.table.id, id))
.returning();
return result[0] as T["$inferSelect"];
}
async delete(id: T["$inferSelect"]["id"]) {
const result = await this.db
.delete(this.table)
.where(eq(this.table.id, id))
.returning();
return result[0] as T["$inferSelect"];
}
async findAll() {
return this.db.select().from(this.table) as Promise<T["$inferSelect"][]>;
}
}import * as schema from "$lib/server/db/schemas/index";
import { eq } from "drizzle-orm";
import type { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
import type { SQLiteColumn, SQLiteTable } from "drizzle-orm/sqlite-core";
type Database = BetterSQLite3Database<typeof schema>;
type TableWithId = SQLiteTable & { id: SQLiteColumn };
export class BaseDao<T extends TableWithId> {
constructor(
protected db: Database,
protected table: T,
) {}
async create(data: T["$inferInsert"]) {
const result = await this.db.insert(this.table).values(data).returning();
return result[0] as T["$inferSelect"];
}
async findById(id: T["$inferSelect"]["id"]) {
return this.db
.select()
.from(this.table)
.where(eq(this.table.id, id))
.then((result) => result[0]) as Promise<T["$inferSelect"] | undefined>;
}
async update(id: T["$inferSelect"]["id"], data: Partial<T["$inferInsert"]>) {
const result = await this.db
.update(this.table)
.set(data)
.where(eq(this.table.id, id))
.returning();
return result[0] as T["$inferSelect"];
}
async delete(id: T["$inferSelect"]["id"]) {
const result = await this.db
.delete(this.table)
.where(eq(this.table.id, id))
.returning();
return result[0] as T["$inferSelect"];
}
async findAll() {
return this.db.select().from(this.table) as Promise<T["$inferSelect"][]>;
}
}pretty new to Drizzle so was wondering if this approach seems alright, feel like typing could be improved, would really appreciate any guidance.
Cheers!