Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"php": "^8.4",
"ext-json": "*",
"ext-pdo": "*",
"symfony/console": "^8.0",
"symfony/console": "^7.4 || ^8.0",
"symfony/finder": "^7.0"
},
"require-dev": {
Expand Down
1 change: 1 addition & 0 deletions docs/configuration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Configuration array can consist of five parts:
- `dependencies` - array - list of dependencies which can be used in __construct of Migration classes. Key is type of dependency (class or interface name which will be used in __construct) and value is object of this type
- `template` - string - path to template file for migrations (used in create, dump and diff commands)
- `indent` - string - indentation in created migrations. Available values: 2spaces, 3spaces, 4spaces, 5spaces, tab [default: 4spaces]
- `adapter_factory_class` - string - fully qualified class name of a custom adapter factory. The class must implement `Phoenix\Database\Adapter\AdapterFactoryInterface`. This allows adding custom database adapters. [default: `Phoenix\Database\Adapter\AdapterFactory`]

### Example
Let's say you want to create configuration file, where `log_table_name` is "my_phoenix_log", you have two `migration_dirs` (first and second, which are located in the same directory as configuration file), also two `environments` both uses mysql adapter, and your `default_environment` is "local". Now we show you, how this config looks like using different type of configuration files:
Expand Down
4 changes: 2 additions & 2 deletions src/Command/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use InvalidArgumentException;
use Phoenix\Config\Config;
use Phoenix\Config\Parser\ConfigParserFactory;
use Phoenix\Database\Adapter\AdapterFactory;
use Phoenix\Database\Adapter\AdapterInterface;
use Phoenix\Exception\ConfigException;
use Phoenix\Exception\DatabaseQueryExecuteException;
Expand Down Expand Up @@ -69,7 +68,8 @@ final public function execute(InputInterface $input, OutputInterface $output): i
if (!$environmentConfig) {
throw new InvalidArgumentException('Environment ' . $environment . ' doesn\'t exist');
}
$this->adapter = AdapterFactory::instance($environmentConfig);
$adapterFactoryClass = $this->getConfig()->getAdapterFactoryClass();
$this->adapter = $adapterFactoryClass::instance($environmentConfig);

$this->manager = new Manager($this->getConfig(), $this->adapter);
$this->check();
Expand Down
4 changes: 2 additions & 2 deletions src/Command/DiffCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Phoenix\Command;

use Phoenix\Database\Adapter\AdapterFactory;
use Phoenix\Database\Element\Structure;
use Phoenix\Dumper\Dumper;
use Phoenix\Exception\InvalidArgumentValueException;
Expand Down Expand Up @@ -66,7 +65,8 @@ private function getStructure(string $type): Structure
throw new InvalidArgumentValueException(ucfirst($type) . ' environment "' . $env . '" doesn\'t exist in config');
}

$adapter = AdapterFactory::instance($config);
$adapterFactoryClass = $this->getConfig()->getAdapterFactoryClass();
$adapter = $adapterFactoryClass::instance($config);
return $adapter->getStructure();
}

Expand Down
16 changes: 16 additions & 0 deletions src/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Phoenix\Config;

use Phoenix\Database\Adapter\AdapterFactory;
use Phoenix\Database\Adapter\AdapterFactoryInterface;
use Phoenix\Exception\ConfigException;
use Phoenix\Exception\InvalidArgumentValueException;

Expand All @@ -20,6 +22,7 @@
'dependencies' => [],
'template' => __DIR__ . '/../Templates/DefaultTemplate.phoenix',
'indent' => '4spaces',
'adapter_factory_class' => AdapterFactory::class,
];

