Result::obtainNumRows()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 10
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
/** @noinspection PhpComposerExtensionStubsInspection */
4
5
declare(strict_types=1);
6
7
namespace EngineWorks\DBAL\Mssql;
8
9
use EngineWorks\DBAL\Internal\SqlServerResultFields;
10
use EngineWorks\DBAL\Result as ResultInterface;
11
use EngineWorks\DBAL\Traits\ResultImplementsCountable;
12
use EngineWorks\DBAL\Traits\ResultImplementsIterator;
13
use PDO;
14
use PDOStatement;
15
16
class Result implements ResultInterface
17
{
18
    use ResultImplementsCountable;
19
    use ResultImplementsIterator;
20
21
    /**
22
     * PDO element
23
     * @var PDOStatement<mixed>
24
     */
25
    private $stmt;
26
27
    /**
28
     * The number of the result rows
29
     * @var int
30
     */
31
    private $numRows;
32
33
    /**
34
     * Set of fieldname and commontype to use instead of detectedTypes
35
     * @var array<string, string>
36
     */
37
    private $overrideTypes;
38
39
    /**
40
     * The place where getFields result is cached
41
     * @var array<int, array{name: string, table: string, commontype: string}>|null
42
     */
43
    private $cachedGetFields;
44
45
    /**
46
     * Result based on PDOStatement
47
     *
48
     * @param PDOStatement<mixed> $result
49
     * @param int $numRows If negative number then the number of rows will be obtained
50
     * from fetching all the rows and move first
51
     * @param array<string, string> $overrideTypes
52
     */
53 52
    public function __construct(PDOStatement $result, int $numRows, array $overrideTypes = [])
54
    {
55 52
        $this->stmt = $result;
56 52
        $this->overrideTypes = $overrideTypes;
57 52
        $this->numRows = ($numRows < 0) ? $this->obtainNumRows() : $numRows;
58
    }
59
60
    /**
61
     * Close the query and remove property association
62
     */
63 42
    public function __destruct()
64
    {
65 42
        $this->stmt->closeCursor();
66
    }
67
68
    /**
69
     * Internal method to retrieve the number of rows if not supplied from constructor
70
     */
71 46
    private function obtainNumRows(): int
72
    {
73 46
        $count = 0;
74 46
        while (false !== $this->stmt->fetch(PDO::FETCH_NUM)) {
75 46
            $count = $count + 1;
76
        }
77 46
        $this->stmt->execute();
78 46
        return $count;
79
    }
80
81 10
    public function getFields(): array
82
    {
83 10
        if (null === $this->cachedGetFields) {
84 10
            $typeChecker = new SqlServerResultFields($this->overrideTypes, 'native_type');
85 10
            $this->cachedGetFields = $typeChecker->obtainFields($this->stmt);
86
        }
87
88 10
        return $this->cachedGetFields;
89
    }
90
91 6
    public function getIdFields(): bool
92
    {
93 6
        return false;
94
    }
95
96 14
    public function resultCount(): int
97
    {
98 14
        return $this->numRows;
99
    }
100
101 40
    public function fetchRow()
102
    {
103 40
        $return = $this->stmt->fetch(PDO::FETCH_ASSOC);
104 40
        return (! is_array($return)) ? false : $return;
105
    }
106
107 3
    public function moveTo(int $offset): bool
108
    {
109
        // there are no records
110 3
        if ($this->resultCount() <= 0) {
111 1
            return false;
112
        }
113
        // the offset is out of bounds
114 2
        if ($offset < 0 || $offset > $this->resultCount() - 1) {
115 1
            return false;
116
        }
117
        // if the offset is on previous
118 1
        if (! $this->moveFirst()) {
119
            return false;
120
        }
121
        // move to the offset
122 1
        for ($i = 0; $i < $offset; $i++) {
123 1
            if (false === $this->stmt->fetch(PDO::FETCH_NUM)) {
124
                return false;
125
            }
126
        }
127 1
        return true;
128
    }
129
130 6
    public function moveFirst(): bool
131
    {
132 6
        if ($this->resultCount() <= 0) {
133 1
            return false;
134
        }
135 5
        return (false !== $this->stmt->execute());
136
    }
137
}
138