private function _gatherRelationsSql($class, array &$sql, array &$columns, array &$constraints) { foreach ($class->associationMappings as $fieldName => $mapping) { if (isset($class->inheritedAssociationFields[$fieldName])) { continue; } $foreignClass = $this->_em->getClassMetadata($mapping->targetEntityName); if ($mapping->isOneToOne() && $mapping->isOwningSide) { $constraint = array(); $constraint['tableName'] = $class->getTableName(); $constraint['foreignTable'] = $foreignClass->getTableName(); $constraint['local'] = array(); $constraint['foreign'] = array(); foreach ($mapping->getJoinColumns() as $joinColumn) { $column = array(); $column['name'] = $joinColumn['name']; $column['type'] = Type::getType($foreignClass->getTypeOfColumn($joinColumn['referencedColumnName'])); $columns[$joinColumn['name']] = $column; $constraint['local'][] = $joinColumn['name']; $constraint['foreign'][] = $joinColumn['referencedColumnName']; } $constraints[] = $constraint; } else { if ($mapping->isOneToMany() && $mapping->isOwningSide) { //... create join table, one-many through join table supported later throw DoctrineException::updateMe("Not yet implemented."); } else { if ($mapping->isManyToMany() && $mapping->isOwningSide) { // create join table $joinTableColumns = array(); $joinTableOptions = array(); $joinTable = $mapping->getJoinTable(); $constraint1 = array(); $constraint1['tableName'] = $joinTable['name']; $constraint1['foreignTable'] = $class->getTableName(); $constraint1['local'] = array(); $constraint1['foreign'] = array(); foreach ($joinTable['joinColumns'] as $joinColumn) { $column = array(); $column['primary'] = true; $joinTableOptions['primary'][] = $joinColumn['name']; $column['name'] = $joinColumn['name']; $column['type'] = Type::getType($class->getTypeOfColumn($joinColumn['referencedColumnName'])); $joinTableColumns[$joinColumn['name']] = $column; $constraint1['local'][] = $joinColumn['name']; $constraint1['foreign'][] = $joinColumn['referencedColumnName']; } $constraints[] = $constraint1; $constraint2 = array(); $constraint2['tableName'] = $joinTable['name']; $constraint2['foreignTable'] = $foreignClass->getTableName(); $constraint2['local'] = array(); $constraint2['foreign'] = array(); foreach ($joinTable['inverseJoinColumns'] as $inverseJoinColumn) { $column = array(); $column['primary'] = true; $joinTableOptions['primary'][] = $inverseJoinColumn['name']; $column['name'] = $inverseJoinColumn['name']; $column['type'] = Type::getType($this->_em->getClassMetadata($mapping->getTargetEntityName())->getTypeOfColumn($inverseJoinColumn['referencedColumnName'])); $joinTableColumns[$inverseJoinColumn['name']] = $column; $constraint2['local'][] = $inverseJoinColumn['name']; $constraint2['foreign'][] = $inverseJoinColumn['referencedColumnName']; } $constraints[] = $constraint2; $sql = array_merge($sql, $this->_platform->getCreateTableSql($joinTable['name'], $joinTableColumns, $joinTableOptions)); } } } } }
/** * generates the sql for altering an existing table on postgresql * * @param string $name name of the table that is intended to be changed. * @param array $changes associative array that contains the details of each type * * @param boolean $check indicates whether the function should just check if the DBMS driver * can perform the requested table alterations if the value is true or * actually perform them otherwise. * @see Doctrine_Export::alterTable() * @return array * @override */ public function getAlterTableSql($name, array $changes, $check = false) { foreach ($changes as $changeName => $change) { switch ($changeName) { case 'add': case 'remove': case 'change': case 'name': case 'rename': break; default: throw DoctrineException::updateMe('change type "' . $changeName . '\\" not yet supported'); } } if ($check) { return true; } $sql = array(); if (isset($changes['add']) && is_array($changes['add'])) { foreach ($changes['add'] as $fieldName => $field) { $query = 'ADD ' . $this->getColumnDeclarationSql($fieldName, $field); $sql[] = 'ALTER TABLE ' . $name . ' ' . $query; } } if (isset($changes['remove']) && is_array($changes['remove'])) { foreach ($changes['remove'] as $fieldName => $field) { $fieldName = $this->quoteIdentifier($fieldName, true); $query = 'DROP ' . $fieldName; $sql[] = 'ALTER TABLE ' . $name . ' ' . $query; } } if (isset($changes['change']) && is_array($changes['change'])) { foreach ($changes['change'] as $fieldName => $field) { $fieldName = $this->quoteIdentifier($fieldName, true); if (isset($field['type'])) { $serverInfo = $this->getServerVersion(); if (is_array($serverInfo) && $serverInfo['major'] < 8) { throw DoctrineException::updateMe('changing column type for "' . $field['type'] . '\\" requires PostgreSQL 8.0 or above'); } $query = 'ALTER ' . $fieldName . ' TYPE ' . $this->getTypeDeclarationSql($field['definition']); $sql[] = 'ALTER TABLE ' . $name . ' ' . $query; } if (array_key_exists('default', $field)) { $query = 'ALTER ' . $fieldName . ' SET DEFAULT ' . $this->quote($field['definition']['default'], $field['definition']['type']); $sql[] = 'ALTER TABLE ' . $name . ' ' . $query; } if (!empty($field['notnull'])) { $query = 'ALTER ' . $fieldName . ' ' . ($field['definition']['notnull'] ? 'SET' : 'DROP') . ' NOT NULL'; $sql[] = 'ALTER TABLE ' . $name . ' ' . $query; } } } if (isset($changes['rename']) && is_array($changes['rename'])) { foreach ($changes['rename'] as $fieldName => $field) { $fieldName = $this->quoteIdentifier($fieldName, true); $sql[] = 'ALTER TABLE ' . $name . ' RENAME COLUMN ' . $fieldName . ' TO ' . $this->quoteIdentifier($field['name'], true); } } $name = $this->quoteIdentifier($name, true); if (isset($changes['name'])) { $changeName = $this->quoteIdentifier($changes['name'], true); $sql[] = 'ALTER TABLE ' . $name . ' RENAME TO ' . $changeName; } return $sql; }
/** * Defines a cache driver to be used for caching result sets. * * @param Doctrine\ORM\Cache\Cache $driver Cache driver * @return Doctrine\ORM\Query */ public function setResultCache($resultCache = null) { if ($resultCache !== null && !$resultCache instanceof \Doctrine\ORM\Cache\Cache) { throw DoctrineException::updateMe('Method setResultCache() accepts only an instance of Doctrine_Cache_Interface or null.'); } $this->_resultCache = $resultCache; return $this; }
/** * Adds support for magic finders. * findByColumnName, findByRelationAlias * findById, findByContactId, etc. * * @return void * @throws BadMethodCallException If the method called is an invalid find* method * or no find* method at all and therefore an invalid * method call. */ public function __call($method, $arguments) { if (substr($method, 0, 6) == 'findBy') { $by = substr($method, 6, strlen($method)); $method = 'findBy'; } else { if (substr($method, 0, 9) == 'findOneBy') { $by = substr($method, 9, strlen($method)); $method = 'findOneBy'; } else { throw new BadMethodCallException("Undefined method '{$method}'."); } } if (isset($by)) { if (!isset($arguments[0])) { throw DoctrineException::updateMe('You must specify the value to findBy.'); } $fieldName = Doctrine::tableize($by); $hydrationMode = isset($arguments[1]) ? $arguments[1] : null; if ($this->_classMetadata->hasField($fieldName)) { return $this->{$method}($fieldName, $arguments[0], $hydrationMode); } else { if ($this->_classMetadata->hasRelation($by)) { $relation = $this->_classMetadata->getRelation($by); if ($relation['type'] === Doctrine_Relation::MANY) { throw DoctrineException::updateMe('Cannot findBy many relationship.'); } return $this->{$method}($relation['local'], $arguments[0], $hydrationMode); } else { throw DoctrineException::updateMe('Cannot find by: ' . $by . '. Invalid field or relationship alias.'); } } } }