Slick / onSave / updated, created - Valraiso

22 views
Skip to first unread message

Guillaume Badin

unread,
Jan 9, 2015, 5:41:50 AM1/9/15
to scala-lyon...@googlegroups.com
Bonjour les lyonnais, 

Petite question pratique sous Slick,  

nous sommes en train de refaire toutes notre architecture sous Scala Slick / Maria DB. 

Sur mes tables j'aimerais placer des comportements communs comme les champs created, updated mis à jour automatiquement sur mes tables. 

Pour faire ceci j'ai donc fait un Table Commune pour la base de donnée. 

abstract class TableLaboratoryAble[T](tag: Tag, name: String) extends Table[T](tag, name) {


 
/**
   * ID
   */
  val id: Column[Long] = column[Long]("id", O.PrimaryKey, O.AutoInc)

 
/** LaboratoryId **/
  val laboratoryId: Column[Long] = column[Long]("laboratory_id", O.NotNull)


 
/** LaboratoryId FK and INDEX **/
  lazy val laboratoryFk = foreignKey("LAB_FK_" + name, laboratoryId :: HNil, LaboratoryQueries.instance)(r => r.id :: HNil, onUpdate = ForeignKeyAction.NoAction, onDelete = ForeignKeyAction.NoAction)
 
val index1 = index("LAB_INDEX_" + name, laboratoryId :: HNil)


 
/** TemporalAble **/

  def temporal = (created, updated) <>((Temporal.apply _).tupled, Temporal.unapply)

 
val created: Column[DateTime] = column[DateTime]("created")
 
val updated: Column[DateTime] = column[DateTime]("updated")

}


Ensuite je me suis fait une case Class commune qui va avoir les champs communs created, updated.  

case class Temporal(created:DateTime, updated:DateTime)


Mon problème vient du fait que lorsque je fait des méthodes générique d'insertion je ne peux pas utiliser la méthode copy des case class du coup je suis obligé d'overrider une méthode onSave à chaque fois pour mes case classe finale. 

case class Crud(implicit currentLaboId: Long, session: Session) {


 
def query =
    _tableReference
.filter(_.laboratoryId === currentLaboId)

 
def insert(row: A) = {
    _tableReference
.insert(row.onSave)
 
}
}


Et voici la case class Finale : 
case class LaboratoryConfigRow(id:Long,laboratoryId:Long,
                               temporal
: Temporal) extends TemporalAble[LaboratoryConfigRow] {



 
override def onSave = this.copy(temporal = Temporal.updatedAt(this.temporal))

}



Si quelqu'un à une idée pour améliorer la chose (Ne pas être obligé de overrider la méthode à chaque fois)  ça serait vraiment super. 






 



Jean Helou

unread,
Jan 9, 2015, 8:36:07 AM1/9/15
to Guillaume Badin, scala-lyon...@googlegroups.com
Avec un trait : 

UbiTemporal[T]{
  self: TemporalAble[T] => 
  override def onSave = this.copy(temporal = Temporal.updatedAt(this.temporal))
}
ou 
UbiTemporal[T] extends TemporalAble[T]{
 override def onSave = this.copy(temporal = Temporal.updatedAt(this.temporal))  
}
et tu mixes ça  au lieu de TemporalAble ?

c'est quoi comme type TemporalAble ? un abstract class aussi ?

jean


--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "Scala Lyon User Group".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse scala-lyon-user-...@googlegroups.com.
Pour obtenir davantage d'options, consultez la page https://groups.google.com/d/optout.

Guillaume Badin

unread,
Jan 9, 2015, 8:47:53 AM1/9/15
to Jean Helou, scala-lyon...@googlegroups.com
Pour l'intant TemporalAble c'est un trait.


trait TemporalAble[A] {
val temporal: Temporal
def onSave:A
}





Cordialement
--
Guillaume Badin
Co-Founder / CTO @ UBILAB
---------------------------------------
---------------------------------------
Ligne directe: +33(0)4.82.53.53.35 
---------------------------------------

Guillaume Badin

unread,
Jan 9, 2015, 8:53:55 AM1/9/15
to Jean Helou, scala-lyon...@googlegroups.com
En fait le problème c'est que le trait ne reconnait pas le copy de la case class. 

Y a t'il un moyen de dire que c'est une case classe au niveau du type ? 


trait UbeTemporal[T <: TemporalAble[T]] {
self:T =>

override def onSave = this.copy(temporal = Temporal.updatedAt(this.temporal))
}
Cordialement
--
Guillaume Badin
Co-Founder / CTO @ UBILAB
---------------------------------------
---------------------------------------
Ligne directe: +33(0)4.82.53.53.35 
---------------------------------------

Jean Helou

unread,
Jan 9, 2015, 9:01:49 AM1/9/15
to Guillaume Badin, scala-lyon...@googlegroups.com
hmm bien sur, 

non il n'y a pas moyen et tu ne peux pas utiliser le structural typing pour contourner ça. Sans y réfléchir plus je ne vois qu'une macro qui identifie toutes les case classe qui mixent TemporalAble et qui crée la méthode override onSave si elle n'existe pas déjà. 

jean 

Guillaume Badin

unread,
Jan 9, 2015, 9:03:48 AM1/9/15
to Jean Helou, scala-lyon...@googlegroups.com
C'est un peu la conclusion ou j'en étais arrivé et la macro c'est un peu overkill, En tout cas merci pour l'effort :-). 


Cordialement
--
Guillaume Badin
Co-Founder / CTO @ UBILAB
---------------------------------------
---------------------------------------
Ligne directe: +33(0)4.82.53.53.35 
---------------------------------------

Reply all
Reply to author
Forward
0 new messages