Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
EnumType
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 4
90
0.00% covered (danger)
0.00%
0 / 1
 getSQLDeclaration
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 makeEnumTypeSql
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 formatValues
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Wikimedia\Rdbms;
4
5use Doctrine\DBAL\Platforms\AbstractPlatform;
6use Doctrine\DBAL\Types\Type;
7use InvalidArgumentException;
8
9/**
10 * Custom handling for ENUM datatype
11 *
12 * NOTE: Use of this type is discouraged unless necessary. Please use
13 * alternative types where possible. See T119173 for the RFC discussion
14 * about this type and potential alternatives.
15 *
16 * @see https://phabricator.wikimedia.org/T119173
17 */
18class EnumType extends Type {
19    public const ENUM = 'mwenum';
20
21    /**
22     * Gets the SQL declaration snippet for an ENUM column
23     *
24     * @param mixed[] $column Column definition
25     * @param AbstractPlatform $platform
26     *
27     * @return string
28     */
29    public function getSQLDeclaration( array $column, AbstractPlatform $platform ) {
30        // SQLite does not support ENUM type
31        if ( $platform->getName() == 'sqlite' ) {
32            return 'TEXT';
33        }
34
35        // PostgreSQL does support but needs custom handling.
36        // This just returns a string name that references the
37        // actual ENUM which will be created by CREATE TYPE command
38        // If 'fixed' option is not passed, this field will use TEXT
39        if ( $platform->getName() == 'postgresql' ) {
40            if ( !$column['fixed'] ) {
41                return 'TEXT';
42            }
43
44            return strtoupper( $column['name'] . '_enum' );
45        }
46
47        if ( $platform->getName() == 'mysql' ) {
48            $enumValues = $this->formatValues( $column['enum_values'] );
49            return "ENUM( $enumValues )";
50        }
51    }
52
53    /**
54     * Gets the sql portion to create ENUM for Postgres table column
55     *
56     * @param mixed[] $column
57     * @param AbstractPlatform $platform
58     *
59     * @see MWPostgreSqlPlatform::_getCreateTableSQL()
60     * @throws \InvalidArgumentException
61     * @return string
62     */
63    public function makeEnumTypeSql( $column, $platform ) {
64        if ( $platform->getName() !== 'postgresql' ) {
65            throw new InvalidArgumentException(
66                __METHOD__ . ' can only be called on Postgres platform'
67            );
68        }
69
70        $enumName = strtoupper( $column['name'] . '_enum' );
71        $enumValues = $this->formatValues( $column['enum_values'] );
72        $typeSql = "\n\nCREATE TYPE $enumName AS ENUM( $enumValues )";
73
74        return $typeSql;
75    }
76
77    /**
78     * Get the imploded values suitable for pushing directly into ENUM();
79     *
80     * @param string[] $values
81     * @return string
82     */
83    public function formatValues( $values ) {
84        $values = implode( "','", $values );
85        $enumValues = "'" . $values . "'";
86
87        return $enumValues;
88    }
89
90    public function getName() {
91        return self::ENUM;
92    }
93}