Closed MarkusJLechner closed 1 month ago
Hey, it would totally make sense if the addDatabaseQuery
helper incremented query counts, I'll look into adding it for the next release.
As a workaround for now, you can increment the database queries yourself in your own wrapper like this:
$request = clock()->request();
// Increment the total query count
$request->databaseQueriesCount++;
// Increment query count of a particular type
$request->databaseSelects++;
$request->databaseInserts++;
$request->databaseUpdates++;
$request->databaseDeletes++;
$request->databaseOthers++;
Thanks for the workaround.
Its a littly hacky but does the job. Here to share my code, which tracks all PDO executes:
<?php
namespace App\Database;
use PDOStatement;
use Clockwork\Helpers\{ Serializer, StackTrace };
class TrackPDOStatement extends PDOStatement
{
protected function __construct()
{
}
public function execute($params = null): bool
{
return $this->trackSql(fn() => parent::execute($params), $this->queryString, $params ?? [], 2);
}
private function trackSql(callable $callback, string $query, array $bindings, int $tracesSkip = 0)
{
if (str_starts_with(strtolower(trim($query)), 'set ')) {
return $callback();
}
$trace = (new Serializer(['tracesSkip' => $tracesSkip]))->trace(StackTrace::get());
$containsQueryBuilder = false;
foreach ($trace as $traceStep) {
if (isset($traceStep['call']) && str_contains($traceStep['call'], 'Illuminate\Database\Query\Builder')) {
$containsQueryBuilder = true;
break;
}
}
$time = microtime(true);
$result = $callback();
$executionTime = (microtime(true) - $time) * 1000;
// Add the database query only if "Illuminate\Database\Query\Builder" is not in the call stack
if (!$containsQueryBuilder) {
clock()->addDatabaseQuery($query, $bindings, $executionTime, ['trace' => $trace, 'model' => 'PDO', 'connection' => 'mysql']);
// See https://github.com/itsgoingd/clockwork/issues/703#issuecomment-2177763487
// Maybe fixed in future
$request = clock()->request();
$sql = ltrim($query);
$request->databaseQueriesCount++;
if (preg_match('/^select\b/i', $sql)) {
$request->databaseSelects++;
} elseif (preg_match('/^insert\b/i', $sql)) {
$request->databaseInserts++;
} elseif (preg_match('/^update\b/i', $sql)) {
$request->databaseUpdates++;
} elseif (preg_match('/^delete\b/i', $sql)) {
$request->databaseDeletes++;
} else {
$request->databaseOthers++;
}
}
return $result;
}
}
in laravel i just add to DatabaseProvider
class DatabaseProvider extends ServiceProvider
{
public function register(): void
{
if ($this->app->environment('local')) {
config()->set('database.connections.mysql.options.' . PDO::ATTR_STATEMENT_CLASS, [TrackPDOStatement::class, []]);
}
}
}
This is now implemented in master (https://github.com/itsgoingd/clockwork/commit/bbcefdf1e32540e9a2de5fbd1eacbb77d3f50bda) and will be released in Clockwork 5.3.
We have converted a legacy project to Laravel and still have many vanilla DB fetches.
We created a wrapper above PDOStatement to log all queries, excluding those made by Laravel's query builder. This works well, but I noticed that the total query count is incorrect. It only counts when the Laravel query event is triggered, but not when calling
clock()->addDatabaseQuery
as described in the docs.Is there a way to increase the count? Instead of using
addDatabaseQuery
, I tried manually triggering the Laravel query event, but then I cannot pass options like trace skipping.Any advice on how to properly increase the count?