/** * @param string $withMappedFields * @param array $visited * @return array */ private function getReferencesAsArray($withMappedFields, array &$visited) { $references = array(); $tableName = $this->_table->getTableName(); $relations = $this->_table->getRelations(); foreach ($relations as $relation) { $refTable = $relation->getReferencedTable(); $owningAlias = $relation->getOwningAlias(); if ($tableName == $refTable && !isset($references[$owningAlias])) { $reference = $this->getReferenceAsArray($relation, $owningAlias, $withMappedFields, $visited); if ($reference !== false) { $references[$owningAlias] = $reference; } } $owningTable = $relation->getOwningTable(); $refAlias = $relation->getReferencedAlias(); if ($tableName == $owningTable && !isset($references[$refAlias])) { $reference = $this->getReferenceAsArray($relation, $refAlias, $withMappedFields, $visited); if ($reference !== false && !isset($references[$refAlias])) { $references[$refAlias] = $reference; } } } return $references; }
/** * @param mixed $record * @throws CollectionException */ protected function throwExceptionIfRecordDoesNotMatchTable($record) { if (!$record instanceof Record) { throw new CollectionException('Argument #1 must be an instance of \\Dive\\Record!' . 'You gave me: ' . (is_object($record) ? get_class($record) : gettype($record))); } if ($record->getTable() != $this->table) { throw new CollectionException('Add record does not match table instance!' . ' Expected: ' . $this->table->getTableName() . ' You gave me: ' . $record->getTable()->getTableName()); } }
/** * hydrates record * * @param Table $table * @param array $row * @return Record */ protected function hydrateRecord(Table $table, array $row) { $record = $this->recordManager->getOrCreateRecord($table->getTableName(), $row, true); return $record; }
/** * NOTE Table should use a different record manager than generator to use different table repositories * * @param \Dive\Record\Generator\RecordGenerator $generator * @param Table $table * @param string $recordKey * @return Record */ protected function getGeneratedRecord(RecordGenerator $generator, Table $table, $recordKey) { $tableName = $table->getTableName(); $pk = $generator->getRecordIdFromMap($tableName, $recordKey); if ($table->hasCompositePrimaryKey()) { $pk = explode(Record::COMPOSITE_ID_SEPARATOR, $pk); } $record = $table->findByPk($pk); $message = "Could not load record for '{$recordKey}' in table '{$tableName}'"; $this->assertInstanceOf('\\Dive\\Record', $record, $message); return $record; }
/** * Clear dataset ids by given table * * @param \Dive\Table $table */ public function clearByTable(Table $table) { $connIndex = $this->getConnectionIndex($table->getConnection()); if ($connIndex === false) { return; } $tableName = $table->getTableName(); unset($this->tables[$connIndex][$tableName]); unset($this->registry[$connIndex][$tableName]); }
/** * Insert row * TODO unit test it! * * @param Table $table * @param array $fields * @return int */ public function insert(Table $table, array $fields) { $columns = array(); $values = array(); $params = array(); $identifierFields = $table->getIdentifierFields(); $identifier = array(); foreach ($fields as $fieldName => $value) { if (!$table->hasField($fieldName)) { continue; } $columns[] = $this->quoteIdentifier($fieldName); if ($value instanceof Expression) { $values[] = $value->getSql(); } else { $values[] = '?'; $params[] = $value; if ($value !== null && in_array($fieldName, $identifierFields, true)) { $identifier[$fieldName] = $value; } } } // build query $query = 'INSERT INTO ' . $this->quoteIdentifier($table->getTableName()) . ' (' . implode(', ', $columns) . ')' . ' VALUES (' . implode(', ', $values) . ')'; if (count($identifier) !== count($identifierFields)) { $identifier = array(); } $this->dispatchRowEvent(self::EVENT_PRE_INSERT, $table, $fields, $identifier); $this->lastInsertId[$table->getTableName()] = null; $affectedRows = $this->exec($query, $params); $this->lastInsertId[$table->getTableName()] = $this->getLastInsertId($table->getTableName()); if (empty($identifier) && count($identifierFields) == 1) { $identifier[$identifierFields[0]] = $this->getLastInsertId($table->getTableName()); } $this->dispatchRowEvent(self::EVENT_POST_INSERT, $table, $fields, $identifier); return $affectedRows; }
/** * Saves record * * @param Table $table * @param array $row * @param string $key * @return string */ private function saveRecord(Table $table, array $row, $key) { $tableName = $table->getTableName(); if ($key && $this->isInRecordMap($tableName, $key)) { return $this->getRecordIdFromMap($tableName, $key); } // keep foreign key relations in array to process after record has been saved $owningRelations = array(); $beforeSaveGeneratedRecords = $this->generatedRecords; $this->generatedRecords = array(); foreach ($row as $relationName => $value) { if ($table->hasRelation($relationName)) { $relation = $table->getRelation($relationName); if ($relation->isReferencedSide($relationName)) { $row = $this->saveRecordOnReferencedRelation($row, $relation, $value); } else { $owningRelations[$relationName] = array('related' => $value, 'relation' => $relation); } unset($row[$relationName]); } } $row = $this->saveRequiredRelations($table, $row); // save record $row = $this->fieldValueGenerator->getRandomRecordData($table->getFields(), $row); $record = $this->rm->getOrCreateRecord($tableName, $row); $this->rm->scheduleSave($record); $this->rm->commit(); // keep record identifier in the record map $id = $record->getIdentifierAsString(); if ($key !== null) { $this->recordAliasIdMap[$tableName][$key] = $id; } $this->generatedRecords = array_merge($beforeSaveGeneratedRecords, array(array('tableName' => $tableName, 'id' => $id)), $this->generatedRecords); // save owning relations foreach ($owningRelations as $relationData) { /** @var $relation Relation */ $relation = $relationData['relation']; $relatedRows = $relationData['related']; $this->saveRecordsOnOwningRelation($relation, $relatedRows, $id); } return $id; }