Isolate project device sync transactions
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import crypto from "node:crypto";
|
||||
import { and, asc, eq, inArray, isNull } from "drizzle-orm";
|
||||
import { and, asc, eq, inArray } from "drizzle-orm";
|
||||
import { db } from "../client.js";
|
||||
import { circuitDeviceRows } from "../schema/circuit-device-rows.js";
|
||||
import { circuitLists } from "../schema/circuit-lists.js";
|
||||
@@ -125,64 +125,6 @@ export class CircuitDeviceRowRepository {
|
||||
await db.update(circuitDeviceRows).set(values).where(eq(circuitDeviceRows.id, rowId));
|
||||
}
|
||||
|
||||
updateLinkedRowsTransactional(
|
||||
projectDeviceId: string,
|
||||
changes: Array<{ rowId: string; input: CircuitDeviceRowUpdateInput }>
|
||||
) {
|
||||
db.transaction((tx) => {
|
||||
for (const change of changes) {
|
||||
const result = tx
|
||||
.update(circuitDeviceRows)
|
||||
.set(toCircuitDeviceRowUpdateValues(change.input))
|
||||
.where(
|
||||
and(
|
||||
eq(circuitDeviceRows.id, change.rowId),
|
||||
eq(circuitDeviceRows.linkedProjectDeviceId, projectDeviceId)
|
||||
)
|
||||
)
|
||||
.run();
|
||||
if (result.changes !== 1) {
|
||||
throw new Error("A linked row changed before the operation could be completed.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
disconnectLinkedRowsTransactional(projectDeviceId: string, rowIds: string[]) {
|
||||
db.transaction((tx) => {
|
||||
for (const rowId of rowIds) {
|
||||
const result = tx
|
||||
.update(circuitDeviceRows)
|
||||
.set({ linkedProjectDeviceId: null })
|
||||
.where(
|
||||
and(
|
||||
eq(circuitDeviceRows.id, rowId),
|
||||
eq(circuitDeviceRows.linkedProjectDeviceId, projectDeviceId)
|
||||
)
|
||||
)
|
||||
.run();
|
||||
if (result.changes !== 1) {
|
||||
throw new Error("A linked row changed before the operation could be completed.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reconnectRowsTransactional(projectDeviceId: string, rowIds: string[]) {
|
||||
db.transaction((tx) => {
|
||||
for (const rowId of rowIds) {
|
||||
const result = tx
|
||||
.update(circuitDeviceRows)
|
||||
.set({ linkedProjectDeviceId: projectDeviceId })
|
||||
.where(and(eq(circuitDeviceRows.id, rowId), isNull(circuitDeviceRows.linkedProjectDeviceId)))
|
||||
.run();
|
||||
if (result.changes !== 1) {
|
||||
throw new Error("A disconnected row changed before the operation could be undone.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async delete(rowId: string) {
|
||||
await db.delete(circuitDeviceRows).where(eq(circuitDeviceRows.id, rowId));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
import type {
|
||||
ProjectDeviceLinkedRowValues,
|
||||
ProjectDeviceRowSyncStore,
|
||||
} from "../../domain/ports/project-device-row-sync.store.js";
|
||||
import type { AppDatabase } from "../database-context.js";
|
||||
import { circuitDeviceRows } from "../schema/circuit-device-rows.js";
|
||||
import { toCircuitDeviceRowUpdateValues } from "./circuit-device-row.persistence.js";
|
||||
|
||||
export class ProjectDeviceRowSyncRepository implements ProjectDeviceRowSyncStore {
|
||||
constructor(private readonly database: AppDatabase) {}
|
||||
|
||||
updateLinkedRows(
|
||||
projectDeviceId: string,
|
||||
changes: Array<{ rowId: string; input: ProjectDeviceLinkedRowValues }>
|
||||
) {
|
||||
this.database.transaction((tx) => {
|
||||
for (const change of changes) {
|
||||
const result = tx
|
||||
.update(circuitDeviceRows)
|
||||
.set(toCircuitDeviceRowUpdateValues(change.input))
|
||||
.where(
|
||||
and(
|
||||
eq(circuitDeviceRows.id, change.rowId),
|
||||
eq(circuitDeviceRows.linkedProjectDeviceId, projectDeviceId)
|
||||
)
|
||||
)
|
||||
.run();
|
||||
if (result.changes !== 1) {
|
||||
throw new Error(
|
||||
"A linked row changed before the operation could be completed."
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
disconnectLinkedRows(projectDeviceId: string, rowIds: string[]) {
|
||||
this.database.transaction((tx) => {
|
||||
for (const rowId of rowIds) {
|
||||
const result = tx
|
||||
.update(circuitDeviceRows)
|
||||
.set({ linkedProjectDeviceId: null })
|
||||
.where(
|
||||
and(
|
||||
eq(circuitDeviceRows.id, rowId),
|
||||
eq(circuitDeviceRows.linkedProjectDeviceId, projectDeviceId)
|
||||
)
|
||||
)
|
||||
.run();
|
||||
if (result.changes !== 1) {
|
||||
throw new Error(
|
||||
"A linked row changed before the operation could be completed."
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reconnectRows(projectDeviceId: string, rowIds: string[]) {
|
||||
this.database.transaction((tx) => {
|
||||
for (const rowId of rowIds) {
|
||||
const result = tx
|
||||
.update(circuitDeviceRows)
|
||||
.set({ linkedProjectDeviceId: projectDeviceId })
|
||||
.where(
|
||||
and(
|
||||
eq(circuitDeviceRows.id, rowId),
|
||||
isNull(circuitDeviceRows.linkedProjectDeviceId)
|
||||
)
|
||||
)
|
||||
.run();
|
||||
if (result.changes !== 1) {
|
||||
throw new Error(
|
||||
"A disconnected row changed before the operation could be undone."
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user