Passed
Push — drop-deprecated ( db0b1f )
by Michael
27:00
created

OCI8Connection::errorCode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 8
ccs 0
cts 7
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 6
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
     * @param string $username
41
     * @param string $password
42
     * @param string $db
43
     * @param string $charset
44
     * @param int    $sessionMode
45
     * @param bool   $persistent
46
     *
47
     * @throws OCI8Exception
48
     */
49
    public function __construct(
50
        $username,
51
        $password,
52
        $db,
53
        $charset = '',
54
        $sessionMode = OCI_DEFAULT,
55
        $persistent = false
56
    ) {
57
        $dbh = $persistent
58
            ? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
59
            : @oci_connect($username, $password, $db, $charset, $sessionMode);
60
61
        if ($dbh === false) {
62
            throw OCI8Exception::fromErrorInfo(oci_error());
63
        }
64
65
        $this->dbh = $dbh;
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     *
71
     * @throws UnexpectedValueException If the version string returned by the database server
72
     *                                  does not contain a parsable version number.
73
     */
74
    public function getServerVersion()
75
    {
76
        $version = oci_server_version($this->dbh);
77
78
        if ($version === false) {
79
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
80
        }
81
82
        if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches)) {
83
            throw new UnexpectedValueException(
84
                sprintf(
85
                    'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' .
86
                    'Please report this database version string to the Doctrine team.',
87
                    $version
88
                )
89
            );
90
        }
91
92
        return $matches[1];
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function requiresQueryForServerVersion()
99
    {
100
        return false;
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function prepare(string $sql) : DriverStatement
107
    {
108
        return new OCI8Statement($this->dbh, $sql, $this);
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function query(string $sql) : ResultStatement
115
    {
116
        $stmt = $this->prepare($sql);
117
        $stmt->execute();
118
119
        return $stmt;
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125
    public function quote(string $input) : string
126
    {
127
        return "'" . addcslashes(str_replace("'", "''", $input), "\000\n\r\\\032") . "'";
128
    }
129
130
    /**
131
     * {@inheritdoc}
132
     */
133
    public function exec(string $statement) : int
134
    {
135
        $stmt = $this->prepare($statement);
136
        $stmt->execute();
137
138
        return $stmt->rowCount();
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144
    public function lastInsertId($name = null)
145
    {
146
        if ($name === null) {
147
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by Doctrine\DBAL\Driver\Connection::lastInsertId() of string.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
148
        }
149
150
        $sql    = 'SELECT ' . $name . '.CURRVAL FROM DUAL';
151
        $stmt   = $this->query($sql);
152
        $result = $stmt->fetchColumn();
153
154
        if ($result === false) {
155
            throw new OCI8Exception('lastInsertId failed: Query was executed but no result was returned.');
156
        }
157
158
        return (int) $result;
159
    }
160
161
    /**
162
     * Returns the current execution mode.
163
     *
164
     * @return int
165
     */
166
    public function getExecuteMode()
167
    {
168
        return $this->executeMode;
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174
    public function beginTransaction() : void
175
    {
176
        $this->executeMode = OCI_NO_AUTO_COMMIT;
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182
    public function commit() : void
183
    {
184
        if (! oci_commit($this->dbh)) {
185
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
186
        }
187
188
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
189
    }
190
191
    /**
192
     * {@inheritdoc}
193
     */
194
    public function rollBack() : void
195
    {
196
        if (! oci_rollback($this->dbh)) {
197
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
198
        }
199
200
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
201
    }
202
}
203