Skip to content

Commit

Permalink
Adding Ability To Specify More Than One Dump File (#5220)
Browse files Browse the repository at this point in the history
* Preliminary Commit

* Adding Protection Against Any Array (IE: databases)

* Updating Documentation

* Discussion Updates
  • Loading branch information
Fenikkusu authored and DavertMik committed Oct 26, 2018
1 parent 5190da2 commit b7d53c8
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 25 deletions.
57 changes: 43 additions & 14 deletions src/Codeception/Lib/DbPopulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@
class DbPopulator
{
/**
* The command to be executed.
*
* @var string
* @var array
*/
private $builtCommand;
protected $config;

/**
* @var array
*/
protected $config;
protected $commands;

/**
* Constructs a DbPopulator object for the given command and Db module.
Expand All @@ -29,8 +27,11 @@ class DbPopulator
public function __construct($config)
{
$this->config = $config;
$command = $this->config['populator'];
$this->builtCommand = $this->buildCommand((string) $command);

//Convert To Array Format
if (isset($this->config['dump']) && !is_array($this->config['dump'])) {
$this->config['dump'] = [$this->config['dump']];
}
}

/**
Expand All @@ -49,10 +50,10 @@ public function __construct($config)
* ```
*
* @param string $command The command to be evaluated using the given config
* @param array $config The configuration values used to replace any found $keys with values from this array.
* @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($command)
protected function buildCommand($command, $dumpFile = null)
{
$dsn = isset($this->config['dsn']) ? $this->config['dsn'] : '';
$dsnVars = [];
Expand All @@ -64,9 +65,18 @@ protected function buildCommand($command)
$dsnVars[$k] = $v;
}
}

$vars = array_merge($dsnVars, $this->config);

if ($dumpFile !== null) {
$vars['dump'] = $dumpFile;
}

foreach ($vars as $key => $value) {
$vars['$'.$key] = $value;
if (!is_array($value)) {
$vars['$'.$key] = $value;
}

unset($vars[$key]);
}
return str_replace(array_keys($vars), array_values($vars), $command);
Expand All @@ -81,7 +91,15 @@ protected function buildCommand($command)
*/
public function run()
{
$command = $this->getBuiltCommand();
foreach ($this->buildCommands() as $command) {
$this->runCommand($command);
}

return true;
}

private function runCommand($command)
{
codecept_debug("[Db] Executing Populator: `$command`");

exec($command, $output, $exitCode);
Expand All @@ -95,11 +113,22 @@ public function run()
}

codecept_debug("[Db] Populator Finished.");
return true;
}

public function getBuiltCommand()
public function buildCommands()
{
return $this->builtCommand;
if ($this->commands !== null) {
return $this->commands;
} else if (!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;
}
}
47 changes: 40 additions & 7 deletions src/Codeception/Module/Db.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@
* ssl_verify_server_cert: false
* ssl_cipher: 'AES256-SHA'
*
* ## Example with multi-dumps
* modules:
* enabled:
* - Db:
* dsn: 'mysql:host=localhost;dbname=testdb'
* user: 'root'
* password: ''
* dump:
* - 'tests/_data/dump.sql'
* - 'tests/_data/dump-2.sql'
*
* ## Example with multi-databases
*
* modules:
Expand Down Expand Up @@ -445,24 +456,45 @@ private function readSql($databaseKey = null, $databaseConfig = null)
return;
}

if (!file_exists(Configuration::projectDir() . $databaseConfig['dump'])) {
if (!is_array($databaseConfig['dump'])) {
$databaseConfig['dump'] = [$databaseConfig['dump']];
}

$sql = '';

foreach ($databaseConfig['dump'] as $filePath) {
$sql .= $this->readSqlFile($filePath);
}

if (!empty($sql)) {
// split SQL dump into lines
$this->databasesSql[$databaseKey] = preg_split('/\r\n|\n|\r/', $sql, -1, PREG_SPLIT_NO_EMPTY);
}
}

/**
* @param $filePath
*
* @return bool|null|string|string[]
* @throws \Codeception\Exception\ModuleConfigException
*/
private function readSqlFile($filePath)
{
if (!file_exists(Configuration::projectDir() . $filePath)) {
throw new ModuleConfigException(
__CLASS__,
"\nFile with dump doesn't exist.\n"
. "Please, check path for sql file: "
. $databaseConfig['dump']
. $filePath
);
}

$sql = file_get_contents(Configuration::projectDir() . $databaseConfig['dump']);
$sql = file_get_contents(Configuration::projectDir() . $filePath);

// remove C-style comments (except MySQL directives)
$sql = preg_replace('%/\*(?!!\d+).*?\*/%s', '', $sql);

if (!empty($sql)) {
// split SQL dump into lines
$this->databasesSql[$databaseKey] = preg_split('/\r\n|\n|\r/', $sql, -1, PREG_SPLIT_NO_EMPTY);
}
return $sql;
}

private function connect($databaseKey, $databaseConfig)
Expand Down Expand Up @@ -511,6 +543,7 @@ private function connect($databaseKey, $databaseConfig)
}

try {
$this->debugSection('Connecting To Db', ['config' => $databaseConfig, 'options' => $options]);
$this->drivers[$databaseKey] = Driver::create($databaseConfig['dsn'], $databaseConfig['user'], $databaseConfig['password'], $options);
} catch (\PDOException $e) {
$message = $e->getMessage();
Expand Down
Binary file modified tests/data/sqlite.db
Binary file not shown.
33 changes: 29 additions & 4 deletions tests/unit/Codeception/Module/Db/Populator/DbPopulatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,39 @@ public function testCommandBuilderInterpolatesVariables()
'dsn' => 'mysql:host=127.0.0.1;dbname=my_db',
'dump' => 'tests/data/dumps/sqlite.sql',
'user' => 'root',
'populator' => 'mysql -u $user -h $host -D $dbname < $dump',
'databases' => []
]
);

$this->assertEquals(
['mysql -u root -h 127.0.0.1 -D my_db < tests/data/dumps/sqlite.sql'],
$populator->buildCommands()
);
}

public function testCommandBuilderInterpolatesVariablesMultiDump()
{
$populator = new DbPopulator(
[
'populate' => true,
'dsn' => 'mysql:host=127.0.0.1;dbname=my_db',
'dump' => [
'tests/data/dumps/sqlite.sql',
'tests/data/dumps/sqlite2.sql',
],
'user' => 'root',
'populator' => 'mysql -u $user -h $host -D $dbname < $dump'

]
);

$this->assertEquals(
'mysql -u root -h 127.0.0.1 -D my_db < tests/data/dumps/sqlite.sql',
$populator->getBuiltCommand()
[
'mysql -u root -h 127.0.0.1 -D my_db < tests/data/dumps/sqlite.sql',
'mysql -u root -h 127.0.0.1 -D my_db < tests/data/dumps/sqlite2.sql'
],
$populator->buildCommands()
);
}

Expand All @@ -34,8 +59,8 @@ public function testCommandBuilderWontTouchVariablesNotFound()
'user' => 'root',
]);
$this->assertEquals(
'noop_tool -u root -h $host -D $dbname < $dump',
$populator->getBuiltCommand()
['noop_tool -u root -h $host -D $dbname < $dump'],
$populator->buildCommands()
);

}
Expand Down

0 comments on commit b7d53c8

Please sign in to comment.