import { and, eq, inArray } from "drizzle-orm"; import type { CircuitSectionTransactionStore } from "../../domain/ports/circuit-section-transaction.store.js"; import type { AppDatabase } from "../database-context.js"; import { circuits } from "../schema/circuits.js"; export class CircuitSectionTransactionRepository implements CircuitSectionTransactionStore { constructor(private readonly database: AppDatabase) {} updateSortOrders(sectionId: string, orderedCircuitIds: string[]) { if (orderedCircuitIds.length === 0) { return; } if (new Set(orderedCircuitIds).size !== orderedCircuitIds.length) { throw new Error( "Stromkreise dürfen in der Reihenfolge nicht mehrfach vorkommen." ); } this.database.transaction((tx) => { const sectionCircuits = tx .select({ id: circuits.id }) .from(circuits) .where(eq(circuits.sectionId, sectionId)) .all(); const sectionCircuitIds = new Set( sectionCircuits.map((circuit) => circuit.id) ); if ( sectionCircuits.length !== orderedCircuitIds.length || orderedCircuitIds.some((circuitId) => !sectionCircuitIds.has(circuitId)) ) { throw new Error( "Die Reihenfolge muss alle Stromkreise des Bereichs enthalten." ); } for (let index = 0; index < orderedCircuitIds.length; index += 1) { const result = tx .update(circuits) .set({ sortOrder: (index + 1) * 10 }) .where( and( eq(circuits.sectionId, sectionId), eq(circuits.id, orderedCircuitIds[index]) ) ) .run(); if (result.changes !== 1) { throw new Error( "Ein Stromkreis wurde vor Abschluss der Sortierung verändert." ); } } }); } updateEquipmentIdentifiers( circuitListId: string, updates: Array<{ id: string; equipmentIdentifier: string }>, tempNamespace: string ) { if (updates.length === 0) { return; } this.database.transaction((tx) => { const ids = updates.map((entry) => entry.id); const existing = tx .select({ id: circuits.id }) .from(circuits) .where( and( eq(circuits.circuitListId, circuitListId), inArray(circuits.id, ids) ) ) .all(); if (existing.length !== ids.length) { throw new Error( "One or more circuit ids are invalid for circuit list." ); } const stamp = Date.now(); for (let index = 0; index < updates.length; index += 1) { const entry = updates[index]; const tempIdentifier = `__tmp_renumber_${tempNamespace}_${stamp}_${index}`; tx .update(circuits) .set({ equipmentIdentifier: tempIdentifier }) .where( and( eq(circuits.circuitListId, circuitListId), eq(circuits.id, entry.id) ) ) .run(); } for (const entry of updates) { tx .update(circuits) .set({ equipmentIdentifier: entry.equipmentIdentifier }) .where( and( eq(circuits.circuitListId, circuitListId), eq(circuits.id, entry.id) ) ) .run(); } }); } }