Skip to content

Commit

Permalink
add play-json support
Browse files Browse the repository at this point in the history
  • Loading branch information
tminglei committed Jan 16, 2014
1 parent c42f425 commit 620448f
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 0 deletions.
12 changes: 12 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@
<artifactId>joda-convert</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>com.typesafe.play</groupId>
<artifactId>play-json_2.10</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.json4s</groupId>
<artifactId>json4s-ast_2.10</artifactId>
Expand All @@ -81,4 +86,11 @@
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>typesafe</id>
<name>typesafe-releases</name>
<url>http://repo.typesafe.com/typesafe/maven-releases</url>
</repository>
</repositories>
</project>
2 changes: 2 additions & 0 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ object SlickPgBuild extends Build {
name := "slick-pg",
description := "Slick extensions for PostgreSQL",
version := "0.2.5",
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/",
libraryDependencies := Seq(
"org.scala-lang" % "scala-reflect" % "2.10.3",
"com.typesafe.slick" % "slick_2.10" % "1.0.1",
Expand All @@ -81,6 +82,7 @@ object SlickPgBuild extends Build {
"org.threeten" % "threetenbp" % "0.8.1",
"joda-time" % "joda-time" % "2.3",
"org.joda" % "joda-convert" % "1.5",
"com.typesafe.play" % "play-json_2.10" % "2.2.1",
"org.json4s" % "json4s-ast_2.10" % "3.2.6",
"org.json4s" % "json4s-core_2.10" % "3.2.6",
"org.json4s" % "json4s-native_2.10" % "3.2.6" % "test",
Expand Down
27 changes: 27 additions & 0 deletions src/main/scala/com/github/tminglei/slickpg/PgPlayJsonSupport.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.github.tminglei.slickpg

import scala.slick.driver.PostgresDriver
import scala.slick.lifted.{TypeMapper, Column}

trait PgPlayJsonSupport extends json.PgJsonExtensions { driver: PostgresDriver =>
import play.api.libs.json._

type JSONType = JsValue

trait JsonImplicits {
implicit val jsonTypeMapper =
new utils.GenericTypeMapper[JsValue]("json",
(v) => Json.parse(v),
(v) => Json.stringify(v)
)

implicit def jsonColumnExtensionMethods(c: Column[JsValue])(
implicit tm: TypeMapper[JsValue], tm1: TypeMapper[List[String]]) = {
new JsonColumnExtensionMethods[JsValue](c)
}
implicit def jsonOptionColumnExtensionMethods(c: Column[Option[JsValue]])(
implicit tm: TypeMapper[JsValue], tm1: TypeMapper[List[String]]) = {
new JsonColumnExtensionMethods[Option[JsValue]](c)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,12 @@ object MyPostgresDriver3 extends PostgresDriver
override val Implicit = new Implicits with DateTimeImplicits
override val simple = new Implicits with SimpleQL with DateTimeImplicits
}

///
object MyPostgresDriver4 extends PostgresDriver
with PgPlayJsonSupport
with PgArraySupport {

override val Implicit = new Implicits with JsonImplicits with ArrayImplicits
override val simple = new Implicits with SimpleQL with JsonImplicits with ArrayImplicits
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.github.tminglei.slickpg

import org.junit._
import org.junit.Assert._
import play.api.libs.json._

class PgPlayJsonSupportTest {
import MyPostgresDriver4.simple._

val db = Database.forURL(url = "jdbc:postgresql://localhost/test?user=test", driver = "org.postgresql.Driver")

case class JsonBean(id: Long, json: JsValue)

object JsonTestTable extends Table[JsonBean]("JsonTest2") {
def id = column[Long]("id", O.AutoInc, O.PrimaryKey)
def json = column[JsValue]("json")

def * = id ~ json <> (JsonBean, JsonBean unapply _)
}

//------------------------------------------------------------------------------

val testRec1 = JsonBean(33L, Json.parse(""" { "a":101, "b":"aaa", "c":[3,4,5,9] } """))
val testRec2 = JsonBean(35L, Json.parse(""" [ {"a":"v1","b":2}, {"a":"v5","b":3} ] """))

@Test
def testJsonFunctions(): Unit = {
db withSession { implicit session: Session =>
JsonTestTable.insert(testRec1)
JsonTestTable.insert(testRec2)

val json1 = Json.parse(""" {"a":"v1","b":2} """)
val json2 = Json.parse(""" {"a":"v5","b":3} """)

val q0 = JsonTestTable.where(_.id === testRec2.id.bind).map(_.json)
println(s"sql0 = ${q0.selectStatement}")
assertEquals(JsArray(List(json1,json2)), q0.first())

// pretty(render(JsNumber(101))) will get "101", but parse("101") will fail, since json string must start with '{' or '['
// println(s"'+>' sql = ${q1.selectStatement}")
// assertEquals(JsNumber(101), q1.first())

val q11 = JsonTestTable.where(_.json.+>>("a") === "101".bind).map(_.json.+>>("c"))
println(s"'+>>' sql = ${q11.selectStatement}")
assertEquals("[3,4,5,9]", q11.first())

val q12 = JsonTestTable.where(_.json.+>>("a") === "101".bind).map(_.json.+>("c"))
println(s"'+>' sql = ${q12.selectStatement}")
assertEquals(JsArray(List(JsNumber(3), JsNumber(4), JsNumber(5), JsNumber(9))), q12.first())

// json array's index starts with 0
val q2 = JsonTestTable.where(_.id === testRec2.id).map(_.json.~>(1))
println(s"'~>' sql = ${q2.selectStatement}")
assertEquals(json2, q2.first())

val q21 = JsonTestTable.where(_.id === testRec2.id).map(_.json.~>>(1))
println(s"'~>>' sql = ${q21.selectStatement}")
assertEquals("""{"a":"v5","b":3}""", q21.first())

val q3 = JsonTestTable.where(_.id === testRec2.id).map(_.json.arrayLength)
println(s"'arrayLength' sql = ${q3.selectStatement}")
assertEquals(2, q3.first())

val q4 = JsonTestTable.where(_.id === testRec2.id).map(_.json.arrayElements)
println(s"'arrayElements' sql = ${q4.selectStatement}")
assertEquals(List(json1, json2), q4.list())

val q41 = JsonTestTable.where(_.id === testRec2.id).map(_.json.arrayElements)
println(s"'arrayElements' sql = ${q41.selectStatement}")
assertEquals(json1, q41.first())

val q5 = JsonTestTable.where(_.id === testRec1.id).map(_.json.objectKeys)
println(s"'objectKeys' sql = ${q5.selectStatement}")
assertEquals(List("a","b","c"), q5.list())

val q51 = JsonTestTable.where(_.id === testRec1.id).map(_.json.objectKeys)
println(s"'objectKeys' sql = ${q51.selectStatement}")
assertEquals("a", q51.first())
}
}

//------------------------------------------------------------------------------

@Before
def createTables(): Unit = {
db withSession { implicit session: Session =>
JsonTestTable.ddl create
}
}

@After
def dropTables(): Unit = {
db withSession { implicit session: Session =>
JsonTestTable.ddl drop
}
}
}

0 comments on commit 620448f

Please sign in to comment.