Completed
Pull Request — master (#3807)
by Sergei
155:06 queued 90: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 2
CRAP Score 1.037

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 3
cp 0.6667
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 1.037
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 30
    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
    ) {
50 30
        $dbh = $persistent
51
            ? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
52 30
            : @oci_connect($username, $password, $db, $charset, $sessionMode);
53
54 30
        if ($dbh === false) {
55 3
            throw OCI8Exception::fromErrorInfo(oci_error());
56
        }
57
58 27
        $this->dbh = $dbh;
59 27
    }
60
61
    /**
62
     * {@inheritdoc}
63
     *
64
     * @throws UnexpectedValueException If the version string returned by the database server
65
     *                                  does not contain a parsable version number.
66
     */
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 2
    public function prepare(string $sql) : DriverStatement
92
    {
93 2
        return new OCI8Statement($this->dbh, $sql, $this);
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 348
    public function query(string $sql) : ResultStatement
100
    {
101 348
        $stmt = $this->prepare($sql);
102
        $stmt->execute();
103
104
        return $stmt;
105
    }
106
107 208
    /**
108
     * {@inheritdoc}
109 208
     */
110 208
    public function quote(string $input) : string
111
    {
112 205
        return "'" . addcslashes(str_replace("'", "''", $input), "\000\n\r\\\032") . "'";
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 2
    public function exec(string $statement) : int
119
    {
120 2
        $stmt = $this->prepare($statement);
121
        $stmt->execute();
122
123
        return $stmt->rowCount();
124
    }
125
126 177
    /**
127
     * {@inheritdoc}
128 177
     */
129 177
    public function lastInsertId(?string $name = null) : string
130
    {
131 171
        if ($name === null) {
132
            throw new OCI8Exception('The driver does not support identity columns.');
133
        }
134
135
        $sql    = 'SELECT ' . $name . '.CURRVAL FROM DUAL';
136
        $stmt   = $this->query($sql);
137 4
        $result = $stmt->fetchColumn();
138
139 4
        if ($result === false) {
140 1
            throw new OCI8Exception('lastInsertId failed: Query was executed but no result was returned.');
141
        }
142
143 3
        return $result;
144 3
    }
145 3
146
    /**
147 3
     * Returns the current execution mode.
148
     */
149
    public function getExecuteMode() : int
150
    {
151 3
        return $this->executeMode;
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157 343
    public function beginTransaction() : void
158
    {
159 343
        $this->executeMode = OCI_NO_AUTO_COMMIT;
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165 16
    public function commit() : void
166
    {
167 16
        if (! oci_commit($this->dbh)) {
168 16
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
169
        }
170
171
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
172
    }
173 7
174
    /**
175 7
     * {@inheritdoc}
176
     */
177
    public function rollBack() : void
178
    {
179 7
        if (! oci_rollback($this->dbh)) {
180 7
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
181
        }
182
183
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
184
    }
185
}
186