From d3ba11f52111102c7c6d6cbf4a15c2cb91a8c7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 14 Nov 2022 12:07:52 +0100 Subject: [PATCH] Feature: Store location of each address contained in geographical units in a materialized view --- src/Bundle/ChillMainBundle/Entity/Address.php | 31 +++++++++++++- .../migrations/Version20221114105345.php | 42 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20221114105345.php diff --git a/src/Bundle/ChillMainBundle/Entity/Address.php b/src/Bundle/ChillMainBundle/Entity/Address.php index 2ddb48fda..1540fec54 100644 --- a/src/Bundle/ChillMainBundle/Entity/Address.php +++ b/src/Bundle/ChillMainBundle/Entity/Address.php @@ -15,6 +15,8 @@ use Chill\MainBundle\Doctrine\Model\Point; use Chill\ThirdPartyBundle\Entity\ThirdParty; use DateTime; use DateTimeInterface; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Context\ExecutionContextInterface; @@ -97,6 +99,23 @@ class Address */ private $floor; + /** + * List of geographical units and addresses. + * + * This list is computed by a materialized view. It won't be populated until a refresh is done + * on the materialized view. + * + * @var Collection|GeographicalUnit[] + * @readonly + * @ORM\ManyToMany(targetEntity=GeographicalUnit::class) + * @ORM\JoinTable( + * name="view_chill_main_address_geographical_unit", + * joinColumns={@ORM\JoinColumn(name="address_id")}, + * inverseJoinColumns={@ORM\JoinColumn(name="geographical_unit_id")} + * ) + */ + private Collection $geographicalUnits; + /** * @var int * @@ -104,8 +123,9 @@ class Address * @ORM\Column(name="id", type="integer") * @ORM\GeneratedValue(strategy="AUTO") * @Groups({"write"}) + * @readonly */ - private $id; + private ?int $id = null; /** * True if the address is a "no address", aka homeless person, ... @@ -190,6 +210,7 @@ class Address public function __construct() { $this->validFrom = new DateTime(); + $this->geographicalUnits = new ArrayCollection(); } public static function createFromAddress(Address $original): Address @@ -273,6 +294,14 @@ class Address return $this->floor; } + /** + * @return Collection|GeographicalUnit[] + */ + public function getGeographicalUnits(): Collection + { + return $this->geographicalUnits; + } + /** * Get id. * diff --git a/src/Bundle/ChillMainBundle/migrations/Version20221114105345.php b/src/Bundle/ChillMainBundle/migrations/Version20221114105345.php new file mode 100644 index 000000000..8bc75ac29 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20221114105345.php @@ -0,0 +1,42 @@ +addSql('DROP MATERIALIZED VIEW view_chill_main_address_geographical_unit'); + } + + public function getDescription(): string + { + return 'Create materialized view to store GeographicalUnitAddress'; + } + + public function up(Schema $schema): void + { + $this->addSql('CREATE MATERIALIZED VIEW view_chill_main_address_geographical_unit (address_id, geographical_unit_id) AS + SELECT + address.id AS address_id, + geographical_unit.id AS geographical_unit_id + FROM chill_main_address AS address + JOIN chill_main_geographical_unit AS geographical_unit ON ST_CONTAINS(geographical_unit.geom, address.point) + '); + + $this->addSql('CREATE INDEX IDX_BD42692CF5B7AF75 ON view_chill_main_address_geographical_unit (address_id)'); + $this->addSql('CREATE INDEX IDX_BD42692CDAA4DAB8 ON view_chill_main_address_geographical_unit (geographical_unit_id)'); + } +}