Total Complexity | 55 |
Total Lines | 514 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like TypeTrait 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 TypeTrait, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | trait TypeTrait |
||
13 | { |
||
14 | /** |
||
15 | * Formats a type correctly for display. Postgres 7.0 had no 'format_type' |
||
16 | * built-in function, and hence we need to do it manually. |
||
17 | * |
||
18 | * @param string $typname The name of the type |
||
19 | * @param string $typmod The contents of the typmod field |
||
20 | * |
||
21 | * @return bool|string |
||
22 | */ |
||
23 | public function formatType($typname, $typmod) |
||
24 | { |
||
25 | // This is a specific constant in the 7.0 source |
||
26 | $varhdrsz = 4; |
||
27 | |||
28 | // If the first character is an underscore, it's an array type |
||
29 | $is_array = false; |
||
30 | if (substr($typname, 0, 1) == '_') { |
||
31 | $is_array = true; |
||
32 | $typname = substr($typname, 1); |
||
33 | } |
||
34 | |||
35 | // Show lengths on bpchar and varchar |
||
36 | if ($typname == 'bpchar') { |
||
37 | $len = $typmod - $varhdrsz; |
||
38 | $temp = 'character'; |
||
39 | if ($len > 1) { |
||
40 | $temp .= "({$len})"; |
||
41 | } |
||
42 | } elseif ($typname == 'varchar') { |
||
43 | $temp = 'character varying'; |
||
44 | if ($typmod != -1) { |
||
45 | $temp .= '('.($typmod - $varhdrsz).')'; |
||
46 | } |
||
47 | } elseif ($typname == 'numeric') { |
||
48 | $temp = 'numeric'; |
||
49 | if ($typmod != -1) { |
||
50 | $tmp_typmod = $typmod - $varhdrsz; |
||
51 | $precision = ($tmp_typmod >> 16) & 0xffff; |
||
52 | $scale = $tmp_typmod & 0xffff; |
||
53 | $temp .= "({$precision}, {$scale})"; |
||
54 | } |
||
55 | } else { |
||
56 | $temp = $typname; |
||
57 | } |
||
58 | |||
59 | // Add array qualifier if it's an array |
||
60 | if ($is_array) { |
||
61 | $temp .= '[]'; |
||
62 | } |
||
63 | |||
64 | return $temp; |
||
65 | } |
||
66 | |||
67 | /** |
||
68 | * Returns all details for a particular type. |
||
69 | * |
||
70 | * @param string $typname The name of the view to retrieve |
||
71 | * |
||
72 | * @return \PHPPgAdmin\ADORecordSet type info |
||
73 | */ |
||
74 | public function getType($typname) |
||
75 | { |
||
76 | $this->clean($typname); |
||
77 | |||
78 | $sql = "SELECT typtype, typbyval, typname, typinput AS typin, typoutput AS typout, typlen, typalign |
||
79 | FROM pg_type WHERE typname='{$typname}'"; |
||
80 | |||
81 | return $this->selectSet($sql); |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * Returns a list of all types in the database. |
||
86 | * |
||
87 | * @param bool $all If true, will find all available types, if false just those in search path |
||
88 | * @param bool $tabletypes If true, will include table types |
||
89 | * @param bool $domains If true, will include domains |
||
90 | * |
||
91 | * @return \PHPPgAdmin\ADORecordSet A recordset |
||
92 | */ |
||
93 | public function getTypes($all = false, $tabletypes = false, $domains = false) |
||
94 | { |
||
95 | if ($all) { |
||
96 | $where = '1 = 1'; |
||
97 | } else { |
||
98 | $c_schema = $this->_schema; |
||
99 | $this->clean($c_schema); |
||
100 | $where = "n.nspname = '{$c_schema}'"; |
||
101 | } |
||
102 | // Never show system table types |
||
103 | $where2 = "AND c.relnamespace NOT IN (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname LIKE 'pg@_%' ESCAPE '@')"; |
||
104 | |||
105 | // Create type filter |
||
106 | $tqry = "'c'"; |
||
107 | if ($tabletypes) { |
||
108 | $tqry .= ", 'r', 'v'"; |
||
109 | } |
||
110 | |||
111 | // Create domain filter |
||
112 | if (!$domains) { |
||
113 | $where .= " AND t.typtype != 'd'"; |
||
114 | } |
||
115 | |||
116 | $sql = "SELECT |
||
117 | t.typname AS basename, |
||
118 | pg_catalog.format_type(t.oid, NULL) AS typname, |
||
119 | pu.usename AS typowner, |
||
120 | t.typtype, |
||
121 | pg_catalog.obj_description(t.oid, 'pg_type') AS typcomment |
||
122 | FROM (pg_catalog.pg_type t |
||
123 | LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace) |
||
124 | LEFT JOIN pg_catalog.pg_user pu ON t.typowner = pu.usesysid |
||
125 | WHERE (t.typrelid = 0 OR (SELECT c.relkind IN ({$tqry}) FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid {$where2})) |
||
126 | AND t.typname !~ '^_' |
||
127 | AND {$where} |
||
128 | ORDER BY typname |
||
129 | "; |
||
130 | |||
131 | return $this->selectSet($sql); |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * Creates a new type. |
||
136 | * |
||
137 | * @param string $typname |
||
138 | * @param string $typin |
||
139 | * @param string $typout |
||
140 | * @param string $typlen |
||
141 | * @param string $typdef |
||
142 | * @param string $typelem |
||
143 | * @param string $typdelim |
||
144 | * @param string $typbyval |
||
145 | * @param string $typalign |
||
146 | * @param string $typstorage |
||
147 | * |
||
148 | * @return int 0 if operation was successful |
||
149 | * |
||
150 | * @internal param $ ... |
||
151 | */ |
||
152 | public function createType( |
||
153 | $typname, |
||
154 | $typin, |
||
155 | $typout, |
||
156 | $typlen, |
||
157 | $typdef, |
||
158 | $typelem, |
||
159 | $typdelim, |
||
160 | $typbyval, |
||
161 | $typalign, |
||
162 | $typstorage |
||
163 | ) { |
||
164 | $f_schema = $this->_schema; |
||
165 | $this->fieldClean($f_schema); |
||
166 | $this->fieldClean($typname); |
||
167 | $this->fieldClean($typin); |
||
168 | $this->fieldClean($typout); |
||
169 | |||
170 | $sql = " |
||
171 | CREATE TYPE \"{$f_schema}\".\"{$typname}\" ( |
||
172 | INPUT = \"{$typin}\", |
||
173 | OUTPUT = \"{$typout}\", |
||
174 | INTERNALLENGTH = {$typlen}"; |
||
175 | if ($typdef != '') { |
||
176 | $sql .= ", DEFAULT = {$typdef}"; |
||
177 | } |
||
178 | |||
179 | if ($typelem != '') { |
||
180 | $sql .= ", ELEMENT = {$typelem}"; |
||
181 | } |
||
182 | |||
183 | if ($typdelim != '') { |
||
184 | $sql .= ", DELIMITER = {$typdelim}"; |
||
185 | } |
||
186 | |||
187 | if ($typbyval) { |
||
188 | $sql .= ', PASSEDBYVALUE, '; |
||
189 | } |
||
190 | |||
191 | if ($typalign != '') { |
||
192 | $sql .= ", ALIGNMENT = {$typalign}"; |
||
193 | } |
||
194 | |||
195 | if ($typstorage != '') { |
||
196 | $sql .= ", STORAGE = {$typstorage}"; |
||
197 | } |
||
198 | |||
199 | $sql .= ')'; |
||
200 | |||
201 | return $this->execute($sql); |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * Drops a type. |
||
206 | * |
||
207 | * @param string $typname The name of the type to drop |
||
208 | * @param bool $cascade True to cascade drop, false to restrict |
||
209 | * |
||
210 | * @return int 0 if operation was successful |
||
211 | */ |
||
212 | public function dropType($typname, $cascade) |
||
213 | { |
||
214 | $f_schema = $this->_schema; |
||
215 | $this->fieldClean($f_schema); |
||
216 | $this->fieldClean($typname); |
||
217 | |||
218 | $sql = "DROP TYPE \"{$f_schema}\".\"{$typname}\""; |
||
219 | if ($cascade) { |
||
220 | $sql .= ' CASCADE'; |
||
221 | } |
||
222 | |||
223 | return $this->execute($sql); |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * Creates a new enum type in the database. |
||
228 | * |
||
229 | * @param string $name The name of the type |
||
230 | * @param array $values An array of values |
||
231 | * @param string $typcomment Type comment |
||
232 | * |
||
233 | * @return bool|int 0 success |
||
234 | */ |
||
235 | public function createEnumType($name, $values, $typcomment) |
||
236 | { |
||
237 | $f_schema = $this->_schema; |
||
238 | $this->fieldClean($f_schema); |
||
239 | $this->fieldClean($name); |
||
240 | |||
241 | if (empty($values)) { |
||
242 | return -2; |
||
243 | } |
||
244 | |||
245 | $status = $this->beginTransaction(); |
||
246 | if ($status != 0) { |
||
247 | return -1; |
||
248 | } |
||
249 | |||
250 | $values = array_unique($values); |
||
251 | |||
252 | $nbval = count($values); |
||
253 | |||
254 | for ($i = 0; $i < $nbval; ++$i) { |
||
255 | $this->clean($values[$i]); |
||
256 | } |
||
257 | |||
258 | $sql = "CREATE TYPE \"{$f_schema}\".\"{$name}\" AS ENUM ('"; |
||
259 | $sql .= implode("','", $values); |
||
260 | $sql .= "')"; |
||
261 | |||
262 | $status = $this->execute($sql); |
||
263 | if ($status) { |
||
264 | $this->rollbackTransaction(); |
||
265 | |||
266 | return -1; |
||
267 | } |
||
268 | |||
269 | if ($typcomment != '') { |
||
270 | $status = $this->setComment('TYPE', $name, '', $typcomment, true); |
||
271 | if ($status) { |
||
272 | $this->rollbackTransaction(); |
||
273 | |||
274 | return -1; |
||
275 | } |
||
276 | } |
||
277 | |||
278 | return $this->endTransaction(); |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * Get defined values for a given enum. |
||
283 | * |
||
284 | * @param string $name |
||
285 | * |
||
286 | * @return \PHPPgAdmin\ADORecordSet A recordset |
||
287 | */ |
||
288 | public function getEnumValues($name) |
||
289 | { |
||
290 | $this->clean($name); |
||
291 | |||
292 | $sql = "SELECT enumlabel AS enumval |
||
293 | FROM pg_catalog.pg_type t JOIN pg_catalog.pg_enum e ON (t.oid=e.enumtypid) |
||
294 | WHERE t.typname = '{$name}' ORDER BY e.oid"; |
||
295 | |||
296 | return $this->selectSet($sql); |
||
297 | } |
||
298 | |||
299 | // Operator functions |
||
300 | |||
301 | /** |
||
302 | * Creates a new composite type in the database. |
||
303 | * |
||
304 | * @param string $name The name of the type |
||
305 | * @param int $fields The number of fields |
||
306 | * @param array $field An array of field names |
||
307 | * @param array $type An array of field types |
||
308 | * @param array $array An array of '' or '[]' for each type if it's an array or not |
||
309 | * @param array $length An array of field lengths |
||
310 | * @param array $colcomment An array of comments |
||
311 | * @param string $typcomment Type comment |
||
312 | * |
||
313 | * @return bool|int 0 success |
||
314 | */ |
||
315 | public function createCompositeType($name, $fields, $field, $type, $array, $length, $colcomment, $typcomment) |
||
423 | } |
||
424 | |||
425 | /** |
||
426 | * Returns a list of all casts in the database. |
||
427 | * |
||
428 | * @return \PHPPgAdmin\ADORecordSet All casts |
||
429 | */ |
||
430 | public function getCasts() |
||
431 | { |
||
432 | $conf = $this->conf; |
||
433 | |||
434 | if ($conf['show_system']) { |
||
435 | $where = ''; |
||
436 | } else { |
||
437 | $where = ' |
||
438 | AND n1.nspname NOT LIKE $$pg\_%$$ |
||
439 | AND n2.nspname NOT LIKE $$pg\_%$$ |
||
440 | AND n3.nspname NOT LIKE $$pg\_%$$ |
||
441 | '; |
||
442 | } |
||
443 | |||
444 | $sql = " |
||
445 | SELECT |
||
446 | c.castsource::pg_catalog.regtype AS castsource, |
||
447 | c.casttarget::pg_catalog.regtype AS casttarget, |
||
448 | CASE WHEN c.castfunc=0 THEN NULL |
||
449 | ELSE c.castfunc::pg_catalog.regprocedure END AS castfunc, |
||
450 | c.castcontext, |
||
451 | obj_description(c.oid, 'pg_cast') as castcomment |
||
452 | FROM |
||
453 | (pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p ON c.castfunc=p.oid JOIN pg_catalog.pg_namespace n3 ON p.pronamespace=n3.oid), |
||
454 | pg_catalog.pg_type t1, |
||
455 | pg_catalog.pg_type t2, |
||
456 | pg_catalog.pg_namespace n1, |
||
457 | pg_catalog.pg_namespace n2 |
||
458 | WHERE |
||
459 | c.castsource=t1.oid |
||
460 | AND c.casttarget=t2.oid |
||
461 | AND t1.typnamespace=n1.oid |
||
462 | AND t2.typnamespace=n2.oid |
||
463 | {$where} |
||
464 | ORDER BY 1, 2 |
||
465 | "; |
||
466 | |||
467 | return $this->selectSet($sql); |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * Returns a list of all conversions in the database. |
||
472 | * |
||
473 | * @return \PHPPgAdmin\ADORecordSet All conversions |
||
474 | */ |
||
475 | public function getConversions() |
||
493 | } |
||
494 | |||
495 | abstract public function fieldClean(&$str); |
||
496 | |||
497 | abstract public function beginTransaction(); |
||
498 | |||
499 | abstract public function rollbackTransaction(); |
||
500 | |||
501 | abstract public function endTransaction(); |
||
502 | |||
503 | abstract public function execute($sql); |
||
504 | |||
505 | abstract public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null); |
||
506 | |||
507 | abstract public function selectSet($sql); |
||
508 | |||
509 | abstract public function clean(&$str); |
||
510 | |||
511 | abstract public function phpBool($parameter); |
||
512 | |||
513 | abstract public function hasCreateTableLikeWithConstraints(); |
||
514 | |||
515 | abstract public function hasCreateTableLikeWithIndexes(); |
||
516 | |||
517 | abstract public function hasTablespaces(); |
||
518 | |||
519 | abstract public function delete($table, $conditions, $schema = ''); |
||
520 | |||
521 | abstract public function fieldArrayClean(&$arr); |
||
522 | |||
523 | abstract public function hasCreateFieldWithConstraints(); |
||
524 | |||
525 | abstract public function getAttributeNames($table, $atts); |
||
526 | } |
||
527 |