Initial implementation of Doctrine\DBAL\Types\Type::convertToDatabaseValueSQL() and Doctrine\DBAL\Types\Type::convertToPHPValueSQL() integration
This commit is contained in:
parent
43b1e79ec4
commit
6f35679911
@ -65,6 +65,11 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
|
||||
$columnAlias = $this->getSQLColumnAlias($columnName);
|
||||
$this->_rsm->addFieldResult($alias, $columnAlias, $field, $class->name);
|
||||
|
||||
if (!$class->isIdentifier($field)) {
|
||||
$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 (!$this->_class->isIdentifier($this->_class->fieldNames[$columnName])) {
|
||||
$type = Type::getType($this->_columnTypes[$columnName]);
|
||||
$placeholder = $type->convertToDatabaseValueSQL('?', $this->_platform);
|
||||
}
|
||||
}
|
||||
|
||||
$set[] = $column . ' = ' . $placeholder;
|
||||
$params[] = $value;
|
||||
$types[] = $this->_columnTypes[$columnName];
|
||||
}
|
||||
@ -1117,7 +1126,18 @@ 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])) {
|
||||
$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) . ')';
|
||||
@ -1156,6 +1176,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'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1178,6 +1199,11 @@ class BasicEntityPersister
|
||||
|
||||
$this->_rsm->addFieldResult($alias, $columnAlias, $field);
|
||||
|
||||
if (!$class->isIdentifier($field)) {
|
||||
$type = Type::getType($class->getTypeOfField($field));
|
||||
$sql = $type->convertToPHPValueSQL($sql, $this->_platform);
|
||||
}
|
||||
|
||||
return $sql . ' AS ' . $columnAlias;
|
||||
}
|
||||
|
||||
@ -1260,12 +1286,19 @@ class BasicEntityPersister
|
||||
foreach ($criteria as $field => $value) {
|
||||
$conditionSql .= $conditionSql ? ' AND ' : '';
|
||||
|
||||
$placeholder = '?';
|
||||
|
||||
if (isset($this->_class->columnNames[$field])) {
|
||||
$className = (isset($this->_class->fieldMappings[$field]['inherited']))
|
||||
? $this->_class->fieldMappings[$field]['inherited']
|
||||
: $this->_class->name;
|
||||
|
||||
$conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->getQuotedColumnName($field, $this->_platform);
|
||||
|
||||
if (!$this->_class->isIdentifier($field)) {
|
||||
$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);
|
||||
@ -1286,7 +1319,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,
|
||||
@ -97,6 +98,17 @@ class SqlWalker implements TreeWalker
|
||||
*/
|
||||
private $_useSqlTableAliases = true;
|
||||
|
||||
/**
|
||||
* Flag that indicates whether to pass columns through Type::convertToPHPValueSQL().
|
||||
* These should only be done for SELECT queries, not for UPDATE.
|
||||
*/
|
||||
private $_useDbalTypeValueSql = true;
|
||||
|
||||
/**
|
||||
* Holds the current columns type.
|
||||
*/
|
||||
private $_currentColumnType;
|
||||
|
||||
/**
|
||||
* The database platform abstraction.
|
||||
*
|
||||
@ -409,6 +421,7 @@ class SqlWalker implements TreeWalker
|
||||
public function walkUpdateStatement(AST\UpdateStatement $AST)
|
||||
{
|
||||
$this->_useSqlTableAliases = false;
|
||||
$this->_useDbalTypeValueSql = false;
|
||||
|
||||
return $this->walkUpdateClause($AST->updateClause) . $this->walkWhereClause($AST->whereClause);
|
||||
}
|
||||
@ -464,11 +477,20 @@ class SqlWalker implements TreeWalker
|
||||
$dqlAlias = $pathExpr->identificationVariable;
|
||||
$class = $this->_queryComponents[$dqlAlias]['metadata'];
|
||||
|
||||
$column = '';
|
||||
|
||||
if ($this->_useSqlTableAliases) {
|
||||
$sql .= $this->walkIdentificationVariable($dqlAlias, $fieldName) . '.';
|
||||
$column .= $this->walkIdentificationVariable($dqlAlias, $fieldName) . '.';
|
||||
}
|
||||
|
||||
$sql .= $class->getQuotedColumnName($fieldName, $this->_platform);
|
||||
$column .= $class->getQuotedColumnName($fieldName, $this->_platform);
|
||||
|
||||
if ($this->_useDbalTypeValueSql && !$class->isIdentifier($fieldName)) {
|
||||
$type = Type::getType($class->getTypeOfField($fieldName));
|
||||
$column = $type->convertToPHPValueSQL($column, $this->_conn->getDatabasePlatform());
|
||||
}
|
||||
|
||||
$sql .= $column;
|
||||
break;
|
||||
|
||||
case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION:
|
||||
@ -1002,9 +1024,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 (!$class->isIdentifier($fieldName)) {
|
||||
$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 +1115,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 (!$class->isIdentifier($fieldName)) {
|
||||
$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 +1144,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 (!$subClass->isIdentifier($fieldName)) {
|
||||
$type = Type::getType($subClass->getTypeOfField($fieldName));
|
||||
$col = $type->convertToPHPValueSQL($col, $this->_platform);
|
||||
}
|
||||
|
||||
$sqlParts[] = $col . ' AS ' . $columnAlias;
|
||||
|
||||
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName);
|
||||
}
|
||||
@ -1386,7 +1429,18 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
switch (true) {
|
||||
case ($newValue instanceof AST\Node):
|
||||
$currentColumnTypeBefore = $this->_currentColumnType;
|
||||
$this->_currentColumnType = null;
|
||||
|
||||
if ($updateItem->pathExpression->type == AST\PathExpression::TYPE_STATE_FIELD) {
|
||||
$class = $this->_queryComponents[$updateItem->pathExpression->identificationVariable]['metadata'];
|
||||
if (!$class->isIdentifier($updateItem->pathExpression->field)) {
|
||||
$this->_currentColumnType = $class->getTypeOfField($updateItem->pathExpression->field);
|
||||
}
|
||||
}
|
||||
|
||||
$sql .= $newValue->dispatch($this);
|
||||
$this->_currentColumnType = $currentColumnTypeBefore;
|
||||
break;
|
||||
|
||||
case ($newValue === null):
|
||||
@ -1759,20 +1813,30 @@ class SqlWalker implements TreeWalker
|
||||
{
|
||||
switch ($literal->type) {
|
||||
case AST\Literal::STRING:
|
||||
return $this->_conn->quote($literal->value);
|
||||
$value = $this->_conn->quote($literal->value);
|
||||
break;
|
||||
|
||||
case AST\Literal::BOOLEAN:
|
||||
$bool = strtolower($literal->value) == 'true' ? true : false;
|
||||
$boolVal = $this->_conn->getDatabasePlatform()->convertBooleans($bool);
|
||||
|
||||
return $boolVal;
|
||||
$value = $boolVal;
|
||||
break;
|
||||
|
||||
case AST\Literal::NUMERIC:
|
||||
return $literal->value;
|
||||
$value = $literal->value;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw QueryException::invalidLiteral($literal);
|
||||
}
|
||||
|
||||
if ($this->_currentColumnType !== null) {
|
||||
$type = Type::getType($this->_currentColumnType);
|
||||
$value = $type->convertToDatabaseValueSQL($value, $this->_conn->getDatabasePlatform());
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
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 . ') * -1)';
|
||||
}
|
||||
}
|
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="negative_to_positive")
|
||||
* @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="negative_to_positive")
|
||||
* @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;
|
||||
}
|
104
tests/Doctrine/Tests/ORM/Functional/TypeValueSqlTest.php
Normal file
104
tests/Doctrine/Tests/ORM/Functional/TypeValueSqlTest.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?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 . " AND p.customInteger = -1");
|
||||
|
||||
$result = $query->getResult();
|
||||
|
||||
$this->assertEquals(1, count($result));
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\CustomType\CustomTypeParent', $result[0][0]);
|
||||
|
||||
$this->assertEquals(-1, $result[0]['customInteger']);
|
||||
|
||||
$this->assertEquals('foo', $result[0][0]->child->lowerCaseString);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?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();
|
||||
|
||||
$this->_em = $this->_getTestEntityManager();
|
||||
|
||||
$this->_persister = new BasicEntityPersister($this->_em, $this->_em->getClassMetadata("Doctrine\Tests\Models\CustomType\CustomTypeParent"));
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
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,48 @@ 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) * -1) 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) * -1) 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,20 @@ 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 testCustomTypeValueSql()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'UPDATE Doctrine\Tests\Models\CustomType\CustomTypeParent p SET p.customInteger = 1 WHERE p.id = 1',
|
||||
'UPDATE customtype_parents SET customInteger = ABS(1) WHERE id = 1'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCustomTypeValueSqlIgnoresIdentifierColumns()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'UPDATE Doctrine\Tests\Models\CustomType\CustomTypeParent p SET p.id = 2 WHERE p.id = 1',
|
||||
'UPDATE customtype_parents SET id = 2 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…
x
Reference in New Issue
Block a user