• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

valkyrjaio / valkyrja / 13047041070

30 Jan 2025 06:43AM UTC coverage: 47.621% (+0.2%) from 47.422%
13047041070

push

github

MelechMizrachi
PHPStan level 7 and 8.

168 of 1038 new or added lines in 111 files covered. (16.18%)

444 existing lines in 45 files now uncovered.

5195 of 10909 relevant lines covered (47.62%)

18.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Valkyrja/Orm/Query/Query.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <melechmizrachi@gmail.com>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13

14
namespace Valkyrja\Orm\Query;
15

16
use stdClass;
17
use Valkyrja\Exception\RuntimeException;
18
use Valkyrja\Orm\Adapter\Contract\Adapter;
19
use Valkyrja\Orm\Entity\Contract\Entity;
20
use Valkyrja\Orm\Exception\NotFoundException;
21
use Valkyrja\Orm\Query\Contract\Query as QueryContract;
22
use Valkyrja\Orm\Statement\Contract\Statement;
23
use Valkyrja\Orm\Support\Helpers;
24

25
use function assert;
26
use function is_array;
27
use function is_int;
28
use function is_string;
29

30
/**
31
 * Class Query.
32
 *
33
 * @author Melech Mizrachi
34
 */
35
class Query implements QueryContract
36
{
37
    /**
38
     * The statement.
39
     *
40
     * @var Statement
41
     */
42
    protected Statement $statement;
43

44
    /**
45
     * The table to query on.
46
     *
47
     * @var string|null
48
     */
49
    protected string|null $table = null;
50

51
    /**
52
     * The entity to query with.
53
     *
54
     * @var class-string<Entity>|null
55
     */
56
    protected string|null $entity = null;
57

58
    /**
59
     * Query constructor.
60
     *
61
     * @param Adapter $adapter
62
     */
63
    public function __construct(
64
        protected Adapter $adapter
65
    ) {
66
    }
×
67

68
    /**
69
     * @inheritDoc
70
     */
71
    public function table(string $table): static
72
    {
73
        $this->table = $table;
×
74

75
        return $this;
×
76
    }
77

78
    /**
79
     * @inheritDoc
80
     */
81
    public function entity(string $entity): static
82
    {
83
        assert(is_a($entity, Entity::class, true));
×
84

85
        $this->entity = $entity;
×
86

87
        return $this;
×
88
    }
89

90
    /**
91
     * @inheritDoc
92
     */
93
    public function prepare(string $query): static
94
    {
95
        $entity = $this->entity;
×
96

97
        if ($entity !== null) {
×
98
            $query = str_replace($entity, $entity::getTableName(), $query);
×
99
        }
100

101
        $this->statement = $this->adapter->prepare($query);
×
102

103
        if ($this->table !== null) {
×
104
            $this->bindValue('table', $this->table);
×
105
        }
106

107
        return $this;
×
108
    }
109

110
    /**
111
     * @inheritDoc
112
     */
113
    public function bindValue(string $property, mixed $value): static
114
    {
115
        if (is_array($value)) {
×
116
            foreach ($value as $key => $item) {
×
117
                $this->bindValue($property . $key, $item);
×
118
            }
119

120
            return $this;
×
121
        }
122

123
        // And bind each value to the column
124
        $this->statement->bindValue(Helpers::getColumnForValueBind($property), $value);
×
125

126
        return $this;
×
127
    }
128

129
    /**
130
     * @inheritDoc
131
     */
132
    public function execute(): bool
133
    {
134
        return $this->statement->execute();
×
135
    }
136

137
    /**
138
     * @inheritDoc
139
     */
140
    public function getResult(): array
141
    {
142
        $results = $this->statement->fetchAll();
×
143

144
        /** @var class-string<Entity>|null $entity */
145
        $entity = $this->entity;
×
146

147
        // If there is no entity specified just return the results
148
        if ($entity === null) {
×
149
            return array_map(
×
150
                static function (array $data): stdClass {
×
151
                    /** @var stdClass $object */
152
                    $object = (object) $data;
×
153

154
                    return $object;
×
155
                },
×
156
                $results
×
157
            );
×
158
        }
159

160
        return array_map(
×
161
            static fn (array $data): Entity => $entity::fromArray($data),
×
162
            $results
×
163
        );
×
164
    }
165

166
    /**
167
     * @inheritDoc
168
     */
169
    public function getOneOrNull(): Entity|stdClass|null
170
    {
171
        return $this->getResult()[0] ?? null;
×
172
    }
173

174
    /**
175
     * @inheritDoc
176
     */
177
    public function getOneOrFail(): object
178
    {
179
        $results = $this->getOneOrNull();
×
180

181
        if ($results === null) {
×
182
            throw new NotFoundException('Result Not Found');
×
183
        }
184

185
        return $results;
×
186
    }
187

188
    /**
189
     * @inheritDoc
190
     */
191
    public function getCount(): int
192
    {
193
        $results = $this->statement->fetchAll();
×
194

NEW
195
        $count = ($results[0]['COUNT(*)'] ?? $results[0]['count'] ?? 0);
×
196

NEW
197
        if (is_int($count)) {
×
NEW
198
            return $count;
×
199
        }
200

NEW
201
        if (is_string($count)) {
×
NEW
202
            return (int) $count;
×
203
        }
204

NEW
205
        throw new RuntimeException('Unsupported count results');
×
206
    }
207

208
    /**
209
     * @inheritDoc
210
     */
211
    public function getError(): string
212
    {
213
        return $this->statement->errorMessage() ?? 'An unknown error occurred.';
×
214
    }
215
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc