diff --git a/DependencyInjection/BMBackupManagerExtension.php b/DependencyInjection/BMBackupManagerExtension.php index 1bd467b..965a7ed 100644 --- a/DependencyInjection/BMBackupManagerExtension.php +++ b/DependencyInjection/BMBackupManagerExtension.php @@ -6,6 +6,7 @@ use League\Flysystem\Adapter\Local; use League\Flysystem\AwsS3v3\AwsS3Adapter; use League\Flysystem\Dropbox\DropboxAdapter; +use Nyholm\DSN; use Srmklive\Dropbox\Adapter\DropboxAdapter as Dropbox2Adapter; use League\Flysystem\Rackspace\RackspaceAdapter; use League\Flysystem\Sftp\SftpAdapter; @@ -30,6 +31,7 @@ public function load(array $configs, ContainerBuilder $container) $config['storage'] = isset($config['storage']) ? $config['storage'] : []; $config['database'] = isset($config['database']) ? $config['database'] : []; $this->validateStorage($config['storage']); + $config['database'] = $this->parseDsn($config['database']); $managerIdMap = [ 'Local' => 'backup_manager.filesystems.local_filesystem', @@ -74,11 +76,35 @@ private function validateStorage(array $config) 'Sftp' => ['package'=>'league/flysystem-sftp:^1.0', 'test'=>SftpAdapter::class], ]; - foreach ($config as $key=>$storageConfig) { + foreach ($config as $key => $storageConfig) { $type = $storageConfig['type']; if (!class_exists($requirements[$type]['test'])) { throw new \LogicException(sprintf('To use the configuration key "%s" in "bm_backup_manager.stroage.%s.type" you need to install "%s"', $type, $key, $requirements[$type]['package'])); } } } + + /** + * If a DSN is configured, then let it override other database storages. + * @param array $config + * + * @param array + */ + private function parseDsn(array $config) + { + foreach ($config as $key => $databaseConfig) { + if (isset($databaseConfig['dsn'])) { + $dsn = new DSN($databaseConfig['dsn']); + $config[$key]['type'] = $dsn->getProtocol(); + $config[$key]['host'] = $dsn->getFirstHost(); + $config[$key]['port'] = $dsn->getFirstPort(); + $config[$key]['user'] = $dsn->getUsername(); + $config[$key]['pass'] = $dsn->getPassword(); + $config[$key]['database'] = $dsn->getDatabase(); + unset($config[$key]['dsn']); + } + } + + return $config; + } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index b4ee4a6..0d6997a 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -91,6 +91,7 @@ public function getConfigTreeBuilder() ->scalarNode('user')->end() ->scalarNode('pass')->end() ->scalarNode('database')->end() + ->scalarNode('dsn')->end() ->booleanNode('singleTransaction')->end() ->booleanNode('ssl')->end() ->arrayNode('ignoreTables') diff --git a/README.md b/README.md index 2d0fce1..18275b4 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,9 @@ bm_backup_manager: pass: password database: test ignoreTables: ['foo', 'bar'] + + # If DSN is specified, it will override other values + dsn: 'mysql://root:root_pass@127.0.0.1:3306/test_db' production: type: postgresql host: localhost @@ -78,6 +81,9 @@ bm_backup_manager: user: postgres pass: password database: test + + # If DSN is specified, it will override other values + dsn: 'pgsql://root:root_pass@127.0.0.1:5432/test_db' storage: local: type: Local diff --git a/Tests/Unit/DependencyInjection/BMBackupManagerExtensionTest.php b/Tests/Unit/DependencyInjection/BMBackupManagerExtensionTest.php index 6076366..2f3f1b9 100644 --- a/Tests/Unit/DependencyInjection/BMBackupManagerExtensionTest.php +++ b/Tests/Unit/DependencyInjection/BMBackupManagerExtensionTest.php @@ -33,6 +33,39 @@ public function testReplacementOfConfig() $this->assertContainerBuilderHasServiceDefinitionWithArgument('backup_manager.config_database', 0, $dbConfig); } + + public function testDsn() + { + $storageConfig = ['local'=>['type'=>'Local', 'root'=>'/foo']]; + $dbConfig = ['dev'=>[ + 'type'=>'mysql', + 'host'=>'host.com', + 'port'=>'3306', + 'user'=>'user', + 'pass'=>'pass', + 'database'=>'db', + // The DSN should override them all. + 'dsn'=>'pgsql://root:root_pass@127.0.0.1:5432/test_db', + ]]; + + $this->load([ + 'storage' => $storageConfig, + 'database' => $dbConfig, + ]); + + $parsedConfig = ['dev'=>[ + 'type'=>'pgsql', + 'host'=>'127.0.0.1', + 'port'=>'5432', + 'user'=>'root', + 'pass'=>'root_pass', + 'database'=>'test_db', + ]]; + + $this->assertContainerBuilderHasServiceDefinitionWithArgument('backup_manager.config_storage', 0, $storageConfig); + $this->assertContainerBuilderHasServiceDefinitionWithArgument('backup_manager.config_database', 0, $parsedConfig); + } + /** * Make sure we can have multiple storage names with the same type */ diff --git a/composer.json b/composer.json index 6ab89d2..4659b92 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "require": { "php": "^5.5 || ^7.0", "backup-manager/backup-manager": "^1.2", + "nyholm/dsn": "^0.1", "symfony/config": "^2.7 || ^3.1 || ^4.0", "symfony/console": "^2.7 || ^3.1 || ^4.0", "symfony/dependency-injection": "^2.7 || ^3.1 || ^4.0",