Skip to content

Commit

Permalink
code refactoring for code gen support
Browse files Browse the repository at this point in the history
  • Loading branch information
tminglei committed Jul 10, 2016
1 parent e8a05a7 commit 3b4123f
Show file tree
Hide file tree
Showing 19 changed files with 202 additions and 161 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
package com.github.tminglei.slickpg

import slick.jdbc.{JdbcType, PositionedResult, PostgresProfile}
import scala.reflect.classTag

trait PgArgonautSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTypes { driver: PostgresProfile =>
import driver.api._
import argonaut._, Argonaut._

///---
def pgjson: String
///---

trait ArgonautCodeGenSupport {
// register types to let `ExModelBuilder` find them
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[Json])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[Json])
}
}

/// alias
trait JsonImplicits extends ArgonautJsonImplicits

trait ArgonautJsonImplicits {
trait ArgonautJsonImplicits extends ArgonautCodeGenSupport {
implicit val argonautJsonTypeMapper: JdbcType[Json] =
new GenericJdbcType[Json](
pgjson,
Expand All @@ -29,17 +40,9 @@ trait PgArgonautSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTyp
}
}

trait ArgonautJsonPlainImplicits {
trait ArgonautJsonPlainImplicits extends ArgonautCodeGenSupport {
import utils.PlainSQLUtils._

import scala.reflect.classTag

// used to support code gen
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[Json])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[Json])
}

implicit class PgJsonPositionedResult(r: PositionedResult) {
def nextJson() = nextJsonOption().getOrElse(jNull)
def nextJsonOption() = r.nextStringOption().flatMap(_.parse.toOption)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
package com.github.tminglei.slickpg

import slick.jdbc.{JdbcType, PositionedResult, PostgresProfile}
import scala.reflect.classTag

trait PgCirceJsonSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTypes { driver: PostgresProfile =>
import driver.api._
import io.circe._
import io.circe.generic.auto._
import io.circe.parser._
import io.circe.syntax._

///---
def pgjson: String
///---

trait CirceCodeGenSupport {
// register types to let `ExModelBuilder` find them
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[Json])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[Json])
}
}

trait JsonImplicits extends CirceImplicits

trait CirceImplicits {
trait CirceImplicits extends CirceCodeGenSupport {
implicit val circeJsonTypeMapper: JdbcType[Json] =
new GenericJdbcType[Json](
pgjson,
(v) => parse(v).getOrElse(Json.Empty),
(v) => parse(v).getOrElse(Json.Null),
(v) => v.asJson.spaces2,
zero = Json.Empty,
zero = Json.Null,
hasLiteralForm = false
)

Expand All @@ -32,20 +42,12 @@ trait PgCirceJsonSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTy
}
}

trait CirceJsonPlainImplicits {
trait CirceJsonPlainImplicits extends CirceCodeGenSupport {
import utils.PlainSQLUtils._

import scala.reflect.classTag

// used to support code gen
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[Json])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[Json])
}

implicit class PgJsonPositionResult(r: PositionedResult) {
def nextJson() = nextJsonOption().getOrElse(Json.Empty)
def nextJsonOption() = r.nextStringOption().map(parse(_).getOrElse(Json.Empty))
def nextJson() = nextJsonOption().getOrElse(Json.Null)
def nextJsonOption() = r.nextStringOption().map(parse(_).getOrElse(Json.Null))
}

implicit val getJson = mkGetResult(_.nextJson())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ trait PgDate2Support extends date.PgDateExtensions with utils.PgCommonJdbcTypes
import PgDate2SupportUtils._
import driver.api._

// used to support code gen
// let user to call this, since we have more than one `TIMETZ, DATETIMETZ, INTERVAL` binding candidates here
def bindPgDateTypesToScala[DATE, TIME, DATETIME, TIMETZ, DATETIMETZ, INTERVAL](
implicit ctag1: ClassTag[DATE], ctag2: ClassTag[TIME], ctag3: ClassTag[DATETIME],
ctag4: ClassTag[TIMETZ], ctag5: ClassTag[DATETIMETZ], ctag6: ClassTag[INTERVAL]) = {
ctag4: ClassTag[TIMETZ], ctag5: ClassTag[DATETIMETZ], ctag6: ClassTag[INTERVAL]) = {
// register types to let `ExModelBuilder` find them
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("date", classTag[DATE])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("time", classTag[TIME])
Expand All @@ -25,7 +26,7 @@ trait PgDate2Support extends date.PgDateExtensions with utils.PgCommonJdbcTypes
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("timestamptz", classTag[DATETIMETZ])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("interval", classTag[INTERVAL])
}
else throw new IllegalArgumentException("The driver MUST BE a `ExPostgresDriver`!")
else throw new IllegalArgumentException("The driver MUST BE a `ExPostgresProfile`!")
}

