Completed
Push — master ( ae0103...9b98c5 )
by Joao
04:23 queued 56s
created

DbOci8Driver::getOci8Cursor()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 0
cts 20
cp 0
rs 8.439
c 0
b 0
f 0
cc 5
eloc 14
nc 5
nop 2
crap 30
1
<?php
2
3
namespace ByJG\AnyDataset\Store;
4
5
use ByJG\AnyDataset\DbDriverInterface;
6
use ByJG\AnyDataset\Exception\DatabaseException;
7
use ByJG\AnyDataset\Dataset\Oci8Iterator;
8
use ByJG\AnyDataset\Exception\NotImplementedException;
9
use ByJG\AnyDataset\Store\Helpers\SqlBind;
10
use ByJG\AnyDataset\Store\Helpers\SqlHelper;
11
use ByJG\Util\Uri;
12
13
class DbOci8Driver implements DbDriverInterface
14
{
15
16
    /**
17
     * Enter description here...
18
     *
19
     * @var Uri
20
     */
21
    protected $connectionUri;
22
23
    /** Used for OCI8 connections * */
24
    protected $conn;
25
    protected $transaction = OCI_COMMIT_ON_SUCCESS;
26
27
    /**
28
     * Ex.
29
     *
30
     *    oci8://username:password@host:1521/servicename?protocol=TCP&codepage=WE8MSWIN1252
31
     *
32
     * @param Uri $connectionString
33
     * @throws DatabaseException
34
     */
35
    public function __construct(Uri $connectionString)
36
    {
37
        $this->connectionUri = $connectionString;
38
39
        $codePage = $this->connectionUri->getQueryPart("codepage");
40
        $codePage = ($codePage == "") ? 'UTF8' : $codePage;
41
42
        $tns = DbOci8Driver::getTnsString($this->connectionUri);
43
44
        $this->conn = oci_connect(
45
            $this->connectionUri->getUsername(),
46
            $this->connectionUri->getPassword(),
47
            $tns,
48
            $codePage
49
        );
50
51
        if (!$this->conn) {
52
            $error = oci_error();
53
            throw new DatabaseException($error['message']);
54
        }
55
    }
56
57
    /**
58
     *
59
     * @param Uri $connUri
60
     * @return string
61
     */
62
    public static function getTnsString(Uri $connUri)
63
    {
64
        $protocol = $connUri->getQueryPart("protocol");
65
        $protocol = ($protocol == "") ? 'TCP' : $protocol;
66
67
        $port = $connUri->getPort();
68
        $port = ($port == "") ? 1521 : $port;
69
70
        $svcName = preg_replace('~^/~', '', $connUri->getPath());
71
72
        $host = $connUri->getHost();
73
74
        $tns = "(DESCRIPTION = " .
75
            "    (ADDRESS = (PROTOCOL = $protocol)(HOST = $host)(PORT = $port)) " .
76
            "        (CONNECT_DATA = (SERVICE_NAME = $svcName)) " .
77
            ")";
78
79
        return $tns;
80
    }
81
82
    public function __destruct()
83
    {
84
        $this->conn = null;
85
    }
86
87
    protected function getOci8Cursor($sql, $array = null)
88
    {
89
        list($query, $array) = SqlBind::parseSQL($this->connectionUri, $sql, $array);
90
91
        // Prepare the statement
92
        $stid = oci_parse($this->conn, $query);
93
        if (!$stid) {
94
            $error = oci_error($this->conn);
95
            throw new DatabaseException($error['message']);
96
        }
97
98
        // Bind the parameters
99
        if (is_array($array)) {
100
            foreach ($array as $key => $value) {
101
                oci_bind_by_name($stid, ":$key", $value);
102
            }
103
        }
104
105
        // Perform the logic of the query
106
        $result = oci_execute($stid, $this->transaction);
107
108
        // Check if is OK;
109
        if (!$result) {
110
            $error = oci_error($stid);
111
            throw new DatabaseException($error['message']);
112
        }
113
114
        return $stid;
115
    }
116
117
    /**
118
     * @param $sql
119
     * @param null $params
120
     * @return \ByJG\AnyDataset\Dataset\Oci8Iterator
121
     */
122
    public function getIterator($sql, $params = null)
123
    {
124
        $cur = $this->getOci8Cursor($sql, $params);
125
        $iterator = new Oci8Iterator($cur);
126
        return $iterator;
127
    }
128
129
    public function getScalar($sql, $array = null)
130
    {
131
        $cur = $this->getOci8Cursor($sql, $array);
132
133
        $row = oci_fetch_array($cur, OCI_RETURN_NULLS);
134
        if ($row) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $row of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
135
            $scalar = $row[0];
136
        } else {
137
            $scalar = null;
138
        }
139
140
        oci_free_cursor($cur);
141
142
        return $scalar;
143
    }
