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

codeigniter4 / CodeIgniter4 / 25637286072

10 May 2026 07:09PM UTC coverage: 88.366% (-0.05%) from 88.418%
25637286072

Pull #10182

github

web-flow
Merge 4a0b49c91 into df9f13771
Pull Request #10182: fix(database): classify prepared query exceptions

77 of 108 new or added lines in 9 files covered. (71.3%)

1 existing line in 1 file now uncovered.

23911 of 27059 relevant lines covered (88.37%)

218.09 hits per line

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

82.86
/system/Database/SQLSRV/PreparedQuery.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of CodeIgniter 4 framework.
7
 *
8
 * (c) CodeIgniter Foundation <admin@codeigniter.com>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace CodeIgniter\Database\SQLSRV;
15

16
use CodeIgniter\Database\BasePreparedQuery;
17
use CodeIgniter\Database\Exceptions\DatabaseException;
18
use CodeIgniter\Exceptions\BadMethodCallException;
19

20
/**
21
 * Prepared query for Postgre
22
 *
23
 * @extends BasePreparedQuery<resource, resource, resource>
24
 */
25
class PreparedQuery extends BasePreparedQuery
26
{
27
    /**
28
     * Parameters array used to store the dynamic variables.
29
     *
30
     * @var array
31
     */
32
    protected $parameters = [];
33

34
    /**
35
     * A reference to the db connection to use.
36
     *
37
     * @var Connection
38
     */
39
    protected $db;
40

41
    public function __construct(Connection $db)
42
    {
43
        parent::__construct($db);
15✔
44
    }
45

46
    /**
47
     * Prepares the query against the database, and saves the connection
48
     * info necessary to execute the query later.
49
     *
50
     * NOTE: This version is based on SQL code. Child classes should
51
     * override this method.
52
     *
53
     * @param array $options Options takes an associative array;
54
     *
55
     * @throws DatabaseException
56
     */
57
    public function _prepare(string $sql, array $options = []): PreparedQuery
58
    {
59
        // Prepare parameters for the query
60
        $queryString = $this->getQueryString();
15✔
61

62
        $parameters = $this->parameterize($queryString, $options);
15✔
63

64
        // Prepare the query
65
        $this->statement = sqlsrv_prepare($this->db->connID, $sql, $parameters);
15✔
66

67
        if (! $this->statement) {
15✔
NEW
68
            $info                    = $this->db->error();
×
NEW
69
            $this->databaseException = $this->db->createDatabaseException($this->db->getAllErrorMessages(), $info['code']);
×
70

71
            if ($this->db->DBDebug) {
×
NEW
72
                throw $this->databaseException;
×
73
            }
74

NEW
75
            $this->errorCode   = is_int($info['code']) ? $info['code'] : 0;
×
76
            $this->errorString = $info['message'];
×
77
        }
78

79
        return $this;
15✔
80
    }
81

82
    /**
83
     * Takes a new set of data and runs it against the currently
84
     * prepared query.
85
     */
86
    public function _execute(array $data): bool
87
    {
88
        if (! isset($this->statement)) {
12✔
89
            throw new BadMethodCallException('You must call prepare before trying to execute a prepared statement.');
1✔
90
        }
91

92
        foreach ($data as $key => $value) {
11✔
93
            $this->parameters[$key] = $value;
11✔
94
        }
95

96
        $result = sqlsrv_execute($this->statement);
11✔
97

98
        if ($result === false) {
11✔
99
            $error = $this->db->error();
5✔
100

101
            $this->errorCode         = is_int($error['code']) ? $error['code'] : 0;
5✔
102
            $this->errorString       = $this->db->getAllErrorMessages();
5✔
103
            $this->databaseException = $this->db->createDatabaseException($this->errorString, $error['code']);
5✔
104

105
            if ($this->db->DBDebug) {
5✔
106
                throw $this->databaseException;
2✔
107
            }
108
        }
109

110
        return $result;
10✔
111
    }
112

113
    /**
114
     * Returns the statement resource for the prepared query or false when preparing failed.
115
     *
116
     * @return resource|null
117
     */
118
    public function _getResult()
119
    {
120
        return $this->statement;
3✔
121
    }
122

123
    /**
124
     * Deallocate prepared statements.
125
     */
126
    protected function _close(): bool
127
    {
128
        return sqlsrv_free_stmt($this->statement);
15✔
129
    }
130

131
    /**
132
     * Handle parameters.
133
     *
134
     * @param array<int, mixed> $options
135
     */
136
    protected function parameterize(string $queryString, array $options): array
137
    {
138
        $numberOfVariables = substr_count($queryString, '?');
15✔
139

140
        $params = [];
15✔
141

142
        for ($c = 0; $c < $numberOfVariables; $c++) {
15✔
143
            $this->parameters[$c] = null;
15✔
144
            if (isset($options[$c])) {
15✔
145
                $params[] = [&$this->parameters[$c], SQLSRV_PARAM_IN, $options[$c]];
1✔
146
            } else {
147
                $params[] = &$this->parameters[$c];
14✔
148
            }
149
        }
150

151
        return $params;
15✔
152
    }
153
}
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