Completed
Push — develop ( 0f123e...6d6ae7 )
by Bartko
05:00
created

Zend2DbAdapter::moveRightIndexes()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 2.0007

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 25
ccs 17
cts 18
cp 0.9444
rs 8.8571
cc 2
eloc 17
nc 2
nop 2
crap 2.0007
1
<?php
2
namespace StefanoTree\NestedSet\Adapter;
3
4
use StefanoTree\NestedSet\Options;
5
use StefanoDb\Adapter\Adapter as DbAdapter;
6
use Zend\Db;
7
use StefanoTree\NestedSet\NodeInfo;
8
use StefanoLockTable\Factory as LockSqlBuilderFactory;
9
use StefanoLockTable\Adapter\AdapterInterface as LockSqlBuilderInterface;
10
11
class Zend2DbAdapter
12
    implements AdapterInterface
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
13
{
14
    private $options;
15
16
    private $dbAdapter;
17
18
    private $defaultDbSelect = null;
19
20
    private $lockSqlBuilder;
21
22 21
    public function __construct(Options $options, DbAdapter $dbAdapter) {
23 21
        $this->options = $options;
24 21
        $this->dbAdapter = $dbAdapter;
25 21
    }
26
27
    /**
28
     * @return Options
29
     */
30 20
    private function getOptions() {
31 20
        return $this->options;
32
    }
33
34
    /**
35
     * @return DbAdapter
36
     */
37 17
    private function getDbAdapter() {
38 17
        return $this->dbAdapter;
39
    }
40
41
    /**
42
     * Data cannot contain keys like idColumnName, levelColumnName, ...
43
     *
44
     * @param array $data
45
     * @return array
46
     */
47 1
    private function cleanData(array $data) {
48 1
        $options = $this->getOptions();
49
50
        $disallowedDataKeys = array(
51 1
            $options->getIdColumnName(),
52 1
            $options->getLeftColumnName(),
53 1
            $options->getRightColumnName(),
54 1
            $options->getLevelColumnName(),
55 1
            $options->getParentIdColumnName(),
56 1
        );
57
58 1
        return array_diff_key($data, array_flip($disallowedDataKeys));
59
    }
60
61
    /**
62
     * @param Db\Sql\Select $dbSelect
63
     * @return void
64
     */
65 1
    public function setDefaultDbSelect(Db\Sql\Select $dbSelect) {
66 1
        $this->defaultDbSelect = $dbSelect;
67 1
    }
68
69
    /**
70
     * Return clone of default db select
71
     * @return Db\Sql\Select
72
     */
73 18
    public function getDefaultDbSelect() {
74 18
        $options = $this->getOptions();
75
76 18
        if(null == $this->defaultDbSelect) {
77 17
            $this->defaultDbSelect = new Db\Sql\Select($options->getTableName());
78 17
        }
79
80 18
        $dbSelect = clone $this->defaultDbSelect;
81
82 18
        return $dbSelect;
83
    }
84
85
    /**
86
    * @return LockSqlBuilderInterface
87
    */
88 12
    private function getLockSqlBuilder() {
89 12
        if(null == $this->lockSqlBuilder) {
90 12
            $vendorName = $this->getDbAdapter()
91 12
                               ->getDriver()
92 12
                               ->getDatabasePlatformName();
93
94 12
            $factory = new LockSqlBuilderFactory();
95 12
            $this->lockSqlBuilder = $factory->createAdapter($vendorName);
96 12
        }
97
98 12
        return $this->lockSqlBuilder;
99
    }
100
101 12
    public function lockTable() {
102 12
        $tableName = $this->getOptions()
103 12
                          ->getTableName();
104
105 12
        $sql = $this->getLockSqlBuilder()
106 12
                    ->getLockSqlString($tableName);
107
108 12
        if(null != $sql) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $sql of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
109 12
            $this->getDbAdapter()
110 12
                 ->query($sql, DbAdapter::QUERY_MODE_EXECUTE);
111 12
        }
112 12
    }
113
114 12
    public function unlockTable() {
115 12
        $sql = $this->getLockSqlBuilder()
116 12
                    ->getUnlockSqlString();
117
118 12
        if(null != $sql) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $sql of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
119
            $this->getDbAdapter()
120
                 ->query($sql, DbAdapter::QUERY_MODE_EXECUTE);
121
        }
122 12
    }
123
124 12
    public function beginTransaction() {
125 12
        $this->getDbAdapter()
126 12
             ->begin();
127 12
    }
128
129 12
    public function commitTransaction() {
130 12
        $this->getDbAdapter()
131 12
             ->commit();
132 12
    }
133
134
    public function rollbackTransaction() {
135
        $this->getDbAdapter()
136
             ->rollback();
137
    }
