2013-01-06 14 views
5

Penso di salvare l'immagine in Postgres correttamente, ma di ottenere risultati imprevisti cercando di caricare l'immagine. Non so davvero se l'errore è in salvataggio o in caricamento.Salvataggio/caricamento di immagini in Postgres con Anorm (Scala/PlayFramework 2)

Ecco il mio codice Anorm per salvare l'immagine:

def storeBadgeImage(badgeHandle: String, imgFile: File) = { 
    val cmd = """ 
     |update badge 
     |set img={imgBytes} 
     |where handle = {badgeHandle} 
    """ 
    var fis = new FileInputStream(imgFile) 
    var imgBytes: Array[Byte] = Resource.fromInputStream(fis).byteArray 
    // at this point I see the image in my browser if I return the imgBytes in the HTTP response, so I'm good so far. 
    DB.withConnection { implicit c => 
    { 
    try { 
     SQL(cmd stripMargin).on("badgeHandle" -> badgeHandle, "imgBytes" -> imgBytes).executeUpdate() match { 
     case 0 => "update failed for badge " + badgeHandle + ", image " + imgFile.getCanonicalPath 
     case _ => "Update Successful" 
     } 
    } catch { 
     case e: SQLException => e.toString() 
    } 
    } 
} 

}

... ho "aggiornamento di successo", in modo da presumo il salvataggio sta funzionando (potrei sbagliarmi). Ecco il mio codice per caricare l'immagine:

def fetchBadgeImage(badgeHandle: String) = { 
    val cmd = """ 
     |select img from badge 
     |where handle = {badgeHandle} 
    """ 
    DB.withConnection { implicit c => 
    SQL(cmd stripMargin).on("badgeHandle" -> badgeHandle)().map { 
     case Row(image: Array[Byte]) => { 
     "image = " + image 
     } 
     case Row(Some(unknown: Any)) => { 
     println(unknown + " unknown type is " + unknown.getClass.getName) //[[email protected] unknown type is [B 
     "unknown" 
     } 
    } 
} 

}

... piuttosto che andare in caso "Row (immagine: Array [Byte])" come sperato, va in "Riga (Alcuni (sconosciuto: Qualsiasi)) "caso. Le mie uscite println "[B @ 11be1c6 tipo sconosciuto è [B"

Non so che tipo [B è o dove forse ho sbagliato ...

risposta

5

Si tratta di una serie di byte in Java (byte[]). > "Non so che tipo [B".

E in questo caso è possibile scrivere anche match { case Row(Some(image: Array[Byte])) => } e questo potrebbe essere migliore.

Oppure si potrebbe essere in grado di farlo come segue.

val results: Stream[Array[Byte]] = SQL(cmd stripMargin) 
    .on("badgeHandle" -> "name")().map { row => row[Array[Byte]]("img") } 

... Oops, ha ottenuto il seguente errore di compilazione.

<console>:43: error: could not find implicit value for parameter c: anorm.Column[Array[Byte]] 
      val res: Stream[Array[Byte]] = SQL(cmd stripMargin).on("badgeHandle" -> "name")().map { row => row[Array[Byte]]("img") } 

Sfortunatamente, scala.Array non è supportato per impostazione predefinita. Se imiti il ​​modo di altri tipi, funziona.

implicit def rowToByteArray: Column[Array[Byte]] = { 
    Column.nonNull[Array[Byte]] { (value, meta) => 
    val MetaDataItem(qualified, nullable, clazz) = meta 
    value match { 
     case bytes: Array[Byte] => Right(bytes) 
     case _ => Left(TypeDoesNotMatch("...")) 
    } 
    } 
} 
val results: Stream[Array[Byte]] = SQL(cmd stripMargin) 
    .on("badgeHandle" -> "name")().map { row => row[Array[Byte]]("img") } 

https://github.com/playframework/Play20/blob/master/framework/src/anorm/src/main/scala/anorm/Anorm.scala

+0

Grazie, Kazuhiro. Ho preso la prima opzione per abbinare "Row (Some (image: Array [Byte]))". Mi sono sentito un po 'sciocco a fare un errore così ovvio. Grazie ancora. –