gpt4 book ai didi

orm - 在 Doctrine 2.1.7 中添加自定义数据类型(几何)。未调用方法 canRequireSQLConversion()

转载 作者:行者123 更新时间:2023-12-04 23:58:09 24 4
gpt4 key购买 nike

我正在尝试将几何类型添加到 Doctrine。我的 Doctrine DBAL 版本和 ORM 版本是 2.1.7。

我尝试按照此处的说明进行操作:
Doctrine 2 Types - Custom Mapping Types .

我成功创建了新的数据类型,但是 convertToPHPValueSQL 方法有问题。我希望在从数据库(数据库是 PostgreSQL 9.1 + PostGIS 2.0.0)获取几何列时始终调用函数 ST_AsText(' .. ')。

Doctrine DBAL 2.1 文档是这样说的:

The job of Doctrine-DBAL is to transform your type into SQL declaration. You can modify the SQL declaration Doctrine will produce. At first, you must to enable this feature by overriding the canRequireSQLConversion method:



<?php
public function canRequireSQLConversion()
{
return true;
}

Then you override the methods convertToPhpValueSQL and convertToDatabaseValueSQL :



<?php
public function convertToPHPValueSQL($sqlExpr, $platform)
{
return 'MyMoneyFunction(\''.$sqlExpr.'\') ';
}

public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
{
return 'MyFunction('.$sqlExpr.')';
}

Now we have to register this type with the Doctrine Type system and hook it into the database platform:



<?php
Type::addType('money', 'My\Project\Types\MoneyType');
$conn->getDatabasePlatform()->registerDoctrineTypeMapping('MyMoney', 'money');

我确实喜欢这个(很多代码是占位符代码,但如果我做了一些愚蠢的事情,欢迎所有建议):

<?php

namespace Minupeenrad\Types;

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

/**
* Class for database column "geometry".
*
* @author Rauni Lillemets
*/
class GeometryType extends Type {
const GEOMETRY = 'geometry';
const SRID = 3301;

public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) {
return 'geometry';
}

//Should create WKT object from WKT string. (or leave as WKT string)
public function convertToPHPValue($value, AbstractPlatform $platform) {
return $value; //+
}

//Should create WKT string from WKT object. (or leave as WKT string)
public function convertToDatabaseValue($value, AbstractPlatform $platform) {
return $value; //+
}

public function getName() {
return self::GEOMETRY;
}

public function canRequireSQLConversion() {
return true;
}

//Should give WKT
public function convertToPHPValueSQL($sqlExpr, $platform) {
return 'ST_AsText(\''.$sqlExpr.'\') '; //+
}

//Should create WKB
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) {
return 'ST_GeomFromText(\''.$sqlExpr.'\', '.self::SRID.')'; //+
}
}

现在我添加了使用此列的实体:

<?php
namespace Minupeenrad\Entities;

/**
* Field
*
* @author Rauni Lillemets
* @Entity
* @Table(name="myfields.fields")
*/
class Field extends GeometryObject {
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
private $id;

/**
* @ManyToOne(targetEntity="User")
*/
private $user;

/**
* @Column(type = "string", length = "40")
*/
private $fieldNumber;

public function getId() {
return $this->id;
}

public function getUser() {
return $this->user;
}

public function setUser($user) {
$this->user = $user;
}

public function getFieldNumber() {
return $this->fieldNumber;
}

public function setFieldNumber($fieldNumber) {
$this->fieldNumber = $fieldNumber;
}
}
?>

但如果我这样做:

$entity = $em->find('\Minupeenrad\Entities\Field', 1);

Doctrine 对数据库执行 SQL 请求,如下所示:

SELECT t0.id AS id1, t0.fieldNumber AS fieldnumber2, t0.geometry AS geometry3, t0.user_id AS user_id4
FROM myfields.fields t0
WHERE t0.id = ?

Doctrine 没有使用我的 convertToPHPValueSQL 方法,尽管 canRequireSQLConversion() 返回 true。此外,我添加了一些调试代码以查看是否甚至调用了 canRequireSQLConversion() ,并且没有调用它。我究竟做错了什么?

PS:我试图搜索堆栈溢出,但我只想出了 GIS extension for Doctrine 2 ,它链接到我已经阅读过的 Doctrine 2.1.x 手册。

编辑:我会在这里阅读: http://docs.doctrine-project.org/en/latest/cookbook/advanced-field-value-conversion-using-custom-mapping-types.html

EDIT2:修复了函数 getSqlDeclaration(),这在我的代码中是错误的。添加了评论。

这似乎是一个更完整的教程。

最佳答案

找到了答案。

在 Doctrine 2.1.7 中,如果我使用 $em->find(),最终会调用 BasicEntityPersister()_getSelectColumnSQL()。它有以下代码:(取自 https://github.com/doctrine/doctrine2/blob/2.1.x/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php )

/**
* Gets the SQL snippet of a qualified column name for the given field name.
*
* @param string $field The field name.
* @param ClassMetadata $class The class that declares this field. The table this class is
* mapped to must own the column for the given field.
* @param string $alias
*/
protected function _getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r')
{
$columnName = $class->columnNames[$field];
$sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias) . '.' . $class->getQuotedColumnName($field, $this->_platform);
$columnAlias = $this->_platform->getSQLResultCasing($columnName . $this->_sqlAliasCounter++);
$this->_rsm->addFieldResult($alias, $columnAlias, $field);

return "$sql AS $columnAlias";
}

这段代码显然不尊重方法“canRequireSQLConversion”

在最新的 Doctrine 版本 2.3.1 中(参见 https://github.com/doctrine/doctrine2/blob/2.3/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php ):
/**
* Gets the SQL snippet of a qualified column name for the given field name.
*
* @param string $field The field name.
* @param ClassMetadata $class The class that declares this field. The table this class is
* mapped to must own the column for the given field.
* @param string $alias
*/
protected function _getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r')
{
$sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias)
. '.' . $this->quoteStrategy->getColumnName($field, $class, $this->_platform);
$columnAlias = $this->getSQLColumnAlias($class->columnNames[$field]);

$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;
}

所以答案是更新我的ORM。

关于orm - 在 Doctrine 2.1.7 中添加自定义数据类型(几何)。未调用方法 canRequireSQLConversion(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14154502/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com