1
0
mirror of synced 2024-12-14 15:16:04 +03:00

Merge branch 'DDC-692'

This commit is contained in:
Benjamin Eberlei 2011-03-29 20:17:56 +02:00
commit e9c4f612cf
11 changed files with 106 additions and 5 deletions

View File

@ -88,6 +88,7 @@
<xs:attribute name="repository-class" type="xs:string"/>
<xs:attribute name="inheritance-type" type="orm:inheritance-type"/>
<xs:attribute name="change-tracking-policy" type="orm:change-tracking-policy" />
<xs:attribute name="read-only" type="xs:boolean" default="false" />
</xs:complexType>
<xs:complexType name="mapped-superclass" >

View File

@ -334,6 +334,10 @@ class ClassMetadata extends ClassMetadataInfo
$serialized[] = 'namedQueries';
}
if ($this->isReadOnly) {
$serialized[] = 'isReadOnly';
}
return $serialized;
}

View File

@ -484,6 +484,17 @@ class ClassMetadataInfo implements ClassMetadata
*/
public $reflClass;
/**
* Is this entity marked as "read-only"?
*
* That means it is never considered for change-tracking in the UnitOfWork. It is a very helpful performance
* optimization for entities that are immutable, either in your domain or through the relation database
* (coming from a view, or a history table for example).
*
* @var bool
*/
public $isReadOnly = false;
/**
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
* metadata of the class with the given name.
@ -1818,4 +1829,14 @@ class ClassMetadataInfo implements ClassMetadata
{
$this->versionField = $versionField;
}
/**
* Mark this class as read only, no change tracking is applied to it.
*
* @return void
*/
public function markReadOnly()
{
$this->isReadOnly = true;
}
}

View File

@ -132,6 +132,10 @@ class AnnotationDriver implements Driver
if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) {
$entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity'];
$metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
if ($entityAnnot->readOnly) {
$metadata->markReadOnly();
}
} else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) {
$metadata->isMappedSuperclass = true;
} else {

View File

@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@ -27,6 +25,7 @@ use Doctrine\Common\Annotations\Annotation;
final class Entity extends Annotation {
public $repositoryClass;
public $readOnly = false;
}
final class MappedSuperclass extends Annotation {}
final class InheritanceType extends Annotation {}

View File

@ -55,6 +55,9 @@ class XmlDriver extends AbstractFileDriver
$metadata->setCustomRepositoryClass(
isset($xmlRoot['repository-class']) ? (string)$xmlRoot['repository-class'] : null
);
if (isset($xmlRoot['read-only']) && $xmlRoot['read-only'] == "true") {
$metadata->markReadOnly();
}
} else if ($xmlRoot->getName() == 'mapped-superclass') {
$metadata->isMappedSuperclass = true;
} else {

View File

@ -49,6 +49,9 @@ class YamlDriver extends AbstractFileDriver
$metadata->setCustomRepositoryClass(
isset($element['repositoryClass']) ? $element['repositoryClass'] : null
);
if (isset($element['readOnly']) && $element['readOnly'] == true) {
$metadata->markReadOnly();
}
} else if ($element['type'] == 'mappedSuperclass') {
$metadata->isMappedSuperclass = true;
} else {

View File

@ -514,9 +514,9 @@ class UnitOfWork implements PropertyChangedListener
$class = $this->em->getClassMetadata($className);
// Skip class if instances are read-only
//if ($class->isReadOnly) {
// continue;
//}
if ($class->isReadOnly) {
continue;
}
// If change tracking is explicit or happens through notification, then only compute
// changes on entities of that type that are explicitly marked for synchronization.

View File

@ -59,6 +59,7 @@ class AllTests
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\PostgreSQLIdentityStrategyTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ExtraLazyCollectionTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ClearEventTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ReadOnlyTest');
$suite->addTest(Locking\AllTests::suite());
$suite->addTest(Ticket\AllTests::suite());

View File

@ -0,0 +1,61 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
require_once __DIR__ . '/../../TestInit.php';
/**
* Functional Query tests.
*
* @group DDC-692
*/
class ReadOnlyTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\ReadOnlyEntity'),
));
}
public function testReadOnlyEntityNeverChangeTracked()
{
$readOnly = new ReadOnlyEntity("Test1", 1234);
$this->_em->persist($readOnly);
$this->_em->flush();
$readOnly->name = "Test2";
$readOnly->number = 4321;
$this->_em->flush();
$this->_em->clear();
$dbReadOnly = $this->_em->find('Doctrine\Tests\ORM\Functional\ReadOnlyEntity', $readOnly->id);
$this->assertEquals("Test1", $dbReadOnly->name);
$this->assertEquals(1234, $dbReadOnly->number);
}
}
/**
* @Entity(readOnly=true)
*/
class ReadOnlyEntity
{
/**
* @Id @GeneratedValue @Column(type="integer")
* @var int
*/
public $id;
/** @column(type="string") */
public $name;
/** @Column(type="integer") */
public $number;
public function __construct($name, $number)
{
$this->name = $name;
$this->number = $number;
}
}

View File

@ -30,6 +30,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$cm->setCustomRepositoryClass("UserRepository");
$cm->setDiscriminatorColumn(array('name' => 'disc', 'type' => 'integer'));
$cm->mapOneToOne(array('fieldName' => 'phonenumbers', 'targetEntity' => 'Bar', 'mappedBy' => 'foo'));
$cm->markReadOnly();
$cm->addNamedQuery(array('name' => 'dql', 'query' => 'foo'));
$this->assertEquals(1, count($cm->associationMappings));
$serialized = serialize($cm);
@ -51,6 +53,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertTrue($oneOneMapping['fetch'] == ClassMetadata::FETCH_LAZY);
$this->assertEquals('phonenumbers', $oneOneMapping['fieldName']);
$this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping['targetEntity']);
$this->assertTrue($cm->isReadOnly);
$this->assertEquals(array('dql' => 'foo'), $cm->namedQueries);
}
public function testFieldIsNullable()