5

イメージを Postgres に正しく保存していると思いますが、イメージを読み込もうとすると予期しない結果が発生します。エラーがセーブにあるのかロードにあるのかはよくわかりません。

画像を保存するための私のAnormコードは次のとおりです。

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

}

...「更新が成功しました」と表示されるので、保存が機能していると思います (間違っている可能性があります)。画像をロードするための私のコードは次のとおりです。

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)  //[B@11be1c6 unknown type is [B
        "unknown"
      }
  }
}

}

...期待どおり「Row(image: Array[Byte])」のケースに入るのではなく、「Row(Some(unknown: Any))」のケースに入ります。私のprintln出力 "[B@11be1c6 unknown type is [B"

[B] がどのタイプなのか、どこが間違っているのかわかりません...

4

1 に答える 1

5

Javaのバイト配列(byte[])です。>「どのタイプか分からない[B]」。

match { case Row(Some(image: Array[Byte])) => }この場合、あなたも書くことができます。

または、次のようにすることもできます。

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

...おっと、次のコンパイル エラーが発生しました。

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

残念ながら、scala.Arrayデフォルトではサポートされていません。他のタイプのやり方を真似すれば、うまくいきます。

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

于 2013-01-06T12:39:16.487 に答える