Created
November 19, 2015 00:02
-
-
Save dbousamra/62a07ce36a4bb643f672 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| object DoobieHelpers { | |
| /* | |
| * See: https://tpolecat.github.io/doobie-0.2.0/10-Custom-Mappings.html | |
| * | |
| * Some modern databases support a json column type that can store structured data as a JSON document, along with | |
| * various SQL extensions to allow querying and selecting arbitrary sub-structures. So an obvious thing we might | |
| * want to do is provide a mapping from Scala model objects to JSON columns, via some kind of JSON serialization | |
| * library. | |
| * | |
| * We can construct a Meta instance for the argonaut Json type by using the Meta.other constructor, which constructs | |
| * a direct object mapping via JDBC's .getObject and .setObject. In the case of PostgreSQL the JSON values are | |
| * marshalled via the PGObject type, which encapsulates an uninspiring (String, String) pair representing the schema | |
| * type and its string value. | |
| */ | |
| implicit val JsonMeta: Meta[Json] = | |
| Meta.other[PGobject]("json").nxmap[Json]( | |
| a => Parse.parse(a.getValue).leftMap[Json](sys.error).merge, // failure raises an exception | |
| a => new PGobject <| (_.setType("json")) <| (_.setValue(a.nospaces)) | |
| ) | |
| /* | |
| * Given this mapping to and from Json we can construct a further mapping to any type that has a CodecJson instance. | |
| * The nxmap constrains us to reference types and requires a TypeTag for diagnostics, so the full type constraint | |
| * is A >: Null : CodecJson: TypeTag. On failure we throw an exception; this indicates a logic or schema problem. | |
| */ | |
| def codecMeta[A >: Null : DecodeJson : EncodeJson : TypeTag]: Meta[A] = { | |
| Meta[Json].nxmap[A](x => { | |
| x.as[A].result.fold(p => { | |
| sys.error(p._1) | |
| }, identity) | |
| }, | |
| _.asJson | |
| ) | |
| } | |
| /* | |
| * Tells Doobie how to work with Joda Time instants. | |
| */ | |
| // implicit val JodaInstantMeta = codecMeta[Instant] | |
| implicit val DateTimeMeta: Meta[Instant] = | |
| Meta[java.sql.Timestamp].nxmap( | |
| ts => new Instant(ts.getTime), | |
| dt => new java.sql.Timestamp(dt.getMillis) | |
| ) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment