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

ICanBoogie / ActiveRecord / 11881061236

17 Nov 2024 06:05PM UTC coverage: 86.108% (-0.02%) from 86.125%
11881061236

push

github

olvlvl
Use PHPStan 2.0

5 of 10 new or added lines in 6 files covered. (50.0%)

16 existing lines in 2 files now uncovered.

1376 of 1598 relevant lines covered (86.11%)

24.51 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
 * @property-read $this $as_assoc
17
 *     Equivalent to `mode(PDO::FETCH_ASSOC)`.
18
 *     {@see self::get_as_assoc()}
19
 * @property-read array<scalar|null> $all
20
 *     An array with the matching records.
21
 *     {@see self::get_all()}
22
 * @property-read array<scalar|null> $pairs
23
 *     An array of key/value pairs, where _key_ is the value of the first column and _value_ the value of the second
24
 *     column.
25
 *     {@see self::get_pairs()}
26
 * @property-read mixed $one
27
 *     The first row of the result set (the cursor is closed).
28
 *     {@see self::get_one()}
29
 * @property-read int|string|false|null $rc
30
 *     The value of the first column of the first row.
31
 *     {@see self::get_rc()}
32
 */
33
final class Statement
34
{
35
    use AccessorTrait;
36

37
    public function __construct(
38
        public readonly PDOStatement $pdo_statement,
39
        private readonly ConnectionTelemetry $telemetry,
40
    ) {
41
    }
44✔
42

43
    /**
44
     * Alias of {@see execute()}.
45
     *
46
     * The arguments can be provided as an array or a list of arguments:
47
     *
48
     *     $statement(1, 2, 3);
49
     *     $statement([ 1, 2, 3 ]);
50
     *
51
     * @return $this
52
     */
53
    public function __invoke(mixed ...$args): self
54
    {
55
        if ($args && is_array($args[0])) {
40✔
56
            $args = $args[0];
40✔
57
        }
58

59
        $this->execute($args); // @phpstan-ignore argument.type
40✔
60

61
        return $this;
40✔
62
    }
63

64
    /**
65
     * Return the {@see queryString} property of the statement.
66
     */
67
    public function __toString(): string
68
    {
69
        return $this->pdo_statement->queryString;
38✔
70
    }
71

72
    /**
73
     * Executes the statement.
74
     *
75
     * The connection queries count is incremented.
76
     *
77
     * @param array<scalar|null> $params
78
     *
79
     * @throws StatementNotValid when the execution of the statement fails.
80
     */
81
    public function execute(array $params = []): void
82
    {
83
        try {
84
            $this->telemetry->record_execute_duration(
44✔
85
                statement: $this->pdo_statement->queryString . ' ' . json_encode($params),
44✔
86
                closure: fn() => $this->pdo_statement->execute($params)
44✔
87
            );
44✔
88
        } catch (PDOException $e) {
3✔
89
            throw new StatementNotValid($this->pdo_statement->queryString, args: $params, original: $e);
3✔
90
        }
91
    }
92

93
    /**
94
     * Set the fetch mode for the statement.
95
     *
96
     * @return $this
97
     *
98
     * @throws UnableToSetFetchMode if the mode can't be set.
99
     *
100
     * @see PDOStatement::setFetchMode()
101
     */
102
    public function mode(int $mode, ?string $class_name = null, mixed ...$params): self
103
    {
104
        // @phpstan-ignore-next-line
105
        $this->pdo_statement->setFetchMode(...func_get_args())
12✔
106
            ?: throw new UnableToSetFetchMode(func_get_args());
×
107

108
        return $this;
12✔
109
    }
110

111
    private function get_as_assoc(): self
112
    {
113
        return $this->mode(PDO::FETCH_ASSOC);
3✔
114
    }
115

116
    /**
117
     * Fetches the first row of the result set and closes the cursor.
118
     *
119
     * @see PDOStatement::fetch()
120
     */
121
    public function one(
122
        int $mode = PDO::FETCH_BOTH,
123
        int $cursor_orientation = PDO::FETCH_ORI_NEXT,
124
        int $cursor_offset = 0
125
    ): mixed {
126
        // @phpstan-ignore-next-line
127
        $rc = $this->pdo_statement->fetch(...func_get_args());
12✔
128

129
        $this->pdo_statement->closeCursor();
12✔
130

131
        return $rc;
12✔
132
    }
133

134
    /**
135
     * @see $one
136
     */
137
    private function get_one(): mixed
138
    {
139
        return $this->one();
12✔
140
    }
141

142
    /**
143
     * Fetches the first column of the first row of the result set and closes the cursor.
144
     *
145
     * @see $rc
146
     */
147
    private function get_rc(): int|string|false|null
148
    {
149
        $rc = $this->pdo_statement->fetchColumn();
2✔
150

151
        $this->pdo_statement->closeCursor();
2✔
152

153
        return $rc;
2✔
154
    }
155

156
    /**
157
     * Returns an array containing all the result-set rows.
158
     *
159
     * @return mixed[]
160
     *
161
     * @see PDOStatement::fetchAll()
162
     */
163
    public function all(int $mode = PDO::FETCH_DEFAULT, mixed ...$args): array
164
    {
165
        // @phpstan-ignore-next-line
166
        return $this->pdo_statement->fetchAll(...func_get_args());
37✔
167
    }
168

169
    /**
170
     * @return mixed[]
171
     *
172
     * @see $all
173
     */
174
    private function get_all(): array
175
    {
176
        return $this->pdo_statement->fetchAll();
1✔
177
    }
178

179
    /**
180
     * @return array<string, scalar>
181
     *     Where _key_ is the value of the first column and _value_ the value of the second column.
182
     *
183
     * @see $pairs
184
     */
185
    private function get_pairs(): array
186
    {
NEW
187
        return $this->pdo_statement->fetchAll(PDO::FETCH_KEY_PAIR); // @phpstan-ignore return.type
×
188
    }
189
}
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