public function all(array $criteria = [])
    {
        /**
         * @var QueryBuilder $queryBuilder
         */
        $queryBuilder = $this->connection->createQueryBuilder();

        $queryBuilder
            ->select('R.*')
            ->from($this->tableName, 'R')
            ->addOrderBy('R.rate_date', 'DESC')
            ->addOrderBy('R.source_name', 'ASC')
            ->addOrderBy('R.currency_code', 'ASC')
            ->addOrderBy('R.rate_type', 'ASC');

        if (0 !== count($currencyCodes = self::extractArrayCriteria('currencyCode', $criteria))) {
            $queryBuilder
                ->andWhere('R.currency_code IN (:currency_codes)')
                ->setParameter(':currency_codes', $currencyCodes, Connection::PARAM_STR_ARRAY);
        }

        if (0 !== count($rateTypes = self::extractArrayCriteria('rateType', $criteria))) {
            $queryBuilder
                ->andWhere('R.rate_type IN (:rate_types)')
                ->setParameter(':rate_types', $rateTypes, Connection::PARAM_STR_ARRAY);
        }

        if (0 !== count($sourceNames = self::extractArrayCriteria('sourceName', $criteria))) {
            $queryBuilder
                ->andWhere('R.source_name IN (:source_names)')
                ->setParameter(':source_names', $sourceNames, Connection::PARAM_STR_ARRAY);
        }

        if (isset($criteria['dateFrom'])) {
            $queryBuilder
                ->andWhere('R.rate_date >= :date_from')
                ->setParameter('date_from', self::extractDateCriteria('dateFrom', $criteria)->format('Y-m-d'));
        }

        if (isset($criteria['dateTo'])) {
            $queryBuilder
                ->andWhere('R.rate_date <= :date_to')
                ->setParameter('date_to', self::extractDateCriteria('dateTo', $criteria)->format('Y-m-d'));
        }

        if (isset($criteria['onDate'])) {
            $queryBuilder
                ->andWhere('R.rate_date = :on_date')
                ->setParameter('on_date', self::extractDateCriteria('onDate', $criteria)->format('Y-m-d'));
        }

        if (isset($criteria['limit'])) {
            $queryBuilder->setMaxResults($criteria['limit']);
        }

        if (isset($criteria['offset'])) {
            $queryBuilder->setFirstResult($criteria['offset']);
        }

        /**
         * @var Statement $statement
         */
        $statement = $queryBuilder->execute();

        $result = [];

        while (($row = $statement->fetch()) !== false) {
            $rate                    = $this->buildRateFromTableRowData($row);
            $key                     = $this->getRateKey($rate->getCurrencyCode(), $rate->getDate(), $rate->getRateType(), $rate->getSourceName());
            $this->identityMap[$key] = $rate;
            $result[]                = $rate;
        }

        return $result;
    }
public function all(array $criteria = [])
    {
        /**
         * @var QueryBuilder $queryBuilder
         */
        $queryBuilder = $this->connection->createQueryBuilder();

        $queryBuilder
            ->select('R.*')
            ->from($this->tableName, 'R')
            ->addOrderBy('R.rate_date', 'DESC')
            ->addOrderBy('R.source_name', 'ASC')
            ->addOrderBy('R.currency_code', 'ASC')
            ->addOrderBy('R.rate_type', 'ASC');

        if (0 !== count($currencyCodes = self::extractArrayCriteria('currencyCode', $criteria))) {
            $queryBuilder
                ->andWhere('R.currency_code IN (:currency_codes)')
                ->setParameter(':currency_codes', $currencyCodes, Connection::PARAM_STR_ARRAY);
        }

        if (0 !== count($rateTypes = self::extractArrayCriteria('rateType', $criteria))) {
            $queryBuilder
                ->andWhere('R.rate_type IN (:rate_types)')
                ->setParameter(':rate_types', $rateTypes, Connection::PARAM_STR_ARRAY);
        }

        if (0 !== count($sourceNames = self::extractArrayCriteria('sourceName', $criteria))) {
            $queryBuilder
                ->andWhere('R.source_name IN (:source_names)')
                ->setParameter(':source_names', $sourceNames, Connection::PARAM_STR_ARRAY);
        }

        if (isset($criteria['dateFrom'])) {
            $queryBuilder
                ->andWhere('R.rate_date >= :date_from')
                ->setParameter('date_from', self::extractDateCriteria('dateFrom', $criteria)->format('Y-m-d'));
        }

        if (isset($criteria['dateTo'])) {
            $queryBuilder
                ->andWhere('R.rate_date <= :date_to')
                ->setParameter('date_to', self::extractDateCriteria('dateTo', $criteria)->format('Y-m-d'));
        }

        if (isset($criteria['onDate'])) {
            $queryBuilder
                ->andWhere('R.rate_date = :on_date')
                ->setParameter('on_date', self::extractDateCriteria('onDate', $criteria)->format('Y-m-d'));
        }

        if (isset($criteria['limit'])) {
            $queryBuilder->setMaxResults($criteria['limit']);
        }

        if (isset($criteria['offset'])) {
            $queryBuilder->setFirstResult($criteria['offset']);
        }

        /**
         * @var Statement $statement
         */
        $statement = $queryBuilder->execute();

        $result = [];

        while (($row = $statement->fetch()) !== false) {
            $rate                    = $this->buildRateFromTableRowData($row);
            $key                     = $this->getRateKey($rate->getCurrencyCode(), $rate->getDate(), $rate->getRateType(), $rate->getSourceName());
            $this->identityMap[$key] = $rate;
            $result[]                = $rate;
        }

        return $result;
    }
{@inheritdoc}