Created
November 20, 2017 15:26
-
-
Save daddykotex/271550f6c330269fc4fc245ca2ec0c65 to your computer and use it in GitHub Desktop.
If you have a SQL column that allows NULL but you want to fallback to a default rather than using an `Option[T]`, you can define your own composite like that. This is probably nota good way to do it but it works and avoid the throwing of `NonNullableColumnRead`
This file contains 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
import java.sql.{ResultSet, PreparedStatement} | |
import doobie.enum.nullability.Nullable | |
import doobie.imports._ | |
import doobie.util.meta | |
import doobie.util.meta.Meta | |
import doobie.util.kernel.Kernel | |
sealed trait LoginWay { | |
import LoginWay._ | |
def asString: String = this match { | |
case UsernamePassword => "UsernamePassword" | |
case MicrosoftSSO => "MicrosoftSSO" | |
} | |
} | |
object LoginWay { | |
val DefaultValues: NonEmptyList[LoginWay] = NonEmptyList.nels( | |
UsernamePassword, | |
MicrosoftSSO | |
) | |
case object UsernamePassword extends LoginWay | |
case object MicrosoftSSO extends LoginWay | |
def parse(value: String): Option[LoginWay] = value match { | |
case "UsernamePassword" => Some(UsernamePassword) | |
case "MicrosoftSSO" => Some(MicrosoftSSO) | |
case _ => None | |
} | |
} | |
/** | |
https://github.com/tpolecat/doobie/blob/v0.4.4/yax/core/src/main/scala/doobie/util/meta.scala | |
https://github.com/tpolecat/doobie/blob/v0.4.4/yax/core/src/main/scala/doobie/util/kernel.scala | |
https://github.com/tpolecat/doobie/blob/v0.4.4/yax/core/src/main/scala/doobie/util/composite.scala | |
*/ | |
implicit val loginWayComposite: Composite[NonEmptyList[LoginWay]] = { | |
val fromStr: String => NonEmptyList[LoginWay] = { str => | |
Option(str) | |
.map(_.trim) | |
.map(_.split(",").toList.flatMap(x => LoginWay.parse(x.trim).toList)) | |
.flatMap[NonEmptyList[LoginWay]](_.toNel) | |
.getOrElse(LoginWay.DefaultValues) | |
} | |
val toStr: NonEmptyList[LoginWay] => String = _.toList.map(_.asString).mkString(",") | |
val strMeta = Meta[String] | |
new Composite[NonEmptyList[LoginWay]] { | |
val kernel = new Kernel[NonEmptyList[LoginWay]] { | |
type I = NonEmptyList[LoginWay] | |
val ia = (i: I) => i | |
val ai = (a: I) => a | |
val get = (rs: ResultSet, n: Int) => { | |
val i = rs.getString(n) | |
if (rs.wasNull) | |
LoginWay.DefaultValues | |
else | |
fromStr(i) | |
} | |
val set = (ps: PreparedStatement, n: Int, nel: I) => { | |
strMeta.unsafeSetNonNullable(ps, n, toStr(nel)) | |
} | |
val setNull = strMeta.unsafeSetNull _ | |
val update = (rs: ResultSet, n: Int, nel: I) => { | |
strMeta.unsafeUpdateNonNullable(rs, n, toStr(nel)) | |
} | |
val width = 1 | |
} | |
val meta = List((strMeta, Nullable)) | |
val toList = (a: NonEmptyList[LoginWay]) => List(a) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment