/**
  * Returns the description of the failure
  *
  * The beginning of failure messages is "Failed asserting that" in most
  * cases. This method should return the second part of that sentence.
  *
  * @param  Relation $relation Evaluated value or object.
  * @return string
  */
 protected function failureDescription($relation)
 {
     $owningAlias = $relation->getOwningAlias();
     $owningTable = $relation->getOwningTable();
     $referencedAlias = $relation->getReferencedAlias();
     $referencedTable = $relation->getReferencedTable();
     return $this->toString() . "{$owningTable}->{$referencedAlias}: {$referencedTable} | {$referencedTable}->{$owningAlias}: {$owningTable}";
 }
예제 #2
0
 /**
  * unlink the record
  *
  * @param  Record $record
  * @return bool
  */
 public function unlinkRecord(Record $record)
 {
     $key = $this->search($record);
     if ($key === false) {
         return false;
     }
     $this->offsetUnset($key);
     if ($this->refRecord && $this->relation) {
         $this->relation->updateRecordReference($record, null);
     }
     return true;
 }
예제 #3
0
 /**
  * Updates references between owner and referenced record collection
  *
  * @param RecordCollection|Record[] $ownerCollection
  * @param RecordCollection|Record[] $referencedCollection
  */
 public function updateOwnerCollectionWithReferencedCollection(RecordCollection $ownerCollection, RecordCollection $referencedCollection)
 {
     $owningField = $this->relation->getOwningField();
     $isOneToMany = $this->relation->isOneToMany();
     foreach ($ownerCollection as $refRecord) {
         $refId = $refRecord->get($owningField);
         $owningId = $refRecord->getInternalId();
         $this->assignReference($refId, $owningId);
     }
     foreach ($referencedCollection as $refRecord) {
         $id = $refRecord->getInternalId();
         if (!$this->isReferenced($id) && !$this->hasNullReference($id)) {
             $reference = $isOneToMany ? array() : null;
             $this->setReference($id, $reference);
         }
     }
 }
예제 #4
0
 /**
  * gets relation instance
  *
  * @param   string $name
  * @param   array  $relationData
  * @return  \Dive\Relation\Relation
  */
 private function getRelationInstance($name, array $relationData)
 {
     if (!isset($this->relations[$name])) {
         $owningTable = $relationData['owningTable'];
         $owningAlias = $relationData['owningAlias'];
         $owningField = $relationData['owningField'];
         $referencedTable = $relationData['refTable'];
         $referencedAlias = $relationData['refAlias'];
         $referencedField = $relationData['refField'];
         $type = $relationData['type'];
         $onDelete = !empty($relationData['onDelete']) ? $relationData['onDelete'] : PlatformInterface::RESTRICT;
         $onUpdate = !empty($relationData['onUpdate']) ? $relationData['onUpdate'] : PlatformInterface::RESTRICT;
         $relation = new Relation($owningAlias, $owningTable, $owningField, $referencedAlias, $referencedTable, $referencedField, $type, $onDelete, $onUpdate);
         if (isset($relationData['orderBy'])) {
             $relation->setOrderBy($relationData['orderBy']);
         }
         $this->relations[$name] = $relation;
     }
     return $this->relations[$name];
 }
예제 #5
0
파일: Migration.php 프로젝트: sigma-z/dive
 /**
  * adds foreign key by relation instance
  *
  * @param  \Dive\Relation\Relation $relation
  * @return Migration
  * @throws MigrationException
  */
 public function addForeignKeyByRelation(Relation $relation)
 {
     if ($relation->getOwningTable() !== $this->tableName) {
         throw new MigrationException("\n                Relation does not belong to table {$this->tableName}, it belongs to " . $relation->getOwningTable() . '!');
     }
     $owningField = $relation->getOwningField();
     $referencedTable = $relation->getReferencedTable();
     $referencedField = $relation->getReferencedField();
     $onDelete = $relation->getOnDelete();
     $onUpdate = $relation->getOnUpdate();
     return $this->addForeignKey($owningField, $referencedTable, $referencedField, $onDelete, $onUpdate);
 }
