package com.tesora.dve.sql.schema.types;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.tesora.dve.common.PEStringUtils;
import com.tesora.dve.common.catalog.UserColumn;
import com.tesora.dve.db.NativeType;
import com.tesora.dve.db.NativeTypeCatalog;
import com.tesora.dve.db.mysql.MysqlNativeType.MysqlType;
import com.tesora.dve.sql.node.expression.LiteralExpression;
import com.tesora.dve.sql.schema.UnqualifiedName;
import com.tesora.dve.sql.schema.modifiers.TypeModifier;
import com.tesora.dve.sql.util.Functional;
public final class DBEnumType extends TextType {
List<LiteralExpression> values;
private final boolean set;
public static Type buildType(UserColumn uc, NativeTypeCatalog types) {
boolean isSet = "set".equalsIgnoreCase(uc.getTypeName());
List<String> values = null;
if (uc.getESUniverse() == null)
values = Collections.EMPTY_LIST;
else
values = Arrays.asList(uc.getESUniverse().split(","));
return makeFromStrings(isSet, values, BasicType.buildModifiers(uc),types);
}
public static DBEnumType makeFromStrings(boolean isSet, List<String> values, List<TypeModifier> mods, NativeTypeCatalog typeCatalog) {
final List<LiteralExpression> valueExpressions = new ArrayList<LiteralExpression>(values.size());
for (final String value : values) {
final String noQuotesValue = PEStringUtils.dequote(value);
if (PEStringUtils.isHexNumber(noQuotesValue)) {
valueExpressions.add(LiteralExpression.makeHexStringLiteral(noQuotesValue));
} else {
valueExpressions.add(LiteralExpression.makeStringLiteral(noQuotesValue));
}
}
return make(isSet, valueExpressions, mods, typeCatalog);
}
public static DBEnumType make(boolean isSet, List<LiteralExpression> values, List<TypeModifier> mods, NativeTypeCatalog typeCatalog) {
NativeType backingType = null;
int size = 0;
if (values.size() < 256) {
size = 1;
backingType = BasicType.lookupNativeType(MysqlType.TINYINT.toString(), typeCatalog);
} else {
size = 2;
backingType = BasicType.lookupNativeType(MysqlType.SMALLINT.toString(), typeCatalog);
}
FlagsAndModifiers fam = buildFlagsAndModifiers(mods);
return new DBEnumType(isSet, values, backingType, fam.flags, size, fam.charset, fam.collation);
}
private DBEnumType(boolean isSet, List<LiteralExpression> values, NativeType bt, short flags, int size,
UnqualifiedName charSet, UnqualifiedName collation) {
super(bt,flags,size,charSet,collation);
this.values = values;
this.set = isSet;
}
@Override
public String getTypeName() {
return getEnumerationTypeName() + "(" + Functional.joinToString(values, ",") + ")";
}
@Override
public void persistTypeName(UserColumn uc) {
uc.setTypeName(set ? "set" : "enum");
uc.setESUniverse(Functional.joinToString(values,","));
}
public String getEnumerationTypeName() {
final MysqlType type = (set) ? MysqlType.SET : MysqlType.ENUM;
return type.toString();
}
@Override
public boolean declUsesSizing() {
return false;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((values == null) ? 0 : values.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
DBEnumType other = (DBEnumType) obj;
if (values == null) {
if (other.values != null)
return false;
} else if (!values.equals(other.values)) {
return false;
}
return true;
}
@Override
public boolean isAcceptableRangeType() {
// never
return false;
}
/**
* @param order 1-based index into the enum.
*/
public LiteralExpression getValueAt(final int order) {
return values.get(order - 1);
}
}