22
33namespace Barryvdh \Debugbar \Support ;
44
5- use DB ;
65use Exception ;
76use Illuminate \Database \ConnectionInterface ;
7+ use Illuminate \Database \QueryException ;
8+ use Illuminate \Support \Facades \DB ;
89use Illuminate \Support \Facades \Http ;
910
1011class Explain
1112{
12- public function confirm (string $ connection ): ?string
13+ public function isVisualExplainSupported (string $ connection ): bool
14+ {
15+ $ driver = DB ::connection ($ connection )->getDriverName ();
16+ if ($ driver === 'pgsql ' ) {
17+ return true ;
18+ }
19+ if ($ driver === 'mysql ' ) {
20+ // Laravel 11 added a new MariaDB database driver but older Laravel versions handle MySQL and MariaDB with
21+ // the same driver - and even with new versions you can use the MySQL driver while connection to a MariaDB
22+ // database. This query uses a feature implemented only in MariaDB to differentiate them.
23+ try {
24+ DB ::connection ($ connection )->select ('SELECT * FROM seq_1_to_1 ' );
25+
26+ return false ;
27+ } catch (QueryException ) {
28+ // This exception is expected when using MySQL as sequence tables are only available with MariaDB. So
29+ // the exception gets silenced as the check for MySQL has succeeded.
30+ return true ;
31+ }
32+ }
33+
34+ return false ;
35+ }
36+
37+ public function confirmVisualExplain (string $ connection ): ?string
1338 {
1439 return match (DB ::connection ($ connection )->getDriverName ()) {
1540 'mysql ' => 'The query and EXPLAIN output is sent to mysqlexplain.com. Do you want to continue? ' ,
@@ -23,7 +48,7 @@ public function hash(string $connection, string $sql, array $bindings): string
2348 $ bindings = json_encode ($ bindings );
2449
2550 return match (DB ::connection ($ connection )->getDriverName ()) {
26- 'mysql ' , 'pgsql ' => hash_hmac ('sha256 ' , "{$ connection }:: {$ sql }:: {$ bindings }" , config ('app.key ' )),
51+ 'mariadb ' , ' mysql ' , 'pgsql ' => hash_hmac ('sha256 ' , "{$ connection }:: {$ sql }:: {$ bindings }" , config ('app.key ' )),
2752 default => null ,
2853 };
2954 }
@@ -42,7 +67,7 @@ public function generateRawExplain(string $connection, string $sql, array $bindi
4267 $ connection = DB ::connection ($ connection );
4368
4469 return match ($ driver = $ connection ->getDriverName ()) {
45- 'mysql ' => $ connection ->select ("EXPLAIN {$ sql }" , $ bindings ),
70+ 'mariadb ' , ' mysql ' => $ connection ->select ("EXPLAIN {$ sql }" , $ bindings ),
4671 'pgsql ' => array_column ($ connection ->select ("EXPLAIN {$ sql }" , $ bindings ), 'QUERY PLAN ' ),
4772 default => throw new Exception ("Visual explain not available for driver ' {$ driver }'. " ),
4873 };
@@ -51,13 +76,15 @@ public function generateRawExplain(string $connection, string $sql, array $bindi
5176 public function generateVisualExplain (string $ connection , string $ sql , array $ bindings , string $ hash ): string
5277 {
5378 $ this ->verify ($ connection , $ sql , $ bindings , $ hash );
79+ if (!$ this ->isVisualExplainSupported ($ connection )) {
80+ throw new Exception ('Visual explain not available for this connection. ' );
81+ }
5482
5583 $ connection = DB ::connection ($ connection );
5684
57- return match ($ driver = $ connection ->getDriverName ()) {
85+ return match ($ connection ->getDriverName ()) {
5886 'mysql ' => $ this ->generateVisualExplainMysql ($ connection , $ sql , $ bindings ),
5987 'pgsql ' => $ this ->generateVisualExplainPgsql ($ connection , $ sql , $ bindings ),
60- default => throw new Exception ("Visual explain not available for driver ' {$ driver }'. " ),
6188 };
6289 }
6390
@@ -70,7 +97,7 @@ private function generateVisualExplainMysql(ConnectionInterface $connection, str
7097 'bindings ' => $ bindings ,
7198 'version ' => $ connection ->selectOne ("SELECT VERSION() " )->{'VERSION() ' },
7299 'explain_json ' => $ connection ->selectOne ("EXPLAIN FORMAT=JSON {$ query }" , $ bindings )->EXPLAIN ,
73- 'explain_tree ' => rescue (fn () => $ connection ->selectOne ("EXPLAIN FORMAT=TREE {$ query }" , $ bindings ), report: false )-> EXPLAIN ,
100+ 'explain_tree ' => rescue (fn () => $ connection ->selectOne ("EXPLAIN FORMAT=TREE {$ query }" , $ bindings )-> EXPLAIN , report: false ),
74101 ])->throw ()->json ('url ' );
75102 }
76103
0 commit comments