Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationLatte
      • ApplicationTracy
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsLatte
      • Framework
      • HttpTracy
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy

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 (http://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\Utils\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\Utils\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:      * @param  int
268:      * @return mixed|FALSE
269:      */
270:     public function fetchField($column = 0)
271:     {
272:         $row = $this->fetch();
273:         return $row ? $row[$column] : FALSE;
274:     }
275: 
276: 
277:     /**
278:      * @inheritDoc
279:      */
280:     public function fetchPairs($key = NULL, $value = NULL)
281:     {
282:         return Helpers::toPairs($this->fetchAll(), $key, $value);
283:     }
284: 
285: 
286:     /**
287:      * @inheritDoc
288:      */
289:     public function fetchAll()
290:     {
291:         if ($this->results === NULL) {
292:             $this->results = iterator_to_array($this);
293:         }
294:         return $this->results;
295:     }
296: 
297: 
298:     /**
299:      * Fetches all rows and returns associative tree.
300:      * @param  string  associative descriptor
301:      * @return array
302:      */
303:     public function fetchAssoc($path)
304:     {
305:         return Nette\Utils\Arrays::associate($this->fetchAll(), $path);
306:     }
307: 
308: }
309: 
Nette 2.2 API documentation generated by ApiGen 2.8.0