Commit 7fefe3f4 authored by Roman S. Borschel's avatar Roman S. Borschel

Merge commit 'upstream/master'

parents 41060023 f3d91b9e
...@@ -36,7 +36,11 @@ class SingleScalarHydrator extends AbstractHydrator ...@@ -36,7 +36,11 @@ class SingleScalarHydrator extends AbstractHydrator
{ {
$cache = array(); $cache = array();
$result = $this->_stmt->fetchAll(\PDO::FETCH_ASSOC); $result = $this->_stmt->fetchAll(\PDO::FETCH_ASSOC);
if (count($result) > 1 || count($result[key($result)]) > 1) { $num = count($result);
if ($num == 0) {
throw new \Doctrine\ORM\NoResultException;
} else if ($num > 1 || count($result[key($result)]) > 1) {
throw new \Doctrine\ORM\NonUniqueResultException; throw new \Doctrine\ORM\NonUniqueResultException;
} }
$result = $this->_gatherScalarRowData($result[key($result)], $cache); $result = $this->_gatherScalarRowData($result[key($result)], $cache);
......
...@@ -155,7 +155,7 @@ abstract class AbstractFileDriver implements Driver ...@@ -155,7 +155,7 @@ abstract class AbstractFileDriver implements Driver
if ($this->_paths) { if ($this->_paths) {
foreach ((array) $this->_paths as $path) { foreach ((array) $this->_paths as $path) {
if ( ! is_dir($path)) { if ( ! is_dir($path)) {
throw MappingException::driverRequiresConfiguredDirectoryPath(); throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath();
} }
$iterator = new \RecursiveIteratorIterator( $iterator = new \RecursiveIteratorIterator(
......
...@@ -465,6 +465,11 @@ class SqlWalker implements TreeWalker ...@@ -465,6 +465,11 @@ class SqlWalker implements TreeWalker
$fieldName = array_pop($parts); $fieldName = array_pop($parts);
$dqlAlias = $pathExpr->identificationVariable; $dqlAlias = $pathExpr->identificationVariable;
$class = $this->_queryComponents[$dqlAlias]['metadata']; $class = $this->_queryComponents[$dqlAlias]['metadata'];
if (isset($class->inheritedAssociationFields[$fieldName])) {
$class = $this->_em->getClassMetadata($class->inheritedAssociationFields[$fieldName]);
}
$assoc = $class->associationMappings[$fieldName]; $assoc = $class->associationMappings[$fieldName];
if ($assoc->isOwningSide) { if ($assoc->isOwningSide) {
...@@ -472,7 +477,7 @@ class SqlWalker implements TreeWalker ...@@ -472,7 +477,7 @@ class SqlWalker implements TreeWalker
if (count($assoc->sourceToTargetKeyColumns) > 1) { if (count($assoc->sourceToTargetKeyColumns) > 1) {
throw QueryException::associationPathCompositeKeyNotSupported(); throw QueryException::associationPathCompositeKeyNotSupported();
} }
$sql .= $this->walkIdentificationVariable($dqlAlias) . '.' $sql .= $this->getSqlTableAlias($class->table['name'], $dqlAlias) . '.'
. reset($assoc->targetToSourceKeyColumns); . reset($assoc->targetToSourceKeyColumns);
} else { } else {
// 2- Inverse side: NOT (YET?) SUPPORTED // 2- Inverse side: NOT (YET?) SUPPORTED
...@@ -683,23 +688,15 @@ class SqlWalker implements TreeWalker ...@@ -683,23 +688,15 @@ class SqlWalker implements TreeWalker
$joinAssocPathExpr = $join->joinAssociationPathExpression; $joinAssocPathExpr = $join->joinAssociationPathExpression;
$joinedDqlAlias = $join->aliasIdentificationVariable; $joinedDqlAlias = $join->aliasIdentificationVariable;
$targetQComp = $this->_queryComponents[$joinedDqlAlias]; $relation = $this->_queryComponents[$joinedDqlAlias]['relation'];
$targetClass = $targetQComp['metadata']; $targetClass = $this->_em->getClassMetadata($relation->targetEntityName);
$relation = $targetQComp['relation']; $sourceClass = $this->_em->getClassMetadata($relation->sourceEntityName);
$sourceClass = $this->_queryComponents[$joinAssocPathExpr->identificationVariable]['metadata'];
$targetTableName = $targetClass->getQuotedTableName($this->_platform); $targetTableName = $targetClass->getQuotedTableName($this->_platform);
$targetTableAlias = $this->getSqlTableAlias($targetClass->getTableName(), $joinedDqlAlias); $targetTableAlias = $this->getSqlTableAlias($targetClass->table['name'], $joinedDqlAlias);
$sourceTableAlias = $this->getSqlTableAlias( $sourceTableAlias = $this->getSqlTableAlias($sourceClass->table['name'], $joinAssocPathExpr->identificationVariable);
$sourceClass->getTableName(), $joinAssocPathExpr->identificationVariable
);
// Ensure we got the owning side, since it has all mapping info // Ensure we got the owning side, since it has all mapping info
if ( ! $relation->isOwningSide) { $assoc = ( ! $relation->isOwningSide) ? $targetClass->associationMappings[$relation->mappedBy] : $relation;
$assoc = $targetClass->associationMappings[$relation->mappedBy];
} else {
$assoc = $relation;
}
if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true) { if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true) {
if ($relation->isOneToMany() || $relation->isManyToMany()) { if ($relation->isOneToMany() || $relation->isManyToMany()) {
......
...@@ -95,9 +95,9 @@ EOT ...@@ -95,9 +95,9 @@ EOT
$deleted = $cacheDriver->delete($id); $deleted = $cacheDriver->delete($id);
if (is_array($deleted)) { if (is_array($deleted)) {
$this->_printDeleted($deleted); $this->_printDeleted($output, $deleted);
} else if (is_bool($deleted) && $deleted) { } else if (is_bool($deleted) && $deleted) {
$this->_printDeleted(array($id)); $this->_printDeleted($output, array($id));
} }
$outputed = true; $outputed = true;
...@@ -105,12 +105,12 @@ EOT ...@@ -105,12 +105,12 @@ EOT
} }
// Removing based on --regex // Removing based on --regex
if (($regex = $input->getOption('regex')) !== null && $regexps) { if (($regexps = $input->getOption('regex')) !== null && $regexps) {
foreach($regexps as $regex) { foreach($regexps as $regex) {
$output->write($outputed ? PHP_EOL : ''); $output->write($outputed ? PHP_EOL : '');
$output->write(sprintf('Clearing Result cache entries that match the regular expression "<info>%s</info>"', $regex) . PHP_EOL); $output->write(sprintf('Clearing Result cache entries that match the regular expression "<info>%s</info>"', $regex) . PHP_EOL);
$this->_printDeleted($cacheDriver->deleteByRegex('/' . $regex. '/')); $this->_printDeleted($output, $cacheDriver->deleteByRegex('/' . $regex. '/'));
$outputed = true; $outputed = true;
} }
...@@ -122,7 +122,7 @@ EOT ...@@ -122,7 +122,7 @@ EOT
$output->write($outputed ? PHP_EOL : ''); $output->write($outputed ? PHP_EOL : '');
$output->write(sprintf('Clearing Result cache entries that have the prefix "<info>%s</info>"', $prefix) . PHP_EOL); $output->write(sprintf('Clearing Result cache entries that have the prefix "<info>%s</info>"', $prefix) . PHP_EOL);
$this->_printDeleted($cacheDriver->deleteByPrefix($prefix)); $this->_printDeleted($output, $cacheDriver->deleteByPrefix($prefix));
$outputed = true; $outputed = true;
} }
...@@ -134,7 +134,7 @@ EOT ...@@ -134,7 +134,7 @@ EOT
$output->write($outputed ? PHP_EOL : ''); $output->write($outputed ? PHP_EOL : '');
$output->write(sprintf('Clearing Result cache entries that have the suffix "<info>%s</info>"', $suffix) . PHP_EOL); $output->write(sprintf('Clearing Result cache entries that have the suffix "<info>%s</info>"', $suffix) . PHP_EOL);
$this->_printDeleted($cacheDriver->deleteBySuffix($suffix)); $this->_printDeleted($output, $cacheDriver->deleteBySuffix($suffix));
$outputed = true; $outputed = true;
} }
...@@ -143,9 +143,9 @@ EOT ...@@ -143,9 +143,9 @@ EOT
// Removing ALL entries // Removing ALL entries
if ( ! $ids && ! $regexps && ! $prefixes && ! $suffixes) { if ( ! $ids && ! $regexps && ! $prefixes && ! $suffixes) {
$output->write($outputed ? PHP_EOL : ''); $output->write($outputed ? PHP_EOL : '');
$output->write('Clearing ALL Result cache entries'); $output->write('Clearing ALL Result cache entries' . PHP_EOL);
$this->_printDeleted($cacheDriver->deleteAll()); $this->_printDeleted($output, $cacheDriver->deleteAll());
$outputed = true; $outputed = true;
} }
......
...@@ -61,8 +61,8 @@ class ConvertMappingCommand extends Console\Command\Command ...@@ -61,8 +61,8 @@ class ConvertMappingCommand extends Console\Command\Command
'dest-path', InputArgument::REQUIRED, 'dest-path', InputArgument::REQUIRED,
'The path to generate your entities classes.' 'The path to generate your entities classes.'
), ),
new InputArgument( new InputOption(
'from-database', InputArgument::OPTIONAL, 'The path of mapping information.' 'from-database', null, null, 'Whether or not to convert mapping information from existing database.'
), ),
new InputOption( new InputOption(
'extend', null, InputOption::PARAMETER_OPTIONAL, 'extend', null, InputOption::PARAMETER_OPTIONAL,
...@@ -86,10 +86,7 @@ EOT ...@@ -86,10 +86,7 @@ EOT
{ {
$em = $this->getHelper('em')->getEntityManager(); $em = $this->getHelper('em')->getEntityManager();
$metadatas = $em->getMetadataFactory()->getAllMetadata(); if ($input->getOption('from-database') === true) {
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
if ($input->getArgument('from-database') === true) {
$em->getConfiguration()->setMetadataDriverImpl( $em->getConfiguration()->setMetadataDriverImpl(
new \Doctrine\ORM\Mapping\Driver\DatabaseDriver( new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$em->getConnection()->getSchemaManager() $em->getConnection()->getSchemaManager()
...@@ -97,8 +94,14 @@ EOT ...@@ -97,8 +94,14 @@ EOT
); );
} }
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
// Process destination directory // Process destination directory
$destPath = realpath($input->getArgument('dest-path')); if ( ! is_dir($destPath = $input->getArgument('dest-path'))) {
mkdir($destPath, 0777, true);
}
$destPath = realpath($destPath);
if ( ! file_exists($destPath)) { if ( ! file_exists($destPath)) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
......
...@@ -65,12 +65,21 @@ EOT ...@@ -65,12 +65,21 @@ EOT
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
{ {
$em = $this->getHelper('em')->getEntityManager(); $em = $this->getHelper('em')->getEntityManager();
$error = false;
try {
$em->getConfiguration()->ensureProductionSettings(); $em->getConfiguration()->ensureProductionSettings();
if ($input->getOption('complete') !== null) { if ($input->getOption('complete') !== null) {
$em->getConnection()->connect(); $em->getConnection()->connect();
} }
} catch (\Exception $e) {
$error = true;
$output->writeln('<error>' . $e->getMessage() . '</error>');
}
$output->write('Environment is correctly configured for production.'); if ($error === false) {
$output->write('<info>Environment is correctly configured for production.</info>' . PHP_EOL);
}
} }
} }
\ No newline at end of file
...@@ -79,6 +79,10 @@ EOT ...@@ -79,6 +79,10 @@ EOT
$destPath = $em->getConfiguration()->getProxyDir(); $destPath = $em->getConfiguration()->getProxyDir();
} }
if ( ! is_dir($destPath)) {
mkdir($destPath, 0777, true);
}
$destPath = realpath($destPath); $destPath = realpath($destPath);
if ( ! file_exists($destPath)) { if ( ! file_exists($destPath)) {
......
...@@ -933,6 +933,9 @@ public function <methodName>() ...@@ -933,6 +933,9 @@ public function <methodName>()
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY: case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
return 'IDENTITY'; return 'IDENTITY';
case ClassMetadataInfo::GENERATOR_TYPE_NONE:
return 'NONE';
default: default:
throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type); throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
} }
......
...@@ -227,6 +227,46 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase ...@@ -227,6 +227,46 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
->getSingleResult(); ->getSingleResult();
} }
/**
* @expectedException Doctrine\ORM\NoResultException
*/
public function testGetSingleScalarResultThrowsExceptionOnNoResult()
{
$this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a")
->getSingleScalarResult();
}
/**
* @expectedException Doctrine\ORM\NonUniqueResultException
*/
public function testGetSingleScalarResultThrowsExceptionOnNonUniqueResult()
{
$user = new CmsUser;
$user->name = 'Guilherme';
$user->username = 'gblanco';
$user->status = 'developer';
$article1 = new CmsArticle;
$article1->topic = "Doctrine 2";
$article1->text = "This is an introduction to Doctrine 2.";
$user->addArticle($article1);
$article2 = new CmsArticle;
$article2->topic = "Symfony 2";
$article2->text = "This is an introduction to Symfony 2.";
$user->addArticle($article2);
$this->_em->persist($user);
$this->_em->persist($article1);
$this->_em->persist($article2);
$this->_em->flush();
$this->_em->clear();
$this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a")
->getSingleScalarResult();
}
public function testSupportsQueriesWithEntityNamespaces() public function testSupportsQueriesWithEntityNamespaces()
{ {
$this->_em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS'); $this->_em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS');
......
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
require_once __DIR__ . '/../../../TestInit.php';
class DDC448Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC448MainTable'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC448ConnectedClass'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC448SubTable'),
));
}
public function testIssue()
{
$q = $this->_em->createQuery("select b from ".__NAMESPACE__."\\DDC448SubTable b where b.connectedClassId = ?1");
$this->assertEquals('SELECT d0_.id AS id0, d0_.discr AS discr1, d0_.connectedClassId AS connectedClassId2 FROM SubTable s1_ INNER JOIN DDC448MainTable d0_ ON s1_.id = d0_.id WHERE d0_.connectedClassId = ?', $q->getSQL());
}
}
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="smallint")
* @DiscriminatorMap({
* "0" = "DDC448MainTable",
* "1" = "DDC448SubTable"
* })
*/
class DDC448MainTable
{
/**
* @Id
* @Column(name="id", type="integer")
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ManyToOne(targetEntity="DDC448ConnectedClass", cascade={"all"}, fetch="EAGER")
* @JoinColumn(name="connectedClassId", referencedColumnName="id", onDelete="CASCADE", onUpdate="CASCADE", nullable=true)
*/
private $connectedClassId;
}
/**
* @Entity
* @Table(name="connectedClass")
* @HasLifecycleCallbacks
*/
class DDC448ConnectedClass
{
/**
* @Id
* @Column(name="id", type="integer")
* @GeneratedValue(strategy="AUTO")
*/
protected $id; // connected with DDC448MainTable
}
/**
* @Entity
* @Table(name="SubTable")
*/
class DDC448SubTable extends DDC448MainTable
{
}
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
require_once __DIR__ . '/../../../TestInit.php';
class DDC493Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC493Customer'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC493Distributor'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC493Contact')
));
}
public function testIssue()
{
$q = $this->_em->createQuery("select u, u.contact.data from ".__NAMESPACE__."\\DDC493Distributor u");
$this->assertEquals('SELECT d0_.id AS id0, d1_.data AS data1, d0_.discr AS discr2, d0_.contact AS contact3 FROM DDC493Distributor d2_ INNER JOIN DDC493Customer d0_ ON d2_.id = d0_.id INNER JOIN DDC493Contact d1_ ON d0_.contact = d1_.id', $q->getSQL());
}
}
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"distributor" = "DDC493Distributor", "customer" = "DDC493Customer"})
*/
class DDC493Customer {
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @OneToOne(targetEntity="DDC493Contact", cascade={"remove","persist"})
* @JoinColumn(name="contact", referencedColumnName="id")
*/
public $contact;
}
/**
* @Entity
*/
class DDC493Distributor extends DDC493Customer {
}
/**
* @Entity
*/
class DDC493Contact
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/** @Column(type="string") */
public $data;
}
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
require_once __DIR__ . '/../../../TestInit.php';
class DDC513Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC513OfferItem'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC513Item'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC513Price'),
));
}
public function testIssue()
{
$q = $this->_em->createQuery("select u from ".__NAMESPACE__."\\DDC513OfferItem u left join u.price p");
$this->assertEquals('SELECT d0_.id AS id0, d0_.discr AS discr1, d0_.price AS price2 FROM DDC513OfferItem d1_ INNER JOIN DDC513Item d0_ ON d1_.id = d0_.id LEFT JOIN DDC513Price d2_ ON d0_.price = d2_.id', $q->getSQL());
}
}
/**
* @Entity
*/
class DDC513OfferItem extends DDC513Item
{
}
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"item" = "DDC513Item", "offerItem" = "DDC513OfferItem"})
*/
class DDC513Item
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @OneToOne(targetEntity="DDC513Price", cascade={"remove","persist"})
* @JoinColumn(name="price", referencedColumnName="id")
*/
public $price;
}
/**
* @Entity
*/
class DDC513Price {
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/** @Column(type="string") */
public $data;
}
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
xsi="http://www.w3.org/2001/XMLSchema-instance" xsi="http://www.w3.org/2001/XMLSchema-instance"
schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\ORM\Mapping\CTI"> <entity name="Doctrine\Tests\ORM\Mapping\CTI">
<discriminiator-column name="discr" type="string" length=""/> <discriminator-column name="discr" type="string" length=""/>
<discriminator-map> <discriminator-map>
<discriminator-mapping value="foo" class="CTIFoo"/> <discriminator-mapping value="foo" class="CTIFoo"/>
<discriminator-mapping value="bar" class="CTIBar"/> <discriminator-mapping value="bar" class="CTIBar"/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment