Total Complexity | 93 |
Total Lines | 633 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like MySQLSchemaManager 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 MySQLSchemaManager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class MySQLSchemaManager extends DBSchemaManager |
||
12 | { |
||
13 | |||
14 | /** |
||
15 | * Identifier for this schema, used for configuring schema-specific table |
||
16 | * creation options |
||
17 | * |
||
18 | * @skipUpgrade |
||
19 | */ |
||
20 | const ID = 'MySQLDatabase'; |
||
21 | |||
22 | public function createTable($table, $fields = null, $indexes = null, $options = null, $advancedOptions = null) |
||
23 | { |
||
24 | $fieldSchemas = $indexSchemas = ""; |
||
25 | |||
26 | if (!empty($options[self::ID])) { |
||
27 | $addOptions = $options[self::ID]; |
||
28 | } else { |
||
29 | $addOptions = "ENGINE=InnoDB"; |
||
30 | } |
||
31 | |||
32 | if (!isset($fields['ID'])) { |
||
33 | $fields['ID'] = "int(11) not null auto_increment"; |
||
34 | } |
||
35 | if ($fields) { |
||
36 | foreach ($fields as $k => $v) { |
||
37 | $fieldSchemas .= "\"$k\" $v,\n"; |
||
38 | } |
||
39 | } |
||
40 | if ($indexes) { |
||
41 | foreach ($indexes as $k => $v) { |
||
42 | // force MyISAM if we have a fulltext index |
||
43 | if ($v['type'] === 'fulltext') { |
||
44 | $addOptions = 'ENGINE=MyISAM'; |
||
45 | } |
||
46 | $indexSchemas .= $this->getIndexSqlDefinition($k, $v) . ",\n"; |
||
47 | } |
||
48 | } |
||
49 | |||
50 | // Switch to "CREATE TEMPORARY TABLE" for temporary tables |
||
51 | $temporary = empty($options['temporary']) |
||
52 | ? "" |
||
53 | : "TEMPORARY"; |
||
54 | |||
55 | $this->query("CREATE $temporary TABLE \"$table\" ( |
||
56 | $fieldSchemas |
||
57 | $indexSchemas |
||
58 | primary key (ID) |
||
59 | ) {$addOptions}"); |
||
60 | |||
61 | return $table; |
||
62 | } |
||
63 | |||
64 | public function alterTable( |
||
65 | $tableName, |
||
66 | $newFields = null, |
||
67 | $newIndexes = null, |
||
68 | $alteredFields = null, |
||
69 | $alteredIndexes = null, |
||
70 | $alteredOptions = null, |
||
71 | $advancedOptions = null |
||
72 | ) { |
||
73 | if ($this->isView($tableName)) { |
||
74 | $this->alterationMessage( |
||
75 | sprintf("Table %s not changed as it is a view", $tableName), |
||
76 | "changed" |
||
77 | ); |
||
78 | return; |
||
79 | } |
||
80 | $alterList = array(); |
||
81 | |||
82 | if ($newFields) { |
||
83 | foreach ($newFields as $k => $v) { |
||
84 | $alterList[] .= "ADD \"$k\" $v"; |
||
85 | } |
||
86 | } |
||
87 | if ($newIndexes) { |
||
88 | foreach ($newIndexes as $k => $v) { |
||
89 | $alterList[] .= "ADD " . $this->getIndexSqlDefinition($k, $v); |
||
90 | } |
||
91 | } |
||
92 | if ($alteredFields) { |
||
93 | foreach ($alteredFields as $k => $v) { |
||
94 | $alterList[] .= "CHANGE \"$k\" \"$k\" $v"; |
||
95 | } |
||
96 | } |
||
97 | if ($alteredIndexes) { |
||
98 | foreach ($alteredIndexes as $k => $v) { |
||
99 | $alterList[] .= "DROP INDEX \"$k\""; |
||
100 | $alterList[] .= "ADD " . $this->getIndexSqlDefinition($k, $v); |
||
101 | } |
||
102 | } |
||
103 | |||
104 | $dbID = self::ID; |
||
105 | if ($alteredOptions && isset($alteredOptions[$dbID])) { |
||
106 | $indexList = $this->indexList($tableName); |
||
107 | $skip = false; |
||
108 | foreach ($indexList as $index) { |
||
109 | if ($index['type'] === 'fulltext') { |
||
110 | $skip = true; |
||
111 | break; |
||
112 | } |
||
113 | } |
||
114 | if ($skip) { |
||
115 | $this->alterationMessage( |
||
116 | sprintf( |
||
117 | "Table %s options not changed to %s due to fulltextsearch index", |
||
118 | $tableName, |
||
119 | $alteredOptions[$dbID] |
||
120 | ), |
||
121 | "changed" |
||
122 | ); |
||
123 | } else { |
||
124 | $this->query(sprintf("ALTER TABLE \"%s\" %s", $tableName, $alteredOptions[$dbID])); |
||
125 | $this->alterationMessage( |
||
126 | sprintf("Table %s options changed: %s", $tableName, $alteredOptions[$dbID]), |
||
127 | "changed" |
||
128 | ); |
||
129 | } |
||
130 | } |
||
131 | |||
132 | $alterations = implode(",\n", $alterList); |
||
133 | $this->query("ALTER TABLE \"$tableName\" $alterations"); |
||
134 | } |
||
135 | |||
136 | public function isView($tableName) |
||
137 | { |
||
138 | $info = $this->query("SHOW /*!50002 FULL*/ TABLES LIKE '$tableName'")->record(); |
||
139 | return $info && strtoupper($info['Table_type']) == 'VIEW'; |
||
|
|||
140 | } |
||
141 | |||
142 | public function renameTable($oldTableName, $newTableName) |
||
143 | { |
||
144 | $this->query("ALTER TABLE \"$oldTableName\" RENAME \"$newTableName\""); |
||
145 | } |
||
146 | |||
147 | public function checkAndRepairTable($tableName) |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * Helper function used by checkAndRepairTable. |
||
175 | * @param string $sql Query to run. |
||
176 | * @return boolean Returns if the query returns a successful result. |
||
177 | */ |
||
178 | protected function runTableCheckCommand($sql) |
||
179 | { |
||
180 | $testResults = $this->query($sql); |
||
181 | foreach ($testResults as $testRecord) { |
||
182 | if (strtolower($testRecord['Msg_text']) != 'ok') { |
||
183 | return false; |
||
184 | } |
||
185 | } |
||
186 | return true; |
||
187 | } |
||
188 | |||
189 | public function hasTable($table) |
||
190 | { |
||
191 | // MySQLi doesn't like parameterised queries for some queries |
||
192 | // underscores need to be escaped in a SHOW TABLES LIKE query |
||
193 | $sqlTable = str_replace('_', '\\_', $this->database->quoteString($table)); |
||
194 | return (bool) ($this->query("SHOW TABLES LIKE $sqlTable")->value()); |
||
195 | } |
||
196 | |||
197 | public function createField($tableName, $fieldName, $fieldSpec) |
||
198 | { |
||
199 | $this->query("ALTER TABLE \"$tableName\" ADD \"$fieldName\" $fieldSpec"); |
||
200 | } |
||
201 | |||
202 | public function databaseList() |
||
203 | { |
||
204 | return $this->query("SHOW DATABASES")->column(); |
||
205 | } |
||
206 | |||
207 | public function databaseExists($name) |
||
208 | { |
||
209 | // MySQLi doesn't like parameterised queries for some queries |
||
210 | $sqlName = $this->database->quoteString($name); |
||
211 | return !!($this->query("SHOW DATABASES LIKE $sqlName")->value()); |
||
212 | } |
||
213 | |||
214 | public function createDatabase($name) |
||
215 | { |
||
216 | $charset = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'charset'); |
||
217 | $collation = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'collation'); |
||
218 | $this->query("CREATE DATABASE \"$name\" DEFAULT CHARACTER SET {$charset} DEFAULT COLLATE {$collation}"); |
||
219 | } |
||
220 | |||
221 | public function dropDatabase($name) |
||
222 | { |
||
223 | $this->query("DROP DATABASE \"$name\""); |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * Change the database type of the given field. |
||
228 | * @param string $tableName The name of the tbale the field is in. |
||
229 | * @param string $fieldName The name of the field to change. |
||
230 | * @param string $fieldSpec The new field specification |
||
231 | */ |
||
232 | public function alterField($tableName, $fieldName, $fieldSpec) |
||
233 | { |
||
234 | $this->query("ALTER TABLE \"$tableName\" CHANGE \"$fieldName\" \"$fieldName\" $fieldSpec"); |
||
235 | } |
||
236 | |||
237 | /** |
||
238 | * Change the database column name of the given field. |
||
239 | * |
||
240 | * @param string $tableName The name of the tbale the field is in. |
||
241 | * @param string $oldName The name of the field to change. |
||
242 | * @param string $newName The new name of the field |
||
243 | */ |
||
244 | public function renameField($tableName, $oldName, $newName) |
||
245 | { |
||
246 | $fieldList = $this->fieldList($tableName); |
||
247 | if (array_key_exists($oldName, $fieldList)) { |
||
248 | $this->query("ALTER TABLE \"$tableName\" CHANGE \"$oldName\" \"$newName\" " . $fieldList[$oldName]); |
||
249 | } |
||
250 | } |
||
251 | |||
252 | protected static $_cache_collation_info = array(); |
||
253 | |||
254 | public function fieldList($table) |
||
255 | { |
||
256 | $fields = $this->query("SHOW FULL FIELDS IN \"$table\""); |
||
257 | $fieldList = array(); |
||
258 | foreach ($fields as $field) { |
||
259 | $fieldSpec = $field['Type']; |
||
260 | if (!$field['Null'] || $field['Null'] == 'NO') { |
||
261 | $fieldSpec .= ' not null'; |
||
262 | } |
||
263 | |||
264 | if ($field['Collation'] && $field['Collation'] != 'NULL') { |
||
265 | // Cache collation info to cut down on database traffic |
||
266 | if (!isset(self::$_cache_collation_info[$field['Collation']])) { |
||
267 | self::$_cache_collation_info[$field['Collation']] |
||
268 | = $this->query("SHOW COLLATION LIKE '{$field['Collation']}'")->record(); |
||
269 | } |
||
270 | $collInfo = self::$_cache_collation_info[$field['Collation']]; |
||
271 | $fieldSpec .= " character set $collInfo[Charset] collate $field[Collation]"; |
||
272 | } |
||
273 | |||
274 | if ($field['Default'] || $field['Default'] === "0") { |
||
275 | $fieldSpec .= " default " . $this->database->quoteString($field['Default']); |
||
276 | } |
||
277 | if ($field['Extra']) { |
||
278 | $fieldSpec .= " " . $field['Extra']; |
||
279 | } |
||
280 | |||
281 | $fieldList[$field['Field']] = $fieldSpec; |
||
282 | } |
||
283 | return $fieldList; |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * Create an index on a table. |
||
288 | * |
||
289 | * @param string $tableName The name of the table. |
||
290 | * @param string $indexName The name of the index. |
||
291 | * @param string $indexSpec The specification of the index, see {@link SS_Database::requireIndex()} for more |
||
292 | * details. |
||
293 | */ |
||
294 | public function createIndex($tableName, $indexName, $indexSpec) |
||
295 | { |
||
296 | $this->query("ALTER TABLE \"$tableName\" ADD " . $this->getIndexSqlDefinition($indexName, $indexSpec)); |
||
297 | } |
||
298 | |||
299 | /** |
||
300 | * Generate SQL suitable for creating this index |
||
301 | * |
||
302 | * @param string $indexName |
||
303 | * @param string|array $indexSpec See {@link requireTable()} for details |
||
304 | * @return string MySQL compatible ALTER TABLE syntax |
||
305 | */ |
||
306 | protected function getIndexSqlDefinition($indexName, $indexSpec) |
||
307 | { |
||
308 | if ($indexSpec['type'] == 'using') { |
||
309 | return sprintf('index "%s" using (%s)', $indexName, $this->implodeColumnList($indexSpec['columns'])); |
||
310 | } else { |
||
311 | return sprintf('%s "%s" (%s)', $indexSpec['type'], $indexName, $this->implodeColumnList($indexSpec['columns'])); |
||
312 | } |
||
313 | } |
||
314 | |||
315 | public function alterIndex($tableName, $indexName, $indexSpec) |
||
316 | { |
||
317 | $this->query(sprintf('ALTER TABLE "%s" DROP INDEX "%s"', $tableName, $indexName)); |
||
318 | $this->query(sprintf( |
||
319 | 'ALTER TABLE "%s" ADD %s "%s" %s', |
||
320 | $tableName, |
||
321 | $indexSpec['type'], |
||
322 | $indexName, |
||
323 | $this->implodeColumnList($indexSpec['columns']) |
||
324 | )); |
||
325 | } |
||
326 | |||
327 | protected function indexKey($table, $index, $spec) |
||
328 | { |
||
329 | // MySQL simply uses the same index name as SilverStripe does internally |
||
330 | return $index; |
||
331 | } |
||
332 | |||
333 | public function indexList($table) |
||
334 | { |
||
335 | $indexes = $this->query("SHOW INDEXES IN \"$table\""); |
||
336 | $groupedIndexes = array(); |
||
337 | $indexList = array(); |
||
338 | |||
339 | foreach ($indexes as $index) { |
||
340 | $groupedIndexes[$index['Key_name']]['fields'][$index['Seq_in_index']] = $index['Column_name']; |
||
341 | |||
342 | if ($index['Index_type'] == 'FULLTEXT') { |
||
343 | $groupedIndexes[$index['Key_name']]['type'] = 'fulltext'; |
||
344 | } elseif (!$index['Non_unique']) { |
||
345 | $groupedIndexes[$index['Key_name']]['type'] = 'unique'; |
||
346 | } elseif ($index['Index_type'] == 'HASH') { |
||
347 | $groupedIndexes[$index['Key_name']]['type'] = 'hash'; |
||
348 | } elseif ($index['Index_type'] == 'RTREE') { |
||
349 | $groupedIndexes[$index['Key_name']]['type'] = 'rtree'; |
||
350 | } else { |
||
351 | $groupedIndexes[$index['Key_name']]['type'] = 'index'; |
||
352 | } |
||
353 | } |
||
354 | |||
355 | if ($groupedIndexes) { |
||
356 | foreach ($groupedIndexes as $index => $details) { |
||
357 | ksort($details['fields']); |
||
358 | $indexList[$index] = array( |
||
359 | 'name' => $index, |
||
360 | 'columns' => $details['fields'], |
||
361 | 'type' => $details['type'], |
||
362 | ); |
||
363 | } |
||
364 | } |
||
365 | |||
366 | return $indexList; |
||
367 | } |
||
368 | |||
369 | public function tableList() |
||
370 | { |
||
371 | $tables = array(); |
||
372 | foreach ($this->query("SHOW FULL TABLES WHERE Table_Type != 'VIEW'") as $record) { |
||
373 | $table = reset($record); |
||
374 | $tables[strtolower($table)] = $table; |
||
375 | } |
||
376 | return $tables; |
||
377 | } |
||
378 | |||
379 | public function enumValuesForField($tableName, $fieldName) |
||
380 | { |
||
381 | // Get the enum of all page types from the SiteTree table |
||
382 | $classnameinfo = $this->query("DESCRIBE \"$tableName\" \"$fieldName\"")->first(); |
||
383 | preg_match_all("/'[^,]+'/", $classnameinfo["Type"], $matches); |
||
384 | |||
385 | $classes = array(); |
||
386 | foreach ($matches[0] as $value) { |
||
387 | $classes[] = stripslashes(trim($value, "'")); |
||
388 | } |
||
389 | return $classes; |
||
390 | } |
||
391 | |||
392 | public function dbDataType($type) |
||
393 | { |
||
394 | $values = array( |
||
395 | 'unsigned integer' => 'UNSIGNED' |
||
396 | ); |
||
397 | |||
398 | if (isset($values[$type])) { |
||
399 | return $values[$type]; |
||
400 | } else { |
||
401 | return ''; |
||
402 | } |
||
403 | } |
||
404 | |||
405 | /** |
||
406 | * Return a boolean type-formatted string |
||
407 | * |
||
408 | * @param array $values Contains a tokenised list of info about this data type |
||
409 | * @return string |
||
410 | */ |
||
411 | public function boolean($values) |
||
412 | { |
||
413 | //For reference, this is what typically gets passed to this function: |
||
414 | //$parts=Array('datatype'=>'tinyint', 'precision'=>1, 'sign'=>'unsigned', 'null'=>'not null', |
||
415 | //'default'=>$this->default); |
||
416 | //DB::requireField($this->tableName, $this->name, "tinyint(1) unsigned not null default |
||
417 | //'{$this->defaultVal}'"); |
||
418 | return 'tinyint(1) unsigned not null' . $this->defaultClause($values); |
||
419 | } |
||
420 | |||
421 | /** |
||
422 | * Return a date type-formatted string |
||
423 | * For MySQL, we simply return the word 'date', no other parameters are necessary |
||
424 | * |
||
425 | * @param array $values Contains a tokenised list of info about this data type |
||
426 | * @return string |
||
427 | */ |
||
428 | public function date($values) |
||
429 | { |
||
430 | //For reference, this is what typically gets passed to this function: |
||
431 | //$parts=Array('datatype'=>'date'); |
||
432 | //DB::requireField($this->tableName, $this->name, "date"); |
||
433 | return 'date'; |
||
434 | } |
||
435 | |||
436 | /** |
||
437 | * Return a decimal type-formatted string |
||
438 | * |
||
439 | * @param array $values Contains a tokenised list of info about this data type |
||
440 | * @return string |
||
441 | */ |
||
442 | public function decimal($values) |
||
443 | { |
||
444 | //For reference, this is what typically gets passed to this function: |
||
445 | //$parts=Array('datatype'=>'decimal', 'precision'=>"$this->wholeSize,$this->decimalSize"); |
||
446 | //DB::requireField($this->tableName, $this->name, "decimal($this->wholeSize,$this->decimalSize)"); |
||
447 | // Avoid empty strings being put in the db |
||
448 | if ($values['precision'] == '') { |
||
449 | $precision = 1; |
||
450 | } else { |
||
451 | $precision = $values['precision']; |
||
452 | } |
||
453 | |||
454 | // Fix format of default value to match precision |
||
455 | if (isset($values['default']) && is_numeric($values['default'])) { |
||
456 | $decs = strpos($precision, ',') !== false |
||
457 | ? (int) substr($precision, strpos($precision, ',') + 1) |
||
458 | : 0; |
||
459 | $values['default'] = number_format($values['default'], $decs, '.', ''); |
||
460 | } else { |
||
461 | unset($values['default']); |
||
462 | } |
||
463 | |||
464 | return "decimal($precision) not null" . $this->defaultClause($values); |
||
465 | } |
||
466 | |||
467 | /** |
||
468 | * Return a enum type-formatted string |
||
469 | * |
||
470 | * @param array $values Contains a tokenised list of info about this data type |
||
471 | * @return string |
||
472 | */ |
||
473 | public function enum($values) |
||
484 | } |
||
485 | |||
486 | /** |
||
487 | * Return a set type-formatted string |
||
488 | * |
||
489 | * @param array $values Contains a tokenised list of info about this data type |
||
490 | * @return string |
||
491 | */ |
||
492 | public function set($values) |
||
493 | { |
||
494 | //For reference, this is what typically gets passed to this function: |
||
495 | //$parts=Array('datatype'=>'enum', 'enums'=>$this->enum, 'character set'=>'utf8', 'collate'=> |
||
496 | // 'utf8_general_ci', 'default'=>$this->default); |
||
497 | //DB::requireField($this->tableName, $this->name, "enum('" . implode("','", $this->enum) . "') character set |
||
498 | //utf8 collate utf8_general_ci default '{$this->default}'"); |
||
499 | $valuesString = implode(",", Convert::raw2sql($values['enums'], true)); |
||
500 | $charset = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'charset'); |
||
501 | $collation = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'collation'); |
||
502 | return "set($valuesString) character set {$charset} collate {$collation}" . $this->defaultClause($values); |
||
503 | } |
||
504 | |||
505 | /** |
||
506 | * Return a float type-formatted string |
||
507 | * For MySQL, we simply return the word 'date', no other parameters are necessary |
||
508 | * |
||
509 | * @param array $values Contains a tokenised list of info about this data type |
||
510 | * @return string |
||
511 | */ |
||
512 | public function float($values) |
||
513 | { |
||
514 | //For reference, this is what typically gets passed to this function: |
||
515 | //$parts=Array('datatype'=>'float'); |
||
516 | //DB::requireField($this->tableName, $this->name, "float"); |
||
517 | return "float not null" . $this->defaultClause($values); |
||
518 | } |
||
519 | |||
520 | /** |
||
521 | * Return a int type-formatted string |
||
522 | * |
||
523 | * @param array $values Contains a tokenised list of info about this data type |
||
524 | * @return string |
||
525 | */ |
||
526 | public function int($values) |
||
527 | { |
||
528 | //For reference, this is what typically gets passed to this function: |
||
529 | //$parts=Array('datatype'=>'int', 'precision'=>11, 'null'=>'not null', 'default'=>(int)$this->default); |
||
530 | //DB::requireField($this->tableName, $this->name, "int(11) not null default '{$this->defaultVal}'"); |
||
531 | return "int(11) not null" . $this->defaultClause($values); |
||
532 | } |
||
533 | |||
534 | /** |
||
535 | * Return a bigint type-formatted string |
||
536 | * |
||
537 | * @param array $values Contains a tokenised list of info about this data type |
||
538 | * @return string |
||
539 | */ |
||
540 | public function bigint($values) |
||
541 | { |
||
542 | //For reference, this is what typically gets passed to this function: |
||
543 | //$parts=Array('datatype'=>'bigint', 'precision'=>20, 'null'=>'not null', 'default'=>$this->defaultVal, |
||
544 | // 'arrayValue'=>$this->arrayValue); |
||
545 | //$values=Array('type'=>'bigint', 'parts'=>$parts); |
||
546 | //DB::requireField($this->tableName, $this->name, $values); |
||
547 | |||
548 | return 'bigint(20) not null' . $this->defaultClause($values); |
||
549 | } |
||
550 | |||
551 | /** |
||
552 | * Return a datetime type-formatted string |
||
553 | * For MySQL, we simply return the word 'datetime', no other parameters are necessary |
||
554 | * |
||
555 | * @param array $values Contains a tokenised list of info about this data type |
||
556 | * @return string |
||
557 | */ |
||
558 | public function datetime($values) |
||
559 | { |
||
560 | //For reference, this is what typically gets passed to this function: |
||
561 | //$parts=Array('datatype'=>'datetime'); |
||
562 | //DB::requireField($this->tableName, $this->name, $values); |
||
563 | return 'datetime'; |
||
564 | } |
||
565 | |||
566 | /** |
||
567 | * Return a text type-formatted string |
||
568 | * |
||
569 | * @param array $values Contains a tokenised list of info about this data type |
||
570 | * @return string |
||
571 | */ |
||
572 | public function text($values) |
||
580 | } |
||
581 | |||
582 | /** |
||
583 | * Return a time type-formatted string |
||
584 | * For MySQL, we simply return the word 'time', no other parameters are necessary |
||
585 | * |
||
586 | * @param array $values Contains a tokenised list of info about this data type |
||
587 | * @return string |
||
588 | */ |
||
589 | public function time($values) |
||
590 | { |
||
591 | //For reference, this is what typically gets passed to this function: |
||
592 | //$parts=Array('datatype'=>'time'); |
||
593 | //DB::requireField($this->tableName, $this->name, "time"); |
||
594 | return 'time'; |
||
595 | } |
||
596 | |||
597 | /** |
||
598 | * Return a varchar type-formatted string |
||
599 | * |
||
600 | * @param array $values Contains a tokenised list of info about this data type |
||
601 | * @return string |
||
602 | */ |
||
603 | public function varchar($values) |
||
604 | { |
||
605 | //For reference, this is what typically gets passed to this function: |
||
606 | //$parts=Array('datatype'=>'varchar', 'precision'=>$this->size, 'character set'=>'utf8', 'collate'=> |
||
607 | //'utf8_general_ci'); |
||
608 | //DB::requireField($this->tableName, $this->name, "varchar($this->size) character set utf8 collate |
||
609 | // utf8_general_ci"); |
||
610 | $default = $this->defaultClause($values); |
||
611 | $charset = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'charset'); |
||
612 | $collation = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'collation'); |
||
613 | return "varchar({$values['precision']}) character set {$charset} collate {$collation}{$default}"; |
||
614 | } |
||
615 | |||
616 | /* |
||
617 | * Return the MySQL-proprietary 'Year' datatype |
||
618 | * |
||
619 | * @param array $values Contains a tokenised list of info about this data type |
||
620 | * @return string |
||
621 | */ |
||
622 | public function year($values) |
||
623 | { |
||
624 | return 'year(4)'; |
||
625 | } |
||
626 | |||
627 | public function IdColumn($asDbValue = false, $hasAutoIncPK = true) |
||
630 | } |
||
631 | |||
632 | /** |
||
633 | * Parses and escapes the default values for a specification |
||
634 | * |
||
635 | * @param array $values Contains a tokenised list of info about this data type |
||
636 | * @return string Default clause |
||
637 | */ |
||
638 | protected function defaultClause($values) |
||
639 | { |
||
644 | } |
||
645 | } |
||
646 |
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.