Package ru.org.linux.comment

Source Code of ru.org.linux.comment.CommentDao$DeletedListItem

/*
* Copyright 1998-2014 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.comment;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import ru.org.linux.site.MessageNotFoundException;
import ru.org.linux.user.User;
import ru.org.linux.util.StringUtil;

import javax.sql.DataSource;
import java.sql.*;
import java.util.Date;
import java.util.List;

/**
* Операции над комментариями
*/

@Repository
public class CommentDao {
  private static final Logger logger = LoggerFactory.getLogger(CommentDao.class);

  private static final String queryCommentById = "SELECT " +
    "postdate, topic, userid, comments.id as msgid, comments.title, " +
    "deleted, replyto, edit_count, edit_date, editor_id, " +
    "ua_id, comments.postip " +
    "FROM comments " +
    "WHERE comments.id=?";

  /**
   * Запрос списка комментариев для топика ВКЛЮЧАЯ удаленные
   */
  private static final String queryCommentListByTopicId = "SELECT " +
    "comments.title, topic, postdate, userid, comments.id as msgid, " +
    "replyto, edit_count, edit_date, editor_id, deleted, " +
    "ua_id, comments.postip " +
    "FROM comments " +
    "WHERE topic=? ORDER BY msgid ASC";

  /**
   * Запрос списка комментариев для топика ИСКЛЮЧАЯ удаленные
   */
  private static final String queryCommentListByTopicIdWithoutDeleted = "SELECT " +
    "comments.title, topic, postdate, userid, comments.id as msgid, " +
    "replyto, edit_count, edit_date, editor_id, deleted, " +
    "ua_id, comments.postip " +
    "FROM comments " +
    "WHERE topic=?  AND NOT deleted ORDER BY msgid ASC";

  private static final String replysForCommentCount = "SELECT count(id) FROM comments WHERE replyto=? AND NOT deleted";
  private static final String deleteComment = "UPDATE comments SET deleted='t' WHERE id=? AND not deleted";

  private JdbcTemplate jdbcTemplate;

  @Autowired
  public void setDataSource(DataSource dataSource) {
    jdbcTemplate = new JdbcTemplate(dataSource);
  }

  /**
     * Получить комментарий по id
     *
     * @param id id нужного комментария
     * @return нужный комментарий
     * @throws MessageNotFoundException при отсутствии сообщения
     */
  public Comment getById(int id) throws MessageNotFoundException {
    Comment comment;
    try {
      comment = jdbcTemplate.queryForObject(queryCommentById, (resultSet, i) -> new Comment(resultSet), id);
    } catch (EmptyResultDataAccessException exception) {
      throw new MessageNotFoundException(id);
    }
    return comment;
  }

  /**
     * Список комментариев топика
     *
     * @param topicId     id топика
     * @param showDeleted вместе с удаленными
     * @return список комментариев топика
     */
  public List<Comment> getCommentList(int topicId, boolean showDeleted) {
    if (showDeleted) {
      return jdbcTemplate.query(queryCommentListByTopicId, (resultSet, rownum) -> new Comment(resultSet), topicId);
    } else {
      return jdbcTemplate.query(queryCommentListByTopicIdWithoutDeleted, (resultSet, rownum) -> new Comment(resultSet), topicId);
    }
  }

  /**
     * Удалить комментарий.
     *
     *
   * @param msgid      идентификационнай номер комментария
   * @param reason     причина удаления
   * @param user       пользователь, удаляющий комментарий
   * @return true если комментарий был удалён, иначе false
     */
  public boolean deleteComment(int msgid, String reason, User user) {
    int deleteCount = jdbcTemplate.update(deleteComment, msgid);

    if (deleteCount > 0) {
      logger.info("Удалено сообщение " + msgid + " пользователем " + user.getNick() + " по причине `" + reason + '\'');

      return true;
    } else {
      logger.info("Пропускаем удаление уже удаленного " + msgid);
      return false;
    }
  }

  /**
     * Обновляет статистику после удаления комментариев в одном топике.
     *
     * @param commentId идентификатор любого из удаленных комментариев (обычно корневой в цепочке)
     * @param count     количество удаленных комментариев
     */
  public void updateStatsAfterDelete(int commentId, int count) {
    int topicId = jdbcTemplate.queryForObject("SELECT topic FROM comments WHERE id=?", Integer.class, commentId);

    jdbcTemplate.update("UPDATE topics SET stat1=stat1-?, lastmod=CURRENT_TIMESTAMP WHERE id = ?", count, topicId);
    jdbcTemplate.update("UPDATE topics SET stat2=stat1 WHERE id=? AND stat2 > stat1", topicId);
    jdbcTemplate.update("UPDATE topics SET stat3=stat1 WHERE id=? AND stat3 > stat1", topicId);
    jdbcTemplate.update("UPDATE topics SET stat4=stat1 WHERE id=? AND stat4 > stat1", topicId);
  }

  /**
     * Сколько ответов на комментарий
     *
     * @param msgid id комментария
     * @return число ответов на комментарий
     */
  public int getReplaysCount(int msgid) {
    return jdbcTemplate.queryForObject(replysForCommentCount, Integer.class, msgid);
  }

