Current Path : /var/www/www-root/data/webdav/www.catalog.monolith-realty.ru/bitrix/modules/main/lib/db/ |
Current File : /var/www/www-root/data/webdav/www.catalog.monolith-realty.ru/bitrix/modules/main/lib/db/result.php |
<?php namespace Bitrix\Main\DB; /** * Class Result is the abstract base class for representing * database query result. * <p> * It has ability to transform raw data populated from * the database into useful associative arrays with * some fields unserialized and some presented as Datetime * objects or other changes. * <p> * It also supports query debugging by providing {@link \Bitrix\Main\Diag\SqlTracker} * with timing information. * * @package Bitrix\Main\DB */ abstract class Result implements \IteratorAggregate { /** @var \Bitrix\Main\DB\Connection */ protected $connection; /** @var resource */ protected $resource; /** @var \Bitrix\Main\Diag\SqlTrackerQuery */ protected $trackerQuery = null; /** @var callable[] */ protected $converters = array(); /** @var string[] */ protected $serializedFields = array(); /** @var string[] */ protected $replacedAliases = array(); /** @var callable[] */ protected $fetchDataModifiers = array(); /** @var int */ protected $count; /** * @param resource $result Database-specific query result. * @param Connection $dbConnection Connection object. * @param \Bitrix\Main\Diag\SqlTrackerQuery $trackerQuery Helps to collect debug information. */ public function __construct($result, Connection $dbConnection = null, \Bitrix\Main\Diag\SqlTrackerQuery $trackerQuery = null) { $this->resource = $result; $this->connection = $dbConnection; $this->trackerQuery = $trackerQuery; $resultFields = $this->getFields(); if ($resultFields && $this->connection) { $helper = $this->connection->getSqlHelper(); foreach ($resultFields as $key => $type) { $converter = $helper->getConverter($resultFields[$key]); if (is_callable($converter)) { $this->converters[$key] = $converter; } } } } /** * Returns database-specific resource of this result. * * @return null|resource */ public function getResource() { return $this->resource; } /** * Sets list of aliased columns. * This allows to overcome database limits on length of the column names. * * @param array[string]string $replacedAliases Aliases map from tech to human. * * @return void * @see \Bitrix\Main\Db\Result::addReplacedAliases */ public function setReplacedAliases(array $replacedAliases) { $this->replacedAliases = $replacedAliases; } /** * Extends list of aliased columns. * * @param array[string]string $replacedAliases Aliases map from tech to human. * * @return void * @see \Bitrix\Main\Db\Result::setReplacedAliases */ public function addReplacedAliases(array $replacedAliases) { $this->replacedAliases = array_merge($this->replacedAliases, $replacedAliases); } /** * Sets internal list of fields which will be unserialized on fetch. * * @param array $serializedFields List of fields. * * @return void */ public function setSerializedFields(array $serializedFields) { $this->serializedFields = $serializedFields; } /** * Modifier should accept once fetched array as an argument, then modify by link or return new array: * - function (&$data) { $data['AGE'] -= 7; } * - function ($data) { $data['AGE'] -= 7; return $data; } * * @param callable $fetchDataModifier Valid callback. * * @return void * @throws \Bitrix\Main\ArgumentException */ public function addFetchDataModifier($fetchDataModifier) { if (!is_callable($fetchDataModifier)) { throw new \Bitrix\Main\ArgumentException('Data Modifier should be a callback'); } $this->fetchDataModifiers[] = $fetchDataModifier; } /** * Fetches one row of the query result and returns it in the associative array of raw DB data or false on empty data. * * @return array|false */ public function fetchRaw() { if ($this->trackerQuery != null) { $this->trackerQuery->restartQuery(); } $data = $this->fetchRowInternal(); if ($this->trackerQuery != null) { $this->trackerQuery->refinishQuery(); } if (!$data) { return false; } return $data; } /** * Fetches one row of the query result and returns it in the associative array of converted data or false on empty data. * * @param \Bitrix\Main\Text\Converter $converter Optional converter to encode data on fetching. * * @return array|false */ public function fetch(\Bitrix\Main\Text\Converter $converter = null) { $data = $this->fetchRaw(); if (!$data) { return false; } if ($this->converters) { foreach ($this->converters as $field => $convertDataModifier) { $data[$field] = call_user_func_array($convertDataModifier, array($data[$field])); } } if ($this->serializedFields) { foreach ($this->serializedFields as $field) { if (isset($data[$field])) $data[$field] = unserialize($data[$field]); } } if ($this->replacedAliases) { foreach ($this->replacedAliases as $tech => $human) { $data[$human] = $data[$tech]; unset($data[$tech]); } } if ($this->fetchDataModifiers) { foreach ($this->fetchDataModifiers as $fetchDataModifier) { $result = call_user_func_array($fetchDataModifier, array(&$data)); if (is_array($result)) { $data = $result; } } } if ($converter !== null) { foreach ($data as $key => $val) { $data[$key] = $converter->encode( $val, ($data[$key."_TYPE"] ?? \Bitrix\Main\Text\Converter::TEXT) ); } } return $data; } /** * Fetches all the rows of the query result and returns it in the array of associative arrays. * Returns an empty array if query has no data. * * @param \Bitrix\Main\Text\Converter $converter Optional converter to encode data on fetching. * * @return array */ public function fetchAll(\Bitrix\Main\Text\Converter $converter = null) { $res = array(); while ($ar = $this->fetch($converter)) { $res[] = $ar; } return $res; } /** * Returns an array of fields according to columns in the result. * * @return \Bitrix\Main\ORM\Fields\ScalarField[] */ abstract public function getFields(); /** * Returns the number of rows in the result. * * @return int */ abstract public function getSelectedRowsCount(); /** * Returns next result row or false. * * @return array|false */ abstract protected function fetchRowInternal(); /** * Returns current query tracker. * * @return \Bitrix\Main\Diag\SqlTrackerQuery|null */ public function getTrackerQuery() { return $this->trackerQuery; } /** * @return callable[] */ public function getConverters() { return $this->converters; } /** * @param callable[] $converters */ public function setConverters($converters) { $this->converters = $converters; } /** * Sets record count. * @param int $n */ public function setCount($n) { $this->count = (int)$n; } /** * Returns record count. It's required to set record count explicitly before. * @return int * @throws \Bitrix\Main\ObjectPropertyException */ public function getCount() { if($this->count !== null) { return $this->count; } throw new \Bitrix\Main\ObjectPropertyException("count"); } /** * Retrieve an external iterator * @link http://php.net/manual/en/iteratoraggregate.getiterator.php * @return \Traversable An instance of an object implementing <b>Iterator</b> or * <b>Traversable</b> * @since 5.0.0 */ public function getIterator(): \Traversable { return new ResultIterator($this); } }