ShardingController::pickGlobal()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
crap 2
1
<?php
2
3
/**
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2015 Repo2
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in all
16
 * copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
 * SOFTWARE.
25
 */
26
27
namespace Repo2\QueryReactor\Sharding;
28
29
use Repo2\QueryReactor\Controller;
30
use Repo2\QueryReactor\Driver;
31
use Repo2\QueryReactor\Query;
32
33
class ShardingController implements Controller
34
{
35
    /** @var ShardingService */
36
    private $sharding;
37
38
    /** @var string */
39
    private $controllerClass;
40
41
    /** @var Controller[] */
42
    private $controllers = [];
43
44
    /**
45
     * @param ShardingService $sharding
46
     * @param string $controllerClass
47
     */
48 30
    public function __construct(ShardingService $sharding, $controllerClass)
49
    {
50 30
        $this->sharding = $sharding;
51 30
        $this->controllerClass = $controllerClass;
52 30
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57 30
    public function getQuery(Driver $driver, $link)
58
    {
59 30
        foreach ($this->controllers as $controller) {
60
            try {
61 30
                return $controller->getQuery($driver, $link);
62 3
            } catch (\OutOfBoundsException $err) {
63 3
                continue;
64
            }
65 3
        }
66 3
        throw new \OutOfBoundsException(sprintf('Undefined %s in the sharding controller.', $driver->info($link)));
67
    }
68
69
    /**
70
     * @inheritDoc
71
     */
72 30
    public function getLink(Driver $driver, Query $query)
73
    {
74 30
        if ($query instanceof ShardedQuery) {
75 9
            $controller = $this->pickShard($query);
76 6
        } else {
77 30
            $controller = $this->pickGlobal();
78
        }
79 30
        return $controller->getLink($driver, $query);
80
    }
81
82
    /**
83
     * @return Controller
84
     */
85 30
    private function pickGlobal()
86
    {
87 30
        if (empty($this->controllers[0])) {
88 30
            $this->controllers[0] = new $this->controllerClass($this->sharding->selectGlobal());
89 30
        }
90 30
        return $this->controllers[0];
91
    }
92
93
    /**
94
     * @param ShardedQuery $query
95
     * @return Controller
96
     */
97 9
    private function pickShard(ShardedQuery $query)
98
    {
99 9
        $params = $this->sharding->selectShard($query->getDistributionName(), $query->getDistributionValue());
100
101 9
        if (empty($params['id'])) {
102 3
            throw new \RuntimeException('Required not empty key "id" in sharding configuration.');
103
        }
104
105 6
        $shardId = $params['id'];
106
107 6
        if (empty($this->controllers[$shardId])) {
108 6
            $this->controllers[$shardId] = new $this->controllerClass($params);
109 6
        }
110
111 6
        return $this->controllers[$shardId];
112
    }
113
}
114