Failed Conditions
Pull Request — develop (#3368)
by Benjamin
13:33
created

OCI8Connection::getSequenceNumber()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.1481

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 11
ccs 6
cts 9
cp 0.6667
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2.1481
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 2
    public function lastInsertId() : string
138
    {
139 2
        throw new DriverException('The OCI8 driver does not support identity columns.');
140
    }
141
142
    /**
143
     * {@inheritdoc}
144
     */
145 4
    public function getSequenceNumber(string $name) : string
146
    {
147 4
        $sql    = 'SELECT ' . $name . '.CURRVAL FROM DUAL';
148 4
        $stmt   = $this->query($sql);
149 3
        $result = $stmt->fetchColumn();
150
151 3
        if ($result === false) {
152
            throw new DriverException('lastInsertId failed: Query was executed but no result was returned.');
153
        }
154
155 3
        return $result;
156
    }
157
158
    /**
159
     * Returns the current execution mode.
160
     *
161
     * @return int
162
     */
163 257
    public function getExecuteMode()
164
    {
165 257
        return $this->executeMode;
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171 15
    public function beginTransaction() : void
172
    {
173 15
        $this->executeMode = OCI_NO_AUTO_COMMIT;
174 15
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179 7
    public function commit() : void
180
    {
181 7
        if (! oci_commit($this->dbh)) {
182
            throw self::exceptionFromErrorInfo($this->errorInfo());
183
        }
184 7
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
185 7
    }
186
187
    /**
188
     * {@inheritdoc}
189
     */
190 9
    public function rollBack() : void
191
    {
192 9
        if (! oci_rollback($this->dbh)) {
193
            throw self::exceptionFromErrorInfo($this->errorInfo());
194
        }
195 9
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
196 9
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201
    public function errorCode()
202
    {
203
        $error = oci_error($this->dbh);
204
        if ($error !== false) {
205
            $error = $error['code'];
206
        }
207
208
        return $error;
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214
    public function errorInfo()
215
    {
216
        return oci_error($this->dbh);
217
    }
218
219
    /**
220
     * @param mixed[] $error The return value of an oci_error() call.
221
     */
222 146
    public static function exceptionFromErrorInfo(array $error) : DriverException
223
    {
224 146
        return new DriverException($error['message'], null, $error['code']);
225
    }
226
}
227