Replicator   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 56
dl 0
loc 127
rs 10
c 1
b 0
f 0
wmc 17

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A copyDatabase() 0 6 1
A databaseName() 0 9 2
A drop() 0 3 1
A copy() 0 17 3
A clearDatabases() 0 16 4
A generateListDatabases() 0 15 4
A generateName() 0 6 1
1
<?php declare(strict_types=1);
2
3
namespace PmgDev\DatabaseReplicator\Database;
4
5
use PmgDev\DatabaseReplicator\Command;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, PmgDev\DatabaseReplicator\Database\Command. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use PmgDev\DatabaseReplicator\Config;
7
use PmgDev\DatabaseReplicator\Exceptions;
8
use PmgDev\DatabaseReplicator\Source;
9
10
class Replicator
11
{
12
	/** @var Command */
13
	private $command;
14
15
	/** @var Prefix */
16
	private $prefix;
17
18
	/** @var Source\Database */
19
	private $sourceDatabase;
20
21
	/** @var Source\Files */
22
	private $files;
23
24
25
	public function __construct(
26
		Command $command,
27
		Prefix $prefix,
28
		Source\Database $sourceDatabase,
29
		?Source\Files $files = NULL
30
	)
31
	{
32
		$this->command = $command;
33
		$this->prefix = $prefix;
34
		$this->sourceDatabase = $sourceDatabase;
35
		$this->files = $files ?? new Source\Files();
36
	}
37
38
39
	public function copy(string $name = ''): Config
40
	{
41
		$dbname = $this->databaseName();
42
		if ($name === '') {
43
			$name = $dbname;
44
		}
45
46
		try {
47
			$config = $this->copyDatabase($name);
48
		} catch (Exceptions\CopyCommandFailedException $e) {
49
			$this->sourceDatabase->build();
50
			$config = $this->copyDatabase($name);
51
		}
52
53
		$this->command->importFiles($this->files, $config);
54
55
		return $config;
56
	}
57
58
59
	public function drop(string $database): void
60
	{
61
		$this->command->drop($database);
62
	}
63
64
65
	/**
66
	 * @param bool|string[] $keepDatabases
67
	 * @return string[][]
68
	 */
69
	public function clearDatabases($keepDatabases = TRUE): array
70
	{
71
		$listDatabases = $this->generateListDatabases($keepDatabases);
72
		$kept = $removed = [];
73
		$dbPrefix = $this->prefix->prefix();
74
		foreach ($this->command->listDatabases() as $database) {
75
			if (preg_match('~^' . $dbPrefix . '[a-z0-9]{32}.*$~', $database)) {
76
				if (in_array($database, $listDatabases, TRUE)) {
77
					$kept[] = $database;
78
				} else {
79
					$this->drop($database);
80
					$removed[] = $database;
81
				}
82
			}
83
		}
84
		return ['removed' => $removed, 'kept' => $kept];
85
	}
86
87
88
	/**
89
	 * @param bool|string[] $keepDatabases
90
	 * @return string[]
91
	 */
92
	private function generateListDatabases($keepDatabases): array
93
	{
94
		try {
95
			if ($keepDatabases === TRUE) {
96
				$listDatabases = [$this->prefix->database()];
97
			} else if (is_array($keepDatabases)) {
98
				$keepDatabases[] = $this->prefix->database();
99
				$listDatabases = $keepDatabases;
100
			} else {
101
				$listDatabases = [];
102
			}
103
		} catch (Exceptions\ActiveFileNotFoundException $e) {
104
			$listDatabases = [];
105
		}
106
		return $listDatabases;
107
	}
108
109
110
	private function generateName(): string
111
	{
112
		static $i = 0;
113
		$name = $this->prefix->database() . '_' . date('His') . '_' . getmypid() . '_' . $i;
114
		++$i;
115
		return $name;
116
	}
117
118
119
	private function databaseName(): string
120
	{
121
		try {
122
			$name = $this->generateName();
123
		} catch (Exceptions\ActiveFileNotFoundException $e) {
124
			$this->sourceDatabase->build();
125
			$name = $this->generateName();
126
		}
127
		return $name;
128
	}
129
130
131
	private function copyDatabase(string $name): Config
132
	{
133
		$config = $this->prefix->config();
134
		$this->command->copy($config, $name);
135
		$config->database = $name;
136
		return $config;
137
	}
138
139
}
140