Failed Conditions
Pull Request — 2.10.x (#3979)
by Ben
31:35 queued 27:39
created

OCI8Connection   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 211
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 26
eloc 59
dl 0
loc 211
ccs 0
cts 116
cp 0
rs 10
c 0
b 0
f 0

14 Methods

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