/**
Expand Down Expand Up @@ -111,4 +114,17 @@
{
return $this->configuration['indent'];
}

/**
* @return class-string<AdapterFactoryInterface>
* @throws InvalidArgumentValueException
*/
public function getAdapterFactoryClass(): string
{
$class = $this->configuration['adapter_factory_class'];
if (!is_subclass_of($class, AdapterFactoryInterface::class)) {
throw new InvalidArgumentValueException('Adapter factory class "' . $class . '" must implement ' . AdapterFactoryInterface::class);
}
return $class;

Check failure on line 128 in src/Config/Config.php

View workflow job for this annotation

GitHub Actions / PHPStan with lowest dependencies - PHP 8.5

Method Phoenix\Config\Config::getAdapterFactoryClass() should return class-string<Phoenix\Database\Adapter\AdapterFactoryInterface> but returns class-string<Phoenix\Database\Adapter\AdapterFactoryInterface>|Phoenix\Database\Adapter\AdapterFactoryInterface.

Check failure on line 128 in src/Config/Config.php

View workflow job for this annotation

GitHub Actions / PHPStan with lowest dependencies - PHP 8.4

Method Phoenix\Config\Config::getAdapterFactoryClass() should return class-string<Phoenix\Database\Adapter\AdapterFactoryInterface> but returns class-string<Phoenix\Database\Adapter\AdapterFactoryInterface>|Phoenix\Database\Adapter\AdapterFactoryInterface.

Check failure on line 128 in src/Config/Config.php

View workflow job for this annotation

GitHub Actions / PHPStan - PHP 8.4

Method Phoenix\Config\Config::getAdapterFactoryClass() should return class-string<Phoenix\Database\Adapter\AdapterFactoryInterface> but returns class-string<Phoenix\Database\Adapter\AdapterFactoryInterface>|Phoenix\Database\Adapter\AdapterFactoryInterface.

Check failure on line 128 in src/Config/Config.php

View workflow job for this annotation

GitHub Actions / PHPStan - PHP 8.5

Method Phoenix\Config\Config::getAdapterFactoryClass() should return class-string<Phoenix\Database\Adapter\AdapterFactoryInterface> but returns class-string<Phoenix\Database\Adapter\AdapterFactoryInterface>|Phoenix\Database\Adapter\AdapterFactoryInterface.
}
}
2 changes: 1 addition & 1 deletion src/Database/Adapter/AdapterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Phoenix\Config\EnvironmentConfig;
use Phoenix\Exception\InvalidArgumentValueException;

final class AdapterFactory
final class AdapterFactory implements AdapterFactoryInterface
{
public static function instance(EnvironmentConfig $config): AdapterInterface
{
Expand Down
12 changes: 12 additions & 0 deletions src/Database/Adapter/AdapterFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Phoenix\Database\Adapter;

use Phoenix\Config\EnvironmentConfig;

interface AdapterFactoryInterface
{
public static function instance(EnvironmentConfig $config): AdapterInterface;
}
48 changes: 48 additions & 0 deletions tests/Config/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

use Phoenix\Config\Config;
use Phoenix\Config\EnvironmentConfig;
use Phoenix\Database\Adapter\AdapterFactory;
use Phoenix\Exception\ConfigException;
use Phoenix\Exception\InvalidArgumentValueException;
use Phoenix\Tests\Mock\Database\Adapter\MockAdapterFactory;
use PHPUnit\Framework\TestCase;
use Ramsey\Uuid\UuidFactory;
use Ramsey\Uuid\UuidFactoryInterface;
Expand Down Expand Up @@ -191,4 +193,50 @@ public function testDependencies(): void
$this->expectExceptionMessage('Dependency for type "Ramsey\Uuid\UuidFactory" not found. Register it via $configuration[\'dependencies\'][\'Ramsey\Uuid\UuidFactory\']');
$config->getDependency(UuidFactory::class);
}

public function testDefaultAdapterFactoryClass(): void
{
$config = new Config([
'migration_dirs' => [
'first_dir',
],
'environments' => [
'first' => [],
],
]);

$this->assertEquals(AdapterFactory::class, $config->getAdapterFactoryClass());
}

public function testInvalidAdapterFactoryClass(): void
{
$config = new Config([
'migration_dirs' => [
'first_dir',
],
'environments' => [
'first' => [],
],
'adapter_factory_class' => 'Invalid\NonExistent\Class',
]);

$this->expectException(InvalidArgumentValueException::class);
$this->expectExceptionMessage('Adapter factory class "Invalid\NonExistent\Class" must implement Phoenix\Database\Adapter\AdapterFactoryInterface');
$config->getAdapterFactoryClass();
}

public function testCustomAdapterFactoryClass(): void
{
$config = new Config([
'migration_dirs' => [
'first_dir',
],
'environments' => [
'first' => [],
],
'adapter_factory_class' => MockAdapterFactory::class,
]);

$this->assertEquals(MockAdapterFactory::class, $config->getAdapterFactoryClass());
}
}
17 changes: 17 additions & 0 deletions tests/Mock/Database/Adapter/MockAdapterFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Phoenix\Tests\Mock\Database\Adapter;

use Phoenix\Config\EnvironmentConfig;
use Phoenix\Database\Adapter\AdapterFactoryInterface;
use Phoenix\Database\Adapter\AdapterInterface;

final class MockAdapterFactory implements AdapterFactoryInterface
{
public static function instance(EnvironmentConfig $config): AdapterInterface
{
throw new \RuntimeException('Mock adapter factory should not be instantiated in tests');
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please import class to uses

}
}
Loading