Package com.springsource.greenhouse.events

Source Code of com.springsource.greenhouse.events.JdbcEventRepository

/*
/*
* Copyright 2010 the original author or authors.
*
* 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 com.springsource.greenhouse.events;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.joda.time.MutableDateTime;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.JoinRowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.springsource.greenhouse.utils.Location;
import com.springsource.greenhouse.utils.ResourceReference;
import com.springsource.greenhouse.utils.SubResourceReference;

/**
* EventRepository implementation that stores Event data in a relational database using the JDBC API.
* @author Keith Donald
*/
@Repository
public class JdbcEventRepository implements EventRepository {

  private final JdbcTemplate jdbcTemplate;

  @Inject
  public JdbcEventRepository(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
  }

  public List<Event> findUpcomingEvents(Long afterMillis) {
    return jdbcTemplate.query(SELECT_UPCOMING_EVENTS, eventMapper.list(), new Date(afterMillis != null ? afterMillis : System.currentTimeMillis()));
  }
 
  public Event findEventBySlug(String groupSlug, Integer year, Integer month, String slug) {
    return jdbcTemplate.queryForObject(SELECT_EVENT_BY_SLUG, eventMapper.single(), groupSlug, year, month, slug);
  }

  public String findEventSearchString(Long eventId) {
    return jdbcTemplate.queryForObject("select g.hashtag from Event e, MemberGroup g where e.id = ? and e.memberGroup = g.id", String.class, eventId);
  }

  public String findSessionSearchString(Long eventId, Integer sessionId) {
    return jdbcTemplate.queryForObject("select (select g.hashtag from Event e, MemberGroup g where e.id = ? and e.memberGroup = g.id) || ' ' || hashtag from EventSession where event = ? and id = ?", String.class, eventId, eventId, sessionId);
  }

  @Transactional
  public List<EventSession> findSessionsOnDay(Long eventId, LocalDate day, Long attendeeId) {
    DateTimeZone eventTimeZone = DateTimeZone.forID(jdbcTemplate.queryForObject("select timezone from Event where id = ?", String.class, eventId));
    DateTime dayStart = day.toDateTimeAtStartOfDay(eventTimeZone);
    DateTime dayEnd = dayStart.plusDays(1);
    return jdbcTemplate.query(SELECT_SESSIONS_ON_DAY, eventSessionMapper.list(), attendeeId, eventId, dayStart.toDate(), dayEnd.toDate());
  }

  public List<EventSession> findEventFavorites(Long eventId, Long attendeeId) {
    return jdbcTemplate.query(SELECT_EVENT_FAVORITES, eventSessionMapper.list(), eventId, attendeeId, eventId);
  }

  public List<EventSession> findAttendeeFavorites(Long eventId, Long attendeeId) {
    return jdbcTemplate.query(SELECT_ATTENDEE_FAVORITES, eventSessionMapper.list(), attendeeId, eventId);
  }

  @Transactional
  public boolean toggleFavorite(Long eventId, Integer sessionId, Long attendeeId) {
    boolean favorite = jdbcTemplate.queryForObject("select exists(select 1 from EventSessionFavorite where event = ? and session = ? and attendee = ?)", Boolean.class, eventId, sessionId, attendeeId);
    if (favorite) {
      jdbcTemplate.update("delete from EventSessionFavorite where event = ? and session = ? and attendee = ?", eventId, sessionId, attendeeId);
    } else {
      jdbcTemplate.update("insert into EventSessionFavorite (event, session, attendee) values (?, ?, ?)", eventId, sessionId, attendeeId);
    }
    return !favorite;
  }

  @Transactional
  public Float rate(Long eventId, Integer sessionId, Long attendeeId, Rating rating) throws RatingPeriodClosedException {
    if (!isSessionEnded(eventId, sessionId)) {
      throw new RatingPeriodClosedException(eventId, sessionId);
    }
    boolean rated = jdbcTemplate.queryForObject("select exists(select 1 from EventSessionRating where event = ? and session = ? and attendee = ?)", Boolean.class, eventId, sessionId, attendeeId);
    if (rated) {
      jdbcTemplate.update("update EventSessionRating set rating = ?, comment = ? where event = ? and session = ? and attendee = ?", rating.getValue(), rating.getComment(), eventId, sessionId, attendeeId);     
    } else {
      jdbcTemplate.update("insert into EventSessionRating (event, session, attendee, rating, comment) values (?, ?, ?, ?, ?)", eventId, sessionId, attendeeId, rating.getValue(), rating.getComment());     
    }
    Float newAvgRating = jdbcTemplate.queryForObject("select round(avg(cast(rating as double)) * 2, 0) / 2 from EventSessionRating where event = ? and session = ? group by event, session", Float.class, eventId, sessionId);
    jdbcTemplate.update("update EventSession set rating = ? where event = ? and id = ?", newAvgRating, eventId, sessionId);
    return newAvgRating;
  }
 
  @Transactional
  public long addEvent() {
    return 0;
  }
  
  // internal helpers
 
  private boolean isSessionEnded(Long eventId, Integer sessionId) {
    Date endTime = jdbcTemplate.queryForObject("select ts.endTime from EventTimeSlot ts, EventSession s where s.event = ? and s.id = ? and ts.id = s.timeSlot", Date.class, eventId, sessionId);
    return new Date().after(endTime);
  }

