Skip to content

Commit

Permalink
[11.x] Enable extension of connection inspection methods (#52231)
Browse files Browse the repository at this point in the history
* Enable extension of connection inspection methods

* Fix CS

* Move the queries to the Grammar classes and show the driver name

* Replace Grammar::getConnectionCount with compileConnectionCount

* Add Connection::getDriverTitle and move compileConnectionCount to the Schema Grammar

* Replace duplicate driver name by the connection name

* New MySQL query

* Move getConnectionCount to Schema\Builder

* Add integration test for Schema::getConnectionCount()

* Fix connection count query for mariadb

* Fix Driver title

* Pluralize ConnectionsCount

* Move Schema::getConnectionsCount to Connection::getThreadsCount

* formatting

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
GromNaN and taylorotwell authored Aug 1, 2024
1 parent eb1d94d commit 05421a0
Show file tree
Hide file tree
Showing 15 changed files with 145 additions and 29 deletions.
22 changes: 22 additions & 0 deletions src/Illuminate/Database/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,18 @@ public function unprepared($query)
});
}

/**
* Get the number of open connections for the database.
*
* @return int|null
*/
public function threadCount()
{
$query = $this->getQueryGrammar()->compileThreadCount();

return $query ? $this->scalar($query) : null;
}

/**
* Execute the given callback in "dry run" mode.
*
Expand Down Expand Up @@ -1347,6 +1359,16 @@ public function getDriverName()
return $this->getConfig('driver');
}

/**
* Get a human-readable name for the given connection driver.
*
* @return string
*/
public function getDriverTitle()
{
return $this->getDriverName();
}

/**
* Get the query grammar used by the connection.
*
Expand Down
33 changes: 7 additions & 26 deletions src/Illuminate/Database/Console/DatabaseInspectionCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
namespace Illuminate\Database\Console;

use Illuminate\Console\Command;
use Illuminate\Database\Connection;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\MariaDbConnection;
use Illuminate\Database\MySqlConnection;
use Illuminate\Database\PostgresConnection;
use Illuminate\Database\SQLiteConnection;
use Illuminate\Database\SqlServerConnection;
use Illuminate\Support\Arr;

abstract class DatabaseInspectionCommand extends Command
Expand All @@ -19,40 +15,25 @@ abstract class DatabaseInspectionCommand extends Command
* @param \Illuminate\Database\ConnectionInterface $connection
* @param string $database
* @return string
*
* @deprecated
*/
protected function getConnectionName(ConnectionInterface $connection, $database)
{
return match (true) {
$connection instanceof MySqlConnection && $connection->isMaria() => 'MariaDB',
$connection instanceof MySqlConnection => 'MySQL',
$connection instanceof MariaDbConnection => 'MariaDB',
$connection instanceof PostgresConnection => 'PostgreSQL',
$connection instanceof SQLiteConnection => 'SQLite',
$connection instanceof SqlServerConnection => 'SQL Server',
default => $database,
};
return $connection->getDriverTitle();
}

/**
* Get the number of open connections for a database.
*
* @param \Illuminate\Database\ConnectionInterface $connection
* @return int|null
*
* @deprecated
*/
protected function getConnectionCount(ConnectionInterface $connection)
{
$result = match (true) {
$connection instanceof MySqlConnection => $connection->selectOne('show status where variable_name = "threads_connected"'),
$connection instanceof PostgresConnection => $connection->selectOne('select count(*) as "Value" from pg_stat_activity'),
$connection instanceof SqlServerConnection => $connection->selectOne('select count(*) Value from sys.dm_exec_sessions where status = ?', ['running']),
default => null,
};

if (! $result) {
return null;
}

return Arr::wrap((array) $result)['Value'];
return $connection->threadCount();
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/Illuminate/Database/Console/MonitorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ protected function parseDatabases($databases)

$maxConnections = $this->option('max');

$connections = $this->connection->connection($database)->threadCount();

return [
'database' => $database,
'connections' => $connections = $this->getConnectionCount($this->connection->connection($database)),
'connections' => $connections,
'status' => $maxConnections && $connections >= $maxConnections ? '<fg=yellow;options=bold>ALERT</>' : '<fg=green;options=bold>OK</>',
];
});
Expand Down
6 changes: 4 additions & 2 deletions src/Illuminate/Database/Console/ShowCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ public function handle(ConnectionResolverInterface $connections)
$data = [
'platform' => [
'config' => $this->getConfigFromDatabase($database),
'name' => $this->getConnectionName($connection, $database),
'name' => $connection->getDriverTitle(),
'connection' => $connection->getName(),
'version' => $connection->getServerVersion(),
'open_connections' => $this->getConnectionCount($connection),
'open_connections' => $connection->threadCount(),
],
'tables' => $this->tables($connection, $schema),
];
Expand Down Expand Up @@ -159,6 +160,7 @@ protected function displayForCli(array $data)
$this->newLine();

