This library adds support to Twitter's Finagle MySQL client for boilerplate-free transformation of rows into case classes.
To use this library configure your sbt project with the following line:
libraryDependencies += "com.linecorp" %% "finagle-mysql-shapes" % "0.1.0"
This project uses shapeless's generic representation of case classes for automatic derivation of RowDecoder[A]
instances.
Given a client, e.g.:
import com.twitter.finagle.Mysql
val client = Mysql.client.withCredentials(...)
and the following relational schema:
CREATE TABLE users
(
firstName VARCHAR(255), NOT NULL
lastName VARCHAR(255) NOT NULL,
address VARCHAR(255),
fruit ENUM('Melon', 'Mango') NOT NULL,
create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) engine=innodb DEFAULT charset=utf8
Marshalling rows into case classes:
import com.linecorp.finagle.mysql.generic._
case class User(firstName: String, lastName: String, address: Option[String])
val result = client.select("SELECT * FROM users WHERE id = 1") {
row => RowDecoder[User].from(row)
}
For a slightly nicer syntax:
import com.linecorp.finagle.mysql.syntax._
val result = client.select("SELECT * FROM users WHERE id = 1") {
row => row.as[User]
}
A streamlined way of unpacking rows into tuples:
import com.linecorp.finagle.mysql.generic.tuples._
val result = client.select("SELECT * FROM users WHERE id = 1") { row =>
row.as[(String, String)]
}
Decoding ENUM
columns into sealed trait hierarchies:
import com.linecorp.finagle.mysql.generic._
sealed trait Fruit
case object Melon extends Fruit
case object Mango extends Fruit
val result = client.select("SELECT fruit FROM users WHERE id = 4") { row =>
row.get[Fruit](column = "fruit")
}
You can also provide your own instance of RowDecoder[A]
:
import com.linecorp.finagle.mysql.RowDecoder
implicit val decoder: RowDecoder[User] = RowDecoder.instance { row =>
for {
f <- row.get[String]("firstName")
l <- row.get[String]("lastName")
} yield User(f, l)
}
See the RowSpec
integration test suite for more examples.
To parse JSON columns this library provides integration with circe.
import com.linecorp.finagle.mysql.circe._
You can use other JSON libraries by providing an instance of JsonDecoder[A]
:
trait JsonDecoder[A] {
def decode(json: String): Try[A]
}
See CONTRIBUTING.md
Copyright 2019 LINE Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
See LICENSE for more detail.