<commit_before><?php

namespace Tequilla\MongoDB;

use MongoDB\Driver\Command;
use MongoDB\Driver\Manager;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Query;
use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\ReadPreference;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Tequilla\Event\DropIndexesEvent;
use Tequilla\MongoDB\Command\Type\DropIndexesType;
use Tequilla\MongoDB\Command\Type\ListIndexesType;
use Tequilla\MongoDB\Command\CommandBuilder;
use Tequilla\MongoDB\Command\Type\CreateCollectionType;
use Tequilla\MongoDB\Command\Type\CreateIndexesType;
use Tequilla\MongoDB\Command\Type\DropCollectionType;
use Tequilla\MongoDB\Command\Type\DropDatabaseType;
use Tequilla\MongoDB\Command\Type\ListCollectionsType;
use Tequilla\MongoDB\Command\Type\ListDatabasesType;
use Tequilla\MongoDB\Event\DatabaseCommandEvent;
use Tequilla\MongoDB\Event\DatabaseDroppedEvent;
use Tequilla\MongoDB\Event\IndexesEvent;
use Tequilla\MongoDB\Exception\InvalidArgumentException;
use Tequilla\MongoDB\Exception\UnexpectedResultException;
use Tequilla\MongoDB\Options\Connection\ConnectionOptions;
use Tequilla\MongoDB\Options\Driver\DriverOptions;
use Tequilla\MongoDB\Options\Driver\TypeMapOptions;
use Tequilla\MongoDB\Event\GetDatabaseEvent;
use Tequilla\MongoDB\Event\DropDatabaseEvent;
use Tequilla\MongoDB\Event\DatabaseEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Class Client
 * @package Tequilla\MongoDB
 */
class Connection
{
    /**
     * @var Manager
     */
    protected $manager;

    /**
     * @var CommandBuilder[]
     */
    private $commandBuilders = [];

    /**
     * @var EventDispatcherInterface|null
     */
    private $dispatcher;

    /**
     * Client constructor.
     * @param string $uri
     * @param array $options
     * @param array $driverOptions
     * @param EventDispatcherInterface $dispatcher
     */
    public function __construct(
        $uri = 'mongodb://localhost:27017',
        array $options = [],
        array $driverOptions = [],
        EventDispatcherInterface $dispatcher = null
    ) {
        $resolver = new OptionsResolver();
        ConnectionOptions::configureOptions($resolver);
        $options = $resolver->resolve($options);

        $driverOptionsResolver = new OptionsResolver();
        DriverOptions::configureOptions($driverOptionsResolver);
        $driverOptions = $driverOptionsResolver->resolve($driverOptions);

        $this->manager = new Manager((string)$uri, $options, $driverOptions);
        $this->dispatcher = $dispatcher;
    }

    /**
     * @return \MongoDB\Driver\ReadConcern
     */
    public function getReadConcern()
    {
        return $this->manager->getReadConcern();
    }

    /**
     * @return \MongoDB\Driver\WriteConcern
     */
    public function getWriteConcern()
    {
        return $this->manager->getWriteConcern();
    }

    /**
     * @return \MongoDB\Driver\ReadPreference
     */
    public function getReadPreference()
    {
        return $this->manager->getReadPreference();
    }

    /**
     * @param string $namespace
     * @param BulkWrite $bulk
     * @param WriteConcern|null $writeConcern
     * @return \MongoDB\Driver\WriteResult
     */
    public function executeBulkWrite($namespace, BulkWrite $bulk, WriteConcern $writeConcern = null)
    {
        ensureValidNamespace($namespace);

        return $this->manager->executeBulkWrite($namespace, $bulk, $writeConcern);
    }