  /**
   * Массовое удаление комментариев пользователя со всеми ответами на комментарии.
   *
   * @param user пользователь для экзекуции
   * @return список удаленных комментариев
   */
  @Transactional(rollbackFor = Exception.class, propagation = Propagation.MANDATORY)
  public List<Integer> getAllByUserForUpdate(User user) {
    return jdbcTemplate.queryForList("SELECT id FROM comments WHERE userid=? AND not deleted ORDER BY id DESC FOR update",
            Integer.class,
            user.getId()
    );
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.MANDATORY)
  public List<Integer> getCommentsByIPAddressForUpdate(String ip, Timestamp timedelta) {
    return jdbcTemplate.queryForList("SELECT id FROM comments WHERE postip=?::inet AND not deleted AND postdate>? ORDER BY id DESC FOR update",
            Integer.class,
            ip, timedelta);
  }

  /**
   * Добавить новый комментарий.
   *
   * @return идентификационный номер нового комментария
   */
  @Transactional(rollbackFor = Exception.class, propagation = Propagation.MANDATORY)
  public int saveNewMessage(final Comment comment, final String userAgent) {
    final int msgid = jdbcTemplate.queryForObject("select nextval('s_msgid') as msgid", Integer.class);

    jdbcTemplate.execute(
      "INSERT INTO comments (id, userid, title, postdate, replyto, deleted, topic, postip, ua_id) VALUES (?, ?, ?, CURRENT_TIMESTAMP, ?, 'f', ?, ?::inet, create_user_agent(?))",
            (PreparedStatement pst) -> {
              pst.setInt(1, msgid);
              pst.setInt(2, comment.getUserid());
              pst.setString(3, comment.getTitle());
              pst.setInt(5, comment.getTopicId());
              pst.setString(6, comment.getPostIP());
              pst.setString(7, userAgent);

              if (comment.getReplyTo() != 0) {
                pst.setInt(4, comment.getReplyTo());
              } else {
                pst.setNull(4, Types.INTEGER);
              }

              pst.executeUpdate();

              return null;
            }
    );

    return msgid;
  }

  /**
     * Редактирование комментария.
     *
   * @param oldComment  данные старого комментария
   * @param title       новый заголовок
   */
  public void changeTitle(Comment oldComment, String title) {
    jdbcTemplate.update(
      "UPDATE comments SET title=? WHERE id=?", title, oldComment.getId()
    );
  }

  /**
     * Обновить информацию о последнем редакторе комментария.
     *
     * @param id        идентификационный номер комментария
     * @param editorId  идентификационный номер редактора комментария
     * @param editDate  дата редактирования
     * @param editCount количество исправлений
     */
  public void updateLatestEditorInfo (int id, int editorId, Date editDate, int editCount) {
    jdbcTemplate.update(
      "UPDATE comments set editor_id = ? , edit_date = ?, edit_count = ? WHERE id = ?",
      editorId,
      new Timestamp(editDate.getTime()),
      editCount,
      id
    );
  }

  /**
     * Получить список последних удалённых комментариев пользователя.
     *
     * @param userId идентификационный номер пользователя
     * @return список удалённых комментариев пользователя
     */
  public List<DeletedListItem> getDeletedComments(int userId) {
    return jdbcTemplate.query(
      "SELECT " +
        "sections.name as ptitle, groups.title as gtitle, topics.title, topics.id as msgid, del_info.reason, deldate, bonus, comments.id as cid " +
        "FROM sections, groups, topics, comments, del_info " +
        "WHERE sections.id=groups.section " +
        "AND groups.id=topics.groupid " +
        "AND comments.topic=topics.id " +
        "AND del_info.msgid=comments.id " +
        "AND comments.userid=? " +
        "AND del_info.delby!=comments.userid " +
        "ORDER BY del_info.delDate DESC NULLS LAST, del_info.msgid DESC LIMIT 20",
            (rs, rowNum) -> new DeletedListItem(rs),
      userId
    );
  }

  /**
   * DTO-класс, описывающий данные удалённого комментария
   */
  public static class DeletedListItem {
    private final String ptitle;
    private final String gtitle;
    private final int msgid;
    private final String title;
    private final String reason;
    private final Timestamp delDate;
    private final int bonus;
    private final int cid;

    public DeletedListItem(ResultSet rs) throws SQLException {
      ptitle = rs.getString("ptitle");
      gtitle = rs.getString("gtitle");
      msgid = rs.getInt("msgid");
      title = StringUtil.makeTitle(rs.getString("title"));
      reason = rs.getString("reason");
      delDate = rs.getTimestamp("deldate");
      bonus = rs.getInt("bonus");
      cid = rs.getInt("cid");
    }

    public String getPtitle() {
      return ptitle;
    }

    public String getGtitle() {
      return gtitle;
    }

    public int getMsgid() {
      return msgid;
    }

    public String getTitle() {
      return title;
    }

    public String getReason() {
      return reason;
    }

    public Timestamp getDelDate() {
      return delDate;
    }

    public int getBonus() {
      return bonus;
    }

    public int getCommentId() {
      return cid;
    }
  }
}
TOP

Related Classes of ru.org.linux.comment.CommentDao$DeletedListItem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.