/// alias
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@ import org.joda.time._
import org.joda.time.format.{DateTimeFormat, ISODateTimeFormat}
import org.postgresql.util.PGInterval
import slick.jdbc.{JdbcType, PositionedResult, PostgresProfile}
import scala.reflect.classTag

trait PgDateSupportJoda extends date.PgDateExtensions with utils.PgCommonJdbcTypes { driver: PostgresProfile =>
import PgJodaSupportUtils._
import driver.api._
import PgJodaSupportUtils._

trait JodaTimeCodeGenSupport {
// register types to let `ExModelBuilder` find them
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("date", classTag[LocalDate])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("time", classTag[LocalTime])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("timestamp", classTag[LocalDateTime])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("timestamptz", classTag[DateTime])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("interval", classTag[Period])
}
}

/// alias
trait DateTimeImplicits extends JodaDateTimeImplicits
Expand All @@ -24,7 +36,7 @@ trait PgDateSupportJoda extends date.PgDateExtensions with utils.PgCommonJdbcTyp
val jodaTzDateTimeFormatter_NoFraction = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ssZ")
}

trait JodaDateTimeImplicits extends JodaDateTimeFormatters {
trait JodaDateTimeImplicits extends JodaDateTimeFormatters with JodaTimeCodeGenSupport {
implicit val jodaDateTypeMapper: JdbcType[LocalDate] = new GenericJdbcType[LocalDate]("date",
LocalDate.parse(_, jodaDateFormatter), _.toString(jodaDateFormatter), hasLiteralForm=false)
implicit val jodaTimeTypeMapper: JdbcType[LocalTime] = new GenericJdbcType[LocalTime]("time",
Expand Down Expand Up @@ -71,24 +83,10 @@ trait PgDateSupportJoda extends date.PgDateExtensions with utils.PgCommonJdbcTyp
new TimestampColumnExtensionMethods[LocalDate, LocalTime, DateTime, LocalDateTime, Period, Option[DateTime]](c)
}

trait JodaDateTimePlainImplicits extends JodaDateTimeFormatters {
trait JodaDateTimePlainImplicits extends JodaDateTimeFormatters with JodaTimeCodeGenSupport {
import java.sql.Types

import utils.PlainSQLUtils._

import scala.reflect.classTag

// used to support code gen
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("date", classTag[LocalDate])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("time", classTag[LocalTime])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("timestamp", classTag[LocalDateTime])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("timestamptz", classTag[DateTime])
// let users do it by themselves
// driver.asInstanceOf[ExPostgresDriver].bindPgTypeToScala("interval", classTag[Duration])
// driver.asInstanceOf[ExPostgresDriver].bindPgTypeToScala("interval", classTag[Period])
}

implicit class PgDate2TimePositionedResult(r: PositionedResult) {
def nextLocalDate() = nextLocalDateOption().orNull
def nextLocalDateOption() = r.nextStringOption().map(LocalDate.parse(_, jodaDateFormatter))
Expand Down Expand Up @@ -137,7 +135,7 @@ trait PgDateSupportJoda extends date.PgDateExtensions with utils.PgCommonJdbcTyp
}

object PgJodaSupportUtils {
/// pg interval string --> joda Duration
/// pg interval string --> joda Period
def pgIntervalStr2jodaPeriod(intervalStr: String): Period = {
val pgInterval = new PGInterval(intervalStr)
val seconds = Math.floor(pgInterval.getSeconds) .asInstanceOf[Int]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
package com.github.tminglei.slickpg

import slick.jdbc.{JdbcType, PositionedResult, PostgresProfile}
import scala.reflect.classTag

trait PgJson4sSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTypes { driver: PostgresProfile =>
import driver.api._
import org.json4s._

///---
type DOCType
def pgjson: String

val jsonMethods: JsonMethods[DOCType]
///---

trait Json4sCodeGenSupport {
// register types to let `ExModelBuilder` find them
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[JValue])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[JValue])
}
}

/// alias
trait JsonImplicits extends Json4sJsonImplicits

trait Json4sJsonImplicits {
trait Json4sJsonImplicits extends Json4sCodeGenSupport {
implicit val json4sJsonTypeMapper: JdbcType[JValue] =
new GenericJdbcType[JValue](
pgjson,
Expand All @@ -32,17 +43,9 @@ trait PgJson4sSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTypes
}
}

trait Json4sJsonPlainImplicits {
trait Json4sJsonPlainImplicits extends Json4sCodeGenSupport {
import utils.PlainSQLUtils._

import scala.reflect.classTag

// used to support code gen
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[JValue])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[JValue])
}

implicit class PgJsonPositionedResult(r: PositionedResult) {
def nextJson() = nextJsonOption().getOrElse(JNull)
def nextJsonOption() = r.nextStringOption().map(jsonMethods.parse(_))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@ import com.vividsolutions.jts.io.{WKBReader, WKBWriter, WKTReader, WKTWriter}
import slick.ast.FieldSymbol
import slick.jdbc._

import scala.reflect.ClassTag
import scala.reflect.{classTag, ClassTag}

trait PgPostGISSupport extends geom.PgPostGISExtensions { driver: PostgresProfile =>
import driver.api._

trait PostGISCodeGenSupport {
// register types to let `ExModelBuilder` find them
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("geometry", classTag[Geometry])
}
}

///
trait PostGISAssistants extends BasePostGISAssistants[Geometry, Point, LineString, Polygon, GeometryCollection]

trait PostGISImplicits {
trait PostGISImplicits extends PostGISCodeGenSupport {
implicit val geometryTypeMapper: JdbcType[Geometry] = new GeometryJdbcType[Geometry]
implicit val pointTypeMapper: JdbcType[Point] = new GeometryJdbcType[Point]
implicit val polygonTypeMapper: JdbcType[Polygon] = new GeometryJdbcType[Polygon]
Expand All @@ -32,7 +40,7 @@ trait PgPostGISSupport extends geom.PgPostGISExtensions { driver: PostgresProfil
new GeometryColumnExtensionMethods[Geometry, Point, LineString, Polygon, GeometryCollection, G1, Option[G1]](c)
}

trait PostGISPlainImplicits {
trait PostGISPlainImplicits extends PostGISCodeGenSupport {
import PgPostGISSupportUtils._
import utils.PlainSQLUtils._

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
package com.github.tminglei.slickpg

import slick.jdbc.{JdbcType, PositionedResult, PostgresProfile}
import scala.reflect.classTag

trait PgPlayJsonSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTypes { driver: PostgresProfile =>
import driver.api._
import play.api.libs.json._

///---
def pgjson: String
///---

trait PlayJsonCodeGenSupport {
// register types to let `ExModelBuilder` find them
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[JsValue])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[JsValue])
}
}

/// alias
trait JsonImplicits extends PlayJsonImplicits

trait PlayJsonImplicits {
trait PlayJsonImplicits extends PlayJsonCodeGenSupport {
implicit val playJsonTypeMapper: JdbcType[JsValue] =
new GenericJdbcType[JsValue](
pgjson,
Expand All @@ -29,17 +40,9 @@ trait PgPlayJsonSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTyp
}
}

trait PlayJsonPlainImplicits {
trait PlayJsonPlainImplicits extends PlayJsonCodeGenSupport {
import utils.PlainSQLUtils._

import scala.reflect.classTag

// used to support code gen
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[JsValue])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[JsValue])
}

implicit class PgJsonPositionedResult(r: PositionedResult) {
def nextJson() = nextJsonOption().getOrElse(JsNull)
def nextJsonOption() = r.nextStringOption().map(Json.parse)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
package com.github.tminglei.slickpg

import slick.jdbc.{JdbcType, PositionedResult, PostgresProfile}
import scala.reflect.classTag

trait PgSprayJsonSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTypes { driver: PostgresProfile =>
import driver.api._
import spray.json._
import DefaultJsonProtocol._ // !!! IMPORTANT, otherwise `convertTo` and `toJson` won't work correctly.

///---
def pgjson: String
///---

trait SprayJsonCodeGenSupport {
// register types to let `ExModelBuilder` find them
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[JsValue])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[JsValue])
}
}

/// alias
trait JsonImplicits extends SprayJsonImplicits

trait SprayJsonImplicits {
trait SprayJsonImplicits extends SprayJsonCodeGenSupport {
implicit val sprayJsonTypeMapper: JdbcType[JsValue] =
new GenericJdbcType[JsValue](
pgjson,
Expand All @@ -30,17 +41,9 @@ trait PgSprayJsonSupport extends json.PgJsonExtensions with utils.PgCommonJdbcTy
}
}

trait SprayJsonPlainImplicits {
trait SprayJsonPlainImplicits extends SprayJsonCodeGenSupport {
import utils.PlainSQLUtils._

import scala.reflect.classTag

// used to support code gen
if (driver.isInstanceOf[ExPostgresProfile]) {
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("json", classTag[JsValue])
driver.asInstanceOf[ExPostgresProfile].bindPgTypeToScala("jsonb", classTag[JsValue])
}

implicit class PgJsonPositionedResult(r: PositionedResult) {
def nextJson() = nextJsonOption().getOrElse(JsNull)
def nextJsonOption() = r.nextStringOption().map(_.parseJson)
Expand Down
Loading

0 comments on commit 3b4123f

Please sign in to comment.