/** * Resolves a query, given a QueryInfo * * @param info The info encapsulating the query information * @param con the db connection * @param params the parameters passed to query * @return the resolved query * @throws SQLException if resolving the query failed */ PreparedStatement resolveQuery(QueryInfo info, Connection con, Map<String, Object> params) throws SQLException, ResourceException { String queryStr = info.getQueryString(); List<String> tokenNames = info.getTokenNames(); // replace ${list:variable} tokens with the correct number of bind variables Map<String, Integer> listReplacements = new HashMap<String, Integer>(); for (String tokenName : tokenNames) { String[] tokenParts = tokenName.split(":", 2); if (PREFIX_LIST.equals(tokenParts[0]) && params.containsKey(tokenParts[1])) { listReplacements.put(tokenName, ((String) params.get(tokenParts[1])).split(",").length); } } if (listReplacements.size() > 0) { TokenHandler tokenHandler = new TokenHandler(); queryStr = tokenHandler.replaceListTokens(queryStr, listReplacements, "?"); } // now prepare the statement using the correct number of bind variables PreparedStatement statement = getPreparedStatement(con, queryStr); int count = 1; // DB column count starts at 1 for (String tokenName : tokenNames) { String[] tokenParts = tokenName.split(":", 2); if (tokenParts.length == 1) { // handle single value - assume String Object objValue = params.get(tokenName); String value = null; if (objValue != null) { value = trimValue(objValue); } else { // fail with an exception if token not found throw new BadRequestException( "Missing entry in params passed to query for token " + tokenName); } statement.setString(count, value); count++; } else { Object objValue = params.get(tokenParts[1]); if (objValue == null) { // fail with an exception if token not found throw new BadRequestException( "Missing entry in params passed to query for token " + tokenName); } if (PREFIX_INT.equals(tokenParts[0])) { // handle single integer value Integer int_value = null; if (objValue != null) { int_value = Integer.parseInt(objValue.toString()); } statement.setInt(count, int_value); count++; } else if (PREFIX_LIST.equals(tokenParts[0])) { // handle list of values - presently assumes Strings, TODO support integer lists if (objValue != null) { for (String list_value : objValue.toString().split(",")) { // if list value is surrounded by single quotes remove them if (list_value != null && list_value.startsWith("'") && list_value.endsWith("'")) { list_value = list_value.substring(1, list_value.length() - 1); } statement.setString(count, trimValue(list_value)); count++; } } else { statement.setString(count, null); count++; } } } } logger.debug("Prepared statement: {}", statement); return statement; }