Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
27 | class Inspector extends Client |
||
28 | { |
||
29 | /** |
||
30 | * getClientType |
||
31 | * |
||
32 | * @see ClientInterface |
||
33 | */ |
||
34 | public function getClientType() |
||
35 | { |
||
36 | return 'inspector'; |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * getClientIdentifier |
||
41 | * |
||
42 | * @see ClientInterface |
||
43 | */ |
||
44 | public function getClientIdentifier() |
||
45 | { |
||
46 | return get_class($this); |
||
47 | } |
||
48 | |||
49 | /** |
||
50 | * getSchemas |
||
51 | * |
||
52 | * Return a list of available schemas in the current database. |
||
53 | * |
||
54 | * @access public |
||
55 | * @return \PommProject\Foundation\ConvertedResultIterator |
||
56 | */ |
||
57 | public function getSchemas() |
||
77 | |||
78 | /** |
||
79 | * getTableOid |
||
80 | * |
||
81 | * Return the table oid from PostgreSQL catalog. If no table is found, null |
||
82 | * is returned. |
||
83 | * |
||
84 | * @access public |
||
85 | * @param string $schema |
||
86 | * @param string $table |
||
87 | * @return int|null |
||
88 | */ |
||
89 | View Code Duplication | public function getTableOid($schema, $table) |
|
90 | { |
||
91 | $sql = <<<SQL |
||
92 | select |
||
93 | c.oid as oid |
||
94 | from |
||
95 | pg_catalog.pg_class c |
||
96 | left join pg_catalog.pg_namespace n on n.oid = c.relnamespace |
||
97 | where |
||
98 | :condition |
||
99 | SQL; |
||
100 | |||
101 | $where = Where::create('n.nspname = $*', [$schema]) |
||
102 | ->andWhere('c.relname = $*', [$table]) |
||
103 | ; |
||
104 | |||
105 | $iterator = $this->executeSql($sql, $where); |
||
106 | |||
107 | return $iterator->isEmpty() ? null : $iterator->current()['oid']; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * getTableFieldInformation |
||
112 | * |
||
113 | * Get table's field information. If no fields are found, null is |
||
114 | * returned. |
||
115 | * |
||
116 | * @access public |
||
117 | * @param int $oid |
||
118 | * @return \PommProject\Foundation\ConvertedResultIterator|null |
||
119 | */ |
||
120 | public function getTableFieldInformation($oid) |
||
121 | { |
||
122 | $sql = <<<SQL |
||
123 | select |
||
124 | att.attname as "name", |
||
125 | case |
||
126 | when name.nspname = 'pg_catalog' then typ.typname |
||
127 | else format('%s.%s', name.nspname, typ.typname) |
||
128 | end as "type", |
||
129 | def.adsrc as "default", |
||
130 | att.attnotnull as "is_notnull", |
||
131 | dsc.description as "comment", |
||
132 | att.attnum as "position", |
||
133 | att.attnum = any(ind.indkey) as "is_primary" |
||
134 | from |
||
135 | pg_catalog.pg_attribute att |
||
136 | join pg_catalog.pg_type typ on att.atttypid = typ.oid |
||
137 | join pg_catalog.pg_class cla on att.attrelid = cla.oid |
||
138 | left join pg_catalog.pg_description dsc on cla.oid = dsc.objoid and att.attnum = dsc.objsubid |
||
139 | left join pg_catalog.pg_attrdef def on att.attrelid = def.adrelid and att.attnum = def.adnum |
||
140 | left join pg_catalog.pg_index ind on cla.oid = ind.indrelid and ind.indisprimary |
||
141 | left join pg_catalog.pg_namespace name on typ.typnamespace = name.oid |
||
142 | where |
||
143 | :condition |
||
144 | order by |
||
145 | att.attnum |
||
146 | SQL; |
||
147 | $where = Where::create('att.attrelid = $*', [$oid]) |
||
148 | ->andWhere('att.attnum > 0') |
||
149 | ->andWhere('not att.attisdropped') |
||
150 | ; |
||
151 | |||
152 | return $this->executeSql($sql, $where); |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * getSchemaOid |
||
157 | * |
||
158 | * Return the given schema oid, null if the schema is not found. |
||
159 | * |
||
160 | * @access public |
||
161 | * @param string $schema |
||
162 | * @param Where $where optional where clause. |
||
163 | * @return int|null |
||
164 | */ |
||
165 | View Code Duplication | public function getSchemaOid($schema, Where $where = null) |
|
166 | { |
||
167 | $condition = |
||
168 | Where::create("s.nspname = $*", [$schema]) |
||
169 | ->andWhere($where) |
||
170 | ; |
||
171 | $sql = <<<SQL |
||
172 | select |
||
173 | s.oid as oid |
||
174 | from |
||
175 | pg_catalog.pg_namespace s |
||
176 | where |
||
177 | :condition |
||
178 | SQL; |
||
179 | |||
180 | $iterator = $this->executeSql($sql, $condition); |
||
181 | |||
182 | return $iterator->isEmpty() ? null : $iterator->current()['oid']; |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * getPrimaryKey |
||
187 | * |
||
188 | * Get relation's primary key if any. |
||
189 | * |
||
190 | * @access public |
||
191 | * @param int $table_oid |
||
192 | * @return array|null |
||
193 | */ |
||
194 | public function getPrimaryKey($table_oid) |
||
220 | |||
221 | /** |
||
222 | * getSchemaRelations |
||
223 | * |
||
224 | * Return information on relations in a given schema. An additional Where |
||
225 | * condition can be passed to filter against other criteria. |
||
226 | * |
||
227 | * @access public |
||
228 | * @param int $schema_oid |
||
229 | * @param Where $where |
||
230 | * @return \PommProject\Foundation\ConvertedResultIterator |
||
231 | */ |
||
232 | public function getSchemaRelations($schema_oid, Where $where = null) |
||
261 | |||
262 | /** |
||
263 | * getTableComment |
||
264 | * |
||
265 | * Return the comment on a table if set. Null otherwise. |
||
266 | * |
||
267 | * @access public |
||
268 | * @param int $table_oid |
||
269 | * @return string|null |
||
270 | */ |
||
271 | View Code Duplication | public function getTableComment($table_oid) |
|
272 | { |
||
273 | $sql = <<<SQL |
||
274 | select description from pg_catalog.pg_description where :condition |
||
275 | SQL; |
||
276 | |||
277 | $where = Where::create('objoid = $*', [$table_oid]); |
||
278 | $iterator = $this->executeSql($sql, $where); |
||
279 | |||
280 | return $iterator->isEmpty() ? null : $iterator->current()['description']; |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * getTypeInformation |
||
285 | * |
||
286 | * Return the Oid of the given type name. |
||
287 | * It Additionally returns the type category. |
||
288 | * |
||
289 | * @access public |
||
290 | * @param string $type_name |
||
291 | * @param string $type_schema |
||
292 | * @return array|null |
||
293 | */ |
||
294 | public function getTypeInformation($type_name, $type_schema = null) |
||
295 | { |
||
296 | $condition = Where::create("t.typname = $*", [$type_name]); |
||
297 | $sql = <<<SQL |
||
298 | select |
||
299 | t.oid as "oid", |
||
300 | t.typcategory as "category" |
||
301 | from |
||
302 | pg_catalog.pg_type t :join |
||
303 | where |
||
304 | :condition |
||
305 | SQL; |
||
306 | |||
307 | if ($type_schema !== null) { |
||
308 | $sql = strtr($sql, [':join' => 'join pg_namespace n on n.oid = t.typnamespace']); |
||
309 | $condition->andWhere('n.nspname = $*', [$type_schema]); |
||
310 | } else { |
||
311 | $sql = strtr($sql, [':join' => '']); |
||
312 | } |
||
313 | |||
314 | $iterator = $this->executeSql($sql, $condition); |
||
315 | |||
316 | return $iterator->isEmpty() ? null : $iterator->current(); |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * getTypeCategory |
||
321 | * |
||
322 | * Get type category. |
||
323 | * |
||
324 | * @access public |
||
325 | * @param int $oid |
||
326 | * @return array|null |
||
327 | */ |
||
328 | View Code Duplication | public function getTypeCategory($oid) |
|
329 | { |
||
330 | $sql = <<<SQL |
||
331 | select |
||
332 | case |
||
333 | when n is null then t.type_name |
||
334 | else n.nspname||'.'||t.type_name |
||
335 | end as "name", |
||
336 | t.typcategory as "category" |
||
337 | from |
||
338 | pg_catalog.pg_type t |
||
339 | left join pg_namespace n on n.oid = t.typnamespace |
||
340 | where |
||
341 | :condition |
||
342 | SQL; |
||
343 | $iterator = $this->executeSql($sql, Where::create('t.oid = $*', [$oid])); |
||
344 | |||
345 | return $iterator->isEmpty() ? null : $iterator->current(); |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * getTypeEnumValues |
||
350 | * |
||
351 | * Return all possible values from an enumerated type in its natural order. |
||
352 | * |
||
353 | * @access public |
||
354 | * @param int $oid |
||
355 | * @return array|null |
||
356 | */ |
||
357 | public function getTypeEnumValues($oid) |
||
358 | { |
||
359 | $sql = <<<SQL |
||
360 | with |
||
361 | enum_value as ( |
||
362 | select |
||
363 | e.enumlabel as "label" |
||
364 | from |
||
365 | pg_catalog.pg_enum e |
||
366 | where |
||
367 | :condition |
||
368 | ) |
||
369 | select array_agg(label) as labels from enum_value |
||
370 | SQL; |
||
371 | |||
372 | $result = $this |
||
373 | ->executeSql($sql, Where::create('e.enumtypid = $*', [$oid])) |
||
374 | ->current() |
||
375 | ; |
||
376 | |||
377 | return $result['labels']; |
||
378 | } |
||
379 | |||
380 | /** |
||
381 | * getCompositeInformation |
||
382 | * |
||
383 | * Return the structure of a composite row. |
||
384 | * |
||
385 | * @access public |
||
386 | * @param int $oid |
||
387 | * @return \PommProject\Foundation\ConvertedResultIterator |
||
388 | */ |
||
389 | public function getCompositeInformation($oid) |
||
390 | { |
||
391 | $sql = <<<SQL |
||
392 | select |
||
393 | a.attname as "name", |
||
394 | t.typname as "type" |
||
395 | from |
||
396 | pg_type orig |
||
397 | join pg_catalog.pg_class c on orig.typrelid = c.oid |
||
398 | join pg_catalog.pg_attribute a on a.attrelid = c.oid and a.attnum > 0 |
||
399 | join pg_catalog.pg_type t on t.oid = a.atttypid |
||
400 | where |
||
401 | :condition |
||
402 | SQL; |
||
403 | |||
404 | return $this->executeSql($sql, Where::create('orig.oid = $*', [$oid])); |
||
405 | } |
||
406 | |||
407 | /** |
||
408 | * getVersion |
||
409 | * |
||
410 | * Return server version. |
||
411 | * |
||
412 | * @access public |
||
413 | * @throws FoundationException if invalid string. |
||
414 | * @return string |
||
415 | */ |
||
416 | public function getVersion() |
||
425 | |||
426 | /** |
||
427 | * executeSql |
||
428 | * |
||
429 | * Launch query execution. |
||
430 | * |
||
431 | * @access protected |
||
432 | * @param string $sql |
||
433 | * @param Where $condition |
||
434 | * @return \PommProject\Foundation\ConvertedResultIterator |
||
435 | */ |
||
436 | protected function executeSql($sql, Where $condition = null) |
||
447 | } |
||
448 |