Completed
Branch master (0bf65c)
by Dmitry
02:31
created

Repository   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 98.04%

Importance

Changes 10
Bugs 3 Features 0
Metric Value
wmc 30
c 10
b 3
f 0
lcom 1
cbo 3
dl 0
loc 167
ccs 100
cts 102
cp 0.9804
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A make() 0 4 1
A __call() 0 12 3
A knows() 0 4 1
C find() 0 48 10
C save() 0 37 8
A register() 0 10 4
B generateId() 0 25 2
1
<?php
2
3
namespace Tarantool\Mapper;
4
5
use Tarantool\Mapper\Contracts;
6
use BadMethodCallException;
7
use LogicException;
8
9
class Repository implements Contracts\Repository
10
{
11
    protected $type;
12
    protected $entities = [];
13
    protected $keyMap = [];
14
15
    protected $magicMethodRules = [
16
        'by' => false,
17
        'firstBy' => true,
18
        'oneBy' => true
19
    ];
20
21 4
    public function __construct(Contracts\Type $type)
22
    {
23 4
        $this->type = $type;
24 4
    }
25
26 4
    public function make(array $data = null)
27
    {
28 4
        return $this->register(new Entity($data));
29
    }
30
31 4
    public function __call($method, $arguments)
32
    {
33 4
        foreach ($this->magicMethodRules as $prefix => $oneItem) {
34 4
            if (substr($method, 0, strlen($prefix)) == $prefix) {
35 4
                $tail = substr($method, strlen($prefix));
36 4
                $fields = array_map('strtolower', explode('And', $tail));
37 4
                return $this->find(array_combine($fields, $arguments), $oneItem);
38
            }
39 4
        }
40
41
        throw new BadMethodCallException("Method $method not found");
42
    }
43
44 4
    public function find($params = [], $oneItem = false)
45
    {
46 4
        if(is_int($params)) {
47
            $params = [
48
                'id' => $params
49 1
            ];
50 1
            $oneItem = true;
51 1
        }
52
53 4
        $fields = array_keys($params);
54 4
        $values = [];
55
56 4
        sort($fields);
57 4
        foreach($fields as $field) {
58 4
            $values[] = $params[$field];
59 4
        }
60
61 4
        $index = implode('_', $fields);
62
63 4
        if(!$index) {
64 1
            $index = 'id';
65 1
        }
66
67 4
        $space = $this->type->getManager()->getClient()->getSpace($this->type->getName());
68 4
        $data = $space->select($values, $index);
69
70
71 4
        $result = [];
72 4
        if (!empty($data->getData())) {
73 4
            foreach ($data->getData() as $tuple) {
74 4
                $data = $this->type->decode($tuple);
75 4
                if (isset($data['id']) && array_key_exists($data['id'], $this->keyMap)) {
76 4
                    $entity = $this->entities[$this->keyMap[$data['id']]];
77 4
                    $entity->update($data);
78 4
                } else {
79 4
                    $entity = new Entity($data);
80 4
                    $this->register($entity);
81
                }
82 4
                if ($oneItem) {
83 4
                    return $entity;
84
                }
85 4
                $result[] = $entity;
86 4
            }
87 4
        }
88 4
        if (!$oneItem) {
89 4
            return $result;
90
        }
91 4
    }
92
93
    /**
94
     * @return Entity
95
     */
96 4
    public function knows(Contracts\Entity $entity)
97
    {
98 4
        return in_array($entity, $this->entities);
99
    }
100
101 4
    public function save(Contracts\Entity $entity)
102
    {
103 4
        if (!$this->knows($entity)) {
104
            throw new LogicException("Entity is not related with this repository");
105
        }
106
107 4
        if (!$entity->getId()) {
108 4
            $this->generateId($entity);
109 4
            $tuple = $this->type->encode($entity->toArray());
110
111
            // normalize tuple
112 4
            if(array_values($tuple) != $tuple) {
113
                // index was skipped
114 1
                $max = max(array_keys($tuple));
115 1
                foreach(range(0, $max) as $index) {
116 1
                    if(!array_key_exists($index, $tuple)) {
117 1
                        $tuple[$index] = null;
118 1
                    }
119 1
                }
120 1
                ksort($tuple);
121 1
            }
122
123 4
            $this->type->getSpace()->insert($tuple);
124 4
        } else {
125 1
            $changes = $entity->pullChanges();
126 1
            if (count($changes)) {
127 1
                $operations = [];
128 1
                foreach ($this->type->encode($changes) as $key => $value) {
129 1
                    $operations[] = ['=', $key, $value];
130 1
                }
131
132 1
                $result = $this->type->getSpace()->update($entity->getId(), $operations);
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
133 1
            }
134
        }
135
136 4
        return $entity;
137
    }
138
139 4
    protected function register(Contracts\Entity $entity)
140
    {
141 4
        if (!$this->knows($entity)) {
142 4
            $this->entities[] = $entity;
143 4
        }
144 4
        if ($entity->getId() && !array_key_exists($entity->getId(), $this->keyMap)) {
145 4
            $this->keyMap[$entity->getId()] = array_search($entity, $this->entities);
146 4
        }
147 4
        return $entity;
148
    }
149
150 4
    protected function generateId(Contracts\Entity $entity)
151
    {
152 4
        $manager = $this->type->getManager();
153 4
        $name = $this->type->getName();
154
155 4
        $sequence = $manager->get('sequences')->oneByName($name);
156 4
        if (!$sequence) {
157 4
            $sequence = $manager->get('sequences')->make([
158 4
                'name' => $name,
159 4
                'value' => 0,
160 4
            ]);
161 4
            $manager->save($sequence);
162 4
        }
163
164 4
        $nextValue = $manager->getClient()
165 4
            ->getSpace('sequences')
166 4
            ->update($sequence->id, [['+', 2, 1]])
167 4
            ->getData()[0][2];
168
169 4
        $entity->setId($nextValue);
170
171 4
        $this->register($entity);
172
173 4
        return $entity;
174
    }
175
}
176