package org.jooq.meta;
import static java.util.Arrays.asList;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DefaultDataType.normalise;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.jooq.Name;
import org.jooq.SQLDialect;
import org.jooq.tools.StringUtils;
import org.jooq.types.UByte;
import org.jooq.types.UInteger;
import org.jooq.types.ULong;
import org.jooq.types.UShort;
public class DefaultDataTypeDefinition implements DataTypeDefinition {
private final Database database;
private final SchemaDefinition schema;
private final String type;
private final Name userType;
private final String javaType;
private final String converter;
private final String binding;
private final boolean nullable;
private boolean isIdentity;
private final String defaultValue;
private final int length;
private final int precision;
private final int scale;
private static final String defaultValue(Boolean defaultable) {
return defaultable != null && defaultable ? "NULL" : null;
}
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName) {
this(database, schema, typeName, null, null, null, null, (String) null, (Name) null);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, Boolean defaultable) {
this(database, schema, typeName, length, precision, scale, nullable, defaultable, typeName, null);
}
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, typeName, null);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, Boolean defaultable, String userType) {
this(database, schema, typeName, length, precision, scale, nullable, defaultable, userType, null);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, String userType) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, name(userType));
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, Boolean defaultValue, Name userType) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue(defaultValue), userType);
}
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, Name userType) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, userType, null);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, Boolean defaultable, String userType, String converter) {
this(database, schema, typeName, length, precision, scale, nullable, defaultable, userType, converter, null);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, String userType, String converter) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, name(userType), converter);
}
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, Name userType, String converter) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, userType, converter, null);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, Boolean defaultable, String userType, String converter, String binding) {
this(database, schema, typeName, length, precision, scale, nullable, defaultable, userType, converter, binding, null);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, String userType, String converter, String binding) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, name(userType), converter, binding, null);
}
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, Name userType, String converter, String binding) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, userType, converter, binding, null);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, Boolean defaultable, String userType, String converter, String binding, String javaType) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue(defaultable), userType, converter, binding, javaType);
}
@Deprecated
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, String userType, String converter, String binding, String javaType) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, name(userType), converter, binding, javaType);
}
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, Name userType, String converter, String binding, String javaType) {
this(database, schema, typeName, length, precision, scale, nullable, defaultValue, false, userType, converter, binding, javaType);
}
public DefaultDataTypeDefinition(Database database, SchemaDefinition schema, String typeName, Number length, Number precision, Number scale, Boolean nullable, String defaultValue, boolean isIdentity, Name userType, String converter, String binding, String javaType) {
this.database = database;
this.schema = schema;
this.type = typeName == null ? "OTHER" : typeName;
this.userType = userType;
this.javaType = javaType;
this.converter = converter;
this.binding = binding;
if (length != null && precision != null && length.intValue() != 0 && precision.intValue() != 0) {
if (this.type.toLowerCase().matches(".*?(char|text|lob|xml|graphic|string).*?")) {
precision = null;
scale = null;
}
else {
length = null;
}
}
this.length = length == null ? 0 : length.intValue();
this.precision = precision == null ? 0 : precision.intValue();
this.scale = scale == null ? 0 : scale.intValue();
this.nullable = nullable == null ? true : nullable.booleanValue();
this.defaultValue = defaultValue;
this.isIdentity = isIdentity;
}
@Override
public final Database getDatabase() {
return database;
}
@Override
public final SchemaDefinition getSchema() {
return schema;
}
private final SQLDialect getDialect() {
return getDatabase().getDialect();
}
@Override
public final boolean isNullable() {
return nullable;
}
public final DefaultDataTypeDefinition identity(boolean identity) {
this.isIdentity = identity;
return this;
}
@Override
public final boolean isIdentity() {
return isIdentity;
}
@Override
public final boolean isDefaulted() {
return getDefaultValue() != null;
}
@Override
public final String getDefaultValue() {
return defaultValue;
}
@Override
public final boolean isUDT() {
if (userType == null)
return false;
return getDatabase().getUDT(schema, userType) != null;
}
@Override
public final boolean isArray() {
if (userType == null)
return false;
return getDatabase().getArray(schema, userType) != null;
}
@Override
public final String getType() {
return type;
}
@Override
public final String getConverter() {
return converter;
}
@Override
public final String getBinding() {
return binding;
}
@Override
public final int getLength() {
return length;
}
@Override
public final int getPrecision() {
return precision;
}
@Override
public final int getScale() {
return scale;
}
@Override
public final String getUserType() {
return userType != null ? userType.last() : null;
}
@Override
public final Name getQualifiedUserType() {
return userType;
}
@Override
public final String getJavaType() {
return javaType;
}
@Override
public final String getJavaType(JavaTypeResolver resolver) {
if (resolver == null)
return getJavaType();
else
return resolver.resolve(this);
}
@Override
public final boolean isGenericNumberType() {
return false;
}
@Override
public List<String> getMatchNames() {
Set<String> result = new LinkedHashSet<>();
result.add(getType());
if (getLength() != 0)
result.add(getType() + "(" + getLength() + ")");
if (getScale() == 0)
result.add(getType() + "(" + getPrecision() + ")");
result.add(getType() + "(" + getPrecision() + "," + getScale() + ")");
result.add(getType() + "(" + getPrecision() + ", " + getScale() + ")");
if (!StringUtils.isBlank(getUserType())) {
result.add(getUserType());
result.add(getQualifiedUserType().unquotedName().toString());
}
return new ArrayList<>(result);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((userType == null) ? 0 : userType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof DefaultDataTypeDefinition) {
DefaultDataTypeDefinition other = (DefaultDataTypeDefinition) obj;
if (!normalise(type).equals(normalise(other.type)))
return false;
if (userType == null && other.userType == null)
return true;
if (userType == null || other.userType == null)
return false;
return normalise(userType.last()).equals(normalise(other.userType.last()));
}
return false;
}
@Override
public final String toString() {
StringBuilder sb = new StringBuilder();
sb.append("DataType [ t=");
sb.append(type);
sb.append("; p=");
sb.append(precision);
sb.append("; s=");
sb.append(scale);
sb.append("; u=");
sb.append(userType);
sb.append("; j=");
sb.append(javaType);
sb.append(" ]");
return sb.toString();
}
}