Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements | SQLServerParameterMetadata improvements with improved code coverage #973

Merged
merged 8 commits into from
Mar 13, 2019
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ private void parseQueryMeta(ResultSet rsQueryMeta) throws SQLServerException {
SQLServerException.getErrString("R_metaDataErrorForParameter"));
Object[] msgArgs = {paramOrdinal};
SQLServerException.makeFromDriverError(con, stmtParent,
form.format(msgArgs) + " " + e.toString(), null, false);
form.format(msgArgs) + " " + e.getMessage(), null, false);
}
}
} else
Expand Down Expand Up @@ -547,8 +547,8 @@ private void checkClosed() throws SQLServerException {
* the procedure name
* @throws SQLServerException
*/
@SuppressWarnings("serial")
SQLServerParameterMetaData(SQLServerPreparedStatement st, String sProcString) throws SQLServerException {

assert null != st;
stmtParent = st;
con = st.connection;
Expand Down Expand Up @@ -680,9 +680,9 @@ private void checkClosed() throws SQLServerException {
catch (SQLServerException e) {
throw e;
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
SQLServerException.makeFromDriverError(con, stmtParent, e.getMessage(), null, false);
} catch (StringIndexOutOfBoundsException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
SQLServerException.makeFromDriverError(con, stmtParent, e.getMessage(), null, false);
}
}

Expand All @@ -703,58 +703,66 @@ public <T> T unwrap(Class<T> iface) throws SQLException {
return t;
}

private Map<String, Object> getParameterInfo(int param) throws SQLServerException {
boolean paramFound = false;
private Map<String, Object> getParameterInfo(int param) {
if ((stmtParent).bReturnValueSyntax && isTVP) {
paramFound = procMetadata.size() >= param;
if (paramFound) {
return procMetadata.get(param - 1);
}
return procMetadata.get(param - 1);
} else {
// Note row 1 is the 'return value' meta data
paramFound = procMetadata.size() > param;
if (paramFound) {
return procMetadata.get(param);
}
return procMetadata.get(param);
}
if (!paramFound) {
}

private boolean isValidParamProc(int n) {
// Note row 1 is the 'return value' meta data
return (((stmtParent).bReturnValueSyntax && isTVP && procMetadata.size() >= n) || procMetadata.size() > n);
}

private boolean isValidParamQuery(int n) {
return (null != queryMetaMap && queryMetaMap.containsKey(n));
}

/**
* Checks if the @param passed is valid for either procedure metadata or query metadata.
*
* @param param
* @throws SQLServerException
*/
private void checkParam(int param) throws SQLServerException {
// Check if Procedure Metadata is not available
if (null == procMetadata) {
// Check if Query Metadata is also not available
if (!isValidParamQuery(param)) {
SQLServerException.makeFromDriverError(con, stmtParent, SQLServerException.getErrString("R_noMetadata"),
null, false);
}
} else if (!isValidParamProc(param)) {
// Throw exception if @param index not found
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidParameterNumber"));
Object[] msgArgs = {param};
SQLServerException.makeFromDriverError(con, stmtParent, form.format(msgArgs), null, false);
}
return null;
}

private void checkParam(int n) throws SQLServerException {
if (!queryMetaMap.containsKey(n)) {
SQLServerException.makeFromDriverError(con, stmtParent, SQLServerException.getErrString("R_noMetadata"),
null, false);
}
}

@Override
public String getParameterClassName(int param) throws SQLServerException {
checkClosed();
checkParam(param);
try {
if (procMetadata == null) {
// PreparedStatement.
checkParam(param);
if (null == procMetadata) {
return queryMetaMap.get(param).parameterClassName;
} else {
JDBCType jdbcType = JDBCType.of((short) getParameterInfo(param).get("DATA_TYPE"));
return jdbcType.className();
return JDBCType.of((short) getParameterInfo(param).get("DATA_TYPE")).className();
}
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
} catch (SQLServerException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.getMessage(), null, false);
return null;
}
}

@Override
public int getParameterCount() throws SQLServerException {
checkClosed();
if (procMetadata == null) {
// PreparedStatement
if (null == procMetadata) {
return queryMetaMap.size();
} else {
// Row 1 is Return Type metadata
Expand All @@ -765,170 +773,121 @@ public int getParameterCount() throws SQLServerException {
@Override
public int getParameterMode(int param) throws SQLServerException {
checkClosed();
try {
if (procMetadata == null) {
checkParam(param);
// if it is not a stored proc, the param can only be input.
checkParam(param);
if (null == procMetadata) {
// if it is not a stored procedure, the @param can only be input.
return parameterModeIn;
} else {
int n = (int) getParameterInfo(param).get("COLUMN_TYPE");
if (n == 1)
return parameterModeIn;
} else {
int n = (int) getParameterInfo(param).get("COLUMN_TYPE");
switch (n) {
case 1:
return parameterModeIn;
case 2:
return parameterModeOut;
default:
return parameterModeUnknown;
}
}
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
return parameterModeUnknown;
else if (n == 2)
return parameterModeOut;
else
return parameterModeUnknown;
}
}

@Override
public int getParameterType(int param) throws SQLServerException {
checkClosed();
checkParam(param);
int parameterType = 0;
try {
if (procMetadata == null) {
// PreparedStatement.
checkParam(param);
parameterType = queryMetaMap.get(param).parameterType;
} else {
Map<String, Object> info = getParameterInfo(param);
if (null != info) {
parameterType = (short) info.get("DATA_TYPE");
}
}
if (0 != parameterType) {
switch (parameterType) {
case microsoft.sql.Types.DATETIME:
case microsoft.sql.Types.SMALLDATETIME:
parameterType = SSType.DATETIME2.getJDBCType().asJavaSqlType();
break;
case microsoft.sql.Types.MONEY:
case microsoft.sql.Types.SMALLMONEY:
parameterType = SSType.DECIMAL.getJDBCType().asJavaSqlType();
break;
case microsoft.sql.Types.GUID:
parameterType = SSType.CHAR.getJDBCType().asJavaSqlType();
break;
default:
break;
}
if (null == procMetadata) {
parameterType = queryMetaMap.get(param).parameterType;
} else {
parameterType = (short) getParameterInfo(param).get("DATA_TYPE");
}
if (0 != parameterType) {
switch (parameterType) {
case microsoft.sql.Types.DATETIME:
case microsoft.sql.Types.SMALLDATETIME:
parameterType = SSType.DATETIME2.getJDBCType().asJavaSqlType();
break;
case microsoft.sql.Types.MONEY:
case microsoft.sql.Types.SMALLMONEY:
parameterType = SSType.DECIMAL.getJDBCType().asJavaSqlType();
break;
case microsoft.sql.Types.GUID:
parameterType = SSType.CHAR.getJDBCType().asJavaSqlType();
break;
}
return parameterType;
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
return 0;
}
return parameterType;
}

@Override
public String getParameterTypeName(int param) throws SQLServerException {
checkClosed();
try {
if (procMetadata == null) {
// PreparedStatement.
checkParam(param);
return queryMetaMap.get(param).parameterTypeName;
} else {
return getParameterInfo(param).get("TYPE_NAME").toString();
}
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
return null;
checkParam(param);
if (null == procMetadata) {
return queryMetaMap.get(param).parameterTypeName;
} else {
return getParameterInfo(param).get("TYPE_NAME").toString();
}
}

@Override
public int getPrecision(int param) throws SQLServerException {
checkClosed();
try {
if (procMetadata == null) {
// PreparedStatement.
checkParam(param);
return queryMetaMap.get(param).precision;
} else {
int nPrec = (int) getParameterInfo(param).get("PRECISION");
return nPrec;
}
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
return 0;
checkParam(param);
if (null == procMetadata) {
return queryMetaMap.get(param).precision;
} else {
return (int) getParameterInfo(param).get("PRECISION");
}
}

@Override
public int getScale(int param) throws SQLServerException {
checkClosed();
try {
if (procMetadata == null) {
// PreparedStatement.
checkParam(param);
return queryMetaMap.get(param).scale;
} else {
int nScale = (int) getParameterInfo(param).get("SCALE");
return nScale;
}
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
return 0;
checkParam(param);
if (null == procMetadata) {
return queryMetaMap.get(param).scale;
} else {
return (int) getParameterInfo(param).get("SCALE");
}
}

@Override
public int isNullable(int param) throws SQLServerException {
checkClosed();
try {
if (procMetadata == null) {
// PreparedStatement.
checkParam(param);
return queryMetaMap.get(param).isNullable;
} else {
int nNull = (int) getParameterInfo(param).get("NULLABLE");
if (nNull == 1)
return parameterNullable;
if (nNull == 0)
return parameterNoNulls;
return parameterNullableUnknown;
}
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
return parameterNoNulls;
checkParam(param);
if (procMetadata == null) {
return queryMetaMap.get(param).isNullable;
} else {
return (int) getParameterInfo(param).get("NULLABLE");
}
}

/**
* Returns if a supplied parameter index is valid.
*
* @param param
* the param index
* the @param index
* @throws SQLServerException
* when an error occurs
* @return boolean
*/
@Override
public boolean isSigned(int param) throws SQLServerException {
checkClosed();
checkParam(param);
try {
if (procMetadata == null) {
// PreparedStatement.
checkParam(param);
if (null == procMetadata) {
return queryMetaMap.get(param).isSigned;
} else {
return JDBCType.of((short) getParameterInfo(param).get("DATA_TYPE")).isSigned();
}
} catch (SQLException e) {
SQLServerException.makeFromDriverError(con, stmtParent, e.toString(), null, false);
SQLServerException.makeFromDriverError(con, stmtParent, e.getMessage(), null, false);
return false;
}
}

String getTVPSchemaFromStoredProcedure(int param) throws SQLServerException {
checkClosed();
checkParam(param);
return (String) getParameterInfo(param).get("SS_TYPE_SCHEMA_NAME");
}
}
Loading