mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
Added Db::beforeExecuting()
to register a hook which to be run just before a database query is executed. (#4908)
Co-authored-by: 李铭昕 <715557344@qq.com>
This commit is contained in:
parent
5ed82f8c0f
commit
13ab808087
@ -51,6 +51,7 @@ composer analyse
|
||||
- [#4700](https://github.com/hyperf/hyperf/pull/4700) Support coroutine style server for `socketio-server`.
|
||||
- [#4852](https://github.com/hyperf/hyperf/pull/4852) Added `NullDisableEventDispatcher` to disable event dispatcher by default.
|
||||
- [#4866](https://github.com/hyperf/hyperf/pull/4866) [#4869](https://github.com/hyperf/hyperf/pull/4869) Added Annotation `Scene` which use scene in FormRequest easily.
|
||||
- [#4908](https://github.com/hyperf/hyperf/pull/4908) Added `Db::beforeExecuting()` to register a hook which to be run just before a database query is executed.
|
||||
|
||||
## Optimized
|
||||
|
||||
|
@ -38,14 +38,14 @@ class Connection implements ConnectionInterface
|
||||
/**
|
||||
* The active PDO connection.
|
||||
*
|
||||
* @var \Closure|\PDO
|
||||
* @var Closure|PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* The active PDO connection used for reads.
|
||||
*
|
||||
* @var \Closure|\PDO
|
||||
* @var Closure|PDO
|
||||
*/
|
||||
protected $readPdo;
|
||||
|
||||
@ -149,10 +149,17 @@ class Connection implements ConnectionInterface
|
||||
*/
|
||||
protected static array $resolvers = [];
|
||||
|
||||
/**
|
||||
* All the callbacks that should be invoked before a query is executed.
|
||||
*
|
||||
* @var Closure[]
|
||||
*/
|
||||
protected static array $beforeExecutingCallbacks = [];
|
||||
|
||||
/**
|
||||
* Create a new database connection instance.
|
||||
*
|
||||
* @param \Closure|\PDO $pdo
|
||||
* @param Closure|PDO $pdo
|
||||
* @param string $database
|
||||
* @param string $tablePrefix
|
||||
*/
|
||||
@ -489,6 +496,22 @@ class Connection implements ConnectionInterface
|
||||
$this->setPdo(null)->setReadPdo(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a hook to be run just before a database query is executed.
|
||||
*/
|
||||
public static function beforeExecuting(Closure $callback): void
|
||||
{
|
||||
static::$beforeExecutingCallbacks[] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all hooks which will be run before a database query.
|
||||
*/
|
||||
public static function clearBeforeExecutingCallbacks(): void
|
||||
{
|
||||
static::$beforeExecutingCallbacks = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a database query listener with the connection.
|
||||
*/
|
||||
@ -623,7 +646,7 @@ class Connection implements ConnectionInterface
|
||||
/**
|
||||
* Set the PDO connection.
|
||||
*
|
||||
* @param null|\Closure|\PDO $pdo
|
||||
* @param null|Closure|PDO $pdo
|
||||
* @return $this
|
||||
*/
|
||||
public function setPdo($pdo)
|
||||
@ -638,7 +661,7 @@ class Connection implements ConnectionInterface
|
||||
/**
|
||||
* Set the PDO connection used for reading.
|
||||
*
|
||||
* @param null|\Closure|\PDO $pdo
|
||||
* @param null|Closure|PDO $pdo
|
||||
* @return $this
|
||||
*/
|
||||
public function setReadPdo($pdo)
|
||||
@ -983,7 +1006,7 @@ class Connection implements ConnectionInterface
|
||||
/**
|
||||
* Execute the given callback in "dry run" mode.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param Closure $callback
|
||||
* @return array
|
||||
*/
|
||||
protected function withFreshQueryLog($callback)
|
||||
@ -1014,6 +1037,10 @@ class Connection implements ConnectionInterface
|
||||
*/
|
||||
protected function run(string $query, array $bindings, Closure $callback)
|
||||
{
|
||||
foreach (static::$beforeExecutingCallbacks as $beforeExecutingCallback) {
|
||||
$beforeExecutingCallback($query, $bindings, $this);
|
||||
}
|
||||
|
||||
$this->reconnectIfMissingConnection();
|
||||
|
||||
$start = microtime(true);
|
||||
|
@ -452,6 +452,35 @@ class ModelRealBuilderTest extends TestCase
|
||||
$this->assertSame('ref', $res[0]->type);
|
||||
}
|
||||
|
||||
public function testBeforeExecuting()
|
||||
{
|
||||
$container = $this->getContainer();
|
||||
$container->shouldReceive('get')->with(Db::class)->andReturn(new Db($container));
|
||||
|
||||
$res = Db::selectOne('SELECT * FROM `user` WHERE id = ?;', [1]);
|
||||
$this->assertSame('Hyperf', $res->name);
|
||||
|
||||
try {
|
||||
$chan = new Channel(2);
|
||||
Db::beforeExecuting(function (string $sql, array $bindings, Connection $connection) use ($chan) {
|
||||
$this->assertSame(null, $connection->getConfig('name'));
|
||||
$chan->push(1);
|
||||
});
|
||||
Db::beforeExecuting(function (string $sql, array $bindings, Connection $connection) use ($chan) {
|
||||
$this->assertSame('SELECT * FROM `user` WHERE id = ?;', $sql);
|
||||
$this->assertSame([1], $bindings);
|
||||
$chan->push(2);
|
||||
});
|
||||
|
||||
$res = Db::selectOne('SELECT * FROM `user` WHERE id = ?;', [1]);
|
||||
$this->assertSame('Hyperf', $res->name);
|
||||
$this->assertSame(1, $chan->pop(1));
|
||||
$this->assertSame(2, $chan->pop(1));
|
||||
} finally {
|
||||
Connection::clearBeforeExecutingCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getContainer()
|
||||
{
|
||||
$dispatcher = Mockery::mock(EventDispatcherInterface::class);
|
||||
|
@ -11,7 +11,9 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace Hyperf\DbConnection;
|
||||
|
||||
use Closure;
|
||||
use Generator;
|
||||
use Hyperf\Database\Connection as Conn;
|
||||
use Hyperf\Database\ConnectionInterface;
|
||||
use Hyperf\Database\ConnectionResolverInterface;
|
||||
use Hyperf\Database\Query\Builder;
|
||||
@ -33,12 +35,12 @@ use Psr\Container\ContainerInterface;
|
||||
* @method static int affectingStatement(string $query, array $bindings = [])
|
||||
* @method static bool unprepared(string $query)
|
||||
* @method static array prepareBindings(array $bindings)
|
||||
* @method static mixed transaction(\Closure $callback, int $attempts = 1)
|
||||
* @method static mixed transaction(Closure $callback, int $attempts = 1)
|
||||
* @method static void beginTransaction()
|
||||
* @method static void rollBack()
|
||||
* @method static void commit()
|
||||
* @method static int transactionLevel()
|
||||
* @method static array pretend(\Closure $callback)
|
||||
* @method static array pretend(Closure $callback)
|
||||
* @method static ConnectionInterface connection(string $pool)
|
||||
*/
|
||||
class Db
|
||||
@ -69,4 +71,9 @@ class Db
|
||||
$resolver = $this->container->get(ConnectionResolverInterface::class);
|
||||
return $resolver->connection($name);
|
||||
}
|
||||
|
||||
public static function beforeExecuting(Closure $closure): void
|
||||
{
|
||||
Conn::beforeExecuting($closure);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user