/** @inheritDoc */
  public void applyCommentDefaultsToEntries(Weblog website) throws WebloggerException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("applyCommentDefaults");
    }

    // TODO: Non-standard JPA bulk update, using parameter values in set clause
    Query q = strategy.getNamedUpdate("WeblogEntry.updateAllowComments&CommentDaysByWebsite");
    q.setParameter(1, website.getDefaultAllowComments());
    q.setParameter(2, website.getDefaultCommentDays());
    q.setParameter(3, website);
    q.executeUpdate();
  }
 /** @inheritDoc */
 public void resetAllHitCounts() throws WebloggerException {
   Query q = strategy.getNamedUpdate("WeblogHitCount.updateDailyHitCountZero");
   q.executeUpdate();
 }
  /**
   * This method maintains the tag aggregate table up-to-date with total counts. More specifically
   * every time this method is called it will act upon exactly two rows in the database
   * (tag,website,count), one with website matching the argument passed and one where website is
   * null. If the count ever reaches zero, the row must be deleted.
   *
   * @param name The tag name
   * @param website The website to used when updating the stats.
   * @param amount The amount to increment the tag count (it can be positive or negative).
   * @throws WebloggerException
   */
  private void updateTagCount(String name, Weblog website, int amount) throws WebloggerException {
    if (amount == 0) {
      throw new WebloggerException("Tag increment amount cannot be zero.");
    }

    if (website == null) {
      throw new WebloggerException("Website cannot be NULL.");
    }

    // The reason why add order lastUsed desc is to make sure we keep picking the most recent
    // one in the case where we have multiple rows (clustered environment)
    // eventually that second entry will have a very low total (most likely 1) and
    // won't matter
    TypedQuery<WeblogEntryTagAggregate> weblogQuery =
        strategy.getNamedQuery(
            "WeblogEntryTagAggregate.getByName&WebsiteOrderByLastUsedDesc",
            WeblogEntryTagAggregate.class);
    weblogQuery.setParameter(1, name);
    weblogQuery.setParameter(2, website);
    WeblogEntryTagAggregate weblogTagData;
    try {
      weblogTagData = weblogQuery.getSingleResult();
    } catch (NoResultException e) {
      weblogTagData = null;
    }

    TypedQuery<WeblogEntryTagAggregate> siteQuery =
        strategy.getNamedQuery(
            "WeblogEntryTagAggregate.getByName&WebsiteNullOrderByLastUsedDesc",
            WeblogEntryTagAggregate.class);
    siteQuery.setParameter(1, name);
    WeblogEntryTagAggregate siteTagData;
    try {
      siteTagData = siteQuery.getSingleResult();
    } catch (NoResultException e) {
      siteTagData = null;
    }
    Timestamp lastUsed = new Timestamp((new Date()).getTime());

    // create it only if we are going to need it.
    if (weblogTagData == null && amount > 0) {
      weblogTagData = new WeblogEntryTagAggregate(null, website, name, amount);
      weblogTagData.setLastUsed(lastUsed);
      strategy.store(weblogTagData);

    } else if (weblogTagData != null) {
      weblogTagData.setTotal(weblogTagData.getTotal() + amount);
      weblogTagData.setLastUsed(lastUsed);
      strategy.store(weblogTagData);
    }

    // create it only if we are going to need it.
    if (siteTagData == null && amount > 0) {
      siteTagData = new WeblogEntryTagAggregate(null, null, name, amount);
      siteTagData.setLastUsed(lastUsed);
      strategy.store(siteTagData);

    } else if (siteTagData != null) {
      siteTagData.setTotal(siteTagData.getTotal() + amount);
      siteTagData.setLastUsed(lastUsed);
      strategy.store(siteTagData);
    }

    // delete all bad counts
    Query removeq = strategy.getNamedUpdate("WeblogEntryTagAggregate.removeByTotalLessEqual");
    removeq.setParameter(1, 0);
    removeq.executeUpdate();
  }