Packages

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

Classes

  • GroupedTableSelection
  • SqlBuilder
  • TableRow
  • TableSelection
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  * @package Nette\Database\Table
 11:  */
 12: 
 13: 
 14: 
 15: /**
 16:  * Representation of filtered table grouped by some column.
 17:  * GroupedSelection is based on the great library NotORM http://www.notorm.com written by Jakub Vrana.
 18:  *
 19:  * @author     Jakub Vrana
 20:  * @author     Jan Skrasek
 21:  * @package Nette\Database\Table
 22:  */
 23: class GroupedTableSelection extends TableSelection
 24: {
 25:     /** @var TableSelection referenced table */
 26:     protected $refTable;
 27: 
 28:     /** @var string grouping column name */
 29:     protected $column;
 30: 
 31:     /** @var int primary key */
 32:     protected $active;
 33: 
 34: 
 35:     /**
 36:      * Creates filtered and grouped table representation.
 37:      * @param  TableSelection  $refTable
 38:      * @param  string  database table name
 39:      * @param  string  joining column
 40:      */
 41:     public function __construct(TableSelection $refTable, $table, $column)
 42:     {
 43:         parent::__construct($table, $refTable->connection);
 44:         $this->refTable = $refTable;
 45:         $this->column = $column;
 46:     }
 47: 
 48: 
 49:     /**
 50:      * Sets active group.
 51:      * @internal
 52:      * @param  int  primary key of grouped rows
 53:      * @return GroupedTableSelection
 54:      */
 55:     public function setActive($active)
 56:     {
 57:         $this->active = $active;
 58:         return $this;
 59:     }
 60: 
 61: 
 62:     /** @deprecated */
 63:     public function through($column)
 64:     {
 65:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::related("' . $this->name . '", "' . $column . '") instead.', E_USER_WARNING);
 66:         $this->column = $column;
 67:         $this->delimitedColumn = $this->refTable->connection->getSupplementalDriver()->delimite($this->column);
 68:         return $this;
 69:     }
 70: 
 71: 
 72:     public function select($columns)
 73:     {
 74:         if (!$this->sqlBuilder->getSelect()) {
 75:             $this->sqlBuilder->addSelect("$this->name.$this->column");
 76:         }
 77: 
 78:         return parent::select($columns);
 79:     }
 80: 
 81: 
 82:     public function order($columns)
 83:     {
 84:         if (!$this->sqlBuilder->getOrder()) {
 85:             // improve index utilization
 86:             $this->sqlBuilder->addOrder("$this->name.$this->column" . (preg_match('~\bDESC\z~i', $columns) ? ' DESC' : ''));
 87:         }
 88: 
 89:         return parent::order($columns);
 90:     }
 91: 
 92: 
 93:     /********************* aggregations ****************d*g**/
 94: 
 95: 
 96:     public function aggregation($function)
 97:     {
 98:         $aggregation = & $this->getRefTable($refPath)->aggregation[$refPath . $function . $this->getSql() . json_encode($this->sqlBuilder->getParameters())];
 99: 
100:         if ($aggregation === NULL) {
101:             $aggregation = array();
102: 
103:             $selection = $this->createSelectionInstance();
104:             $selection->getSqlBuilder()->importConditions($this->getSqlBuilder());
105:             $selection->select($function);
106:             $selection->select("$this->name.$this->column");
107:             $selection->group("$this->name.$this->column");
108: 
109:             foreach ($selection as $row) {
110:                 $aggregation[$row[$this->column]] = $row;
111:             }
112:         }
113: 
114:         if (isset($aggregation[$this->active])) {
115:             foreach ($aggregation[$this->active] as $val) {
116:                 return $val;
117:             }
118:         }
119:     }
120: 
121: 
122:     public function count($column = NULL)
123:     {
124:         $return = parent::count($column);
125:         return isset($return) ? $return : 0;
126:     }
127: 
128: 
129:     /********************* internal ****************d*g**/
130: 
131: 
132:     protected function execute()
133:     {
134:         if ($this->rows !== NULL) {
135:             $this->observeCache = $this;
136:             return;
137:         }
138: 
139:         $hash = md5($this->getSql() . json_encode($this->sqlBuilder->getParameters()));
140:         $accessedColumns = $this->accessedColumns;
141: 
142:         $referencingBase = & $this->getRefTable($refPath)->referencing[$this->getCacheKey()];
143:         $referencing = & $referencingBase[$refPath . $hash];
144:         $this->rows = & $referencing['rows'];
145:         $this->referenced = & $referencing['refs'];
146:         $this->accessedColumns = & $referencing['accessed'];
147:         $this->observeCache = & $referencingBase['observeCache'];
148:         $refData = & $referencing['data'];
149: 
150:         if ($refData === NULL) {
151:             // we have not fetched any data => init accessedColumns by cached accessedColumns
152:             $this->accessedColumns = $accessedColumns;
153: 
154:             $limit = $this->sqlBuilder->getLimit();
155:             $rows = count($this->refTable->rows);
156:             if ($limit && $rows > 1) {
157:                 $this->sqlBuilder->setLimit(NULL, NULL);
158:             }
159:             parent::execute();
160:             $this->sqlBuilder->setLimit($limit, NULL);
161:             $refData = array();
162:             $offset = array();
163:             $this->accessColumn($this->column);
164:             foreach ((array) $this->rows as $key => $row) {
165:                 $ref = & $refData[$row[$this->column]];
166:                 $skip = & $offset[$row[$this->column]];
167:                 if ($limit === NULL || $rows <= 1 || (count($ref) < $limit && $skip >= $this->sqlBuilder->getOffset())) {
168:                     $ref[$key] = $row;
169:                 } else {
170:                     unset($this->rows[$key]);
171:                 }
172:                 $skip++;
173:                 unset($ref, $skip);
174:             }
175:         }
176: 
177:         $this->observeCache = $this;
178:         $this->data = & $refData[$this->active];
179:         if ($this->data === NULL) {
180:             $this->data = array();
181:         } else {
182:             foreach ($this->data as $row) {
183:                 $row->setTable($this); // injects correct parent GroupedSelection
184:             }
185:             reset($this->data);
186:             $this->checkReferenced = TRUE;
187:         }
188:     }
189: 
190: 
191:     protected function getRefTable(& $refPath)
192:     {
193:         $refObj = $this->refTable;
194:         $refPath = $this->name . '.';
195:         while ($refObj instanceof GroupedTableSelection) {
196:             $refPath .= $refObj->name . '.';
197:             $refObj = $refObj->refTable;
198:         }
199: 
200:         return $refObj;
201:     }
202: 
203: 
204:     /********************* manipulation ****************d*g**/
205: 
206: 
207:     public function insert($data)
208:     {
209:         if ($data instanceof Traversable && !$data instanceof TableSelection) {
210:             $data = iterator_to_array($data);
211:         }
212: 
213:         if (Validators::isList($data)) {
214:             foreach (array_keys($data) as $key) {
215:                 $data[$key][$this->column] = $this->active;
216:             }
217:         } else {
218:             $data[$this->column] = $this->active;
219:         }
220: 
221:         return parent::insert($data);
222:     }
223: 
224: 
225:     public function update($data)
226:     {
227:         $builder = $this->sqlBuilder;
228: 
229:         $this->sqlBuilder = clone $this->sqlBuilder;
230:         $this->where($this->column, $this->active);
231:         $return = parent::update($data);
232: 
233:         $this->sqlBuilder = $builder;
234:         return $return;
235:     }
236: 
237: 
238:     public function delete()
239:     {
240:         $builder = $this->sqlBuilder;
241: 
242:         $this->sqlBuilder = clone $this->sqlBuilder;
243:         $this->where($this->column, $this->active);
244:         $return = parent::delete();
245: 
246:         $this->sqlBuilder = $builder;
247:         return $return;
248:     }
249: 
250: }
251: 
Nette Framework 2.0.12 (for PHP 5.2, un-prefixed) API API documentation generated by ApiGen 2.8.0