Completed
Push — master ( 5dd66e...5b5c2c )
by Marco
114:19 queued 111:15
created

Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php (2 issues)

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 242
    public function __construct($serverName, $connectionOptions)
42
    {
43 242
        if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
44
            throw SQLSrvException::fromSqlSrvErrors();
45
        }
46
47 242
        $conn = sqlsrv_connect($serverName, $connectionOptions);
48
49 242
        if ($conn === false) {
50 221
            throw SQLSrvException::fromSqlSrvErrors();
51
        }
52
53 242
        $this->conn         = $conn;
54 242
        $this->lastInsertId = new LastInsertId();
55 242
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 242
    public function getServerVersion()
61
    {
62 242
        $serverInfo = sqlsrv_server_info($this->conn);
63
64 242
        return $serverInfo['SQLServerVersion'];
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70 242
    public function requiresQueryForServerVersion()
71
    {
72 242
        return false;
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     */
78 241
    public function prepare($sql)
79
    {
80 241
        return new SQLSrvStatement($this->conn, $sql, $this->lastInsertId);
81
    }
82
83
    /**
84
     * {@inheritDoc}
85
     */
86 240
    public function query()
87
    {
88 240
        $args = func_get_args();
89 240
        $sql  = $args[0];
90 240
        $stmt = $this->prepare($sql);
91 240
        $stmt->execute();
92
93 240
        return $stmt;
94
    }
95
96
    /**
97
     * {@inheritDoc}
98
     */
99 224
    public function quote($value, $type = ParameterType::STRING)
100
    {
101 224
        if (is_int($value)) {
102 215
            return $value;
103 224
        } elseif (is_float($value)) {
104
            return sprintf('%F', $value);
105
        }
106
107 224
        return "'" . str_replace("'", "''", $value) . "'";
108
    }
109
110
    /**
111
     * {@inheritDoc}
112
     */
113 242
    public function exec($statement)
114
    {
115 242
        $stmt = sqlsrv_query($this->conn, $statement);
116
117 242
        if ($stmt === false) {
118 242
            throw SQLSrvException::fromSqlSrvErrors();
119
        }
120
121 242
        $rowsAffected = sqlsrv_rows_affected($stmt);
122
123 242
        if ($rowsAffected === false) {
124
            throw SQLSrvException::fromSqlSrvErrors();
125
        }
126
127 242
        return $rowsAffected;
128
    }
129
130
    /**
131
     * {@inheritDoc}
132
     */
133 8
    public function lastInsertId($name = null)
134
    {
135 8
        if ($name !== null) {
136 7
            $stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?');
137 7
            $stmt->execute([$name]);
138
        } else {
139 8
            $stmt = $this->query('SELECT @@IDENTITY');
140
        }
141
142 8
        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...
143
    }
144
145
    /**
146
     * {@inheritDoc}
147
     */
148 234
    public function beginTransaction()
149
    {
150 234
        if (! sqlsrv_begin_transaction($this->conn)) {
151
            throw SQLSrvException::fromSqlSrvErrors();
152
        }
153 234
    }
154
155
    /**
156
     * {@inheritDoc}
157
     */
158 232
    public function commit()
159
    {
160 232
        if (! sqlsrv_commit($this->conn)) {
161
            throw SQLSrvException::fromSqlSrvErrors();
162
        }
163 232
    }
164
165
    /**
166
     * {@inheritDoc}
167
     */
168 234
    public function rollBack()
169
    {
170 234
        if (! sqlsrv_rollback($this->conn)) {
171
            throw SQLSrvException::fromSqlSrvErrors();
172
        }
173 234
    }
174
175
    /**
176
     * {@inheritDoc}
177
     */
178
    public function errorCode()
179
    {
180
        $errors = sqlsrv_errors(SQLSRV_ERR_ERRORS);
181
        if ($errors) {
182
            return $errors[0]['code'];
183
        }
184
185
        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...
186
    }
187
188
    /**
189
     * {@inheritDoc}
190
     */
191
    public function errorInfo()
192
    {
193
        return (array) sqlsrv_errors(SQLSRV_ERR_ERRORS);
194
    }
195
}
196