prepare( "SELECT url FROM corpus_sources WHERE corpus_id = 1 AND name = ? LIMIT 1" ); $srcStmt->execute([$sourceName]); $srcRow = $srcStmt->fetch(PDO::FETCH_ASSOC); if ($srcRow && !empty($srcRow['url'])) { $parsed = parse_url($srcRow['url']); $host = $parsed['host'] ?? ''; if ($host !== '') { $where[] = "d.source_url LIKE ?"; $params[] = '%' . $host . '%'; } } } $whereStr = implode(' AND ', $where); // Total count $countParams = $params; $countStmt = $ragDb->prepare("SELECT COUNT(*) FROM documents d WHERE $whereStr"); $countStmt->execute($countParams); $total = (int)$countStmt->fetchColumn(); // Paginated rows $dataParams = $params; $dataParams[] = $limit; $dataParams[] = $offset; $dataStmt = $ragDb->prepare( "SELECT d.id, d.title, d.category, d.source_url, d.language, d.updated_at, COUNT(c.id) AS chunk_count FROM documents d LEFT JOIN chunks c ON c.document_id = d.id WHERE $whereStr GROUP BY d.id ORDER BY d.updated_at DESC LIMIT ? OFFSET ?" ); $dataStmt->execute($dataParams); $documents = $dataStmt->fetchAll(PDO::FETCH_ASSOC); // Normalise chunk_count to int foreach ($documents as &$doc) { $doc['chunk_count'] = (int)$doc['chunk_count']; } unset($doc); dbnToolsRespond([ 'ok' => true, 'documents' => $documents, 'total' => $total, 'offset' => $offset, 'limit' => $limit, 'filter' => [ 'category' => $category, 'source_name' => $sourceName, ], ]); } catch (Throwable $e) { dbnToolsError('Could not load documents: ' . $e->getMessage(), 500, 'documents_error'); }