Completed
Pull Request — master (#3697)
by
unknown
60:41
created

PingCommand::execute()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 12
rs 9.6111
cc 5
nc 3
nop 2
1
<?php
2
3
namespace Doctrine\DBAL\Tools\Console\Command;
4
5
use Doctrine\DBAL\Connection;
6
use RuntimeException;
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Throwable;
12
use function is_numeric;
13
use function sleep;
14
use function sprintf;
15
16
class PingCommand extends Command
17
{
18
    protected function configure()
19
    {
20
        $this
21
            ->setName('dbal:ping')
22
            ->setDescription('Check db is available')
23
            ->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Max number of pings to try', '1')
24
            ->addOption('sleep', null, InputOption::VALUE_REQUIRED, 'Length of time (seconds) to sleep between pings', '1')
25
            ->setHelp(<<<EOT
26
Connects to the database to check if it is accessible.
27
28
The exit code will be non-zero when the connection fails.
29
EOT
30
            );
31
    }
32
33
    protected function execute(InputInterface $input, OutputInterface $output) : int
34
    {
35
        $limit = $input->getOption('limit');
36
        if (! is_numeric($limit) || $limit < 0) {
37
            throw new RuntimeException('Option "limit" must contain a positive integer value');
38
        }
39
        $sleep = $input->getOption('sleep');
40
        if (! is_numeric($sleep) || $sleep < 0) {
41
            throw new RuntimeException('Option "sleep" must contain a positive integer value');
42
        }
43
44
        return $this->waitForPing($this->getHelper('db')->getConnection(), (int) $limit, (int) $sleep, $output);
45
    }
46
47
    /**
48
     * @return int > 0 for error
49
     */
50
    private function waitForPing(Connection $conn, int $limit, int $sleep, OutputInterface $output) : int
51
    {
52
        while (true) {
53
            $last = $this->ping($conn, $output);
54
            if ($last === 0 || --$limit <= 0) {
55
                break;
56
            }
57
            sleep($sleep);
58
        }
59
60
        return $last;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $last does not seem to be defined for all execution paths leading up to this point.
Loading history...
61
    }
62
63
    /**
64
     * @return int > 0 for error
65
     */
66
    private function ping(Connection $conn, OutputInterface $output) : int
67
    {
68
        try {
69
            if ($conn->ping()) {
70
                return 0;
71
            }
72
73
            $output->writeln('Ping failed');
74
75
            return 1;
76
        } catch (Throwable $e) {
77
            $output->writeln(sprintf('Ping failed: <error>%s</error>', $e->getMessage()));
78
79
            return 2;
80
        }
81
    }
82
}
83