Skip to content

Commit

Permalink
Merge pull request #665 from mxl/fix-594
Browse files Browse the repository at this point in the history
Fix encoders and decoders for java.util.UUID.
  • Loading branch information
fwbrasil authored Dec 26, 2016
2 parents 4dc5544 + d8d0aee commit 38d4d79
Show file tree
Hide file tree
Showing 38 changed files with 279 additions and 185 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ If the database type is not supported by Quill, it is possible to provide "raw"

```scala
trait UUIDEncodingExample {
val jdbcContext: JdbcContext[PostgresDialect, Literal] // your context should go here
val jdbcContext: PostgresJdbcContext[Literal] // your context should go here

import jdbcContext._

Expand Down Expand Up @@ -1106,7 +1106,7 @@ SQL Contexts
Example:

```scala
lazy val ctx = new JdbcContext[MySQLDialect, SnakeCase]("ctx")
lazy val ctx = new MysqlJdbcContext[SnakeCase]("ctx")
```

#### Dialect
Expand Down Expand Up @@ -1155,7 +1155,7 @@ Additionally, the contexts provide multiple constructors. For instance, with `Jd
```scala
def createDataSource: javax.sql.DataSource with java.io.Closeable = ???

lazy val ctx = new JdbcContext[MySQLDialect, SnakeCase](createDataSource)
lazy val ctx = new MysqlJdbcContext[SnakeCase](createDataSource)
```

