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

  • ActiveRow
  • GroupedSelection
  • Selection
  • SqlBuilder

Interfaces

  • IRow
  • IRowContainer
  • 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\Table;
  9: 
 10: use Nette;
 11: 
 12: 
 13: /**
 14:  * Single row representation.
 15:  * ActiveRow is based on the great library NotORM http://www.notorm.com written by Jakub Vrana.
 16:  *
 17:  * @author     Jakub Vrana
 18:  * @author     Jan Skrasek
 19:  */
 20: class ActiveRow implements \IteratorAggregate, IRow
 21: {
 22:     /** @var Selection */
 23:     private $table;
 24: 
 25:     /** @var array of row data */
 26:     private $data;
 27: 
 28:     /** @var bool */
 29:     private $dataRefreshed = FALSE;
 30: 
 31: 
 32:     public function __construct(array $data, Selection $table)
 33:     {
 34:         $this->data = $data;
 35:         $this->table = $table;
 36:     }
 37: 
 38: 
 39:     /**
 40:      * @internal
 41:      * @ignore
 42:      */
 43:     public function setTable(Selection $table)
 44:     {
 45:         $this->table = $table;
 46:     }
 47: 
 48: 
 49:     /**
 50:      * @internal
 51:      */
 52:     public function getTable()
 53:     {
 54:         return $this->table;
 55:     }
 56: 
 57: 
 58:     public function __toString()
 59:     {
 60:         try {
 61:             return (string) $this->getPrimary();
 62:         } catch (\Exception $e) {
 63:             if (func_num_args()) {
 64:                 throw $e;
 65:             }
 66:             trigger_error("Exception in " . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR);
 67:         }
 68:     }
 69: 
 70: 
 71:     /**
 72:      * @return array
 73:      */
 74:     public function toArray()
 75:     {
 76:         $this->accessColumn(NULL);
 77:         return $this->data;
 78:     }
 79: 
 80: 
 81:     /**
 82:      * Returns primary key value.
 83:      * @param  bool
 84:      * @return mixed possible int, string, array, object (Nette\Utils\DateTime)
 85:      */
 86:     public function getPrimary($need = TRUE)
 87:     {
 88:         $primary = $this->table->getPrimary($need);
 89:         if ($primary === NULL) {
 90:             return NULL;
 91: 
 92:         } elseif (!is_array($primary)) {
 93:             if (isset($this->data[$primary])) {
 94:                 return $this->data[$primary];
 95:             } elseif ($need) {
 96:                 throw new Nette\InvalidStateException("Row does not contain primary $primary column data.");
 97:             } else {
 98:                 return NULL;
 99:             }
100: 
101:         } else {
102:             $primaryVal = array();
103:             foreach ($primary as $key) {
104:                 if (!isset($this->data[$key])) {
105:                     if ($need) {
106:                         throw new Nette\InvalidStateException("Row does not contain primary $key column data.");
107:                     } else {
108:                         return NULL;
109:                     }
110:                 }
111:                 $primaryVal[$key] = $this->data[$key];
112:             }
113:             return $primaryVal;
114:         }
115:     }
116: 
117: 
118:     /**
119:      * Returns row signature (composition of primary keys)
120:      * @param  bool
121:      * @return string
122:      */
123:     public function getSignature($need = TRUE)
124:     {
125:         return implode('|', (array) $this->getPrimary($need));
126:     }
127: 
128: 
129:     /**
130:      * Returns referenced row.
131:      * @param  string
132:      * @param  string
133:      * @return IRow or NULL if the row does not exist
134:      */
135:     public function ref($key, $throughColumn = NULL)
136:     {
137:         $row = $this->table->getReferencedTable($this, $key, $throughColumn);
138:         if ($row === FALSE) {
139:             throw new Nette\MemberAccessException("No reference found for \${$this->table->name}->ref($key).");
140:         }
141: 
142:         return $row;
143:     }
144: 
145: 
146:     /**
147:      * Returns referencing rows.
148:      * @param  string
149:      * @param  string
150:      * @return GroupedSelection
151:      */
152:     public function related($key, $throughColumn = NULL)
153:     {
154:         $groupedSelection = $this->table->getReferencingTable($key, $throughColumn, $this[$this->table->getPrimary()]);
155:         if (!$groupedSelection) {
156:             throw new Nette\MemberAccessException("No reference found for \${$this->table->name}->related($key).");
157:         }
158: 
159:         return $groupedSelection;
160:     }
161: 
162: 
163:     /**
164:      * Updates row.
165:      * @param  array|\Traversable (column => value)
166:      * @return bool
167:      */
168:     public function update($data)
169:     {
170:         if ($data instanceof \Traversable) {
171:             $data = iterator_to_array($data);
172:         }
173: 
174:         $primary = $this->getPrimary();
175:         if (!is_array($primary)) {
176:             $primary = array($this->table->getPrimary() => $primary);
177:         }
178: 
179:         $selection = $this->table->createSelectionInstance()
180:             ->wherePrimary($primary);
181: 
182:         if ($selection->update($data)) {
183:             if ($tmp = array_intersect_key($data, $primary)) {
184:                 $selection = $this->table->createSelectionInstance()
185:                     ->wherePrimary($tmp + $primary);
186:             }
187:             $selection->select('*');
188:             if (($row = $selection->fetch()) === FALSE) {
189:                 throw new Nette\InvalidStateException('Database refetch failed; row does not exist!');
190:             }
191:             $this->data = $row->data;
192:             return TRUE;
193:         } else {
194:             return FALSE;
195:         }
196:     }
197: 
198: 
199:     /**
200:      * Deletes row.
201:      * @return int number of affected rows
202:      */
203:     public function delete()
204:     {
205:         $res = $this->table->createSelectionInstance()
206:             ->wherePrimary($this->getPrimary())
207:             ->delete();
208: 
209:         if ($res > 0 && ($signature = $this->getSignature(FALSE))) {
210:             unset($this->table[$signature]);
211:         }
212: 
213:         return $res;
214:     }
215: 
216: 
217:     /********************* interface IteratorAggregate ****************d*g**/
218: 
219: 
220:     public function getIterator()
221:     {
222:         $this->accessColumn(NULL);
223:         return new \ArrayIterator($this->data);
224:     }
225: 
226: 
227:     /********************* interface ArrayAccess & magic accessors ****************d*g**/
228: 
229: 
230:     /**
231:      * Stores value in column.
232:      * @param  string column name
233:      * @param  string value
234:      * @return void
235:      */
236:     public function offsetSet($key, $value)
237:     {
238:         $this->__set($key, $value);
239:     }
240: 
241: 
242:     /**
243:      * Returns value of column.
244:      * @param  string column name
245:      * @return string
246:      */
247:     public function offsetGet($key)
248:     {
249:         return $this->__get($key);
250:     }
251: 
252: 
253:     /**
254:      * Tests if column exists.
255:      * @param  string column name
256:      * @return bool
257:      */
258:     public function offsetExists($key)
259:     {
260:         return $this->__isset($key);
261:     }
262: 
263: 
264:     /**
265:      * Removes column from data.
266:      * @param  string column name
267:      * @return void
268:      */
269:     public function offsetUnset($key)
270:     {
271:         $this->__unset($key);
272:     }
273: 
274: 
275:     public function __set($key, $value)
276:     {
277:         throw new Nette\DeprecatedException('ActiveRow is read-only; use update() method instead.');
278:     }
279: 
280: 
281:     public function &__get($key)
282:     {
283:         $this->accessColumn($key);
284:         if (array_key_exists($key, $this->data)) {
285:             return $this->data[$key];
286:         }
287: 
288:         $referenced = $this->table->getReferencedTable($this, $key);
289:         if ($referenced !== FALSE) {
290:             $this->accessColumn($key, FALSE);
291:             return $referenced;
292:         }
293: 
294:         $this->removeAccessColumn($key);
295:         throw new Nette\MemberAccessException("Cannot read an undeclared column '$key'.");
296:     }
297: 
298: 
299:     public function __isset($key)
300:     {
301:         $this->accessColumn($key);
302:         if (array_key_exists($key, $this->data)) {
303:             return isset($this->data[$key]);
304:         }
305:         $this->removeAccessColumn($key);
306:         return FALSE;
307:     }
308: 
309: 
310:     public function __unset($key)
311:     {
312:         throw new Nette\DeprecatedException('ActiveRow is read-only.');
313:     }
314: 
315: 
316:     protected function accessColumn($key, $selectColumn = TRUE)
317:     {
318:         $this->table->accessColumn($key, $selectColumn);
319:         if ($this->table->getDataRefreshed() && !$this->dataRefreshed) {
320:             $this->data = $this->table[$this->getSignature()]->data;
321:             $this->dataRefreshed = TRUE;
322:         }
323:     }
324: 
325: 
326:     protected function removeAccessColumn($key)
327:     {
328:         $this->table->removeAccessColumn($key);
329:     }
330: 
331: }
332: 
Nette 2.3.1 API API documentation generated by ApiGen 2.8.0