138
139 2
    public function update($nodeId, array $data, NodeInfo $nodeInfo = null) {
140 2
        $options = $this->getOptions();
141
142 2
        $dbAdapter = $this->getDbAdapter();
143
144 2
        if(null == $nodeInfo) {
145 1
            $data = $this->cleanData($data);
146 1
        } else {
147 1
            $data[$options->getParentIdColumnName()] = $nodeInfo->getParentId();
148 1
            $data[$options->getLevelColumnName()]    = $nodeInfo->getLevel();
149 1
            $data[$options->getLeftColumnName()]     = $nodeInfo->getLeft();
150 1
            $data[$options->getRightColumnName()]    = $nodeInfo->getRight();
151
        }
152
153 2
        $update = new Db\Sql\Update($options->getTableName());
154 2
        $update->set($data)
155 2
               ->where(array(
156 2
                    $options->getIdColumnName() => $nodeId,
157 2
               ));
158
159 2
        $dbAdapter->query($update->getSqlString($dbAdapter->getPlatform()),
160 2
                DbAdapter::QUERY_MODE_EXECUTE);
161 2
    }
162
163 4
    public function insert(NodeInfo $nodeInfo, array $data) {
164 4
        $options = $this->getOptions();
165
166 4
        $dbAdapter = $this->getDbAdapter();
167
168 4
        $data[$options->getParentIdColumnName()] = $nodeInfo->getParentId();
169 4
        $data[$options->getLevelColumnName()]    = $nodeInfo->getLevel();
170 4
        $data[$options->getLeftColumnName()]     = $nodeInfo->getLeft();
171 4
        $data[$options->getRightColumnName()]    = $nodeInfo->getRight();
172
173 4
        $insert = new Db\Sql\Insert($options->getTableName());
174 4
        $insert->values($data);
175 4
        $dbAdapter->query($insert->getSqlString($dbAdapter->getPlatform()),
176 4
            DbAdapter::QUERY_MODE_EXECUTE);
177
178 4
        $lastGeneratedValue = $dbAdapter->getDriver()
179 4
                                        ->getLastGeneratedValue($options->getSequenceName());
180
181 4
        return $lastGeneratedValue;
182
    }
183
184 2
    public function delete($leftIndex, $rightIndex) {
185 2
        $options = $this->getOptions();
186
187 1
        $dbAdapter = $this->getDbAdapter();
188
189 1
        $delete = new Db\Sql\Delete($options->getTableName());
190 1
        $delete->where
191 1
               ->greaterThanOrEqualTo($options->getLeftColumnName(), $leftIndex)
192 1
               ->AND
193 1
               ->lessThanOrEqualTo($options->getRightColumnName(), $rightIndex);
194
195 1
        $dbAdapter->query($delete->getSqlString($dbAdapter->getPlatform()),
196 1
            DbAdapter::QUERY_MODE_EXECUTE);
197 1
    }
198
199 1
    public function deleteAll($expectNodeId) {
200 1
        $options = $this->getOptions();
201 1
        $dbAdapter = $this->getDbAdapter();
202
203 1
        $delete = new Db\Sql\Delete;
204 1
        $delete->from($options->getTableName())
205 1
               ->where
206 1
               ->notEqualTo($options->getIdColumnName(), $expectNodeId);
207 1
        $dbAdapter->query($delete->getSqlString($dbAdapter->getPlatform()),
208 1
            DbAdapter::QUERY_MODE_EXECUTE);
209 1
    }
210
211 9
    public function moveLeftIndexes($fromIndex, $shift) {
212 9
        $options = $this->getOptions();
213
214 9
        if(0 == $shift) {
215
            return null;
216
        }
217
218 9
        $dbAdapter = $this->getDbAdapter();
219 9
        $dbPlatform = $dbAdapter->getPlatform();
220
221 9
        $sql = 'UPDATE ' . $dbPlatform->quoteIdentifier($options->getTableName())
222 9
                . ' SET '
223 9
                    . $dbPlatform->quoteIdentifier($options->getLeftColumnName()) . ' = '
224 9
                        . $dbPlatform->quoteIdentifier($options->getLeftColumnName()) . ' + :shift'
225 9
                . ' WHERE '
226 9
                    . $dbPlatform->quoteIdentifier($options->getLeftColumnName()) . ' > :fromIndex';
227
228
        $binds = array(
229 9
            ':shift' => $shift,
230 9
            ':fromIndex' => $fromIndex,
231 9
        );
232
233 9
        $dbAdapter->query($sql)
234 9
                  ->execute($binds);
235 9
    }
