-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackup-tool.php
137 lines (122 loc) · 4.25 KB
/
backup-tool.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
class FileBackupData
{
public function __construct(
public string $sourcePath,
public iterable $excludePaths = [],
) {
}
}
class MysqlBackupData
{
public function __construct(
public string $host,
public int $port = 3306,
public string $user,
public string $password,
public iterable $databases = [],
) {
}
}
interface BackupProcessInterface
{
public function execute(string $dest);
}
class BackupCopiesData
{
public function __construct(
public BackupProcessInterface $backupProcess,
public string $dateFormat = 'Y-m-d',
public string $copiesPath,
public int $maxCopies,
public \DateTimeInterface $maxOldDate,
public \DateTimeInterface $dateFrom,
) {
}
}
class FileBackupProcess implements BackupProcessInterface
{
public function __construct(
public FileBackupData $backupData,
) {
}
public function execute(string $destinationPath)
{
$data = $this->backupData;
$excludeStr = '';
foreach ($data->excludePaths as $path) {
$excludeStr .= " --exclude='" . $path . "'";
}
exec("rsync -as --delete$excludeStr '{$data->sourcePath}' '$destinationPath'");
}
}
class MysqlBackupProcess implements BackupProcessInterface
{
public function __construct(
public MysqlBackupData $backupData,
) {
}
public function execute(string $destinationPath)
{
$data = $this->backupData;
$paramsString = "-h{$data->host} --port {$data->port} -u{$data->user} -p{$data->password}";
$databases = [];
exec("mysql $paramsString -e 'show databases' -s --skip-column-names", $databases);
foreach ($databases as $database) {
if (!$data->databases || in_array($database, $data->databases)) {
exec("rm -fr $destinationPath/*");
exec("mysqldump $paramsString --single-transaction=true $database | zip $destinationPath/$database.sql.zip -");
}
}
}
}
class BackupCopiesProcess
{
public function __construct(
/** @var BackupCopiesData[] $backupCopiesDatas */
public iterable $backupCopiesDatas,
) {
}
public function execute()
{
foreach ($this->backupCopiesDatas as $backupCopiesData) {
$copiesCount = 0;
$lastDate = null;
if (!file_exists($backupCopiesData->copiesPath)) {
mkdir($backupCopiesData->copiesPath);
}
$dirs = scandir($backupCopiesData->copiesPath);
foreach ($dirs as $dirName) {
$dir = $backupCopiesData->copiesPath . '/' . $dirName;
if (is_dir($dir)) {
$date = \DateTime::createFromFormat($backupCopiesData->dateFormat, $dirName);
if ($date) {
$copiesCount++;
if (!$lastDate || $date > $lastDate) {
$lastDate = $date;
}
}
}
}
foreach ($dirs as $dirName) {
$dir = $backupCopiesData->copiesPath . '/' . $dirName;
if (is_dir($dir)) {
$date = \DateTime::createFromFormat($backupCopiesData->dateFormat, $dirName);
if ($date) {
if ($date < $backupCopiesData->maxOldDate && $lastDate < $backupCopiesData->dateFrom) {
$lastDate = date($backupCopiesData->dateFormat);
$newDir = $backupCopiesData->copiesPath . '/' . $lastDate;
rename($dir, $newDir);
$backupCopiesData->backupProcess->execute($newDir);
}
}
}
}
if ($copiesCount < $backupCopiesData->maxCopies && (!$lastDate || $lastDate < $backupCopiesData->dateFrom)) {
$newDir = $backupCopiesData->copiesPath . '/' . date($backupCopiesData->dateFormat);
mkdir($newDir);
$backupCopiesData->backupProcess->execute($newDir);
}
}
}
}