Skip to content

Commit dfb7f32

Browse files
Support different name entity manager connection (#378)
* Take connection from EntityManager if ObjectManager implements it. Fallback to the original logic otherwise * Added related tests * Added second entity manager config with tests --------- Co-authored-by: Alexis Lefebvre <2071331+alexislefebvre@users.noreply.github.com>
1 parent 14f7016 commit dfb7f32

6 files changed

Lines changed: 328 additions & 1 deletion

File tree

src/Services/DatabaseTools/AbstractDbalDatabaseTool.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Doctrine\DBAL\Platforms\MySQLPlatform;
1919
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
2020
use Doctrine\DBAL\Platforms\SQLitePlatform;
21+
use Doctrine\ORM\EntityManagerInterface;
2122

2223
abstract class AbstractDbalDatabaseTool extends AbstractDatabaseTool
2324
{
@@ -26,7 +27,12 @@ abstract class AbstractDbalDatabaseTool extends AbstractDatabaseTool
2627
public function setObjectManagerName(?string $omName = null): void
2728
{
2829
parent::setObjectManagerName($omName);
29-
$this->connection = $this->registry->getConnection($omName);
30+
31+
if ($this->om instanceof EntityManagerInterface) {
32+
$this->connection = $this->om->getConnection();
33+
} else {
34+
$this->connection = $this->registry->getConnection($omName);
35+
}
3036
}
3137

3238
protected function getPlatformName(): string
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Liip/TestFixturesBundle
7+
*
8+
* (c) Lukas Kahwe Smith <smith@pooteeweet.org>
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName;
15+
16+
use Liip\Acme\Tests\App\AppKernel;
17+
use Symfony\Component\Config\Loader\LoaderInterface;
18+
use Symfony\Component\DependencyInjection\ContainerBuilder;
19+
20+
class AppConfigSqliteDifferentConnectionNameKernel extends AppKernel
21+
{
22+
public function getCacheDir(): string
23+
{
24+
return __DIR__.'/var/cache/';
25+
}
26+
27+
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
28+
{
29+
// Load the default file.
30+
parent::configureContainer($container, $loader);
31+
32+
// Load the file with 2 entity managers
33+
$loader->load(__DIR__.'/config.yml');
34+
}
35+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Liip/TestFixturesBundle
7+
*
8+
* (c) Lukas Kahwe Smith <smith@pooteeweet.org>
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName\DataFixtures\ORM;
15+
16+
use Doctrine\Common\DataFixtures\AbstractFixture;
17+
use Doctrine\Persistence\ObjectManager;
18+
use Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName\Entity\Queue;
19+
20+
class LoadQueueData extends AbstractFixture
21+
{
22+
public function load(ObjectManager $manager): void
23+
{
24+
$queue1 = new Queue();
25+
$queue1->setId(1);
26+
$queue1->setPriority(100);
27+
$queue1->setJobContext(json_encode([
28+
'className' => 'someClass1',
29+
]));
30+
31+
$manager->persist($queue1);
32+
33+
$queue2 = new Queue();
34+
$queue2->setId(2);
35+
$queue2->setPriority(200);
36+
$queue2->setJobContext(json_encode([
37+
'className' => 'someClass2',
38+
]));
39+
40+
$manager->persist($queue2);
41+
$manager->flush();
42+
}
43+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Liip/TestFixturesBundle
7+
*
8+
* (c) Lukas Kahwe Smith <smith@pooteeweet.org>
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName\Entity;
15+
16+
use Doctrine\DBAL\Types\Types;
17+
use Doctrine\ORM\Mapping as ORM;
18+
19+
#[ORM\Entity]
20+
#[ORM\Table(name: 'liip_queue')]
21+
class Queue
22+
{
23+
#[ORM\Id]
24+
#[ORM\Column(type: Types::INTEGER)]
25+
#[ORM\GeneratedValue(strategy: 'AUTO')]
26+
private ?int $id = null;
27+
28+
#[ORM\Column]
29+
private int $priority;
30+
31+
#[ORM\Column]
32+
private string $jobContext;
33+
34+
public function __construct()
35+
{
36+
}
37+
38+
public function setId(int $id): self
39+
{
40+
$this->id = $id;
41+
42+
return $this;
43+
}
44+
45+
public function getId(): int
46+
{
47+
return $this->id;
48+
}
49+
50+
public function setPriority(int $priority): self
51+
{
52+
$this->priority = $priority;
53+
54+
return $this;
55+
}
56+
57+
public function getPriority(): int
58+
{
59+
return $this->priority;
60+
}
61+
62+
public function setJobContext(string $jobContext): self
63+
{
64+
$this->jobContext = $jobContext;
65+
66+
return $this;
67+
}
68+
69+
public function getJobContext(): string
70+
{
71+
return $this->jobContext;
72+
}
73+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# inherits configuration from ../App/config.yml
2+
3+
doctrine:
4+
dbal:
5+
default_connection: default
6+
connections:
7+
default:
8+
url: 'sqlite:///%kernel.cache_dir%/test.db'
9+
additional:
10+
url: 'sqlite:///%kernel.cache_dir%/test_additional.db'
11+
12+
orm:
13+
default_entity_manager: different
14+
entity_managers:
15+
different:
16+
connection: default
17+
mappings:
18+
LiipAcme:
19+
dir: "%kernel.project_dir%/Entity"
20+
prefix: 'Liip\Acme\Tests\App\Entity'
21+
is_bundle: false
22+
additional:
23+
connection: additional
24+
mappings:
25+
LiipAcme:
26+
dir: "%kernel.project_dir%/../AppConfigSqliteDifferentConnectionName/Entity"
27+
prefix: 'Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName\Entity'
28+
is_bundle: false
29+
30+
services:
31+
Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName\DataFixtures\ORM\:
32+
resource: 'DataFixtures/ORM/*'
33+
tags: [ 'doctrine.fixture.orm' ]
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Liip/TestFixturesBundle
7+
*
8+
* (c) Lukas Kahwe Smith <smith@pooteeweet.org>
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Liip\Acme\Tests\Test;
15+
16+
use Doctrine\ORM\EntityManagerInterface;
17+
use Doctrine\ORM\EntityRepository;
18+
use Doctrine\Persistence\ManagerRegistry;
19+
use Liip\Acme\Tests\App\Entity\User;
20+
use Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName\AppConfigSqliteDifferentConnectionNameKernel;
21+
use Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName\DataFixtures\ORM\LoadQueueData;
22+
use Liip\Acme\Tests\AppConfigSqliteDifferentConnectionName\Entity\Queue;
23+
use Liip\TestFixturesBundle\Event\PostFixtureSetupEvent;
24+
use Liip\TestFixturesBundle\LiipTestFixturesEvents;
25+
use Liip\TestFixturesBundle\Services\DatabaseToolCollection;
26+
use Liip\TestFixturesBundle\Services\DatabaseTools\AbstractDatabaseTool;
27+
use PHPUnit\Framework\Attributes\DataProvider;
28+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
29+
30+
/**
31+
* Test SQLite database with entity manager having different name than its connection.
32+
*
33+
* @internal
34+
*/
35+
class ConfigSqliteDifferentConnectionNameTest extends ConfigSqliteTest
36+
{
37+
private const MAIN_ENTITY_MANAGER_NAME = 'different';
38+
private const MAIN_CONNECTION_NAME = 'default';
39+
40+
private const ADDITIONAL_ENTITY_MANAGER_NAME = 'additional';
41+
private const ADDITIONAL_CONNECTION_NAME = 'additional';
42+
43+
/**
44+
* @var EntityRepository<User>
45+
*/
46+
private EntityRepository $queueRepository;
47+
48+
protected function setUp(): void
49+
{
50+
parent::setUp();
51+
52+
$testContainer = static::getContainer();
53+
54+
$this->queueRepository = $testContainer->get('doctrine')
55+
->getRepository(Queue::class);
56+
57+
$this->databaseTool = $testContainer->get(DatabaseToolCollection::class)
58+
->get(self::MAIN_ENTITY_MANAGER_NAME);
59+
}
60+
61+
public function testLoadFixturesForSecondEntityManager(): void
62+
{
63+
$this->getDatabaseTool(self::ADDITIONAL_ENTITY_MANAGER_NAME)
64+
->loadFixtures([LoadQueueData::class]);
65+
66+
$queueList = $this->queueRepository->findAll();
67+
68+
$this->assertCount(2, $queueList);
69+
70+
/** @var Queue $queue */
71+
$queue = $this->queueRepository
72+
->findOneBy([
73+
'id' => 1,
74+
]);
75+
76+
$this->assertSame(
77+
'{"className":"someClass1"}',
78+
$queue->getJobContext()
79+
);
80+
}
81+
82+
/**
83+
* @return iterable<array{0:string,1:string}>
84+
*/
85+
public static function objectManagerNameViaEventDataProvider(): iterable
86+
{
87+
yield [self::MAIN_ENTITY_MANAGER_NAME, self::MAIN_CONNECTION_NAME];
88+
yield [self::ADDITIONAL_ENTITY_MANAGER_NAME, self::ADDITIONAL_CONNECTION_NAME];
89+
}
90+
91+
#[DataProvider('objectManagerNameViaEventDataProvider')]
92+
public function testObjectManagerAndConnectionViaEvent(string $onName, string $connectionName): void
93+
{
94+
/** @var EventDispatcherInterface $eventDispatcher */
95+
$eventDispatcher = $this->getContainer()->get(EventDispatcherInterface::class);
96+
/** @var ManagerRegistry $registry */
97+
$registry = $this->getContainer()->get(ManagerRegistry::class);
98+
99+
$eventDispatcher->addListener(
100+
LiipTestFixturesEvents::POST_FIXTURE_SETUP,
101+
function (PostFixtureSetupEvent $event) use ($registry, $onName, $connectionName) {
102+
/** @var EntityManagerInterface $entityManager */
103+
$entityManager = $event->getManager();
104+
105+
$this->assertInstanceOf(EntityManagerInterface::class, $entityManager);
106+
107+
$this->assertSame(
108+
$registry->getManager($onName),
109+
$entityManager,
110+
);
111+
112+
$this->assertSame(
113+
$registry->getConnection($connectionName),
114+
$entityManager->getConnection(),
115+
);
116+
}
117+
);
118+
119+
$this->getDatabaseTool($onName)
120+
->loadFixtures();
121+
}
122+
123+
public static function getKernelClass(): string
124+
{
125+
return AppConfigSqliteDifferentConnectionNameKernel::class;
126+
}
127+
128+
private function getDatabaseTool(string $omName): AbstractDatabaseTool
129+
{
130+
$testContainer = static::getContainer();
131+
132+
/** @var DatabaseToolCollection $databaseToolCollection */
133+
$databaseToolCollection = $testContainer->get(DatabaseToolCollection::class);
134+
135+
return $databaseToolCollection->get($omName);
136+
}
137+
}

0 commit comments

Comments
 (0)