db->prepare( 'SELECT t.*, ft.name AS from_tenant_name, tt.name AS to_tenant_name FROM instructor_travel_times t JOIN tenants ft ON ft.id = t.from_tenant_id JOIN tenants tt ON tt.id = t.to_tenant_id WHERE t.instructor_id = :instructor_id ORDER BY ft.name, tt.name' ); $stmt->execute(['instructor_id' => $instructorId]); return $stmt->fetchAll(); } public function getMinutes(int $instructorId, int $fromTenantId, int $toTenantId): ?int { $stmt = $this->db->prepare( 'SELECT minutes FROM instructor_travel_times WHERE instructor_id = :instructor_id AND from_tenant_id = :from_tenant_id AND to_tenant_id = :to_tenant_id' ); $stmt->execute([ 'instructor_id' => $instructorId, 'from_tenant_id' => $fromTenantId, 'to_tenant_id' => $toTenantId, ]); $result = $stmt->fetch(); return $result ? (int) $result['minutes'] : null; } public function upsert(int $instructorId, int $fromTenantId, int $toTenantId, int $minutes): array { $stmt = $this->db->prepare( 'INSERT INTO instructor_travel_times (instructor_id, from_tenant_id, to_tenant_id, minutes) VALUES (:instructor_id, :from_tenant_id, :to_tenant_id, :minutes) ON CONFLICT (instructor_id, from_tenant_id, to_tenant_id) DO UPDATE SET minutes = :minutes RETURNING *' ); $stmt->execute([ 'instructor_id' => $instructorId, 'from_tenant_id' => $fromTenantId, 'to_tenant_id' => $toTenantId, 'minutes' => $minutes, ]); return $stmt->fetch(); } public function delete(int $id): bool { $stmt = $this->db->prepare('DELETE FROM instructor_travel_times WHERE id = :id RETURNING id'); $stmt->execute(['id' => $id]); return (bool) $stmt->fetch(); } }