Failed Conditions
Pull Request — develop (#3367)
by Benjamin
12:53
created

OCI8Connection::query()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1.008

Importance

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