/* * Copyright 1998-2016 Linux.org.ru * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ru.org.linux.spring.dao; import com.google.common.base.Preconditions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import ru.org.linux.site.DeleteInfo; import ru.org.linux.user.User; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.sql.DataSource; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; /** * Получение информации кем и почему удален топик */ @Repository public class DeleteInfoDao { private JdbcTemplate jdbcTemplate; private static final String QUERY_DELETE_INFO = "SELECT reason,delby as userid, deldate, bonus FROM del_info WHERE msgid=?"; private static final String QUERY_DELETE_INFO_FOR_UPDATE = "SELECT reason,delby as userid, deldate, bonus FROM del_info WHERE msgid=? FOR UPDATE"; private static final String INSERT_DELETE_INFO = "INSERT INTO del_info (msgid, delby, reason, deldate, bonus) values(?,?,?, CURRENT_TIMESTAMP, ?)"; @Autowired public void setJdbcTemplate(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); } /** * Кто, когда и почему удалил сообщение * @param id id проверяемого сообщения * @return информация о удаленном сообщении */ @Nullable public DeleteInfo getDeleteInfo(int id) { return getDeleteInfo(id, false); } /** * Кто, когда и почему удалил сообщение * @param id id проверяемого сообщения * @param forUpdate блокировать запись до конца текущей транзакции (SELECT ... FOR UPDATE) * @return информация о удаленном сообщении */ public DeleteInfo getDeleteInfo(int id, boolean forUpdate) { List<DeleteInfo> list = jdbcTemplate.query( forUpdate?QUERY_DELETE_INFO_FOR_UPDATE:QUERY_DELETE_INFO, (resultSet, i) -> { Integer bonus = resultSet.getInt("bonus"); if (resultSet.wasNull()) { bonus = null; } return new DeleteInfo( resultSet.getInt("userid"), resultSet.getString("reason"), resultSet.getTimestamp("deldate"), bonus ); }, id); if (list.isEmpty()) { return null; } else { return list.get(0); } } public void insert(int msgid, User deleter, String reason, int scoreBonus) { Preconditions.checkArgument(scoreBonus <= 0, "Score bonus on delete must be non-positive"); jdbcTemplate.update(INSERT_DELETE_INFO, msgid, deleter.getId(), reason, scoreBonus); } public void insert(final List<InsertDeleteInfo> deleteInfos) { if (deleteInfos.isEmpty()) { return; } jdbcTemplate.batchUpdate(INSERT_DELETE_INFO, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { InsertDeleteInfo info = deleteInfos.get(i); ps.setInt(1, info.getMsgid()); ps.setInt(2, info.getDeleteUser()); ps.setString(3, info.getReason()); ps.setInt(4, info.getBonus()); } @Override public int getBatchSize() { return deleteInfos.size(); } }); } public static class InsertDeleteInfo { private final int msgid; private final String reason; private final int bonus; private final int deleteUser; public InsertDeleteInfo(int msgid, @Nonnull String reason, int bonus, int deleteUser) { Preconditions.checkArgument(bonus <= 0, "Score bonus on delete must be non-positive"); this.msgid = msgid; this.reason = reason; this.bonus = bonus; this.deleteUser = deleteUser; } public int getMsgid() { return msgid; } public String getReason() { return reason; } public int getBonus() { return bonus; } public int getDeleteUser() { return deleteUser; } } }