Skip to content

Instantly share code, notes, and snippets.

@tyrcho
Created March 4, 2013 23:14
Show Gist options
  • Save tyrcho/5086544 to your computer and use it in GitHub Desktop.
Save tyrcho/5086544 to your computer and use it in GitHub Desktop.
play-slick issue : DDL
package models
import scala.slick.session.Database
import Database.threadLocalSession
import play.api.db.slick.Config.driver.simple._
case class Bar(id: Option[Int] = None, name: String)
object Bars extends Table[Bar]("bar") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
// This is the primary key column
def name = column[String]("name")
// Every table needs a * projection with the same type as the table's type parameter
def * = id.? ~ name <> (Bar, Bar.unapply _)
}
package models
import scala.slick.driver.MySQLDriver.simple._
case class DbCard(
name: String,
id: Option[Int] = None)
case class Card(name: String)
object Cards extends Table[DbCard]("card") {
def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
def name = column[String]("name")
def * = name ~ id.? <> (DbCard, DbCard.unapply _)
def idx = index("idx_card_name", name, unique = true)
/**
* Creates the DbCard if the name is new.
* Returns the DbCard id (new or existing).
*/
def createIfNew(c: Card): Int = {
import Database.threadLocalSession
Query(Cards) filter { _.name === c.name } firstOption match {
case None => Cards returning id insert DbCard(c.name)
case Some(existing) => existing.id.get
}
}
}
package models
import scala.slick.driver.MySQLDriver.simple._
case class DbCardList(
cardId: Int,
count: Int,
id: Int)
case class CardData(card: Card, count: Int)
case class CardList(cards: List[CardData]) {
override def toString =
cards map { case CardData(card, count) => s"$count x $card" } mkString "\n"
/**
* Repeats the card names based on their occurence.
*/
def toMultiset: Vector[String] =
cards flatMap (c => Vector.fill(c.count)(c.card.name)) toVector
}
object CardLists extends Table[DbCardList]("card_list") {
def id = column[Int]("id")
def cardId = column[Int]("card_id")
def count = column[Int]("count")
def * = cardId ~ count ~ id <> (DbCardList, DbCardList.unapply _)
def idx = index("idx_card_data_id", (cardId, id), unique = true)
def card = foreignKey("card_fk", cardId, Cards)(_.id)
/**
* Creates all the cards if they do not exist, then the list.
* Return the id of the list.
*/
def create(cl: CardList) = {
import Database.threadLocalSession
assert(cl.cards.nonEmpty, "cannot create an empty card list")
val cardWithIds = cl.cards map { cd => (cd, Cards createIfNew cd.card) }
val (cd, cid) = cardWithIds head;
val listId = Query(CardLists.id.max).first.getOrElse(0) + 1
for ((cd, cid) <- cardWithIds tail)
CardLists insert DbCardList(cid, cd.count, listId)
listId
}
}
package models
import scala.slick.driver.MySQLDriver.simple._
case class DbDeck(
eventId: Int,
mainId: Int,
sideId: Int,
val name: String,
val place: Int,
val player: String,
id: Option[Int] = None)
case class Deck(
main: CardList,
side: CardList,
val name: String,
val place: Int,
val player: String) {
def info: String = s"$name - $player ($place)"
}
object Decks extends Table[DbDeck]("deck") {
def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
def eventId = column[Int]("event_id")
def mainId = column[Int]("main_id")
def sideId = column[Int]("side_id")
def name = column[String]("name")
def place = column[Int]("place")
def player = column[String]("player")
def * = eventId ~ mainId ~ sideId ~ name ~ place ~ player ~ id.? <> (DbDeck, DbDeck.unapply _)
/**
* Creates a deck an associates it with an existing event.
*/
def create(d: Deck, eventId: Int) {
import Database.threadLocalSession
val Seq(mainId, sideId) = Seq(d.main, d.side) map CardLists.create
Decks insert DbDeck(eventId, mainId, sideId, d.name, d.place, d.player)
}
}
package models
import scala.slick.driver.MySQLDriver.simple._
import java.util.Date
import Database.threadLocalSession
case class DbEvent(
name: String,
url: String,
size: Int,
date: Date,
id: Option[Int] = None)
case class Event(
name: String,
url: String,
size: Int,
date: Date,
decks: List[Deck] = List.empty) {
def info = s"$name ($dateString) - $size players"
def dateString = dateFormat.format(date)
}
object Events extends Table[DbEvent]("event") {
def id = column[Int]("id", O.AutoInc, O.PrimaryKey)
def name = column[String]("name")
def url = column[String]("url")
def size = column[Int]("size")
def date = column[Date]("date")
def * = name ~ url ~ size ~ date ~ id.? <> (DbEvent, DbEvent.unapply _)
implicit def eventToDb(e: Event) = DbEvent(e.name, e.url, e.size, e.date)
implicit def eventFromDb(e: DbEvent) = Event(e.name, e.url, e.size, e.date)
def create(e: Event) {
val eventId = Events returning id insert e
for (d <- e.decks) Decks.create(d, eventId)
}
def all: List[Event] =
Query(Events).list map eventFromDb
implicit val dateTypeMapper = MappedTypeMapper.base[java.util.Date, java.sql.Date](
{ jud => new java.sql.Date(jud.getTime) },
{ jsd => jsd })
}
import scala.slick.lifted.MappedTypeMapper
import java.text.SimpleDateFormat
package object models {
lazy val dateFormat = new SimpleDateFormat("dd/MM/yyyy")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment