ChunkRepository.php
- Pfad:
src/Infrastructure/Persistence/ChunkRepository.php - Namespace: Infrastructure\Persistence
- Zeilen: 241 | Größe: 6,780 Bytes
- Geändert: 2025-12-31 02:21:23 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 96
- Dependencies: 100 (25%)
- LOC: 100 (20%)
- Methods: 80 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 100 (10%)
Keine Issues gefunden.
Dependencies 4
- implements Domain\Repository\ChunkRepositoryInterface
- constructor PDO
- use Domain\Repository\ChunkRepositoryInterface
- use PDO
Klassen 1
-
ChunkRepositoryclass Zeile 12
Funktionen 12
-
__construct()public Zeile 16 -
getStats()public Zeile 24 -
findRecent()public Zeile 40 -
findByDocument()public Zeile 58 -
findFiltered()public Zeile 75 -
count()public Zeile 107 -
find()public Zeile 135 -
findByDocumentAndIndex()public Zeile 152 -
getChunkEntities()public Zeile 167 -
getChunkTaxonomy()public Zeile 184 -
findChunksByEntity()public Zeile 201 -
getTextSemantics()public Zeile 221
Verwendet von 2
Versionen 5
-
v5
2025-12-31 02:21 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v4
2025-12-28 02:53 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v3
2025-12-27 00:12 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v2
2025-12-25 10:28 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v1
2025-12-25 10:28 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
Code
<?php
declare(strict_types=1);
namespace Infrastructure\Persistence;
// @responsibility: CRUD-Operationen für Text-Chunks aus Dokumenten
use Domain\Repository\ChunkRepositoryInterface;
use PDO;
final class ChunkRepository implements ChunkRepositoryInterface
{
private PDO $db;
public function __construct(PDO $pdo)
{
$this->db = $pdo;
}
/**
* {@inheritDoc}
*/
public function getStats(): array
{
$result = $this->db->query(
'SELECT
COUNT(*) as total,
COALESCE(SUM(token_count), 0) as tokens,
SUM(CASE WHEN qdrant_id IS NOT NULL THEN 1 ELSE 0 END) as embedded
FROM chunks'
)->fetch();
return $result !== false ? $result : ['total' => 0, 'tokens' => 0, 'embedded' => 0];
}
/**
* {@inheritDoc}
*/
public function findRecent(int $limit = 5): array
{
$stmt = $this->db->prepare(
'SELECT c.id, c.content, c.token_count, c.created_at, c.qdrant_id, d.filename
FROM chunks c
JOIN documents d ON c.document_id = d.id
ORDER BY c.created_at DESC
LIMIT :limit'
);
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll();
}
/**
* {@inheritDoc}
*/
public function findByDocument(int $documentId): array
{
$stmt = $this->db->prepare(
'SELECT c.id, c.chunk_index, c.content, c.token_count, c.heading_path,
c.metadata, c.qdrant_id, c.created_at
FROM chunks c
WHERE c.document_id = :id
ORDER BY c.chunk_index'
);
$stmt->execute(['id' => $documentId]);
return $stmt->fetchAll();
}
/**
* {@inheritDoc}
*/
public function findFiltered(string $search = '', string $embedded = '', int $limit = 50, int $offset = 0): array
{
$sql = 'SELECT c.id, c.chunk_index, c.content, c.token_count, c.qdrant_id, c.created_at,
d.filename, d.id as document_id
FROM chunks c
JOIN documents d ON c.document_id = d.id
WHERE 1=1';
$params = [];
if ($search !== '') {
$sql .= ' AND c.content LIKE :search';
$params['search'] = '%' . $search . '%';
}
if ($embedded === 'yes') {
$sql .= ' AND c.qdrant_id IS NOT NULL';
} elseif ($embedded === 'no') {
$sql .= ' AND c.qdrant_id IS NULL';
}
$sql .= ' ORDER BY c.created_at DESC LIMIT ' . $limit . ' OFFSET ' . $offset;
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
/**
* {@inheritDoc}
*/
public function count(string $search = '', string $embedded = ''): int
{
$sql = 'SELECT COUNT(*) FROM chunks c
JOIN documents d ON c.document_id = d.id
WHERE 1=1';
$params = [];
if ($search !== '') {
$sql .= ' AND c.content LIKE :search';
$params['search'] = '%' . $search . '%';
}
if ($embedded === 'yes') {
$sql .= ' AND c.qdrant_id IS NOT NULL';
} elseif ($embedded === 'no') {
$sql .= ' AND c.qdrant_id IS NULL';
}
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return (int) $stmt->fetchColumn();
}
/**
* {@inheritDoc}
*/
public function find(int $id): ?array
{
$stmt = $this->db->prepare(
'SELECT c.*, d.filename, d.source_path, d.id as document_id
FROM chunks c
JOIN documents d ON c.document_id = d.id
WHERE c.id = :id'
);
$stmt->execute(['id' => $id]);
$result = $stmt->fetch();
return $result === false ? null : $result;
}
/**
* {@inheritDoc}
*/
public function findByDocumentAndIndex(int $documentId, int $chunkIndex): ?array
{
$stmt = $this->db->prepare(
'SELECT id, chunk_index FROM chunks
WHERE document_id = :doc_id AND chunk_index = :idx'
);
$stmt->execute(['doc_id' => $documentId, 'idx' => $chunkIndex]);
$result = $stmt->fetch();
return $result === false ? null : $result;
}
/**
* {@inheritDoc}
*/
public function getChunkEntities(int $chunkId): array
{
$stmt = $this->db->prepare(
'SELECT e.id, e.name, e.type, ce.relevance_score
FROM chunk_entities ce
JOIN entities e ON ce.entity_id = e.id
WHERE ce.chunk_id = :chunk_id
ORDER BY ce.relevance_score DESC'
);
$stmt->execute(['chunk_id' => $chunkId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}
/**
* {@inheritDoc}
*/
public function getChunkTaxonomy(int $chunkId): array
{
$stmt = $this->db->prepare(
'SELECT tt.id as term_id, tt.name as term_name, tt.path as term_path, ct.confidence
FROM chunk_taxonomy ct
JOIN taxonomy_terms tt ON ct.taxonomy_term_id = tt.id
WHERE ct.chunk_id = :chunk_id
ORDER BY ct.confidence DESC'
);
$stmt->execute(['chunk_id' => $chunkId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}
/**
* {@inheritDoc}
*/
public function findChunksByEntity(int $entityId, int $limit = 10): array
{
$stmt = $this->db->prepare(
'SELECT c.id as chunk_id, c.content, ce.relevance_score
FROM chunk_entities ce
JOIN chunks c ON ce.chunk_id = c.id
WHERE ce.entity_id = :entity_id
ORDER BY ce.relevance_score DESC
LIMIT :limit'
);
$stmt->bindValue(':entity_id', $entityId, PDO::PARAM_INT);
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}
/**
* {@inheritDoc}
*/
public function getTextSemantics(int $chunkId): ?array
{
$stmt = $this->db->prepare(
'SELECT statement_form, intent, frame, is_negated, discourse_role, analysis_model as model_used
FROM chunk_semantics
WHERE chunk_id = :chunk_id'
);
$stmt->execute(['chunk_id' => $chunkId]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result === false) {
return null;
}
// Convert is_negated to boolean
$result['is_negated'] = (bool) $result['is_negated'];
return $result;
}
}