Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • 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
    • Bridges
      • Nette

Classes

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

Interfaces

  • IConventions
  • IReflection
  • IRow
  • IRowContainer
  • IStructure
  • ISupplementalDriver

Exceptions

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