/* * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, * and the EPL 1.0 (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.jdbc; import java.sql.ParameterMetaData; import java.sql.SQLException; import java.util.ArrayList; import org.h2.command.CommandInterface; import org.h2.expression.ParameterInterface; import org.h2.message.DbException; import org.h2.message.Trace; import org.h2.message.TraceObject; import org.h2.util.MathUtils; import org.h2.value.DataType; import org.h2.value.Value; /** * Information about the parameters of a prepared statement. */ public class JdbcParameterMetaData extends TraceObject implements ParameterMetaData { private final JdbcPreparedStatement prep; private final int paramCount; private final ArrayList<? extends ParameterInterface> parameters; JdbcParameterMetaData(Trace trace, JdbcPreparedStatement prep, CommandInterface command, int id) { setTrace(trace, TraceObject.PARAMETER_META_DATA, id); this.prep = prep; this.parameters = command.getParameters(); this.paramCount = parameters.size(); } /** * Returns the number of parameters. * * @return the number */ @Override public int getParameterCount() throws SQLException { try { debugCodeCall("getParameterCount"); checkClosed(); return paramCount; } catch (Exception e) { throw logAndConvert(e); } } /** * Returns the parameter mode. * Always returns parameterModeIn. * * @param param the column index (1,2,...) * @return parameterModeIn */ @Override public int getParameterMode(int param) throws SQLException { try { debugCodeCall("getParameterMode", param); getParameter(param); return parameterModeIn; } catch (Exception e) { throw logAndConvert(e); } } /** * Returns the parameter type. * java.sql.Types.VARCHAR is returned if the data type is not known. * * @param param the column index (1,2,...) * @return the data type */ @Override public int getParameterType(int param) throws SQLException { try { debugCodeCall("getParameterType", param); ParameterInterface p = getParameter(param); int type = p.getType(); if (type == Value.UNKNOWN) { type = Value.STRING; } return DataType.getDataType(type).sqlType; } catch (Exception e) { throw logAndConvert(e); } } /** * Returns the parameter precision. * The value 0 is returned if the precision is not known. * * @param param the column index (1,2,...) * @return the precision */ @Override public int getPrecision(int param) throws SQLException { try { debugCodeCall("getPrecision", param); ParameterInterface p = getParameter(param); return MathUtils.convertLongToInt(p.getPrecision()); } catch (Exception e) { throw logAndConvert(e); } } /** * Returns the parameter scale. * The value 0 is returned if the scale is not known. * * @param param the column index (1,2,...) * @return the scale */ @Override public int getScale(int param) throws SQLException { try { debugCodeCall("getScale", param); ParameterInterface p = getParameter(param); return p.getScale(); } catch (Exception e) { throw logAndConvert(e); } } /** * Checks if this is nullable parameter. * Returns ResultSetMetaData.columnNullableUnknown.. * * @param param the column index (1,2,...) * @return ResultSetMetaData.columnNullableUnknown */ @Override public int isNullable(int param) throws SQLException { try { debugCodeCall("isNullable", param); return getParameter(param).getNullable(); } catch (Exception e) { throw logAndConvert(e); } } /** * Checks if this parameter is signed. * It always returns true. * * @param param the column index (1,2,...) * @return true */ @Override public boolean isSigned(int param) throws SQLException { try { debugCodeCall("isSigned", param); getParameter(param); return true; } catch (Exception e) { throw logAndConvert(e); } } /** * Returns the Java class name of the parameter. * "java.lang.String" is returned if the type is not known. * * @param param the column index (1,2,...) * @return the Java class name */ @Override public String getParameterClassName(int param) throws SQLException { try { debugCodeCall("getParameterClassName", param); ParameterInterface p = getParameter(param); int type = p.getType(); if (type == Value.UNKNOWN) { type = Value.STRING; } return DataType.getTypeClassName(type); } catch (Exception e) { throw logAndConvert(e); } } /** * Returns the parameter type name. * "VARCHAR" is returned if the type is not known. * * @param param the column index (1,2,...) * @return the type name */ @Override public String getParameterTypeName(int param) throws SQLException { try { debugCodeCall("getParameterTypeName", param); ParameterInterface p = getParameter(param); int type = p.getType(); if (type == Value.UNKNOWN) { type = Value.STRING; } return DataType.getDataType(type).name; } catch (Exception e) { throw logAndConvert(e); } } private ParameterInterface getParameter(int param) { checkClosed(); if (param < 1 || param > paramCount) { throw DbException.getInvalidValueException("param", param); } return parameters.get(param - 1); } private void checkClosed() { prep.checkClosed(); } /** * Return an object of this class if possible. * * @param iface the class * @return this */ @Override @SuppressWarnings("unchecked") public <T> T unwrap(Class<T> iface) throws SQLException { try { if (isWrapperFor(iface)) { return (T) this; } throw DbException.getInvalidValueException("iface", iface); } catch (Exception e) { throw logAndConvert(e); } } /** * Checks if unwrap can return an object of this class. * * @param iface the class * @return whether or not the interface is assignable from this class */ @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return iface != null && iface.isAssignableFrom(getClass()); } /** * INTERNAL */ @Override public String toString() { return getTraceObjectName() + ": parameterCount=" + paramCount; } }