83 lines
2.4 KiB
PHP
83 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace Webman\Database;
|
|
|
|
use Illuminate\Database\DatabaseManager as BaseDatabaseManager;
|
|
use Throwable;
|
|
use Webman\Context;
|
|
use Workerman\Coroutine\Pool;
|
|
|
|
/**
|
|
* Class DatabaseManager
|
|
*/
|
|
class DatabaseManager extends BaseDatabaseManager
|
|
{
|
|
|
|
/**
|
|
* @var Pool[]
|
|
*/
|
|
protected static array $pools = [];
|
|
|
|
/**
|
|
* Get connection
|
|
*
|
|
* @param $name
|
|
* @return mixed
|
|
* @throws Throwable
|
|
*/
|
|
public function connection($name = null)
|
|
{
|
|
$name = $name ?: $this->getDefaultConnection();
|
|
[$database, $type] = $this->parseConnectionName($name);
|
|
|
|
$key = "database.connections.$name";
|
|
$connection = Context::get($key);
|
|
if (!$connection) {
|
|
if (!isset(static::$pools[$name])) {
|
|
$poolConfig = $this->app['config']['database.connections'][$name]['pool'] ?? [];
|
|
$pool = new Pool($poolConfig['max_connections'] ?? 6, $poolConfig);
|
|
$pool->setConnectionCreator(function () use ($database, $type) {
|
|
return $this->configure($this->makeConnection($database), $type);
|
|
});
|
|
$pool->setConnectionCloser(function ($connection) {
|
|
$this->closeAndFreeConnection($connection);
|
|
});
|
|
$pool->setHeartbeatChecker(function ($connection) {
|
|
$connection->select('select 1');
|
|
});
|
|
static::$pools[$name] = $pool;
|
|
}
|
|
try {
|
|
$connection = static::$pools[$name]->get();
|
|
Context::set($key, $connection);
|
|
} finally {
|
|
// We cannot use Coroutine::defer() because we may not be in a coroutine environment currently.
|
|
Context::onDestroy(function () use ($connection, $name) {
|
|
try {
|
|
$connection && static::$pools[$name]->put($connection);
|
|
} catch (Throwable) {
|
|
// ignore
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return $connection;
|
|
}
|
|
|
|
/**
|
|
* Close connection.
|
|
*
|
|
* @param $connection
|
|
* @return void
|
|
*/
|
|
protected function closeAndFreeConnection($connection): void
|
|
{
|
|
$connection->disconnect();
|
|
$clearProperties = function () {
|
|
$this->queryGrammar = null;
|
|
};
|
|
$clearProperties->call($connection);
|
|
}
|
|
|
|
}
|