<commit_before><?php

namespace TopicCards\Db;

use GraphAware\Neo4j\Client\Exception\Neo4jException;
use TopicCards\Interfaces\TopicMapInterface;
use TopicCards\Interfaces\TopicMapDbAdapterInterface;


class TopicMapDbAdapter implements TopicMapDbAdapterInterface
{
    /** @var TopicMapInterface */
    protected $topicmap;
    

    public function __construct(TopicMapInterface $topicmap)
    {
        $this->topicmap = $topicmap;
    }
    
    
    public function selectTopics(array $filters)
    {
        $logger = $this->topicmap->getLogger();
        $db = $this->topicmap->getDb();
        
        if (! isset($filters['limit']))
        {
            $filters['limit'] = 500;
        }

        if (isset($filters['type']))
        {
            $filters['type_id'] = $this->topicmap->getTopicIdBySubject($filters['type']);
        }

        $db_conn = $db->getConnection();
        
        if ($db_conn === NULL)
        {
            return -1;
        }

        $classes = [ 'Topic' ];

        if (! empty($filters['type_id']))
        {
            $classes[] = $filters['type_id'];
        }

        $query = sprintf
        (
            'MATCH (t%s)',
            DbUtils::labelsString($classes)
        );

        $bind = [ ];

        if (! empty($filters['name_like']))
        {
            $query .= '-[:hasName]->(n:Name) WHERE lower(n.value) CONTAINS lower({name_like})';
            $bind[ 'name_like' ] = $filters['name_like']; 
        }

        $query .= ' RETURN DISTINCT t.id';

        if ($filters[ 'limit' ] > 0)
        {
            $query .= ' LIMIT ' . $filters[ 'limit' ];
        }

        $logger->info($query, $bind);

        try
        {
            $qresult = $db_conn->run($query, $bind);
        }
        catch (Neo4jException $exception)
        {
            $logger->error($exception->getMessage());
            // TODO: Error handling
            return -1;
        }

        $result = [ ];

        foreach ($qresult->records() as $record)
        {
            $result[ ] = $record->get('t.id');
        }

        return $result;
    }
    
    
    public function selectTopicBySubject($uri)
    {
        $logger = $this->topicmap->getLogger();
        $db = $this->topicmap->getDb();
        
        if (strlen($uri) === 0)
        {
            return false;
        }

        $db_conn = $db->getConnection();

        if ($db_conn === NULL)
        {
            return -1;
        }

        $query = 'MATCH (n:Topic) WHERE {uri} in n.subject_identifiers RETURN n.id';
        $bind = [ 'uri' => $uri ];

        $logger->info($query, $bind);

        try
        {
            $qresult = $db_conn->run($query, $bind);
        }
        catch (Neo4jException $exception)
        {
            $logger->error($exception->getMessage());
            // TODO: Error handling
            return -1;
        }

        foreach ($qresult->records() as $record)
        {
            return $record->get('n.id');
        }

        return false;
    }
    
    
    public function selectTopicSubjectIdentifier($topic_id)
    {
        return $this->selectTopicSubject($topic_id, 'subject_identifiers');
    }
    
    
    public function selectTopicSubjectLocator($topic_id)
    {
        return $this->selectTopicSubject($topic_id, 'subject_locators');
    }
    
    
    protected function selectTopicSubject($topic_id, $what)
    {
        $logger = $this->topicmap->getLogger();
        $db = $this->topicmap->getDb();
        
        if (strlen($topic_id) === 0)
        {
            return false;
        }

        $db_conn = $db->getConnection();

        if ($db_conn === NULL)
        {
            return false;
        }

        $query = 'MATCH (topic { id: {id} }) RETURN topic.' . $what;
        $bind = [ 'id' => $topic_id ];

        $logger->info($query, $bind);
        
        try
        {
            $qresult = $db_conn->run($query, $bind);
        }
        catch (Neo4jException $exception)
        {
            $logger->error($exception->getMessage());
            return false;
        }

        // TODO add error handling

        $record = $qresult->firstRecord();
        
        if (empty($record))
        {
            return false;
        }
        
        $values = $record->get('topic.' . $what);
        <commit_msg>Fixed fatal error in TopicMapDbAdapter::selectTopicSubject() when the topic does not exist.<commit_after><?php

namespace TopicCards\Db;

use GraphAware\Neo4j\Client\Exception\Neo4jException;
use TopicCards\Interfaces\TopicMapInterface;
use TopicCards\Interfaces\TopicMapDbAdapterInterface;


class TopicMapDbAdapter implements TopicMapDbAdapterInterface
{
    /** @var TopicMapInterface */
    protected $topicmap;
    

    public function __construct(TopicMapInterface $topicmap)
    {
        $this->topicmap = $topicmap;
    }
    
    
    public function selectTopics(array $filters)
    {
        $logger = $this->topicmap->getLogger();
        $db = $this->topicmap->getDb();
        
        if (! isset($filters['limit']))
        {
            $filters['limit'] = 500;
        }

        if (isset($filters['type']))
        {
            $filters['type_id'] = $this->topicmap->getTopicIdBySubject($filters['type']);
        }

        $db_conn = $db->getConnection();
        
        if ($db_conn === NULL)
        {
            return -1;
        }

        $classes = [ 'Topic' ];

        if (! empty($filters['type_id']))
        {
            $classes[] = $filters['type_id'];
        }

        $query = sprintf
        (
            'MATCH (t%s)',
            DbUtils::labelsString($classes)
        );

        $bind = [ ];

        if (! empty($filters['name_like']))
        {
            $query .= '-[:hasName]->(n:Name) WHERE lower(n.value) CONTAINS lower({name_like})';
            $bind[ 'name_like' ] = $filters['name_like']; 
        }

        $query .= ' RETURN DISTINCT t.id';

        if ($filters[ 'limit' ] > 0)
        {
            $query .= ' LIMIT ' . $filters[ 'limit' ];
        }

        $logger->info($query, $bind);

        try
        {
            $qresult = $db_conn->run($query, $bind);
        }
        catch (Neo4jException $exception)
        {
            $logger->error($exception->getMessage());
            // TODO: Error handling
            return -1;
        }

        $result = [ ];

        foreach ($qresult->records() as $record)
        {
            $result[ ] = $record->get('t.id');
        }

        return $result;
    }
    
    
    public function selectTopicBySubject($uri)
    {
        $logger = $this->topicmap->getLogger();
        $db = $this->topicmap->getDb();
        
        if (strlen($uri) === 0)
        {
            return false;
        }

        $db_conn = $db->getConnection();

        if ($db_conn === NULL)
        {
            return -1;
        }

        $query = 'MATCH (n:Topic) WHERE {uri} in n.subject_identifiers RETURN n.id';
        $bind = [ 'uri' => $uri ];

        $logger->info($query, $bind);

        try
        {
            $qresult = $db_conn->run($query, $bind);
        }
        catch (Neo4jException $exception)
        {
            $logger->error($exception->getMessage());
            // TODO: Error handling
            return -1;
        }

        foreach ($qresult->records() as $record)
        {
            return $record->get('n.id');
        }

        return false;
    }
    
    
    public function selectTopicSubjectIdentifier($topic_id)
    {
        return $this->selectTopicSubject($topic_id, 'subject_identifiers');
    }
    
    
    public function selectTopicSubjectLocator($topic_id)
    {
        return $this->selectTopicSubject($topic_id, 'subject_locators');
    }
    
    
    protected function selectTopicSubject($topic_id, $what)
    {
        $logger = $this->topicmap->getLogger();
        $db = $this->topicmap->getDb();
        
        if (strlen($topic_id) === 0)
        {
            return false;
        }

        $db_conn = $db->getConnection();

        if ($db_conn === NULL)
        {
            return false;
        }

        $query = 'MATCH (topic { id: {id} }) RETURN topic.' . $what;
        $bind = [ 'id' => $topic_id ];

        $logger->info($query, $bind);
        
        try
        {
            $qresult = $db_conn->run($query, $bind);
        }
        catch (Neo4jException $exception)
        {
            $logger->error($exception->getMessage());
            return false;
        }

        if ($qresult->size() === 0)
        {
            return false;
        }
        
        $record = $qresult->firstRecord();
        
        $values = $record->get('topic.' . $what);
        
{'fraction_non_alphanumeric': 0.14915098669114274, 'fraction_numerical': 0.003556677374942634, 'mean_word_length': 1.5858795609611391, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 88, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3717492', 'n_tokens_mistral': 2621, 'n_tokens_neox': 2556, 'n_words': 461}