1

I am trying to add a column to an existing model that has an optional image, I am using Scala Slick with the Play Framework. What would be an example of storing a image with a Scala Slick model?

case class Complication(complicationId:Long,
vitalSignId:Long,
complication:String,definition:String,reason:String,
treatment:String,notes:String,
weblinks:String,upperlower:String)


object ComplicationDAO extends Table[Complication]("complications") with DbConn { 

  def complicationId = column[Long]("complication_id", O.PrimaryKey, O.AutoInc)
  def vitalSignId = column[Long]("vital_sign_id") 
  def complication = column[String]("complication")
  def definition = column[String]("definition",O.DBType("varchar(4000)"))
  def reason = column[String]("reason",O.DBType("varchar(4000)"))
  def treatment = column[String]("treatment",O.DBType("varchar(4000)"))
  def notes = column[String]("notes",O.DBType("varchar(4000)")) 
  def weblinks = column[String]("weblinks")
  def upperlower = column[String]("upperlower") 
  def treatmentImage = ??? //here is where it needs to be defined! 
  def * = complicationId ~  vitalSignId ~ complication ~ definition ~ reason ~ treatment ~ notes ~ weblinks ~ upperlower<> (Complication, Complication.unapply _) 

  def autoInc = 
    vitalSignId ~ complication ~ definition ~ reason ~ 
    treatment ~ notes ~ weblinks ~ upperlower <>
    (NewComplication, NewComplication.unapply _) returning complicationId 

}

This is the model that I am trying to integrate an image into.

Thanks for the advice!

Lilluda 5
  • 1,111
  • 3
  • 18
  • 38

1 Answers1

2

If you don't want to actually store it into the DB you can use a url as String field, this example can get you started.

A table for pictures is used:

case class Picture(url: String, id: Option[Int] = None)

trait PictureComponent { this: Profile => //requires a Profile to be mixed in...
  import profile.simple._ //...to be able import profile.simple._ 

  class Pictures(tag: Tag) extends Table[Picture](tag, "PICTURES") {  

    def id = column[Option[Int]]("PIC_ID", O.PrimaryKey, O.AutoInc)
    def url = column[String]("PIC_URL", O.NotNull)

    def * = (url, id) <> (Picture.tupled, Picture.unapply)
  }

  val pictures = TableQuery[Pictures]

  private val picturesAutoInc = pictures returning pictures.map(_.id) into { case (p, id) => p.copy(id = id) }
  def insert(picture: Picture)(implicit session: Session): Picture = picturesAutoInc.insert(picture)
}

And then the user table as an external reference to the picture id:

class Users(tag: Tag) extends Table[(String, Int, Option[Int])](tag, "USERS") {
  def id = column[Option[Int]]("USER_ID", O.PrimaryKey, O.AutoInc)
  def name = column[String]("USER_NAME", O.NotNull)
  def pictureId = column[Int]("PIC_ID", O.NotNull)
  def * = (name, pictureId, id)
}

When inserting you can upload the image, store the url, retrieve the id and assign it to the User entity as external key. To make the external key column nullable you just have to use [column[Option[Int]] instead of column[Int].

Otherwise you could use a Blob field as suggested in a comment, there's a test inside the Slick library with JDBC that creates a table with a Blob field:

class T(tag: Tag) extends Table[(Int, Blob)](tag, "test3") {
  def id = column[Int]("id")
  def data = column[Blob]("data")
  def * = (id, data)
}

val ts = TableQuery[T]

And then to insert:

ts insert (1, new SerialBlob(Array[Byte](1,2,3)))
ts insert (2, new SerialBlob(Array[Byte](4,5)))

Then you can look into java.io.serializable on how to transform a file to bites before storing it into a Blob, this link could help (ignore the sql parts).

Ende Neu
  • 15,581
  • 5
  • 57
  • 68