Merge branch 'DBAL-15'
This commit is contained in:
commit
be4eb63c62
@ -20,6 +20,7 @@
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
@ -746,6 +747,14 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
$this->isIdentifierComposite = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Type::hasType($mapping['type']) && Type::getType($mapping['type'])->canRequireSQLConversion()) {
|
||||
if (isset($mapping['id']) && $mapping['id'] === true) {
|
||||
throw MappingException::sqlConversionNotAllowedForIdentifiers($this->name, $mapping['fieldName'], $mapping['type']);
|
||||
}
|
||||
|
||||
$mapping['requireSQLConversion'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,6 +226,11 @@ class MappingException extends \Doctrine\ORM\ORMException
|
||||
return new self("Setting Id field '$fieldName' as versionale in entity class '$className' is not supported.");
|
||||
}
|
||||
|
||||
public static function sqlConversionNotAllowedForIdentifiers($className, $fieldName, $type)
|
||||
{
|
||||
return new self("It is not possible to set id field '$fieldName' to type '$type' in entity class '$className'. The type '$type' requires conversion SQL which is not allowed for identifiers.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param string $columnName
|
||||
|
@ -65,6 +65,11 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
|
||||
$columnAlias = $this->getSQLColumnAlias($columnName);
|
||||
$this->_rsm->addFieldResult($alias, $columnAlias, $field, $class->name);
|
||||
|
||||
if (isset($class->fieldMappings[$field]['requireSQLConversion'])) {
|
||||
$type = Type::getType($class->getTypeOfField($field));
|
||||
$sql = $type->convertToPHPValueSQL($sql, $this->_platform);
|
||||
}
|
||||
|
||||
return $sql . ' AS ' . $columnAlias;
|
||||
}
|
||||
|
||||
|
@ -338,10 +338,19 @@ class BasicEntityPersister
|
||||
$set = $params = $types = array();
|
||||
|
||||
foreach ($updateData as $columnName => $value) {
|
||||
$set[] = (isset($this->_class->fieldNames[$columnName]))
|
||||
? $this->_class->getQuotedColumnName($this->_class->fieldNames[$columnName], $this->_platform) . ' = ?'
|
||||
: $columnName . ' = ?';
|
||||
$column = $columnName;
|
||||
$placeholder = '?';
|
||||
|
||||
if (isset($this->_class->fieldNames[$columnName])) {
|
||||
$column = $this->_class->getQuotedColumnName($this->_class->fieldNames[$columnName], $this->_platform);
|
||||
|
||||
if (isset($this->_class->fieldMappings[$this->_class->fieldNames[$columnName]]['requireSQLConversion'])) {
|
||||
$type = Type::getType($this->_columnTypes[$columnName]);
|
||||
$placeholder = $type->convertToDatabaseValueSQL('?', $this->_platform);
|
||||
}
|
||||
}
|
||||
|
||||
$set[] = $column . ' = ' . $placeholder;
|
||||
$params[] = $value;
|
||||
$types[] = $this->_columnTypes[$columnName];
|
||||
}
|
||||
@ -1121,7 +1130,19 @@ class BasicEntityPersister
|
||||
);
|
||||
} else {
|
||||
$columns = array_unique($columns);
|
||||
$values = array_fill(0, count($columns), '?');
|
||||
|
||||
$values = array();
|
||||
foreach ($columns AS $column) {
|
||||
$placeholder = '?';
|
||||
|
||||
if (isset($this->_columnTypes[$column]) &&
|
||||
isset($this->_class->fieldMappings[$this->_class->fieldNames[$column]]['requireSQLConversion'])) {
|
||||
$type = Type::getType($this->_columnTypes[$column]);
|
||||
$placeholder = $type->convertToDatabaseValueSQL('?', $this->_platform);
|
||||
}
|
||||
|
||||
$values[] = $placeholder;
|
||||
}
|
||||
|
||||
$insertSql = 'INSERT INTO ' . $this->_class->getQuotedTableName($this->_platform)
|
||||
. ' (' . implode(', ', $columns) . ') VALUES (' . implode(', ', $values) . ')';
|
||||
@ -1160,6 +1181,7 @@ class BasicEntityPersister
|
||||
}
|
||||
} else if ($this->_class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $this->_class->identifier[0] != $name) {
|
||||
$columns[] = $this->_class->getQuotedColumnName($name, $this->_platform);
|
||||
$this->_columnTypes[$name] = $this->_class->fieldMappings[$name]['type'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1182,6 +1204,11 @@ class BasicEntityPersister
|
||||
|
||||
$this->_rsm->addFieldResult($alias, $columnAlias, $field);
|
||||
|
||||
if (isset($class->fieldMappings[$field]['requireSQLConversion'])) {
|
||||
$type = Type::getType($class->getTypeOfField($field));
|
||||
$sql = $type->convertToPHPValueSQL($sql, $this->_platform);
|
||||
}
|
||||
|
||||
return $sql . ' AS ' . $columnAlias;
|
||||
}
|
||||
|
||||
@ -1263,6 +1290,8 @@ class BasicEntityPersister
|
||||
|
||||
foreach ($criteria as $field => $value) {
|
||||
$conditionSql .= $conditionSql ? ' AND ' : '';
|
||||
|
||||
$placeholder = '?';
|
||||
|
||||
if (isset($this->_class->columnNames[$field])) {
|
||||
$className = (isset($this->_class->fieldMappings[$field]['inherited']))
|
||||
@ -1270,6 +1299,11 @@ class BasicEntityPersister
|
||||
: $this->_class->name;
|
||||
|
||||
$conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->getQuotedColumnName($field, $this->_platform);
|
||||
|
||||
if (isset($this->_class->fieldMappings[$field]['requireSQLConversion'])) {
|
||||
$type = Type::getType($this->_class->getTypeOfField($field));
|
||||
$placeholder = $type->convertToDatabaseValueSQL($placeholder, $this->_platform);
|
||||
}
|
||||
} else if (isset($this->_class->associationMappings[$field])) {
|
||||
if ( ! $this->_class->associationMappings[$field]['isOwningSide']) {
|
||||
throw ORMException::invalidFindByInverseAssociation($this->_class->name, $field);
|
||||
@ -1290,7 +1324,7 @@ class BasicEntityPersister
|
||||
throw ORMException::unrecognizedField($field);
|
||||
}
|
||||
|
||||
$conditionSql .= (is_array($value)) ? ' IN (?)' : (($value === null) ? ' IS NULL' : ' = ?');
|
||||
$conditionSql .= (is_array($value)) ? ' IN (?)' : (($value === null) ? ' IS NULL' : ' = ' . $placeholder);
|
||||
}
|
||||
return $conditionSql;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
namespace Doctrine\ORM\Query;
|
||||
|
||||
use Doctrine\DBAL\LockMode,
|
||||
Doctrine\DBAL\Types\Type,
|
||||
Doctrine\ORM\Mapping\ClassMetadata,
|
||||
Doctrine\ORM\Query,
|
||||
Doctrine\ORM\Query\QueryException,
|
||||
@ -1002,9 +1003,16 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
$sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
|
||||
$columnName = $class->getQuotedColumnName($fieldName, $this->_platform);
|
||||
$columnAlias = $this->getSQLColumnAlias($columnName);
|
||||
$columnAlias = $this->getSQLColumnAlias($columnName);
|
||||
|
||||
$sql .= $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
|
||||
$col = $sqlTableAlias . '.' . $columnName;
|
||||
|
||||
if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) {
|
||||
$type = Type::getType($class->getTypeOfField($fieldName));
|
||||
$col = $type->convertToPHPValueSQL($col, $this->_conn->getDatabasePlatform());
|
||||
}
|
||||
|
||||
$sql .= $col . ' AS ' . $columnAlias;
|
||||
|
||||
if ( ! $hidden) {
|
||||
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
|
||||
@ -1086,7 +1094,14 @@ class SqlWalker implements TreeWalker
|
||||
$columnAlias = $this->getSQLColumnAlias($mapping['columnName']);
|
||||
$quotedColumnName = $class->getQuotedColumnName($fieldName, $this->_platform);
|
||||
|
||||
$sqlParts[] = $sqlTableAlias . '.' . $quotedColumnName . ' AS '. $columnAlias;
|
||||
$col = $sqlTableAlias . '.' . $quotedColumnName;
|
||||
|
||||
if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) {
|
||||
$type = Type::getType($class->getTypeOfField($fieldName));
|
||||
$col = $type->convertToPHPValueSQL($col, $this->_platform);
|
||||
}
|
||||
|
||||
$sqlParts[] = $col . ' AS '. $columnAlias;
|
||||
|
||||
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $class->name);
|
||||
}
|
||||
@ -1108,7 +1123,14 @@ class SqlWalker implements TreeWalker
|
||||
$columnAlias = $this->getSQLColumnAlias($mapping['columnName']);
|
||||
$quotedColumnName = $subClass->getQuotedColumnName($fieldName, $this->_platform);
|
||||
|
||||
$sqlParts[] = $sqlTableAlias . '.' . $quotedColumnName . ' AS ' . $columnAlias;
|
||||
$col = $sqlTableAlias . '.' . $quotedColumnName;
|
||||
|
||||
if (isset($subClass->fieldMappings[$fieldName]['requireSQLConversion'])) {
|
||||
$type = Type::getType($subClass->getTypeOfField($fieldName));
|
||||
$col = $type->convertToPHPValueSQL($col, $this->_platform);
|
||||
}
|
||||
|
||||
$sqlParts[] = $col . ' AS ' . $columnAlias;
|
||||
|
||||
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName);
|
||||
}
|
||||
|
34
tests/Doctrine/Tests/DbalTypes/NegativeToPositiveType.php
Normal file
34
tests/Doctrine/Tests/DbalTypes/NegativeToPositiveType.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\DbalTypes;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
class NegativeToPositiveType extends Type
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'negative_to_positive';
|
||||
}
|
||||
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
|
||||
{
|
||||
return $platform->getIntegerTypeDeclarationSQL($fieldDeclaration);
|
||||
}
|
||||
|
||||
public function canRequireSQLConversion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
|
||||
{
|
||||
return 'ABS(' . $sqlExpr . ')';
|
||||
}
|
||||
|
||||
public function convertToPHPValueSQL($sqlExpr, $platform)
|
||||
{
|
||||
return '-(' . $sqlExpr . ')';
|
||||
}
|
||||
}
|
29
tests/Doctrine/Tests/DbalTypes/UpperCaseStringType.php
Normal file
29
tests/Doctrine/Tests/DbalTypes/UpperCaseStringType.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\DbalTypes;
|
||||
|
||||
use Doctrine\DBAL\Types\StringType;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
class UpperCaseStringType extends StringType
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'upper_case_string';
|
||||
}
|
||||
|
||||
public function canRequireSQLConversion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
|
||||
{
|
||||
return 'UPPER(' . $sqlExpr . ')';
|
||||
}
|
||||
|
||||
public function convertToPHPValueSQL($sqlExpr, $platform)
|
||||
{
|
||||
return 'LOWER(' . $sqlExpr . ')';
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
private $_platformMock;
|
||||
private $_lastInsertId = 0;
|
||||
private $_inserts = array();
|
||||
private $_executeUpdates = array();
|
||||
|
||||
public function __construct(array $params, $driver, $config = null, $eventManager = null)
|
||||
{
|
||||
@ -35,6 +36,14 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
$this->_inserts[$tableName][] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function executeUpdate($query, array $params = array(), array $types = array())
|
||||
{
|
||||
$this->_executeUpdates[] = array('query' => $query, 'params' => $params, 'types' => $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@ -84,6 +93,11 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
return $this->_inserts;
|
||||
}
|
||||
|
||||
public function getExecuteUpdates()
|
||||
{
|
||||
return $this->_executeUpdates;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->_inserts = array();
|
||||
|
21
tests/Doctrine/Tests/Models/CustomType/CustomTypeChild.php
Normal file
21
tests/Doctrine/Tests/Models/CustomType/CustomTypeChild.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\CustomType;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="customtype_children")
|
||||
*/
|
||||
class CustomTypeChild
|
||||
{
|
||||
/**
|
||||
* @Id @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="upper_case_string")
|
||||
*/
|
||||
public $lowerCaseString = 'foo';
|
||||
}
|
68
tests/Doctrine/Tests/Models/CustomType/CustomTypeParent.php
Normal file
68
tests/Doctrine/Tests/Models/CustomType/CustomTypeParent.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\CustomType;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="customtype_parents")
|
||||
*/
|
||||
class CustomTypeParent
|
||||
{
|
||||
/**
|
||||
* @Id @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="negative_to_positive", nullable=true)
|
||||
*/
|
||||
public $customInteger;
|
||||
|
||||
/**
|
||||
* @OneToOne(targetEntity="Doctrine\Tests\Models\CustomType\CustomTypeChild", cascade={"persist", "remove"})
|
||||
*/
|
||||
public $child;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="Doctrine\Tests\Models\CustomType\CustomTypeParent", mappedBy="myFriends")
|
||||
*/
|
||||
private $friendsWithMe;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="Doctrine\Tests\Models\CustomType\CustomTypeParent", inversedBy="friendsWithMe")
|
||||
* @JoinTable(
|
||||
* name="customtype_parent_friends",
|
||||
* joinColumns={@JoinColumn(name="customtypeparent_id", referencedColumnName="id")},
|
||||
* inverseJoinColumns={@JoinColumn(name="friend_customtypeparent_id", referencedColumnName="id")}
|
||||
* )
|
||||
*/
|
||||
private $myFriends;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->friendsWithMe = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
$this->myFriends = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
}
|
||||
|
||||
public function addMyFriend(CustomTypeParent $friend)
|
||||
{
|
||||
$this->getMyFriends()->add($friend);
|
||||
$friend->addFriendWithMe($this);
|
||||
}
|
||||
|
||||
public function getMyFriends()
|
||||
{
|
||||
return $this->myFriends;
|
||||
}
|
||||
|
||||
public function addFriendWithMe(CustomTypeParent $friend)
|
||||
{
|
||||
$this->getFriendsWithMe()->add($friend);
|
||||
}
|
||||
|
||||
public function getFriendsWithMe()
|
||||
{
|
||||
return $this->friendsWithMe;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\CustomType;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="customtype_uppercases")
|
||||
*/
|
||||
class CustomTypeUpperCase
|
||||
{
|
||||
/**
|
||||
* @Id @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="upper_case_string")
|
||||
*/
|
||||
public $lowerCaseString;
|
||||
}
|
105
tests/Doctrine/Tests/ORM/Functional/TypeValueSqlTest.php
Normal file
105
tests/Doctrine/Tests/ORM/Functional/TypeValueSqlTest.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeChild;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeParent;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeUpperCase;
|
||||
use Doctrine\DBAL\Types\Type as DBALType;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class TypeValueSqlTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
if (DBALType::hasType('upper_case_string')) {
|
||||
DBALType::overrideType('upper_case_string', '\Doctrine\Tests\DbalTypes\UpperCaseStringType');
|
||||
} else {
|
||||
DBALType::addType('upper_case_string', '\Doctrine\Tests\DbalTypes\UpperCaseStringType');
|
||||
}
|
||||
|
||||
if (DBALType::hasType('negative_to_positive')) {
|
||||
DBALType::overrideType('negative_to_positive', '\Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
} else {
|
||||
DBALType::addType('negative_to_positive', '\Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
}
|
||||
|
||||
$this->useModelSet('customtype');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testUpperCaseStringType()
|
||||
{
|
||||
$entity = new CustomTypeUpperCase();
|
||||
$entity->lowerCaseString = 'foo';
|
||||
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
|
||||
$id = $entity->id;
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$entity = $this->_em->find('\Doctrine\Tests\Models\CustomType\CustomTypeUpperCase', $id);
|
||||
|
||||
$this->assertEquals('foo', $entity->lowerCaseString, 'Entity holds lowercase string');
|
||||
$this->assertEquals('FOO', $this->_em->getConnection()->fetchColumn("select lowerCaseString from customtype_uppercases where id=".$entity->id.""), 'Database holds uppercase string');
|
||||
}
|
||||
|
||||
public function testTypeValueSqlWithAssociations()
|
||||
{
|
||||
$parent = new CustomTypeParent();
|
||||
$parent->customInteger = -1;
|
||||
$parent->child = new CustomTypeChild();
|
||||
|
||||
$friend1 = new CustomTypeParent();
|
||||
$friend2 = new CustomTypeParent();
|
||||
|
||||
$parent->addMyFriend($friend1);
|
||||
$parent->addMyFriend($friend2);
|
||||
|
||||
$this->_em->persist($parent);
|
||||
$this->_em->persist($friend1);
|
||||
$this->_em->persist($friend2);
|
||||
$this->_em->flush();
|
||||
|
||||
$parentId = $parent->id;
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$entity = $this->_em->find('Doctrine\Tests\Models\CustomType\CustomTypeParent', $parentId);
|
||||
|
||||
$this->assertTrue($entity->customInteger < 0, 'Fetched customInteger negative');
|
||||
$this->assertEquals(1, $this->_em->getConnection()->fetchColumn("select customInteger from customtype_parents where id=".$entity->id.""), 'Database has stored customInteger positive');
|
||||
|
||||
$this->assertNotNull($parent->child, 'Child attached');
|
||||
$this->assertCount(2, $entity->getMyFriends(), '2 friends attached');
|
||||
}
|
||||
|
||||
public function testSelectDQL()
|
||||
{
|
||||
$parent = new CustomTypeParent();
|
||||
$parent->customInteger = -1;
|
||||
$parent->child = new CustomTypeChild();
|
||||
|
||||
$this->_em->persist($parent);
|
||||
$this->_em->flush();
|
||||
|
||||
$parentId = $parent->id;
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery("SELECT p, p.customInteger, c from Doctrine\Tests\Models\CustomType\CustomTypeParent p JOIN p.child c where p.id = " . $parentId);
|
||||
|
||||
$result = $query->getResult();
|
||||
|
||||
$this->assertEquals(1, count($result));
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\CustomType\CustomTypeParent', $result[0][0]);
|
||||
$this->assertEquals(-1, $result[0][0]->customInteger);
|
||||
|
||||
$this->assertEquals(-1, $result[0]['customInteger']);
|
||||
|
||||
$this->assertEquals('foo', $result[0][0]->child->lowerCaseString);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\DBAL\Types\Type as DBALType;
|
||||
use Doctrine\ORM\Persisters\BasicEntityPersister;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeParent;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeChild;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeFriend;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
protected $_persister;
|
||||
protected $_em;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (DBALType::hasType('negative_to_positive')) {
|
||||
DBALType::overrideType('negative_to_positive', '\Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
} else {
|
||||
DBALType::addType('negative_to_positive', '\Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
}
|
||||
|
||||
if (DBALType::hasType('upper_case_string')) {
|
||||
DBALType::overrideType('upper_case_string', '\Doctrine\Tests\DbalTypes\UpperCaseStringType');
|
||||
} else {
|
||||
DBALType::addType('upper_case_string', '\Doctrine\Tests\DbalTypes\UpperCaseStringType');
|
||||
}
|
||||
|
||||
$this->_em = $this->_getTestEntityManager();
|
||||
|
||||
$this->_persister = new BasicEntityPersister($this->_em, $this->_em->getClassMetadata("Doctrine\Tests\Models\CustomType\CustomTypeParent"));
|
||||
}
|
||||
|
||||
public function testGetInsertSQLUsesTypeValuesSQL()
|
||||
{
|
||||
$method = new \ReflectionMethod($this->_persister, '_getInsertSQL');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$sql = $method->invoke($this->_persister);
|
||||
|
||||
$this->assertEquals('INSERT INTO customtype_parents (customInteger, child_id) VALUES (ABS(?), ?)', $sql);
|
||||
}
|
||||
|
||||
public function testUpdateUsesTypeValuesSQL()
|
||||
{
|
||||
$child = new CustomTypeChild();
|
||||
|
||||
$parent = new CustomTypeParent();
|
||||
$parent->customInteger = 1;
|
||||
$parent->child = $child;
|
||||
|
||||
$this->_em->getUnitOfWork()->registerManaged($parent, array('id' => 1), array('customInteger' => 0, 'child' => null));
|
||||
$this->_em->getUnitOfWork()->registerManaged($child, array('id' => 1), array());
|
||||
|
||||
$this->_em->getUnitOfWork()->propertyChanged($parent, 'customInteger', 0, 1);
|
||||
$this->_em->getUnitOfWork()->propertyChanged($parent, 'child', null, $child);
|
||||
|
||||
$this->_persister->update($parent);
|
||||
|
||||
$executeUpdates = $this->_em->getConnection()->getExecuteUpdates();
|
||||
|
||||
$this->assertEquals('UPDATE customtype_parents SET customInteger = ABS(?), child_id = ? WHERE id = ?', $executeUpdates[0]['query']);
|
||||
}
|
||||
|
||||
public function testGetSelectConditionSQLUsesTypeValuesSQL()
|
||||
{
|
||||
$method = new \ReflectionMethod($this->_persister, '_getSelectConditionSQL');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$sql = $method->invoke($this->_persister, array('customInteger' => 1, 'child' => 1));
|
||||
|
||||
$this->assertEquals('t0.customInteger = ABS(?) AND t0.child_id = ?', $sql);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Query;
|
||||
|
||||
use Doctrine\DBAL\Types\Type as DBALType;
|
||||
use Doctrine\ORM\Query;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
@ -1333,6 +1334,62 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
'SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_employees c0_ GROUP BY c0_.id, c0_.name, c0_.spouse_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCustomTypeValueSql()
|
||||
{
|
||||
if (DBALType::hasType('negative_to_positive')) {
|
||||
DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
} else {
|
||||
DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
}
|
||||
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT p.customInteger FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
|
||||
'SELECT -(c0_.customInteger) AS customInteger0 FROM customtype_parents c0_ WHERE c0_.id = 1'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCustomTypeValueSqlIgnoresIdentifierColumn()
|
||||
{
|
||||
if (DBALType::hasType('negative_to_positive')) {
|
||||
DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
} else {
|
||||
DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
}
|
||||
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT p.id FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
|
||||
'SELECT c0_.id AS id0 FROM customtype_parents c0_ WHERE c0_.id = 1'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCustomTypeValueSqlForAllFields()
|
||||
{
|
||||
if (DBALType::hasType('negative_to_positive')) {
|
||||
DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
} else {
|
||||
DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
}
|
||||
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT p FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
|
||||
'SELECT c0_.id AS id0, -(c0_.customInteger) AS customInteger1 FROM customtype_parents c0_'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCustomTypeValueSqlForPartialObject()
|
||||
{
|
||||
if (DBALType::hasType('negative_to_positive')) {
|
||||
DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
} else {
|
||||
DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
}
|
||||
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT partial p.{id, customInteger} FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
|
||||
'SELECT c0_.id AS id0, -(c0_.customInteger) AS customInteger1 FROM customtype_parents c0_'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Query;
|
||||
|
||||
use Doctrine\DBAL\Types\Type as DBALType;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
@ -42,6 +44,12 @@ class UpdateSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
private $_em;
|
||||
|
||||
protected function setUp() {
|
||||
if (DBALType::hasType('negative_to_positive')) {
|
||||
DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
} else {
|
||||
DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
|
||||
}
|
||||
|
||||
$this->_em = $this->_getTestEntityManager();
|
||||
}
|
||||
|
||||
@ -186,4 +194,12 @@ class UpdateSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
"UPDATE cms_users SET status = 'inactive' WHERE (SELECT COUNT(*) FROM cms_users_groups c0_ WHERE c0_.user_id = cms_users.id) = 10"
|
||||
);
|
||||
}
|
||||
|
||||
public function testCustomTypeValueSqlCompletelyIgnoredInUpdateStatements()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'UPDATE Doctrine\Tests\Models\CustomType\CustomTypeParent p SET p.customInteger = 1 WHERE p.id = 1',
|
||||
'UPDATE customtype_parents SET customInteger = 1 WHERE id = 1'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,11 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
'Doctrine\Tests\Models\Legacy\LegacyArticle',
|
||||
'Doctrine\Tests\Models\Legacy\LegacyCar',
|
||||
),
|
||||
'customtype' => array(
|
||||
'Doctrine\Tests\Models\CustomType\CustomTypeChild',
|
||||
'Doctrine\Tests\Models\CustomType\CustomTypeParent',
|
||||
'Doctrine\Tests\Models\CustomType\CustomTypeUpperCase',
|
||||
),
|
||||
);
|
||||
|
||||
protected function useModelSet($setName)
|
||||
@ -219,6 +224,13 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
$conn->executeUpdate('DELETE FROM legacy_users');
|
||||
}
|
||||
|
||||
if (isset($this->_usedModelSets['customtype'])) {
|
||||
$conn->executeUpdate('DELETE FROM customtype_parent_friends');
|
||||
$conn->executeUpdate('DELETE FROM customtype_parents');
|
||||
$conn->executeUpdate('DELETE FROM customtype_children');
|
||||
$conn->executeUpdate('DELETE FROM customtype_uppercases');
|
||||
}
|
||||
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user