@@ -0,0 +1,288 @@
package models
import play .api ._
import play .api .db ._
import play .api .Play .current
import anorm ._
import anorm .SqlParser ._
import java .util .Date
// -- Users
case class User (email : String , name : Option [String ]) {
def myEvents : Seq [Event ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from events
join users on events.author = users.email
join subscribers on subscribers.event_id = events.id
where subscribers.user_email = {myEmail}
"""
).on(
' myEmail -> email
).as(Event .withAuthor * )
}
def mySubjects : Seq [Subject ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from subjects
join users on subjects.author = users.email
join followers on followers.subject_id = subjects.id
where followers.user_email = {myEmail}
"""
).on(
' myEmail -> email
).as(Subject .withAuthor * )
}
}
object User {
val simple = {
get[String ](" users.email" ) ~
get[Option [String ]](" users.name" ) map {
case email ~ name => User (email, name)
}
}
def authenticate (email : String , name : Option [String ] = None ): User = DB .withConnection { implicit connection =>
SQL (
"""
INSERT INTO users (email,name) VALUES ({email},{name})
ON DUPLICATE KEY UPDATE name = {name}
"""
).on(
' email -> email,
' name -> name
).executeUpdate()
User (email, name)
}
def findByEmail (email : String ): Option [User ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from users where email = {email}
"""
).on(
' email -> email
).as(User .simple.singleOpt)
}
}
// -- Subjects
case class Subject (id : Long , title : String , summary : String , imageUrl : Option [String ], author : Option [User ] = None ) {
lazy val slug = utils.Html .stub(title)
def followers : Seq [User ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from users
join followers on followers.user_email = users.email
where followers.subject_id = {id}
"""
).on(
' id -> id
).as(User .simple * )
}
def comments : Seq [Comment ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from comments
join subjects on comments.subject_id = subjects.id
where subjects.id = {id}
"""
).on(
' id -> id
).as(Comment .simple * )
}
}
object Subject {
val simple = {
get[Long ](" subjects.id" ) ~
get[String ](" subjects.title" ) ~
get[String ](" subjects.summary" ) ~
get[Option [String ]](" subjects.imageUrl" ) map {
case id~ title~ summary~ image => Subject (id, title, summary, image)
}
}
val withAuthor = {
simple ~ User .simple map {
case subject~ author => subject.copy(author = Some (author))
}
}
def findAll : Seq [Subject ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from subjects join users on subjects.author = users.email
"""
).as(Subject .withAuthor * )
}
def findById (id : Long ): Option [Subject ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from subjects join users on subjects.author = users.email where subjects.id = {id}
"""
).on(' id -> id).as(Subject .withAuthor.singleOpt)
}
}
// -- Events
case class Event (id : Long , title : String , summary : String , place : String , start : Option [Date ], end : Option [Date ], imageUrl : Option [String ], author : Option [User ] = None ) {
lazy val slug = utils.Html .stub(title)
def subscribers : Seq [User ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from users
join subscribers on subscribers.user_email = users.email
where subscribers.event_id = {id}
"""
).on(
' id -> id
).as(User .simple * )
}
def comments : Seq [Comment ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from comments
join events on comments.event_id = events.id
join users on comments.author = users.email
where events.id = {id}
"""
).on(
' id -> id
).as(Comment .withAuthor * )
}
}
object Event {
val simple = {
get[Long ](" events.id" ) ~
get[String ](" events.title" ) ~
get[String ](" events.summary" ) ~
get[String ](" events.place" ) ~
get[Option [Long ]](" events.start" ) ~
get[Option [Long ]](" events.end" ) ~
get[Option [String ]](" events.imageUrl" ) map {
case id~ title~ summary~ place~ start~ end~ image => Event (id, title, summary, place, start.map(new Date (_)), end.map(new Date (_)), image)
}
}
val withAuthor = {
simple ~ User .simple map {
case event~ author => event.copy(author = Some (author))
}
}
val withAuthorAndSubjects = {
withAuthor ~ Subject .simple map {
case event~ subject => (event,subject)
}
}
def next : Option [Event ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from events where events.start > {now} order by start limit 0,1
"""
).on(' now -> new Date ().getTime()).as(Event .simple.singleOpt)
}
def findAll : Seq [Event ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from events
join users on events.author = users.email
"""
).as(Event .withAuthor * )
}
def findById (id : Long ): Option [(Event ,Seq [Subject ])] = DB .withConnection { implicit connection =>
SQL (
"""
select * from events
join users on events.author = users.email
join events_subjects on events.id = events_subjects.event_id
join subjects on subjects.id = events_subjects.subject_id
where events.id = {id}
"""
).on(' id -> id).as(Event .withAuthorAndSubjects * ).groupBy(_._1).headOption.map {
case (event, eventWithSubjects) => (event, eventWithSubjects.map(_._2))
}
}
}
// -- Comments
case class Comment (id : Long , content : String , date : Date , author : Option [User ] = None )
object Comment {
val simple = {
get[Long ](" comments.id" ) ~
get[String ](" comments.content" ) ~
get[Long ](" comments.postedAt" ) map {
case id~ content~ postedAt => Comment (id, content, new Date (postedAt))
}
}
val withAuthor = {
simple ~ User .simple map {
case comment ~ author => comment.copy(author = Some (author))
}
}
}
// -- Wall
case class Log (date : Date , kind : String , user : User , event : Option [Event ], subject : Option [Subject ])
object Log {
val simple = {
get[Long ](" logs.at" ) ~
get[String ](" logs.kind" ) ~
User .simple ~
(Event .simple? ) ~
(Subject .simple? ) map {
case at~ kind~ user~ event~ subject => Log (new Date (at), kind, user, event, subject)
}
}
def wall : Seq [Log ] = DB .withConnection { implicit connection =>
SQL (
"""
select * from logs
join users on logs.user_id = users.email
left join events on events.id = logs.event_id
left join subjects on subjects.id = logs.subject_id
order by logs.at desc
limit 0, 20
"""
).as(Log .simple * )
}
}