Completed
Push — master ( 4c8d32...c7efbc )
by James Ekow Abaka
04:08
created

QueryOperations::doFields()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 9.4285
cc 3
eloc 10
nc 3
nop 0
crap 3
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
     *
37
     * @var RecordWrapper
38
     */
39
    private $wrapper;
40
    private $adapter;
41
    private $queryParameters;
42
    private $pendingMethod;
43
    private $dynamicMethods = [ 
44
        "/(?<method>filterBy)(?<variable>[A-Z][A-Za-z]+){1}/",
45
        "/(?<method>sort)(?<direction>Asc|Desc)?(By)(?<variable>[A-Z][A-Za-z]+){1}/",
46
        "/(?<method>fetch)(?<first>First)?(With)(?<variable>[A-Za-z]+)/"
47
    ];
48
    private $dataOperations;
49
50
    /**
51
     * 
52
     * @param RecordWrapper $wrapper
53
     * @param DataAdapter $adapter
54
     * @param DataOperations $dataOperations
55
     */
56 34
    public function __construct($wrapper, $adapter, $dataOperations)
57
    {
58 34
        $this->wrapper = $wrapper;
59 34
        $this->adapter = $adapter;
60 34
        $this->dataOperations = $dataOperations;
61 34
    }
62
63 24
    public function doFetch($id = null)
64
    {
65 24
        $parameters = $this->getFetchQueryParameters($id);
66 24
        $data = $this->adapter->select($parameters);
67 24
        $this->wrapper->setData($data);
68 24
        $this->resetQueryParameters();
69 24
        return $this->wrapper;
70
    }
71
72 24
    private function getFetchQueryParameters($arg)
73
    {
74 24
        $parameters = $this->getQueryParameters();
75 24
        if (is_numeric($arg)) {
76 6
            $parameters = $this->getQueryParameters();
77 6
            $description = $this->wrapper->getDescription();
78 6
            $parameters->addFilter($description->getPrimaryKey()[0], [$arg]);
79 6
            $parameters->setFirstOnly(true);
80 24
        } else if ($arg instanceof \ntentan\nibii\QueryParameters) {
81 12
            $parameters = $arg;
82 20
        } else if (is_array($arg)) {
83 6
            foreach($arg as $field => $value) {
84 6
                $parameters->addFilter($field, [$value]);
85
            }
86
        }
87 24
        return $parameters;
88
    }
89
90
    /**
91
     *
92
     * @return \ntentan\nibii\QueryParameters
93
     */
94 32
    private function getQueryParameters($instantiate = true)
95
    {
96 32
        if ($this->queryParameters === null && $instantiate) {
97 32
            $this->queryParameters = new QueryParameters($this->wrapper);
98
        }
99 32
        return $this->queryParameters;
100
    }
101
102 32
    private function resetQueryParameters()
103
    {
104 32
        $this->queryParameters = null;
105 32
    }
106
107 10
    public function doFetchFirst($id = null)
108
    {
109 10
        $this->getQueryParameters()->setFirstOnly(true);
110 10
        return $this->doFetch($id);
111
    }
112
113 12
    public function doFields()
114
    {
115 12
        $fields = [];
116 12
        $arguments = func_get_args();
117 12
        foreach($arguments as $argument) {
118 12
            if(is_array($argument)) {
119 6
                $fields = array_merge($fields, $argument);
120
            } else {
121 12
                $fields[]=$argument;
122
            }
123
        }
124 12
        $this->getQueryParameters()->setFields($fields);
125 12
        return $this->wrapper;
126
    }
127
128 10
    private function getFilter($arguments)
129
    {
130 10
        if (count($arguments) == 2 && is_array($arguments[1])) {
131 2
            $filter = $arguments[0];
132 2
            $data = $arguments[1];
133
        } else {
134 10
            $filter = array_shift($arguments);
135 10
            $data = $arguments;
136
        }
137 10
        return ['filter' => $filter, 'data' => $data];
138
    }
