Failed Conditions
Pull Request — develop (#3581)
by Jonathan
12:44
created

OCI8Connection   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Test Coverage

Coverage 45.05%

Importance

Changes 0
Metric Value
wmc 20
eloc 43
dl 0
loc 163
ccs 41
cts 91
cp 0.4505
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A query() 0 6 1
A prepare() 0 3 1
A requiresQueryForServerVersion() 0 3 1
A exec() 0 6 1
A lastInsertId() 0 15 3
A getExecuteMode() 0 3 1
A getServerVersion() 0 19 3
A quote() 0 3 1
A beginTransaction() 0 3 1
A __construct() 0 17 3
A commit() 0 7 2
A rollBack() 0 7 2
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
     * @throws OCI8Exception
41
     */
42 29
    public function __construct(
43
        string $username,
44
        string $password,
45
        string $db,
46
        string $charset = '',
47
        int $sessionMode = OCI_DEFAULT,
48
        bool $persistent = false
49
    ) {
50 29
        $dbh = $persistent
51
            ? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
52 29
            : @oci_connect($username, $password, $db, $charset, $sessionMode);
53
54 29
        if ($dbh === false) {
55 3
            throw OCI8Exception::fromErrorInfo(oci_error());
56
        }
57
58 26
        $this->dbh = $dbh;
59 26
    }
60
61
    /**
62
     * {@inheritdoc}
63
     *
64
     * @throws UnexpectedValueException If the version string returned by the database server
65
     *                                  does not contain a parsable version number.
66
     */
67
    public function getServerVersion() : string
68
    {
69
        $version = oci_server_version($this->dbh);
70
71
        if ($version === false) {
72
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
73
        }
74
75
        if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches)) {
76
            throw new UnexpectedValueException(
77
                sprintf(
78
                    'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' .
79
                    'Please report this database version string to the Doctrine team.',
80
                    $version
81
                )
82
            );
83
        }
84
85
        return $matches[1];
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 1
    public function requiresQueryForServerVersion() : bool
92
    {
93 1
        return false;
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 346
    public function prepare(string $sql) : DriverStatement
100
    {
101 346
        return new OCI8Statement($this->dbh, $sql, $this);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 205
    public function query(string $sql) : ResultStatement
108
    {
109 205
        $stmt = $this->prepare($sql);
110 205
        $stmt->execute();
111
112 202
        return $stmt;
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 2
    public function quote(string $input) : string
119
    {
120 2
        return "'" . addcslashes(str_replace("'", "''", $input), "\000\n\r\\\032") . "'";
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126 175
    public function exec(string $statement) : int
127
    {
128 175
        $stmt = $this->prepare($statement);
129 175
        $stmt->execute();
130
131 169
        return $stmt->rowCount();
132
    }
133
134
    /**
135
     * {@inheritdoc}
136
     */
137 4
    public function lastInsertId(?string $name = null) : string
138
    {
139 4
        if ($name === null) {
140 1
            throw new OCI8Exception('The driver does not support identity columns.');
141
        }
142
143 3
        $sql    = 'SELECT ' . $name . '.CURRVAL FROM DUAL';
144 3
        $stmt   = $this->query($sql);
145 3
        $result = $stmt->fetchColumn();
146
147 3
        if ($result === false) {
148
            throw new OCI8Exception('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 341
    public function getExecuteMode() : int
158
    {
159 341
        return $this->executeMode;
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165 15
    public function beginTransaction() : void
166
    {
167 15
        $this->executeMode = OCI_NO_AUTO_COMMIT;
168 15
    }
169
170
    /**
171
     * {@inheritdoc}
172
     */
173 7
    public function commit() : void
174
    {
175 7
        if (! oci_commit($this->dbh)) {
176
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
177
        }
178
179 7
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
180 7
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185 9
    public function rollBack() : void
186
    {
187 9
        if (! oci_rollback($this->dbh)) {
188
            throw OCI8Exception::fromErrorInfo(oci_error($this->dbh));
189
        }
190
191 9
        $this->executeMode = OCI_COMMIT_ON_SUCCESS;
192 9
    }
193
}
194