barryvdh / laravel-debugbar

Debugbar for Laravel (Integrates PHP Debug Bar)
MIT License
17.05k stars 1.54k forks source link

Track queries when using DB raw pdo #1477

Closed raicabogdan closed 11 months ago

raicabogdan commented 11 months ago

Hello,

I'm currently using DB::getRawPdo() to get the pdo instance and run some custom queries. I find it much easier to run them myself for cases where PDO::FECTCH_GROUP makes quick work of the query result instead of manually grouping them.

At the same time, perhaps I don't need the entire eloquent power to get a result that I need from some particular select, I just need the result into an array as fast as possible and be done with it. Using with(), whereHas() to filter relationships and then grouping them is much more complicated then just running my own query and using pdo's FETCH_GROUP or other fetch options, that is just an example ...

The downside is that in case I make some logic mistake, I can't see the queries I made in the debugbar. I'm not sure if this was previously discussed before, but is there way to create a wrapper manually around the rawPdo() to still have the tracking available in debugbar?

Thanks!

erikn69 commented 11 months ago

try doing a macro

\Illuminate\Database\Connection::macro('selectWithFetch',
    function ($query, $bindings = [], $fetchMode = \PDO::FETCH_OBJ, $useReadPdo = true) {
      return $this->run($query, $bindings, function ($query, $bindings) use ($fetchMode, $useReadPdo) {
          if ($this->pretending()) {
              return [];
          }

          $statement = $this->prepared(
              $this->getPdoForSelect($useReadPdo)->prepare($query)
          );

          $this->bindValues($statement, $this->prepareBindings($bindings));

          $statement->execute();

          return $statement->fetchAll($fetchMode);
      });
  });
// USAGE:
\DB::selectWithFetch('YOUR_RAW_QUERY', [/*YOUR_BINDINGS*/], \PDO::FETCH_GROUP | \PDO::FETCH_ASSOC);
raicabogdan commented 11 months ago

Hello,

@erikn69 your solution I like more than mine, my approach was to make a trait and create specific fetch methods for fetch() and fetchAll() , for example, one method will be like:

public function query($query, $bindings, $fetchMode = \PDO::FETCH_ASSOC): bool|array
{
    if(config('app.env') === 'local') {
        $start = microtime(true);
    }

    $statement = DB::getRawPdo()->prepare($query);
    $statement->execute($bindings);
    $result = $statement->fetchAll($fetchMode);

    if(config('app.env') === 'local') {
        $end = microtime(true);
        DB::logQuery($query, $bindings, ($end-$start) * 1000);
    }

    return $result;
}

Not exactly sure which way to go yet, but again, thank you!

erikn69 commented 11 months ago

My solution sends query to laravel debugbar tab Also my solution prepares bindings, it is much better and cleaner.

raicabogdan commented 11 months ago

right, thank you! Will close this as it has been answered.

raicabogdan commented 11 months ago

My solution sends query to laravel debugbar tab Also my solution prepares bindings, it is much better and cleaner.

It works well, thanks!