Namespaces

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Diagnostics
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
      • Diagnostics
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • PhpGenerator
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
  • NetteModule
  • none

Classes

  • Connection
  • Context
  • Helpers
  • ResultSet
  • Row
  • SqlLiteral
  • SqlPreprocessor

Interfaces

  • IReflection
  • IRow
  • IRowContainer
  • ISupplementalDriver
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Database;
  9: 
 10: use Nette;
 11: use PDO;
 12: 
 13: 
 14: /**
 15:  * Represents a result set.
 16:  *
 17:  * @author     David Grudl
 18:  * @author     Jan Skrasek
 19:  *
 20:  * @property-read Connection $connection
 21:  */
 22: class ResultSet extends Nette\Object implements \Iterator, IRowContainer
 23: {
 24:     /** @var Connection */
 25:     private $connection;
 26: 
 27:     /** @var ISupplementalDriver */
 28:     private $supplementalDriver;
 29: 
 30:     /** @var \PDOStatement|NULL */
 31:     private $pdoStatement;
 32: 
 33:     /** @var IRow */
 34:     private $result;
 35: 
 36:     /** @var int */
 37:     private $resultKey = -1;
 38: 
 39:     /** @var IRow[] */
 40:     private $results;
 41: 
 42:     /** @var float */
 43:     private $time;
 44: 
 45:     /** @var string */
 46:     private $queryString;
 47: 
 48:     /** @var array */
 49:     private $params;
 50: 
 51:     /** @var array */
 52:     private $types;
 53: 
 54: 
 55:     public function __construct(Connection $connection, $queryString, array $params)
 56:     {
 57:         $time = microtime(TRUE);
 58:         $this->connection = $connection;
 59:         $this->supplementalDriver = $connection->getSupplementalDriver();
 60:         $this->queryString = $queryString;
 61:         $this->params = $params;
 62: 
 63:         if (substr($queryString, 0, 2) === '::') {
 64:             $connection->getPdo()->{substr($queryString, 2)}();
 65:         } elseif ($queryString !== NULL) {
 66:             $this->pdoStatement = $connection->getPdo()->prepare($queryString);
 67:             $this->pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
 68:             $this->pdoStatement->execute($params);
 69:         }
 70:         $this->time = microtime(TRUE) - $time;
 71:     }
 72: 
 73: 
 74:     /**
 75:      * @return Connection
 76:      */
 77:     public function getConnection()
 78:     {
 79:         return $this->connection;
 80:     }
 81: 
 82: 
 83:     /**
 84:      * @internal
 85:      * @return \PDOStatement
 86:      */
 87:     public function getPdoStatement()
 88:     {
 89:         return $this->pdoStatement;
 90:     }
 91: 
 92: 
 93:     /**
 94:      * @return string
 95:      */
 96:     public function getQueryString()
 97:     {
 98:         return $this->queryString;
 99:     }
100: 
101: 
102:     /**
103:      * @return array
104:      */
105:     public function getParameters()
106:     {
107:         return $this->params;
108:     }
109: 
110: 
111:     /**
112:      * @return int
113:      */
114:     public function getColumnCount()
115:     {
116:         return $this->pdoStatement ? $this->pdoStatement->columnCount() : NULL;
117:     }
118: 
119: 
120:     /**
121:      * @return int
122:      */
123:     public function getRowCount()
124:     {
125:         return $this->pdoStatement ? $this->pdoStatement->rowCount() : NULL;
126:     }
127: 
128: 
129:     /**
130:      * @return float
131:      */
132:     public function getTime()
133:     {
134:         return $this->time;
135:     }
136: 
137: 
138:     /**
139:      * Normalizes result row.
140:      * @param  array
141:      * @return array
142:      */
143:     public function normalizeRow($row)
144:     {
145:         if ($this->types === NULL) {
146:             $this->types = (array) $this->supplementalDriver->getColumnTypes($this->pdoStatement);
147:         }
148: 
149:         foreach ($this->types as $key => $type) {
150:             $value = $row[$key];
151:             if ($value === NULL || $value === FALSE || $type === IReflection::FIELD_TEXT) {
152: 
153:             } elseif ($type === IReflection::FIELD_INTEGER) {
154:                 $row[$key] = is_float($tmp = $value * 1) ? $value : $tmp;
155: 
156:             } elseif ($type === IReflection::FIELD_FLOAT) {
157:                 if (($pos = strpos($value, '.')) !== FALSE) {
158:                     $value = rtrim(rtrim($pos === 0 ? "0$value" : $value, '0'), '.');
159:                 }
160:                 $float = (float) $value;
161:                 $row[$key] = (string) $float === $value ? $float : $value;
162: 
163:             } elseif ($type === IReflection::FIELD_BOOL) {
164:                 $row[$key] = ((bool) $value) && $value !== 'f' && $value !== 'F';
165: 
166:             } elseif ($type === IReflection::FIELD_DATETIME || $type === IReflection::FIELD_DATE || $type === IReflection::FIELD_TIME) {
167:                 $row[$key] = new Nette\DateTime($value);
168: 
169:             } elseif ($type === IReflection::FIELD_TIME_INTERVAL) {
170:                 preg_match('#^(-?)(\d+)\D(\d+)\D(\d+)\z#', $value, $m);
171:                 $row[$key] = new \DateInterval("PT$m[2]H$m[3]M$m[4]S");
172:                 $row[$key]->invert = (int) (bool) $m[1];
173: 
174:             } elseif ($type === IReflection::FIELD_UNIX_TIMESTAMP) {
175:                 $row[$key] = Nette\DateTime::from($value);
176:             }
177:         }
178: 
179:         return $this->supplementalDriver->normalizeRow($row);
180:     }
181: 
182: 
183:     /********************* misc tools ****************d*g**/
184: 
185: 
186:     /**
187:      * Displays complete result set as HTML table for debug purposes.
188:      * @return void
189:      */
190:     public function dump()
191:     {
192:         Helpers::dumpResult($this);
193:     }
194: 
195: 
196:     /********************* interface Iterator ****************d*g**/
197: 
198: 
199:     public function rewind()
200:     {
201:         if ($this->result === FALSE) {
202:             throw new Nette\InvalidStateException('Nette\\Database\\ResultSet implements only one way iterator.');
203:         }
204:     }
205: 
206: 
207:     public function current()
208:     {
209:         return $this->result;
210:     }
211: 
212: 
213:     public function key()
214:     {
215:         return $this->resultKey;
216:     }
217: 
218: 
219:     public function next()
220:     {
221:         $this->result = FALSE;
222:     }
223: 
224: 
225:     public function valid()
226:     {
227:         if ($this->result) {
228:             return TRUE;
229:         }
230: 
231:         return $this->fetch() !== FALSE;
232:     }
233: 
234: 
235:     /********************* interface IRowContainer ****************d*g**/
236: 
237: 
238:     /**
239:      * @inheritDoc
240:      */
241:     public function fetch()
242:     {
243:         $data = $this->pdoStatement ? $this->pdoStatement->fetch() : NULL;
244:         if (!$data) {
245:             $this->pdoStatement->closeCursor();
246:             return FALSE;
247:         }
248: 
249:         $row = new Row;
250:         foreach ($this->normalizeRow($data) as $key => $value) {
251:             if ($key !== '') {
252:                 $row->$key = $value;
253:             }
254:         }
255: 
256:         if ($this->result === NULL && count($data) !== $this->pdoStatement->columnCount()) {
257:             trigger_error('Found duplicate columns in database result set.', E_USER_NOTICE);
258:         }
259: 
260:         $this->resultKey++;
261:         return $this->result = $row;
262:     }
263: 
264: 
265:     /**
266:      * Fetches single field.
267:      * @return mixed|FALSE
268:      */
269:     public function fetchField($column = 0)
270:     {
271:         $row = $this->fetch();
272:         return $row ? $row[$column] : FALSE;
273:     }
274: 
275: 
276:     /**
277:      * @inheritDoc
278:      */
279:     public function fetchPairs($key = NULL, $value = NULL)
280:     {
281:         return Helpers::toPairs($this->fetchAll(), $key, $value);
282:     }
283: 
284: 
285:     /**
286:      * @inheritDoc
287:      */
288:     public function fetchAll()
289:     {
290:         if ($this->results === NULL) {
291:             $this->results = iterator_to_array($this);
292:         }
293:         return $this->results;
294:     }
295: 
296: 
297:     /** @deprecated */
298:     function columnCount()
299:     {
300:         trigger_error(__METHOD__ . '() is deprecated; use getColumnCount() instead.', E_USER_DEPRECATED);
301:         return $this->getColumnCount();
302:     }
303: 
304: 
305:     /** @deprecated */
306:     function rowCount()
307:     {
308:         trigger_error(__METHOD__ . '() is deprecated; use getRowCount() instead.', E_USER_DEPRECATED);
309:         return $this->getRowCount();
310:     }
311: 
312: }
313: 
Nette 2.1 API documentation generated by ApiGen 2.8.0