thefactory/finagle-postgres — pull request #6 by vkostyukov (2014-05-29 13:19:49+00:00)
Title: Introduces RowReader (Reader Monad)

Hi all!

First of all thank you guys for working on the `finagle-postgres` codec. We've been using your fork `thefactory` in our startup based in Russia for a while. Everything works fine! We've just wanted share with you a tiny useful class that we use in our project.

This PR introduces three entities `RowReader`, `RequiredField` and `OptionalField`. These classes implement Reader Monad pattern and might be slightly used in for-comprehension. Here is the example on how these classes allow the developer build reusable and com posable readers over the postgres row.

For instance, we want to fetch clients for the DB, but sometimes we need just a basic info (like name and age). We can define a `SmallClient` reader for this.

```scala
val SmallClient = for {
name <- RequiredField[String]("name")
age <- OptionalField[Int]("age")
} yield (name, age.getOrElse(100))
```

This defines a new reader, so we pass a row to it and fetch client:

```scala
for {
reply <- client.select("*") { row => SmallClient(row) } // Seq[(String, Int)]
} yield reply
```

Now we want to define a richer client reader that fetches an additional field `city`. We can do that like this:

```scala
val BigClient = for {
(name, age) = SmallClient
city <- RequiredField[String]("city")
} yield (name, age, city)
```

And use it in the same manner.

Thanks again! Hope you will find this style interesting.