Completed
Pull Request — master (#3)
by Rémy
01:26
created

Query::getConnection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * @author Rémy M. Böhler <[email protected]>
4
 */
5
declare(strict_types=1);
6
7
namespace Rorm;
8
9
class Query
10
{
11
    /** @var \PDO */
12
    private $connection;
13
14
    /** @var string */
15
    private $class;
16
17
    /** @var string */
18
    private $query;
19
20
    /** @var array */
21
    private $params;
22
23
    /** @var \PDOStatement */
24
    private $statement;
25
26
    /** @var ModelBuilder */
27
    private $modelBuilder;
28
29 22
    public function __construct(\PDO $connection, ModelBuilder $modelBuilder, string $class = \stdClass::class)
30
    {
31 22
        $this->connection = $connection;
32 22
        $this->class = $class;
33 22
        $this->modelBuilder = $modelBuilder;
34 22
    }
35
36 22
    public function getClass(): string
37
    {
38 22
        return $this->class;
39
    }
40
41 22
    public function getConnection(): \PDO
42
    {
43 22
        return $this->connection;
44
    }
45
46 2
    public function setQuery(string $query): void
47
    {
48 2
        $this->query = $query;
49 2
    }
50
51 2
    public function getQuery(): ?string
52
    {
53 2
        return $this->query;
54
    }
55
56 2
    public function setParams(array $params): void
57
    {
58 2
        $this->params = $params;
59 2
    }
60
61 2
    public function getParams(): ?array
62
    {
63 2
        return $this->params;
64
    }
65
66 12
    private function execute(): void
67
    {
68 12
        $this->statement = $this->connection->prepare($this->query);
69
        // set fetchMode to assoc, it is easier to copy data from an array than an object
70 12
        $this->statement->setFetchMode(\PDO::FETCH_ASSOC);
71
72 12
        if (!$this->statement->execute($this->params)) {
73
            // in case of the error mode does not throw exceptions we create one
74 2
            throw new \PDOException($this->statement->errorInfo(), $this->statement->errorCode());
75
        }
76 10
    }
77
78 4
    private function fetch()
79
    {
80 4
        $data = $this->statement->fetch();
81 4
        if ($data !== false) {
82 2
            return $this->instanceFromObject($data);
83
        }
84 2
        return null;
85
    }
86
87 4
    public function instanceFromObject(array $data)
88
    {
89 4
        $instance = $this->modelBuilder->build($this->class);
90 4
        if ($instance instanceof Model) {
91 2
            $instance->setData($data);
92
        } else {
93 2
            foreach ($data as $key => $value) {
94 2
                $instance->$key = $value;
95
            }
96
        }
97
98 4
        return $instance;
99
    }
100
101 2
    public function findColumn()
102
    {
103 2
        $this->execute();
104 2
        return $this->statement->fetchColumn();
105
    }
106
107
    /**
108
     * Return one object
109
     */
110 4
    public function findOne()
111
    {
112
        // DO NOT use rowCount to check if something was found because not all drivers support it
113 4
        $this->execute();
114 4
        return $this->fetch();
115
    }
116
117
    /**
118
     * Return a iterator to iterate over which returns one object at a time
119
     * the objects are lazy loaded and not kept on memory
120
     *
121
     * because the results are not buffered you can only iterate once over it!
122
     * If you need to iterate multiple times over the result you should use the findAll method
123
     *
124
     * Note for PHP 5.5
125
     * yield could be used
126
     */
127 2
    public function findMany(): \Generator
128
    {
129 2
        $this->execute();
130 2
        while ($object = $this->statement->fetchObject()) {
131 2
            yield $this->instanceFromObject($object);
132
        }
133 2
    }
134
135
    /**
136
     * Return an array with all objects, this can lead to heavy memory consumption
137
     */
138 2
    public function findAll(): array
139
    {
140 2
        $result = [];
141
142 2
        foreach ($this->findMany() as $object) {
143 2
            $result[] = $object;
144
        }
145
146 2
        return $result;
147
    }
148
149
    /**
150
     * This operation is very expensive.
151
     *
152
     * PDOStatement::rowCount does not work on all drivers!
153
     */
154 2
    public function count(): int
155
    {
156 2
        return count($this->findAll());
157
    }
158
}
159