Total Complexity | 54 |
Total Lines | 420 |
Duplicated Lines | 0 % |
Changes | 3 | ||
Bugs | 0 | Features | 0 |
Complex classes like Database often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Database, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
9 | class Database |
||
10 | { |
||
11 | private $app; |
||
12 | |||
13 | private static $connection; |
||
14 | |||
15 | private $table; |
||
16 | |||
17 | private $rows; |
||
18 | |||
19 | private $lastId; |
||
20 | |||
21 | private $data = []; |
||
22 | |||
23 | private $bindings = []; |
||
24 | |||
25 | private $selects = []; |
||
26 | |||
27 | private $joins = []; |
||
28 | |||
29 | private $wheres = []; |
||
30 | |||
31 | private $havings = []; |
||
32 | |||
33 | private $orderBy = []; |
||
34 | |||
35 | private $limit; |
||
36 | |||
37 | private $offset; |
||
38 | |||
39 | private $groupBy = []; |
||
40 | |||
41 | public function __construct(Application $app) |
||
48 | } |
||
49 | } |
||
50 | |||
51 | private function isConnected() |
||
52 | { |
||
53 | return self::$connection instanceof PDO; |
||
54 | } |
||
55 | |||
56 | private function connect() |
||
57 | { |
||
58 | $data = $this->app->config['db']; |
||
59 | |||
60 | extract($data); |
||
61 | |||
62 | try { |
||
63 | self::$connection = new PDO('mysql:host=' . $server . ';dbname=' . $dbname, $dbuser, $dbpass); |
||
64 | |||
65 | self::$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
||
66 | |||
67 | self::$connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); |
||
68 | |||
69 | self::$connection->exec('SET NAMES utf8'); |
||
70 | |||
71 | } catch (PDOException $e) { |
||
72 | |||
73 | throw new Exception($e->getMessage()); |
||
74 | } |
||
75 | } |
||
76 | |||
77 | public function connection() |
||
78 | { |
||
79 | return self::$connection; |
||
80 | } |
||
81 | |||
82 | public function table($table) |
||
87 | } |
||
88 | |||
89 | public function select(...$select) |
||
90 | { |
||
91 | $this->selects = array_merge($this->selects, $select); |
||
92 | |||
93 | return $this; |
||
94 | } |
||
95 | |||
96 | public function join($join, $localId = null, $forginId = null) |
||
97 | { |
||
98 | if (!$localId) { |
||
99 | |||
100 | $localId = trim($join, 's') . '_id'; |
||
101 | } |
||
102 | |||
103 | if (!$forginId) { |
||
104 | |||
105 | $forginId = 'id'; |
||
106 | } |
||
107 | |||
108 | $sql = $join . ' ON ' . $this->table . '.' . $localId . ' = ' . $join . '.' . $forginId; |
||
109 | |||
110 | $this->joins[] = $sql; |
||
111 | |||
112 | return $this; |
||
113 | } |
||
114 | |||
115 | public function where(...$bindings) |
||
116 | { |
||
117 | $sql = array_shift($bindings); |
||
118 | |||
119 | if (is_array($bindings[0])) { |
||
120 | |||
121 | $bindings = $bindings[0]; |
||
122 | } |
||
123 | |||
124 | $this->addToBindings($bindings); |
||
125 | |||
126 | $this->wheres[] = $sql; |
||
127 | |||
128 | return $this; |
||
129 | } |
||
130 | |||
131 | public function having() |
||
132 | { |
||
133 | $bindings = func_get_args(); |
||
134 | |||
135 | $sql = array_shift($bindings); |
||
136 | |||
137 | $this->addToBindings($bindings); |
||
138 | |||
139 | $this->havings[] = $sql; |
||
140 | |||
141 | return $this; |
||
142 | } |
||
143 | |||
144 | public function groupBy(...$arguments) |
||
145 | { |
||
146 | $this->groupBy = $arguments; |
||
147 | |||
148 | return $this; |
||
149 | } |
||
150 | |||
151 | public function limit($limit, $offset = 0) |
||
152 | { |
||
153 | $this->limit = $limit; |
||
154 | |||
155 | $this->offset = $offset; |
||
156 | |||
157 | return $this; |
||
158 | } |
||
159 | |||
160 | public function rows() |
||
163 | } |
||
164 | |||
165 | public function orderBy($orderBy, $sort = 'ASC') |
||
170 | } |
||
171 | |||
172 | public function fetch($table = null) |
||
173 | { |
||
174 | if ($table) { |
||
175 | |||
176 | $this->table($table); |
||
177 | } |
||
178 | |||
179 | $sql = $this->fetchStatment(); |
||
180 | |||
181 | $sql = $this->fetchStatmentExtra($sql); |
||
182 | |||
183 | $query = $this->query($sql, $this->bindings); |
||
184 | |||
185 | $result = $query->fetch(); |
||
186 | |||
187 | $this->rows = $query->rowCount(); |
||
188 | |||
189 | return $result; |
||
190 | } |
||
191 | |||
192 | public function fetchAll($table = null) |
||
193 | { |
||
194 | if ($table) { |
||
195 | |||
196 | $this->table($table); |
||
197 | } |
||
198 | |||
199 | $sql = $this->fetchStatment(); |
||
200 | |||
201 | $sql = $this->fetchStatmentExtra($sql); |
||
202 | |||
203 | $query = $this->query($sql, $this->bindings); |
||
204 | |||
205 | $results = $query->fetchall(); |
||
206 | |||
207 | $this->rows = $query->rowCount(); |
||
208 | |||
209 | return $results; |
||
210 | } |
||
211 | |||
212 | private function fetchStatment() |
||
213 | { |
||
214 | $sql = 'SELECT '; |
||
215 | |||
216 | $sql .= $this->selects ? implode(', ', $this->selects) : '*'; |
||
217 | |||
218 | $sql .= ' FROM ' . $this->table . ' '; |
||
219 | |||
220 | if (!empty($this->joins)) { |
||
221 | |||
222 | $sql .= 'LEFT JOIN ' . implode(' ', $this->joins); |
||
223 | } |
||
224 | |||
225 | if (!empty($this->wheres)) { |
||
226 | |||
227 | $sql .= ' WHERE ' . implode(' ', $this->wheres); |
||
228 | } |
||
229 | |||
230 | return $sql; |
||
231 | } |
||
232 | |||
233 | private function fetchStatmentExtra($sql) |
||
234 | { |
||
235 | if (!empty($this->havings)) { |
||
236 | |||
237 | $sql .= ' HAVING ' . implode(' ', $this->havings) . ' '; |
||
238 | } |
||
239 | |||
240 | if (!empty($this->orderBy)) { |
||
241 | |||
242 | $sql .= ' ORDER BY ' . implode(' ', $this->orderBy); |
||
243 | } |
||
244 | |||
245 | if ($this->limit) { |
||
246 | |||
247 | $sql .= ' LIMIT ' . $this->limit; |
||
248 | } |
||
249 | |||
250 | if ($this->offset) { |
||
251 | |||
252 | $sql .= ' OFFSET ' . $this->offset; |
||
253 | } |
||
254 | |||
255 | if (!empty($this->groupBy)) { |
||
256 | |||
257 | $sql .= ' GROUP BY ' . implode(' ', $this->groupBy); |
||
258 | } |
||
259 | |||
260 | return $sql; |
||
261 | } |
||
262 | |||
263 | public function lastId() |
||
264 | { |
||
265 | return $this->lastId; |
||
266 | } |
||
267 | |||
268 | public function from($table) |
||
269 | { |
||
270 | return $this->table($table); |
||
271 | } |
||
272 | |||
273 | public function data($key, $value = null) |
||
274 | { |
||
275 | if (is_array($key)) { |
||
276 | |||
277 | $this->data = array_merge($this->data, $key); |
||
278 | |||
279 | $this->addToBindings($key); |
||
280 | |||
281 | } else { |
||
282 | |||
283 | $this->data[$key] = $value; |
||
284 | |||
285 | $this->addToBindings($value); |
||
286 | } |
||
287 | |||
288 | return $this; |
||
289 | } |
||
290 | |||
291 | public function insert($table = null) |
||
292 | { |
||
293 | if ($table) { |
||
294 | |||
295 | $this->table($table); |
||
296 | } |
||
297 | |||
298 | $sql = 'INSERT INTO ' . $this->table . ' SET '; |
||
299 | |||
300 | $sql .= $this->setField(); |
||
301 | |||
302 | $this->query($sql, $this->bindings); |
||
303 | |||
304 | $this->lastId = $this->connection()->lastInsertId(); |
||
305 | |||
306 | return $this; |
||
307 | } |
||
308 | |||
309 | public function update($table = null) |
||
310 | { |
||
311 | if ($table) { |
||
312 | |||
313 | $this->table($table); |
||
314 | } |
||
315 | |||
316 | $sql = 'UPDATE ' . $this->table . ' SET '; |
||
317 | |||
318 | $sql .= $this->setField(); |
||
319 | |||
320 | if (!empty($this->wheres)) { |
||
321 | |||
322 | $sql .= ' WHERE ' . implode('', $this->wheres); |
||
323 | } |
||
324 | |||
325 | $this->query($sql, $this->bindings); |
||
326 | |||
327 | return $this; |
||
328 | } |
||
329 | |||
330 | public function delete($table = null) |
||
331 | { |
||
332 | if ($table) { |
||
333 | |||
334 | $this->table($table); |
||
335 | } |
||
336 | |||
337 | $sql = 'DELETE FROM ' . $this->table . ' '; |
||
338 | |||
339 | if (!empty($this->wheres)) { |
||
340 | |||
341 | $sql .= ' WHERE ' . implode('', $this->wheres); |
||
342 | } |
||
343 | |||
344 | $this->query($sql, $this->bindings); |
||
345 | |||
346 | return $this; |
||
347 | } |
||
348 | |||
349 | private function setField() |
||
350 | { |
||
351 | $sql = ''; |
||
352 | |||
353 | foreach ($this->data as $key => $value) { |
||
354 | |||
355 | $sql .= '`' . $key . '` = ? ,'; |
||
356 | } |
||
357 | |||
358 | $sql = rtrim($sql, ' ,'); |
||
359 | |||
360 | return $sql; |
||
361 | } |
||
362 | |||
363 | private function addToBindings($value) |
||
364 | { |
||
365 | if (is_array($value)) { |
||
366 | |||
367 | $this->bindings = array_merge($this->bindings, array_values($value)); |
||
368 | |||
369 | } else { |
||
370 | |||
371 | $this->bindings[] = $value; |
||
372 | } |
||
373 | } |
||
374 | |||
375 | public function query(...$bindings) |
||
401 | } |
||
402 | } |
||
403 | |||
404 | private function reset() |
||
405 | { |
||
429 | } |
||
430 | } |