Skip to content

Commit f2cc876

Browse files
committed
Extract connection handling
1 parent bf8c511 commit f2cc876

File tree

8 files changed

+237
-83
lines changed

8 files changed

+237
-83
lines changed

src/Connection/MySqlConnection.php

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Simply\Database\Connection;
44

5+
use Simply\Database\Connection\Provider\ConnectionProvider;
6+
57
/**
68
* MySqlConnection.
79
* @author Riikka Kalliomäki <[email protected]>
@@ -10,46 +12,17 @@
1012
*/
1113
class MySqlConnection implements Connection
1214
{
13-
/** @var callable */
14-
private $lazyLoader;
15-
16-
/** @var \PDO|null */
17-
private $pdo;
18-
19-
public function __construct(string $hostname, string $database, string $username, string $password)
20-
{
21-
$this->lazyLoader = function () use ($hostname, $database, $username, $password): \PDO {
22-
return new \PDO($this->getDataSource($hostname, $database), $username, $password, [
23-
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
24-
\PDO::ATTR_EMULATE_PREPARES => false,
25-
\PDO::MYSQL_ATTR_INIT_COMMAND => sprintf("SET time_zone = '%s'", date('P')),
26-
\PDO::MYSQL_ATTR_FOUND_ROWS => true,
27-
]);
28-
};
29-
}
15+
/** @var ConnectionProvider */
16+
private $provider;
3017

31-
private function getDataSource(string $hostname, string $database): string
18+
public function __construct(ConnectionProvider $provider)
3219
{
33-
if (strncmp($hostname, '/', 1) === 0) {
34-
return sprintf('mysql:unix_socket=%s;dbname=%s;charset=utf8mb4', $hostname, $database);
35-
}
36-
37-
$parts = explode(':', $hostname, 2);
38-
39-
if (\count($parts) === 1) {
40-
return sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', $hostname, $database);
41-
}
42-
43-
return sprintf('mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4', $parts[0], $parts[1], $database);
20+
$this->provider = $provider;
4421
}
4522

4623
public function getConnection(): \PDO
4724
{
48-
if (!$this->pdo) {
49-
$this->pdo = ($this->lazyLoader)();
50-
}
51-
52-
return $this->pdo;
25+
return $this->provider->getConnection();
5326
}
5427

5528
public function insert(string $table, array $values, string & $primaryKey = null): \PDOStatement
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Simply\Database\Connection\Provider;
4+
5+
/**
6+
* ConnectionProvider.
7+
* @author Riikka Kalliomäki <[email protected]>
8+
* @copyright Copyright (c) 2018 Riikka Kalliomäki
9+
* @license http://opensource.org/licenses/mit-license.php MIT License
10+
*/
11+
interface ConnectionProvider
12+
{
13+
public function getConnection(): \PDO;
14+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Simply\Database\Connection\Provider;
4+
5+
/**
6+
* LazyConnectionProvider.
7+
* @author Riikka Kalliomäki <[email protected]>
8+
* @copyright Copyright (c) 2018 Riikka Kalliomäki
9+
* @license http://opensource.org/licenses/mit-license.php MIT License
10+
*/
11+
class GenericConnectionProvider implements ConnectionProvider
12+
{
13+
private $dsn;
14+
private $username;
15+
private $password;
16+
private $options;
17+
private $pdo;
18+
19+
public function __construct(string $dsn, string $username, string $password, array $options)
20+
{
21+
$this->dsn = $dsn;
22+
$this->username = $username;
23+
$this->password = $password;
24+
$this->options = $options;
25+
}
26+
27+
public function getConnection(): \PDO
28+
{
29+
if (empty($this->pdo)) {
30+
$this->pdo = $this->initializeConnection();
31+
}
32+
33+
return $this->pdo;
34+
}
35+
36+
protected function initializeConnection(): \PDO
37+
{
38+
return new \PDO($this->dsn, $this->username, $this->password, $this->options);
39+
}
40+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Simply\Database\Connection\Provider;
4+
5+
/**
6+
* MySqlConnectionProvider.
7+
* @author Riikka Kalliomäki <[email protected]>
8+
* @copyright Copyright (c) 2018 Riikka Kalliomäki
9+
* @license http://opensource.org/licenses/mit-license.php MIT License
10+
*/
11+
class MySqlConnectionProvider extends GenericConnectionProvider
12+
{
13+
public function __construct(string $hostname, string $database, string $username, string $password)
14+
{
15+
parent::__construct($this->getDataSourceName($hostname, $database), $username, $password, $this->getOptions());
16+
}
17+
18+
protected function getDataSourceName(string $hostname, string $database): string
19+
{
20+
if (strncmp($hostname, '/', 1) === 0) {
21+
return sprintf('mysql:unix_socket=%s;dbname=%s;charset=utf8mb4', $hostname, $database);
22+
}
23+
24+
$parts = explode(':', $hostname, 2);
25+
26+
if (\count($parts) === 1) {
27+
return sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', $hostname, $database);
28+
}
29+
30+
return sprintf('mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4', $parts[0], $parts[1], $database);
31+
}
32+
33+
protected function getOptions(): array
34+
{
35+
return [
36+
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
37+
\PDO::ATTR_EMULATE_PREPARES => false,
38+
\PDO::MYSQL_ATTR_INIT_COMMAND => sprintf("SET time_zone = '%s'", date('P')),
39+
\PDO::MYSQL_ATTR_FOUND_ROWS => true,
40+
];
41+
}
42+
}

src/Schema.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,20 @@ public function __construct(ContainerInterface $container)
2626

2727
abstract public function getModel(): string;
2828
abstract public function getTable(): string;
29+
30+
/**
31+
* @return string[]
32+
*/
2933
abstract public function getPrimaryKey(): array;
34+
35+
/**
36+
* @return string[]
37+
*/
3038
abstract public function getFields(): array;
39+
40+
/**
41+
* @return array[]
42+
*/
3143
abstract public function getRelationshipDefinitions(): array;
3244

3345
/**

tests/helpers/TestCase/IntegrationTestCase.php

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* @copyright Copyright (c) 2018 Riikka Kalliomäki
1919
* @license http://opensource.org/licenses/mit-license.php MIT License
2020
*/
21-
abstract class IntegrationTestCase extends TestCase
21+
abstract class IntegrationTestCase extends UnitTestCase
2222
{
2323
/** @var Connection */
2424
protected $connection;
@@ -32,23 +32,60 @@ abstract class IntegrationTestCase extends TestCase
3232
/** @var TestHouseSchema */
3333
protected $houseSchema;
3434

35-
abstract protected function createConnection(): Connection;
36-
abstract protected function setUpDatabase(Connection $connection): void;
35+
abstract protected static function createConnection(): Connection;
3736

38-
protected function setUp()
37+
abstract protected static function createTables(
38+
Connection $connection,
39+
TestParentSchema $parentSchema,
40+
TestPersonSchema $personSchema,
41+
TestHouseSchema $houseSchema
42+
): void;
43+
44+
abstract protected static function dropTables(
45+
Connection $connection,
46+
TestParentSchema $parentSchema,
47+
TestPersonSchema $personSchema,
48+
TestHouseSchema $houseSchema
49+
): void;
50+
51+
abstract protected function truncateTables(Connection $connection): void;
52+
53+
public static function setUpBeforeClass()
54+
{
55+
$container = static::initializeContainer();
56+
$connection = static::createConnection();
57+
58+
static::createTables(
59+
$connection,
60+
$container[TestParentSchema::class],
61+
$container[TestPersonSchema::class],
62+
$container[TestHouseSchema::class]
63+
);
64+
}
65+
66+
public static function tearDownAfterClass()
3967
{
40-
$container = new Container();
68+
$container = static::initializeContainer();
69+
$connection = static::createConnection();
70+
71+
static::dropTables(
72+
$connection,
73+
$container[TestParentSchema::class],
74+
$container[TestPersonSchema::class],
75+
$container[TestHouseSchema::class]
76+
);
77+
}
4178

42-
$this->personSchema = new TestPersonSchema($container);
43-
$this->parentSchema = new TestParentSchema($container);
44-
$this->houseSchema = new TestHouseSchema($container);
79+
protected function setUp()
80+
{
81+
$container = static::initializeContainer();
4582

46-
$container[TestPersonSchema::class] = $this->personSchema;
47-
$container[TestParentSchema::class] = $this->parentSchema;
48-
$container[TestHouseSchema::class] = $this->houseSchema;
83+
$this->personSchema = $container[TestPersonSchema::class];
84+
$this->parentSchema = $container[TestParentSchema::class];
85+
$this->houseSchema = $container[TestHouseSchema::class];
4986

50-
$this->connection = $this->createConnection();
51-
$this->setUpDatabase($this->connection);
87+
$this->connection = static::createConnection();
88+
$this->truncateTables($this->connection);
5289
}
5390

5491
private function getTestPersonRepository(): TestRepository
@@ -424,4 +461,4 @@ public function testDeletingDeletedRecord()
424461
$this->expectException(MissingRecordException::class);
425462
$repository->deletePerson($person);
426463
}
427-
}
464+
}

tests/helpers/TestCase/UnitTestCase.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,22 @@
1818
*/
1919
class UnitTestCase extends TestCase
2020
{
21-
protected function getPersonSchema(): TestPersonSchema
21+
protected static function initializeContainer(): Container
2222
{
2323
$container = new Container();
24-
$schema = new TestPersonSchema($container);
2524

26-
$container[TestPersonSchema::class] = $schema;
25+
$container[TestPersonSchema::class] = new TestPersonSchema($container);
2726
$container[TestParentSchema::class] = new TestParentSchema($container);
2827
$container[TestHouseSchema::class] = new TestHouseSchema($container);
2928

30-
return $schema;
29+
return $container;
30+
}
31+
32+
protected function getPersonSchema(): TestPersonSchema
33+
{
34+
$container = static::initializeContainer();
35+
36+
return $container[TestPersonSchema::class];
3137
}
3238

3339
protected function getCompositeForeignKeySchema(): Schema
@@ -55,4 +61,4 @@ protected function getCompositeForeignKeySchema(): Schema
5561
$container['TestSchema'] = $schema;
5662
return $schema;
5763
}
58-
}
64+
}

0 commit comments

Comments
 (0)