pdo = $pdo; } public function findById(int $id): ?ScanJob { $stmt = $this->pdo->prepare('SELECT * FROM scan_jobs WHERE id = :id'); $stmt->execute(['id' => $id]); $row = $stmt->fetch(); return $row ? ScanJob::fromArray($row) : null; } public function findPending(): array { $stmt = $this->pdo->prepare('SELECT * FROM scan_jobs WHERE status = :status ORDER BY created_at ASC'); $stmt->execute(['status' => 'pending']); $results = []; while ($row = $stmt->fetch()) { $results[] = ScanJob::fromArray($row); } return $results; } public function findRecent(int $limit = 10): array { $stmt = $this->pdo->prepare('SELECT * FROM scan_jobs ORDER BY created_at DESC LIMIT :limit'); $stmt->bindValue('limit', $limit, PDO::PARAM_INT); $stmt->execute(); $results = []; while ($row = $stmt->fetch()) { $results[] = ScanJob::fromArray($row); } return $results; } public function findRunning(): array { $stmt = $this->pdo->prepare('SELECT * FROM scan_jobs WHERE status = :status ORDER BY started_at ASC'); $stmt->execute(['status' => 'running']); $results = []; while ($row = $stmt->fetch()) { $results[] = ScanJob::fromArray($row); } return $results; } public function save(ScanJob $job): void { $now = (new \DateTimeImmutable())->format('Y-m-d H:i:s'); if ($job->id === null) { $stmt = $this->pdo->prepare( 'INSERT INTO scan_jobs (type, status, network_range_id, device_id, created_by, created_at) VALUES (:type, :status, :network_range_id, :device_id, :created_by, :created_at)' ); $stmt->execute([ 'type' => $job->type, 'status' => $job->status, 'network_range_id' => $job->networkRangeId, 'device_id' => $job->deviceId, 'created_by' => $job->createdBy, 'created_at' => $now, ]); $job->id = (int)$this->pdo->lastInsertId(); } else { $stmt = $this->pdo->prepare( 'UPDATE scan_jobs SET type = :type, status = :status, network_range_id = :network_range_id, device_id = :device_id, started_at = :started_at, finished_at = :finished_at, error_message = :error_message, result_json = :result_json WHERE id = :id' ); $stmt->execute([ 'id' => $job->id, 'type' => $job->type, 'status' => $job->status, 'network_range_id' => $job->networkRangeId, 'device_id' => $job->deviceId, 'started_at' => $job->startedAt?->format('Y-m-d H:i:s'), 'finished_at' => $job->finishedAt?->format('Y-m-d H:i:s'), 'error_message' => $job->errorMessage, 'result_json' => $job->resultJson, ]); } } }