forked from Codeception/module-db
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDbPopulator.php
More file actions
133 lines (110 loc) · 3.79 KB
/
Copy pathDbPopulator.php
File metadata and controls
133 lines (110 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
declare(strict_types=1);
namespace Codeception\Lib;
/**
* Populates a db using a parameterized command built from the Db module configuration.
*/
class DbPopulator
{
protected array $config = [];
protected array $commands = [];
/**
* Constructs a DbPopulator object for the given command and Db module.
*
* @internal param string $command The parameterized command to evaluate and execute later.
* @internal param Codeception\Module\Db|null $dbModule The Db module used to build the populator command or null.
*/
public function __construct(array $config)
{
$this->config = $config;
//Convert To Array Format
if (!isset($this->config['dump'])) {
return;
}
if (is_array($this->config['dump'])) {
return;
}
$this->config['dump'] = [$this->config['dump']];
}
/**
* Builds out a command replacing any found `$key` with its value if found in the given configuration.
*
* Process any $key found in the configuration array as a key of the array and replaces it with
* the found value for the key. Example:
*
* ```php
* <?php
*
* $command = 'Hello $name';
* $config = ['name' => 'Mauro'];
*
* // With the above parameters it will return `'Hello Mauro'`.
* ```
*
* @param string $command The command to be evaluated using the given config
* @param string|null $dumpFile The dump file to build the command with.
* @return string The resulting command string after evaluating any configuration's key
*/
protected function buildCommand(string $command, string $dumpFile = null): string
{
$dsn = $this->config['dsn'] ?? '';
$dsnVars = [];
$dsnWithoutDriver = preg_replace('#^[a-z]+:#i', '', $dsn);
foreach (explode(';', $dsnWithoutDriver) as $item) {
$keyValueTuple = explode('=', $item);
if (count($keyValueTuple) > 1) {
[$k, $v] = array_values($keyValueTuple);
$dsnVars[$k] = $v;
}
}
$vars = array_merge($dsnVars, $this->config);
if ($dumpFile !== null) {
$vars['dump'] = $dumpFile;
}
foreach ($vars as $key => $value) {
if (!is_array($value)) {
$vars['$'.$key] = $value;
}
unset($vars[$key]);
}
return str_replace(array_keys($vars), $vars, $command);
}
/**
* Executes the command built using the Db module configuration.
*
* Uses the PHP `exec` to spin off a child process for the built command.
*/
public function run(): bool
{
foreach ($this->buildCommands() as $command) {
$this->runCommand($command);
}
return true;
}
private function runCommand($command): void
{
codecept_debug("[Db] Executing Populator: `{$command}`");
exec($command, $output, $exitCode);
if (0 !== $exitCode) {
throw new \RuntimeException(
"The populator command did not end successfully: \n" .
" Exit code: {$exitCode} \n" .
" Output:" . implode("\n", $output)
);
}
codecept_debug("[Db] Populator Finished.");
}
public function buildCommands(): array
{
if ($this->commands !== []) {
return $this->commands;
} elseif (!isset($this->config['dump']) || $this->config['dump'] === false) {
return [$this->buildCommand($this->config['populator'])];
}
$this->commands = [];
foreach ($this->config['dump'] as $dumpFile) {
$this->commands[] = $this->buildCommand($this->config['populator'], $dumpFile);
}
return $this->commands;
}
}