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

ICanBoogie / ActiveRecord / 11873528571

16 Nov 2024 09:57PM UTC coverage: 86.125%. Remained the same
11873528571

push

github

olvlvl
Test against PHP 8.4

2 of 3 new or added lines in 3 files covered. (66.67%)

2 existing lines in 1 file now uncovered.

1378 of 1600 relevant lines covered (86.13%)

24.48 hits per line

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

92.31
/lib/ActiveRecord/Statement.php
1
<?php
2

3
namespace ICanBoogie\ActiveRecord;
4

5
use ICanBoogie\Accessor\AccessorTrait;
6
use PDO;
7
use PDOException;
8
use PDOStatement;
9

10
use function is_array;
11
use function json_encode;
12

13
/**
14
 * A database statement.
15
 *
16
 * @see self::get_as_assoc()
17
 * @property-read $this $as_assoc
18
 *     Equivalent to `mode(PDO::FETCH_ASSOC)`.
19
 *
20
 * @see self::get_all()
21
 * @property-read array $all
22
 *     An array with the matching records.
23
 * @see self::get_pairs()
24
 * @property-read array $pairs
25
 *     An array of key/value pairs, where _key_ is the value of the first column and _value_ the value of the second
26
 *     column.
27
 * @see self::get_one()
28
 * @property-read mixed $one
29
 *     The first row of the result set (the cursor is closed).
30
 * @see self::get_rc()
31
 * @property-read int|string|false|null $rc
32
 *     The value of the first column of the first row.
33
 */
34
final class Statement
35
{
36
    /**
37
     * @uses get_as_assoc
38
     * @uses get_one
39
     * @uses get_rc
40
     * @uses get_all
41
     * @uses get_pairs
42
     */
43
    use AccessorTrait;
44

45
    public function __construct(
46
        public readonly PDOStatement $pdo_statement,
47
        private readonly ConnectionTelemetry $telemetry,
48
    ) {
49
    }
44✔
50

51
    /**
52
     * Alias of {@see execute()}.
53
     *
54
     * The arguments can be provided as an array or a list of arguments:
55
     *
56
     *     $statement(1, 2, 3);
57
     *     $statement([ 1, 2, 3 ]);
58
     *
59
     * @return $this
60
     */
61
    public function __invoke(mixed ...$args): self
62
    {
63
        if ($args && is_array($args[0])) {
40✔
64
            $args = $args[0];
40✔
65
        }
66

67
        $this->execute($args);
40✔
68

69
        return $this;
40✔
70
    }
71

72
    /**
73
     * Return the {@see queryString} property of the statement.
74
     */
75
    public function __toString(): string
76
    {
77
        return $this->pdo_statement->queryString;
38✔
78
    }
79

80
    /**
81
     * Executes the statement.
82
     *
83
     * The connection queries count is incremented.
84
     *
85
     * @param mixed[] $params
86
     *
87
     * @throws StatementNotValid when the execution of the statement fails.
88
     */
89
    public function execute(array $params = []): void
90
    {
91
        try {
92
            $this->telemetry->record_execute_duration(
44✔
93
                statement: $this->pdo_statement->queryString . ' ' . json_encode($params),
44✔
94
                closure: fn() => $this->pdo_statement->execute($params)
44✔
95
            );
44✔
96
        } catch (PDOException $e) {
3✔
97
            throw new StatementNotValid($this->pdo_statement->queryString, args: $params, original: $e);
3✔
98
        }
99
    }
100

101
    /**
102
     * Set the fetch mode for the statement.
103
     *
104
     * @return $this
105
     *
106
     * @throws UnableToSetFetchMode if the mode cannot be set.
107
     *
108
     * @see PDOStatement::setFetchMode()
109
     */
110
    public function mode(int $mode, ?string $class_name = null, mixed ...$params): self
111
    {
112
        // @phpstan-ignore-next-line
113
        $this->pdo_statement->setFetchMode(...func_get_args())
12✔
UNCOV
114
            ?: throw new UnableToSetFetchMode(func_get_args());
×
115

116
        return $this;
12✔
117
    }
118

119
    private function get_as_assoc(): self
120
    {
121
        return $this->mode(PDO::FETCH_ASSOC);
3✔
122
    }
123

124
    /**
125
     * Fetches the first row of the result set and closes the cursor.
126
     *
127
     * @see PDOStatement::fetch()
128
     */
129
    public function one(
130
        int $mode = PDO::FETCH_BOTH,
131
        int $cursor_orientation = PDO::FETCH_ORI_NEXT,
132
        int $cursor_offset = 0
133
    ): mixed {
134
        // @phpstan-ignore-next-line
135
        $rc = $this->pdo_statement->fetch(...func_get_args());
12✔
136

137
        $this->pdo_statement->closeCursor();
12✔
138

139
        return $rc;
12✔
140
    }
141

142
    /**
143
     * @see $one
144
     */
145
    private function get_one(): mixed
146
    {
147
        return $this->one();
12✔
148
    }
149

150
    /**
151
     * Fetches the first column of the first row of the result set and closes the cursor.
152
     *
153
     * @see $rc
154
     */
155
    private function get_rc(): int|string|false|null
156
    {
157
        $rc = $this->pdo_statement->fetchColumn();
2✔
158

159
        $this->pdo_statement->closeCursor();
2✔
160

161
        return $rc;
2✔
162
    }
163

164
    /**
165
     * Returns an array containing all the result-set rows.
166
     *
167
     * @return mixed[]
168
     *
169
     * @see PDOStatement::fetchAll()
170
     */
171
    public function all(int $mode = PDO::FETCH_DEFAULT, mixed ...$args): array
172
    {
173
        // @phpstan-ignore-next-line
174
        return $this->pdo_statement->fetchAll(...func_get_args());
37✔
175
    }
176

177
    /**
178
     * @return mixed[]
179
     *
180
     * @see $all
181
     */
182
    private function get_all(): array
183
    {
184
        return $this->pdo_statement->fetchAll();
1✔
185
    }
186

187
    /**
188
     * @return array<string, string>
189
     *     Where _key_ is the value of the first column and _value_ the value of the second column.
190
     *
191
     * @see $pairs
192
     */
193
    private function get_pairs(): array
194
    {
UNCOV
195
        return $this->pdo_statement->fetchAll(PDO::FETCH_KEY_PAIR);
×
196
    }
197
}
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