package wbbs.service;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import wbbs.domain.Board;
import wbbs.domain.BoardCategory;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
@Singleton
public class BoardService {
LinkedHashMap<Integer, BoardCategory> categories;
Map<Integer, Board> boards;
final Map<Integer, Integer> boardTopicCountMap = new HashMap<Integer, Integer>();
final Map<Integer, Integer> boardReplyCountMap = new HashMap<Integer, Integer>();
@Inject
QueryRunner qr;
void prepare() throws SQLException {
if (categories == null) {
List<BoardCategory> categoryList = qr.query("select * from BoardCategory order by seq", new BeanListHandler<BoardCategory>(BoardCategory.class));
List<Board> boardList = qr.query("select * from Board order by seq", new BeanListHandler<Board>(Board.class));
categories = new LinkedHashMap<Integer, BoardCategory>();
for (BoardCategory category : categoryList) {
categories.put(category.id, category);
for (Board board : boardList) {
if (board.boardCategoryId == category.id) {
category.boards.add(board);
board.category = category;
}
}
}
boards = new HashMap<Integer, Board>();
for (Board board : boardList) {
boards.put(board.id, board);
}
}
for (Map.Entry<Integer, Board> entry : boards.entrySet()) {
Board board = entry.getValue();
board.topicCount = getBoardTopicCount(board.id);
board.replyCount = getBoardReplyCount(board.replyCount);
board.masterIds = qr.query("select masterId from BoardMaster where boardId=?", new ColumnListHandler<String>(), board.id);
}
}
synchronized public List<BoardCategory> listCategories() throws SQLException {
prepare();
return new ArrayList<BoardCategory>(categories.values());
}
synchronized public Board findBoard(int id) throws SQLException {
prepare();
return boards.get(id);
}
public BoardCategory findCategory(int id) throws SQLException {
prepare();
return categories.get(id);
}
synchronized public void insertCategory(BoardCategory category) throws SQLException {
Connection con = qr.getDataSource().getConnection();
try {
qr.update(con, "insert into BoardCategory(name, remark, seq) values(?, ?, ?)", category.name, category.remark, category.seq);
category.id = qr.query(con, "call identity()", new ScalarHandler<Number>()).intValue();
} finally {
con.close();
}
categories = null;
}
synchronized public void updateCategory(BoardCategory category) throws SQLException {
qr.update("update BoardCategory set name=?, remark=?, seq=? where id=?", category.name, category.remark, category.seq, category.id);
categories = null;
}
synchronized public void insertBoard(Board board) throws SQLException {
Connection con = qr.getDataSource().getConnection();
try {
qr.update(con, "insert into Board(name, remark, boardCategoryId, seq) values(?, ?, ?, ?)", board.name, board.remark, board.boardCategoryId, board.seq);
board.id = qr.query(con, "call identity()", new ScalarHandler<Number>()).intValue();
} finally {
con.close();
}
categories = null;
}
synchronized public void updateBoard(Board board) throws SQLException {
qr.update("update Board set name=?, remark=?, seq=? where id=?", board.name, board.remark, board.seq, board.id);
categories = null;
}
public int getBoardTopicCount(int boardId) throws SQLException {
synchronized (boardTopicCountMap) {
Integer count = boardTopicCountMap.get(boardId);
if (count == null) {
count = qr.query("select count(*) from Topic where boardId=?", new ScalarHandler<Number>(), boardId).intValue();
boardTopicCountMap.put(boardId, count);
}
return count;
}
}
public void changeBoardTopicCount(int boardId, int dx) {
synchronized (boardTopicCountMap) {
Integer count = boardTopicCountMap.get(boardId);
if (count != null) {
boardReplyCountMap.put(boardId, count + dx);
}
}
}
public int getBoardReplyCount(int boardId) throws SQLException {
synchronized (boardReplyCountMap) {
Integer count = boardReplyCountMap.get(boardId);
if (count == null) {
count = qr.query("select count(*) from Reply join Topic on Reply.topicId=Topic.id where boardId=?", new ScalarHandler<Number>(), boardId).intValue();
boardReplyCountMap.put(boardId, count);
}
return count;
}
}
public void changeBoardReplyCount(int boardId, int dx) {
synchronized (boardReplyCountMap) {
Integer count = boardReplyCountMap.get(boardId);
if (count != null) {
boardReplyCountMap.put(boardId, count + dx);
}
}
}
public void modifyBoardTopicCount(int boardId, int d) {
synchronized (boardTopicCountMap) {
Integer count = boardTopicCountMap.get(boardId);
if (count != null) {
boardTopicCountMap.put(boardId, count + d);
}
}
}
public void modifyBoardReplyCount(int boardId, int d) {
synchronized (boardReplyCountMap) {
Integer count = boardReplyCountMap.get(boardId);
if (count != null) {
boardReplyCountMap.put(boardId, count + d);
}
}
}
}