1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace RDV\Bundle\MigrationBundle\Migration; |
4
|
|
|
|
5
|
|
|
use Doctrine\DBAL\Connection; |
6
|
|
|
use Doctrine\DBAL\Types\Type; |
7
|
|
|
use Psr\Log\LoggerInterface; |
8
|
|
|
|
9
|
|
|
abstract class ParametrizedMigrationQuery implements MigrationQuery, ConnectionAwareInterface |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* @var Connection |
13
|
|
|
*/ |
14
|
|
|
protected $connection; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* {@inheritdoc} |
18
|
|
|
*/ |
19
|
|
|
public function setConnection(Connection $connection) |
20
|
|
|
{ |
21
|
|
|
$this->connection = $connection; |
22
|
|
|
} |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Adds a query to a log |
26
|
|
|
* |
27
|
|
|
* @param LoggerInterface $logger |
28
|
|
|
* @param string $query |
29
|
|
|
* @param array $params |
30
|
|
|
* @param array $types |
31
|
|
|
*/ |
32
|
|
|
protected function logQuery(LoggerInterface $logger, $query, array $params = [], array $types = []) |
33
|
|
|
{ |
34
|
|
|
$logger->notice($query); |
35
|
|
|
if (!empty($params)) { |
36
|
|
|
$resolvedParams = $this->resolveParams($params, $types); |
37
|
|
|
$logger->notice('Parameters:'); |
38
|
|
|
foreach ($resolvedParams as $key => $val) { |
39
|
|
|
if (is_array($val)) { |
40
|
|
|
$val = implode(',', $val); |
41
|
|
|
} |
42
|
|
|
$logger->notice(sprintf('[%s] = %s', $key, $val)); |
43
|
|
|
} |
44
|
|
|
} |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Resolves the parameters to a format which can be displayed. |
49
|
|
|
* |
50
|
|
|
* @param array $params |
51
|
|
|
* @param array $types |
52
|
|
|
* |
53
|
|
|
* @return array |
54
|
|
|
*/ |
55
|
|
|
protected function resolveParams(array $params, array $types) |
56
|
|
|
{ |
57
|
|
|
$resolvedParams = array(); |
58
|
|
|
|
59
|
|
|
// Check whether parameters are positional or named. Mixing is not allowed. |
60
|
|
|
if (is_int(key($params))) { |
61
|
|
|
// Positional parameters |
62
|
|
|
$typeOffset = array_key_exists(0, $types) ? -1 : 0; |
63
|
|
|
$bindIndex = 1; |
64
|
|
|
foreach ($params as $value) { |
65
|
|
|
$typeIndex = $bindIndex + $typeOffset; |
66
|
|
View Code Duplication |
if (isset($types[$typeIndex])) { |
|
|
|
|
67
|
|
|
$type = $types[$typeIndex]; |
68
|
|
|
$value = $this->convertToDatabaseValue($value, $type); |
69
|
|
|
$resolvedParams[$bindIndex] = $value; |
70
|
|
|
} else { |
71
|
|
|
$resolvedParams[$bindIndex] = $value; |
72
|
|
|
} |
73
|
|
|
$bindIndex++; |
74
|
|
|
} |
75
|
|
|
} else { |
76
|
|
|
// Named parameters |
77
|
|
|
foreach ($params as $name => $value) { |
78
|
|
View Code Duplication |
if (isset($types[$name])) { |
|
|
|
|
79
|
|
|
$type = $types[$name]; |
80
|
|
|
$value = $this->convertToDatabaseValue($value, $type); |
81
|
|
|
$resolvedParams[$name] = $value; |
82
|
|
|
} else { |
83
|
|
|
$resolvedParams[$name] = $value; |
84
|
|
|
} |
85
|
|
|
} |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return $resolvedParams; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Converts a value from its PHP representation to its database representation. |
93
|
|
|
* |
94
|
|
|
* @param mixed $value |
95
|
|
|
* @param string|Type $type |
96
|
|
|
* |
97
|
|
|
* @return array the (escaped) value |
98
|
|
|
*/ |
99
|
|
|
protected function convertToDatabaseValue($value, $type) |
100
|
|
|
{ |
101
|
|
|
if (is_string($type)) { |
102
|
|
|
$type = Type::getType($type); |
103
|
|
|
} |
104
|
|
|
if ($type instanceof Type) { |
105
|
|
|
$value = $type->convertToDatabaseValue($value, $this->connection->getDatabasePlatform()); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
return $value; |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.