package com.dci.intellij.dbn.data.type;
import com.dci.intellij.dbn.object.DBPackage;
import com.dci.intellij.dbn.object.DBSchema;
import com.dci.intellij.dbn.object.DBType;
import com.dci.intellij.dbn.object.common.DBObject;
import com.dci.intellij.dbn.object.common.DBObjectBundle;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
public class DBDataType {
private DBType declaredType;
private DBNativeDataType nativeDataType;
private String typeName;
private String qualifiedName;
private long length;
private int precision;
private int scale;
public DBDataType(DBObject parent, ResultSet resultSet) throws SQLException {
length = resultSet.getLong("DATA_LENGTH");
precision = resultSet.getInt("DATA_PRECISION");
scale = resultSet.getInt("DATA_SCALE");
String typeOwner = resultSet.getString("DATA_TYPE_OWNER");
String typePackage = resultSet.getString("DATA_TYPE_PACKAGE");
String dataTypeName = resultSet.getString("DATA_TYPE_NAME");
DBObjectBundle objectBundle = parent.getConnectionHandler().getObjectBundle();
if (typeOwner != null) {
DBSchema typeSchema = objectBundle.getSchema(typeOwner);
if (typePackage != null) {
DBPackage packagee = typeSchema.getPackage(typePackage);
declaredType = packagee.getType(dataTypeName);
} else {
declaredType = typeSchema.getType(dataTypeName);
}
if (declaredType == null) typeName = dataTypeName;
} else {
nativeDataType = objectBundle.getNativeDataType(dataTypeName);
if (nativeDataType == null) typeName = dataTypeName;
}
}
public DBDataType(DBNativeDataType nativeDataType, int precision, int scale) throws SQLException {
this.precision = precision;
this.scale = scale;
this.nativeDataType = nativeDataType;
}
public boolean isDeclared() {
return declaredType != null;
}
public boolean isNative() {
return nativeDataType != null;
}
public String getName() {
return nativeDataType == null && declaredType == null ? typeName :
nativeDataType == null ? declaredType.getQualifiedName() :
nativeDataType.getName();
}
public Class getTypeClass() {
return nativeDataType == null ? Object.class : nativeDataType.getDataTypeDefinition().getTypeClass();
}
public int getSqlType() {
return nativeDataType == null ? Types.CHAR : nativeDataType.getSqlType();
}
public DBNativeDataType getNativeDataType() {
return nativeDataType;
}
public DBType getDeclaredType() {
return declaredType;
}
public long getLength() {
return length;
}
public int getPrecision() {
return precision;
}
public int getScale() {
return scale;
}
public Object getValueFromResultSet(ResultSet resultSet, int columnIndex) throws SQLException {
if (nativeDataType != null) {
return nativeDataType.getValueFromResultSet(resultSet, columnIndex);
} else {
return declaredType == null ? "[UNKNOWN]" : "[" + declaredType.getName() + "]";
}
}
public void setValueToResultSet(ResultSet resultSet, int columnIndex, Object value) throws SQLException {
if (nativeDataType != null) {
nativeDataType.setValueToResultSet(resultSet, columnIndex, value);
}
}
public void setValueToPreparedStatement(PreparedStatement preparedStatement, int index, Object value) throws SQLException {
if (nativeDataType != null) {
nativeDataType.setValueToPreparedStatement(preparedStatement, index, value);
}
}
public String getQualifiedName() {
if (qualifiedName == null) {
StringBuilder buffer = new StringBuilder();
String name = getName();
buffer.append(name == null ? "" : name.toLowerCase());
if (getPrecision() > 0) {
buffer.append(" (");
buffer.append(getPrecision());
if (getScale() > 0) {
buffer.append(", ");
buffer.append(getScale());
}
buffer.append(")");
} else if (getLength() > 0) {
buffer.append(" (");
buffer.append(getLength());
buffer.append(")");
}
qualifiedName = buffer.toString();
}
return qualifiedName;
}
/**
* @deprecated
*/
public Object convert(String stringValue) throws Exception{
Class clazz = getTypeClass();
if (String.class.isAssignableFrom(clazz)) {
return stringValue;
}
if (Date.class.isAssignableFrom(clazz)) {
Method method = clazz.getMethod("valueOf", String.class);
return method.invoke(clazz, stringValue);
} else {
Constructor constructor = clazz.getConstructor(String.class);
return constructor.newInstance(stringValue);
}
}
@Override
public String toString() {
return getName();
}
@Override
public int hashCode() {
return toString().hashCode();
}
}