    /**
     * @param string $databaseName
     * @param array|object $command
     * @param ReadPreference|null $readPreference
     * @return array
     */
    public function executeCommand($databaseName, $command, ReadPreference $readPreference = null)
    {
        ensureValidDatabaseName($databaseName);

        if (!is_array($command) && !is_object($command)) {
            throw new InvalidArgumentException(
                sprintf(
                    '$command must be an array or an object, %s given',
                    getType($command)
                )
            );
        }

        $command = (array)$command;

        if (empty($command)) {
            throw new InvalidArgumentException('$command must not be empty.');
        }

        if (!$readPreference) {
            $readPreference = $this->getReadPreference();
        }

        $server = $this->manager->selectServer($readPreference);

        if ($this->dispatcher) {
            $event = new DatabaseCommandEvent($databaseName, $command, $server);
            $this->dispatcher->dispatch(Events::BEFORE_DATABASE_COMMAND_EXECUTED, $event);
        }

        $driverCommand = new Command($command);

        $cursor = $server->executeCommand($databaseName, $driverCommand);
        $result = TypeMapOptions::setArrayTypeMapOnCursor($cursor)->toArray();

        if ($this->dispatcher && isset($event)) {
            $event->refreshPropagation();
            $event->setCommandResult($result);<commit_msg>Making Connection::executeCommand to NOT accept driver's Command instances<commit_after><?php

namespace Tequilla\MongoDB;

use MongoDB\Driver\Command;
use MongoDB\Driver\Manager;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Query;
use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\ReadPreference;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Tequilla\Event\DropIndexesEvent;
use Tequilla\MongoDB\Command\Type\DropIndexesType;
use Tequilla\MongoDB\Command\Type\ListIndexesType;
use Tequilla\MongoDB\Command\CommandBuilder;
use Tequilla\MongoDB\Command\Type\CreateCollectionType;
use Tequilla\MongoDB\Command\Type\CreateIndexesType;
use Tequilla\MongoDB\Command\Type\DropCollectionType;
use Tequilla\MongoDB\Command\Type\DropDatabaseType;
use Tequilla\MongoDB\Command\Type\ListCollectionsType;
use Tequilla\MongoDB\Command\Type\ListDatabasesType;
use Tequilla\MongoDB\Event\DatabaseCommandEvent;
use Tequilla\MongoDB\Event\DatabaseDroppedEvent;
use Tequilla\MongoDB\Event\IndexesEvent;
use Tequilla\MongoDB\Exception\InvalidArgumentException;
use Tequilla\MongoDB\Exception\UnexpectedResultException;
use Tequilla\MongoDB\Options\Connection\ConnectionOptions;
use Tequilla\MongoDB\Options\Driver\DriverOptions;
use Tequilla\MongoDB\Options\Driver\TypeMapOptions;
use Tequilla\MongoDB\Event\GetDatabaseEvent;
use Tequilla\MongoDB\Event\DropDatabaseEvent;
use Tequilla\MongoDB\Event\DatabaseEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Class Client
 * @package Tequilla\MongoDB
 */
class Connection
{
    /**
     * @var Manager
     */
    protected $manager;

    /**
     * @var CommandBuilder[]
     */
    private $commandBuilders = [];

    /**
     * @var EventDispatcherInterface|null
     */
    private $dispatcher;

    /**
     * Client constructor.
     * @param string $uri
     * @param array $options
     * @param array $driverOptions
     * @param EventDispatcherInterface $dispatcher
     */
    public function __construct(
        $uri = 'mongodb://localhost:27017',
        array $options = [],
        array $driverOptions = [],
        EventDispatcherInterface $dispatcher = null
    ) {
        $resolver = new OptionsResolver();
        ConnectionOptions::configureOptions($resolver);
        $options = $resolver->resolve($options);

        $driverOptionsResolver = new OptionsResolver();
        DriverOptions::configureOptions($driverOptionsResolver);
        $driverOptions = $driverOptionsResolver->resolve($driverOptions);

        $this->manager = new Manager((string)$uri, $options, $driverOptions);
        $this->dispatcher = $dispatcher;
    }

    /**
     * @return \MongoDB\Driver\ReadConcern
     */
    public function getReadConcern()
    {
        return $this->manager->getReadConcern();
    }

    /**
     * @return \MongoDB\Driver\WriteConcern
     */
    public function getWriteConcern()
    {
        return $this->manager->getWriteConcern();
    }

    /**
     * @return \MongoDB\Driver\ReadPreference
     */
    public function getReadPreference()
    {
        return $this->manager->getReadPreference();
    }

    /**
     * @param string $namespace
     * @param BulkWrite $bulk
     * @param WriteConcern|null $writeConcern
     * @return \MongoDB\Driver\WriteResult
     */
    public function executeBulkWrite($namespace, BulkWrite $bulk, WriteConcern $writeConcern = null)
    {
        ensureValidNamespace($namespace);

        return $this->manager->executeBulkWrite($namespace, $bulk, $writeConcern);
    }

    /**
     * @param string $databaseName
     * @param array|object $command
     * @param ReadPreference|null $readPreference
     * @return array
     */
    public function executeCommand($databaseName, $command, ReadPreference $readPreference = null)
    {
        ensureValidDatabaseName($databaseName);

        if (!is_array($command) && !is_object($command)) {
            throw new InvalidArgumentException(
                sprintf(
                    '$command must be an array or an object, %s given',
                    getType($command)
                )
            );
        }

        if ($command instanceof Command) {
            throw new InvalidArgumentException(
                sprintf(
                    '%s does not accept Command instances in order to have access to the command options',
                    __METHOD__
                )
            );
        }

        $command = (array) $command;

        if (empty($command)) {
            throw new InvalidArgumentException('$command must not be empty.');
        }

        if (!$readPreference) {
            $readPreference = $this->getReadPreference();
        }

        $server = $this->manager->selectServer($readPreference);

        if ($this->dispatcher) {
            $event = new DatabaseCommandEvent($databaseName, $command, $server);
            $this->dispatcher->dispatch(Events::BEFORE_DATABASE_COMMAND_EXECUTED, $event);
        }

        $driverCommand = new Command($command);

        $cursor = $server->executeCommand($databaseName, $driverCommand);
        $result = TypeMapOptions::setArrayTypeMapOnCursor($cursor)->toArray();

        if ($this->dispatcher && isset($event)) {
            $event->refreshPropagation();
            $event->setCommandResult($result);
{'fraction_non_alphanumeric': 0.11344127975029263, 'fraction_numerical': 0.0009754194303550526, 'mean_word_length': 3.046172059984215, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 49, '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': '7615609', 'n_tokens_mistral': 2968, 'n_tokens_neox': 2867, 'n_words': 521}