Skip to content

Commit bf4b5ce

Browse files
authored
Merge pull request #61208 from nextcloud/artonge/fix/psalm_from_60840
fix: Psalm errors from #60840
2 parents d1762f1 + 9f6984d commit bf4b5ce

7 files changed

Lines changed: 207 additions & 200 deletions

File tree

composer.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/Command/Db/DbIndexUsage.php

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public function __construct(
2525
parent::__construct();
2626
}
2727

28+
#[\Override]
2829
protected function configure(): void {
2930
$this
3031
->setName('db:index-usage')
@@ -33,39 +34,36 @@ protected function configure(): void {
3334
->addOption('all', null, InputOption::VALUE_NONE, 'Show all indexes, not just unused ones');
3435
}
3536

37+
#[\Override]
3638
protected function execute(InputInterface $input, OutputInterface $output): int {
3739
$platform = $this->connection->getDatabasePlatform();
38-
$asJson = $input->getOption('json');
39-
$showAll = $input->getOption('all');
40+
$asJson = $input->getOption('json');
41+
$showAll = $input->getOption('all');
4042

4143
if ($platform instanceof MySQLPlatform) {
4244
// Requires performance_schema to be enabled (default in MySQL 5.6+/MariaDB 10.0+)
4345
$unused_filter = $showAll ? '' : "WHERE s.count_read = 0 AND s.index_name IS NOT NULL AND s.index_name != 'PRIMARY'";
44-
$sql = "
45-
SELECT s.object_name AS `table`,
46-
s.index_name AS `index`,
47-
s.count_read AS reads,
48-
s.count_write AS writes
46+
$sql = "SELECT s.object_name AS `table`,
47+
s.index_name AS `index`,
48+
s.count_read AS reads,
49+
s.count_write AS writes
4950
FROM performance_schema.table_io_waits_summary_by_index_usage s
5051
{$unused_filter}
51-
ORDER BY s.object_name, s.index_name
52-
";
52+
ORDER BY s.object_name, s.index_name";
5353
} elseif ($platform instanceof PostgreSQLPlatform) {
5454
$unused_filter = $showAll ? '' : 'AND idx_scan = 0';
55-
$sql = "
56-
SELECT relname AS table,
57-
indexrelname AS index,
58-
idx_scan AS reads,
59-
idx_tup_read AS tuples_read,
60-
idx_tup_fetch AS tuples_fetched
55+
$sql = "SELECT relname AS table,
56+
indexrelname AS index,
57+
idx_scan AS reads,
58+
idx_tup_read AS tuples_read,
59+
idx_tup_fetch AS tuples_fetched
6160
FROM pg_stat_user_indexes
6261
JOIN pg_index USING (indexrelid)
6362
WHERE indisunique IS FALSE
6463
{$unused_filter}
65-
ORDER BY relname, indexrelname
66-
";
64+
ORDER BY relname, indexrelname";
6765
} else {
68-
$output->writeln('<comment>db:index-usage is not supported for SQLite.</comment>');
66+
$output->writeln('<comment>db:index-usage is not supported for SQLite and Oracle.</comment>');
6967
return Command::SUCCESS;
7068
}
7169

@@ -105,7 +103,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
105103

106104
if (!$showAll) {
107105
$output->writeln(sprintf(
108-
'<comment>Found %d unused index(es). Consider removing them to improve write performance.</comment>',
106+
'<comment>Found %d unused index(es). If those were not created by Nextcloud, consider removing them to improve write performance.</comment>',
109107
count($rows)
110108
));
111109
}

core/Command/Db/DbInfo.php

Lines changed: 100 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -20,102 +20,104 @@
2020

2121
class DbInfo extends Command {
2222

23-
public function __construct(
24-
private readonly Connection $connection,
25-
) {
26-
parent::__construct();
27-
}
28-
29-
protected function configure(): void {
30-
$this
31-
->setName('db:info')
32-
->setDescription('Show database server information and configuration health check')
33-
->addOption('json', null, InputOption::VALUE_NONE, 'Output in JSON format');
34-
}
35-
36-
protected function execute(InputInterface $input, OutputInterface $output): int {
37-
$platform = $this->connection->getDatabasePlatform();
38-
$asJson = $input->getOption('json');
39-
40-
if ($platform instanceof MySQLPlatform) {
41-
$rows = $this->getMySQLInfo();
42-
} elseif ($platform instanceof PostgreSQLPlatform) {
43-
$rows = $this->getPostgreSQLInfo();
44-
} elseif ($platform instanceof SqlitePlatform) {
45-
$rows = $this->getSQLiteInfo();
46-
} else {
47-
$output->writeln('<error>Unsupported database platform.</error>');
48-
return Command::FAILURE;
49-
}
50-
51-
if ($asJson) {
52-
$output->writeln(json_encode($rows, JSON_PRETTY_PRINT));
53-
return Command::SUCCESS;
54-
}
55-
56-
$table = new Table($output);
57-
$table->setHeaders(['Setting', 'Value', 'Recommended', 'Status']);
58-
59-
foreach ($rows as $row) {
60-
$status = isset($row['recommended'])
61-
? ($row['ok'] ? '<info>OK</info>' : '<comment>CHECK</comment>')
62-
: '';
63-
$table->addRow([
64-
$row['setting'],
65-
$row['value'],
66-
$row['recommended'] ?? '',
67-
$status,
68-
]);
69-
}
70-
71-
$table->render();
72-
return Command::SUCCESS;
73-
}
74-
75-
private function getMySQLInfo(): array {
76-
$result = $this->connection->executeQuery(
77-
"SELECT VERSION() AS version, @@innodb_buffer_pool_size AS buffer_pool,
78-
@@max_connections AS max_conn, @@character_set_database AS charset,
79-
@@transaction_isolation AS tx_isolation"
80-
);
81-
$info = $result->fetchAssociative();
82-
83-
$bufferPoolGB = round(($info['buffer_pool'] / 1024 / 1024 / 1024), 2);
84-
85-
return [
86-
['setting' => 'Engine', 'value' => 'MySQL/MariaDB'],
87-
['setting' => 'Version', 'value' => $info['version']],
88-
['setting' => 'Character Set', 'value' => $info['charset'], 'recommended' => 'utf8mb4', 'ok' => str_contains($info['charset'], 'utf8mb4')],
89-
['setting' => 'Max Connections', 'value' => $info['max_conn'], 'recommended' => '≥ 150', 'ok' => (int)$info['max_conn'] >= 150],
90-
['setting' => 'InnoDB Buffer Pool (GB)','value' => $bufferPoolGB, 'recommended' => '≥ 1 GB', 'ok' => $bufferPoolGB >= 1],
91-
['setting' => 'Transaction Isolation', 'value' => $info['tx_isolation'], 'recommended' => 'READ-COMMITTED', 'ok' => $info['tx_isolation'] === 'READ-COMMITTED'],
92-
];
93-
}
94-
95-
private function getPostgreSQLInfo(): array {
96-
$result = $this->connection->executeQuery(
97-
"SELECT version(),
98-
current_setting('max_connections') AS max_conn,
99-
current_setting('shared_buffers') AS shared_buffers,
100-
current_setting('work_mem') AS work_mem"
101-
);
102-
$info = $result->fetchAssociative();
103-
104-
return [
105-
['setting' => 'Engine', 'value' => 'PostgreSQL'],
106-
['setting' => 'Version', 'value' => $info['version']],
107-
['setting' => 'Max Connections', 'value' => $info['max_conn'], 'recommended' => '≥ 100', 'ok' => (int)$info['max_conn'] >= 100],
108-
['setting' => 'Shared Buffers', 'value' => $info['shared_buffers'],'recommended' => '128MB+', 'ok' => true],
109-
['setting' => 'Work Mem', 'value' => $info['work_mem'], 'recommended' => '4MB+', 'ok' => true],
110-
];
111-
}
112-
113-
private function getSQLiteInfo(): array {
114-
$result = $this->connection->executeQuery('SELECT sqlite_version() AS version');
115-
$info = $result->fetchAssociative();
116-
return [
117-
['setting' => 'Engine', 'value' => 'SQLite'],
118-
['setting' => 'Version', 'value' => $info['version']],
119-
];
120-
}
23+
public function __construct(
24+
private readonly Connection $connection,
25+
) {
26+
parent::__construct();
27+
}
28+
29+
#[\Override]
30+
protected function configure(): void {
31+
$this
32+
->setName('db:info')
33+
->setDescription('Show database server information and configuration health check')
34+
->addOption('json', null, InputOption::VALUE_NONE, 'Output in JSON format');
35+
}
36+
37+
#[\Override]
38+
protected function execute(InputInterface $input, OutputInterface $output): int {
39+
$platform = $this->connection->getDatabasePlatform();
40+
$asJson = $input->getOption('json');
41+
42+
if ($platform instanceof MySQLPlatform) {
43+
$rows = $this->getMySQLInfo();
44+
} elseif ($platform instanceof PostgreSQLPlatform) {
45+
$rows = $this->getPostgreSQLInfo();
46+
} elseif ($platform instanceof SqlitePlatform) {
47+
$rows = $this->getSQLiteInfo();
48+
} else {
49+
$output->writeln('<error>Unsupported database platform.</error>');
50+
return Command::FAILURE;
51+
}
52+
53+
if ($asJson) {
54+
$output->writeln(json_encode($rows, JSON_PRETTY_PRINT));
55+
return Command::SUCCESS;
56+
}
57+
58+
$table = new Table($output);
59+
$table->setHeaders(['Setting', 'Value', 'Recommended', 'Status']);
60+
61+
foreach ($rows as $row) {
62+
$status = isset($row['recommended'])
63+
? ($row['ok'] ? '<info>OK</info>' : '<comment>CHECK</comment>')
64+
: '';
65+
$table->addRow([
66+
$row['setting'],
67+
$row['value'],
68+
$row['recommended'] ?? '',
69+
$status,
70+
]);
71+
}
72+
73+
$table->render();
74+
return Command::SUCCESS;
75+
}
76+
77+
private function getMySQLInfo(): array {
78+
$result = $this->connection->executeQuery(
79+
"SELECT VERSION() AS version, @@innodb_buffer_pool_size AS buffer_pool,
80+
@@max_connections AS max_conn, @@character_set_database AS charset,
81+
@@transaction_isolation AS tx_isolation"
82+
);
83+
$info = $result->fetchAssociative();
84+
85+
$bufferPoolGB = round(($info['buffer_pool'] / 1024 / 1024 / 1024), 2);
86+
87+
return [
88+
['setting' => 'Engine', 'value' => 'MySQL/MariaDB'],
89+
['setting' => 'Version', 'value' => $info['version']],
90+
['setting' => 'Character Set', 'value' => $info['charset'], 'recommended' => 'utf8mb4', 'ok' => str_contains($info['charset'], 'utf8mb4')],
91+
['setting' => 'Max Connections', 'value' => $info['max_conn'], 'recommended' => '≥ 150', 'ok' => (int)$info['max_conn'] >= 150],
92+
['setting' => 'InnoDB Buffer Pool (GB)','value' => $bufferPoolGB, 'recommended' => '≥ 1 GB', 'ok' => $bufferPoolGB >= 1],
93+
['setting' => 'Transaction Isolation', 'value' => $info['tx_isolation'], 'recommended' => 'READ-COMMITTED', 'ok' => $info['tx_isolation'] === 'READ-COMMITTED'],
94+
];
95+
}
96+
97+
private function getPostgreSQLInfo(): array {
98+
$result = $this->connection->executeQuery(
99+
"SELECT version(),
100+
current_setting('max_connections') AS max_conn,
101+
current_setting('shared_buffers') AS shared_buffers,
102+
current_setting('work_mem') AS work_mem"
103+
);
104+
$info = $result->fetchAssociative();
105+
106+
return [
107+
['setting' => 'Engine', 'value' => 'PostgreSQL'],
108+
['setting' => 'Version', 'value' => $info['version']],
109+
['setting' => 'Max Connections', 'value' => $info['max_conn'], 'recommended' => '≥ 100', 'ok' => (int)$info['max_conn'] >= 100],
110+
['setting' => 'Shared Buffers', 'value' => $info['shared_buffers'],'recommended' => '128MB+', 'ok' => true],
111+
['setting' => 'Work Mem', 'value' => $info['work_mem'], 'recommended' => '4MB+', 'ok' => true],
112+
];
113+
}
114+
115+
private function getSQLiteInfo(): array {
116+
$result = $this->connection->executeQuery('SELECT sqlite_version() AS version');
117+
$info = $result->fetchAssociative();
118+
return [
119+
['setting' => 'Engine', 'value' => 'SQLite'],
120+
['setting' => 'Version', 'value' => $info['version']],
121+
];
122+
}
121123
}

0 commit comments

Comments
 (0)