/** * Update row. * * @throws Exception * * @return System\DbRecord\DbRecord */ public function update(DbRecord $record) { if (!$record->isRecordExisting()) { throw new \Nette\InvalidStateException("Only existing row can be updated."); } $engine = $this->getConnection(); if (!$engine->inTransaction()) { $doCommit = true; $engine->begin(); } if ($record->isDirty()) { try { if (isset($record->belongsToCollection)) { // patrim do kolekce a již jsem uložen v databázi! logicky // predek uz musi met nastaveny PK ... $collection = $record->belongsToCollection; $localId = $collection->getAssociation()->getForeignId(); $collectionOwner = $collection->getBelongsToRecord(); $ownerId = $collection->getAssociation()->getLocalId(); if (!isset($collectionOwner->{$ownerId})) { throw new \LogicException("Collection owner has not primary key, associations can not be updated! {$ownerId}"); } // ... i ja musím mít nastaven relační klíč... if (!isset($record->{$localId})) { throw new \LogicException("Member of collection can not be save without known primary key of owner of collection! {$localId}"); } // ... a musí být shodný s rodičem kolekce. if ($record->{$localId} != $collectionOwner->{$ownerId}) { throw new \LogicException("Member of collection has different id then owner of collection! [" . $record->{$localId} . " / " . $collectionOwner->{$ownerId} . "]"); } } $this->onBeforeUpdate($record); if (!$record->isValid(EntityValidator::VALIDATION_UPDATE)) { $errors = $record->getErrors(); if (count($errors)) { $msg = current($errors); throw new Exception($msg[0]); } else { throw new Exception("Undefined validator exception!"); } } $this->onBeforeUpdateAfterValidation($record); $values = $record->getModifiedValues(true); $config = $this->getConfig(); if ($config->isPrimaryAutoincrement()) { $pk = $config->getPrimaryColumn(); unset($values[$pk . "%" . $config->getType($pk)]); } if (count($values)) { $engine->update($record::table(), $values)->where('%and', $record->getPrimaryCondition())->execute(); } } catch (\DibiException $e) { if ($engine->getDriver() instanceof \DibiMySqliDriver) { switch ($e->getCode()) { case \DibiMySqliDriver::ERROR_DUPLICATE_ENTRY: if (preg_match('~Duplicate entry \'([^\']*)\' for key \'([^\']*)\'~', $e->getMessage(), $matches)) { $msg = $record::validator()->translate('v/recordDuplicity', 1, array('{__ENTRY__}' => $matches[1], '{__KEY__}' => $matches[2])); throw new Exception($msg, $e->getCode(), $e); } else { throw $e; } break; default: throw $e; } } else { throw new \LogicException('implementovane pouze pro mysql.'); } } $record->clearModified(); } foreach ($record->getAssociations() as $key => $associationObject) { // treba neexistuje, kdyz neni povinna vytvori se NULL if (!$associationObject) { continue; } $associationObject->save(); } $this->onAfterUpdate($record); if (isset($doCommit)) { $engine->commit(); } // set action / pravdepodobne probehla v poradku $record->lastAction('u'); $record->setLastAffectedRows($engine->affectedRows()); return $record; }