Completed
Push — master ( ae1aa8...20d020 )
by CodexShaper
02:07
created

PgsqlDumper::getDumpCommand()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace CodexShaper\Dumper\Drivers;
4
5
use CodexShaper\Dumper\Dumper;
6
use Symfony\Component\Process\Exception\ProcessFailedException;
7
8
class PgsqlDumper extends Dumper
9
{
10
    /*@var int*/
11
    protected $port = 5432;
12
    /*@var bool*/
13
    protected $useInserts = false;
14
    /*@var bool*/
15
    protected $createTables = true;
16
17 2
    public function useInserts()
18
    {
19 2
        $this->useInserts = true;
20 2
        return $this;
21
    }
22
23 2
    public function doNotCreateTables()
24
    {
25 2
        $this->createTables = false;
26
27 2
        return $this;
28
    }
29
30
    public function dump(string $destinationPath = "")
31
    {
32
        $destinationPath = !empty($destinationPath) ? '"' . $destinationPath . '"' : '"' . $this->destinationPath . '"';
33
        $dumpCommand     = $this->prepareDumpCommand($destinationPath);
34
        $this->command   = $this->removeExtraSpaces($dumpCommand);
35
        $this->runCommand();
36
    }
37
38
    public function restore(string $restorePath = "")
39
    {
40
        $restorePath    = !empty($restorePath) ? '"' . $restorePath . '"' : '"' . $this->restorePath . '"';
41
        $restoreCommand = $this->prepareRestoreCommand($restorePath);
42
        $this->command  = $this->removeExtraSpaces($restoreCommand);
43
        $this->runCommand();
44
    }
45
46 24
    public function getDumpCommand($destinationPath = '')
47
    {
48 24
        $destinationPath = !empty($destinationPath) ? $destinationPath : $this->destinationPath;
49 24
        $dumpCommand     = $this->prepareDumpCommand($destinationPath);
50
51 24
        return $this->removeExtraSpaces($dumpCommand);
52
    }
53
54 6
    public function getRestoreCommand(string $filePath = '')
55
    {
56 6
        $filePath       = !empty($filePath) ? '"' . $filePath : $this->restorePath;
57 6
        $restoreCommand = $this->prepareRestoreCommand($filePath);
58
59 6
        return $this->removeExtraSpaces($restoreCommand);
60
    }
61
62 24
    protected function prepareDumpCommand(string $destinationPath): string
63
    {
64 24
        $dumpCommand = sprintf(
65 24
            '%s -U %s -h %s %s %s %s %s %s %s',
66 24
            $this->quoteCommand($this->commandBinaryPath . 'pg_dump'),
67 24
            $this->prepareUserName(),
68 24
            $this->prepareHost(),
69 24
            $this->preparePort(),
70 24
            $this->prepareUseInserts(),
71 24
            $this->prepareCreateTables(),
72 24
            $this->prepareIncludeTables(),
73 24
            $this->prepareIgnoreTables(),
74 24
            $this->prepareDatabase()
75
        );
76
77 24
        if ($this->isCompress) {
78 2
            $compressCommand = $this->quoteCommand("{$this->compressBinaryPath}{$this->compressCommand}");
79 2
            return "{$dumpCommand} | {$compressCommand} > \"{$destinationPath}{$this->compressExtension}\"";
80
        }
81 22
        return "{$dumpCommand} > \"{$destinationPath}\"";
82
    }
83
84 6
    protected function prepareRestoreCommand(string $filePath): string
85
    {
86 6
        $restoreCommand = sprintf("%s -U %s -h %s %s %s",
87 6
            $this->quoteCommand($this->commandBinaryPath . 'psql'),
88 6
            $this->prepareUserName(),
89 6
            $this->prepareHost(),
90 6
            $this->preparePort(),
91 6
            $this->prepareDatabase()
92
        );
93
94 6
        if ($this->isCompress) {
95 2
            $compressCommand = $this->quoteCommand("{$this->compressBinaryPath}{$this->compressCommand}");
96 2
            return "{$compressCommand} < \"{$filePath}\" | {$restoreCommand}";
97
        }
98
99 4
        return "{$restoreCommand} < \"{$filePath}\"";
100
    }
101
102
    protected function runCommand()
103
    {
104
        try {
105
106
            $credentials    = $this->host . ':' . $this->port . ':' . $this->dbName . ':' . $this->username . ':' . $this->password;
107
            $this->tempFile = tempnam(sys_get_temp_dir(), 'pgsqlpass');
0 ignored issues
show
Bug Best Practice introduced by
The property tempFile does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
108
            $handler        = fopen($this->tempFile, 'r+');
109
            fwrite($handler, $credentials);
0 ignored issues
show
Bug introduced by
It seems like $handler can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
            fwrite(/** @scrutinizer ignore-type */ $handler, $credentials);
Loading history...
110
            $env     = ['PGPASSFILE' => $this->tempFile];
111
            $process = $this->prepareProcessCommand($this->command);
0 ignored issues
show
Unused Code introduced by
The call to CodexShaper\Dumper\Dumper::prepareProcessCommand() has too many arguments starting with $this->command. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
            /** @scrutinizer ignore-call */ 
112
            $process = $this->prepareProcessCommand($this->command);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
112
            if ($this->debug) {
113
                $process->mustRun(null, $env);
114
            } else {
115
                $process->run(null, $env);
116
            }
117
118
            fclose($handler);
0 ignored issues
show
Bug introduced by
It seems like $handler can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

118
            fclose(/** @scrutinizer ignore-type */ $handler);
Loading history...
119
            unlink($this->tempFile);
120
121
        } catch (ProcessFailedException $e) {
122
            throw new \Exception($e->getMessage());
123
124
        }
125
    }
126
127 24
    public function prepareCreateTables()
128
    {
129 24
        return (!$this->createTables) ? '--data-only' : '';
130
    }
131
132 24
    public function prepareUseInserts()
133
    {
134 24
        return ($this->useInserts) ? '--inserts' : '';
135
    }
136
}
137