Completed
Pull Request — master (#212)
by Alexandru
43:58 queued 01:14
created

Analyzer::getCondition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Rennokki\DynamoDb\ConditionAnalyzer;
4
5
use Illuminate\Support\Arr;
6
use Rennokki\DynamoDb\ComparisonOperator;
7
use Rennokki\DynamoDb\DynamoDbModel;
8
use Rennokki\DynamoDb\H;
9
10
/**
11
 * Class ConditionAnalyzer.
12
 */
13
class Analyzer
14
{
15
    /**
16
     * @var DynamoDbModel
17
     */
18
    private $model;
19
20
    /**
21
     * @var array
22
     */
23
    private $conditions = [];
24
25
    /**
26
     * @var string
27
     */
28
    private $indexName;
29
30 5
    public function on(DynamoDbModel $model)
31
    {
32 5
        $this->model = $model;
33
34 5
        return $this;
35
    }
36
37 5
    public function withIndex($index)
38
    {
39 5
        $this->indexName = $index;
40
41 5
        return $this;
42
    }
43
44 5
    public function analyze($conditions)
45
    {
46 5
        $this->conditions = $conditions;
47
48 5
        return $this;
49
    }
50
51 2
    public function isExactSearch()
52
    {
53 2
        if (empty($this->conditions)) {
54
            return false;
55
        }
56
57 2
        if (empty($this->identifierConditions())) {
58
            return false;
59
        }
60
61 2
        foreach ($this->conditions as $condition) {
62 2
            if (Arr::get($condition, 'type') !== ComparisonOperator::EQ) {
63 2
                return false;
64
            }
65
        }
66
67 2
        return true;
68
    }
69
70
    /**
71
     * @return Index|null
72
     */
73 3
    public function index()
74
    {
75 3
        return $this->getIndex();
76
    }
77
78 3
    public function keyConditions()
79
    {
80 3
        $index = $this->getIndex();
81
82 3
        if ($index) {
83 1
            return $this->getConditions($index->columns());
84
        }
85
86 2
        return $this->identifierConditions();
87
    }
88
89 3
    public function filterConditions()
90
    {
91 3
        $keyConditions = $this->keyConditions() ?: [];
92
93
        return array_filter($this->conditions, function ($condition) use ($keyConditions) {
94 3
            return array_search($condition, $keyConditions) === false;
95 3
        });
96
    }
97
98 4
    public function identifierConditions()
99
    {
100 4
        $keyNames = $this->model->getKeyNames();
101
102 4
        $conditions = $this->getConditions($keyNames);
103
104 4
        if (! $this->hasValidQueryOperator(...$keyNames)) {
0 ignored issues
show
Bug introduced by
$keyNames is expanded, but the parameter $hash of Rennokki\DynamoDb\Condit...hasValidQueryOperator() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

104
        if (! $this->hasValidQueryOperator(/** @scrutinizer ignore-type */ ...$keyNames)) {
Loading history...
105 2
            return;
106
        }
107
108 2
        return $conditions;
109
    }
110
111 2
    public function identifierConditionValues()
112
    {
113 2
        $idConditions = $this->identifierConditions();
114
115 2
        if (! $idConditions) {
116
            return [];
117
        }
118
119 2
        $values = [];
120
121 2
        foreach ($idConditions as $condition) {
122 2
            $values[$condition['column']] = $condition['value'];
123
        }
124
125 2
        return $values;
126
    }
127
128
    /**
129
     * @param $column
130
     *
131
     * @return array
132
     */
133 5
    private function getCondition($column)
134
    {
135
        return H::array_first($this->conditions, function ($condition) use ($column) {
136 5
            return $condition['column'] === $column;
137 5
        });
138
    }
139
140
    /**
141
     * @param $columns
142
     *
143
     * @return array
144
     */
145 5
    private function getConditions($columns)
146
    {
147
        return array_filter($this->conditions, function ($condition) use ($columns) {
148 5
            return in_array($condition['column'], $columns);
149 5
        });
150
    }
151
152
    /**
153
     * @return Index|null
154
     */
155 3
    private function getIndex()
156
    {
157 3
        if (empty($this->conditions)) {
158
            return;
159
        }
160
161 3
        $index = null;
162
163 3
        foreach ($this->model->getDynamoDbIndexKeys() as $name => $keysInfo) {
164 3
            $conditionKeys = Arr::pluck($this->conditions, 'column');
165 3
            $keys = array_values($keysInfo);
166
167 3
            if (count(array_intersect($conditionKeys, $keys)) === count($keys)) {
168 1
                if (! isset($this->indexName) || $this->indexName === $name) {
169 1
                    $index = new Index(
170 1
                        $name,
171 1
                        Arr::get($keysInfo, 'hash'),
172 1
                        Arr::get($keysInfo, 'range')
173
                    );
174
175 3
                    break;
176
                }
177
            }
178
        }
179
180 3
        if ($index && ! $this->hasValidQueryOperator($index->hash, $index->range)) {
0 ignored issues
show
introduced by
$index is of type Rennokki\DynamoDb\ConditionAnalyzer\Index|null, thus it always evaluated to false.
Loading history...
181
            $index = null;
182
        }
183
184 3
        return $index;
185
    }
186
187 5
    private function hasValidQueryOperator($hash, $range = null)
188
    {
189 5
        $hashCondition = $this->getCondition($hash);
190
191 5
        $validQueryOp = ComparisonOperator::isValidQueryDynamoDbOperator($hashCondition['type']);
192
193 5
        if ($validQueryOp && $range) {
194 2
            $rangeCondition = $this->getCondition($range);
195
196 2
            $validQueryOp = ComparisonOperator::isValidQueryDynamoDbOperator(
197 2
                $rangeCondition['type'],
198 2
                true
199
            );
200
        }
201
202 5
        return $validQueryOp;
203
    }
204
}
205