Passed
Pull Request — 2.10 (#3778)
by Benjamin
08:25
created

SQLSrvConnection::requiresQueryForServerVersion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
188
    }
189
190
    /**
191
     * {@inheritDoc}
192
     */
193
    public function errorInfo()
194
    {
195
        return (array) sqlsrv_errors(SQLSRV_ERR_ERRORS);
196
    }
197
}
198