Completed
Pull Request — master (#3)
by Rémy
08:33
created

Query::getConnection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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