Geometry タイプを Doctrine に追加しようとしています。私の Doctrine DBAL バージョンと ORM バージョンは 2.1.7 です。
ここの指示に従おうとしました: Doctrine 2 Types - Custom Mapping Types。
新しいデータ型は正常に作成されましたが、convertToPHPValueSQL メソッドに問題があります。データベースからジオメトリ列を取得するときに、関数 ST_AsText(' .. ') が常に呼び出されるようにします (データベースは PostgreSQL 9.1 + PostGIS 2.0.0 です)。
Doctrine DBAL 2.1のドキュメントには次のように書かれています:
Doctrine-DBAL の仕事は、型を SQL 宣言に変換することです。Doctrine が生成する SQL 宣言を変更できます。最初に、canRequireSQLConversion メソッドをオーバーライドして、この機能を有効にする必要があります。
<?php
public function canRequireSQLConversion()
{
return true;
}
次に、メソッド convertToPhpValueSQL および convertToDatabaseValueSQL をオーバーライドします。
<?php
public function convertToPHPValueSQL($sqlExpr, $platform)
{
return 'MyMoneyFunction(\''.$sqlExpr.'\') ';
}
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
{
return 'MyFunction('.$sqlExpr.')';
}
次に、このタイプを Doctrine Type システムに登録し、データベース プラットフォームにフックする必要があります。
<?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 = ?
canRequireSQLConversion() は true を返しますが、Doctrine は私の convertToPHPValueSQL メソッドを使用しません。さらに、canRequireSQLConversion() が呼び出されても呼び出されないかどうかを確認するためのデバッグ コードを追加しました。私は何を間違っていますか?
PS: Stack Overflow を検索しようとしましたが、既に読んだ Doctrine 2.1.x マニュアルにリンクしているDoctrine 2 の GIS 拡張しか思いつきませんでした。
編集: ここで読みます: http://docs.doctrine-project.org/en/latest/cookbook/advanced-field-value-conversion-using-custom-mapping-types.html
EDIT2: 私のコードで間違っていた関数 getSqlDeclaration() を修正しました。コメントを追加しました。
より完全なチュートリアルのようです。