ArrayStatement.php 3.09 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
    }

47
    public function closeCursor() : void
48
    {
Benjamin Morel's avatar
Benjamin Morel committed
49
        $this->data = [];
50 51
    }

52
    public function columnCount() : int
53 54 55 56
    {
        return $this->columnCount;
    }

57 58 59 60 61
    public function rowCount() : int
    {
        return count($this->data);
    }

Benjamin Morel's avatar
Benjamin Morel committed
62 63 64
    /**
     * {@inheritdoc}
     */
65
    public function setFetchMode(int $fetchMode, ...$args) : void
66
    {
67
        if (count($args) > 0) {
68
            throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode().');
69 70
        }

71
        $this->defaultFetchMode = $fetchMode;
72 73
    }

Benjamin Morel's avatar
Benjamin Morel committed
74 75 76
    /**
     * {@inheritdoc}
     */
77 78
    public function getIterator()
    {
79
        $data = $this->fetchAll();
Benjamin Morel's avatar
Benjamin Morel committed
80

81
        return new ArrayIterator($data);
82 83
    }

Benjamin Morel's avatar
Benjamin Morel committed
84 85 86
    /**
     * {@inheritdoc}
     */
87
    public function fetch(?int $fetchMode = null, ...$args)
88
    {
Sergei Morozov's avatar
Sergei Morozov committed
89
        if (! isset($this->data[$this->num])) {
90
            return false;
91
        }
Benjamin Morel's avatar
Benjamin Morel committed
92

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
        $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);
        }

112 113 114
        throw new InvalidArgumentException(
            sprintf('Invalid fetch mode given for fetching result, %d given.', $fetchMode)
        );
115 116
    }

Benjamin Morel's avatar
Benjamin Morel committed
117 118 119
    /**
     * {@inheritdoc}
     */
120
    public function fetchAll(?int $fetchMode = null, ...$args) : array
121
    {
122
        $rows = [];
123
        while ($row = $this->fetch($fetchMode, ...$args)) {
124 125
            $rows[] = $row;
        }
Benjamin Morel's avatar
Benjamin Morel committed
126

127 128 129
        return $rows;
    }

Benjamin Morel's avatar
Benjamin Morel committed
130 131 132
    /**
     * {@inheritdoc}
     */
133
    public function fetchColumn(int $columnIndex = 0)
134
    {
135
        $row = $this->fetch(FetchMode::NUMERIC);
Benjamin Morel's avatar
Benjamin Morel committed
136

137 138 139 140 141
        if ($row === false) {
            return false;
        }

        if (! array_key_exists($columnIndex, $row)) {
142
            throw InvalidColumnIndex::new($columnIndex, count($row));
143 144 145
        }

        return $row[$columnIndex];
146
    }
147
}