package org.nextprot.api.user.dao.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nextprot.api.commons.exception.NextProtException; import org.nextprot.api.commons.spring.jdbc.DataSourceServiceLocator; import org.nextprot.api.commons.utils.JdbcTemplateUtils; import org.nextprot.api.commons.utils.KeyValuesJdbcBatchUpdater; import org.nextprot.api.commons.utils.SQLDictionary; import org.nextprot.api.user.dao.UserProteinListDao; import org.nextprot.api.user.domain.UserProteinList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.springframework.stereotype.Repository; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @Lazy @Repository public class UserProteinListDaoImpl implements UserProteinListDao { private final Log Logger = LogFactory.getLog(UserProteinListDaoImpl.class); @Autowired private SQLDictionary sqlDictionary; @Autowired(required = false) private DataSourceServiceLocator dsLocator; @Override public List<UserProteinList> getUserProteinLists(String username) { String sql = sqlDictionary.getSQLQuery("read-user-protein-lists-by-username"); SqlParameterSource namedParameters = new MapSqlParameterSource("user_name", username); return new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).query(sql, namedParameters, new ProteinListRowMapper()); } @Override public UserProteinList getUserProteinListById(long listId) throws DataAccessException { String sql = sqlDictionary.getSQLQuery("read-user-protein-list-by-id"); SqlParameterSource namedParams = new MapSqlParameterSource("list_id", listId); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()); UserProteinList userProteinList = template.queryForObject(sql, namedParams, new ProteinListRowMapper()); userProteinList.setAccessions(getAccessionsByListId(listId)); return userProteinList; } @Override public UserProteinList getUserProteinListByPublicId(String publicId) throws DataAccessException { String sql = sqlDictionary.getSQLQuery("read-user-protein-list-by-pubid"); SqlParameterSource namedParams = new MapSqlParameterSource("public_id", publicId); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()); UserProteinList userProteinList = template.queryForObject(sql, namedParams, new ProteinListRowMapper()); userProteinList.setAccessions(getAccessionsByListId(userProteinList.getId())); return userProteinList; } @Override public UserProteinList getUserProteinListByName(String userIdentifier, String listName) throws DataAccessException { String sql = sqlDictionary.getSQLQuery("read-user-protein-list-by-username-listname"); Map<String, String> namedParams = new HashMap<String, String>(); namedParams.put("user_name", userIdentifier); namedParams.put("list_name", listName); UserProteinList userProteinList = new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).queryForObject(sql, namedParams, new ProteinListRowMapper()); userProteinList.setAccessions(getAccessionsByListId(userProteinList.getId())); return userProteinList; } /** * Get the accession numbers that belongs to the list {@code listId} * * @param listId the list identifier * @return a set of proteins */ @Override public Set<String> getAccessionsByListId(long listId) { SqlParameterSource namedParameters = new MapSqlParameterSource("list_id", listId); List<String> accs = new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).queryForList(sqlDictionary.getSQLQuery("read-protein-list-items-by-listid"), namedParameters, String.class); return new HashSet<String>(accs); } @Override public long createUserProteinList(final UserProteinList userProteinList) { final String INSERT_SQL = sqlDictionary.getSQLQuery("create-user-protein-list"); MapSqlParameterSource namedParameters = new MapSqlParameterSource(); namedParameters.addValue("list_name", userProteinList.getName()); namedParameters.addValue("description", userProteinList.getDescription()); namedParameters.addValue("owner_id", userProteinList.getOwnerId()); namedParameters.addValue("public_id", userProteinList.getPublicId()); return JdbcTemplateUtils.insertAndGetKey(INSERT_SQL, "list_id", namedParameters, new NamedParameterJdbcTemplate(dsLocator.getUserDataSource())).longValue(); } @Override public void createUserProteinListItems(final long listId, final Set<String> accessions) { final String INSERT_SQL = sqlDictionary.getSQLQuery("create-protein-list-item"); KeyValuesJdbcBatchUpdater updater = new KeyValuesJdbcBatchUpdater(new JdbcTemplate(dsLocator.getUserDataSource()), listId) { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setString(1, getValue(i)); ps.setLong(2, listId); } }; updater.batchUpdate(INSERT_SQL, new ArrayList<String>(accessions)); } @Override public int deleteProteinListItems(long listId, Set<String> accessions) { if(!accessions.isEmpty()){ final String DELETE_SQL = sqlDictionary.getSQLQuery("delete-protein_list_items"); Map<String, Object> params = new HashMap<String, Object>(); params.put("accession_numbers", accessions); params.put("list_id", listId); return new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).update(DELETE_SQL, params); } return 0; } @Override public int deleteAllProteinListItems(long listId) { final String DELETE_SQL = sqlDictionary.getSQLQuery("delete-all-protein-list-items"); Map<String, Object> params = new HashMap<String, Object>(); params.put("list_id", listId); return new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).update(DELETE_SQL, params); } @Override public void updateUserProteinListMetadata(UserProteinList src) { final String UPDATE_SQL = sqlDictionary.getSQLQuery("update-user-protein-list"); MapSqlParameterSource namedParameters = new MapSqlParameterSource(); // key to identify application to be updated namedParameters.addValue("list_id", src.getId()); // values to update namedParameters.addValue("description", src.getDescription()); namedParameters.addValue("list_name", src.getName()); NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()); int affectedRows = jdbcTemplate.update(UPDATE_SQL, namedParameters); if (affectedRows != 1) { String msg = "oops something wrong occurred" + affectedRows + " rows were affected instead of only 1."; Logger.error(msg); throw new NextProtException(msg); } } @Override public int deleteUserProteinList(long listId) { final String DELETE_SQL = sqlDictionary.getSQLQuery("delete-user-protein-list"); Map<String, Object> params = new HashMap<String, Object>(); params.put("list_id", listId); return new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).update(DELETE_SQL, params); } class ProteinListRowMapper implements ParameterizedRowMapper<UserProteinList> { @Override public UserProteinList mapRow(ResultSet rs, int row) throws SQLException { UserProteinList pl = new UserProteinList(); pl.setId(rs.getLong("list_id")); pl.setName(rs.getString("list_name")); pl.setDescription(rs.getString("description")); pl.setOwnerId(rs.getLong("owner_id")); pl.setOwner(rs.getString("user_name")); pl.setPublicId(rs.getString("public_id")); pl.setEntriesCount(rs.getInt("protCount")); return pl; } } }