139
140 6
    public function doFilter()
141
    {
142 6
        $arguments = func_get_args();
143 6
        $details = $this->getFilter($arguments);
144 6
        $filterCompiler = new FilterCompiler();
145 6
        $this->getQueryParameters()->setRawFilter(
146 6
                $filterCompiler->compile($details['filter']), $filterCompiler->rewriteBoundData($details['data'])
147
        );
148 6
        return $this->wrapper;
149
    }
150
151 4
    public function doFilterBy()
152
    {
153 4
        $arguments = func_get_args();
154 4
        $details = $this->getFilter($arguments);
155 4
        $this->getQueryParameters()->addFilter($details['filter'], $details['data']);
156 4
        return $this->wrapper;
157
    }
158
159 6
    public function doUpdate($data)
160
    {
161 6
        Db::getDriver()->beginTransaction();
162 6
        $parameters = $this->getQueryParameters();
163 6
        $this->adapter->bulkUpdate($data, $parameters);
164 6
        Db::getDriver()->commit();
165 6
        $this->resetQueryParameters();
166 6
    }
167
168 2
    public function doDelete()
169
    {
170 2
        Db::getDriver()->beginTransaction();
171 2
        $parameters = $this->getQueryParameters(false);
172
173 2
        if ($parameters === null) {
174
            $primaryKey = $this->wrapper->getDescription()->getPrimaryKey();
175
            $parameters = $this->getQueryParameters();
176
            $data = $this->wrapper->getData();
177
            $keys = [];
178
179
            foreach ($data as $datum) {
180
                if ($this->dataOperations->isItemDeletable($primaryKey, $datum)) {
181
                    $keys[] = $datum[$primaryKey[0]];
182
                }
183
            }
184
185
            $parameters->addFilter($primaryKey[0], $keys);
186
            $this->adapter->delete($parameters);
187
        } else {
188 2
            $this->adapter->delete($parameters);
189
        }
190
191 2
        Db::getDriver()->commit();
192 2
        $this->resetQueryParameters();
193 2
    }
194
195 10
    public function runDynamicMethod($arguments)
196
    {
197 10
        switch ($this->pendingMethod['method']) {
198 10
            case 'filterBy':
199 4
                $this->getQueryParameters()->addFilter(Text::deCamelize($this->pendingMethod['variable']), $arguments);
200 4
                return $this->wrapper;
201 8
            case 'sort':
202
                $this->getQueryParameters()->addSort(Text::deCamelize($this->pendingMethod['variable']), $this->pendingMethod['direction']);
203
                return $this->wrapper;
204 8
            case 'fetch':
205 8
                $parameters = $this->getQueryParameters();
206 8
                $parameters->addFilter(Text::deCamelize($this->pendingMethod['variable']), $arguments);
207 8
                if ($this->pendingMethod['first'] === 'First') {
208 8
                    $parameters->setFirstOnly(true);
209
                }
210 8
                return $this->doFetch();
211
        }
212
    }
213
214 10
    public function initDynamicMethod($method)
215
    {
216 10
        $return = false;
217
218 10
        foreach ($this->dynamicMethods as $regexp) {
219 10
            if (preg_match($regexp, $method, $matches)) {
220 10
                $return = true;
221 10
                $this->pendingMethod = $matches;
222 10
                break;
223
            }
224
        }
225
226 10
        return $return;
227
    }
228
229
    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...
230
    {
231
        return $this->adapter->count($this->getQueryParameters());
232
    }
233
234
    public function doLimit($numItems)
235
    {
236
        $this->getQueryParameters()->setLimit($numItems);
237
        return $this->wrapper;
238
    }
239
240
    public function doOffset($offset)
241
    {
242
        $this->getQueryParameters()->setOffset($offset);
243
        return $this->wrapper;
244
    }   
245
}
246