236
237 9
    public function moveRightIndexes($fromIndex, $shift) {
238 9
        $options = $this->getOptions();
239
240 9
        if(0 == $shift) {
241
            return null;
242
        }
243
244 9
        $dbAdapter = $this->getDbAdapter();
245 9
        $dbPlatform = $dbAdapter->getPlatform();
246
247 9
        $sql = 'UPDATE ' . $dbPlatform->quoteIdentifier($options->getTableName())
248 9
                . ' SET '
249 9
                    . $dbPlatform->quoteIdentifier($options->getRightColumnName()) . ' = '
250 9
                        . $dbPlatform->quoteIdentifier($options->getRightColumnName()) . ' + :shift'
251 9
                . ' WHERE '
252 9
                    . $dbPlatform->quoteIdentifier($options->getRightColumnName()) . ' > :fromIndex';
253
254
        $binds = array(
255 9
            ':shift' => $shift,
256 9
            ':fromIndex' => $fromIndex,
257 9
        );
258
259 9
        $dbAdapter->query($sql)
260 9
                  ->execute($binds);
261 9
    }
262
263 4
    public function updateParentId($nodeId, $newParentId) {
264 4
        $options = $this->getOptions();
265
266 4
        $dbAdapter = $this->getDbAdapter();
267
268 4
        $update = new Db\Sql\Update($options->getTableName());
269 4
        $update->set(array(
270 4
                    $options->getParentIdColumnName() => $newParentId,
271 4
               ))
272 4
               ->where(array(
273 4
                   $options->getIdColumnName() => $nodeId,
274 4
               ));
275
276 4
        $dbAdapter->query($update->getSqlString($dbAdapter->getPlatform()),
277 4
            DbAdapter::QUERY_MODE_EXECUTE);
278 4
    }
279
280 4
    public function updateLevels($leftIndexFrom, $rightIndexTo, $shift) {
281 4
        $options = $this->getOptions();
282
283 4
        if(0 == $shift) {
284
            return null;
285
        }
286
287 4
        $dbAdapter = $this->getDbAdapter();
288 4
        $dbPlatform = $dbAdapter->getPlatform();
289
290 4
        $sql = 'UPDATE ' . $dbPlatform->quoteIdentifier($options->getTableName())
291 4
            . ' SET '
292 4
                . $dbPlatform->quoteIdentifier($options->getLevelColumnName()) . ' = '
293 4
                    . $dbPlatform->quoteIdentifier($options->getLevelColumnName()) . ' + :shift'
294 4
            . ' WHERE '
295 4
                . $dbPlatform->quoteIdentifier($options->getLeftColumnName()) . ' >= :leftFrom'
296 4
                . ' AND ' . $dbPlatform->quoteIdentifier($options->getRightColumnName()) . ' <= :rightTo';
297
298
        $binds = array(
299 4
            ':shift' => $shift,
300 4
            ':leftFrom' => $leftIndexFrom,
301 4
            ':rightTo' => $rightIndexTo,
302 4
        );
303
304 4
        $dbAdapter->query($sql)
305 4
                  ->execute($binds);
306 4
    }
307
308 4
    public function moveBranch($leftIndexFrom, $rightIndexTo, $shift) {
309 4
        if(0 == $shift) {
310
            return;
311
        }
312
313 4
        $options = $this->getOptions();
314
315 4
        $dbAdapter = $this->getDbAdapter();
316 4
        $dbPlatform = $dbAdapter->getPlatform();
317
318 4
        $sql = 'UPDATE ' . $dbPlatform->quoteIdentifier($options->getTableName())
319 4
            . ' SET '
320 4
                . $dbPlatform->quoteIdentifier($options->getLeftColumnName()) . ' = '
321 4
                    . $dbPlatform->quoteIdentifier($options->getLeftColumnName()) . ' + :shift, '
322 4
                . $dbPlatform->quoteIdentifier($options->getRightColumnName()) . ' = '
323 4
                    . $dbPlatform->quoteIdentifier($options->getRightColumnName()) . ' + :shift'
324 4
            . ' WHERE '
325 4
                . $dbPlatform->quoteIdentifier($options->getLeftColumnName()) . ' >= :leftFrom'
326 4
                . ' AND ' . $dbPlatform->quoteIdentifier($options->getRightColumnName()) . ' <= :rightTo';
327
328
        $binds = array(
329 4
            ':shift' => $shift,
330 4
            ':leftFrom' => $leftIndexFrom,
331 4
            ':rightTo' => $rightIndexTo,
332 4
        );
333
334 4
        $dbAdapter->query($sql)
335 4
                  ->execute($binds);
336 4
    }
337
338 15
    public function getNode($nodeId) {
339 15
        $options = $this->getOptions();
340
341 15
        $nodeId = (int) $nodeId;
342
343 15
        $dbAdapter = $this->getDbAdapter();
344
345 15
        $select = $this->getDefaultDbSelect()
346 15
                       ->where(array($options->getIdColumnName() =>  $nodeId));
347
348 15
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
349 15
                DbAdapter::QUERY_MODE_EXECUTE);
350
351 15
        $array = $result->toArray();
