Bitrix-D7  20.0.0
main/lib/db/result.php
См. документацию.
1 <?php
2 namespace Bitrix\Main\DB;
3 
4 /**
5  * Class Result is the abstract base class for representing
6  * database query result.
7  * <p>
8  * It has ability to transform raw data populated from
9  * the database into useful associative arrays with
10  * some fields unserialized and some presented as Datetime
11  * objects or other changes.
12  * <p>
13  * It also supports query debugging by providing {@link \Bitrix\Main\Diag\SqlTracker}
14  * with timing information.
15  *
16  * @package Bitrix\Main\DB
17  */
18 abstract class Result implements \IteratorAggregate
19 {
20  /** @var \Bitrix\Main\DB\Connection */
21  protected $connection;
22  /** @var resource */
23  protected $resource;
24  /** @var \Bitrix\Main\Diag\SqlTrackerQuery */
25  protected $trackerQuery = null;
26 
27  /** @var callable[] */
28  protected $converters = array();
29  /** @var string[] */
30  protected $serializedFields = array();
31  /** @var string[] */
32  protected $replacedAliases = array();
33  /** @var callable[] */
34  protected $fetchDataModifiers = array();
35 
36  /** @var int */
37  protected $count;
38 
39  /**
40  * @param resource $result Database-specific query result.
41  * @param Connection $dbConnection Connection object.
42  * @param \Bitrix\Main\Diag\SqlTrackerQuery $trackerQuery Helps to collect debug information.
43  */
44  public function __construct($result, Connection $dbConnection = null, \Bitrix\Main\Diag\SqlTrackerQuery $trackerQuery = null)
45  {
46  $this->resource = $result;
47  $this->connection = $dbConnection;
48  $this->trackerQuery = $trackerQuery;
49  $resultFields = $this->getFields();
50  if ($resultFields && $this->connection)
51  {
52  $helper = $this->connection->getSqlHelper();
53  foreach ($resultFields as $key => $type)
54  {
55  $converter = $helper->getConverter($resultFields[$key]);
56  if (is_callable($converter))
57  {
58  $this->converters[$key] = $converter;
59  }
60  }
61  }
62  }
63 
64  /**
65  * Returns database-specific resource of this result.
66  *
67  * @return null|resource
68  */
69  public function getResource()
70  {
71  return $this->resource;
72  }
73 
74  /**
75  * Sets list of aliased columns.
76  * This allows to overcome database limits on length of the column names.
77  *
78  * @param array[string]string $replacedAliases Aliases map from tech to human.
79  *
80  * @return void
81  * @see \Bitrix\Main\Db\Result::addReplacedAliases
82  */
83  public function setReplacedAliases(array $replacedAliases)
84  {
85  $this->replacedAliases = $replacedAliases;
86  }
87 
88  /**
89  * Extends list of aliased columns.
90  *
91  * @param array[string]string $replacedAliases Aliases map from tech to human.
92  *
93  * @return void
94  * @see \Bitrix\Main\Db\Result::setReplacedAliases
95  */
96  public function addReplacedAliases(array $replacedAliases)
97  {
98  $this->replacedAliases = array_merge($this->replacedAliases, $replacedAliases);
99  }
100 
101  /**
102  * Sets internal list of fields which will be unserialized on fetch.
103  *
104  * @param array $serializedFields List of fields.
105  *
106  * @return void
107  */
108  public function setSerializedFields(array $serializedFields)
109  {
110  $this->serializedFields = $serializedFields;
111  }
112 
113  /**
114  * Modifier should accept once fetched array as an argument, then modify by link or return new array:
115  * - function (&$data) { $data['AGE'] -= 7; }
116  * - function ($data) { $data['AGE'] -= 7; return $data; }
117  *
118  * @param callable $fetchDataModifier Valid callback.
119  *
120  * @return void
121  * @throws \Bitrix\Main\ArgumentException
122  */
123  public function addFetchDataModifier($fetchDataModifier)
124  {
125  if (!is_callable($fetchDataModifier))
126  {
127  throw new \Bitrix\Main\ArgumentException('Data Modifier should be a callback');
128  }
129 
130  $this->fetchDataModifiers[] = $fetchDataModifier;
131  }
132 
133  /**
134  * Fetches one row of the query result and returns it in the associative array of raw DB data or false on empty data.
135  *
136  * @return array|false
137  */
138  public function fetchRaw()
139  {
140  if ($this->trackerQuery != null)
141  {
142  $this->trackerQuery->restartQuery();
143  }
144 
145  $data = $this->fetchRowInternal();
146 
147  if ($this->trackerQuery != null)
148  {
149  $this->trackerQuery->refinishQuery();
150  }
151 
152  if (!$data)
153  {
154  return false;
155  }
156 
157  return $data;
158  }
159 
160  /**
161  * Fetches one row of the query result and returns it in the associative array of converted data or false on empty data.
162  *
163  * @param \Bitrix\Main\Text\Converter $converter Optional converter to encode data on fetching.
164  *
165  * @return array|false
166  */
167  public function fetch(\Bitrix\Main\Text\Converter $converter = null)
168  {
169  $data = $this->fetchRaw();
170 
171  if (!$data)
172  {
173  return false;
174  }
175 
176  if ($this->converters)
177  {
178  foreach ($this->converters as $field => $convertDataModifier)
179  {
180  $data[$field] = call_user_func_array($convertDataModifier, array($data[$field]));
181  }
182  }
183 
184  if ($this->serializedFields)
185  {
186  foreach ($this->serializedFields as $field)
187  {
188  if (isset($data[$field]))
189  $data[$field] = unserialize($data[$field]);
190  }
191  }
192 
193  if ($this->replacedAliases)
194  {
195  foreach ($this->replacedAliases as $tech => $human)
196  {
197  $data[$human] = $data[$tech];
198  unset($data[$tech]);
199  }
200  }
201 
202  if ($this->fetchDataModifiers)
203  {
204  foreach ($this->fetchDataModifiers as $fetchDataModifier)
205  {
206  $result = call_user_func_array($fetchDataModifier, array(&$data));
207 
208  if (is_array($result))
209  {
210  $data = $result;
211  }
212  }
213  }
214 
215  if ($converter != null)
216  {
217  foreach ($data as $key => $val)
218  {
219  $data[$key] = $converter->encode(
220  $val,
221  (isset($data[$key."_TYPE"])? $data[$key."_TYPE"] : \Bitrix\Main\Text\Converter::TEXT)
222  );
223  }
224  }
225 
226  return $data;
227  }
228 
229  /**
230  * Fetches all the rows of the query result and returns it in the array of associative arrays.
231  * Returns an empty array if query has no data.
232  *
233  * @param \Bitrix\Main\Text\Converter $converter Optional converter to encode data on fetching.
234  *
235  * @return array
236  */
237  public function fetchAll(\Bitrix\Main\Text\Converter $converter = null)
238  {
239  $res = array();
240  while ($ar = $this->fetch($converter))
241  {
242  $res[] = $ar;
243  }
244  return $res;
245  }
246 
247  /**
248  * Returns an array of fields according to columns in the result.
249  *
250  * @return \Bitrix\Main\ORM\Fields\ScalarField[]
251  */
252  abstract public function getFields();
253 
254  /**
255  * Returns the number of rows in the result.
256  *
257  * @return int
258  */
259  abstract public function getSelectedRowsCount();
260 
261  /**
262  * Returns next result row or false.
263  *
264  * @return array|false
265  */
266  abstract protected function fetchRowInternal();
267 
268  /**
269  * Returns current query tracker.
270  *
271  * @return \Bitrix\Main\Diag\SqlTrackerQuery|null
272  */
273  public function getTrackerQuery()
274  {
275  return $this->trackerQuery;
276  }
277 
278  /**
279  * @return callable[]
280  */
281  public function getConverters()
282  {
283  return $this->converters;
284  }
285 
286  /**
287  * @param callable[] $converters
288  */
289  public function setConverters($converters)
290  {
291  $this->converters = $converters;
292  }
293 
294  /**
295  * Sets record count.
296  * @param int $n
297  */
298  public function setCount($n)
299  {
300  $this->count = (int)$n;
301  }
302 
303  /**
304  * Returns record count. It's required to set record count explicitly before.
305  * @return int
306  * @throws \Bitrix\Main\ObjectPropertyException
307  */
308  public function getCount()
309  {
310  if($this->count !== null)
311  {
312  return $this->count;
313  }
314  throw new \Bitrix\Main\ObjectPropertyException("count");
315  }
316 
317  /**
318  * Retrieve an external iterator
319  * @link http://php.net/manual/en/iteratoraggregate.getiterator.php
320  * @return \Traversable An instance of an object implementing <b>Iterator</b> or
321  * <b>Traversable</b>
322  * @since 5.0.0
323  */
324  public function getIterator()
325  {
326  return new ResultIterator($this);
327  }
328 }
Bitrix\Main\DB\Result\getCount
getCount()
Returns record count.
Definition: main/lib/db/result.php:308
Bitrix\Main\DB\Result\$replacedAliases
$replacedAliases
Definition: main/lib/db/result.php:32
Bitrix\Main\DB\Result\getIterator
getIterator()
Retrieve an external iterator http://php.net/manual/en/iteratoraggregate.getiterator....
Definition: main/lib/db/result.php:324
Bitrix\Main\DB\Result\fetchRaw
fetchRaw()
Fetches one row of the query result and returns it in the associative array of raw DB data or false o...
Definition: main/lib/db/result.php:138
Bitrix\Main\DB\Result\getSelectedRowsCount
getSelectedRowsCount()
Returns the number of rows in the result.
Bitrix\Main\DB\Result\setConverters
setConverters($converters)
Definition: main/lib/db/result.php:289
Bitrix\Main\DB\Result\$converters
$converters
Definition: main/lib/db/result.php:28
Bitrix\Main\Text\Converter\TEXT
const TEXT
Definition: main/lib/text/converter.php:6
Bitrix\Main\Data\Connection
Class Connection.
Definition: main/lib/data/connection.php:16
Bitrix\Main\Text\Converter
Definition: main/lib/text/converter.php:4
Bitrix\Main\DB\Result
Definition: main/lib/db/result.php:18
Bitrix\Main\DB\Result\getResource
getResource()
Returns database-specific resource of this result.
Definition: main/lib/db/result.php:69
Bitrix\Main\DB\Result\fetch
fetch(\Bitrix\Main\Text\Converter $converter=null)
Fetches one row of the query result and returns it in the associative array of converted data or fals...
Definition: main/lib/db/result.php:167
Bitrix\Main\DB\Result\setSerializedFields
setSerializedFields(array $serializedFields)
Sets internal list of fields which will be unserialized on fetch.
Definition: main/lib/db/result.php:108
Bitrix\Main\DB\Result\$fetchDataModifiers
$fetchDataModifiers
Definition: main/lib/db/result.php:34
Bitrix\Main\Diag\SqlTrackerQuery
Definition: sqltrackerquery.php:4
Bitrix\Main\DB\Result\$count
$count
Definition: main/lib/db/result.php:37
Bitrix\Main\DB\ResultIterator
Definition: resultiterator.php:7
Bitrix\Main\DB\Result\getTrackerQuery
getTrackerQuery()
Returns current query tracker.
Definition: main/lib/db/result.php:273
Bitrix\Main\DB\Result\__construct
__construct($result, Connection $dbConnection=null, \Bitrix\Main\Diag\SqlTrackerQuery $trackerQuery=null)
Definition: main/lib/db/result.php:44
Bitrix\Main\DB\Result\fetchAll
fetchAll(\Bitrix\Main\Text\Converter $converter=null)
Fetches all the rows of the query result and returns it in the array of associative arrays.
Definition: main/lib/db/result.php:237
Bitrix\Main\DB\Result\getConverters
getConverters()
Definition: main/lib/db/result.php:281
Bitrix\Main\DB
Definition: arrayresult.php:2
Bitrix\Main\DB\Result\$connection
$connection
Definition: main/lib/db/result.php:21
Bitrix\Main\DB\Result\setCount
setCount($n)
Sets record count.
Definition: main/lib/db/result.php:298
Bitrix\Main\DB\Result\$resource
$resource
Definition: main/lib/db/result.php:23
Bitrix\Main\DB\Result\addReplacedAliases
addReplacedAliases(array $replacedAliases)
Extends list of aliased columns.
Definition: main/lib/db/result.php:96
Bitrix
Class Button.
Bitrix\Main\DB\Result\$trackerQuery
$trackerQuery
Definition: main/lib/db/result.php:25
Bitrix\Main\DB\Result\fetchRowInternal
fetchRowInternal()
Returns next result row or false.
Bitrix\Main\DB\Result\getFields
getFields()
Returns an array of fields according to columns in the result.
Bitrix\Main\DB\Result\setReplacedAliases
setReplacedAliases(array $replacedAliases)
Sets list of aliased columns.
Definition: main/lib/db/result.php:83
Bitrix\Main\DB\Result\addFetchDataModifier
addFetchDataModifier($fetchDataModifier)
Modifier should accept once fetched array as an argument, then modify by link or return new array:
Definition: main/lib/db/result.php:123
Bitrix\Main\DB\Result\$serializedFields
$serializedFields
Definition: main/lib/db/result.php:30