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