Skip to content

Commit 45938b9

Browse files
authored
Merge pull request #20 from nealio82/allow-pre-existing-connections-to-be-used
Allow pre existing connections to be used
2 parents 9ddd2d7 + f1d8493 commit 45938b9

16 files changed

+545
-408
lines changed

Diff for: src/App.php

+27-31
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace Quidco\DbSampler;
34

45
use Doctrine\DBAL\Connection;
@@ -7,6 +8,9 @@
78
use Psr\Log\LoggerAwareInterface;
89
use Psr\Log\LoggerInterface;
910
use Psr\Log\NullLogger;
11+
use Quidco\DbSampler\DatabaseSchema\TablesList;
12+
use Quidco\DbSampler\DatabaseSchema\ViewsList;
13+
use Quidco\DbSampler\Configuration\MigrationConfigurationCollection;
1014

1115
/**
1216
* Dependency container / app for DbSampler
@@ -27,6 +31,16 @@ class App extends Container implements DatabaseConnectionFactoryInterface, Logge
2731
*/
2832
protected $configuredMigrationNames = [];
2933

34+
/**
35+
* @var MigrationConfigurationCollection
36+
*/
37+
private $databaseConfigurationCollection;
38+
39+
public function __construct(MigrationConfigurationCollection $databaseConfigurationCollection)
40+
{
41+
$this->databaseConfigurationCollection = $databaseConfigurationCollection;
42+
}
43+
3044
/**
3145
* Load common DB credentials file
3246
*
@@ -46,44 +60,26 @@ public function loadCredentialsFile($filename)
4660
$this['db.credentialsFile'] = $filename;
4761
}
4862

49-
/**
50-
* Load migration specification for a single database
51-
*
52-
* @param string $filename Path to specification file
53-
*
54-
* @return void
55-
* @throws \RuntimeException If config is invalid
56-
*/
57-
public function loadDatabaseConfigFile($filename)
58-
{
59-
$config = json_decode(file_get_contents($filename));
60-
$name = $config->name;
61-
if (!$name) {
62-
throw new \RuntimeException("Migration file '$filename' has no name field");
63-
}
64-
65-
$this->configuredMigrationNames[] = $name;
66-
$this["db.migrations.$name"] = $config;
67-
}
68-
6963
/**
7064
* Perform migrations from a named set
7165
*
7266
* @param string $name Migration name as specified in a .db.json migration file
7367
*
74-
* @return void
7568
* @throws \RuntimeException If config is invalid
7669
*/
77-
public function performMigrationSet($name)
70+
public function performMigrationSet($name): void
7871
{
79-
$migrator = new Migrator($name);
80-
$migrator->setLogger($this->getLogger());
81-
$migrator->setDatabaseConnectionFactory($this);
72+
$configuration = $this->databaseConfigurationCollection->get($name);
73+
74+
$sourceConnection = $this->createSourceConnectionByDbName($configuration->getSourceDbName());
75+
$destConnection = $this->createDestConnectionByDbName($configuration->getDestinationDbName());
8276

83-
$migrationConfigProcessor = new MigrationConfigProcessor();
84-
$migrationConfigProcessor->configureMigratorFromConfig($migrator, $this["db.migrations.$name"]);
77+
$migrator = new Migrator($sourceConnection, $destConnection, $this->getLogger());
8578

86-
$migrator->execute();
79+
$tableCollection = TablesList::fromConfig($configuration);
80+
$viewCollection = ViewsList::fromConfig($configuration);
81+
82+
$migrator->execute($name, $tableCollection, $viewCollection);
8783
}
8884

