1 | <?php |
||||||
2 | /** |
||||||
3 | * DronePHP (http://www.dronephp.com) |
||||||
4 | * |
||||||
5 | * @link http://github.com/Pleets/DronePHP |
||||||
6 | * @copyright Copyright (c) 2016-2018 Pleets. (http://www.pleets.org) |
||||||
7 | * @license http://www.dronephp.com/license |
||||||
8 | * @author Darío Rivera <[email protected]> |
||||||
9 | */ |
||||||
10 | |||||||
11 | namespace Drone\Db\Driver; |
||||||
12 | |||||||
13 | /** |
||||||
14 | * Oracle class |
||||||
15 | * |
||||||
16 | * This is a database driver class to connect to Oracle |
||||||
17 | */ |
||||||
18 | class Oracle extends AbstractDriver implements DriverInterface |
||||||
19 | { |
||||||
20 | /** |
||||||
21 | * {@inheritdoc} |
||||||
22 | * |
||||||
23 | * @var resource |
||||||
24 | */ |
||||||
25 | protected $dbconn; |
||||||
26 | |||||||
27 | /** |
||||||
28 | * {@inheritdoc} |
||||||
29 | * |
||||||
30 | * @param array $options |
||||||
31 | */ |
||||||
32 | public function __construct($options) |
||||||
33 | { |
||||||
34 | $this->driverName = 'Oci8'; |
||||||
35 | |||||||
36 | if (!array_key_exists("dbchar", $options)) { |
||||||
37 | $options["dbchar"] = "AL32UTF8"; |
||||||
38 | } |
||||||
39 | |||||||
40 | parent::__construct($options); |
||||||
41 | |||||||
42 | $auto_connect = array_key_exists('auto_connect', $options) ? $options["auto_connect"] : true; |
||||||
43 | |||||||
44 | if ($auto_connect) { |
||||||
45 | $this->connect(); |
||||||
46 | } |
||||||
47 | } |
||||||
48 | |||||||
49 | /** |
||||||
50 | * Connects to database |
||||||
51 | * |
||||||
52 | * @throws RuntimeException |
||||||
53 | * @throws Exception\ConnectionException |
||||||
54 | * |
||||||
55 | * @return resource |
||||||
56 | */ |
||||||
57 | public function connect() |
||||||
58 | { |
||||||
59 | if (!extension_loaded('oci8')) { |
||||||
60 | throw new \RuntimeException("The Oci8 extension is not loaded"); |
||||||
61 | } |
||||||
62 | |||||||
63 | $connection_string = (is_null($this->dbhost) || empty($this->dbhost)) |
||||||
64 | ? $this->dbname |
||||||
65 | : |
||||||
66 | (!is_null($this->dbport) && !empty($this->dbport)) |
||||||
67 | ? $this->dbhost .":". $this->dbport ."/". $this->dbname |
||||||
68 | : $this->dbhost ."/". $this->dbname; |
||||||
69 | |||||||
70 | $conn = @oci_connect($this->dbuser, $this->dbpass, $connection_string, $this->dbchar); |
||||||
71 | |||||||
72 | if ($conn === false) { |
||||||
73 | $error = oci_error(); |
||||||
74 | throw new Exception\ConnectionException($error["message"], $error["code"]); |
||||||
75 | } |
||||||
76 | |||||||
77 | $this->dbconn = $conn; |
||||||
78 | |||||||
79 | return $this->dbconn; |
||||||
80 | } |
||||||
81 | |||||||
82 | /** |
||||||
83 | * Excecutes a statement |
||||||
84 | * |
||||||
85 | * @param string $sql |
||||||
86 | * @param array $params |
||||||
87 | * |
||||||
88 | * @throws Exception\InvalidQueryException |
||||||
89 | * |
||||||
90 | * @return resource |
||||||
91 | */ |
||||||
92 | public function execute($sql, array $params = []) |
||||||
93 | { |
||||||
94 | $this->numRows = 0; |
||||||
95 | $this->numFields = 0; |
||||||
96 | $this->rowsAffected = 0; |
||||||
97 | |||||||
98 | $this->arrayResult = null; |
||||||
99 | |||||||
100 | $this->result = $stid = @oci_parse($this->dbconn, $sql); |
||||||
101 | |||||||
102 | if (!$stid) { |
||||||
0 ignored issues
–
show
introduced
by
![]() |
|||||||
103 | $error = $stid ? oci_error($stid) : oci_error(); |
||||||
0 ignored issues
–
show
|
|||||||
104 | |||||||
105 | if (!empty($error)) { |
||||||
106 | $error = [ |
||||||
107 | "message" => "Could not prepare statement!", |
||||||
108 | ]; |
||||||
109 | |||||||
110 | $this->error($error["message"]); |
||||||
0 ignored issues
–
show
The method
error() does not exist on Drone\Db\Driver\Oracle . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
111 | } else { |
||||||
112 | $this->error($error["code"], $error["message"]); |
||||||
113 | } |
||||||
114 | |||||||
115 | if (array_key_exists("code", $error)) { |
||||||
0 ignored issues
–
show
It seems like
$error can also be of type false ; however, parameter $search of array_key_exists() does only seem to accept array , 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
![]() |
|||||||
116 | throw new Exception\InvalidQueryException($error["message"], $error["code"]); |
||||||
117 | } else { |
||||||
118 | throw new Exception\InvalidQueryException($error["message"]); |
||||||
119 | } |
||||||
120 | } |
||||||
121 | |||||||
122 | # Bound variables |
||||||
123 | if (count($params)) { |
||||||
124 | $param_keys = array_keys($params); |
||||||
125 | $param_values = array_values($params); |
||||||
126 | |||||||
127 | $param_count = count($params); |
||||||
128 | |||||||
129 | for ($i = 0; $i < $param_count; $i++) { |
||||||
130 | oci_bind_by_name($stid, $param_keys[$i], $param_values[$i], -1); |
||||||
131 | } |
||||||
132 | } |
||||||
133 | |||||||
134 | $prev_error_handler = set_error_handler(['\Drone\Error\ErrorHandler', 'errorControlOperator'], E_ALL); |
||||||
135 | |||||||
136 | // may be throw a Fatal error (Ex: Maximum execution time) |
||||||
137 | $r = ($this->transac_mode) ? oci_execute($stid, OCI_NO_AUTO_COMMIT) : oci_execute($stid, OCI_COMMIT_ON_SUCCESS); |
||||||
138 | |||||||
139 | set_error_handler($prev_error_handler); |
||||||
140 | |||||||
141 | if (!$r) { |
||||||
142 | $error = oci_error($stid); |
||||||
143 | $this->error($error["code"], $error["message"]); |
||||||
144 | |||||||
145 | throw new Exception\InvalidQueryException($error["message"], $error["code"]); |
||||||
146 | } |
||||||
147 | |||||||
148 | # This should be before of getArrayResult() because oci_fetch() is incremental. |
||||||
149 | $this->rowsAffected = oci_num_rows($stid); |
||||||
150 | |||||||
151 | $rows = $this->getArrayResult(); |
||||||
152 | |||||||
153 | $this->numRows = count($rows); |
||||||
154 | $this->numFields = oci_num_fields($stid); |
||||||
155 | |||||||
156 | if ($this->transac_mode) { |
||||||
157 | $this->transac_result = is_null($this->transac_result) ? $stid : $this->transac_result && $stid; |
||||||
158 | } |
||||||
159 | |||||||
160 | $this->result = $stid; |
||||||
161 | |||||||
162 | return $this->result; |
||||||
163 | } |
||||||
164 | |||||||
165 | /** |
||||||
166 | * {@inheritdoc} |
||||||
167 | */ |
||||||
168 | public function commit() |
||||||
169 | { |
||||||
170 | return oci_commit($this->dbconn); |
||||||
171 | } |
||||||
172 | |||||||
173 | /** |
||||||
174 | * {@inheritdoc} |
||||||
175 | */ |
||||||
176 | public function rollback() |
||||||
177 | { |
||||||
178 | return oci_rollback($this->dbconn); |
||||||
179 | } |
||||||
180 | |||||||
181 | /** |
||||||
182 | * {@inheritdoc} |
||||||
183 | */ |
||||||
184 | public function disconnect() |
||||||
185 | { |
||||||
186 | parent::disconnect(); |
||||||
187 | |||||||
188 | return oci_close($this->dbconn); |
||||||
189 | } |
||||||
190 | |||||||
191 | /** |
||||||
192 | * Returns an array with the rows fetched |
||||||
193 | * |
||||||
194 | * @throws LogicException |
||||||
195 | * |
||||||
196 | * @return array |
||||||
197 | */ |
||||||
198 | protected function toArray() |
||||||
199 | { |
||||||
200 | $data = []; |
||||||
201 | |||||||
202 | if ($this->result) { |
||||||
203 | while (($row = @oci_fetch_array($this->result, OCI_BOTH + OCI_RETURN_NULLS)) !== false) { |
||||||
204 | $data[] = $row; |
||||||
205 | } |
||||||
206 | } else { # This error is thrown because of 'execute' method has not been executed. |
||||||
207 | throw new \LogicException('There are not data in the buffer!'); |
||||||
208 | } |
||||||
209 | |||||||
210 | $this->arrayResult = $data; |
||||||
211 | |||||||
212 | return $data; |
||||||
213 | } |
||||||
214 | |||||||
215 | /** |
||||||
216 | * By default __destruct() disconnects to database |
||||||
217 | * |
||||||
218 | * @return null |
||||||
219 | */ |
||||||
220 | public function __destruct() |
||||||
221 | { |
||||||
222 | if ($this->dbconn) { |
||||||
223 | oci_close($this->dbconn); |
||||||
224 | } |
||||||
225 | } |
||||||
226 | } |
||||||
227 |