2013-01-06 8 views
5

Myślę, że zapisuję obraz w Postgreycie poprawnie, ale otrzymuję nieoczekiwane wyniki próbujące załadować obraz. Naprawdę nie wiem, czy błąd jest zapisany, czy załadowany.Zapisywanie/ładowanie obrazów w Postgreycie przy użyciu Anorm (Scala/PlayFramework 2)

Oto mój kod Anorm do zapisywania obrazu:

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() 
    } 
    } 
} 

}

... otrzymuję „aktualizacji udany”, więc przypuszczam Zapisz pracuje (mogę się mylić). Tu jest mój kodu do ładowania obrazu:

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" 
     } 
    } 
} 

}

... zamiast wchodzenia w sprawie "Row (zdjęcie: Array [bajt])", jak się spodziewano, to idzie do „Row (Some (unknown: Any)) "Sprawa. Moi wyjścia println „[B @ 11be1c6 nieznanego typu jest [B”

nie wiem jaki typ [B jest lub gdzie mogę pójść źle ...

Odpowiedz

5

To tablicę bajtów w Javie (bajt[]). > "Nie wiem, jaki typ [B".

Możesz również napisać match { case Row(Some(image: Array[Byte])) => } w tym przypadku i może być lepiej.

Albo możesz to zrobić w następujący sposób.

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

... Ups, wystąpił następujący błąd kompilacji.

<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") } 

Niestety, scala.Array nie jest obsługiwany domyślnie. Jeśli naśladujesz drogę innych typów, to działa.

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

Dziękuję, Kazuhiro. Zastosowałem pierwszą opcję, aby dopasować "Wiersz (Some (image: Array [Byte]))". Czułem się trochę głupio robiąc tak oczywisty błąd. Dzięki jeszcze raz. –