Example #1
0
 public function afterSave($event)
 {
     if (!$this->transaction) {
         return;
     }
     $this->transaction->commit();
     $this->transaction = null;
 }
 public static function rollbackStackedTransaction()
 {
     self::$transactionsStackSize && --self::$transactionsStackSize;
     //decrement only when positive
     if (self::$transactionsStackSize == 0) {
         self::$transaction->rollback();
     }
 }
 /**
  * Responds to {@link CActiveRecord::onAfterSave} event.
  * @throws CDbException
  * @param CModelEvent $event event parameter
  */
 public function afterSave($event)
 {
     try {
         /** @var CDbCommandBuilder $commandBuilder */
         $commandBuilder = $this->owner->dbConnection->commandBuilder;
         foreach ($this->owner->relations() as $name => $relation) {
             switch ($relation[0]) {
                 /* MANY_MANY: this corresponds to the many-to-many relationship in database.
                  *            An associative table is needed to break a many-to-many relationship into one-to-many
                  *            relationships, as most DBMS do not support many-to-many relationship directly.
                  */
                 case CActiveRecord::MANY_MANY:
                     break;
                     if (!is_array($this->owner->{$name})) {
                         break;
                     }
                     Yii::trace('updating MANY_MANY table for relation ' . get_class($this->owner) . '.' . $name, 'system.db.ar.CActiveRecord');
                     // get table and fk information
                     list($relationTable, $fks) = $this->parseManyManyFk($name, $relation);
                     // get pks of the currently related records
                     $newPKs = $this->getNewManyManyPks($name);
                     // 1. delete relation table entries for records that have been removed from relation
                     // @todo add support for composite primary keys
                     $criteria = new CDbCriteria();
                     $criteria->addNotInCondition($fks[1], $newPKs)->addColumnCondition(array($fks[0] => $this->owner->getPrimaryKey()));
                     $commandBuilder->createDeleteCommand($relationTable, $criteria)->execute();
                     // 2. add new entries to relation table
                     // @todo add support for composite primary keys
                     $oldPKs = $this->getOldManyManyPks($name);
                     foreach ($newPKs as $fk) {
                         if (!in_array($fk, $oldPKs)) {
                             $commandBuilder->createInsertCommand($relationTable, array($fks[0] => $this->owner->getPrimaryKey(), $fks[1] => $fk))->execute();
                         }
                     }
                     // refresh relation data
                     //$this->owner->getRelated($name, true); // will come back with github issue #4
                     break;
                     // HAS_MANY: if the relationship between table A and B is one-to-many, then A has many B
                     //           (e.g. User has many Post);
                     // HAS_ONE: this is special case of HAS_MANY where A has at most one B
                     //          (e.g. User has at most one Profile);
                     // need to change the foreign ARs attributes
                 // HAS_MANY: if the relationship between table A and B is one-to-many, then A has many B
                 //           (e.g. User has many Post);
                 // HAS_ONE: this is special case of HAS_MANY where A has at most one B
                 //          (e.g. User has at most one Profile);
                 // need to change the foreign ARs attributes
                 case CActiveRecord::HAS_MANY:
                 case CActiveRecord::HAS_ONE:
                     if (!$this->owner->hasRelated($name) || !$this->isRelationSupported($relation)) {
                         break;
                     }
                     Yii::trace('updating ' . ($relation[0] == CActiveRecord::HAS_ONE ? 'HAS_ONE' : 'HAS_MANY') . ' foreign-key field for relation ' . get_class($this->owner) . '.' . $name, 'system.db.ar.CActiveRecord');
                     $newRelatedRecords = $this->owner->getRelated($name, false);
                     if ($relation[0] == CActiveRecord::HAS_MANY && !is_array($newRelatedRecords)) {
                         if (!is_null($newRelatedRecords)) {
                             throw new CDbException('A HAS_MANY relation needs to be an array of records or primary keys!');
                         }
                         break;
                     }
                     // HAS_ONE is special case of HAS_MANY, so we have array with one or no element
                     if ($relation[0] == CActiveRecord::HAS_ONE) {
                         if ($newRelatedRecords === null) {
                             $newRelatedRecords = array();
                         } else {
                             $newRelatedRecords = array($newRelatedRecords);
                         }
                     }
                     // get related records as objects and primary keys
                     $newRelatedRecords = $this->primaryKeysToObjects($newRelatedRecords, $relation[1]);
                     $newPKs = $this->objectsToPrimaryKeys($newRelatedRecords);
                     // update all not anymore related records
                     $criteria = new ECompositeDbCriteria();
                     $criteria->addNotInCondition(CActiveRecord::model($relation[1])->tableSchema->primaryKey, $newPKs);
                     // @todo add support for composite primary keys
                     $criteria->addColumnCondition(array($relation[2] => $this->owner->getPrimaryKey()));
                     if (CActiveRecord::model($relation[1])->tableSchema->getColumn($relation[2])->allowNull) {
                         CActiveRecord::model($relation[1])->updateAll(array($relation[2] => null), $criteria);
                     } else {
                         CActiveRecord::model($relation[1])->deleteAll($criteria);
                     }
                     /** @var CActiveRecord $record */
                     foreach ($newRelatedRecords as $record) {
                         // only save if relation did not exist
                         // @todo add support for composite primary keys
                         if ($record->{$relation[2]} === null || $record->{$relation[2]} != $this->owner->getPrimaryKey()) {
                             $record->saveAttributes(array($relation[2] => $this->owner->getPrimaryKey()));
                         }
                     }
                     break;
             }
         }
         // commit internal transaction if one exists
         if ($this->_transaction !== null) {
             $this->_transaction->commit();
         }
     } catch (Exception $e) {
         // roll back internal transaction if one exists
         if ($this->_transaction !== null) {
             $this->_transaction->rollback();
         }
         // re-throw exception
         throw $e;
     }
 }
 /**
  * Применение изменений.
  * @throws \CDbException
  */
 private function commitTransaction()
 {
     if ($this->transaction !== null) {
         $this->transaction->commit();
     }
 }
 /**
  * Rollbacks changes applied with database.
  */
 protected function rollbackChanges()
 {
     if ($this->_transaction->getActive()) {
         $this->_transaction->rollback();
     }
 }
Example #6
0
 /**
  * Rolls back a database transaction if transaction is not `null`.
  *
  * @param \CDbTransaction $transaction
  */
 protected function rollbackTransaction($transaction)
 {
     if ($transaction) {
         $transaction->rollback();
     }
 }
 public function rollBack()
 {
     if ($this->connection->decTransactionLevel() == 0) {
         parent::rollBack();
     }
 }