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