Database Explorer insert() vrací null
- libik
- Člen | 96
Ahoj,
snažím se zprovoznit logování SQL dotazů do databáze (pro INSERT a UPDATE). Našel jsem, že by k tomu šla využít událost Nette\Database\Connection událost onQuery.
Logování probíhá tak, že při ukládání záznamu A do db
v libovolné fasádě se spustí onQuery, kteoru mám ve službě dblogger a
uloží se záznam B do logovací tabulky.
V takovém případě ale Nette\Database\Explorer insert() nevrátí ActiveRow
s vloženým záznamem A, ale vrátí null.
Zřejmě je to vlastnost, protože mezi vrácením ActiveRow proběhne ještě další ukládání do databáze logerem. Když logger vypustím, ActiveRow dostanu. Lze to ale nějak ošetřit?
fasáda (v ní je právě $row null):
class UzivateleFacade implements Authenticator
{
private Explorer $database;
private Passwords $passwords;
/**
*
* @param \Nette\Database\Explorer $database
* @param \Nette\Security\Passwords $passwords
*/
public function __construct(Explorer $database, Passwords $passwords, DbLogger $dblogger)
{
$this->database = $database;
$this->passwords = $passwords;
$this->dblogger = $dblogger;
}
/**
*
* @param \Nette\Utils\ArrayHash $user
* @return void
*/
public function create(\Nette\Utils\ArrayHash $user): void
{
$row = $this->database->table('uzivatele')->insert([
'jmeno' => $user->jmeno,
'heslo' => $this->passwords->hash($user->heslo),
'id_skupiny' => 0,
'aktivni' => $user->aktivni
]);
}
sluzba dblogger (vypíchnuto jen to podstatné)
class DbLogger
{
use \Nette\SmartObject;
private LogFacade $logFacade;
private Connection $connection;
protected Application $application;
public function __construct(Connection $connection, LogFacade $logFacade, Application $application)
{
$connection->onQuery[] = \Closure::fromCallable([$this, 'logSql']);
$this->logFacade = $logFacade;
$this->application = $application;
}
public function logSql(Connection $connection, ResultSet|DriverException $result): Connection
{
$this->logFacade->create($log);
}
}
fasáda pro dblogger
class LogFacade
{
private Explorer $database;
/**
*
* @param \Nette\Database\Explorer $database
*/
public function __construct(Explorer $database)
{
$this->database = $database;
}
public function create($log): void
{
$this->database->table('log')->insert([
'datum' => new \Nette\Utils\DateTime(),
'zdroj' => $log->getZdroj(),
'log' => $log->getLog(),
'skript' => $log->getSkript(),
'chyba' => $log->getChyba()]);
}
}
Díky za nějaký tip.
L
- uestla
- Backer | 799
@libik Napadá mě přidat stavový boolean
do loggeru,
který řekne, že „se právě loguje“.
Něco ve stylu
class DbLogger
{
private bool $logging = false;
public function logSql(...)
{
if ($this->logging) {
return ;
}
$this->logging = true;
$this->logFacade->create($log);
$this->logging = false;
}
}
Tím pádem se ti query, které vyvolá fasáda, nebude logovat.