Completed
Push — 2.x-locator-profiling ( d872b9 )
by Paul
06:27
created

ConnectionLocator::addProfiles()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 9
cp 0
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
nop 3
crap 12
1
<?php
2
/**
3
 *
4
 * This file is part of Aura for PHP.
5
 *
6
 * @license http://opensource.org/licenses/bsd-license.php BSD
7
 *
8
 */
9
namespace Aura\Sql;
10
11
/**
12
 *
13
 * Manages PDO connection objects for default, read, and write connections.
14
 *
15
 * @package Aura.Sql
16
 *
17
 */
18
class ConnectionLocator implements ConnectionLocatorInterface
19
{
20
    /**
21
     *
22
     * A registry of PDO connection entries.
23
     *
24
     * @var array
25
     *
26
     */
27
    protected $registry = array(
28
        'default' => null,
29
        'read' => array(),
30
        'write' => array(),
31
    );
32
33
    /**
34
     *
35
     * Whether or not registry entries have been converted to objects.
36
     *
37
     * @var array
38
     *
39
     */
40
    protected $converted = array(
41
        'default' => false,
42
        'read' => array(),
43
        'write' => array(),
44
    );
45
46
    /**
47
     *
48
     * Whether or not to turn on profiling when retrieving a connection.
49
     *
50
     * @var bool
51
     *
52
     */
53
    protected $profiling = false;
54
55
    /**
56
     *
57
     * Constructor.
58
     *
59
     * @param callable $default A callable to create a default connection.
60
     *
61
     * @param array $read An array of callables to create read connections.
62
     *
63
     * @param array $write An array of callables to create write connections.
64
     *
65
     */
66 10
    public function __construct(
67
        $default = null,
68
        array $read = array(),
69
        array $write = array()
70
    ) {
71 10
        if ($default) {
72 9
            $this->setDefault($default);
73 9
        }
74 10
        foreach ($read as $name => $callable) {
75 6
            $this->setRead($name, $callable);
76 10
        }
77 10
        foreach ($write as $name => $callable) {
78 6
            $this->setWrite($name, $callable);
79 10
        }
80 10
    }
81
82
    /**
83
     *
84
     * Sets the default connection registry entry.
85
     *
86
     * @param callable $callable The registry entry.
87
     *
88
     * @return null
89
     *
90
     */
91 9
    public function setDefault($callable)
92
    {
93 9
        $this->registry['default'] = $callable;
94 9
        $this->converted['default'] = false;
95 9
    }
96
97
    /**
98
     *
99
     * Returns the default connection object.
100
     *
101
     * @return ExtendedPdoInterface
102
     *
103
     */
104 3
    public function getDefault()
105
    {
106 3
        if (! $this->converted['default']) {
107 3
            $callable = $this->registry['default'];
108 3
            $this->registry['default'] = call_user_func($callable);
109 3
            $this->converted['default'] = true;
110 3
        }
111
112 3
        $connection = $this->registry['default'];
113 3
        $this->setProfiler($connection);
114 3
        return $connection;
115
    }
116
117
    /**
118
     *
119
     * Sets a read connection registry entry by name.
120
     *
121
     * @param string $name The name of the registry entry.
122
     *
123
     * @param callable $callable The registry entry.
124
     *
125
     * @return null
126
     *
127
     */
128 6
    public function setRead($name, $callable)
129
    {
130 6
        $this->registry['read'][$name] = $callable;
131 6
        $this->converted['read'][$name] = false;
132 6
    }
133
134
    /**
135
     *
136
     * Returns a read connection by name; if no name is given, picks a
137
     * random connection; if no read connections are present, returns the
138
     * default connection.
139
     *
140
     * @param string $name The read connection name to return.
141
     *
142
     * @return ExtendedPdoInterface
143
     *
144
     */
145 4
    public function getRead($name = null)
146
    {
147 4
        return $this->getConnection('read', $name);
148
    }
149
150
    /**
151
     *
152
     * Sets a write connection registry entry by name.
153
     *
154
     * @param string $name The name of the registry entry.
155
     *
156
     * @param callable $callable The registry entry.
157
     *
158
     * @return null
159
     *
160
     */
161 6
    public function setWrite($name, $callable)
162
    {
163 6
        $this->registry['write'][$name] = $callable;
164 6
        $this->converted['write'][$name] = false;
165 6
    }
166
167
    /**
168
     *
169
     * Returns a write connection by name; if no name is given, picks a
170
     * random connection; if no write connections are present, returns the
171
     * default connection.
172
     *
173
     * @param string $name The write connection name to return.
174
     *
175
     * @return ExtendedPdoInterface
176
     *
177
     */
178 4
    public function getWrite($name = null)
179
    {
180 4
        return $this->getConnection('write', $name);
181
    }
182
183
    /**
184
     *
185
     * Returns a connection by name.
186
     *
187
     * @param string $type The connection type ('read' or 'write').
188
     *
189
     * @param string $name The name of the connection.
190
     *
191
     * @return ExtendedPdoInterface
192
     *
193
     * @throws Exception\ConnectionNotFound
194
     */
195 8
    protected function getConnection($type, $name)
196
    {
197 8
        if (! $this->registry[$type]) {
198 2
            return $this->getDefault();
199
        }
200
201 6
        if (! $name) {
202 2
            $name = array_rand($this->registry[$type]);
203 2
        }
204
205 6
        if (! isset($this->registry[$type][$name])) {
206 2
            throw new Exception\ConnectionNotFound("{$type}:{$name}");
207
        }
208
209 4
        if (! $this->converted[$type][$name]) {
210 4
            $callable = $this->registry[$type][$name];
211 4
            $this->registry[$type][$name] = call_user_func($callable);
212 4
            $this->converted[$type][$name] = true;
213 4
        }
214
215 4
        $connection = $this->registry[$type][$name];
216 4
        $this->setProfiler($connection);
217 4
        return $connection;
218
    }
219
220
    /**
221
     *
222
     * Given a connection, enable or disable profiling on it. If a profiler has
223
     * not been set into the connection, this will instantiate and set one.
224
     *
225
     * @param ExtendedPdo $connection The connection.
226
     *
227
     * @return null
228
     *
229
     */
230 7
    protected function setProfiler(ExtendedPdo $connection)
231
    {
232 7
        $profiler = $connection->getProfiler();
233
234 7
        if (! $this->profiling && ! $profiler) {
235 7
            return;
236
        }
237
238
        if (! $profiler) {
239
            $profiler = new Profiler();
240
            $connection->setProfiler($profiler);
241
        }
242
243
        $profiler->setProfiling($this->profiling);
0 ignored issues
show
Bug introduced by
The method setProfiling() does not seem to exist on object<Aura\Sql\ProfilerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
244
    }
245
246
    /**
247
     *
248
     * Set profiling on all connections at retrieval time?
249
     *
250
     * @param bool $flag True to enable, or false to disable, profiling on each
251
     * connection as it is retrieved.
252
     *
253
     * @return null
254
     *
255
     */
256
    public function setProfiling($flag = true)
0 ignored issues
show
Unused Code introduced by
The parameter $flag is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
257
    {
258
        $this->profiling = (bool) $profiling;
0 ignored issues
show
Bug introduced by
The variable $profiling does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
259
    }
260
261
    /**
262
     *
263
     * Gets the profiles from all connections.
264
     *
265
     * @return array
266
     *
267
     */
268
    public function getProfiles()
269
    {
270
        $profiles = [];
271
272
        if ($this->converted['default']) {
273
            $connection = $this->registry['default'];
274
            $this->addProfiles('default', $connection, $profiles);
275
        }
276
277
        foreach (['read', 'write'] as $type) {
278
            foreach ($this->registry[$type] as $name) {
279
                if ($this->converted[$type][$name]) {
280
                    $connection = $this->registry[$type][$name];
281
                    $this->addProfiles("{$type}:{$name}", $connection, $profiles);
282
                }
283
            }
284
        }
285
286
        ksort($profiles);
287
        return $profiles;
288
    }
289
290
    /**
291
     *
292
     * Adds profiles from a connection, with a label for the connection name.
293
     *
294
     * @param string $label The connection label.
295
     *
296
     * @param ExtendedPdo $connection The connection.
297
     *
298
     * @param array &$profiles Add the connection profiles to this array, in
299
     * place.
300
     *
301
     * @return null
302
     */
303
    protected function addProfiles($label, ExtendedPdo $connection, &$profiles)
304
    {
305
        $profiler = $connection->getProfiler();
306
        if (! $profiler) {
307
            return;
308
        }
309
310
        foreach ($profiler->getProfiles() as $key => $profile) {
311
            $profile = ['connection' => $label] + $profile;
312
            $profiles[$key] = $profile;
313
        }
314
    }
315
}
316