144
145
    public function getAllFields($tablename)
146
    {
147
        $cur = $this->getOci8Cursor(SqlHelper::createSafeSQL("select * from :table", array(':table' => $tablename)));
148
149
        $ncols = oci_num_fields($cur);
150
151
        $fields = array();
152
        for ($i = 1; $i <= $ncols; $i++) {
153
            $fields[] = strtolower(oci_field_name($cur, $i));
154
        }
155
156
        oci_free_statement($cur);
157
158
        return $fields;
159
    }
160
161
    public function beginTransaction()
162
    {
163
        $this->transaction = OCI_NO_AUTO_COMMIT;
164
    }
165
166
    public function commitTransaction()
167
    {
168
        if ($this->transaction == OCI_COMMIT_ON_SUCCESS) {
169
            throw new DatabaseException('No transaction for commit');
170
        }
171
172
        $this->transaction = OCI_COMMIT_ON_SUCCESS;
173
174
        $result = oci_commit($this->conn);
175
        if (!$result) {
176
            $error = oci_error($this->conn);
177
            throw new DatabaseException($error['message']);
178
        }
179
    }
180
181
    public function rollbackTransaction()
182
    {
183
        if ($this->transaction == OCI_COMMIT_ON_SUCCESS) {
184
            throw new DatabaseException('No transaction for rollback');
185
        }
186
187
        $this->transaction = OCI_COMMIT_ON_SUCCESS;
188
189
        oci_rollback($this->conn);
190
    }
191
192
    public function execute($sql, $array = null)
193
    {
194
        $cur = $this->getOci8Cursor($sql, $array);
195
        oci_free_cursor($cur);
196
        return true;
197
    }
198
199
    /**
200
     *
201
     * @return resource
202
     */
203
    public function getDbConnection()
204
    {
205
        return $this->conn;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->conn; of type resource|null adds the type resource to the return on line 205 which is incompatible with the return type declared by the interface ByJG\AnyDataset\DbDriverInterface::getDbConnection of type PDO.
Loading history...
206
    }
207
208
    public function getAttribute($name)
209
    {
210
        throw new NotImplementedException('Method not implemented for OCI Driver');
211
    }
212
213
    public function setAttribute($name, $value)
214
    {
215
        throw new NotImplementedException('Method not implemented for OCI Driver');
216
    }
217
218
    public function executeAndGetId($sql, $array = null)
219
    {
220
        throw new NotImplementedException('Method not implemented for OCI Driver');
221
    }
222
223
    public function getDbHelper()
224
    {
225
        throw new NotImplementedException('Method not implemented for OCI Driver');
226
    }
227
228
    /**
229
     * @return Uri
230
     */
231
    public function getUri()
232
    {
233
        return $this->connectionUri;
234
    }
235
236
    public function isSupportMultRowset()
237
    {
238
        throw new NotImplementedException('Method not implemented for OCI Driver');
239
    }
240
241
    public function setSupportMultRowset($multipleRowSet)
242
    {
243
        throw new NotImplementedException('Method not implemented for OCI Driver');
244
    }
245
}
246