pdo = $pdo; } public function findById(int $id): ?DiscoveredHost { $stmt = $this->pdo->prepare('SELECT * FROM discovered_hosts WHERE id = :id'); $stmt->execute(['id' => $id]); $row = $stmt->fetch(); return $row ? DiscoveredHost::fromArray($row) : null; } public function findByStatus(string $status, int $limit = 100): array { $stmt = $this->pdo->prepare('SELECT * FROM discovered_hosts WHERE status = :status ORDER BY last_seen DESC LIMIT :limit'); $stmt->bindValue('status', $status); $stmt->bindValue('limit', $limit, PDO::PARAM_INT); $stmt->execute(); $results = []; while ($row = $stmt->fetch()) { $results[] = DiscoveredHost::fromArray($row); } return $results; } public function findByScanJob(int $scanJobId): array { $stmt = $this->pdo->prepare('SELECT * FROM discovered_hosts WHERE scan_job_id = :scan_job_id ORDER BY ip_address ASC'); $stmt->execute(['scan_job_id' => $scanJobId]); $results = []; while ($row = $stmt->fetch()) { $results[] = DiscoveredHost::fromArray($row); } return $results; } public function findAll(int $limit = 100): array { $stmt = $this->pdo->prepare('SELECT * FROM discovered_hosts ORDER BY last_seen DESC LIMIT :limit'); $stmt->bindValue('limit', $limit, PDO::PARAM_INT); $stmt->execute(); $results = []; while ($row = $stmt->fetch()) { $results[] = DiscoveredHost::fromArray($row); } return $results; } public function save(DiscoveredHost $host): void { $now = (new \DateTimeImmutable())->format('Y-m-d H:i:s'); if ($host->id === null) { $stmt = $this->pdo->prepare( 'INSERT INTO discovered_hosts (scan_job_id, ip_address, mac_address, hostname, vendor, detected_os, open_ports_json, protocols_json, fingerprint_json, confidence, status, matched_device_id, first_seen, last_seen, created_at, updated_at) VALUES (:scan_job_id, :ip_address, :mac_address, :hostname, :vendor, :detected_os, :open_ports_json, :protocols_json, :fingerprint_json, :confidence, :status, :matched_device_id, :first_seen, :last_seen, :created_at, :updated_at)' ); $stmt->execute([ 'scan_job_id' => $host->scanJobId, 'ip_address' => $host->ipAddress, 'mac_address' => $host->macAddress, 'hostname' => $host->hostname, 'vendor' => $host->vendor, 'detected_os' => $host->detectedOs, 'open_ports_json' => json_encode($host->openPorts), 'protocols_json' => json_encode($host->protocols), 'fingerprint_json' => json_encode($host->fingerprint), 'confidence' => $host->confidence, 'status' => $host->status, 'matched_device_id' => $host->matchedDeviceId, 'first_seen' => $now, 'last_seen' => $now, 'created_at' => $now, 'updated_at' => $now, ]); $host->id = (int)$this->pdo->lastInsertId(); } else { $stmt = $this->pdo->prepare( 'UPDATE discovered_hosts SET status = :status, matched_device_id = :matched_device_id, last_seen = :last_seen, updated_at = :updated_at WHERE id = :id' ); $stmt->execute([ 'id' => $host->id, 'status' => $host->status, 'matched_device_id' => $host->matchedDeviceId, 'last_seen' => $now, 'updated_at' => $now, ]); } } }