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