Completed
Pull Request — master (#3759)
by Benjamin
61:16
created

SQLSrvConnection::exec()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 4.5435

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 15
ccs 4
cts 9
cp 0.4444
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 4.5435
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Driver\SQLSrv;
6
7
use Doctrine\DBAL\Driver\ResultStatement;
8
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
9
use Doctrine\DBAL\Driver\Statement as DriverStatement;
10
use function sqlsrv_begin_transaction;
11
use function sqlsrv_commit;
12
use function sqlsrv_configure;
13
use function sqlsrv_connect;
14
use function sqlsrv_query;
15
use function sqlsrv_rollback;
16
use function sqlsrv_rows_affected;
17
use function sqlsrv_server_info;
18
use function str_replace;
19
20
/**
21
 * SQL Server implementation for the Connection interface.
22
 */
23
class SQLSrvConnection implements ServerInfoAwareConnection
24
{
25
    /** @var resource */
26
    protected $conn;
27
28
    /** @var LastInsertId */
29
    protected $lastInsertId;
30
31
    /**
32
     * @param array<string, mixed> $connectionOptions
33
     *
34
     * @throws SQLSrvException
35
     */
36
    public function __construct(string $serverName, array $connectionOptions)
37
    {
38
        if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
39
            throw SQLSrvException::fromSqlSrvErrors();
40
        }
41 242
42
        $conn = sqlsrv_connect($serverName, $connectionOptions);
43 242
44
        if ($conn === false) {
45
            throw SQLSrvException::fromSqlSrvErrors();
46
        }
47 242
48
        $this->conn         = $conn;
49 242
        $this->lastInsertId = new LastInsertId();
50 221
    }
51
52
    /**
53 242
     * {@inheritdoc}
54 242
     */
55 242
    public function getServerVersion() : string
56
    {
57
        $serverInfo = sqlsrv_server_info($this->conn);
58
59
        return $serverInfo['SQLServerVersion'];
60 242
    }
61
62 242
    /**
63
     * {@inheritdoc}
64 242
     */
65
    public function requiresQueryForServerVersion() : bool
66
    {
67
        return false;
68
    }
69
70 242
    /**
71
     * {@inheritDoc}
72 242
     */
73
    public function prepare(string $sql) : DriverStatement
74
    {
75
        return new SQLSrvStatement($this->conn, $sql, $this->lastInsertId);
76
    }
77
78 241
    /**
79
     * {@inheritDoc}
80 241
     */
81
    public function query(string $sql) : ResultStatement
82
    {
83
        $stmt = $this->prepare($sql);
84
        $stmt->execute();
85
86 240
        return $stmt;
87
    }
88 240
89 240
    /**
90 240
     * {@inheritDoc}
91 240
     */
92
    public function quote(string $input) : string
93 240
    {
94
        return "'" . str_replace("'", "''", $input) . "'";
95
    }
96
97
    /**
98
     * {@inheritDoc}
99 224
     */
100
    public function exec(string $statement) : int
101 224
    {
102 215
        $stmt = sqlsrv_query($this->conn, $statement);
103
104
        if ($stmt === false) {
105 224
            throw SQLSrvException::fromSqlSrvErrors();
106
        }
107
108
        $rowsAffected = sqlsrv_rows_affected($stmt);
109 224
110
        if ($rowsAffected === false) {
111
            throw SQLSrvException::fromSqlSrvErrors();
112
        }
113
114
        return $rowsAffected;
115 242
    }
116
117 242
    /**
118
     * {@inheritDoc}
119 242
     */
120 242
    public function lastInsertId() : string
121
    {
122
        $stmt = $this->query('SELECT @@IDENTITY');
123 242
124
        $result = $stmt->fetchColumn();
125 242
126
        if ($result === null) {
127
            throw new SQLSrvException('No identity value was generated by the last statement.');
128
        }
129 242
130
        return (string) $result;
131
    }
132
133
    /**
134
     * {@inheritDoc}
135 8
     */
136
    public function getSequenceNumber(string $name) : string
137 8
    {
138 7
        $stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?');
139 7
        $stmt->execute([$name]);
140
141 8
        $result = $stmt->fetchColumn();
142
143
        if ($result === false) {
144 8
            throw new SQLSrvException('No sequence with name "' . $name . '" found.');
145
        }
146
147
        return (string) $result;
148
    }
149
150 234
    /**
151
     * {@inheritDoc}
152 234
     */
153
    public function beginTransaction() : void
154
    {
155 234
        if (! sqlsrv_begin_transaction($this->conn)) {
156
            throw SQLSrvException::fromSqlSrvErrors();
157
        }
158
    }
159
160 231
    /**
161
     * {@inheritDoc}
162 231
     */
163
    public function commit() : void
164
    {
165 231
        if (! sqlsrv_commit($this->conn)) {
166
            throw SQLSrvException::fromSqlSrvErrors();
167
        }
168
    }
169
170 234
    /**
171
     * {@inheritDoc}
172 234
     */
173
    public function rollBack() : void
174
    {
175 234
        if (! sqlsrv_rollback($this->conn)) {
176
            throw SQLSrvException::fromSqlSrvErrors();
177
        }
178
    }
179
}
180