352
353 15
        if(0 < count($array)) {
354 14
            return $array[0];
355
        }
356 7
    }
357
358 14
    public function getNodeInfo($nodeId) {
359 14
        $options = $this->getOptions();
360 14
        $result = $this->getNode($nodeId);
361
362 14
        if(null == $result) {
363 6
            $result = null;
364 6
        } else {
365 13
            $id        = $result[$options->getIdColumnName()];
366 13
            $parentId  = $result[$options->getParentIdColumnName()];
367 13
            $level     = $result[$options->getLevelColumnName()];
368 13
            $left      = $result[$options->getLeftColumnName()];
369 13
            $right     = $result[$options->getRightColumnName()];
370
371 13
            $result = new NodeInfo($id, $parentId, $level, $left, $right);
372
        }
373
374 14
        return $result;
375
    }
376
377 1
    public function getPath($nodeId, $startLevel = 0, $excludeLastNode = false) {
378 1
        $options = $this->getOptions();
379
380 1
        $startLevel = (int) $startLevel;
381
382
        // node does not exist
383 1
        if(!$nodeInfo = $this->getNodeInfo($nodeId)) {
384 1
            return null;
385
        }
386
387 1
        $dbAdapter = $this->getDbAdapter();
388
389 1
        $select = $this->getDefaultDbSelect();
390 1
        $select->where
391 1
               ->lessThanOrEqualTo($options->getLeftColumnName(), $nodeInfo->getLeft())
392 1
               ->AND
393 1
               ->greaterThanOrEqualTo($options->getRightColumnName(), $nodeInfo->getRight());
394
395 1
        $select->order($options->getLeftColumnName() . ' ASC');
396
397 1
        if(0 < $startLevel) {
398 1
            $select->where
399 1
                   ->greaterThanOrEqualTo($options->getLevelColumnName(), $startLevel);
400 1
        }
401
402 1
        if(true == $excludeLastNode) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
403 1
            $select->where
404 1
                   ->lessThan($options->getLevelColumnName(), $nodeInfo->getLevel());
405 1
        }
406
407 1
        $result = $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
408 1
            DbAdapter::QUERY_MODE_EXECUTE);
409
410 1
        return $result->toArray();
411
    }
412
413 2
    public function getDescendants($nodeId = 1, $startLevel = 0, $levels = null, $excludeBranch = null) {
414 2
        $options = $this->getOptions();
415
416 2
        if(!$nodeInfo = $this->getNodeInfo($nodeId)) {
417 2
            return null;
418
        }
419
420 2
        $dbAdapter = $this->getDbAdapter();
421 2
        $select = $this->getDefaultDbSelect();
422 2
        $select->order($options->getLeftColumnName() . ' ASC');
423
424
425 2
        if(0 != $startLevel) {
426 2
            $level = $nodeInfo->getLevel() + (int) $startLevel;
427 2
            $select->where
428 2
                   ->greaterThanOrEqualTo($options->getLevelColumnName(), $level);
429 2
        }
430
431 2
        if(null != $levels) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $levels of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
432 2
            $endLevel = $nodeInfo->getLevel() + (int) $startLevel + abs($levels);
433 2
            $select->where
434 2
                   ->lessThan($options->getLevelColumnName(), $endLevel);
435 2
        }
436
437 2
        if(null != $excludeBranch && null != ($excludeNodeInfo = $this->getNodeInfo($excludeBranch))) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $excludeBranch of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison !== instead.
Loading history...
438 1
            $select->where
439 1
                   ->NEST
440 1
                   ->between($options->getLeftColumnName(),
441 1
                        $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1)
442 1
                   ->OR
443 1
                   ->between($options->getLeftColumnName(),
444 1
                        $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight())
445 1
                   ->UNNEST
446 1
                   ->AND
447 1
                   ->NEST
448 1
                   ->between($options->getRightColumnName(),
449 1
                        $excludeNodeInfo->getRight() + 1, $nodeInfo->getRight())
450 1
                   ->OR
451 1
                   ->between($options->getRightColumnName(),
452 1
                        $nodeInfo->getLeft(), $excludeNodeInfo->getLeft() - 1)
453 1
                   ->UNNEST;
454 1
        } else {
455 2
            $select->where
456 2
                   ->greaterThanOrEqualTo($options->getLeftColumnName(), $nodeInfo->getLeft())
457 2
                   ->AND
458 2
                   ->lessThanOrEqualTo($options->getRightColumnName(), $nodeInfo->getRight());
459
        }
460
461 2
        $result =  $dbAdapter->query($select->getSqlString($dbAdapter->getPlatform()),
462 2
            DbAdapter::QUERY_MODE_EXECUTE);
463
464 2
        $resultArray = $result->toArray();
465
466 2
        if(0 < count($resultArray)) {
467 2
            return $resultArray;
468
        }
469 1
    }
470
}
471