Skip to content
Permalink
Browse files

Macro-based PlainSQL API

Implemented TypedStaticQuery as tsql
  • Loading branch information
radsaggi committed Feb 11, 2015
1 parent ac5a097 commit 62ddadc84ecf4aefe2fdc580945d263edd203772
@@ -0,0 +1,9 @@
typedsql {

default {
url = "jdbc:h2:mem:test1;INIT=runscript from 'slick-testkit/src/codegen/resources/dbs/h2mem/create.sql'\\;runscript from 'slick-testkit/src/codegen/resources/dbs/h2mem/populate.sql'"
jdbcDriver = "org.h2.Driver"
slickDriver = "scala.slick.driver.H2Driver"
}

}
@@ -119,6 +119,46 @@ class OldPlainSQLTest extends TestkitTest[JdbcTestDB] {

assertEquals(User(2,"guest"), userForIdAndName(2, "guest").first)
assertEquals(None, userForIdAndName(2, "foo").firstOption)

sqlu"""create table LONGTABLE(
VAL1 int not null, VAL2 int not null, VAL3 int not null, VAL4 int not null,
VAL5 int not null, VAL6 int not null, VAL7 int not null, VAL8 int not null,
VAL9 int not null, VAL10 int not null, VAL11 int not null, VAL12 int not null,
VAL13 int not null, VAL14 int not null, VAL15 int not null, VAL16 int not null,
VAL17 int not null, VAL18 int not null, VAL19 int not null, VAL20 int not null,
VAL21 int not null, VAL22 int not null, VAL23 int not null, VAL24 int not null)""".execute

val s3 = sqlu"""insert into LONGTABLE values (
#${100}, #${101}, #${102}, #${103}, #${104}, #${105}, #${106}, #${107},
#${108}, #${109}, #${110}, #${111}, #${112}, #${113}, #${114}, #${115},
#${116}, #${117}, #${118}, #${119}, #${120}, #${121}, #${122}, #${123}) """
val s4 = sqlu"""insert into LONGTABLE values (
#${200}, #${201}, #${202}, #${203}, #${204}, #${205}, #${206}, #${207},
#${208}, #${209}, #${210}, #${211}, #${212}, #${213}, #${214}, #${215},
#${216}, #${217}, #${218}, #${219}, #${220}, #${221}, #${222}, #${223}) """
assertEquals("""insert into LONGTABLE values (
100, 101, 102, 103, 104, 105, 106, 107,
108, 109, 110, 111, 112, 113, 114, 115,
116, 117, 118, 119, 120, 121, 122, 123) """, s3.getStatement)
s3.execute
assertEquals("""insert into LONGTABLE values (
200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 215,
216, 217, 218, 219, 220, 221, 222, 223) """, s4.getStatement)
s4.execute

val s5 = sql"""select VAL24 from LONGTABLE WHERE VAL1=${100} AND VAL2=${101} AND VAL3=${102}
AND VAL4=${103} AND VAL5=${104} AND VAL6=${105} AND VAL7=${106} AND VAL8=${107}
AND VAL9=${108} AND VAL10=${109} AND VAL11=${110} AND VAL12=${111} AND VAL13=${112}
AND VAL14=${113} AND VAL15=${114} AND VAL16=${115} AND VAL17=${116} AND VAL18=${117}
AND VAL19=${118} AND VAL20=${119} AND VAL21=${120} AND VAL22=${121} AND VAL23=${122}""".as[Int]
val s6 = sql"""select VAL24 from LONGTABLE WHERE VAL1=${200} AND VAL2=${201} AND VAL3=${202}
AND VAL4=${203} AND VAL5=${204} AND VAL6=${205} AND VAL7=${206} AND VAL8=${207}
AND VAL9=${208} AND VAL10=${209} AND VAL11=${210} AND VAL12=${211} AND VAL13=${212}
AND VAL14=${213} AND VAL15=${214} AND VAL16=${215} AND VAL17=${216} AND VAL18=${217}
AND VAL19=${218} AND VAL20=${219} AND VAL21=${220} AND VAL22=${221} AND VAL23=${222}""".as[Int]
assertEquals(123, s5.first)
assertEquals(223, s6.first)
}

