Passed
Push — master ( 03a6f5...40da0b )
by Luca
11:01 queued 15s
created

AbstractDatabase::getMysqlArgs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 14
ccs 0
cts 9
cp 0
rs 10
cc 2
nc 2
nop 0
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Service;
6
7
use Exception;
8
9
/**
10
 * Tool to reload the entire local database from remote database for a given site
11
 * Requirements:
12
 * - ssh access to remote server (via ~/.ssh/config)
13
 * - both local and remote sites must be accesible via: /sites/MY_SITE
14
 */
15
abstract class AbstractDatabase
16
{
17
    /**
18
     * Dump data from database on $remote server
19
     *
20
     * @param string $remote
21
     * @param string $dumpFile path
22
     */
23
    private static function dumpDataRemotely($remote, $dumpFile): void
24
    {
25
        $sshCmd = <<<STRING
26
                    ssh $remote "cd /sites/$remote/ && php7.4 bin/dump-data.php $dumpFile"
27
            STRING;
28
29
        echo "dumping data $dumpFile on $remote...\n";
30
        self::executeLocalCommand($sshCmd);
31
    }
32
33
    /**
34
     * Dump data from database
35
     *
36
     * @param string $dumpFile path
37
     */
38
    public static function dumpData($dumpFile): void
39
    {
40
        $mysqlArgs = self::getMysqlArgs();
41
42
        echo "dumping $dumpFile...\n";
43
        $dumpCmd = "mysqldump -v $mysqlArgs | gzip > $dumpFile";
44
        self::executeLocalCommand($dumpCmd);
45
    }
46
47
    /**
48
     * Copy a file from $remote
49
     *
50
     * @param string $remote
51
     * @param string $dumpFile
52
     */
53
    private static function copyFile($remote, $dumpFile): void
54
    {
55
        $copyCmd = <<<STRING
56
                    rsync -avz --progress $remote:$dumpFile $dumpFile
57
            STRING;
58
59
        echo "copying dump to $dumpFile ...\n";
60
        self::executeLocalCommand($copyCmd);
61
    }
62
63
    /**
64
     * Load SQL dump in local database
65
     *
66
     * @param string $dumpFile
67
     */
68
    public static function loadData($dumpFile): void
69
    {
70
        $mysqlArgs = self::getMysqlArgs();
71
72
        $dumpFile = realpath($dumpFile);
73
        echo "loading dump $dumpFile...\n";
74
        if (!is_readable($dumpFile)) {
75
            throw new Exception("Cannot read dump file \"$dumpFile\"");
76
        }
77
78
        self::executeLocalCommand(PHP_BINARY . ' ./vendor/bin/doctrine orm:schema-tool:drop --ansi --full-database --force');
79
        self::executeLocalCommand("gunzip -c \"$dumpFile\" | mysql $mysqlArgs");
80
        self::executeLocalCommand(PHP_BINARY . ' ./vendor/bin/doctrine-migrations --ansi migrations:migrate --no-interaction');
81
    }
82
83
    private static function getMysqlArgs(): string
84
    {
85
        $dbConfig = _em()->getConnection()->getParams();
86
87
        $host = $dbConfig['host'] ?? 'localhost';
88
        $username = $dbConfig['user'];
89
        $database = $dbConfig['dbname'];
90
        $password = $dbConfig['password'];
91
        $port = $dbConfig['port'] ?? 3306;
92
93
        // It's possible to have no password at all
94
        $password = $password ? '-p' . $password : '';
95
96
        return "--user=$username $password --host=$host --port=$port $database";
97
    }
98
99
    public static function loadRemoteData($remote): void
100
    {
101
        $dumpFile = "/tmp/$remote." . exec('whoami') . '.backup.gz';
102
        self::dumpDataRemotely($remote, $dumpFile);
103
        self::copyFile($remote, $dumpFile);
104
        self::loadData($dumpFile);
105
106
        echo "database updated\n";
107
    }
108
109
    /**
110
     * Execute a shell command and throw exception if fails
111
     *
112
     * @param string $command
113
     */
114
    public static function executeLocalCommand($command): void
115
    {
116
        $return_var = null;
117
        $fullCommand = "$command 2>&1";
118
        passthru($fullCommand, $return_var);
119
        if ($return_var) {
120
            throw new Exception('FAILED executing: ' . $command);
121
        }
122
    }
123
}
124