/** * @param Record $record * @param array $visited * @return Record[] */ private static function getRecordsToInsertFromGraph(Record $record, array $visited = array()) { $oid = $record->getOid(); if (in_array($oid, $visited)) { return array(); } $visited[] = $oid; $recordsToInsert = array(); if (!$record->exists()) { $recordsToInsert[] = $record; } $table = $record->getTable(); $relations = $table->getRelations(); foreach ($relations as $relationName => $relation) { if ($relation->hasReferenceLoadedFor($record, $relationName)) { $related = $relation->getReferenceFor($record, $relationName); if ($related) { if ($related instanceof RecordCollection) { foreach ($related as $relatedRecord) { $relatedRecordsToInsert = self::getRecordsToInsertFromGraph($relatedRecord, $visited); $recordsToInsert = array_merge($recordsToInsert, $relatedRecordsToInsert); } } else { $relatedRecordsToInsert = self::getRecordsToInsertFromGraph($related, $visited); $recordsToInsert = array_merge($recordsToInsert, $relatedRecordsToInsert); } } } } return $recordsToInsert; }
/** * @param array $recordData */ private function thenItShouldHaveCreatedARecordWithData(array $recordData) { $this->assertNotNull($this->resultRecord); $this->assertFalse($this->resultRecord->exists()); foreach ($recordData as $fieldName => $fieldValue) { $this->assertEquals($fieldValue, $this->resultRecord->get($fieldName)); } }
/** * @param Record $record * @param array $uniqueIndexesToCheck * @return \Dive\Query\Query * @throws \Dive\Exception */ private function getUniqueIndexesQuery(Record $record, array $uniqueIndexesToCheck) { $table = $record->getTable(); $conn = $table->getConnection(); $conditions = array(); $queryParams = array(); $recordExists = $record->exists(); $identifier = array(); if ($recordExists) { $condition = ''; foreach ($record->getIdentifierFieldIndexed() as $idField => $idValue) { $condition .= $conn->quoteIdentifier($idField) . ' != ? AND '; $identifier[] = $idValue; } // strip last AND from string $condition = substr($condition, 0, -4); $conditions['primary'] = $condition; } foreach ($uniqueIndexesToCheck as $uniqueName => $uniqueIndexToCheck) { $isNullConstrained = $table->isUniqueIndexNullConstrained($uniqueName); $conditionParams = array(); $condition = ''; $fieldNames = $uniqueIndexToCheck['fields']; foreach ($fieldNames as $fieldName) { $fieldNameQuoted = $conn->quoteIdentifier($fieldName); $fieldValue = $record->get($fieldName); if ($fieldValue !== null) { $condition .= $fieldNameQuoted . ' = ? AND '; $conditionParams[] = $fieldValue; } else { if ($isNullConstrained) { $condition .= $fieldNameQuoted . ' IS NULL AND '; } else { throw new Exception("Cannot process unique index for creating query to check whether the record is unique, or not!"); } } } // strip last AND from string $condition = substr($condition, 0, -4); $conditions[$uniqueName] = $condition; $queryParams = array_merge($queryParams, $conditionParams); } $whereCondition = ($recordExists ? array_shift($conditions) . ' AND (' : '') . implode(' OR ', $conditions) . ($recordExists ? ')' : ''); $query = $table->createQuery(); $query->where($whereCondition); foreach ($conditions as $uniqueName => $condition) { $query->addSelect("({$condition}) AS " . $conn->quoteIdentifier($uniqueName)); } $whereParams = $recordExists ? array_merge($identifier, $queryParams) : $queryParams; $query->setParams(Query::PART_SELECT, $queryParams); $query->setParams(Query::PART_WHERE, $whereParams); $query->limit(1); return $query; }
/** * Updates identity map on record insert/update or removes identity map entry on record delete * Refreshes record identity in repository * * @param Record $record * @param string $oldInternalIdentifier */ public function refreshIdentity(Record $record, $oldInternalIdentifier = null) { $oid = $record->getOid(); if (!$this->has($oid)) { return; } $id = $record->getIdentifierAsString(); if ($record->exists()) { if ($oldInternalIdentifier) { unset($this->identityMap[$oldInternalIdentifier]); } $this->identityMap[$id] = $record->getOid(); } else { unset($this->identityMap[$id]); } }
/** * @param Record $record * @return array */ private function getFieldNamesForValidation(Record $record) { if ($record->exists()) { $fields = $record->getModifiedFields(); } else { $table = $record->getTable(); $fields = $table->getFields(); if ($table->hasAutoIncrementTrigger()) { $idFields = $table->getIdentifierFields(); foreach ($idFields as $idFieldName) { unset($fields[$idFieldName]); } } } return array_keys($fields); }
/** * @param Record $record * @throws Exception */ private function handleDeleteConstraints(Record $record) { if (!$record->exists()) { return; } $owningRelations = $record->getTable()->getOwningRelations(); foreach ($owningRelations as $relationName => $owningRelation) { $owningRecords = $owningRelation->getOriginalReferenceFor($record, $relationName); foreach ($owningRecords as $owningRecord) { $this->applyDeleteConstraint($owningRelation, $owningRecord); } } }
/** * Updates record collections of referenced record (record collection is to be exchanged with another) * * @param Record $record * @param RecordCollection|Record[] $related */ public function updateCollectionReference(Record $record, RecordCollection $related) { $oid = $record->getOid(); // when exchanging collection, we have to unlink all related records $relatedCollection = $this->getRelatedCollection($oid); if ($relatedCollection && $relatedCollection !== $related) { $owningField = $this->relation->getOwningField(); foreach ($relatedCollection as $owningRecord) { $this->removeFieldMapping($owningRecord->getOid()); $owningRecord->set($owningField, null); } } // set references for new related records $this->setReference($record->getInternalId(), $related->getIdentifiers()); if (!$record->exists()) { foreach ($related as $relatedRecord) { $this->setFieldMapping($relatedRecord->getOid(), $oid); } } $this->setRelatedCollection($oid, $related); }