def assertUnquotedTablesExist(tables: String*) {
@@ -99,10 +99,12 @@ class PlainSQLTest extends AsyncTest[JdbcTestDB] {
def userForID(id: Int) = sql"select id, name from USERS where id = $id".as[User]
def userForIdAndName(id: Int, name: String) = sql"select id, name from USERS where id = $id and name = $name".as[User]

val s1 = sql"select id from USERS where name = ${"szeiger"}".as[Int]
val s2 = sql"select id from USERS where name = '#${"guest"}'".as[Int]
val param = "szeiger"

val s1 = sql"select id from USERS where name = ${param}".as[Int]
val s2 = sql"select id from USERS where name = ${"guest"}".as[Int]
s1.statements.head shouldBe "select id from USERS where name = ?"
s2.statements.head shouldBe "select id from USERS where name = 'guest'"
s2.statements.head shouldBe "select id from USERS where name = ?"

seq(
sqlu"create table USERS(ID int not null primary key, NAME varchar(255))",
@@ -0,0 +1,165 @@
package scala.slick.test.jdbc

import org.junit.Test
import org.junit.Assert._
import scala.slick.collection.heterogenous.HNil
import scala.slick.collection.heterogenous.syntax._
import scala.slick.dbio.DBIO
import scala.slick.driver.JdbcDriver.api._

@TSQLConfig("default")
class TypedStaticQueryTest {
import scala.concurrent.ExecutionContext.Implicits.global

val config = TypedStaticQuery.getConfigHandler()

@Test
def testTypedInterpolation: Unit = config.connection run {
val id1 = 150
val id2 = 1
val s1 = tsql"select * from SUPPLIERS where SUP_ID = ${id1}"
val s2 = tsql"select * from COFFEES where SUP_ID = ${id2}"
assertEquals("select * from SUPPLIERS where SUP_ID = ?", s1.statements.head)
assertEquals("select * from COFFEES where SUP_ID = ?", s2.statements.head)

val (total1, sales1) = (5, 4)
val s3 = tsql"select COF_NAME from COFFEES where SALES = ${sales1} and TOTAL = ${total1}"

val s4 = tsql"select 1, '2', 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23"

DBIO.seq(
s1.map { list1 =>
val typedList1: Vector[(Int, String, String, String, String, String)] = list1
assertEquals(Vector((150, "The High Ground", "100 Coffee Lane", "Meadows", "CA", "93966")), typedList1)
},
s2.map { list2 =>
val typedList2: Vector[(String, Int, Double, Int, Int)] = list2
assertEquals(Vector(("coffee", 1, 2.3, 4, 5)), typedList2)
},
s3.map { list3 =>
val cof1: String = list3.head
assertEquals("coffee", cof1)
},
s4.map { list4 =>
val hlist1Typed: Int :: String :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: Int :: HNil = list4.head
assertEquals(1 :: "2" :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: 9 :: 10 :: 11 :: 12 :: 13 :: 14 :: 15 :: 16 :: 17 :: 18 :: 19 :: 20 :: 21 :: 22 :: 23 :: HNil, hlist1Typed)
}
)
}

@Test
def testCustomTypes: Unit = config.connection run {
import scala.slick.jdbc.SetParameter

case class Foo(intVal: Int)
case class Bar(strVal: String)

implicit val SetFoo = SetParameter[Foo] { (i, pp) =>
SetParameter.SetInt(i.intVal, pp)
}
implicit val SetBar = SetParameter[Bar] { (s, pp) =>
SetParameter.SetString(s.strVal, pp)
}

val foo = new Foo(150)
val bar = new Bar("Something")
val num = 15

val s1 = tsql"select * from SUPPLIERS where SUP_ID = ${foo}"
val s2 = tsql"select * from SUPPLIERS where SUP_ID = ${num * 10}"
val s3 = tsql"select SUP_ID from SUPPLIERS"
val s4 = tsql"select CITY from SUPPLIERS"

DBIO.seq(
s1.map { o1 =>
val t1: Vector[(Int, String, String, String, String, String)] = o1
assertEquals(Vector((150, "The High Ground", "100 Coffee Lane", "Meadows", "CA", "93966")), t1)
},
s2.map { o2 =>
val t2: Vector[(Int, String, String, String, String, String)] = o2
assertEquals(Vector((150, "The High Ground", "100 Coffee Lane", "Meadows", "CA", "93966")), t2)
},
s3.map { o3 =>
val t3: Vector[Foo] = o3.map(Foo(_))
assertEquals(Vector(Foo(101), Foo(150), Foo(49)), t3)
},
s4.map { o4 =>
val t4: Vector[Bar] = o4.map(Bar(_))
assertEquals(List(Bar("Groundsville"), Bar("Meadows"), Bar("Mendocino")), t4)
}
)
}

@Test
def testPreparedQueries: Unit = config.connection run {
case class Supplier(id: Int, name: String)
implicit val supplierGetter = (arg: (Int, String)) => Supplier(arg._1, arg._2)

def supplierForID(id: Int) =
tsql"select SUP_ID, SUP_NAME from SUPPLIERS where SUP_ID = $id"
def supplierForIdAndName(id: Int, name: String) =
tsql"select SUP_ID, SUP_NAME from SUPPLIERS where SUP_ID = $id and SUP_NAME = $name"

val s1 = supplierForID(101)
val s2 = supplierForID(49)
val s3 = supplierForIdAndName(150, "The High Ground")
val s4 = supplierForIdAndName(49, "Superior Coffee")

DBIO.seq(
s1.map { o1 =>
val t1: Supplier = o1.map(supplierGetter).head
assertEquals(Supplier(101, "Acme, Inc."), t1)
},
s2.map { o2 =>
val t2: Supplier = o2.map(supplierGetter).head
assertEquals(Supplier(49, "Superior Coffee"), t2)
},
s3.map { o3 =>
val t3: Supplier = o3.map(supplierGetter).head
assertEquals(Supplier(150, "The High Ground"), o3)
},
s4.map { o4 =>
val t4: Supplier = o4.map(supplierGetter).head
assertEquals(Supplier(49, "Superior Coffee"), t4)
}
)
}

@Test
def testAllStatements: Unit = config.connection run {
case class Supplier(id: Int, name: String)
implicit val supplierGetter = (arg: (Int, String)) => Supplier(arg._1, arg._2)

val testUnitDML = (x: Vector[Int]) => assertEquals(1, x.head)

val s1 = tsql"select SUP_ID, SUP_NAME from SUPPLIERS where SUP_ID = 102"
val s2 = tsql"select SUP_ID, SUP_NAME from SUPPLIERS where SUP_ID = 103"

DBIO.seq(
tsql"""create table "SUPPLIERS2" ("SUP_ID" INTEGER NOT NULL PRIMARY KEY,"SUP_NAME" VARCHAR NOT NULL);""",
tsql"""INSERT INTO SUPPLIERS VALUES(102, 'Acme, Inc. Next', '99 Market Street', 'Groundsville', 'CA', '95199');""" map testUnitDML,
tsql"""INSERT INTO SUPPLIERS VALUES(103, 'Coffee Retailers Corp.', '9 Random Street', 'Ville', 'LA', '63195');""" map testUnitDML,
s1.map { o1 =>
val t1: Supplier = o1.map(supplierGetter).head
assertEquals(Supplier(102, "Acme, Inc. Next"), t1)
},
s2.map { o2 =>
val t2: Supplier = o2.map(supplierGetter).head
assertEquals(Supplier(103, "Coffee Retailers Corp."), t2)
},
tsql"""UPDATE SUPPLIERS SET SUP_NAME = 'Acme, Inc. II' WHERE SUP_ID = '102';""" map testUnitDML,
tsql"""UPDATE SUPPLIERS SET SUP_NAME = 'Coffee Retailers Corp. II' WHERE SUP_ID = '103';""" map testUnitDML,
s1.map { o1 =>
val t1: Supplier = o1.map(supplierGetter).head
assertEquals(Supplier(102, "Acme, Inc. II"), t1)
},
s2.map { o2 =>
val t2: Supplier = o2.map(supplierGetter).head
assertEquals(Supplier(103, "Coffee Retailers Corp. II"), t2)
},
tsql"""DELETE FROM SUPPLIERS WHERE SUP_ID = '102';""" map testUnitDML,
tsql"""DELETE FROM SUPPLIERS WHERE SUP_ID = '103';""" map testUnitDML,
tsql"""drop table "SUPPLIERS2" """
)
}
}
@@ -4,7 +4,7 @@ import scala.language.{implicitConversions, higherKinds}
import scala.slick.ast.{BaseTypedType, Node}
import scala.slick.compiler.{Phase, QueryCompiler, InsertCompiler}
import scala.slick.lifted._
import scala.slick.jdbc._
import scala.slick.jdbc.{TypedStaticQuery => TSQ, _}
import scala.slick.profile.{SqlDriver, SqlProfile, Capability}

/** A profile for accessing SQL databases via JDBC. All drivers for JDBC-based databases
@@ -86,6 +86,8 @@ trait JdbcProfile extends SqlProfile with JdbcActionComponent
new JdbcActionExtensionMethods[E, R, S](a)

implicit def actionBasedSQLInterpolation(s: StringContext) = new ActionBasedSQLInterpolation(s)
val TypedStaticQuery = TSQ
type TSQLConfig = TSQ.TSQLConfig
}

@deprecated("Use 'api' instead of 'simple' or 'Implicit' to import the new API", "3.0")

0 comments on commit 62ddadc

Please sign in to comment.
You can’t perform that action at this time.