/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.datasource.jdbc; import com.google.common.base.Joiner; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import org.obiba.magma.Value; import org.obiba.magma.Variable; import org.obiba.magma.VariableEntity; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * Performs the SQL query to get one or more {@link org.obiba.magma.ValueSet}s. */ class JdbcValueSetFetcher { private final JdbcValueTable valueTable; private final String sqlTableName; private RowMapper<Map<String, Value>> mapper; JdbcValueSetFetcher(final JdbcValueTable valueTable) { this.valueTable = valueTable; sqlTableName = valueTable.getSettings().getSqlTableName(); this.mapper = new JdbcRowMapper(valueTable); } List<Map<String, Value>> loadNonBinaryVariableValues(List<VariableEntity> entities) { return loadValues(getNonBinaryColumns(), entities); } List<Map<String, Value>> loadNonBinaryVariableValues(VariableEntity entity) { return loadValues(getNonBinaryColumns(), entity); } List<Map<String, Value>> loadVariableValues(Variable variable, VariableEntity entity) { return loadValues( Lists.newArrayList(valueTable.getVariableSqlName(variable.getName())), entity); } // // Private methods // private List<String> getNonBinaryColumns() { List<String> columns = valueTable.getVariables().stream() .filter(variable -> !variable.getValueType().isBinary()) .map(variable -> valueTable.getVariableSqlName(variable.getName())) .collect(Collectors.toList()); String created = valueTable.getCreatedTimestampColumnName(); if (!Strings.isNullOrEmpty(created)) columns.add(created); String updated = valueTable.getUpdatedTimestampColumnName(); if (!Strings.isNullOrEmpty(updated)) columns.add(updated); return columns; } /** * Get the rows for the given entity. * * @param columnNames * @param entity * @return */ private List<Map<String, Value>> loadValues(List<String> columnNames, VariableEntity entity) { final JdbcDatasource datasource = valueTable.getDatasource(); String entityIdentifierColumn = valueTable.getSettings().getEntityIdentifierColumn(); String whereClause = String.format("%s = ?", datasource.escapeColumnName(entityIdentifierColumn)); if (valueTable.getSettings().hasEntityIdentifiersWhere()) { whereClause = String.format("%s AND %s", valueTable.getSettings().getEntityIdentifiersWhere(), whereClause); } Iterable<String> escapedColumnNames = columnNames.stream().map(datasource::escapeColumnName).collect(Collectors.toList()); return queryValues(Joiner.on(", ").join(escapedColumnNames), datasource.escapeTableName(sqlTableName), whereClause, entity); } /** * Query the rows for the given entity. * * @param selectClause * @param fromClause * @param whereClause * @param entity * @return */ private List<Map<String, Value>> queryValues(String selectClause, String fromClause, String whereClause, VariableEntity entity) { String sql = String.format("SELECT %s FROM %s WHERE %s", selectClause, fromClause, whereClause); return valueTable.getDatasource().getJdbcTemplate() .query(sql, new String[] { entity.getIdentifier() }, mapper); } private List<Map<String, Value>> loadValues(List<String> columnNames, List<VariableEntity> entities) { final JdbcDatasource datasource = valueTable.getDatasource(); String whereClause = String.format("%s IN (:ids)", valueTable.getEntityIdentifierColumnSql()); if (valueTable.getSettings().hasEntityIdentifiersWhere()) { whereClause = String.format("%s AND %s", valueTable.getSettings().getEntityIdentifiersWhere(), whereClause); } ImmutableList.Builder<String> escapedColumnNames = ImmutableList.builder(); for (String columnName : columnNames) { escapedColumnNames.add(datasource.escapeColumnName(columnName)); } escapedColumnNames.add(valueTable.getEntityIdentifierColumnSql()); return queryValues(Joiner.on(", ").join(escapedColumnNames.build()), datasource.escapeTableName(sqlTableName), whereClause, entities); } private List<Map<String, Value>> queryValues(String selectClause, String fromClause, String whereClause, List<VariableEntity> entities) { String sql = String.format("SELECT %s FROM %s WHERE %s", selectClause, fromClause, whereClause); MapSqlParameterSource parameters = new MapSqlParameterSource(); ImmutableList.Builder<String> ids = ImmutableList.builder(); for (VariableEntity entity : entities) { ids.add(entity.getIdentifier()); } parameters.addValue("ids", ids.build()); return valueTable.getDatasource().getNamedParameterJdbcTemplate().query(sql, parameters, mapper); } }