task-managment / src / lib / db / drizzle-client.ts
drizzle-client.ts
Raw
// // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// // @ts-nocheck
import {
  BuildQueryResult,
  DBQueryConfig,
  eq,
  ExtractTablesWithRelations,
  InferInsertModel,
} from "drizzle-orm";

import { db } from "@/database/db";
import * as schema from "@/database/schema";

type TSchema = ExtractTablesWithRelations<typeof schema>;

type QueryConfig<TableName extends keyof TSchema> = DBQueryConfig<
  "one" | "many",
  boolean,
  TSchema,
  TSchema[TableName]
>;

type OptsQuery<T extends keyof TSchema> = QueryConfig<T>;

type QueryResult<
  TableName extends keyof TSchema,
  QBConfig extends QueryConfig<TableName>
> = BuildQueryResult<TSchema, TSchema[TableName], QBConfig>;

export async function dbGetAll<
  T extends keyof TSchema,
  Opts extends OptsQuery<T>
>(table: T, opts?: Opts): Promise<QueryResult<T, Opts>[]> {
  try {
    const data = await db.query[table].findMany(opts || {});
    return data as QueryResult<T, Opts>[];
  } catch (error) {
    console.log("err", error);
    throw new Error("Error getting data: " + error);
  }
}

export async function dbGetOne<
  T extends keyof TSchema,
  Opts extends OptsQuery<T>
>(table: T, opts?: Opts): Promise<QueryResult<T, Opts>> {
  try {
    const data = await db.query[table].findFirst(opts || {});

    return data as QueryResult<T, Opts>;
  } catch (error) {
    throw new Error("Error getting data: " + error);
  }
}

export async function dbGetById<T extends keyof TSchema>(
  table: T,
  id: number,
  Opts?: OptsQuery<T>
) {
  try {
    const data = await db.query[table].findFirst({
      where: eq(schema[table].id as any, id),
      columns: Opts?.columns,
      with: Opts?.with,
      extras: Opts?.extras,
    });

    if (!data) {
      throw new Error("No record found");
    }

    return data;
  } catch (error) {
    throw new Error("Error getting data: " + error);
  }
}

export async function dbCreate<T extends keyof TSchema>(
  table: T,
  values: InferInsertModel<(typeof schema)[T]>
) {
  try {
    const [data] = await db
      .insert(schema[table])
      .values(values as any)
      .returning({ id: schema[table].id });

    if (!data) {
      throw new Error("Error creating element");
    }

    return data;
  } catch (error) {
    throw new Error("Error getting data: " + error);
  }
}


export async function dbDelete<
  T extends keyof TSchema
>(
  table: T,
  where: Partial<Record<keyof InferInsertModel<(typeof schema)[T]>, any>>
) {
  try {
    const [key, value] = Object.entries(where)[0] as [
      keyof InferInsertModel<(typeof schema)[T]>,
      any
    ];

    if (!key || value === undefined) {
      throw new Error("Invalid where condition");
    }

    const [data] = await db
      .delete(schema[table])
      .where(eq(schema[table][key] as any, value))
      .returning();

    return data;
  } catch (error) {
    throw new Error("Error deleting data: " + error);
  }
}