##### quill-jdbc
Expand Down Expand Up @@ -1189,7 +1189,7 @@ libraryDependencies ++= Seq(

context definition
```scala
lazy val ctx = new JdbcContext[MySQLDialect, SnakeCase]("ctx")
lazy val ctx = new MysqlJdbcContext[SnakeCase]("ctx")
```

application.properties
Expand All @@ -1216,7 +1216,7 @@ libraryDependencies ++= Seq(

context definition
```scala
lazy val ctx = new JdbcContext[PostgresDialect, SnakeCase]("ctx")
lazy val ctx = new PostgresJdbcContext[SnakeCase]("ctx")
```

application.properties
Expand All @@ -1242,7 +1242,7 @@ libraryDependencies ++= Seq(

context definition
```scala
lazy val ctx = new JdbcContext[SqliteDialect, SnakeCase]("ctx")
lazy val ctx = new SqliteJdbcContext[SnakeCase]("ctx")
```

application.properties
Expand All @@ -1263,7 +1263,7 @@ libraryDependencies ++= Seq(

context definition
```scala
lazy val ctx = new JdbcContext[H2Dialect, SnakeCase]("ctx")
lazy val ctx = new H2JdbcContext[SnakeCase]("ctx")
```

application.properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import com.github.mauricio.async.db.mysql.MySQLConnection
import com.github.mauricio.async.db.mysql.MySQLQueryResult
import com.github.mauricio.async.db.pool.PartitionedConnectionPool
import com.typesafe.config.Config
import io.getquill.context.async.AsyncContext
import io.getquill.context.async.{ AsyncContext, UUIDStringEncoding }
import io.getquill.util.LoadConfig
import com.github.mauricio.async.db.general.ArrayRowData

class MysqlAsyncContext[N <: NamingStrategy](pool: PartitionedConnectionPool[MySQLConnection])
extends AsyncContext[MySQLDialect, N, MySQLConnection](pool) {
extends AsyncContext[MySQLDialect, N, MySQLConnection](pool) with UUIDStringEncoding {

def this(config: MysqlAsyncContextConfig) = this(config.pool)
def this(config: Config) = this(MysqlAsyncContextConfig(config))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import com.github.mauricio.async.db.{ RowData, QueryResult => DBQueryResult }
import com.github.mauricio.async.db.pool.PartitionedConnectionPool
import com.github.mauricio.async.db.postgresql.PostgreSQLConnection
import com.typesafe.config.Config
import io.getquill.context.async.AsyncContext
import io.getquill.context.async.{ AsyncContext, UUIDObjectEncoding }
import io.getquill.util.LoadConfig

class PostgresAsyncContext[N <: NamingStrategy](pool: PartitionedConnectionPool[PostgreSQLConnection])
extends AsyncContext[PostgresDialect, N, PostgreSQLConnection](pool) {
extends AsyncContext[PostgresDialect, N, PostgreSQLConnection](pool) with UUIDObjectEncoding {

def this(config: PostgresAsyncContextConfig) = this(config.pool)
def this(config: Config) = this(PostgresAsyncContextConfig(config))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class PostgresAsyncEncodingSpec extends EncodingSpec {

"returning UUID" in {
val success = for {
uuid <- Await.result(testContext.run(insertBarCode.apply(lift(barCodeEntry))), Duration.Inf)
uuid <- Await.result(testContext.run(insertBarCode(lift(barCodeEntry))), Duration.Inf)
barCode <- Await.result(testContext.run(findBarCodeByUuid(uuid)), Duration.Inf).headOption
} yield {
verifyBarcode(barCode)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package io.getquill.context.async

import java.time.{ LocalDate, LocalDateTime, ZoneId }
import java.util.{ Date, UUID }
import java.util.Date

import com.github.mauricio.async.db.RowData
import io.getquill.util.Messages.fail
import org.joda.time.{ LocalDate => JodaLocalDate, LocalDateTime => JodaLocalDateTime }

Expand All @@ -27,7 +26,7 @@ trait Decoders {
sqlType: DecoderSqlType
): Decoder[T] =
AsyncDecoder[T](sqlType)(new BaseDecoder[T] {
def apply(index: Int, row: RowData) = {
def apply(index: Index, row: ResultRow) = {
row(index) match {
case value: T => value
case value if f.isDefinedAt(value) => f(value)
Expand All @@ -46,7 +45,7 @@ trait Decoders {
})

trait NumericDecoder[T] extends BaseDecoder[T] {
def apply(index: Int, row: RowData) =
def apply(index: Index, row: ResultRow) =
row(index) match {
case v: Byte => decode(v)
case v: Short => decode(v)
Expand All @@ -64,7 +63,7 @@ trait Decoders {

implicit def optionDecoder[T](implicit d: Decoder[T]): Decoder[Option[T]] =
AsyncDecoder(d.sqlType)(new BaseDecoder[Option[T]] {
def apply(index: Int, row: RowData) = {
def apply(index: Index, row: ResultRow) = {
row(index) match {
case null => None
case value => Some(d(index, row))
Expand Down Expand Up @@ -162,11 +161,4 @@ trait Decoders {
)
}, SqlTypes.TIMESTAMP)

implicit val uuidDecoder: Decoder[UUID] =
AsyncDecoder(SqlTypes.UUID)(new BaseDecoder[UUID] {
def apply(index: Int, row: RowData): UUID = row(index) match {
case value: UUID => value
}
})

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.getquill.context.async

import java.time.{ LocalDate, LocalDateTime, ZoneId }
import java.util.{ Date, UUID }
import java.util.Date

import org.joda.time.{ LocalDate => JodaLocalDate, LocalDateTime => JodaLocalDateTime }

Expand Down Expand Up @@ -59,7 +59,6 @@ trait Encoders {
encoder[Date]({ (value: Date) =>
new JodaLocalDateTime(value)
}, SqlTypes.TIMESTAMP)
implicit val uuidEncoder: Encoder[UUID] = encoder[UUID](SqlTypes.UUID)
implicit val localDateEncoder: Encoder[LocalDate] =
encoder[LocalDate]({ (value: LocalDate) =>
new JodaLocalDate(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.getquill.context.async

import java.util.UUID

trait UUIDObjectEncoding {
this: AsyncContext[_, _, _] =>

implicit val uuidEncoder: Encoder[UUID] = encoder[UUID](SqlTypes.UUID)

implicit val uuidDecoder: Decoder[UUID] =
AsyncDecoder(SqlTypes.UUID)(
(index: Index, row: ResultRow) => row(index) match {
case value: UUID => value
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.getquill.context.async

import java.util.UUID

trait UUIDStringEncoding {
this: AsyncContext[_, _, _] =>

implicit val uuidEncoder: Encoder[UUID] = encoder[UUID]((v: UUID) => v.toString, SqlTypes.UUID)

implicit val uuidDecoder: Decoder[UUID] =
AsyncDecoder(SqlTypes.UUID)(
(index: Index, row: ResultRow) => row(index) match {
case value: String => UUID.fromString(value)
}
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.getquill.context.finagle.mysql

import java.time.{ LocalDate, LocalDateTime }
import java.util.Date
import java.util.{ Date, UUID }

import com.twitter.finagle.mysql._
import io.getquill.FinagleMysqlContext
Expand Down Expand Up @@ -35,7 +35,7 @@ trait FinagleMysqlDecoders {
FinangleMysqlDecoder((index, row) => {
row.values(index) match {
case NullValue => None
case other => Some(d.decoder(index, row))
case _ => Some(d.decoder(index, row))
}
})

Expand Down Expand Up @@ -102,4 +102,6 @@ trait FinagleMysqlDecoders {
implicit val localDateTimeDecoder: Decoder[LocalDateTime] = decoder[LocalDateTime] {
case `timestampValue`(v) => v.toLocalDateTime
}

implicit val uuidDecoder: Decoder[UUID] = mappedDecoder(MappedEncoding(UUID.fromString), stringDecoder)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package io.getquill.context.finagle.mysql

import java.sql.Timestamp
import java.time.{ LocalDate, LocalDateTime }
import java.util.Date
import java.util.{ Date, UUID }

import com.twitter.finagle.mysql.CanBeParameter._
import com.twitter.finagle.mysql.Parameter.wrap
Expand Down Expand Up @@ -58,4 +58,5 @@ trait FinagleMysqlEncoders {
implicit val localDateTimeEncoder: Encoder[LocalDateTime] = encoder[LocalDateTime] {
(d: LocalDateTime) => new TimestampValue(dateTimezone, dateTimezone).apply(Timestamp.valueOf(d)): Parameter
}
implicit val uuidEncoder: Encoder[UUID] = mappedEncoder(MappedEncoding(_.toString), stringEncoder)
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class FinaglePostgresEncodingSpec extends EncodingSpec {

"returning UUID" in {
val success = for {
uuid <- Await.result(testContext.run(insertBarCode.apply(lift(barCodeEntry))))
uuid <- Await.result(testContext.run(insertBarCode(lift(barCodeEntry))))
barCode <- Await.result(testContext.run(findBarCodeByUuid(uuid))).headOption
} yield {
verifyBarcode(barCode)
Expand Down
17 changes: 17 additions & 0 deletions quill-jdbc/src/main/scala/io/getquill/H2JdbcContext.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.getquill

import java.io.Closeable
import javax.sql.DataSource

import com.typesafe.config.Config
import io.getquill.context.jdbc.{ JdbcContext, UUIDStringEncoding }
import io.getquill.util.LoadConfig

class H2JdbcContext[N <: NamingStrategy](dataSource: DataSource with Closeable)
extends JdbcContext[H2Dialect, N](dataSource) with UUIDStringEncoding {

def this(config: JdbcContextConfig) = this(config.dataSource)
def this(config: Config) = this(JdbcContextConfig(config))
def this(configPrefix: String) = this(LoadConfig(configPrefix))

}
17 changes: 17 additions & 0 deletions quill-jdbc/src/main/scala/io/getquill/MysqlJdbcContext.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.getquill

import java.io.Closeable
import javax.sql.DataSource

import com.typesafe.config.Config
import io.getquill.context.jdbc.{ JdbcContext, UUIDStringEncoding }
import io.getquill.util.LoadConfig

class MysqlJdbcContext[N <: NamingStrategy](dataSource: DataSource with Closeable)
extends JdbcContext[MySQLDialect, N](dataSource) with UUIDStringEncoding {

def this(config: JdbcContextConfig) = this(config.dataSource)
def this(config: Config) = this(JdbcContextConfig(config))
def this(configPrefix: String) = this(LoadConfig(configPrefix))

}
17 changes: 17 additions & 0 deletions quill-jdbc/src/main/scala/io/getquill/PostgresJdbcContext.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.getquill

import java.io.Closeable
import javax.sql.DataSource

import com.typesafe.config.Config
import io.getquill.context.jdbc.{ JdbcContext, UUIDObjectEncoding }
import io.getquill.util.LoadConfig

class PostgresJdbcContext[N <: NamingStrategy](dataSource: DataSource with Closeable)
extends JdbcContext[PostgresDialect, N](dataSource) with UUIDObjectEncoding {

def this(config: JdbcContextConfig) = this(config.dataSource)
def this(config: Config) = this(JdbcContextConfig(config))
def this(configPrefix: String) = this(LoadConfig(configPrefix))

}
17 changes: 17 additions & 0 deletions quill-jdbc/src/main/scala/io/getquill/SqliteJdbcContext.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.getquill

import java.io.Closeable
import javax.sql.DataSource

import com.typesafe.config.Config
import io.getquill.context.jdbc.{ JdbcContext, UUIDStringEncoding }
import io.getquill.util.LoadConfig

class SqliteJdbcContext[N <: NamingStrategy](dataSource: DataSource with Closeable)
extends JdbcContext[SqliteDialect, N](dataSource) with UUIDStringEncoding {

def this(config: JdbcContextConfig) = this(config.dataSource)
def this(config: Config) = this(JdbcContextConfig(config))
def this(configPrefix: String) = this(LoadConfig(configPrefix))

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import java.time.{ LocalDate, LocalDateTime }
import java.util
import java.util.Calendar

import io.getquill.JdbcContext

import scala.math.BigDecimal.javaBigDecimal2bigDecimal

trait JdbcDecoders {
trait Decoders {
this: JdbcContext[_, _] =>

type Decoder[T] = JdbcDecoder[T]
Expand All @@ -32,10 +30,15 @@ trait JdbcDecoders {
JdbcDecoder(
d.sqlType,
(index, row) => {
val res = d.decoder(index, row)
row.wasNull match {
case true => None
case false => Some(res)
try {
val res = d.decoder(index, row)
if (row.wasNull()) {
None
} else {
Some(res)
}
} catch {
case _: NullPointerException if row.wasNull() => None
}
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import java.time.{ LocalDate, LocalDateTime }
import java.util.{ Calendar, TimeZone }
import java.{ sql, util }

import io.getquill.JdbcContext

import scala.reflect.ClassTag

trait JdbcEncoders {
trait Encoders {
this: JdbcContext[_, _] =>

type Encoder[T] = JdbcEncoder[T]
Expand Down
Loading

0 comments on commit 38d4d79

Please sign in to comment.