dbwatchmanager.java

来自「Jive是基于JSP/JAVA技术构架的一个大型BBS论坛系统,这是Jive论坛」· Java 代码 · 共 484 行 · 第 1/2 页

JAVA
484
字号
        if (isWatched && (isExpirable != expirable)) {            Connection con = null;            PreparedStatement pstmt = null;            try {                con = ConnectionManager.getConnection();                pstmt = con.prepareStatement(UPDATE_WATCH_EXPIRATION);                pstmt.setInt(1, expirable?1:0);                pstmt.setLong(2, user.getID());                pstmt.setLong(3, thread.getID());                pstmt.setInt(4, watchType);                pstmt.executeUpdate();            }            catch( SQLException sqle ) {                sqle.printStackTrace();            }            finally {                try {  pstmt.close();   }                catch (Exception e) { e.printStackTrace(); }                try {  con.close();   }                catch (Exception e) { e.printStackTrace(); }            }            // Remove user's watch list from cache.            StringBuffer key = new StringBuffer(Long.toString(user.getID()));            key.append("-").append(watchType);            factory.cacheManager.watchCache.remove(key.toString());        }    }    public Iterator getWatchedForumThreads(Forum forum, User user, int watchType)    {        return getWatchList(user, watchType).watchedThreads(forum);    }    public Iterator getWatchedForumThreads(User user, int watchType) {        return getWatchList(user, watchType).watchedThreads();    }    public int getWatchCount(Forum forum, User user, int watchType) {        return getWatchList(user, watchType).getWatchCount(forum);    }    public int getWatchCount(User user, int watchType) {        return getWatchList(user, watchType).getWatchCount();    }    public boolean isWatchedThread(User user, ForumThread thread, int watchType) {        return getWatchList(user, watchType).isWatchedThread(thread.getID());    }    /**     * Notifies watches that a thread has been updated. If there are email     * watches, email notifications are sent out.     *     * @param thread the thread that was updated.     * @param message the new message in the thread that triggered the update.     */    protected void notifyWatches(ForumThread thread, ForumMessage message) {        // If watches are turned on.        if (!emailNotifyEnabled) {            return;        }        // Create a new email watch update task that will send out emails to        // any users that have watches on the updated thread.        EmailWatchUpdateTask task = new EmailWatchUpdateTask(this, thread, message);        TaskEngine.addTask(TaskEngine.LOW_PRIORITY, task);    }    /**     * Deletes all watches on a thread. Typically, this method is called when     * deleting a thread from the system. A Connection is passed in so that     * this method can participate in a transaction.     *     * @param thread the ForumThread to remove all watches from.     * @param con a database connection to perform work with.     */    protected void deleteThreadWatches(ForumThread thread, Connection con)            throws SQLException    {        int numRows;        PreparedStatement pstmt = null;        try {            pstmt = con.prepareStatement(DELETE_THREAD_WATCHES);            pstmt.setLong(1,thread.getID());            numRows = pstmt.executeUpdate();        }        finally {            try {  pstmt.close(); }            catch (Exception e) { e.printStackTrace(); }        }        // If any watches were deleted, expire the watch cache. This is        // potentially a "bad" thing if there is a huge number of active users        // looking at their watches, but is a good trade-off for now compared to        // trying to expire individual cache entries.        if (numRows > 0) {            factory.cacheManager.watchCache.clear();        }    }    private WatchList getWatchList(User user, int watchType) {        // Remove user's watch list from cache.        StringBuffer key = new StringBuffer(Long.toString(user.getID()));        key.append("-").append(watchType);        WatchList watchList =                (WatchList)factory.cacheManager.watchCache.get(key.toString());        if (watchList != null) {            return watchList;        }        LongList threadsByDate = new LongList();        BooleanList expirableByDate = new BooleanList();        LongList threadsByForum = new LongList();        LongList forumsByForum = new LongList();        Connection con = null;        PreparedStatement pstmt = null;        try {            con = ConnectionManager.getConnection();            pstmt = con.prepareStatement(ALL_WATCHES);            pstmt.setLong(1, user.getID());            pstmt.setInt(2, watchType);            ResultSet rs = pstmt.executeQuery();            while (rs.next()) {                threadsByDate.add(rs.getLong(1));                expirableByDate.add(rs.getInt(2)==1?true:false);            }            pstmt.close();            pstmt = con.prepareStatement(ALL_WATCHES_BY_FORUM);            pstmt.setLong(1, user.getID());            pstmt.setInt(2, watchType);            rs = pstmt.executeQuery();            while (rs.next()) {                threadsByForum.add(rs.getLong(1));                forumsByForum.add(rs.getLong(2));            }        }        catch( SQLException sqle ) {            sqle.printStackTrace();        }        finally {            try {  pstmt.close();   }            catch (Exception e) { e.printStackTrace(); }            try {  con.close();   }            catch (Exception e) { e.printStackTrace(); }        }        watchList = new WatchList(                threadsByDate.toArray(),                expirableByDate.toArray(),                threadsByForum.toArray(),                forumsByForum.toArray()            );        // Add watch list to cache for next time, then return it.        factory.cacheManager.watchCache.put(key.toString(), watchList);        return watchList;    }    /**     * A task the deletes all watches that are "delatable" and that are attached     * to threads older than a certain value.     *     * The class does not deal with watch cache expiration since that would     * require deletion of the entire cache. Instead, we just let the watch     * objects expire naturally.     */    class DeleteWatchesTask implements Runnable {        public void run() {            long now = System.currentTimeMillis();            long deleteDays = JiveGlobals.DAY * getDeleteDays();            // Get the oldest date as a correctly padded String.            String oldestDate = StringUtils.dateToMillis(new Date(now - deleteDays));            Connection con = null;            PreparedStatement pstmt = null;            boolean abortTransaction = false;            try {                con = ConnectionManager.getTransactionConnection();                // Simple case: database supports sub-selects. This query can be                // slow if many records are affected, but will at least work.                if (ConnectionManager.supportsSubqueries) {                    pstmt = con.prepareStatement(EXPIRE_OLD_WATCHES);                    pstmt.setString(1, oldestDate);                    pstmt.execute();                }                // Complicated case: db doesn't support sub-selects. So, build                // up the "IN" clause ourselves. We'll submit them 100 records                // at a time.                else {                    pstmt = con.prepareStatement(GET_EXPIRED_WATCHES);                    pstmt.setString(1, oldestDate);                    ResultSet rs = pstmt.executeQuery();                    LongList expiredThreads = new LongList();                    while (rs.next()) {                        expiredThreads.add(rs.getLong(1));                    }                    pstmt.close();                    int length = expiredThreads.size();                    // Do nothing if there are no records to delete.                    if (length == 0) {                        return;                    }                    int numBlocks = length / 100;                    for (int i=0; i <= numBlocks; i++) {                        int blockNum = i*100;                        // Build up "IN" SQL statement list.                        StringBuffer buf = new StringBuffer();                        buf.append(expiredThreads.get(blockNum));                        int j=1;                        while (j < 100 && blockNum+j < length) {                            buf.append(",").append(expiredThreads.get(blockNum+j));                            j++;                        }                        // Do db delete.                        String sql = "DELETE FROM jiveWatch WHERE threadID IN (" +                                buf.toString() + ")";                        Statement stmt = con.createStatement();                        stmt.execute(sql);                        stmt.close();                     }                }            }            catch( SQLException sqle ) {                abortTransaction = true;                sqle.printStackTrace();            }            finally {                try {                    if (ConnectionManager.supportsSubqueries) { pstmt.close(); }                }                catch (Exception e) { e.printStackTrace(); }                try {                    ConnectionManager.closeTransactionConnection(con, abortTransaction);                }                catch (Exception e) { e.printStackTrace(); }            }        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?