SQLSrvConnection.php 3.69 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\DBAL\Driver\SQLSrv;

5
use Doctrine\DBAL\Driver\Result as ResultInterface;
6
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
7
use Doctrine\DBAL\Driver\Statement as DriverStatement;
8
use Doctrine\DBAL\ParameterType;
9

10 11 12 13 14 15 16 17 18 19 20 21
use function is_float;
use function is_int;
use function sprintf;
use function sqlsrv_begin_transaction;
use function sqlsrv_commit;
use function sqlsrv_configure;
use function sqlsrv_connect;
use function sqlsrv_query;
use function sqlsrv_rollback;
use function sqlsrv_rows_affected;
use function sqlsrv_server_info;
use function str_replace;
Steve Müller's avatar
Steve Müller committed
22

23 24 25
/**
 * SQL Server implementation for the Connection interface.
 */
26
class SQLSrvConnection implements ServerInfoAwareConnection
27
{
28
    /** @var resource */
29 30
    protected $conn;

31
    /** @var LastInsertId */
32 33
    protected $lastInsertId;

Benjamin Morel's avatar
Benjamin Morel committed
34
    /**
35 36
     * @param string  $serverName
     * @param mixed[] $connectionOptions
Benjamin Morel's avatar
Benjamin Morel committed
37
     *
38
     * @throws SQLSrvException
Benjamin Morel's avatar
Benjamin Morel committed
39
     */
40 41
    public function __construct($serverName, $connectionOptions)
    {
42
        if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
43 44 45
            throw SQLSrvException::fromSqlSrvErrors();
        }

Sergei Morozov's avatar
Sergei Morozov committed
46 47 48
        $conn = sqlsrv_connect($serverName, $connectionOptions);

        if ($conn === false) {
49 50
            throw SQLSrvException::fromSqlSrvErrors();
        }
Sergei Morozov's avatar
Sergei Morozov committed
51 52

        $this->conn         = $conn;
53
        $this->lastInsertId = new LastInsertId();
54 55
    }

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
    /**
     * {@inheritdoc}
     */
    public function getServerVersion()
    {
        $serverInfo = sqlsrv_server_info($this->conn);

        return $serverInfo['SQLServerVersion'];
    }

    /**
     * {@inheritdoc}
     */
    public function requiresQueryForServerVersion()
    {
        return false;
    }

74
    public function prepare(string $sql): DriverStatement
75
    {
Benjamin Eberlei's avatar
Benjamin Eberlei committed
76
        return new SQLSrvStatement($this->conn, $sql, $this->lastInsertId);
77 78
    }

79
    public function query(string $sql): ResultInterface
80
    {
81
        return $this->prepare($sql)->execute();
82 83 84 85 86
    }

    /**
     * {@inheritDoc}
     */
87
    public function quote($value, $type = ParameterType::STRING)
88 89 90
    {
        if (is_int($value)) {
            return $value;
91 92 93
        }

        if (is_float($value)) {
94 95 96 97 98 99
            return sprintf('%F', $value);
        }

        return "'" . str_replace("'", "''", $value) . "'";
    }

100
    public function exec(string $statement): int
101
    {
102 103
        $stmt = sqlsrv_query($this->conn, $statement);

104
        if ($stmt === false) {
105 106
            throw SQLSrvException::fromSqlSrvErrors();
        }
Benjamin Morel's avatar
Benjamin Morel committed
107

Sergei Morozov's avatar
Sergei Morozov committed
108 109 110 111 112 113 114
        $rowsAffected = sqlsrv_rows_affected($stmt);

        if ($rowsAffected === false) {
            throw SQLSrvException::fromSqlSrvErrors();
        }

        return $rowsAffected;
115 116 117 118 119 120 121
    }

    /**
     * {@inheritDoc}
     */
    public function lastInsertId($name = null)
    {
122
        if ($name !== null) {
123 124
            $result = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?')
                ->execute([$name]);
125
        } else {
126
            $result = $this->query('SELECT @@IDENTITY');
127 128
        }

129
        return $result->fetchOne();
130 131 132 133 134 135 136
    }

    /**
     * {@inheritDoc}
     */
    public function beginTransaction()
    {
137
        if (! sqlsrv_begin_transaction($this->conn)) {
138 139
            throw SQLSrvException::fromSqlSrvErrors();
        }
140 141

        return true;
142 143 144 145 146 147 148
    }

    /**
     * {@inheritDoc}
     */
    public function commit()
    {
149
        if (! sqlsrv_commit($this->conn)) {
150 151
            throw SQLSrvException::fromSqlSrvErrors();
        }
152 153

        return true;
154 155 156 157 158 159 160
    }

    /**
     * {@inheritDoc}
     */
    public function rollBack()
    {
161
        if (! sqlsrv_rollback($this->conn)) {
162 163
            throw SQLSrvException::fromSqlSrvErrors();
        }
164 165

        return true;
166 167
    }
}