Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
199 lars 1
<?php namespace Clockwork\DataSource\Concerns;
2
 
3
use Clockwork\Helpers\StackFilter;
4
use Clockwork\Helpers\StackTrace;
5
use Clockwork\Request\Log;
6
use Clockwork\Request\Request;
7
 
8
// Duplicate (N+1) queries detection for EloquentDataSource, inspired by the beyondcode/laravel-query-detector package
9
// by Marcel Pociot (https://github.com/beyondcode/laravel-query-detector)
10
trait EloquentDetectDuplicateQueries
11
{
12
	protected $duplicateQueries = [];
13
 
14
	protected function appendDuplicateQueriesWarnings(Request $request)
15
	{
16
		$log = new Log;
17
 
18
		foreach ($this->duplicateQueries as $query) {
19
			if ($query['count'] <= 1) continue;
20
 
21
			$log->warning(
22
				"N+1 queries: {$query['model']}::{$query['relation']} loaded {$query['count']} times.",
23
				[ 'performance' => true, 'trace' => $query['trace'] ]
24
			);
25
		}
26
 
27
		$request->log()->merge($log);
28
	}
29
 
30
	protected function detectDuplicateQuery(StackTrace $trace)
31
	{
32
		$relationFrame = $trace->first(function ($frame) {
33
			return $frame->function == 'getRelationValue'
34
				|| $frame->class == \Illuminate\Database\Eloquent\Relations\Relation::class;
35
		});
36
 
37
		if (! $relationFrame || ! $relationFrame->object) return;
38
 
39
		if ($relationFrame->class == \Illuminate\Database\Eloquent\Relations\Relation::class) {
40
			$model = get_class($relationFrame->object->getParent());
41
			$relation = get_class($relationFrame->object->getRelated());
42
		} else {
43
			$model = get_class($relationFrame->object);
44
			$relation = $relationFrame->args[0];
45
		}
46
 
47
		$shortTrace = $trace->skip(StackFilter::make()
48
			->isNotVendor([ 'itsgoingd', 'laravel', 'illuminate' ])
49
			->isNotNamespace([ 'Clockwork', 'Illuminate' ]));
50
 
51
		$hash = implode('-', [ $model, $relation, $shortTrace->first()->file, $shortTrace->first()->line ]);
52
 
53
		if (! isset($this->duplicateQueries[$hash])) {
54
			$this->duplicateQueries[$hash] = [
55
				'count'    => 0,
56
				'model'    => $model,
57
				'relation' => $relation,
58
				'trace'    => $trace
59
			];
60
		}
61
 
62
		$this->duplicateQueries[$hash]['count']++;
63
	}
64
}