Backup #2191

ID2191
Dateipfad/var/www/dev.campus.systemische-tools.de/src/Infrastructure/Persistence/ChunkRepository.php
Version5
Typ modified
Größe6.6 KB
Hasha80f66323f29ddf6edeb56c44785ef593360535dddf61d73ec1d64d31e3caabf
Datum2025-12-31 02:21:23
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?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, model_used
             FROM chunk_text_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;
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

Andere Versionen dieser Datei

ID Version Typ Größe Datum
2191 5 modified 6.6 KB 2025-12-31 02:21
1981 4 modified 6.0 KB 2025-12-28 02:53
1587 3 modified 4.3 KB 2025-12-27 00:12
1164 2 modified 4.3 KB 2025-12-25 10:28
1157 1 modified 4.4 KB 2025-12-25 10:28

← Zurück zur Übersicht