1
0
mirror of synced 2024-12-14 15:16:04 +03:00
doctrine2/lib/Doctrine/Mapper/Joined.php

266 lines
9.1 KiB
PHP

<?php
class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
{
protected $_columnNameFieldNameMap = array();
/**
* inserts a record into database
*
* @param Doctrine_Record $record record to be inserted
* @return boolean
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/
protected function _doInsert(Doctrine_Record $record)
{
$table = $this->_table;
$dataSet = $this->_formatDataSet($record);
$component = $table->getComponentName();
$classes = $table->getOption('joinedParents');
array_unshift($classes, $component);
try {
$this->_conn->beginInternalTransaction();
$identifier = null;
foreach (array_reverse($classes) as $k => $parent) {
$parentTable = $this->_conn->getTable($parent);
if ($k == 0) {
$identifierType = $parentTable->getIdentifierType();
if ($identifierType == Doctrine::IDENTIFIER_AUTOINC) {
$this->_conn->insert($parentTable, $dataSet[$parent]);
$identifier = $this->_conn->sequence->lastInsertId();
} else if ($identifierType == Doctrine::IDENTIFIER_SEQUENCE) {
$seq = $record->getTable()->getOption('sequenceName');
if ( ! empty($seq)) {
$identifier = $this->_conn->sequence->nextId($seq);
$dataSet[$parent][$parentTable->getIdentifier()] = $identifier;
$this->_conn->insert($parentTable, $dataSet[$parent]);
}
} else {
throw new Doctrine_Mapper_Exception("Unsupported identifier type '$identifierType'.");
}
$record->assignIdentifier($identifier);
} else {
foreach ((array) $record->identifier() as $id => $value) {
$dataSet[$parent][$id] = $value;
}
$this->_conn->insert($parentTable, $dataSet[$parent]);
}
}
$this->_conn->commit();
} catch (Exception $e) {
$this->_conn->rollback();
throw $e;
}
return true;
}
/**
* updates given record
*
* @param Doctrine_Record $record record to be updated
* @return boolean whether or not the update was successful
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/
protected function _doUpdate(Doctrine_Record $record)
{
$table = $this->_table;
$identifier = $record->identifier();
$dataSet = $this->_formatDataSet($record);
$component = $table->getComponentName();
$classes = $table->getOption('joinedParents');
array_unshift($classes, $component);
foreach ($record as $field => $value) {
if ($value instanceof Doctrine_Record) {
if ( ! $value->exists()) {
$value->save();
}
$record->set($field, $value->getIncremented());
}
}
foreach (array_reverse($classes) as $class) {
$parentTable = $this->_conn->getTable($class);
$this->_conn->update($parentTable, $dataSet[$class], $identifier);
}
$record->assignIdentifier(true);
return true;
}
protected function _doDelete(Doctrine_Record $record, Doctrine_Connection $conn)
{
try {
$table = $this->_table;
$conn->beginInternalTransaction();
$this->deleteComposites($record);
$record->state(Doctrine_Record::STATE_TDIRTY);
foreach ($table->getOption('joinedParents') as $parent) {
$parentTable = $conn->getTable($parent);
$conn->delete($parentTable, $record->identifier());
}
$conn->delete($table, $record->identifier());
$record->state(Doctrine_Record::STATE_TCLEAN);
$this->removeRecord($record);
$conn->commit();
} catch (Exception $e) {
$conn->rollback();
throw $e;
}
return true;
}
/**
*
*
*/
public function getCustomJoins()
{
$customJoins = array();
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$customJoins[$parentClass] = 'INNER';
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
if ($subClass != $this->_domainClassName) {
$customJoins[$subClass] = 'LEFT';
}
}
return $customJoins;
}
public function getCustomFields()
{
$fields = array();
if ($this->_table->getOption('subclasses')) {
foreach ($this->_table->getOption('subclasses') as $subClass) {
$fields = array_merge($this->_conn->getTable($subClass)->getFieldNames(), $fields);
}
}
return array_unique($fields);
}
/**
*
*/
public function getDiscriminatorColumn()
{
$joinedParents = $this->_table->getOption('joinedParents');
if (count($joinedParents) <= 0) {
$inheritanceMap = $this->_table->getOption('inheritanceMap');
} else {
$inheritanceMap = $this->_conn->getTable(array_pop($joinedParents))->getOption('inheritanceMap');
}
return isset($inheritanceMap[$this->_domainClassName]) ? $inheritanceMap[$this->_domainClassName] : array();
}
/**
*
*/
public function getFieldNames()
{
if ($this->_fieldNames) {
return $this->_fieldNames;
}
$fieldNames = $this->_table->getFieldNames();
foreach ($this->_table->getOption('joinedParents') as $parent) {
$parentTable = $this->_conn->getTable($parent);
$fieldNames = array_merge($parentTable->getFieldNames(), $fieldNames);
}
$this->_fieldNames = array_unique($fieldNames);
return $fieldNames;
}
public function getFieldName($columnName)
{
if (isset($this->_columnNameFieldNameMap[$columnName])) {
return $this->_columnNameFieldNameMap[$columnName];
}
if ($this->_table->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $this->_table->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$parentTable = $this->_conn->getTable($parentClass);
if ($parentTable->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $parentTable->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
$subTable = $this->_conn->getTable($subClass);
if ($subTable->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $subTable->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
}
throw new Doctrine_Mapper_Exception("No field name found for column name '$columnName'.");
}
public function getOwningTable($fieldName)
{
if ($this->_table->hasField($fieldName)) {
return $this->_table;
}
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$parentTable = $this->_conn->getTable($parentClass);
if ($parentTable->hasField($fieldName)) {
return $parentTable;
}
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
$subTable = $this->_conn->getTable($subClass);
if ($subTable->hasField($fieldName)) {
return $subTable;
}
}
throw new Doctrine_Mapper_Exception("Unable to find owner of field '$fieldName'.");
}
/**
*
*/
protected function _formatDataSet(Doctrine_Record $record)
{
$table = $this->_table;
$dataSet = array();
$component = $table->getComponentName();
$array = $record->getPrepared();
$classes = array_merge(array($component), $this->_table->getOption('joinedParents'));
foreach ($classes as $class) {
$table = $this->_conn->getTable($class);
foreach ($table->getColumns() as $columnName => $definition) {
if (isset($definition['primary'])) {
continue;
}
$fieldName = $table->getFieldName($columnName);
$dataSet[$class][$fieldName] = isset($array[$fieldName]) ? $array[$fieldName] : null;
}
}
return $dataSet;
}
}