Completed
Push — master ( 2b9193...abd76f )
by James Ekow Abaka
03:07
created

QueryOperations::doCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 0
cts 2
cp 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
/*
4
 * The MIT License
5
 *
6
 * Copyright 2015 ekow.
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
16
 * all 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
24
 * THE SOFTWARE.
25
 */
26
27
namespace ntentan\nibii;
28
29
use ntentan\utils\Text;
30
use ntentan\atiaa\Db;
31
32
class QueryOperations {
33
34
    /**
35
     *
36
     * @var RecordWrapper
37
     */
38
    private $wrapper;
39
    private $adapter;
40
    private $queryParameters;
41
    private $pendingMethod;
42
    private $dynamicMethods = [
43
        "/(?<method>filterBy)(?<variable>[A-Z][A-Za-z]+){1}/",
44
        "/(?<method>sort)(?<direction>Asc|Desc)?(By)(?<variable>[A-Z][A-Za-z]+){1}/",
45
        "/(?<method>fetch)(?<first>First)?(With)(?<variable>[A-Za-z]+)/"
46
    ];
47
    private $dataOperations;
48
49
    /**
50
     * 
51
     * @param RecordWrapper $wrapper
52
     * @param DataAdapter $adapter
53
     * @param DataOperations $dataOperations
54
     */
55 36
    public function __construct($wrapper, $adapter, $dataOperations) {
56 36
        $this->wrapper = $wrapper;
57 36
        $this->adapter = $adapter;
58 36
        $this->dataOperations = $dataOperations;
59 36
    }
60
61 26
    public function doFetch($id = null) {
62 26
        $parameters = $this->getFetchQueryParameters($id);
63 26
        $data = $this->adapter->select($parameters);
64 24
        $this->wrapper->setData($data);
65 24
        $this->resetQueryParameters();
66 24
        return $this->wrapper;
67
    }
68
69 26
    private function getFetchQueryParameters($arg) {
70 26
        if ($arg instanceof \ntentan\nibii\QueryParameters) {
71 12
            return $arg;
72
        }        
73
        
74 26
        $parameters = $this->getQueryParameters();
75
        
76 26
        if (is_numeric($arg)) {
77 6
            $description = $this->wrapper->getDescription();
78 6
            $parameters->addFilter($description->getPrimaryKey()[0], [$arg]);
79 6
            $parameters->setFirstOnly(true);
80 22
        } else if (is_array($arg)) {
81 6
            foreach ($arg as $field => $value) {
82 6
                $parameters->addFilter($field, [$value]);
83
            }
84
        }
85
        
86 26
        return $parameters;
87
    }
88
89
    /**
90
     *
91
     * @return \ntentan\nibii\QueryParameters
92
     */
93 34
    private function getQueryParameters($instantiate = true) {
94 34
        if ($this->queryParameters === null && $instantiate) {
95 34
            $this->queryParameters = new QueryParameters($this->wrapper->getDBStoreInformation()['quoted_table']);
96
        }
97 34
        return $this->queryParameters;
98
    }
99
100 32
    private function resetQueryParameters() {
101 32
        $this->queryParameters = null;
102 32
    }
103
104 10
    public function doFetchFirst($id = null) {
105 10
        $this->getQueryParameters()->setFirstOnly(true);
106 10
        return $this->doFetch($id);
107
    }
108
109 12
    public function doFields() {
110 12
        $fields = [];
111 12
        $arguments = func_get_args();
112 12
        foreach ($arguments as $argument) {
113 12
            if (is_array($argument)) {
114 6
                $fields = array_merge($fields, $argument);
115
            } else {
116 12
                $fields[] = $argument;
117
            }
118
        }
119 12
        $this->getQueryParameters()->setFields($fields);
120 12
        return $this->wrapper;
121
    }
122
123 10
    private function getFilter($arguments) {
124 10
        if (count($arguments) == 2 && is_array($arguments[1])) {
125 2
            $filter = $arguments[0];
126 2
            $data = $arguments[1];
127
        } else {
128 10
            $filter = array_shift($arguments);
129 10
            $data = $arguments;
130
        }
131 10
        return ['filter' => $filter, 'data' => $data];
132
    }
133
134 6
    public function doFilter() {
135 6
        $arguments = func_get_args();
136 6
        $details = $this->getFilter($arguments);
137 6
        $filterCompiler = new FilterCompiler();
138 6
        $this->getQueryParameters()->setRawFilter(
139 6
                $filterCompiler->compile($details['filter']), $filterCompiler->rewriteBoundData($details['data'])
140
        );
141 6
        return $this->wrapper;
142
    }
143
144 4
    public function doFilterBy() {
145 4
        $arguments = func_get_args();
146 4
        $details = $this->getFilter($arguments);
147 4
        $this->getQueryParameters()->addFilter($details['filter'], $details['data']);
148 4
        return $this->wrapper;
149
    }
150
151 6
    public function doUpdate($data) {
152 6
        Db::getDriver()->beginTransaction();
153 6
        $parameters = $this->getQueryParameters();
154 6
        $this->adapter->bulkUpdate($data, $parameters);
155 6
        Db::getDriver()->commit();
156 6
        $this->resetQueryParameters();
157 6
    }
158
159 2
    public function doDelete() {
160 2
        Db::getDriver()->beginTransaction();
161 2
        $parameters = $this->getQueryParameters(false);
162
163 2
        if ($parameters === null) {
164
            $primaryKey = $this->wrapper->getDescription()->getPrimaryKey();
165
            $parameters = $this->getQueryParameters();
166
            $data = $this->wrapper->getData();
167
            $keys = [];
168
169
            foreach ($data as $datum) {
170
                if ($this->dataOperations->isItemDeletable($primaryKey, $datum)) {
171
                    $keys[] = $datum[$primaryKey[0]];
172
                }
173
            }
174
175
            $parameters->addFilter($primaryKey[0], $keys);
176
            $this->adapter->delete($parameters);
177
        } else {
178 2
            $this->adapter->delete($parameters);
179
        }
180
181 2
        Db::getDriver()->commit();
182 2
        $this->resetQueryParameters();
183 2
    }
184
185 10
    public function runDynamicMethod($arguments) {
186 10
        switch ($this->pendingMethod['method']) {
187 10
            case 'filterBy':
188 4
                $this->getQueryParameters()->addFilter(Text::deCamelize($this->pendingMethod['variable']), $arguments);
189 4
                return $this->wrapper;
190 8
            case 'sort':
191
                $this->getQueryParameters()->addSort(Text::deCamelize($this->pendingMethod['variable']), $this->pendingMethod['direction']);
192
                return $this->wrapper;
193 8
            case 'fetch':
194 8
                $parameters = $this->getQueryParameters();
195 8
                $parameters->addFilter(Text::deCamelize($this->pendingMethod['variable']), $arguments);
196 8
                if ($this->pendingMethod['first'] === 'First') {
197 8
                    $parameters->setFirstOnly(true);
198
                }
199 8
                return $this->doFetch();
200
        }
201
    }
202
203 10
    public function initDynamicMethod($method) {
204 10
        $return = false;
205
206 10
        foreach ($this->dynamicMethods as $regexp) {
207 10
            if (preg_match($regexp, $method, $matches)) {
208 10
                $return = true;
209 10
                $this->pendingMethod = $matches;
210 10
                break;
211
            }
212
        }
213
214 10
        return $return;
215
    }
216
217
    public function doCount() {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
218
        return $this->adapter->count($this->getQueryParameters());
219
    }
220
221
    public function doLimit($numItems) {
222
        $this->getQueryParameters()->setLimit($numItems);
223
        return $this->wrapper;
224
    }
225
226
    public function doOffset($offset) {
227
        $this->getQueryParameters()->setOffset($offset);
228
        return $this->wrapper;
229
    }
230
231
}
232