$this->components->twoColumnDetail('<fg=green;options=bold>'.$platform['name'].'</>', $platform['version']);
$this->components->twoColumnDetail('Connection', Arr::get($platform['config'], 'connection'));
$this->components->twoColumnDetail('Database', Arr::get($platform['config'], 'database'));
$this->components->twoColumnDetail('Host', Arr::get($platform['config'], 'host'));
$this->components->twoColumnDetail('Port', Arr::get($platform['config'], 'port'));
Expand Down
8 changes: 8 additions & 0 deletions src/Illuminate/Database/MariaDbConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@

class MariaDbConnection extends MySqlConnection
{
/**
* {@inheritdoc}
*/
public function getDriverTitle()
{
return 'MariaDB';
}

/**
* Determine if the connected database is a MariaDB database.
*
Expand Down
8 changes: 8 additions & 0 deletions src/Illuminate/Database/MySqlConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@

class MySqlConnection extends Connection
{
/**
* {@inheritdoc}
*/
public function getDriverTitle()
{
return $this->isMaria() ? 'MariaDB' : 'MySQL';
}

/**
* Escape a binary value for safe SQL embedding.
*
Expand Down
8 changes: 8 additions & 0 deletions src/Illuminate/Database/PostgresConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@

class PostgresConnection extends Connection
{
/**
* {@inheritdoc}
*/
public function getDriverTitle()
{
return 'PostgreSQL';
}

/**
* Escape a binary value for safe SQL embedding.
*
Expand Down
10 changes: 10 additions & 0 deletions src/Illuminate/Database/Query/Grammars/Grammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,16 @@ protected function compileLock(Builder $query, $value)
return is_string($value) ? $value : '';
}

/**
* Compile a query to get the number of open connections for a database.
*
* @return string|null
*/
public function compileThreadCount()
{
return null;
}

/**
* Determine if the grammar supports savepoints.
*
Expand Down
10 changes: 10 additions & 0 deletions src/Illuminate/Database/Query/Grammars/MariaDbGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ public function compileJsonValueCast($value)
return "json_query({$value}, '$')";
}

/**
* Compile a query to get the number of open connections for a database.
*
* @return string
*/
public function compileThreadCount()
{
return 'select variable_value as `Value` from information_schema.global_status where variable_name = \'THREADS_CONNECTED\'';
}

/**
* Determine whether to use a legacy group limit clause for MySQL < 8.0.
*
Expand Down
10 changes: 10 additions & 0 deletions src/Illuminate/Database/Query/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,16 @@ protected function compileDeleteWithoutJoins(Builder $query, $table, $where)
return $sql;
}

/**
* Compile a query to get the number of open connections for a database.
*
* @return string
*/
public function compileThreadCount()
{
return 'select variable_value as `Value` from performance_schema.session_status where variable_name = \'threads_connected\'';
}

/**
* Wrap a single string in keyword identifiers.
*
Expand Down
10 changes: 10 additions & 0 deletions src/Illuminate/Database/Query/Grammars/PostgresGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,16 @@ public function compileTruncate(Builder $query)
return ['truncate '.$this->wrapTable($query->from).' restart identity cascade' => []];
}

/**
* Compile a query to get the number of open connections for a database.
*
* @return string
*/
public function compileThreadCount()
{
return 'select count(*) as "Value" from pg_stat_activity';
}

/**
* Wrap the given JSON selector.
*
Expand Down
10 changes: 10 additions & 0 deletions src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,16 @@ public function compileSavepointRollBack($name)
return 'ROLLBACK TRANSACTION '.$name;
}

/**
* Compile a query to get the number of open connections for a database.
*
* @return string
*/
public function compileThreadCount()
{
return 'select count(*) Value from sys.dm_exec_sessions where status = N\'running\'';
}

/**
* Get the format for database stored dates.
*
Expand Down
8 changes: 8 additions & 0 deletions src/Illuminate/Database/SQLiteConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public function __construct($pdo, $database = '', $tablePrefix = '', array $conf
$this->configureSynchronous();
}

/**
* {@inheritdoc}
*/
public function getDriverTitle()
{
return 'SQLite';
}

/**
* Enable or disable foreign key constraints if configured.
*
Expand Down
8 changes: 8 additions & 0 deletions src/Illuminate/Database/SqlServerConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@

class SqlServerConnection extends Connection
{
/**
* {@inheritdoc}
*/
public function getDriverTitle()
{
return 'SQL Server';
}

/**
* Execute a Closure within a transaction.
*
Expand Down
19 changes: 19 additions & 0 deletions tests/Integration/Database/ConnectionThreadsCountTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Illuminate\Tests\Integration\Database;

use Illuminate\Support\Facades\DB;

class ConnectionThreadsCountTest extends DatabaseTestCase
{
public function testGetThreadsCount()
{
$count = DB::connection()->threadCount();

if ($this->driver === 'sqlite') {
$this->assertNull($count, 'SQLite does not support connection count');
} else {
$this->assertGreaterThanOrEqual(1, $count);
}
}
}

0 comments on commit 05421a0

Please sign in to comment.