From a515bd07a71b9eda8c9f62202fa233d7cceafe8e Mon Sep 17 00:00:00 2001 From: Benjamin Morel Date: Wed, 7 Feb 2024 22:47:53 +0100 Subject: [PATCH 1/3] Upgrade to doctrine/orm v3 & doctrine/dbal v4 --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 11 +++++++ composer.json | 10 +++--- src/Functions/AbstractFunction.php | 10 +++--- src/Types/GeometryCollectionType.php | 2 +- src/Types/GeometryType.php | 33 +++++++++---------- src/Types/LineStringType.php | 2 +- src/Types/MultiLineStringType.php | 2 +- src/Types/MultiPointType.php | 2 +- src/Types/MultiPolygonType.php | 2 +- src/Types/PointType.php | 2 +- src/Types/PolygonType.php | 2 +- tests/DataFixtures/LoadGeometryData.php | 2 +- tests/DataFixtures/LoadLineStringData.php | 2 +- .../DataFixtures/LoadMultiLineStringData.php | 2 +- tests/DataFixtures/LoadMultiPointData.php | 2 +- tests/DataFixtures/LoadMultiPolygonData.php | 2 +- tests/DataFixtures/LoadPointData.php | 2 +- tests/DataFixtures/LoadPolygonData.php | 2 +- tests/Fixtures/GeometryEntity.php | 32 +++++------------- tests/Fixtures/LineStringEntity.php | 32 +++++------------- tests/Fixtures/MultiLineStringEntity.php | 32 +++++------------- tests/Fixtures/MultiPointEntity.php | 32 +++++------------- tests/Fixtures/MultiPolygonEntity.php | 32 +++++------------- tests/Fixtures/PointEntity.php | 32 +++++------------- tests/Fixtures/PolygonEntity.php | 32 +++++------------- tests/FunctionalTestCase.php | 13 ++++---- tests/Types/GeometryTypeTest.php | 2 +- tests/Types/LineStringTypeTest.php | 2 +- tests/Types/MultiLineStringTypeTest.php | 2 +- tests/Types/MultiPointTypeTest.php | 2 +- tests/Types/MultiPolygonTypeTest.php | 2 +- tests/Types/PointTypeTest.php | 2 +- tests/Types/PolygonTypeTest.php | 2 +- 34 files changed, 121 insertions(+), 224 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 672c5cc..f0744ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: services: mariadb: - image: "mariadb:10.1" + image: "mariadb:10.11" env: MYSQL_ALLOW_EMPTY_PASSWORD: yes options: >- diff --git a/CHANGELOG.md b/CHANGELOG.md index 432fa14..1d5fb7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [0.4.0](https://github.com/brick/geo-doctrine/releases/tag/0.4.0) - 2024-12-19 + +💥 **Breaking changes** + +- compatibility with `doctrine/orm` `3.x` (`2.x` is no longer supported) +- compatibility with `doctrine/dbal` `4.x` (`2.x` and `3.x` are no longer supported) + +🐛 **Bug fixes** + +- `GeometryType::convertToDatabaseValue()` now properly throws `ConversionException` as it should + ## [0.3.1](https://github.com/brick/geo-doctrine/releases/tag/0.3.1) - 2024-06-07 ✨ **Upgrades** diff --git a/composer.json b/composer.json index 57e160f..504e0d3 100644 --- a/composer.json +++ b/composer.json @@ -11,16 +11,18 @@ "require": { "php": "^8.1", "brick/geo": "~0.10.0 || ~0.11.0", - "doctrine/orm": "^2.8" + "doctrine/dbal": "^4.0", + "doctrine/orm": "^3.0" }, "require-dev": { - "doctrine/annotations": "^1.0", + "ext-pdo": "*", "doctrine/cache": "^1.11", - "doctrine/data-fixtures": "^1.0", + "doctrine/data-fixtures": "^1.7", "guzzlehttp/guzzle": "^7.0", "phpunit/phpunit": "^10.5", "php-coveralls/php-coveralls": "^2.7", - "vimeo/psalm": "5.21.1" + "vimeo/psalm": "5.21.1", + "symfony/cache": "^5.0 || ^6.0 || ^7.0" }, "autoload": { "psr-4": { diff --git a/src/Functions/AbstractFunction.php b/src/Functions/AbstractFunction.php index 1fee6e1..6280113 100644 --- a/src/Functions/AbstractFunction.php +++ b/src/Functions/AbstractFunction.php @@ -5,9 +5,9 @@ namespace Brick\Geo\Doctrine\Functions; use Doctrine\ORM\Query\AST\Functions\FunctionNode; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * Base class for Doctrine functions. @@ -44,20 +44,20 @@ public function parse(Parser $parser) : void { $this->args = []; - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $parameterCount = $this->getParameterCount(); for ($i = 0; $i < $parameterCount; $i++) { if ($i !== 0) { - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); } /** @psalm-suppress InvalidPropertyAssignmentValue */ $this->args[] = $parser->ArithmeticPrimary(); } - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Types/GeometryCollectionType.php b/src/Types/GeometryCollectionType.php index 8aedd4f..0c11f67 100644 --- a/src/Types/GeometryCollectionType.php +++ b/src/Types/GeometryCollectionType.php @@ -11,7 +11,7 @@ */ class GeometryCollectionType extends GeometryType { - public function getName() : string + protected function getGeometryName() : string { return 'GeometryCollection'; } diff --git a/src/Types/GeometryType.php b/src/Types/GeometryType.php index a12918d..c2fe7da 100644 --- a/src/Types/GeometryType.php +++ b/src/Types/GeometryType.php @@ -4,13 +4,16 @@ namespace Brick\Geo\Doctrine\Types; +use Brick\DateTime\LocalDateTime; use Brick\Geo\Geometry; use Brick\Geo\IO\WKBReader; use Brick\Geo\Proxy\GeometryProxy; use Brick\Geo\Proxy\ProxyInterface; +use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Platforms\AbstractMySQLPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform; +use Doctrine\DBAL\Types\Exception\InvalidType; use Doctrine\DBAL\Types\Type; /** @@ -50,7 +53,7 @@ protected function hasKnownSubclasses() : bool return true; } - public function getName() : string + protected function getGeometryName() : string { return 'Geometry'; } @@ -58,10 +61,10 @@ public function getName() : string public function getSQLDeclaration(array $column, AbstractPlatform $platform) : string { if ($platform instanceof PostgreSQLPlatform) { - return 'GEOMETRY'; + return 'Geometry'; } - return strtoupper($this->getName()); + return $this->getGeometryName(); } public function convertToPHPValue($value, AbstractPlatform $platform) : ?Geometry @@ -99,10 +102,14 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform) : ?st return $value->asBinary(); } - throw new \UnexpectedValueException(sprintf('Expected %s, got %s.', Geometry::class, get_debug_type($value))); + throw InvalidType::new( + $value, + static::class, + [Geometry::class, 'null'], + ); } - public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) : string + public function convertToDatabaseValueSQL(string $sqlExpr, AbstractPlatform $platform) : string { if ($platform instanceof AbstractMySQLPlatform) { $sqlExpr = sprintf('BINARY %s', $sqlExpr); @@ -111,23 +118,13 @@ public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) return sprintf('ST_GeomFromWKB(%s, %d)', $sqlExpr, self::$srid); } - public function convertToPHPValueSQL($sqlExpr, $platform) : string + public function convertToPHPValueSQL(string $sqlExpr, AbstractPlatform $platform) : string { return sprintf('ST_AsBinary(%s)', $sqlExpr); } - public function canRequireSQLConversion() : bool + public function getBindingType() : ParameterType { - return true; - } - - public function requiresSQLCommentHint(AbstractPlatform $platform) : bool - { - return true; - } - - public function getBindingType() : int - { - return \PDO::PARAM_LOB; + return ParameterType::LARGE_OBJECT; } } diff --git a/src/Types/LineStringType.php b/src/Types/LineStringType.php index 0b2fe6b..1a37b25 100644 --- a/src/Types/LineStringType.php +++ b/src/Types/LineStringType.php @@ -11,7 +11,7 @@ */ class LineStringType extends GeometryType { - public function getName() : string + protected function getGeometryName() : string { return 'LineString'; } diff --git a/src/Types/MultiLineStringType.php b/src/Types/MultiLineStringType.php index 657568c..462873c 100644 --- a/src/Types/MultiLineStringType.php +++ b/src/Types/MultiLineStringType.php @@ -11,7 +11,7 @@ */ class MultiLineStringType extends GeometryType { - public function getName() : string + protected function getGeometryName() : string { return 'MultiLineString'; } diff --git a/src/Types/MultiPointType.php b/src/Types/MultiPointType.php index 618147e..6a4b18b 100644 --- a/src/Types/MultiPointType.php +++ b/src/Types/MultiPointType.php @@ -11,7 +11,7 @@ */ class MultiPointType extends GeometryType { - public function getName() : string + protected function getGeometryName() : string { return 'MultiPoint'; } diff --git a/src/Types/MultiPolygonType.php b/src/Types/MultiPolygonType.php index 005df00..197a7c2 100644 --- a/src/Types/MultiPolygonType.php +++ b/src/Types/MultiPolygonType.php @@ -11,7 +11,7 @@ */ class MultiPolygonType extends GeometryType { - public function getName() : string + protected function getGeometryName() : string { return 'MultiPolygon'; } diff --git a/src/Types/PointType.php b/src/Types/PointType.php index 5f371d5..1919676 100644 --- a/src/Types/PointType.php +++ b/src/Types/PointType.php @@ -11,7 +11,7 @@ */ class PointType extends GeometryType { - public function getName() : string + protected function getGeometryName() : string { return 'Point'; } diff --git a/src/Types/PolygonType.php b/src/Types/PolygonType.php index eab6a35..31ada86 100644 --- a/src/Types/PolygonType.php +++ b/src/Types/PolygonType.php @@ -11,7 +11,7 @@ */ class PolygonType extends GeometryType { - public function getName() : string + protected function getGeometryName() : string { return 'Polygon'; } diff --git a/tests/DataFixtures/LoadGeometryData.php b/tests/DataFixtures/LoadGeometryData.php index de6fc46..094fdcc 100644 --- a/tests/DataFixtures/LoadGeometryData.php +++ b/tests/DataFixtures/LoadGeometryData.php @@ -15,7 +15,7 @@ class LoadGeometryData implements FixtureInterface public function load(ObjectManager $manager): void { $point1 = new GeometryEntity(); - $point1->setGeometry(Point::xy(1, 2)); + $point1->geometry = Point::xy(1, 2); $manager->persist($point1); $manager->flush(); diff --git a/tests/DataFixtures/LoadLineStringData.php b/tests/DataFixtures/LoadLineStringData.php index c6d21cf..45f1697 100644 --- a/tests/DataFixtures/LoadLineStringData.php +++ b/tests/DataFixtures/LoadLineStringData.php @@ -20,7 +20,7 @@ public function load(ObjectManager $manager): void $point3 = Point::xy(1,1); $lineString1 = new LineStringEntity(); - $lineString1->setLineString(LineString::of($point1, $point2, $point3)); + $lineString1->lineString = LineString::of($point1, $point2, $point3); $manager->persist($lineString1); $manager->flush(); diff --git a/tests/DataFixtures/LoadMultiLineStringData.php b/tests/DataFixtures/LoadMultiLineStringData.php index 57cc1c2..dbcb817 100644 --- a/tests/DataFixtures/LoadMultiLineStringData.php +++ b/tests/DataFixtures/LoadMultiLineStringData.php @@ -27,7 +27,7 @@ public function load(ObjectManager $manager): void $lineString2 = LineString::of($point4, $point5, $point6); $multilineString1 = new MultiLineStringEntity(); - $multilineString1->setMultiLineString(MultiLineString::of($lineString1, $lineString2)); + $multilineString1->multiLineString = MultiLineString::of($lineString1, $lineString2); $manager->persist($multilineString1); $manager->flush(); diff --git a/tests/DataFixtures/LoadMultiPointData.php b/tests/DataFixtures/LoadMultiPointData.php index 337055a..38caea8 100644 --- a/tests/DataFixtures/LoadMultiPointData.php +++ b/tests/DataFixtures/LoadMultiPointData.php @@ -20,7 +20,7 @@ public function load(ObjectManager $manager): void $point3 = Point::xy(1,1); $multiPoint1 = new MultiPointEntity(); - $multiPoint1->setMultiPoint(MultiPoint::of($point1, $point2, $point3)); + $multiPoint1->multiPoint = MultiPoint::of($point1, $point2, $point3); $manager->persist($multiPoint1); $manager->flush(); diff --git a/tests/DataFixtures/LoadMultiPolygonData.php b/tests/DataFixtures/LoadMultiPolygonData.php index 95ea702..fb0dedb 100644 --- a/tests/DataFixtures/LoadMultiPolygonData.php +++ b/tests/DataFixtures/LoadMultiPolygonData.php @@ -36,7 +36,7 @@ public function load(ObjectManager $manager): void $poly2 = Polygon::of($ring2); $multiPoly1 = new MultiPolygonEntity(); - $multiPoly1->setMultiPolygon(MultiPolygon::of($poly1, $poly2)); + $multiPoly1->multiPolygon = MultiPolygon::of($poly1, $poly2); $manager->persist($multiPoly1); $manager->flush(); diff --git a/tests/DataFixtures/LoadPointData.php b/tests/DataFixtures/LoadPointData.php index 742a954..648e0d4 100644 --- a/tests/DataFixtures/LoadPointData.php +++ b/tests/DataFixtures/LoadPointData.php @@ -15,7 +15,7 @@ class LoadPointData implements FixtureInterface public function load(ObjectManager $manager): void { $point1 = new PointEntity(); - $point1->setPoint(Point::xy(0, 0)); + $point1->point = Point::xy(0, 0); $manager->persist($point1); $manager->flush(); diff --git a/tests/DataFixtures/LoadPolygonData.php b/tests/DataFixtures/LoadPolygonData.php index 18f008c..86f28b6 100644 --- a/tests/DataFixtures/LoadPolygonData.php +++ b/tests/DataFixtures/LoadPolygonData.php @@ -25,7 +25,7 @@ public function load(ObjectManager $manager): void $ring = LineString::of($point1, $point2, $point3, $point4, $point5); $poly1 = new PolygonEntity(); - $poly1->setPolygon(Polygon::of($ring)); + $poly1->polygon = Polygon::of($ring); $manager->persist($poly1); $manager->flush(); diff --git a/tests/Fixtures/GeometryEntity.php b/tests/Fixtures/GeometryEntity.php index 94f44c8..5ba11c8 100644 --- a/tests/Fixtures/GeometryEntity.php +++ b/tests/Fixtures/GeometryEntity.php @@ -5,32 +5,16 @@ namespace Brick\Geo\Doctrine\Tests\Fixtures; use Brick\Geo\Geometry; +use Doctrine\ORM\Mapping as ORM; -/** - * @Entity - * @Table(name="geometries") - */ +#[ORM\Entity] class GeometryEntity { - /** - * @Id - * @Column(type="integer") - * @GeneratedValue - */ - private int $id; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + public int $id; - /** - * @Column(type="Geometry") - */ - private Geometry $geometry; - - public function getGeometry() : Geometry - { - return $this->geometry; - } - - public function setGeometry(Geometry $geometry) : void - { - $this->geometry = $geometry; - } + #[ORM\Column(type: 'Geometry')] + public Geometry $geometry; } diff --git a/tests/Fixtures/LineStringEntity.php b/tests/Fixtures/LineStringEntity.php index d719808..58289c7 100644 --- a/tests/Fixtures/LineStringEntity.php +++ b/tests/Fixtures/LineStringEntity.php @@ -5,32 +5,16 @@ namespace Brick\Geo\Doctrine\Tests\Fixtures; use Brick\Geo\LineString; +use Doctrine\ORM\Mapping as ORM; -/** - * @Entity - * @Table(name="linestrings") - */ +#[ORM\Entity] class LineStringEntity { - /** - * @Id - * @Column(type="integer") - * @GeneratedValue - */ - private int $id; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + public int $id; - /** - * @Column(type="LineString") - */ - private LineString $lineString; - - public function getLineString() : LineString - { - return $this->lineString; - } - - public function setLineString(LineString $lineString) : void - { - $this->lineString = $lineString; - } + #[ORM\Column(type: 'LineString')] + public LineString $lineString; } diff --git a/tests/Fixtures/MultiLineStringEntity.php b/tests/Fixtures/MultiLineStringEntity.php index 4639133..b87cbc9 100644 --- a/tests/Fixtures/MultiLineStringEntity.php +++ b/tests/Fixtures/MultiLineStringEntity.php @@ -5,32 +5,16 @@ namespace Brick\Geo\Doctrine\Tests\Fixtures; use Brick\Geo\MultiLineString; +use Doctrine\ORM\Mapping as ORM; -/** - * @Entity - * @Table(name="multilinestrings") - */ +#[ORM\Entity] class MultiLineStringEntity { - /** - * @Id - * @Column(type="integer") - * @GeneratedValue - */ - private int $id; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + public int $id; - /** - * @Column(type="MultiLineString") - */ - private MultiLineString $multiLineString; - - public function getMultiLineString() : MultiLineString - { - return $this->multiLineString; - } - - public function setMultiLineString(MultiLineString $multiLineString) : void - { - $this->multiLineString = $multiLineString; - } + #[ORM\Column(type: 'MultiLineString')] + public MultiLineString $multiLineString; } diff --git a/tests/Fixtures/MultiPointEntity.php b/tests/Fixtures/MultiPointEntity.php index c340807..0f95600 100644 --- a/tests/Fixtures/MultiPointEntity.php +++ b/tests/Fixtures/MultiPointEntity.php @@ -5,32 +5,16 @@ namespace Brick\Geo\Doctrine\Tests\Fixtures; use Brick\Geo\MultiPoint; +use Doctrine\ORM\Mapping as ORM; -/** - * @Entity - * @Table(name="multipoints") - */ +#[ORM\Entity] class MultiPointEntity { - /** - * @Id - * @Column(type="integer") - * @GeneratedValue - */ - private int $id; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + public int $id; - /** - * @Column(type="MultiPoint") - */ - private MultiPoint $multiPoint; - - public function getMultiPoint() : MultiPoint - { - return $this->multiPoint; - } - - public function setMultiPoint(MultiPoint $multiPoint) : void - { - $this->multiPoint = $multiPoint; - } + #[ORM\Column(type: 'MultiPoint')] + public MultiPoint $multiPoint; } diff --git a/tests/Fixtures/MultiPolygonEntity.php b/tests/Fixtures/MultiPolygonEntity.php index bbf3b77..116c2d5 100644 --- a/tests/Fixtures/MultiPolygonEntity.php +++ b/tests/Fixtures/MultiPolygonEntity.php @@ -5,32 +5,16 @@ namespace Brick\Geo\Doctrine\Tests\Fixtures; use Brick\Geo\MultiPolygon; +use Doctrine\ORM\Mapping as ORM; -/** - * @Entity - * @Table(name="multipolygons") - */ +#[ORM\Entity] class MultiPolygonEntity { - /** - * @Id - * @Column(type="integer") - * @GeneratedValue - */ - private int $id; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + public int $id; - /** - * @Column(type="MultiPolygon") - */ - private MultiPolygon $multiPolygon; - - public function getMultiPolygon() : MultiPolygon - { - return $this->multiPolygon; - } - - public function setMultiPolygon(MultiPolygon $multiPolygon) : void - { - $this->multiPolygon = $multiPolygon; - } + #[ORM\Column(type: 'MultiPolygon')] + public MultiPolygon $multiPolygon; } diff --git a/tests/Fixtures/PointEntity.php b/tests/Fixtures/PointEntity.php index 2fce628..151902a 100644 --- a/tests/Fixtures/PointEntity.php +++ b/tests/Fixtures/PointEntity.php @@ -5,32 +5,16 @@ namespace Brick\Geo\Doctrine\Tests\Fixtures; use Brick\Geo\Point; +use Doctrine\ORM\Mapping as ORM; -/** - * @Entity - * @Table(name="points") - */ +#[ORM\Entity] class PointEntity { - /** - * @Id - * @Column(type="integer") - * @GeneratedValue - */ - private int $id; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + public int $id; - /** - * @Column(type="Point") - */ - private Point $point; - - public function getPoint() : Point - { - return $this->point; - } - - public function setPoint(Point $point) : void - { - $this->point = $point; - } + #[ORM\Column(type: 'Point')] + public Point $point; } diff --git a/tests/Fixtures/PolygonEntity.php b/tests/Fixtures/PolygonEntity.php index 3b117a9..c07910a 100644 --- a/tests/Fixtures/PolygonEntity.php +++ b/tests/Fixtures/PolygonEntity.php @@ -5,32 +5,16 @@ namespace Brick\Geo\Doctrine\Tests\Fixtures; use Brick\Geo\Polygon; +use Doctrine\ORM\Mapping as ORM; -/** - * @Entity - * @Table(name="polygons") - */ +#[ORM\Entity] class PolygonEntity { - /** - * @Id - * @Column(type="integer") - * @GeneratedValue - */ - private int $id; + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue] + public int $id; - /** - * @Column(type="Polygon") - */ - private Polygon $polygon; - - public function getPolygon() : Polygon - { - return $this->polygon; - } - - public function setPolygon(Polygon $polygon) : void - { - $this->polygon = $polygon; - } + #[ORM\Column(type: 'Polygon')] + public Polygon $polygon; } diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index 76a5fab..54c271a 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -13,9 +13,10 @@ use Doctrine\Common\DataFixtures\Purger\ORMPurger; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use Doctrine\ORM\EntityManager; +use Doctrine\ORM\ORMSetup; use Doctrine\ORM\Tools\SchemaTool; -use Doctrine\ORM\Tools\Setup; use PHPUnit\Framework\TestCase; /** @@ -48,17 +49,15 @@ protected function setUp(): void $this->platform->registerDoctrineTypeMapping('point', 'binary'); $this->platform->registerDoctrineTypeMapping('polygon', 'binary'); - switch ($this->platform->getName()) { - case 'postgresql': - $this->connection->executeQuery('CREATE EXTENSION IF NOT EXISTS postgis;'); - break; + if ($this->platform instanceof PostgreSQLPlatform) { + $this->connection->executeQuery('CREATE EXTENSION IF NOT EXISTS postgis;'); } $this->fixtureLoader = new Loader(); - $config = Setup::createAnnotationMetadataConfiguration([__DIR__ . '/Fixtures'], false); + $config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/Fixtures']); - $this->em = EntityManager::create($this->connection, $config, $this->platform->getEventManager()); + $this->em = new EntityManager($this->connection, $config); $schemaTool = new SchemaTool($this->em); $schemaTool->updateSchema([ diff --git a/tests/Types/GeometryTypeTest.php b/tests/Types/GeometryTypeTest.php index 6caa939..faaf776 100644 --- a/tests/Types/GeometryTypeTest.php +++ b/tests/Types/GeometryTypeTest.php @@ -30,7 +30,7 @@ public function testReadFromDbAndConvertToPHPValue() : void $geometryEntity = $repository->findOneBy(['id' => 1]); self::assertNotNull($geometryEntity); - $geometry = $geometryEntity->getGeometry(); + $geometry = $geometryEntity->geometry; self::assertInstanceOf(Point::class, $geometry); self::assertInstanceOf(ProxyInterface::class, $geometry); diff --git a/tests/Types/LineStringTypeTest.php b/tests/Types/LineStringTypeTest.php index c1c0edd..7c45769 100644 --- a/tests/Types/LineStringTypeTest.php +++ b/tests/Types/LineStringTypeTest.php @@ -29,7 +29,7 @@ public function testReadFromDbAndConvertToPHPValue() : void $lineStringEntity = $repository->findOneBy(['id' => 1]); self::assertNotNull($lineStringEntity); - $lineString = $lineStringEntity->getLineString(); + $lineString = $lineStringEntity->lineString; self::assertInstanceOf(LineString::class, $lineString); self::assertSame(3, $lineString->numPoints()); diff --git a/tests/Types/MultiLineStringTypeTest.php b/tests/Types/MultiLineStringTypeTest.php index 0da162c..c0f73bf 100644 --- a/tests/Types/MultiLineStringTypeTest.php +++ b/tests/Types/MultiLineStringTypeTest.php @@ -30,7 +30,7 @@ public function testReadFromDbAndConvertToPHPValue() : void $multiLineStringEntity = $repository->findOneBy(['id' => 1]); self::assertNotNull($multiLineStringEntity); - $multiLineString = $multiLineStringEntity->getMultiLineString(); + $multiLineString = $multiLineStringEntity->multiLineString; self::assertInstanceOf(MultiLineString::class, $multiLineString); self::assertSame(2, $multiLineString->numGeometries()); diff --git a/tests/Types/MultiPointTypeTest.php b/tests/Types/MultiPointTypeTest.php index 284d588..9999702 100644 --- a/tests/Types/MultiPointTypeTest.php +++ b/tests/Types/MultiPointTypeTest.php @@ -30,7 +30,7 @@ public function testReadFromDbAndConvertToPHPValue() : void $multiPointEntity = $repository->findOneBy(['id' => 1]); self::assertNotNull($multiPointEntity); - $multiPoint = $multiPointEntity->getMultiPoint(); + $multiPoint = $multiPointEntity->multiPoint; self::assertInstanceOf(MultiPoint::class, $multiPoint); self::assertSame(3, $multiPoint->numGeometries()); diff --git a/tests/Types/MultiPolygonTypeTest.php b/tests/Types/MultiPolygonTypeTest.php index e6de5b8..42d8ea3 100644 --- a/tests/Types/MultiPolygonTypeTest.php +++ b/tests/Types/MultiPolygonTypeTest.php @@ -31,7 +31,7 @@ public function testReadFromDbAndConvertToPHPValue() : void $multiPolygonEntity = $repository->findOneBy(['id' => 1]); self::assertNotNull($multiPolygonEntity); - $multiPolygon = $multiPolygonEntity->getMultiPolygon(); + $multiPolygon = $multiPolygonEntity->multiPolygon; self::assertInstanceOf(MultiPolygon::class, $multiPolygon); self::assertSame(2, $multiPolygon->numGeometries()); diff --git a/tests/Types/PointTypeTest.php b/tests/Types/PointTypeTest.php index 4c4a7b2..3b1024f 100644 --- a/tests/Types/PointTypeTest.php +++ b/tests/Types/PointTypeTest.php @@ -28,7 +28,7 @@ public function testReadFromDbAndConvertToPHPValue() : void $pointEntity = $repository->findOneBy([]); self::assertNotNull($pointEntity); - $point = $pointEntity->getPoint(); + $point = $pointEntity->point; $this->assertPointEquals($point, 0.0, 0.0); } } diff --git a/tests/Types/PolygonTypeTest.php b/tests/Types/PolygonTypeTest.php index f752c85..0cac29c 100644 --- a/tests/Types/PolygonTypeTest.php +++ b/tests/Types/PolygonTypeTest.php @@ -30,7 +30,7 @@ public function testReadFromDbAndConvertToPHPValue() : void $polygonEntity = $repository->findOneBy(['id' => 1]); self::assertNotNull($polygonEntity); - $polygon = $polygonEntity->getPolygon(); + $polygon = $polygonEntity->polygon; self::assertInstanceOf(Polygon::class, $polygon); self::assertSame(1, $polygon->count()); self::assertInstanceOf(LineString::class, $polygon->exteriorRing()); From ecb433fd82f403061ff493fc064e0473e33978ad Mon Sep 17 00:00:00 2001 From: Benjamin Morel Date: Wed, 7 Feb 2024 23:05:07 +0100 Subject: [PATCH 2/3] Use env vars for connection params in phpunit-bootstrap.php --- .github/workflows/ci.yml | 20 ++++- phpunit-bootstrap.php | 158 +++++++++++++++++++---------------- tests/FunctionalTestCase.php | 7 +- tests/TestUtil.php | 44 ---------- 4 files changed, 102 insertions(+), 127 deletions(-) delete mode 100644 tests/TestUtil.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0744ee..2572449 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,7 +74,10 @@ jobs: - name: Run PHPUnit run: vendor/bin/phpunit env: - DRIVER: PDO_MYSQL + DB_DRIVER: pdo_mysql + DB_HOST: 127.0.0.1 + DB_USER: root + DB_PASSWORD: "" if: ${{ matrix.php-version != env.COVERAGE_PHP_VERSION }} - name: Run PHPUnit with coverage @@ -82,7 +85,10 @@ jobs: mkdir -p mkdir -p build/logs vendor/bin/phpunit --coverage-clover build/logs/clover.xml env: - DRIVER: PDO_MYSQL + DB_DRIVER: pdo_mysql + DB_HOST: 127.0.0.1 + DB_USER: root + DB_PASSWORD: "" if: ${{ matrix.php-version == env.COVERAGE_PHP_VERSION }} - name: Upload coverage report to Coveralls @@ -129,7 +135,10 @@ jobs: mkdir -p mkdir -p build/logs vendor/bin/phpunit --coverage-clover build/logs/clover.xml env: - DRIVER: PDO_MYSQL + DB_DRIVER: pdo_mysql + DB_HOST: 127.0.0.1 + DB_USER: root + DB_PASSWORD: "" - name: Upload coverage report to Coveralls run: vendor/bin/php-coveralls --coverage_clover=build/logs/clover.xml -v @@ -171,7 +180,10 @@ jobs: mkdir -p mkdir -p build/logs vendor/bin/phpunit --coverage-clover build/logs/clover.xml env: - DRIVER: PDO_PGSQL + DB_DRIVER: pdo_pgsql + DB_HOST: localhost + DB_USER: postgres + DB_PASSWORD: postgres - name: Upload coverage report to Coveralls run: vendor/bin/php-coveralls --coverage_clover=build/logs/clover.xml -v diff --git a/phpunit-bootstrap.php b/phpunit-bootstrap.php index 3eca6ee..33beddf 100644 --- a/phpunit-bootstrap.php +++ b/phpunit-bootstrap.php @@ -1,101 +1,113 @@ addPsr4('Doctrine\\Tests\\', [ - __DIR__ . '/vendor/doctrine/orm/tests/Doctrine/Tests', - __DIR__ . '/vendor/doctrine/dbal/tests/Doctrine/Tests' - ]); - $classLoader->loadClass('Doctrine\Tests\DbalFunctionalTestCase'); - $classLoader->loadClass('Doctrine\Tests\DBAL\Mocks\MockPlatform'); +function createDoctrineConnection(bool $selectDatabase): Connection +{ + $env = getenv(); - Type::addType('Geometry', Types\GeometryType::class); - Type::addType('LineString', Types\LineStringType::class); - Type::addType('MultiLineString', Types\MultiLineStringType::class); - Type::addType('MultiPoint', Types\MultiPointType::class); - Type::addType('MultiPolygon', Types\MultiPolygonType::class); - Type::addType('Point', Types\PointType::class); - Type::addType('Polygon', Types\PolygonType::class); + $requiredEnv = [ + 'DB_DRIVER', + 'DB_HOST', + 'DB_USER', + 'DB_PASSWORD', + ]; - $driver = getenv('DRIVER'); + $driver = $env['DB_DRIVER'] ?? null; + $host = $env['DB_HOST'] ?? null; + $port = $env['DB_PORT'] ?? null; + $user = $env['DB_USER'] ?? null; + $password = $env['DB_PASSWORD'] ?? null; - if ($driver === false) { - echo 'Please set the database driver to use:' . PHP_EOL; - echo 'DRIVER={driver} vendor/bin/phpunit' . PHP_EOL; - echo 'Available drivers: PDO_MYSQL, PDO_PGSQL' . PHP_EOL; - exit(1); - } else { - switch ($driver) { - case 'PDO_MYSQL': - echo 'Using PDO_MYSQL driver' . PHP_EOL; + if ($driver === null || $host === null || $user === null || $password === null) { + $missingEnv = array_diff($requiredEnv, array_keys($env)); - $pdo = new PDO('mysql:host=127.0.0.1;port=3306', 'root', ''); - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + echo "Missing environment variables: ", PHP_EOL; + foreach ($missingEnv as $key) { + echo " - $key", PHP_EOL; + } + echo PHP_EOL; - $pdo->exec('DROP DATABASE IF EXISTS geo_tests'); - $pdo->exec('CREATE DATABASE geo_tests'); + echo "Example:", PHP_EOL; + echo 'DB_DRIVER=pdo_mysql DB_HOST=localhost DB_PORT=3306 DB_USER=root DB_PASSWORD=password vendor/bin/phpunit' , PHP_EOL; + echo PHP_EOL; - $statement = $pdo->query('SELECT VERSION()'); - $version = $statement->fetchColumn(); + echo 'Available drivers:', PHP_EOL; + echo 'https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#driver', PHP_EOL; - echo 'MySQL version: ' . $version . PHP_EOL; + exit(1); + } - $GLOBALS['db_type'] = 'pdo_mysql'; - $GLOBALS['db_host'] = '127.0.0.1'; - $GLOBALS['db_port'] = 3306; - $GLOBALS['db_username'] = 'root'; - $GLOBALS['db_password'] = ''; - $GLOBALS['db_name'] = 'geo_tests'; + $params = [ + 'driver' => $driver, + 'host' => $host, + 'user' => $user, + 'password' => $password, + ]; - // doctrine/dbal >= 2.13.0 - $GLOBALS['db_driver'] = 'pdo_mysql'; - $GLOBALS['db_user'] = 'root'; - $GLOBALS['db_dbname'] = 'geo_tests'; + if ($port !== null) { + $params['port'] = (int) $port; + } - break; + if ($selectDatabase) { + $params['dbname'] = TEST_DATABASE; + } - case 'PDO_PGSQL': - echo 'Using PDO_PGSQL driver' . PHP_EOL; + $connection = DriverManager::getConnection($params); - $pdo = new PDO('pgsql:host=localhost', 'postgres', 'postgres'); - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + if ($connection->getDatabasePlatform() instanceof PostgreSQLPlatform) { + $connection->executeStatement('CREATE EXTENSION IF NOT EXISTS postgis'); + } - $pdo->exec('DROP DATABASE IF EXISTS geo_tests'); - $pdo->exec('CREATE DATABASE geo_tests'); + return $connection; +} - $statement = $pdo->query('SELECT version()'); - $version = $statement->fetchColumn(); +(function() { + $connection = createDoctrineConnection(selectDatabase: false); - echo 'PostgreSQL version: ' . $version . PHP_EOL; + echo "Database version: ", $connection->getServerVersion(), PHP_EOL; + echo "Database platform: ", get_class($connection->getDatabasePlatform()), PHP_EOL; - $statement = $pdo->query('SELECT PostGIS_Version()'); - $version = $statement->fetchColumn(); + if ($connection->getDatabasePlatform() instanceof PostgreSQLPlatform) { + $version = $connection->executeQuery('SELECT PostGIS_Version()')->fetchOne(); + echo 'PostGIS version: ', $version, PHP_EOL; + } - echo 'PostGIS version: ' . $version . PHP_EOL; + $schemaManager = $connection->createSchemaManager(); - $GLOBALS['db_type'] = 'pdo_pgsql'; - $GLOBALS['db_host'] = 'localhost'; - $GLOBALS['db_port'] = 5432; - $GLOBALS['db_username'] = 'postgres'; - $GLOBALS['db_password'] = 'postgres'; - $GLOBALS['db_name'] = 'geo_tests'; + try { + $schemaManager->dropDatabase('geo_tests'); + } catch (DatabaseDoesNotExist) { + // not an error! + } - // doctrine/dbal >= 2.13.0 - $GLOBALS['db_driver'] = 'pdo_pgsql'; - $GLOBALS['db_user'] = 'postgres'; - $GLOBALS['db_dbname'] = 'geo_tests'; + $schemaManager->createDatabase('geo_tests'); - break; + /** @var \Composer\Autoload\ClassLoader $classLoader */ + $classLoader = require 'vendor/autoload.php'; - default: - echo 'Unknown driver: ' . $driver . PHP_EOL; - exit(1); - } - } + // Add namespace for doctrine base tests + $classLoader->addPsr4('Doctrine\\Tests\\', [ + __DIR__ . '/vendor/doctrine/orm/tests/Doctrine/Tests', + __DIR__ . '/vendor/doctrine/dbal/tests/Doctrine/Tests' + ]); + + $classLoader->loadClass('Doctrine\Tests\DbalFunctionalTestCase'); + $classLoader->loadClass('Doctrine\Tests\DBAL\Mocks\MockPlatform'); + + // Register Doctrine types + Type::addType('Geometry', Types\GeometryType::class); + Type::addType('LineString', Types\LineStringType::class); + Type::addType('MultiLineString', Types\MultiLineStringType::class); + Type::addType('MultiPoint', Types\MultiPointType::class); + Type::addType('MultiPolygon', Types\MultiPolygonType::class); + Type::addType('Point', Types\PointType::class); + Type::addType('Polygon', Types\PolygonType::class); })(); diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index 54c271a..1b47997 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -5,7 +5,6 @@ namespace Brick\Geo\Doctrine\Tests; use Brick\Geo\Point; -use Brick\Geo\Doctrine\Tests\Fixtures; use Doctrine\Common\DataFixtures\Executor\ORMExecutor; use Doctrine\Common\DataFixtures\FixtureInterface; @@ -38,7 +37,7 @@ protected function setUp(): void { parent::setUp(); - $this->connection = TestUtil::getConnection(); + $this->connection = createDoctrineConnection(selectDatabase: true); $this->platform = $this->connection->getDatabasePlatform(); $this->platform->registerDoctrineTypeMapping('geometry', 'binary'); @@ -49,10 +48,6 @@ protected function setUp(): void $this->platform->registerDoctrineTypeMapping('point', 'binary'); $this->platform->registerDoctrineTypeMapping('polygon', 'binary'); - if ($this->platform instanceof PostgreSQLPlatform) { - $this->connection->executeQuery('CREATE EXTENSION IF NOT EXISTS postgis;'); - } - $this->fixtureLoader = new Loader(); $config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/Fixtures']); diff --git a/tests/TestUtil.php b/tests/TestUtil.php deleted file mode 100644 index 9f406d9..0000000 --- a/tests/TestUtil.php +++ /dev/null @@ -1,44 +0,0 @@ - Date: Thu, 8 Feb 2024 00:26:15 +0100 Subject: [PATCH 3/3] Prevent push and pull_request from running at the same time See: https://github.com/orgs/community/discussions/26276 --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2572449..57d4f68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,8 @@ name: CI on: push: + branches: + - master pull_request: env: