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

dg / dibi / 23992579605

05 Apr 2026 02:31AM UTC coverage: 77.838%. Remained the same
23992579605

push

github

dg
drivers: escape*() methods moved to Engine [WIP]

101 of 113 new or added lines in 8 files covered. (89.38%)

162 existing lines in 9 files now uncovered.

1721 of 2211 relevant lines covered (77.84%)

0.78 hits per line

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

70.83
/src/Dibi/Drivers/PDO/Connection.php
1
<?php declare(strict_types=1);
2

3
/**
4
 * This file is part of the Dibi, smart database abstraction layer (https://dibi.nette.org)
5
 * Copyright (c) 2005 David Grudl (https://davidgrudl.com)
6
 */
7

8
namespace Dibi\Drivers\PDO;
9

10
use Dibi;
11
use Dibi\Drivers;
12
use Dibi\Drivers\Engines;
13
use Dibi\Helpers;
14
use PDO;
15

16

17
/**
18
 * The driver for PDO.
19
 *
20
 * Driver options:
21
 *   - dsn => driver specific DSN
22
 *   - username (or user)
23
 *   - password (or pass)
24
 *   - options (array) => driver specific options {@see PDO::__construct}
25
 *   - resource (PDO) => existing connection
26
 */
27
class Connection implements Drivers\Connection
28
{
29
        private PDO $connection;
30
        private ?int $affectedRows;
31
        private string $driverName;
32

33

34
        /**
35
         * @param  array<string, mixed>  $config
36
         * @throws Dibi\NotSupportedException
37
         */
38
        public function __construct(array $config)
1✔
39
        {
40
                if (!extension_loaded('pdo')) {
1✔
UNCOV
41
                        throw new Dibi\NotSupportedException("PHP extension 'pdo' is not loaded.");
×
42
                }
43

44
                $foo = &$config['dsn'];
1✔
45
                $foo = &$config['options'];
1✔
46
                Helpers::alias($config, 'resource', 'pdo');
1✔
47

48
                if ($config['resource'] instanceof PDO) {
1✔
49
                        $this->connection = $config['resource'];
1✔
50
                        unset($config['resource'], $config['pdo']);
1✔
51

52
                        if ($this->connection->getAttribute(PDO::ATTR_ERRMODE) !== PDO::ERRMODE_SILENT) {
1✔
53
                                throw new Dibi\DriverException('PDO connection in exception or warning error mode is not supported.');
1✔
54
                        }
55
                } else {
56
                        try {
57
                                $this->connection = new PDO($config['dsn'], $config['username'], $config['password'], $config['options']);
1✔
58
                                $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
1✔
59
                        } catch (\PDOException $e) {
×
60
                                if ($e->getMessage() === 'could not find driver') {
×
UNCOV
61
                                        throw new Dibi\NotSupportedException('PHP extension for PDO is not loaded.');
×
62
                                }
63

UNCOV
64
                                throw new Dibi\DriverException($e->getMessage(), $e->getCode());
×
65
                        }
66
                }
67

68
                $this->driverName = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);
1✔
69
        }
1✔
70

71

72
        /**
73
         * Disconnects from a database.
74
         */
75
        public function disconnect(): void
76
        {
77
                unset($this->connection);
1✔
78
        }
1✔
79

80

81
        /**
82
         * Executes the SQL query.
83
         * @throws Dibi\DriverException
84
         */
85
        public function query(string $sql): ?Result
1✔
86
        {
87
                $res = $this->connection->query($sql);
1✔
88
                if ($res) {
1✔
89
                        $this->affectedRows = $res->rowCount();
1✔
90
                        return $res->columnCount() ? $this->createResultDriver($res) : null;
1✔
91
                }
92

93
                $this->affectedRows = null;
1✔
94

95
                [$sqlState, $code, $message] = $this->connection->errorInfo();
1✔
96
                $code ??= 0;
1✔
97
                $message = "SQLSTATE[$sqlState]: $message";
1✔
98
                throw match ($this->driverName) {
1✔
99
                        'mysql' => Drivers\MySQLi\Connection::createException($message, $code, $sql),
1✔
UNCOV
100
                        'oci' => Drivers\OCI8\Connection::createException($message, $code, $sql),
×
101
                        'pgsql' => Drivers\PgSQL\Connection::createException($message, $sqlState, $sql),
1✔
102
                        'sqlite' => Drivers\SQLite3\Connection::createException($message, $code, $sql),
1✔
103
                        default => new Dibi\DriverException($message, $code, $sql),
1✔
104
                };
105
        }
106

107

108
        /**
109
         * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
110
         */
111
        public function getAffectedRows(): ?int
112
        {
113
                return $this->affectedRows;
1✔
114
        }
115

116

117
        /**
118
         * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
119
         */
120
        public function getInsertId(?string $sequence): ?int
121
        {
UNCOV
122
                return Helpers::intVal($this->connection->lastInsertId($sequence));
×
123
        }
124

125

126
        /**
127
         * Begins a transaction (if supported).
128
         * @throws Dibi\DriverException
129
         */
130
        public function begin(?string $savepoint = null): void
1✔
131
        {
132
                if (!$this->connection->beginTransaction()) {
1✔
133
                        $err = $this->connection->errorInfo();
×
UNCOV
134
                        throw new Dibi\DriverException("SQLSTATE[$err[0]]: $err[2]", $err[1] ?? 0);
×
135
                }
136
        }
1✔
137

138

139
        /**
140
         * Commits statements in a transaction.
141
         * @throws Dibi\DriverException
142
         */
143
        public function commit(?string $savepoint = null): void
1✔
144
        {
145
                if (!$this->connection->commit()) {
1✔
146
                        $err = $this->connection->errorInfo();
×
UNCOV
147
                        throw new Dibi\DriverException("SQLSTATE[$err[0]]: $err[2]", $err[1] ?? 0);
×
148
                }
149
        }
1✔
150

151

152
        /**
153
         * Rollback changes in a transaction.
154
         * @throws Dibi\DriverException
155
         */
156
        public function rollback(?string $savepoint = null): void
1✔
157
        {
158
                if (!$this->connection->rollBack()) {
1✔
159
                        $err = $this->connection->errorInfo();
×
UNCOV
160
                        throw new Dibi\DriverException("SQLSTATE[$err[0]]: $err[2]", $err[1] ?? 0);
×
161
                }
162
        }
1✔
163

164

165
        /**
166
         * Returns the connection resource.
167
         */
168
        public function getResource(): ?PDO
169
        {
170
                return $this->connection ?? null;
1✔
171
        }
172

173

174
        /**
175
         * Returns the connection reflector.
176
         */
177
        public function getReflector(): Drivers\Engine
178
        {
179
                return match ($this->driverName) {
1✔
180
                        'mysql' => new Engines\MySQLEngine($this),
1✔
UNCOV
181
                        'oci' => new Engines\OracleEngine($this),
×
182
                        'pgsql' => new Engines\PostgreSQLEngine($this),
1✔
183
                        'sqlite' => new Engines\SQLiteEngine($this),
1✔
UNCOV
184
                        'mssql', 'dblib', 'sqlsrv' => new Engines\SQLServerEngine($this),
×
185
                        default => throw new Dibi\NotSupportedException,
1✔
186
                };
187
        }
188

189

190
        /**
191
         * Result set driver factory.
192
         */
193
        public function createResultDriver(\PDOStatement $result): Result
1✔
194
        {
195
                return new Result($result, $this->driverName);
1✔
196
        }
197

198

199
        /********************* SQL ****************d*g**/
200

201

202
        /**
203
         * Encodes data for use in a SQL statement.
204
         */
205
        public function escapeText(string $value): string
1✔
206
        {
207
                return match ($this->driverName) {
1✔
208
                        'odbc' => "'" . str_replace("'", "''", $value) . "'",
×
UNCOV
209
                        'sqlsrv' => "N'" . str_replace("'", "''", $value) . "'",
×
210
                        default => $this->connection->quote($value, PDO::PARAM_STR),
1✔
211
                };
212
        }
213

214

215
        public function escapeBinary(string $value): string
216
        {
217
                return match ($this->driverName) {
×
218
                        'odbc' => "'" . str_replace("'", "''", $value) . "'",
×
219
                        'sqlsrv' => '0x' . bin2hex($value),
×
UNCOV
220
                        default => $this->connection->quote($value, PDO::PARAM_LOB),
×
221
                };
222
        }
223
}
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