ArrayStatement.php 2.55 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\DBAL\Cache;

5
use ArrayIterator;
6
use Doctrine\DBAL\Driver\ResultStatement;
7
use Doctrine\DBAL\FetchMode;
8 9
use InvalidArgumentException;
use IteratorAggregate;
10 11 12 13
use function array_merge;
use function array_values;
use function count;
use function reset;
14

15
class ArrayStatement implements IteratorAggregate, ResultStatement
16
{
17
    /** @var mixed[] */
18
    private $data;
Benjamin Morel's avatar
Benjamin Morel committed
19

20
    /** @var int */
21
    private $columnCount = 0;
Benjamin Morel's avatar
Benjamin Morel committed
22

23
    /** @var int */
24
    private $num = 0;
Benjamin Morel's avatar
Benjamin Morel committed
25

26
    /** @var int */
27
    private $defaultFetchMode = FetchMode::MIXED;
28

Benjamin Morel's avatar
Benjamin Morel committed
29
    /**
30
     * @param mixed[] $data
Benjamin Morel's avatar
Benjamin Morel committed
31
     */
32 33 34
    public function __construct(array $data)
    {
        $this->data = $data;
35
        if (count($data) === 0) {
36
            return;
37
        }
38 39

        $this->columnCount = count($data[0]);
40 41
    }

Benjamin Morel's avatar
Benjamin Morel committed
42 43 44
    /**
     * {@inheritdoc}
     */
45 46
    public function closeCursor()
    {
47
        unset($this->data);
48 49

        return true;
50 51
    }

Benjamin Morel's avatar
Benjamin Morel committed
52 53 54
    /**
     * {@inheritdoc}
     */
55 56 57 58 59
    public function columnCount()
    {
        return $this->columnCount;
    }

Benjamin Morel's avatar
Benjamin Morel committed
60 61 62
    /**
     * {@inheritdoc}
     */
63
    public function setFetchMode($fetchMode)
64
    {
65
        $this->defaultFetchMode = $fetchMode;
Benjamin Morel's avatar
Benjamin Morel committed
66 67

        return true;
68 69
    }

Benjamin Morel's avatar
Benjamin Morel committed
70 71 72
    /**
     * {@inheritdoc}
     */
73 74
    public function getIterator()
    {
75
        $data = $this->fetchAll();
Benjamin Morel's avatar
Benjamin Morel committed
76

77
        return new ArrayIterator($data);
78 79
    }

Benjamin Morel's avatar
Benjamin Morel committed
80 81 82
    /**
     * {@inheritdoc}
     */
83
    public function fetch($fetchMode = null)
84
    {
Sergei Morozov's avatar
Sergei Morozov committed
85
        if (! isset($this->data[$this->num])) {
86
            return false;
87
        }
Benjamin Morel's avatar
Benjamin Morel committed
88

89
        $row       = $this->data[$this->num++];
90
        $fetchMode = $fetchMode ?? $this->defaultFetchMode;
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107

        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);
        }

108
        throw new InvalidArgumentException('Invalid fetch-style given for fetching result.');
109 110
    }

Benjamin Morel's avatar
Benjamin Morel committed
111 112 113
    /**
     * {@inheritdoc}
     */
114
    public function fetchAll($fetchMode = null)
115
    {
116
        $rows = [];
117
        while ($row = $this->fetch($fetchMode)) {
118 119
            $rows[] = $row;
        }
Benjamin Morel's avatar
Benjamin Morel committed
120

121 122 123
        return $rows;
    }

Benjamin Morel's avatar
Benjamin Morel committed
124 125 126
    /**
     * {@inheritdoc}
     */
127
    public function fetchColumn()
128
    {
129
        $row = $this->fetch(FetchMode::NUMERIC);
Benjamin Morel's avatar
Benjamin Morel committed
130

131
        // TODO: verify that return false is the correct behavior
132
        return $row[0] ?? false;
133
    }
134
}