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 + -
显示快捷键?