SyncerDb::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.032

Importance

Changes 8
Bugs 1 Features 1
Metric Value
c 8
b 1
f 1
dl 0
loc 18
ccs 8
cts 10
cp 0.8
rs 9.4285
cc 2
eloc 13
nc 2
nop 4
crap 2.032
1
<?php
2
3
namespace Velikonja\LabbyBundle\Database;
4
5
use Symfony\Component\Console\Output\NullOutput;
6
use Symfony\Component\Console\Output\OutputInterface;
7
use Symfony\Component\Process\Process;
8
use Velikonja\LabbyBundle\Command\DumpCommand;
9
use Velikonja\LabbyBundle\Remote\Ssh;
10
use Velikonja\LabbyBundle\Remote\Scp;
11
use Velikonja\LabbyBundle\Util\ZipArchive;
12
13
class SyncerDb
14
{
15
    /**
16
     * @var ImporterInterface
17
     */
18
    private $importer;
19
20
    /**
21
     * @var Ssh
22
     */
23
    private $ssh;
24
25
    /**
26
     * @var Scp
27
     */
28
    private $scp;
29
30
    /**
31
     * @var ZipArchive
32
     */
33
    private $zip;
34
35
    /**
36
     * @var string
37
     */
38
    private $tmpDir;
39
40
    /**
41
     * @param ImporterInterface $importer
42
     * @param Ssh               $ssh
43
     * @param Scp               $scp
44
     * @param ZipArchive        $zip
45
     *
46
     * @throws \Exception
47
     */
48 4
    public function __construct(
49
        ImporterInterface $importer,
50
        Ssh $ssh,
51
        Scp $scp,
52
        ZipArchive $zip
53
    ) {
54 4
        $this->importer = $importer;
55 4
        $this->ssh      = $ssh;
56 4
        $this->scp      = $scp;
57 4
        $this->zip      = $zip;
58 4
        $this->tmpDir   = sys_get_temp_dir();
59
60 4
        if (!is_writable($this->tmpDir)) {
61
            throw new \Exception(
62
                sprintf('Temporary directory `%s` is unreadable.', $this->tmpDir)
63
            );
64
        }
65 4
    }
66
67
    /**
68
     * @param null|OutputInterface $output
69
     *
70
     * @throws DatabaseException
71
     * @throws \Exception
72
     */
73 3
    public function sync(OutputInterface $output = null)
74
    {
75 3
        $output     = $output ?: new NullOutput();
76 3
        $remoteFile = 'dump-remote.zip'; //TODO: improve location and name of remote file
77 3
        $localFile  = $this->tmpDir . '/labby_' . uniqid() . '.zip';
78
79 3
        $this->write('Executing remote dump...', $output);
80
81 3
        $this->ssh->execSf(
82 3
            DumpCommand::COMMAND_NAME,
83
            array(
84 3
                $remoteFile,
85 3
                '--compress',
86
            ),
87 3
            $this->getOutputCallback($output, 1)
88
        );
89
90 3
        $this->write('Copying...', $output);
91 3
        $this->scp->copyFile($remoteFile, $localFile, $output);
92 3
        $this->write(
93
            sprintf(
94 3
                "Remote file `%s` copied locally to `%s`.",
95
                $remoteFile,
96
                $localFile
97
            ),
98
            $output,
99 3
            1
100
        );
101
102 3
        $dumpFile = $this->zip->unzip($localFile);
103 3
        $this->write(
104
            sprintf(
105 3
                "File `%s` unzipped to `%s`.",
106
                $localFile,
107
                $dumpFile
108
            ),
109
            $output,
110 3
            1
111
        );
112
113
        //TODO: recreate database
114
115 3
        $this->write('Importing...', $output);
116 3
        $this->importer->import($dumpFile, $this->getOutputCallback($output, 1));
117 3
        $this->write(
118
            sprintf(
119 3
                "File `%s` imported.",
120
                $dumpFile
121
            ),
122
            $output,
123 3
            1
124
        );
125
126 3
        $this->write('Cleaning up...', $output);
127
128 3
        unlink($localFile);
129 3
        $this->write(
130
            sprintf(
131 3
                "File `%s` removed.",
132
                $localFile
133
            ),
134
            $output,
135 3
            1
136
        );
137
138 3
        unlink($dumpFile);
139 3
        $this->write(
140
            sprintf(
141 3
                "File `%s` removed.",
142
                $dumpFile
143
            ),
144
            $output,
145 3
            1
146
        );
147
148
        //TODO: remove remote file
149 3
    }
150
151
    /**
152
     * @param OutputInterface $output
153
     * @param int             $level
154
     *
155
     * @return null|\Closure
156
     */
157 3
    private function getOutputCallback(OutputInterface $output, $level = 0)
158
    {
159 3
        if ($output->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) {
160
            return null;
161
        }
162
163 3
        return function ($type, $buffer) use ($output, $level) {
164 3
            $output->write(str_repeat(' ', $level * 2));
165 3
            if (Process::ERR === $type) {
166
                $output->writeln(sprintf('<error>%s</error>', $buffer));
167
            } else {
168 3
                $output->writeln(sprintf('%s', $buffer));
169
            }
170 3
        };
171
    }
172
173
    /**
174
     * @param string          $string
175
     * @param OutputInterface $output
176
     * @param int             $level
177
     */
178 3
    private function write($string, OutputInterface $output, $level = 0)
179
    {
180 3
        $info = str_repeat(' ', $level * 2) . $string;
181 3
        $output->writeln(sprintf('<comment>%s</comment>', $info));
182 3
    }
183
}
184