Add method to intelligently insert/update.
The `upsert()` method can both create and update tasks. The method checks for an `id` propery to determine whether to `INSERT` or `UPDATE`. A successful operation returns a `ServiceResponse` object with the inserted task `id`, which can be used to fetch updated information if needed. The `NewTask` type is exported for use in form actions, etc.
This commit is contained in:
parent
f63f5ccc5a
commit
eddaf02824
@ -1,7 +1,7 @@
|
||||
import { type DB, db } from "$lib/server/db/db";
|
||||
import type { tasks, taskTypes } from "$lib/server/db/schema/tasks";
|
||||
import { tasks, type taskTypes } from "$lib/server/db/schema/tasks";
|
||||
import type { ServiceResponse } from "$lib/server/services/service.types";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import { eq, type InferSelectModel } from "drizzle-orm";
|
||||
import logger from "../logger";
|
||||
|
||||
export type Task = InferSelectModel<typeof tasks> & {
|
||||
@ -12,6 +12,8 @@ export type TaskOrNull = InferSelectModel<typeof tasks> & {
|
||||
type: InferSelectModel<typeof taskTypes> | null;
|
||||
};
|
||||
|
||||
export type NewTask = typeof tasks.$inferInsert;
|
||||
|
||||
class TasksService {
|
||||
private db: DB;
|
||||
private caller: "internal" | "api";
|
||||
@ -90,6 +92,33 @@ class TasksService {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public async upsert(taskData: NewTask): Promise<ServiceResponse<{ id: number }, "INTERNAL_ERROR" | "VALIDATION_ERROR">> {
|
||||
try {
|
||||
if (taskData.id) {
|
||||
const updated = await this.db.update(tasks)
|
||||
.set(taskData)
|
||||
.where(eq(tasks.id, taskData.id))
|
||||
.returning({ id: tasks.id });
|
||||
if (updated.length === 0) {
|
||||
return { status: "failure", code: "VALIDATION_ERROR", error: `Task with ID ${taskData.id} not found for update.` };
|
||||
}
|
||||
return { status: "ok", data: { id: updated[0].id } };
|
||||
} else {
|
||||
const created = await this.db.insert(tasks)
|
||||
.values(taskData)
|
||||
.returning({ id: tasks.id });
|
||||
if (created.length === 0) {
|
||||
throw new Error("Insert operation failed to return the new task.");
|
||||
}
|
||||
return { status: "ok", data: { id: created[0].id } };
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
logger.error({ msg: "Error upserting task.", error });
|
||||
return { status: "failure", error: "An internal server error occurred while saving the task.", code: "INTERNAL_ERROR" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default TasksService;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user