Passed
Push — master ( 27ca4d...8d618a )
by Ondřej
02:45 queued 10s
created

CursorControl::declareCursor()   B

Complexity

Conditions 7
Paths 26

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 24
nc 26
nop 3
dl 0
loc 36
rs 8.6026
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
namespace Ivory\Connection;
4
5
use Ivory\Query\IRelationDefinition;
6
use Ivory\Relation\Cursor;
7
use Ivory\Relation\CursorProperties;
8
use Ivory\Relation\ICursor;
9
10
class CursorControl implements ICursorControl
11
{
12
    private $stmtExec;
13
14
    public function __construct(IStatementExecution $stmtExec)
15
    {
16
        $this->stmtExec = $stmtExec;
17
    }
18
19
    public function declareCursor(string $name, IRelationDefinition $relationDefinition, int $options = 0): ICursor
20
    {
21
        $isBinary = (bool)($options & ICursor::BINARY);
22
        $isHoldable = (bool)($options & ICursor::HOLDABLE);
23
        $isScrollable = null;
24
25
        $declarePattern = 'DECLARE %ident';
26
        if ($isBinary) {
27
            $declarePattern .= ' BINARY';
28
        }
29
30
        if ($options & ICursor::NON_SCROLLABLE) {
31
            if ($options & ICursor::SCROLLABLE) {
32
                throw new \LogicException("Cursor `$name` specified to be both scrollable and non-scrollable");
33
            }
34
            $isScrollable = false;
35
            $declarePattern .= ' NO SCROLL';
36
        } elseif ($options & ICursor::SCROLLABLE) {
37
            $isScrollable = true;
38
            $declarePattern .= ' SCROLL';
39
        }
40
41
        $declarePattern .= ' CURSOR';
42
        if ($isHoldable) {
43
            $declarePattern .= ' WITH HOLD';
44
        }
45
46
        $declarePattern .= ' FOR %rel';
47
48
        $this->stmtExec->command($declarePattern, $name, $relationDefinition);
49
        if ($isScrollable !== null) {
50
            $props = new CursorProperties($isHoldable, $isScrollable, $isBinary);
51
        } else {
52
            $props = null;
53
        }
54
        return new Cursor($this->stmtExec, $name, $props);
55
    }
56
57
    public function getAllCursors(): array
58
    {
59
        $rel = $this->stmtExec->query(
60
            "SELECT name, is_holdable, is_scrollable, is_binary
61
             FROM pg_catalog.pg_cursors
62
             WHERE name != ''
63
             ORDER BY creation_time"
64
        );
65
        $result = [];
66
        foreach ($rel as $tuple) {
67
            $name = $tuple->name;
68
            $props = new CursorProperties($tuple->is_holdable, $tuple->is_scrollable, $tuple->is_binary);
69
            $result[$name] = new Cursor($this->stmtExec, $name, $props);
70
        }
71
        return $result;
72
    }
73
74
    public function closeAllCursors(): void
75
    {
76
        $this->stmtExec->command('CLOSE ALL');
77
    }
78
}
79