Failed Conditions
Pull Request — develop (#3523)
by
unknown
62:01
created

PDOSqlsrvStatement::execute()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 27
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 27
rs 9.2222
c 0
b 0
f 0
cc 6
nc 5
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Driver\PDOSqlsrv;
6
7
use Doctrine\DBAL\Driver\PDOConnection;
8
use Doctrine\DBAL\Driver\PDOStatement;
9
use Doctrine\DBAL\Driver\Statement;
10
use Doctrine\DBAL\ParameterType;
11
use IteratorAggregate;
12
use PDO;
13
use function stripos;
14
15
/**
16
 * PDO SQL Server Statement
17
 */
18
class PDOSqlsrvStatement implements IteratorAggregate, Statement
19
{
20
    /**
21
     * The PDO Connection.
22
     *
23
     * @var PDOConnection
24
     */
25
    private $conn;
26
27
    /**
28
     * The SQL statement to execute.
29
     *
30
     * @var string
31
     */
32
    private $sql;
33
34
    /**
35
     * The PDO statement.
36
     *
37
     * @var PDOStatement
38
     */
39
    private $stmt;
40
41
    /**
42
     * The last insert ID.
43
     *
44
     * @var LastInsertId|null
45
     */
46
    private $lastInsertId;
47
48
    /**
49
     * The affected number of rows
50
     *
51
     * @var int|null
52
     */
53
    private $rowCount;
54
55
    /**
56
     * Append to any INSERT query to retrieve the last insert id.
57
     */
58
    public const LAST_INSERT_ID_SQL = ';SELECT SCOPE_IDENTITY() AS LastInsertId;';
59
60
    public function __construct(PDOConnection $conn, string $sql, ?LastInsertId $lastInsertId = null)
61
    {
62
        $this->conn = $conn;
63
        $this->sql  = $sql;
64
65
        if (stripos($sql, 'INSERT INTO ') === 0) {
66
            $this->sql         .= self::LAST_INSERT_ID_SQL;
67
            $this->lastInsertId = $lastInsertId;
68
        }
69
70
        $this->stmt = $this->prepare();
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function bindValue($param, $value, $type = ParameterType::STRING) : void
77
    {
78
        $this->bindParam($param, $value, $type);
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    public function bindParam($param, &$variable, int $type = ParameterType::STRING, ?int $length = null) : void
85
    {
86
        $driverOptions = null;
87
88
        if ($type === ParameterType::LARGE_OBJECT || $type === ParameterType::BINARY) {
89
            $driverOptions = PDO::SQLSRV_ENCODING_BINARY;
90
        }
91
92
        $this->stmt->bindParam($param, $variable, $type, $length, $driverOptions);
93
    }
94
95
        /**
96
         * {@inheritdoc}
97
         */
98
    public function closeCursor() : void
99
    {
100
        $this->stmt->closeCursor();
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function columnCount() : int
107
    {
108
        return $this->stmt->columnCount();
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function execute(?array $params = null) : void
115
    {
116
        $this->stmt->execute($params);
117
        $this->rowCount = $this->rowCount();
118
119
        if (! $this->lastInsertId) {
120
            return;
121
        }
122
123
        $id = null;
124
        $this->stmt->nextRowset();
125
126
        if ($this->columnCount() > 0) {
127
            $id = $this->fetchColumn();
128
        }
129
130
        if (! $id) {
131
            while ($this->stmt->nextRowset()) {
132
                if ($this->columnCount() === 0) {
133
                    continue;
134
                }
135
136
                $id = $this->fetchColumn();
137
            }
138
        }
139
140
        $this->lastInsertId->setId($id);
141
    }
142
143
    /**
144
     * Prepares PDO statement resource
145
     *
146
     * @return PDOStatement
147
     */
148
    private function prepare()
149
    {
150
        /** @var PDOStatement $stmt */
151
        $stmt = $this->conn->prepare($this->sql);
152
153
        return $stmt;
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159
    public function setFetchMode($fetchMode, ...$args) : void
160
    {
161
        $this->stmt->setFetchMode($fetchMode, ...$args);
162
    }
163
164
    /**
165
     * {@inheritdoc}
166
     */
167
    public function getIterator()
168
    {
169
        yield from $this->stmt;
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function fetch(?int $fetchMode = null, ...$args)
176
    {
177
        return $this->stmt->fetch($fetchMode, ...$args);
178
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183
    public function fetchAll(?int $fetchMode = null, ...$args) : array
184
    {
185
        return $this->stmt->fetchAll($fetchMode, ...$args);
186
    }
187
188
    /**
189
     * {@inheritdoc}
190
     */
191
    public function fetchColumn($columnIndex = 0)
192
    {
193
        return $this->stmt->fetchColumn($columnIndex);
194
    }
195
196
    /**
197
     * {@inheritdoc}
198
     */
199
    public function rowCount() : int
200
    {
201
        return $this->rowCount ?: $this->stmt->rowCount();
202
    }
203
204
    public function nextRowset() : bool
205
    {
206
        return $this->stmt->nextRowset();
207
    }
208
}
209