  private final JoinRowMapper<Event, Long> eventMapper = new JoinRowMapper<Event, Long>() {
    protected Long mapId(ResultSet rs) throws SQLException {
      return rs.getLong("id");
    }
    protected Event mapRoot(Long id, ResultSet rs) throws SQLException {
      String eventTimeZone = rs.getString("timeZone");
      return new Event(id, rs.getString("title"), DateTimeZone.forID(eventTimeZone), adjustEventTimeToUTC(rs.getTimestamp("startTime"), eventTimeZone), adjustEventTimeToUTC(rs.getTimestamp("endTime"), eventTimeZone),
          rs.getString("slug"), rs.getString("description"), rs.getString("hashtag"), new ResourceReference<String>(rs.getString("groupSlug"), rs.getString("groupName")));
    }
    protected void addChild(Event event, ResultSet rs) throws SQLException {
      event.addVenue(new Venue(rs.getLong("venueId"), rs.getString("venueName"), rs.getString("venuePostalAddress"),
          new Location(rs.getDouble("venueLatitude"), rs.getDouble("venueLongitude")), rs.getString("venueLocationHint")));
    }
  };

  private final JoinRowMapper<EventSession, Integer> eventSessionMapper = new JoinRowMapper<EventSession, Integer>() {
    protected Integer mapId(ResultSet rs) throws SQLException {
      return rs.getInt("id");
    }
    protected EventSession mapRoot(Integer id, ResultSet rs) throws SQLException {
      String eventTimeZone = "America/New_York"; // HACK: For now hard-code to S2GX 2012's value while sorting this out.     
      return new EventSession(id, rs.getString("title"), adjustEventTimeToUTC(rs.getTimestamp("startTime"), eventTimeZone), adjustEventTimeToUTC(rs.getTimestamp("endTime"), eventTimeZone),
          rs.getString("description"), rs.getString("hashtag"), rs.getFloat("rating"), new SubResourceReference<Long, Integer>(rs.getLong("venue"), rs.getInt("room"), rs.getString("roomName")), rs.getBoolean("favorite"));
    }
    protected void addChild(EventSession session, ResultSet rs) throws SQLException {
      session.addLeader(new EventSessionLeader(rs.getString("name")));         
    }
  };
 
  private static DateTime adjustEventTimeToUTC(Timestamp timestamp, String eventTimeZone) {
    MutableDateTime mutableDateTime = new DateTime(timestamp).toMutableDateTime();
    mutableDateTime.setZoneRetainFields(DateTimeZone.forID(eventTimeZone));
    DateTime utcAdjustedDateTime = mutableDateTime.toDateTime().toDateTime(DateTimeZone.UTC);
    return utcAdjustedDateTime;
  }

  private static final String SELECT_FROM_EVENT_SESSION = "select s.id, s.title, ts.startTime, ts.endTime, s.description, s.hashtag, s.rating, s.venue, s.room, r.name as roomName, (f.attendee is not null) as favorite, l.name from EventSession s ";
 
  private static final String SELECT_EVENT = "select e.id, e.title, e.timeZone, e.startTime, e.endTime, e.slug, e.description, g.hashtag, g.slug as groupSlug, g.name as groupName, " +
    "v.id as venueId, v.name as venueName, v.postalAddress as venuePostalAddress, v.latitude as venueLatitude, v.longitude as venueLongitude, v.locationHint as venueLocationHint from Event e " +
    "inner join MemberGroup g on e.memberGroup = g.id " +
    "inner join EventVenue ev on e.id = ev.event " +
    "inner join Venue v on ev.venue = v.id";
   
  private static final String SELECT_UPCOMING_EVENTS = SELECT_EVENT + " where e.endTime > ? order by e.startTime";

  private static final String SELECT_EVENT_BY_SLUG = SELECT_EVENT + " where g.slug = ? and extract(year from e.startTime) = ? and extract(month from e.startTime) = ? and e.slug = ?";

  private static final String SELECT_SESSIONS_ON_DAY = SELECT_FROM_EVENT_SESSION +
    "left outer join VenueRoom r on s.venue = r.venue and s.room = r.id " +
    "left outer join EventSessionFavorite f on s.event = f.event and s.id = f.session and f.attendee = ? " +
    "inner join EventSessionLeader sl on s.event = sl.event and s.id = sl.session " +
    "inner join Leader l on sl.leader = l.id " +
    "inner join EventTimeSlot ts on ts.id = s.timeSlot " +
    "where s.event = ? and ts.startTime >= ? and ts.endTime <= ? " +
    "order by ts.startTime, s.id, sl.rank";

  private static final String SELECT_EVENT_FAVORITES = SELECT_FROM_EVENT_SESSION +
    "inner join (select top 10 session, count(*) as favoriteCount from EventSessionFavorite where event = ? group by session) top on s.id = top.session " +
    "left outer join VenueRoom r on s.venue = r.venue and s.room = r.id " +
    "left outer join EventSessionFavorite f on s.event = f.event and s.id = f.session and f.attendee = ? " +
    "inner join EventSessionLeader sl on s.event = sl.event and s.id = sl.session " +
    "inner join Leader l on sl.leader = l.id " +
    "inner join EventTimeSlot ts on ts.id = s.timeSlot " +
    "where s.event = ? " +
    "order by top.favoriteCount desc, s.id, sl.rank";

  private static final String SELECT_ATTENDEE_FAVORITES = SELECT_FROM_EVENT_SESSION +
    "left outer join VenueRoom r on s.venue = r.venue and s.room = r.id " +
    "inner join EventSessionFavorite f on s.event = f.event and s.id = f.session and f.attendee = ? "
    "inner join EventSessionLeader sl on s.event = sl.event and s.id = sl.session " +
    "inner join Leader l on sl.leader = l.id " +
    "inner join EventTimeSlot ts on ts.id = s.timeSlot " +
    "where s.event = ? " +
    "order by f.rank, s.id, sl.rank";
 
}
TOP

Related Classes of com.springsource.greenhouse.events.JdbcEventRepository

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.