예제 #6
0
 /**
  * @param RecordManager $rm
  * @param Relation      $relation
  * @return string
  */
 protected function insertRequiredLocalRelationGraph(RecordManager $rm, Relation $relation)
 {
     $randomGenerator = new FieldValuesGenerator();
     $conn = $rm->getConnection();
     $refTableName = $relation->getReferencedTable();
     $refTable = $rm->getTable($refTableName);
     $refFields = $refTable->getFields();
     $data = array();
     // recursion: walk through all local relations that are required and handle this by calling this method with
     //  next relation
     $owningRelations = $refTable->getReferencedRelationsIndexedByOwningField();
     foreach ($owningRelations as $owningField => $owningRelation) {
         // check if field is required (default of matchType) and insert required related data
         if ($randomGenerator->matchType($refFields[$owningField])) {
             $data[$owningField] = $this->insertRequiredLocalRelationGraph($rm, $owningRelation);
         }
     }
     // insert a record and return its id
     $data = $randomGenerator->getRandomRecordData($refFields, $data);
     $conn->insert($refTable, $data);
     return $conn->getLastInsertId($refTableName);
 }
예제 #7
0
파일: Record.php 프로젝트: sigma-z/dive
 /**
  * @param  Relation $relation
  * @param  string   $relationName
  * @param  bool     $withMappedFields
  * @param  array    $visited
  * @return array|bool
  */
 private function getReferenceAsArray(Relation $relation, $relationName, $withMappedFields, array &$visited)
 {
     if (!$relation->hasReferenceLoadedFor($this, $relationName)) {
         return false;
     }
     /** @var Record|Record[]|RecordCollection $related */
     $related = $this->get($relationName);
     if ($relation->isOneToMany() && $relation->isOwningSide($relationName)) {
         $reference = array();
         foreach ($related as $relatedRecord) {
             $reference[] = $relatedRecord->toArray(true, $withMappedFields, $visited);
         }
         return $reference;
     }
     return $related->toArray(true, $withMappedFields, $visited);
 }
예제 #8
0
파일: UnitOfWork.php 프로젝트: sigma-z/dive
 /**
  * @param  Relation $owningRelation
  * @param  Record   $owningRecord
  * @throws UnitOfWorkException
  */
 private function applyDeleteConstraint(Relation $owningRelation, Record $owningRecord)
 {
     $owningFieldName = $owningRelation->getOwningField();
     if ($owningRecord->isFieldModified($owningFieldName)) {
         return;
     }
     $constraintName = $owningRelation->getOnDelete();
     switch ($constraintName) {
         case PlatformInterface::CASCADE:
             $this->scheduleDelete($owningRecord);
             break;
         case PlatformInterface::SET_NULL:
             if (!$this->isRecordScheduledForDelete($owningRecord)) {
                 $owningRecord->set($owningFieldName, null);
                 $this->scheduleSave($owningRecord);
             }
             break;
         case PlatformInterface::RESTRICT:
         case PlatformInterface::NO_ACTION:
             // if not deleted yet, it has to be deleted before commit for comply with the constraint
             if (!$this->isRecordScheduledForDelete($owningRecord)) {
                 $this->markRecordForRestrictOnCommitWhenNotDeleted($owningRecord);
             }
             break;
     }
 }
예제 #9
0
 public function testGetDefinition()
 {
     $expected = array('owningAlias' => 'Author', 'owningTable' => 'user_id', 'owningField' => 'author', 'refAlias' => 'User', 'refTable' => 'id', 'refField' => 'user', 'type' => '1-1', 'onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE', 'orderBy' => '');
     $rm = new Relation($expected['owningAlias'], $expected['owningTable'], $expected['owningField'], $expected['refAlias'], $expected['refTable'], $expected['refField'], $expected['type'], $expected['onDelete'], $expected['onUpdate']);
     $this->assertEquals($expected, $rm->getDefinition());
 }
 /**
  * @param  Relation $relation
  * @param  string   $relationName
  * @return Record
  */
 private function getReferencedRecord(Relation $relation, $relationName)
 {
     return $relation->isReferencedSide($relationName) ? $this->relatedRecord : $this->storedRecord;
 }
예제 #11
0
 /**
  * Saves record on owning relation
  *
  * @param  array                    $row
  * @param  \Dive\Relation\Relation  $relation
  * @param  string                   $value
  * @return array
  */
 private function saveRecordOnReferencedRelation(array $row, Relation $relation, $value)
 {
     $refTable = $relation->getReferencedTable();
     $relatedId = $this->getRecordIdFromMap($refTable, $value);
     if ($relatedId === false) {
         $relatedId = $this->saveRelatedRecord($refTable, $value);
     }
     $row[$relation->getOwningField()] = $relatedId;
     return $row;
 }