Skip to content

Commit

Permalink
Add Database injector #26
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Mar 16, 2022
2 parents d948a39 + bb175be commit bc62d98
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 17 deletions.
5 changes: 3 additions & 2 deletions src/Bootloader/DataGridBootloader.php
Expand Up @@ -4,7 +4,8 @@

namespace Spiral\Cycle\Bootloader;

use Cycle\Database\DatabaseInterface;
use Cycle\Database\DatabaseManager;
use Cycle\Database\DatabaseProviderInterface;
use Psr\Container\ContainerInterface;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Bootloader\AttributesBootloader;
Expand Down Expand Up @@ -55,7 +56,7 @@ public function boot(): void

public function compiler(ContainerInterface $container, Compiler $compiler, GridConfig $config): Compiler
{
if ($container->has(DatabaseInterface::class)) {
if ($container->has(DatabaseProviderInterface::class)) {
foreach ($config->getWriters() as $writer) {
$compiler->addWriter($container->get($writer));
}
Expand Down
15 changes: 5 additions & 10 deletions src/Bootloader/DatabaseBootloader.php
Expand Up @@ -10,7 +10,9 @@
use Cycle\Database\DatabaseProviderInterface;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Config\ConfiguratorInterface;
use Spiral\Core\Container;
use Spiral\Core\Container\SingletonInterface;
use Spiral\Cycle\Injector\DatabaseInjector;
use Spiral\Cycle\LoggerFactory;

final class DatabaseBootloader extends Bootloader implements SingletonInterface
Expand All @@ -20,14 +22,10 @@ final class DatabaseBootloader extends Bootloader implements SingletonInterface
DatabaseProviderInterface::class => DatabaseManager::class,
];

protected const BINDINGS = [
DatabaseInterface::class => [self::class, 'getDefaultDatabase'],
];

/**
* Init database config.
*/
public function boot(ConfiguratorInterface $config): void
public function boot(Container $container, ConfiguratorInterface $config): void
{
$config->setDefaults(
DatabaseConfig::CONFIG,
Expand All @@ -42,16 +40,13 @@ public function boot(ConfiguratorInterface $config): void
'drivers' => [],
]
);

$container->bindInjector(DatabaseInterface::class, DatabaseInjector::class);
}

protected function initManager(DatabaseConfig $config, LoggerFactory $loggerFactory): DatabaseProviderInterface
{
return new DatabaseManager($config, $loggerFactory);
}

protected function getDefaultDatabase(DatabaseProviderInterface $manager): DatabaseInterface
{
return $manager->database();
}
}

32 changes: 32 additions & 0 deletions src/Injector/DatabaseInjector.php
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Spiral\Cycle\Injector;

use Cycle\Database\DatabaseInterface;
use Cycle\Database\DatabaseManager;
use Cycle\Database\Exception\DBALException;
use Spiral\Core\Container\InjectorInterface;

final class DatabaseInjector implements InjectorInterface
{
public function __construct(
private DatabaseManager $dm
) {
}

public function createInjection(\ReflectionClass $class, string $context = null): DatabaseInterface
{
// if context is empty default database will be returned
try {
return $this->dm->database($context);
} catch (DBALException $e) {
if ($context === null || !str_contains($e->getMessage(), ' no presets for ')) {
throw $e;
}
// get default database
return $this->dm->database();
}
}
}
24 changes: 24 additions & 0 deletions tests/app/Injector/DatabaseInjectorAliasResolverTester.php
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Spiral\App\Injector;

use Cycle\Database\Database;
use Cycle\Database\DatabaseInterface;

final class DatabaseInjectorAliasResolverTester
{
public function __construct(
public DatabaseInterface $dbRuntime,
public DatabaseInterface $dbOther,
public Database $dbSqlite,
public Database $dbPostgres,
) {
}

public static function getDefaultDatabase(DatabaseInterface $usingUndefinedAlias)
{
return $usingUndefinedAlias;
}
}
13 changes: 13 additions & 0 deletions tests/app/config/database.php
Expand Up @@ -29,6 +29,12 @@
'default' => [
'driver' => 'runtime',
],
'runtime' => [
'driver' => 'runtime',
],
'other' => [
'driver' => 'runtime',
],
],

/**
Expand All @@ -48,4 +54,11 @@
)
),
],

'aliases' => [
'dbRuntime' => 'runtime',
'dbOther' => 'other',
'dbSqlite' => 'runtime',
'dbPostgres' => 'other'
],
];
9 changes: 4 additions & 5 deletions tests/src/Console/Command/Database/ListCommandTest.php
Expand Up @@ -7,7 +7,6 @@
use Cycle\Database\Database;
use Cycle\Database\DatabaseInterface;
use Cycle\Database\DatabaseManager;
use Cycle\Database\DatabaseProviderInterface;
use Spiral\Tests\ConsoleTest;

final class ListCommandTest extends ConsoleTest
Expand Down Expand Up @@ -40,20 +39,20 @@ public function testList(): void
public function testBrokenList(): void
{
/** @var DatabaseManager $dm */
$dm = $this->getContainer()->get(DatabaseProviderInterface::class);
$dm = $this->getContainer()->get(DatabaseManager::class);

$dm->addDatabase(
new Database(
'other',
'another',
'',
$dm->driver('other')
)
);

$output = $this->runCommand('db:list', ['db' => 'other']);
$output = $this->runCommand('db:list', ['db' => 'another']);

$this->assertStringContainsString('Postgres', $output);
$this->assertStringContainsString('database', $output);
$this->assertStringContainsString('other', $output);
$this->assertStringContainsString('another', $output);
}
}
39 changes: 39 additions & 0 deletions tests/src/Injector/DatabaseInjectorTest.php
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Spiral\Tests\Injector;

use Cycle\Database\Database;
use Cycle\Database\DatabaseInterface;
use Spiral\App\Injector\DatabaseInjectorAliasResolverTester;
use Spiral\Core\Container;
use Spiral\Tests\BaseTest;

final class DatabaseInjectorTest extends BaseTest
{
public function testInjectRepository(): void
{
$this->assertInstanceOf(DatabaseInterface::class, $this->getContainer()->get(DatabaseInterface::class));
$this->assertInstanceOf(Database::class, $this->getContainer()->get(Database::class));
}

public function testAlias(): void
{
$obj = $this->getContainer()->get(DatabaseInjectorAliasResolverTester::class);
$this->assertInstanceOf(Database::class, $obj->dbRuntime);
$this->assertInstanceOf(Database::class, $obj->dbOther);
$this->assertSame($obj->dbRuntime, $obj->dbSqlite);
$this->assertSame($obj->dbOther, $obj->dbPostgres);
}

public function testUseUndeclaredContext(): void
{
$c = $this->getContainer();

$database1 = $c->invoke([DatabaseInjectorAliasResolverTester::class, 'getDefaultDatabase']);
$database2 = $c->get(DatabaseInterface::class);

$this->assertSame($database2, $database1);
}
}

0 comments on commit bc62d98

Please sign in to comment.