Allow custom driver which you can used to register your own driver (#3316)

* Allow custom driver which you can used to register your own driver

* Added test cases

* Update CHANGELOG-2.1.md
This commit is contained in:
李铭昕 2021-02-26 19:09:30 +08:00 committed by GitHub
parent 65c73ab5f2
commit 5e46eef8da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 2 deletions

View File

@ -8,6 +8,7 @@
- [#3310](https://github.com/hyperf/hyperf/pull/3310) Added `Blueprint::comment()` which you can set comment of table for migration.
- [#3311](https://github.com/hyperf/hyperf/pull/3311) Added `RouteCollector::getRouteParser` which you can get `RouteParser` from `RouteCollector`.
- [#3316](https://github.com/hyperf/hyperf/pull/3316) Allow custom driver which you can used to register your own driver for `hyperf/db`.
## Optimized

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace Hyperf\DB\Exception;
class InvalidDriverException extends RuntimeException
{
}

View File

@ -13,6 +13,7 @@ namespace Hyperf\DB\Pool;
use Hyperf\Contract\ConfigInterface;
use Hyperf\DB\Exception\DriverNotFoundException;
use Hyperf\DB\Exception\InvalidDriverException;
use Psr\Container\ContainerInterface;
class PoolFactory
@ -42,7 +43,11 @@ class PoolFactory
$driver = $config->get(sprintf('db.%s.driver', $name), 'pdo');
$class = $this->getPoolName($driver);
return $this->pools[$name] = make($class, [$this->container, $name]);
$pool = make($class, [$this->container, $name]);
if (! $pool instanceof Pool) {
throw new InvalidDriverException(sprintf('Driver %s is not invalid.', $driver));
}
return $this->pools[$name] = $pool;
}
protected function getPoolName(string $driver)
@ -54,6 +59,10 @@ class PoolFactory
return PDOPool::class;
}
if (class_exists($driver)) {
return $driver;
}
throw new DriverNotFoundException(sprintf('Driver %s is not found.', $driver));
}
}

View File

@ -43,6 +43,8 @@ abstract class AbstractTestCase extends TestCase
protected function getContainer($options = [])
{
$container = Mockery::mock(Container::class);
ApplicationContext::setContainer($container);
$container->shouldReceive('get')->with(ConfigInterface::class)->andReturn(new Config([
'db' => [
'default' => [
@ -86,7 +88,6 @@ abstract class AbstractTestCase extends TestCase
return new DB($factory, $params['poolName']);
});
$container->shouldReceive('has')->with(StdoutLoggerInterface::class)->andReturn(false);
ApplicationContext::setContainer($container);
return $container;
}
}

View File

@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\DB\Cases;
use Hyperf\Config\Config;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Contract\ConnectionInterface;
use Hyperf\DB\Pool\Pool;
use Hyperf\DB\Pool\PoolFactory;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerInterface;
/**
* @internal
* @coversNothing
*/
class CustomDriverTest extends AbstractTestCase
{
public function testCustomDriver()
{
$container = \Mockery::mock(ContainerInterface::class);
ApplicationContext::setContainer($container);
$container->shouldReceive('get')->with(ConfigInterface::class)->andReturn(new Config([
'db' => [
'custom' => [
'driver' => CustomPool::class,
'host' => '127.0.0.1',
'password' => '',
'database' => 'hyperf',
'pool' => [
'max_connections' => 20,
],
'options' => [],
],
],
]));
$factory = new PoolFactory($container);
$pool = $factory->getPool('custom');
$this->assertInstanceOf(CustomPool::class, $pool);
$this->assertInstanceOf(CustomConnection::class, $pool->get());
}
}
class CustomPool extends Pool
{
protected function createConnection(): ConnectionInterface
{
return new CustomConnection();
}
}
class CustomConnection implements ConnectionInterface
{
public function getConnection()
{
// TODO: Implement getConnection() method.
}
public function reconnect(): bool
{
// TODO: Implement reconnect() method.
}
public function check(): bool
{
// TODO: Implement check() method.
}
public function close(): bool
{
// TODO: Implement close() method.
}
public function release(): void
{
// TODO: Implement release() method.
}
}