Issues (2)

src/DatabaseReplicatorExtension24.php (1 issue)

1
<?php declare(strict_types=1);
2
3
namespace PmgDev\DatabaseReplicator;
4
5
use Nette\DI;
6
use PmgDev\DatabaseReplicator\Source;
7
8
abstract class DatabaseReplicatorExtension24 extends DI\CompilerExtension
9
{
10
	private const DB_SETTINGS = [
11
		'database' => '',
12
		'username' => '',
13
		'host' => '',
14
		'password' => '',
15
		'port' => 5432,
16
	];
17
18
	private const DEFAULTS = [
19
		'admin' => self::DB_SETTINGS,
20
		'connections' => [],
21
		'sourceFile' => [],
22
		// optional
23
		'psql' => '/usr/bin/psql',
24
		'tempDir' => '/tmp/database.replicator',
25
	];
26
27
28
	public function loadConfiguration(): void
29
	{
30
		$config = $this->validateConfig($this->getDefaults());
0 ignored issues
show
Deprecated Code introduced by
The function Nette\DI\CompilerExtension::validateConfig() has been deprecated: use getConfigSchema() ( Ignorable by Annotation )

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

30
		$config = /** @scrutinizer ignore-deprecated */ $this->validateConfig($this->getDefaults());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
31
32
		$adminConfig = $this->buildConfig('admin', $config['admin']);
33
		$command = $this->buildCommand($adminConfig, $config['psql']);
34
		$this->buildDatabaseOperation(array_keys($config['connections']));
35
36
		$autowire = count($config['connections']) < 2;
37
		foreach ($config['connections'] as $name => $connection) {
38
			if (!isset($connection['database']) || $connection['database'] === '') {
39
				$connection['database'] = $name;
40
			}
41
42
			$dbconfig = $this->buildConfig($name . '.config', $connection + $config['admin']);
43
44
			$sourceFile = $this->buildSourceFile($name, $config['sourceFile'], $config['tempDir']);
45
46
			$prefix = $this->buildDatabasePrefix($name, $dbconfig, $sourceFile);
47
48
			$sourceDatabase = $this->buildSourceDatabase($name, $prefix, $sourceFile, $command);
49
50
			$this->buildDatabaseReplicator($name, $command, $prefix, $sourceDatabase);
51
52
			$this->buildDatabase($name, $autowire);
53
		}
54
	}
55
56
57
	protected function getDefaults(): array
58
	{
59
		return self::DEFAULTS;
60
	}
61
62
63
	private function replicatorName(string $name, $service = FALSE): string
64
	{
65
		return $this->prefix(($service ? ('@' . $name) : $name) . '.database.replicator');
66
	}
67
68
69
	/**
70
	 * @param string $name
71
	 * @param string[] $config
72
	 */
73
	private function buildConfig(string $name, array $config): DI\ServiceDefinition
74
	{
75
		return $this->getContainerBuilder()->addDefinition($this->prefix($name))
76
			->setFactory(Config::class)
77
			->setArguments([
78
				$config['database'],
79
				$config['username'],
80
				$config['password'],
81
				$config['host'],
82
				$config['port'],
83
			])
84
			->setAutowired(FALSE);
85
	}
86
87
88
	private function buildDatabase(string $name, bool $autowire): void
89
	{
90
		$database = $this->getContainerBuilder()
91
			->addDefinition($this->prefix($name . '.database'))
92
			->setAutowired($autowire);
93
		$this->buildDatabaseConnection($database, $name, $this->replicatorName($name, TRUE));
94
	}
95
96
97
	abstract protected function buildDatabaseConnection(DI\ServiceDefinition $service, string $name, string $replicatorService): void;
98
99
100
	private function buildDatabaseReplicator(
101
		string $name,
102
		DI\ServiceDefinition $command,
103
		DI\ServiceDefinition $prefix,
104
		DI\ServiceDefinition $sourceDatabase
105
	): void
106
	{
107
		$builder = $this->getContainerBuilder();
108
		$files = $builder->addDefinition($this->prefix($name . '.database.replicator.files'))
109
			->setFactory(Source\Files::class)
110
			->setAutowired(FALSE);
111
112
		$builder->addDefinition($this->replicatorName($name))
113
			->setFactory(Database\Replicator::class)
114
			->setArguments([$command, $prefix, $sourceDatabase, $files])
115
			->setAutowired(FALSE);
116
	}
117
118
119
	private function buildSourceFile(
120
		string $name,
121
		string $sourceFile,
122
		string $tempDir
123
	): DI\ServiceDefinition
124
	{
125
		$builder = $this->getContainerBuilder();
126
		$files = $builder->addDefinition($this->prefix($name . '.source.hash.files'))
127
			->setFactory(Source\Files::class, [[$sourceFile]])
128
			->setAutowired(FALSE);
129
130
		return $builder->addDefinition($this->prefix($name . '.source.hash'))
131
			->setFactory(Source\Hash::class)
132
			->setArguments([$name, $tempDir, $files])
133
			->setAutowired(FALSE);
134
	}
135
136
137
	private function buildSourceDatabase(
138
		string $name,
139
		DI\ServiceDefinition $prefix,
140
		DI\ServiceDefinition $sourceFile,
141
		DI\ServiceDefinition $command
142
	): DI\ServiceDefinition
143
	{
144
		return $this->getContainerBuilder()->addDefinition($this->prefix($name . '.source.database'))
145
			->setFactory(Source\Database::class)
146
			->setArguments([$prefix, $sourceFile, $command])
147
			->setAutowired(FALSE);
148
	}
149
150
151
	private function buildDatabasePrefix(
152
		string $name,
153
		DI\ServiceDefinition $dbconfig,
154
		DI\ServiceDefinition $sourceFile
155
	): DI\ServiceDefinition
156
	{
157
		return $this->getContainerBuilder()->addDefinition($this->prefix($name . '.database.prefix'))
158
			->setFactory(Database\Prefix::class)
159
			->setArguments([$dbconfig, $sourceFile])
160
			->setAutowired(FALSE);
161
	}
162
163
164
	private function buildCommand(
165
		DI\ServiceDefinition $adminConfig,
166
		string $psql
167
	): DI\ServiceDefinition
168
	{
169
		$builder = $this->getContainerBuilder();
170
		$builder->addDefinition($this->prefix('command.factory'))
171
			->setFactory(Database\Postgres\CommandFactory::class, [$psql])
172
			->setAutowired(FALSE);
173
174
		return $builder->addDefinition($this->prefix('command'))
175
			->setFactory(new DI\Statement([$this->prefix('@command.factory'), 'create'], [$adminConfig]))
176
			->setAutowired(FALSE);
177
	}
178
179
180
	private function buildDatabaseOperation(array $connectionsName): DI\ServiceDefinition
181
	{
182
		return $this->getContainerBuilder()->addDefinition($this->prefix('database.operation'))
183
			->setFactory(DatabaseOperation::class)
184
			->addSetup('setPrefix', [$this->prefix('')])
185
			->addSetup('setConnectionsName', [$connectionsName])
186
			->setAutowired(FALSE);
187
	}
188
189
}
190