ArrayStatement.php 3.26 KB
Newer Older
1 2
<?php

Michael Moravec's avatar
Michael Moravec committed
3 4
declare(strict_types=1);

5 6
namespace Doctrine\DBAL\Cache;

7
use ArrayIterator;
8
use Doctrine\DBAL\Driver\ResultStatement;
9
use Doctrine\DBAL\Exception\InvalidColumnIndex;
10
use Doctrine\DBAL\FetchMode;
11 12
use InvalidArgumentException;
use IteratorAggregate;
13
use function array_key_exists;
14 15 16 17
use function array_merge;
use function array_values;
use function count;
use function reset;
18
use function sprintf;
19

20
final class ArrayStatement implements IteratorAggregate, ResultStatement
21
{
22
    /** @var mixed[] */
23
    private $data;
Benjamin Morel's avatar
Benjamin Morel committed
24

25
    /** @var int */
26
    private $columnCount = 0;
Benjamin Morel's avatar
Benjamin Morel committed
27

28
    /** @var int */
29
    private $num = 0;
Benjamin Morel's avatar
Benjamin Morel committed
30

31
    /** @var int */
32
    private $defaultFetchMode = FetchMode::MIXED;
33

Benjamin Morel's avatar
Benjamin Morel committed
34
    /**
35
     * @param mixed[] $data
Benjamin Morel's avatar
Benjamin Morel committed
36
     */
37 38 39
    public function __construct(array $data)
    {
        $this->data = $data;
40 41
        if (! count($data)) {
            return;
42
        }
43 44

        $this->columnCount = count($data[0]);
45 46
    }

Benjamin Morel's avatar
Benjamin Morel committed
47 48 49
    /**
     * {@inheritdoc}
     */
50
    public function closeCursor() : void
51
    {
52
        $this->data = null;
53 54
    }

Benjamin Morel's avatar
Benjamin Morel committed
55 56 57
    /**
     * {@inheritdoc}
     */
58
    public function columnCount() : int
59 60 61 62
    {
        return $this->columnCount;
    }

63 64 65 66 67 68 69 70 71 72 73 74
    /**
     * {@inheritdoc}
     */
    public function rowCount() : int
    {
        if ($this->data === null) {
            return 0;
        }

        return count($this->data);
    }

Benjamin Morel's avatar
Benjamin Morel committed
75 76 77
    /**
     * {@inheritdoc}
     */
78
    public function setFetchMode(int $fetchMode, ...$args) : void
79
    {
80
        if (count($args) > 0) {
81
            throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode().');
82 83
        }

84
        $this->defaultFetchMode = $fetchMode;
85 86
    }

Benjamin Morel's avatar
Benjamin Morel committed
87 88 89
    /**
     * {@inheritdoc}
     */
90 91
    public function getIterator()
    {
92
        $data = $this->fetchAll();
Benjamin Morel's avatar
Benjamin Morel committed
93

94
        return new ArrayIterator($data);
95 96
    }

Benjamin Morel's avatar
Benjamin Morel committed
97 98 99
    /**
     * {@inheritdoc}
     */
100
    public function fetch(?int $fetchMode = null, ...$args)
101
    {
Sergei Morozov's avatar
Sergei Morozov committed
102
        if (! isset($this->data[$this->num])) {
103
            return false;
104
        }
Benjamin Morel's avatar
Benjamin Morel committed
105

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
        $row       = $this->data[$this->num++];
        $fetchMode = $fetchMode ?: $this->defaultFetchMode;

        if ($fetchMode === FetchMode::ASSOCIATIVE) {
            return $row;
        }

        if ($fetchMode === FetchMode::NUMERIC) {
            return array_values($row);
        }

        if ($fetchMode === FetchMode::MIXED) {
            return array_merge($row, array_values($row));
        }

        if ($fetchMode === FetchMode::COLUMN) {
            return reset($row);
        }

125 126 127
        throw new InvalidArgumentException(
            sprintf('Invalid fetch mode given for fetching result, %d given.', $fetchMode)
        );
128 129
    }

Benjamin Morel's avatar
Benjamin Morel committed
130 131 132
    /**
     * {@inheritdoc}
     */
133
    public function fetchAll(?int $fetchMode = null, ...$args) : array
134
    {
135
        $rows = [];
136
        while ($row = $this->fetch($fetchMode, ...$args)) {
137 138
            $rows[] = $row;
        }
Benjamin Morel's avatar
Benjamin Morel committed
139

140 141 142
        return $rows;
    }

Benjamin Morel's avatar
Benjamin Morel committed
143 144 145
    /**
     * {@inheritdoc}
     */
146
    public function fetchColumn(int $columnIndex = 0)
147
    {
148
        $row = $this->fetch(FetchMode::NUMERIC);
Benjamin Morel's avatar
Benjamin Morel committed
149

150 151 152 153 154
        if ($row === false) {
            return false;
        }

        if (! array_key_exists($columnIndex, $row)) {
155
            throw InvalidColumnIndex::new($columnIndex, count($row));
156 157 158
        }

        return $row[$columnIndex];
159
    }
160
}