Oracle   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 71
c 1
b 0
f 0
dl 0
loc 161
rs 9.6
wmc 35

13 Methods

Rating   Name   Duplication   Size   Complexity  
A lastInsertId() 0 3 1
A beginTransaction() 0 8 2
A rollBack() 0 5 1
A commit() 0 5 1
A getType() 0 10 4
A languageDialect() 0 3 1
A rowCount() 0 3 2
A disconnect() 0 6 2
B query() 0 26 7
A getExecMode() 0 3 2
B exec() 0 23 7
A connect() 0 4 2
A connectToServer() 0 13 3
1
<?php
2
3
namespace kalanis\kw_mapper\Storage\Database\Raw;
4
5
6
use kalanis\kw_mapper\MapperException;
7
use kalanis\kw_mapper\Storage\Database\ASQL;
8
use kalanis\kw_mapper\Storage\Database\Dialects;
9
use kalanis\kw_mapper\Storage\Database\TBindNames;
10
11
12
/**
13
 * Class Oracle
14
 * @package kalanis\kw_mapper\Storage\Database\Raw
15
 * Secondary connector to Oracle DB; use when the primary one under PDO has problems
16
 * @codeCoverageIgnore remote connection
17
 */
18
class Oracle extends ASQL
19
{
20
    use TBindNames;
21
22
    protected string $extension = 'oci8';
23
    /** @var resource|null */
24
    protected $connection = null;
25
    /** @var resource|null */
26
    protected $lastStatement = null;
27
28
    protected bool $autoCommit = true;
29
30
    public function disconnect(): void
31
    {
32
        if ($this->isConnected()) {
33
            \oci_close($this->connection);
0 ignored issues
show
Bug introduced by
It seems like $this->connection can also be of type object; however, parameter $connection of oci_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

33
            \oci_close(/** @scrutinizer ignore-type */ $this->connection);
Loading history...
34
        }
35
        $this->connection = null;
36
    }
37
38
    public function languageDialect(): string
39
    {
40
        return Dialects\Oracle::class;
41
    }
42
43
    public function query(string $query, array $params): array
44
    {
45
        if (empty($query)) {
46
            return [];
47
        }
48
49
        $this->connect();
50
51
        $statement = \oci_parse($this->connection, $query);
0 ignored issues
show
Bug introduced by
It seems like $this->connection can also be of type object; however, parameter $connection of oci_parse() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

51
        $statement = \oci_parse(/** @scrutinizer ignore-type */ $this->connection, $query);
Loading history...
52
        if (false === $statement) {
53
            $err = \oci_error();
54
            throw new MapperException('oci8 parse error: ' . (!empty($err['message']) ? strval($err['message']) : 'error also has error'));
55
        }
56
        foreach ($params as $paramName => $paramValue) {
57
            \oci_bind_by_name($statement, $paramName, $params[$paramName], -1, $this->getType($paramValue));
58
        }
59
        if (!\oci_execute($statement, $this->getExecMode())) {
60
            $err = \oci_error($statement);
61
            throw new MapperException('oci8 connection error: ' . (!empty($err['message']) ? strval($err['message']) : 'error also has error'));
62
        };
63
        $results = [];
64
        \oci_fetch_all($statement, $results, 0, -1, OCI_ASSOC);
65
66
        $this->lastStatement = $statement;
67
68
        return $results;
69
    }
70
71
    public function exec(string $query, array $params): bool
72
    {
73
        if (empty($query)) {
74
            return false;
75
        }
76
77
        $this->connect();
78
79
        $statement = \oci_parse($this->connection, $query);
0 ignored issues
show
Bug introduced by
It seems like $this->connection can also be of type object; however, parameter $connection of oci_parse() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

79
        $statement = \oci_parse(/** @scrutinizer ignore-type */ $this->connection, $query);
Loading history...
80
        if (false === $statement) {
81
            $err = \oci_error();
82
            throw new MapperException('oci8 parse error: ' . (!empty($err['message']) ? strval($err['message']) : 'error also has error'));
83
        }
84
        foreach ($params as $paramName => $paramValue) {
85
            \oci_bind_by_name($statement, $paramName, $params[$paramName], -1, $this->getType($paramValue));
86
        }
87
        $this->lastStatement = $statement;
88
89
        if (!\oci_execute($statement, $this->getExecMode())) {
90
            $err = \oci_error($statement);
91
            throw new MapperException('oci8 connection error: ' . (!empty($err['message']) ? strval($err['message']) : 'error also has error'));
92
        }
93
        return true;
94
    }
95
96
    /**
97
     * @param mixed $var
98
     * @return int
99
     */
100
    protected function getType($var): int
101
    {
102
        if (is_bool($var)) {
103
            return OCI_B_BOL;
104
        } elseif (is_int($var)) {
105
            return OCI_B_INT;
106
        } elseif (is_float($var)) {
107
            return OCI_B_NUM;
108
        } else {
109
            return SQLT_CHR;
110
        }
111
    }
112
113
    protected function getExecMode(): int
114
    {
115
        return $this->autoCommit ? OCI_COMMIT_ON_SUCCESS : OCI_NO_AUTO_COMMIT;
116
    }
117
118
    /**
119
     * @throws MapperException
120
     */
121
    public function connect(): void
122
    {
123
        if (!$this->isConnected()) {
124
            $this->connection = $this->connectToServer();
125
        }
126
    }
127
128
    /**
129
     * @throws MapperException
130
     * @return resource
131
     */
132
    protected function connectToServer()
133
    {
134
        $connection = \oci_connect(
135
            $this->config->getUser(),
136
            $this->config->getPassword(),
137
            $this->config->getLocation(),
138
        );
139
        if (false === $connection) {
140
            $err = \oci_error();
141
            throw new MapperException('oci8 connection error: ' . (!empty($err['message']) ? strval($err['message']) : 'error also has error'));
142
        }
143
144
        return $connection;
145
    }
146
147
    public function lastInsertId(): ?string
148
    {
149
        return null;
150
    }
151
152
    public function rowCount(): ?int
153
    {
154
        return $this->lastStatement ? intval(\oci_num_rows($this->lastStatement)) : null ;
155
    }
156
157
    public function beginTransaction(): bool
158
    {
159
        if (!$this->isConnected()) {
160
            $this->connection = $this->connectToServer();
161
        }
162
163
        $this->autoCommit = false;
164
        return true;
165
    }
166
167
    public function commit(): bool
168
    {
169
        $result = \oci_commit($this->connection);
170
        $this->autoCommit = true;
171
        return $result;
172
    }
173
174
    public function rollBack(): bool
175
    {
176
        $result = \oci_rollback($this->connection);
177
        $this->autoCommit = true;
178
        return $result;
179
    }
180
}
181