-
Notifications
You must be signed in to change notification settings - Fork 12
/
ValueBinder.php
151 lines (138 loc) · 4.43 KB
/
ValueBinder.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database;
/**
* Value binder class manages list of values bound to conditions.
*
* @internal
*/
class ValueBinder
{
/**
* Array containing a list of bound values to the conditions on this
* object. Each array entry is another array structure containing the actual
* bound value, its type and the placeholder it is bound to.
*
* @var array
*/
protected $_bindings = [];
/**
* A counter of the number of parameters bound in this expression object
*
* @var int
*/
protected $_bindingsCount = 0;
/**
* Associates a query placeholder to a value and a type
*
* @param string|int $param placeholder to be replaced with quoted version
* of $value
* @param mixed $value The value to be bound
* @param string|int|null $type the mapped type name, used for casting when sending
* to database
* @return void
*/
public function bind($param, $value, $type = null): void
{
$this->_bindings[$param] = compact('value', 'type') + [
'placeholder' => is_int($param) ? $param : substr($param, 1),
];
}
/**
* Creates a unique placeholder name if the token provided does not start with ":"
* otherwise, it will return the same string and internally increment the number
* of placeholders generated by this object.
*
* @param string $token string from which the placeholder will be derived from,
* if it starts with a colon, then the same string is returned
* @return string to be used as a placeholder in a query expression
*/
public function placeholder(string $token): string
{
$number = $this->_bindingsCount++;
if ($token[0] !== ':' && $token !== '?') {
$token = sprintf(':%s%s', $token, $number);
}
return $token;
}
/**
* Creates unique named placeholders for each of the passed values
* and binds them with the specified type.
*
* @param iterable $values The list of values to be bound
* @param string|int|null $type The type with which all values will be bound
* @return array with the placeholders to insert in the query
*/
public function generateManyNamed(iterable $values, $type = null): array
{
$placeholders = [];
foreach ($values as $k => $value) {
$param = $this->placeholder('c');
$this->_bindings[$param] = [
'value' => $value,
'type' => $type,
'placeholder' => substr($param, 1),
];
$placeholders[$k] = $param;
}
return $placeholders;
}
/**
* Returns all values bound to this expression object at this nesting level.
* Subexpression bound values will not be returned with this function.
*
* @return array
*/
public function bindings(): array
{
return $this->_bindings;
}
/**
* Clears any bindings that were previously registered
*
* @return void
*/
public function reset(): void
{
$this->_bindings = [];
$this->_bindingsCount = 0;
}
/**
* Resets the bindings count without clearing previously bound values
*
* @return void
*/
public function resetCount(): void
{
$this->_bindingsCount = 0;
}
/**
* Binds all the stored values in this object to the passed statement.
*
* @param \Cake\Database\StatementInterface $statement The statement to add parameters to.
* @return void
*/
public function attachTo(StatementInterface $statement): void
{
$bindings = $this->bindings();
if (empty($bindings)) {
return;
}
foreach ($bindings as $b) {
$statement->bindValue($b['placeholder'], $b['value'], $b['type']);
}
}
}