Make bulk row moves atomic
This commit is contained in:
@@ -330,7 +330,7 @@ export class CircuitWriteService {
|
||||
circuitListId: sourceCircuit.circuitListId,
|
||||
sectionId: section.id,
|
||||
equipmentIdentifier: nextIdentifier,
|
||||
displayName: "New circuit",
|
||||
displayName: "Neuer Stromkreis",
|
||||
sortOrder: nextSortOrder,
|
||||
isReserve: false,
|
||||
});
|
||||
@@ -436,7 +436,17 @@ export class CircuitWriteService {
|
||||
throw new Error("Invalid target circuit id.");
|
||||
}
|
||||
|
||||
// Bulk placeholder move creates exactly one new circuit as common target.
|
||||
// Bulk placeholder move prepares exactly one new circuit as common target.
|
||||
// Its actual creation happens together with the row moves in one transaction.
|
||||
let createTargetCircuit:
|
||||
| {
|
||||
circuitListId: string;
|
||||
sectionId: string;
|
||||
equipmentIdentifier: string;
|
||||
displayName: string;
|
||||
sortOrder: number;
|
||||
}
|
||||
| undefined;
|
||||
if (!targetCircuit) {
|
||||
if (!input.targetSectionId || !input.createNewCircuit) {
|
||||
throw new Error("Invalid move target.");
|
||||
@@ -446,86 +456,27 @@ export class CircuitWriteService {
|
||||
const sectionCircuits = await this.circuitRepository.listBySection(section.id);
|
||||
const nextSortOrder =
|
||||
sectionCircuits.length > 0 ? Math.max(...sectionCircuits.map((circuit) => circuit.sortOrder)) + 10 : 10;
|
||||
const createdId = await this.circuitRepository.create({
|
||||
createTargetCircuit = {
|
||||
circuitListId: referenceSourceCircuit.circuitListId,
|
||||
sectionId: section.id,
|
||||
equipmentIdentifier: nextIdentifier,
|
||||
displayName: "New circuit",
|
||||
displayName: "Neuer Stromkreis",
|
||||
sortOrder: nextSortOrder,
|
||||
isReserve: false,
|
||||
});
|
||||
targetCircuit = await this.circuitRepository.findById(createdId);
|
||||
if (!targetCircuit) {
|
||||
throw new Error("Failed to create target circuit.");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Any source circuit emptied by bulk move is preserved as reserve circuit.
|
||||
const targetCircuitListId = targetCircuit?.circuitListId ?? createTargetCircuit!.circuitListId;
|
||||
for (const sourceCircuit of sourceCircuits.values()) {
|
||||
if (sourceCircuit.circuitListId !== targetCircuit.circuitListId) {
|
||||
if (sourceCircuit.circuitListId !== targetCircuitListId) {
|
||||
throw new Error("All moved rows must belong to same circuit list as target.");
|
||||
}
|
||||
}
|
||||
|
||||
const targetCount = await this.deviceRowRepository.countByCircuit(targetCircuit.id);
|
||||
let offset = 1;
|
||||
for (const row of rows) {
|
||||
await this.deviceRowRepository.moveToCircuit(row.id, targetCircuit.id, (targetCount + offset) * 10);
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
for (const sourceCircuit of sourceCircuits.values()) {
|
||||
const remaining = await this.deviceRowRepository.countByCircuit(sourceCircuit.id);
|
||||
if (remaining === 0) {
|
||||
await this.circuitRepository.update(sourceCircuit.id, {
|
||||
sectionId: sourceCircuit.sectionId,
|
||||
equipmentIdentifier: sourceCircuit.equipmentIdentifier,
|
||||
displayName: sourceCircuit.displayName ?? undefined,
|
||||
sortOrder: sourceCircuit.sortOrder,
|
||||
protectionType: sourceCircuit.protectionType ?? undefined,
|
||||
protectionRatedCurrent: sourceCircuit.protectionRatedCurrent ?? undefined,
|
||||
protectionCharacteristic: sourceCircuit.protectionCharacteristic ?? undefined,
|
||||
cableType: sourceCircuit.cableType ?? undefined,
|
||||
cableCrossSection: sourceCircuit.cableCrossSection ?? undefined,
|
||||
cableLength: sourceCircuit.cableLength ?? undefined,
|
||||
rcdAssignment: sourceCircuit.rcdAssignment ?? undefined,
|
||||
terminalDesignation: sourceCircuit.terminalDesignation ?? undefined,
|
||||
voltage: sourceCircuit.voltage ?? undefined,
|
||||
controlRequirement: sourceCircuit.controlRequirement ?? undefined,
|
||||
status: sourceCircuit.status ?? undefined,
|
||||
isReserve: true,
|
||||
remark: sourceCircuit.remark ?? undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean(targetCircuit.isReserve)) {
|
||||
await this.circuitRepository.update(targetCircuit.id, {
|
||||
sectionId: targetCircuit.sectionId,
|
||||
equipmentIdentifier: targetCircuit.equipmentIdentifier,
|
||||
displayName: targetCircuit.displayName ?? undefined,
|
||||
sortOrder: targetCircuit.sortOrder,
|
||||
protectionType: targetCircuit.protectionType ?? undefined,
|
||||
protectionRatedCurrent: targetCircuit.protectionRatedCurrent ?? undefined,
|
||||
protectionCharacteristic: targetCircuit.protectionCharacteristic ?? undefined,
|
||||
cableType: targetCircuit.cableType ?? undefined,
|
||||
cableCrossSection: targetCircuit.cableCrossSection ?? undefined,
|
||||
cableLength: targetCircuit.cableLength ?? undefined,
|
||||
rcdAssignment: targetCircuit.rcdAssignment ?? undefined,
|
||||
terminalDesignation: targetCircuit.terminalDesignation ?? undefined,
|
||||
voltage: targetCircuit.voltage ?? undefined,
|
||||
controlRequirement: targetCircuit.controlRequirement ?? undefined,
|
||||
status: targetCircuit.status ?? undefined,
|
||||
isReserve: false,
|
||||
remark: targetCircuit.remark ?? undefined,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
movedRowIds: rows.map((row) => row.id),
|
||||
targetCircuitId: targetCircuit.id,
|
||||
createdCircuitId: input.targetCircuitId ? undefined : targetCircuit.id,
|
||||
};
|
||||
return this.deviceRowRepository.moveRowsTransactional({
|
||||
rows: rows.map((row) => ({ id: row.id, expectedCircuitId: row.circuitId })),
|
||||
targetCircuitId: targetCircuit?.id,
|
||||
createTargetCircuit,
|
||||
});
|
||||
}
|
||||
|
||||
async getNextIdentifier(sectionId: string) {
|
||||
|
||||
Reference in New Issue
Block a user