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