Namespaces

  • 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

  • ActiveRow
  • GroupedSelection
  • Selection
  • Overview
  • Namespace
  • Class
  • Tree
  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:  */
 11: 
 12: namespace Nette\Database\Table;
 13: 
 14: use Nette;
 15: 
 16: 
 17: 
 18: /**
 19:  * Representation of filtered table grouped by some column.
 20:  * GroupedSelection is based on the great library NotORM http://www.notorm.com written by Jakub Vrana.
 21:  *
 22:  * @author     Jakub Vrana
 23:  * @author     Jan Skrasek
 24:  */
 25: class GroupedSelection extends Selection
 26: {
 27:     /** @var Selection referenced table */
 28:     protected $refTable;
 29: 
 30:     /** @var string grouping column name */
 31:     protected $column;
 32: 
 33:     /** @var string */
 34:     protected $delimitedColumn;
 35: 
 36:     /** @var int primary key */
 37:     protected $active;
 38: 
 39:     /** @var array of referencing cached results */
 40:     protected $referencing;
 41: 
 42:     /** @var array of [conditions => [key => ActiveRow]] */
 43:     protected $aggregation = array();
 44: 
 45: 
 46: 
 47:     public function __construct($name, Selection $refTable, $column)
 48:     {
 49:         parent::__construct($name, $refTable->connection);
 50:         $this->refTable = $refTable;
 51:         $this->column = $column;
 52:         $this->delimitedColumn = $this->connection->getSupplementalDriver()->delimite($this->column);
 53:     }
 54: 
 55: 
 56: 
 57:     /**
 58:      * @internal
 59:      * @param  int  $active
 60:      * @return GroupedSelection
 61:      */
 62:     public function setActive($active)
 63:     {
 64:         $this->rows = NULL;
 65:         $this->active = $active;
 66:         $this->select = $this->where = $this->conditions = $this->parameters = $this->order = array();
 67:         $this->limit = $this->offset = NULL;
 68:         $this->group = $this->having = '';
 69:         return $this;
 70:     }
 71: 
 72: 
 73: 
 74:     /** @deprecated */
 75:     public function through($column)
 76:     {
 77:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::related("' . $this->name . '", "' . $column . '") instead.', E_USER_WARNING);
 78:         $this->column = $column;
 79:         $this->delimitedColumn = $this->refTable->connection->getSupplementalDriver()->delimite($this->column);
 80:         return $this;
 81:     }
 82: 
 83: 
 84: 
 85:     public function select($columns)
 86:     {
 87:         if (!$this->select) {
 88:             $this->select[] = "$this->delimitedName.$this->delimitedColumn";
 89:         }
 90:         return parent::select($columns);
 91:     }
 92: 
 93: 
 94: 
 95:     public function order($columns)
 96:     {
 97:         if (!$this->order) { // improve index utilization
 98:             $this->order[] = "$this->delimitedName.$this->delimitedColumn"
 99:                 . (preg_match('~\\bDESC$~i', $columns) ? ' DESC' : '');
100:         }
101:         return parent::order($columns);
102:     }
103: 
104: 
105: 
106:     public function aggregation($function)
107:     {
108:         $aggregation = & $this->aggregation[$function . implode('', $this->where) . implode('', $this->conditions)];
109:         if ($aggregation === NULL) {
110:             $aggregation = array();
111: 
112:             $selection = new Selection($this->name, $this->connection);
113:             $selection->where = $this->where;
114:             $selection->parameters = $this->parameters;
115:             $selection->conditions = $this->conditions;
116: 
117:             $selection->select($function);
118:             $selection->select("{$this->name}.{$this->column}");
119:             $selection->group("{$this->name}.{$this->column}");
120: 
121:             foreach ($selection as $row) {
122:                 $aggregation[$row[$this->column]] = $row;
123:             }
124:         }
125: 
126:         if (isset($aggregation[$this->active])) {
127:             foreach ($aggregation[$this->active] as $val) {
128:                 return $val;
129:             }
130:         }
131:     }
132: 
133: 
134: 
135:     public function count($column = '')
136:     {
137:         $return = parent::count($column);
138:         return isset($return) ? $return : 0;
139:     }
140: 
141: 
142: 
143:     public function insert($data)
144:     {
145:         if ($data instanceof \Traversable && !$data instanceof Selection) {
146:             $data = iterator_to_array($data);
147:         }
148: 
149:         if (Nette\Utils\Validators::isList($data)) {
150:             foreach (array_keys($data) as $key) {
151:                 $data[$key][$this->column] = $this->active;
152:             }
153:         } else {
154:             $data[$this->column] = $this->active;
155:         }
156: 
157:         return parent::insert($data);
158:     }
159: 
160: 
161: 
162:     public function update($data)
163:     {
164:         $condition = array($this->where, $this->parameters);
165: 
166:         $this->where[0] = "$this->delimitedColumn = ?";
167:         $this->parameters[0] = $this->active;
168:         $return = parent::update($data);
169: 
170:         list($this->where, $this->parameters) = $condition;
171:         return $return;
172:     }
173: 
174: 
175: 
176:     public function delete()
177:     {
178:         $condition = array($this->where, $this->parameters);
179: 
180:         $this->where[0] = "$this->delimitedColumn = ?";
181:         $this->parameters[0] = $this->active;
182:         $return = parent::delete();
183: 
184:         list($this->where, $this->parameters) = $condition;
185:         return $return;
186:     }
187: 
188: 
189: 
190:     protected function execute()
191:     {
192:         if ($this->rows !== NULL) {
193:             return;
194:         }
195: 
196:         $hash = md5($this->getSql() . json_encode($this->parameters));
197:         $referencing = & $this->referencing[$hash];
198:         if ($referencing === NULL) {
199:             $limit = $this->limit;
200:             $rows = count($this->refTable->rows);
201:             if ($this->limit && $rows > 1) {
202:                 $this->limit = NULL;
203:             }
204:             parent::execute();
205:             $this->limit = $limit;
206:             $referencing = array();
207:             $offset = array();
208:             foreach ($this->rows as $key => $row) {
209:                 $ref = & $referencing[$row[$this->column]];
210:                 $skip = & $offset[$row[$this->column]];
211:                 if ($limit === NULL || $rows <= 1 || (count($ref) < $limit && $skip >= $this->offset)) {
212:                     $ref[$key] = $row;
213:                 } else {
214:                     unset($this->rows[$key]);
215:                 }
216:                 $skip++;
217:                 unset($ref, $skip);
218:             }
219:         }
220: 
221:         $this->data = & $referencing[$this->active];
222:         if ($this->data === NULL) {
223:             $this->data = array();
224:         } else {
225:             reset($this->data);
226:         }
227:     }
228: 
229: }
230: 
Nette Framework 2.0.4 API API documentation generated by ApiGen 2.7.0