8985
/**
@@ -117,14 +113,14 @@ public function createDestConnectionByDbName($name)
117113
/**
118114
* Create connection object for DB name / direction. Other credentials (host, password etc) must already be known
119115
*
120-
* @param string $name Database name
116+
* @param string $name Database name
121117
* @param string $direction Determines whether 'source' or 'dest' credentials used, must be one of those values
122118
*
123119
* @return Connection
124120
* @throws \UnexpectedValueException If configuration is invalid
125121
* @throws \Doctrine\DBAL\DBALException If connection cannot be made
126122
*/
127-
protected function createConnectionByDbName($name, $direction = self::CONNECTION_SOURCE)
123+
protected function createConnectionByDbName($name, $direction): Connection
128124
{
129125
if (!isset($this["db.connections.$name"])) {
130126
$dbcredentials = isset($this["db.credentials"]->$direction) ?
@@ -211,6 +207,6 @@ protected function getLogger()
211207
*/
212208
public function getConfiguredMigrationNames()
213209
{
214-
return $this->configuredMigrationNames;
210+
return $this->databaseConfigurationCollection->listConfigurations();
215211
}
216212
}

Diff for: src/Configuration/MigrationConfiguration.php

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Quidco\DbSampler\Configuration;
4+
5+
class MigrationConfiguration
6+
{
7+
private $config;
8+
9+
private function __construct(\stdClass $config)
10+
{
11+
$this->config = $config;
12+
}
13+
14+
public static function fromJson(string $configJson): self
15+
{
16+
$config = \json_decode($configJson);
17+
18+
if (null === $config) {
19+
throw new \RuntimeException("Migration JSON config was not valid");
20+
}
21+
22+
if (!isset($config->name)) {
23+
throw new \RuntimeException("Migration file has no name field");
24+
}
25+
26+
return new self($config);
27+
}
28+
29+
public function getName(): string
30+
{
31+
return $this->config->name;
32+
}
33+
34+
public function getTables(): array
35+
{
36+
return (array)$this->config->tables;
37+
}
38+
39+
public function getViews(): array
40+
{
41+
return $this->config->views ?? [];
42+
}
43+
44+
public function getSourceDbName(): string
45+
{
46+
return $this->config->sourceDb;
47+
}
48+
49+
public function getDestinationDbName(): string
50+
{
51+
return $this->config->destDb;
52+
}
53+
}
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Quidco\DbSampler\Configuration;
4+
5+
class MigrationConfigurationCollection
6+
{
7+
/**
8+
* @var array
9+
*/
10+
private $configs;
11+
12+
private function __construct(array $configs)
13+
{
14+
$this->configs = $configs;
15+
}
16+
17+
public static function fromFilePaths(array $filepaths): self
18+
{
19+
$configs = [];
20+
21+
foreach ($filepaths as $migrationFilePath) {
22+
try {
23+
$migrationFiles = [$migrationFilePath];
24+
25+
if (is_dir($migrationFilePath)) {
26+
$migrationFiles = glob(rtrim($migrationFilePath, '/') . '/*.json');
27+
}
28+
29+
foreach ($migrationFiles as $file) {
30+
$config = MigrationConfiguration::fromJson(file_get_contents($file));
31+
32+
$configs[$config->getName()] = $config;
33+
}
34+
} catch (\RuntimeException $e) {
35+
print("Migration file '$migrationFilePath' is invalid " . $e->getMessage());
36+
}
37+
}
38+
39+
return new self($configs);
40+
}
41+
42+
public function get(string $configName): MigrationConfiguration
43+
{
44+
return $this->configs[$configName];
45+
}
46+
47+
public function listConfigurations(): array
48+
{
49+
return \array_keys($this->configs);
50+
}
51+
}

Diff for: src/ConsoleRunner.php

+5-15
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Monolog\Logger;
66
use Psr\Log\LoggerAwareInterface;
77
use Psr\Log\LoggerInterface;
8+
use Quidco\DbSampler\Configuration\MigrationConfigurationCollection;
89

910
/**
1011
* Console Runner for Quidco\DbSampler\App
@@ -88,7 +89,10 @@ public function run()
8889
exit($exitCode);
8990
}
9091

91-
$app = new App();
92+
$app = new App(
93+
MigrationConfigurationCollection::fromFilePaths($this->migrationFilePaths)
94+
);
95+
9296
$app->setLogger($this->getLogger());
9397

9498
try {
@@ -97,20 +101,6 @@ public function run()
97101
print("Credentials file '{$this->credentialsFilePath}' is invalid " . $e->getMessage());
98102
}
99103

100-
foreach ($this->migrationFilePaths as $migrationFilePath) {
101-
try {
102-
if (is_dir($migrationFilePath)) {
103-
$migrationFiles = glob(rtrim($migrationFilePath, '/') . '/*.json');
104-
} else {
105-
$migrationFiles = [$migrationFilePath];
106-
}
107-
foreach ($migrationFiles as $file) {
108-
$app->loadDatabaseConfigFile($file);
109-
}
110-
} catch (\RuntimeException $e) {
111-
print("Migration file '$migrationFilePath' is invalid " . $e->getMessage());
112-
}
113-
}
114104

115105
if (!$this->databases) {
116106
$this->databases = $app->getConfiguredMigrationNames();

Diff for: src/DatabaseSchema/TablesList.php

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace Quidco\DbSampler\DatabaseSchema;
4+
5+
use Quidco\DbSampler\Configuration\MigrationConfiguration;
6+
use Quidco\DbSampler\ReferenceStore;
7+
use Quidco\DbSampler\SamplerInterface;
8+
use Quidco\DbSampler\SamplerMap;
9+
10+
class TablesList
11+
{
12+
private $tables = [];
13+
14+
/**
15+
* @var ReferenceStore
16+
*/
17+
private $referenceStore;
18+
/**
19+
* @var array
20+
*/
21+
private $rawTables;
22+
23+
private function __construct(array $rawTables)
24+
{
25+
$this->referenceStore = new ReferenceStore();
26+
$this->rawTables = $rawTables;
27+
}
28+
29+
public static function fromConfig(MigrationConfiguration $configuration): self
30+
{
31+
return new self((array)$configuration->getTables());
32+
}
33+
34+
public function getTables(): array
35+
{
36+
// @todo we probably shouldn't be building the sampler in this getter. find another place to do it!
37+
if ([] === $this->tables) {
38+
foreach ($this->rawTables as $table => $migrationSpec) {
39+
$this->tables[$table] = $this->buildTableSampler($migrationSpec);
40+
}
41+
}
42+
43+
return $this->tables;
44+
}
45+
46+
/**
47+
* Build a SamplerInterface object from configuration
48+
*
49+
* @throws \UnexpectedValueException If bad object created - should be impossible
50+
* @throws \RuntimeException On invalid specification
51+
*/
52+
private function buildTableSampler(\stdClass $migrationSpec): SamplerInterface
53+
{
54+
$sampler = null;
55+
56+
// @todo: $migrationSpec should be an object with a getSampler() method
57+
$samplerType = strtolower($migrationSpec->sampler);
58+
if (array_key_exists($samplerType, SamplerMap::MAP)) {
59+
$samplerClass = SamplerMap::MAP[$samplerType];
60+
$sampler = new $samplerClass;
61+
if (!$sampler instanceof SamplerInterface) {
62+
throw new \UnexpectedValueException('Invalid sampler created');
63+
}
64+
/** @var SamplerInterface $sampler */
65+
$sampler->loadConfig($migrationSpec);
66+
$sampler->setReferenceStore($this->referenceStore);
67+
} else {
68+
throw new \RuntimeException("Unrecognised sampler type '$samplerType' required");
69+
}
70+
71+
return $sampler;
72+
}
73+
}

Diff for: src/DatabaseSchema/ViewsList.php

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Quidco\DbSampler\DatabaseSchema;
4+
5+
use Quidco\DbSampler\Configuration\MigrationConfiguration;
6+
7+
class ViewsList
8+
{
9+
private $views = [];
10+
11+
private function __construct(array $views)
12+
{
13+
$this->views = $views;
14+
}
15+
16+
public static function fromConfig(MigrationConfiguration $configuration): self
17+
{
18+
return new self($configuration->getViews());
19+
}
20+
21+
public function getViews(): array
22+
{
23+
return $this->views;
24+
}
25+
}

0 commit comments

Comments
 (0)