Issues (201)

src/Driver/SQLSrv/SQLSrvConnection.php (1 issue)

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
final class SQLSrvConnection implements ServerInfoAwareConnection
24
{
25
    /** @var resource */
26
    private $conn;
27
28
    /** @var LastInsertId */
29
    private $lastInsertId;
30
31
    /**
32
     * @param array<string, mixed> $connectionOptions
33
     *
34
     * @throws SQLSrvException
35
     */
36 25
    public function __construct(string $serverName, array $connectionOptions)
37
    {
38 25
        if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
39
            throw SQLSrvException::fromSqlSrvErrors();
40
        }
41
42 25
        $conn = sqlsrv_connect($serverName, $connectionOptions);
43
44 25
        if ($conn === false) {
45
            throw SQLSrvException::fromSqlSrvErrors();
46
        }
47
48 25
        $this->conn         = $conn;
49 25
        $this->lastInsertId = new LastInsertId();
50 25
    }
51
52
    public function getServerVersion() : string
53
    {
54
        $serverInfo = sqlsrv_server_info($this->conn);
55
56
        return $serverInfo['SQLServerVersion'];
57
    }
58
59 318
    public function prepare(string $sql) : DriverStatement
60
    {
61 318
        return new SQLSrvStatement($this->conn, $sql, $this->lastInsertId);
62
    }
63
64 215
    public function query(string $sql) : ResultStatement
65
    {
66 215
        $stmt = $this->prepare($sql);
67 215
        $stmt->execute();
68
69 215
        return $stmt;
70
    }
71
72 5
    public function quote(string $input) : string
73
    {
74 5
        return "'" . str_replace("'", "''", $input) . "'";
75
    }
76
77 153
    public function exec(string $statement) : int
78
    {
79 153
        $stmt = sqlsrv_query($this->conn, $statement);
80
81 153
        if ($stmt === false) {
82 60
            throw SQLSrvException::fromSqlSrvErrors();
83
        }
84
85 146
        $rowsAffected = sqlsrv_rows_affected($stmt);
86
87 146
        if ($rowsAffected === false) {
88
            throw SQLSrvException::fromSqlSrvErrors();
89
        }
90
91 146
        return $rowsAffected;
92
    }
93
94 3
    public function lastInsertId(?string $name = null) : string
95
    {
96 3
        if ($name !== null) {
97 1
            $stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?');
98 1
            $stmt->execute([$name]);
99
        } else {
100 2
            $stmt = $this->query('SELECT @@IDENTITY');
101
        }
102
103 3
        return $stmt->fetchColumn();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $stmt->fetchColumn() could return the type false which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
104
    }
105
106 16
    public function beginTransaction() : void
107
    {
108 16
        if (! sqlsrv_begin_transaction($this->conn)) {
109
            throw SQLSrvException::fromSqlSrvErrors();
110
        }
111 16
    }
112
113 6
    public function commit() : void
114
    {
115 6
        if (! sqlsrv_commit($this->conn)) {
116
            throw SQLSrvException::fromSqlSrvErrors();
117
        }
118 6
    }
119
120 11
    public function rollBack() : void
121
    {
122 11
        if (! sqlsrv_rollback($this->conn)) {
123
            throw SQLSrvException::fromSqlSrvErrors();
124
        }
125 11
    }
126
}
127