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

OCI8Connection::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 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Driver\OCI8;
6
7
use Doctrine\DBAL\Driver\Connection;
8
use Doctrine\DBAL\Driver\ResultStatement;
9
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
10
use Doctrine\DBAL\Driver\Statement as DriverStatement;
11
use UnexpectedValueException;
12
use const OCI_COMMIT_ON_SUCCESS;
13
use const OCI_DEFAULT;
14
use const OCI_NO_AUTO_COMMIT;
15
use function addcslashes;
16
use function oci_commit;
17
use function oci_connect;
18
use function oci_error;
19
use function oci_pconnect;
20
use function oci_rollback;
21
use function oci_server_version;
22
use function preg_match;
23
use function sprintf;
24
use function str_replace;
25
26
/**
27
 * OCI8 implementation of the Connection interface.
28
 */
29
class OCI8Connection implements Connection, ServerInfoAwareConnection
30
{
31
    /** @var resource */
32
    protected $dbh;
33
34
    /** @var int */
35
    protected $executeMode = OCI_COMMIT_ON_SUCCESS;
36
37
    /**
38
     * Creates a Connection to an Oracle Database using oci8 extension.
39
     *
40
     * @throws OCI8Exception
41
     */
42
    public function __construct(
43
        string $username,
44
        string $password,
45
        string $db,
46
        string $charset = '',
47
        int $sessionMode = OCI_DEFAULT,
48
        bool $persistent = false
49 32
    ) {
50
        $dbh = $persistent
51
            ? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
52
            : @oci_connect($username, $password, $db, $charset, $sessionMode);
53
54
        if ($dbh === false) {
55
            throw OCI8Exception::fromErrorInfo(oci_error());
56
        }
57 32
58
        $this->dbh = $dbh;
59 32
    }
60
61 32
    /**
62 3
     * {@inheritdoc}
63
     *
64
     * @throws UnexpectedValueException If the version string returned by the database server
65 29
     *                                  does not contain a parsable version number.
66 29
     */
67
    public function getServerVersion() : string
68
    {
69
        $version = oci_server_version($this->dbh);
70
71
        if ($version === false) {
72
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
73
        }
74
75
        if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches)) {
76
            throw new UnexpectedValueException(
77
                sprintf(
78
                    'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' .
79
                    'Please report this database version string to the Doctrine team.',
80
                    $version
81
                )
82
            );
83
        }
84
85
        return $matches[1];
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    public function requiresQueryForServerVersion() : bool
92
    {
93
        return false;
94
    }
95
96
    /**
97
     * {@inheritdoc}
98 2
     */
99
    public function prepare(string $sql) : DriverStatement
100 2
    {
101
        return new OCI8Statement($this->dbh, $sql, $this);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106 301
     */
107
    public function query(string $sql) : ResultStatement
108 301
    {
109
        $stmt = $this->prepare($sql);
110
        $stmt->execute();
111
112
        return $stmt;
113
    }
114 212
115
    /**
116 212
     * {@inheritdoc}
117 212
     */
118
    public function quote(string $input) : string
119 212
    {
120 212
        return "'" . addcslashes(str_replace("'", "''", $input), "\000\n\r\\\032") . "'";
121
    }
122 209
123
    /**
124
     * {@inheritdoc}
125
     */
126
    public function exec(string $statement) : int
127
    {
128 4
        $stmt = $this->prepare($statement);
129
        $stmt->execute();
130 4
131 2
        return $stmt->rowCount();
132
    }
133 3
134
    /**
135 3
     * {@inheritdoc}
136
     */
137
    public function lastInsertId() : string
138
    {
139
        throw new OCI8Exception('The driver does not support identity columns.');
140
    }
141 180
142
    /**
143 180
     * {@inheritdoc}
144 180
     */
145
    public function getSequenceNumber(string $name) : string
146 174
    {
147
        $sql    = 'SELECT ' . $name . '.CURRVAL FROM DUAL';
148
        $stmt   = $this->query($sql);
149
        $result = $stmt->fetchColumn();
150
151
        if ($result === false) {
152 4
            throw new OCI8Exception('lastInsertId failed: Query was executed but no result was returned.');
153
        }
154 4
155 1
        return $result;
156
    }
157
158 3
    /**
159 3
     * Returns the current execution mode.
160 3
     */
161
    public function getExecuteMode() : int
162 3
    {
163
        return $this->executeMode;
164
    }
165
166 3
    /**
167
     * {@inheritdoc}
168
     */
169
    public function beginTransaction() : void
170
    {
171
        $this->executeMode = OCI_NO_AUTO_COMMIT;
172
    }
173
174 296
    /**
175
     * {@inheritdoc}
176 296
     */
177
    public function commit() : void
178
    {
179
        if (! oci_commit($this->dbh)) {
180
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
181
        }
182 16
183
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
184 16
    }
185
186 16
    /**
187
     * {@inheritdoc}
188
     */
189
    public function rollBack() : void
190
    {
191
        if (! oci_rollback($this->dbh)) {
192 7
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
193
        }
194 7
195
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
196
    }
197
}
198