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
{
$cache = array();
$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;
}
$result = $this->_gatherScalarRowData($result[key($result)], $cache);
......
......@@ -243,10 +243,10 @@ class ClassMetadata extends ClassMetadataInfo
// Store ReflectionProperty of mapped field
$sourceFieldName = $assocMapping->sourceFieldName;
$refProp = $this->reflClass->getProperty($sourceFieldName);
$refProp->setAccessible(true);
$this->reflFields[$sourceFieldName] = $refProp;
$refProp = $this->reflClass->getProperty($sourceFieldName);
$refProp->setAccessible(true);
$this->reflFields[$sourceFieldName] = $refProp;
}
/**
......
......@@ -155,7 +155,7 @@ abstract class AbstractFileDriver implements Driver
if ($this->_paths) {
foreach ((array) $this->_paths as $path) {
if ( ! is_dir($path)) {
throw MappingException::driverRequiresConfiguredDirectoryPath();
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath();
}
$iterator = new \RecursiveIteratorIterator(
......
......@@ -465,6 +465,11 @@ class SqlWalker implements TreeWalker
$fieldName = array_pop($parts);
$dqlAlias = $pathExpr->identificationVariable;
$class = $this->_queryComponents[$dqlAlias]['metadata'];
if (isset($class->inheritedAssociationFields[$fieldName])) {
$class = $this->_em->getClassMetadata($class->inheritedAssociationFields[$fieldName]);
}
$assoc = $class->associationMappings[$fieldName];
if ($assoc->isOwningSide) {
......@@ -472,8 +477,8 @@ class SqlWalker implements TreeWalker
if (count($assoc->sourceToTargetKeyColumns) > 1) {
throw QueryException::associationPathCompositeKeyNotSupported();
}
$sql .= $this->walkIdentificationVariable($dqlAlias) . '.'
. reset($assoc->targetToSourceKeyColumns);
$sql .= $this->getSqlTableAlias($class->table['name'], $dqlAlias) . '.'
. reset($assoc->targetToSourceKeyColumns);
} else {
// 2- Inverse side: NOT (YET?) SUPPORTED
throw QueryException::associationPathInverseSideNotSupported();
......@@ -683,23 +688,15 @@ class SqlWalker implements TreeWalker
$joinAssocPathExpr = $join->joinAssociationPathExpression;
$joinedDqlAlias = $join->aliasIdentificationVariable;
$targetQComp = $this->_queryComponents[$joinedDqlAlias];
$targetClass = $targetQComp['metadata'];
$relation = $targetQComp['relation'];
$sourceClass = $this->_queryComponents[$joinAssocPathExpr->identificationVariable]['metadata'];
$relation = $this->_queryComponents[$joinedDqlAlias]['relation'];
$targetClass = $this->_em->getClassMetadata($relation->targetEntityName);
$sourceClass = $this->_em->getClassMetadata($relation->sourceEntityName);
$targetTableName = $targetClass->getQuotedTableName($this->_platform);
$targetTableAlias = $this->getSqlTableAlias($targetClass->getTableName(), $joinedDqlAlias);
$sourceTableAlias = $this->getSqlTableAlias(
$sourceClass->getTableName(), $joinAssocPathExpr->identificationVariable
);
$targetTableAlias = $this->getSqlTableAlias($targetClass->table['name'], $joinedDqlAlias);
$sourceTableAlias = $this->getSqlTableAlias($sourceClass->table['name'], $joinAssocPathExpr->identificationVariable);
// Ensure we got the owning side, since it has all mapping info
if ( ! $relation->isOwningSide) {
$assoc = $targetClass->associationMappings[$relation->mappedBy];
} else {
$assoc = $relation;
}
$assoc = ( ! $relation->isOwningSide) ? $targetClass->associationMappings[$relation->mappedBy] : $relation;
if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true) {
if ($relation->isOneToMany() || $relation->isManyToMany()) {
......@@ -713,7 +710,7 @@ class SqlWalker implements TreeWalker
foreach ($assoc->sourceToTargetKeyColumns as $sourceColumn => $targetColumn) {
if ( ! $first) $sql .= ' AND '; else $first = false;
if ($relation->isOwningSide) {
$quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$targetColumn], $this->_platform);
$sql .= $sourceTableAlias . '.' . $sourceColumn
......
......@@ -95,9 +95,9 @@ EOT
$deleted = $cacheDriver->delete($id);
if (is_array($deleted)) {
$this->_printDeleted($deleted);
$this->_printDeleted($output, $deleted);
} else if (is_bool($deleted) && $deleted) {
$this->_printDeleted(array($id));
$this->_printDeleted($output, array($id));
}
$outputed = true;
......@@ -105,12 +105,12 @@ EOT
}
// Removing based on --regex
if (($regex = $input->getOption('regex')) !== null && $regexps) {
if (($regexps = $input->getOption('regex')) !== null && $regexps) {
foreach($regexps as $regex) {
$output->write($outputed ? 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;
}
......@@ -122,7 +122,7 @@ EOT
$output->write($outputed ? 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;
}
......@@ -134,7 +134,7 @@ EOT
$output->write($outputed ? 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;
}
......@@ -143,9 +143,9 @@ EOT
// Removing ALL entries
if ( ! $ids && ! $regexps && ! $prefixes && ! $suffixes) {
$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;
}
......
......@@ -61,8 +61,8 @@ class ConvertMappingCommand extends Console\Command\Command
'dest-path', InputArgument::REQUIRED,
'The path to generate your entities classes.'
),
new InputArgument(
'from-database', InputArgument::OPTIONAL, 'The path of mapping information.'
new InputOption(
'from-database', null, null, 'Whether or not to convert mapping information from existing database.'
),
new InputOption(
'extend', null, InputOption::PARAMETER_OPTIONAL,
......@@ -86,10 +86,7 @@ EOT
{
$em = $this->getHelper('em')->getEntityManager();
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
if ($input->getArgument('from-database') === true) {
if ($input->getOption('from-database') === true) {
$em->getConfiguration()->setMetadataDriverImpl(
new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$em->getConnection()->getSchemaManager()
......@@ -97,8 +94,14 @@ EOT
);
}
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
// 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)) {
throw new \InvalidArgumentException(
......
......@@ -65,12 +65,21 @@ EOT
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$em->getConfiguration()->ensureProductionSettings();
if ($input->getOption('complete') !== null) {
$em->getConnection()->connect();
$error = false;
try {
$em->getConfiguration()->ensureProductionSettings();
if ($input->getOption('complete') !== null) {
$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
$destPath = $em->getConfiguration()->getProxyDir();
}
if ( ! is_dir($destPath)) {
mkdir($destPath, 0777, true);
}
$destPath = realpath($destPath);
if ( ! file_exists($destPath)) {
......
......@@ -933,6 +933,9 @@ public function <methodName>()
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
return 'IDENTITY';
case ClassMetadataInfo::GENERATOR_TYPE_NONE:
return 'NONE';
default:
throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
}
......
......@@ -224,7 +224,47 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testGetSingleResultThrowsExceptionOnNoResult()
{
$this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a")
->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()
......
<?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 @@
xsi="http://www.w3.org/2001/XMLSchema-instance"
schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\ORM\Mapping\CTI">
<discriminiator-column name="discr" type="string" length=""/>
<discriminator-column name="discr" type="string" length=""/>
<discriminator-map>
<discriminator-mapping value="foo" class="CTIFoo"/>
<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