Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 43 additions & 48 deletions slick-codegen/src/main/scala/slick/codegen/AbstractGenerator.scala

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package slick.codegen

import slick.SlickException
import scala.collection.compat._

import slick.ast.ColumnOption
import slick.{model => m}
import slick.model.ForeignKeyAction
import slick.relational.RelationalProfile
import slick.sql.SqlProfile
import slick.{SlickException, model => m}

/** Base implementation for a Source code String generator */
abstract class AbstractSourceCodeGenerator(model: m.Model)
extends AbstractGenerator[String,String,String](model)
with StringGeneratorHelpers{
with StringGeneratorHelpers {
/** Generates code for the complete model (not wrapped in a package yet)
@group Basic customization overrides */
def code = {
Expand Down Expand Up @@ -94,7 +95,7 @@ abstract class AbstractSourceCodeGenerator(model: m.Model)

protected def tuple(i: Int) = termName(s"_${i+1}")

abstract class TableDef(model: m.Table) extends super.TableDef(model){
abstract class AbstractSourceCodeTableDef(model: m.Table) extends AbstractTableDef(model) {

def compoundType(types: Seq[String]): String = {
if(hlistEnabled){
Expand All @@ -117,7 +118,7 @@ abstract class AbstractSourceCodeGenerator(model: m.Model)
def factory = if(columns.size == 1 || isMappedToHugeClass) TableClass.elementType else s"${TableClass.elementType}.tupled"
def extractor = s"${TableClass.elementType}.unapply"

trait EntityTypeDef extends super.EntityTypeDef{
trait AbstractSourceCodeEntityTypeDef extends AbstractEntityTypeDef {
def code = {
val args = columns.map(c=>
c.default.map( v =>
Expand All @@ -144,7 +145,7 @@ def $name($args): $name = {
}
}

trait PlainSqlMapperDef extends super.PlainSqlMapperDef{
trait AbstractSourceCodePlainSqlMapperDef extends AbstractPlainSqlMapperDef {
def code = {
val types = columnsPositional.map(c => (if(c.asOption || c.model.nullable)s"<<?[${c.rawType}]"else s"<<[${c.rawType}]"))
val dependencies = columns.map(_.exposedType).distinct.zipWithIndex.map{ case (t,i) => s"""e$i: GR[$t]"""}.mkString(", ")
Expand Down Expand Up @@ -172,7 +173,7 @@ implicit def ${name}(implicit $dependencies): GR[${TableClass.elementType}] = GR
}
}

trait TableClassDef extends super.TableClassDef{
trait AbstractSourceCodeTableClassDef extends AbstractTableClassDef {
def star = {
val struct = compoundValue(columns.map(c=>if(c.asOption)s"Rep.Some(${c.name})" else s"${c.name}"))
val rhs = if (isMappedToHugeClass) s"($struct).mapTo[${typeName(entityName(model.name.table))}]" else if(mappingEnabled) s"$struct.<>($factory, $extractor)" else struct
Expand Down Expand Up @@ -213,11 +214,11 @@ class $name(_tableTag: Tag) extends profile.api.Table[$elementType](_tableTag, $
}
}

trait TableValueDef extends super.TableValueDef{
trait AbstractSourceCodeTableValueDef extends AbstractTableValueDef {
def code = s"lazy val $name = new TableQuery(tag => new ${TableClass.name}(tag))"
}

class ColumnDef(model: m.Column) extends super.ColumnDef(model){
class AbstractSourceCodeColumnDef(model: m.Column) extends AbstractColumnDef(model) {
import ColumnOption._
import RelationalProfile.ColumnOption._
import SqlProfile.ColumnOption._
Expand Down Expand Up @@ -253,11 +254,11 @@ class $name(_tableTag: Tag) extends profile.api.Table[$elementType](_tableTag, $
def code = s"""val $name: Rep[$actualType] = column[$actualType]("${model.name}"${options.map(", "+_).mkString("")})"""
}

class PrimaryKeyDef(model: m.PrimaryKey) extends super.PrimaryKeyDef(model){
class AbstractSourceCodePrimaryKeyDef(model: m.PrimaryKey) extends AbstractPrimaryKeyDef(model) {
def code = s"""val $name = primaryKey("$dbName", ${compoundValue(columns.map(_.name))})"""
}

class ForeignKeyDef(model: m.ForeignKey) extends super.ForeignKeyDef(model){
class AbstractSourceCodeForeignKeyDef(model: m.ForeignKey) extends AbstractForeignKeyDef(model) {
def actionCode(action: ForeignKeyAction) = action match{
case ForeignKeyAction.Cascade => "ForeignKeyAction.Cascade"
case ForeignKeyAction.Restrict => "ForeignKeyAction.Restrict"
Expand All @@ -267,7 +268,7 @@ class $name(_tableTag: Tag) extends profile.api.Table[$elementType](_tableTag, $
}
def code = {
val pkTable = referencedTable.TableValue.name
val (pkColumns, fkColumns) = (referencedColumns, referencingColumns).zipped.map { (p, f) =>
val (pkColumns, fkColumns) = referencedColumns.lazyZip(referencingColumns).map { (p, f) =>
val pk = s"r.${p.name}"
val fk = f.name
if(p.model.nullable && !f.model.nullable) (pk, s"Rep.Some($fk)")
Expand All @@ -278,7 +279,7 @@ class $name(_tableTag: Tag) extends profile.api.Table[$elementType](_tableTag, $
}
}

class IndexDef(model: m.Index) extends super.IndexDef(model){
class AbstractSourceCodeIndexDef(model: m.Index) extends AbstractIndexDef(model) {
def code = {
val unique = if(model.unique) s", unique=true" else ""
s"""val $name = index("$dbName", ${compoundValue(columns.map(_.name))}$unique)"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,27 @@ import slick.util.ConfigExtensionMethods.configExtensionMethods
class SourceCodeGenerator(model: m.Model)
extends AbstractSourceCodeGenerator(model) with OutputHelpers{
// "Tying the knot": making virtual classes concrete
type Table = TableDef
def Table = new TableDef(_)
class TableDef(model: m.Table) extends super.TableDef(model){
type Table = SourceCodeTableDef
def Table = new SourceCodeTableDef(_)
class SourceCodeTableDef(model: m.Table) extends AbstractSourceCodeTableDef(model) {
// Using defs instead of (caching) lazy vals here to provide consitent interface to the user.
// Performance should really not be critical in the code generator. Models shouldn't be huge.
// Also lazy vals don't inherit docs from defs
type EntityType = EntityTypeDef
def EntityType = new EntityType{}
type PlainSqlMapper = PlainSqlMapperDef
def PlainSqlMapper = new PlainSqlMapper{}
type TableClass = TableClassDef
def TableClass = new TableClass{}
type TableValue = TableValueDef
def TableValue = new TableValue{}
type Column = ColumnDef
type EntityType = AbstractSourceCodeEntityTypeDef
def EntityType = new EntityType {}
type PlainSqlMapper = AbstractSourceCodePlainSqlMapperDef
def PlainSqlMapper = new PlainSqlMapper {}
type TableClass = AbstractSourceCodeTableClassDef
def TableClass = new TableClass {}
type TableValue = AbstractSourceCodeTableValueDef
def TableValue = new TableValue {}
type Column = AbstractSourceCodeColumnDef
def Column = new Column(_)
type PrimaryKey = PrimaryKeyDef
type PrimaryKey = AbstractSourceCodePrimaryKeyDef
def PrimaryKey = new PrimaryKey(_)
type ForeignKey = ForeignKeyDef
type ForeignKey = AbstractSourceCodeForeignKeyDef
def ForeignKey = new ForeignKey(_)
type Index = IndexDef
type Index = AbstractSourceCodeIndexDef
def Index = new Index(_)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ val SimpleA = CustomTyping.SimpleA
new Config("CG9", StandardTestDBs.H2Mem, "H2Mem", Seq("/dbs/h2.sql")) {
override def generator = tdb.profile.createModel(ignoreInvalidDefaults=false).map(new MyGen(_) {
override def Table = new Table(_){
override def autoIncLastAsOption = true
override def autoIncLast = true
override def Column = new Column(_){
override def asOption = autoInc
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class Tables(val profile: JdbcProfile){
class Categories(tag: Tag) extends Table[Category](tag, "categories") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name", O.Length(254))
def * = (id, name) <> (Category.tupled,Category.unapply)
def * = (id, name).<>(Category.tupled,Category.unapply)
def idx = index("IDX_NAME",name)
}
val categories = TableQuery[Categories]
Expand Down Expand Up @@ -233,7 +233,7 @@ class Tables(val profile: JdbcProfile){
(p4i1, p4i2, p4i3, p4i4, p4i5, p4i6),
(p5i1, p5i2, p5i3, p5i4, p5i5, p5i6),
(p6i1, p6i2, p6i3, p6i4, p6i5, p6i6)
).shaped <> ({ case (id, p1, p2, p3, p4, p5, p6) =>
).shaped.<>({ case (id, p1, p2, p3, p4, p5, p6) =>
// We could do this without .shaped but then we'd have to write a type annotation for the parameters
Whole(id, Part.tupled.apply(p1), Part.tupled.apply(p2), Part.tupled.apply(p3), Part.tupled.apply(p4), Part.tupled.apply(p5), Part.tupled.apply(p6))
}, { (w: Whole) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ForceInsertQueryTest extends AsyncTest[JdbcTestDB] {

def eyeColor = column[Option[String]]("eye_color")

def * = (id.?, name, hairColor, eyeColor) <>(Person.tupled, Person.unapply)
def * = (id.?, name, hairColor, eyeColor).<>(Person.tupled, Person.unapply)
}

object peopleTable extends TableQuery(new People(_)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class InsertTest extends AsyncTest[JdbcTestDB] {
def id = column[Int]("id" , O.AutoInc , O.PrimaryKey)
def email = column[String]("email" , O.Unique , O.Length(254))

def * = (email , id)<>(ARow.tupled , ARow.unapply )
def * = (email , id).<>(ARow.tupled , ARow.unapply )
}
val atq = TableQuery[A]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ class JdbcMapperTest extends AsyncTest[JdbcTestDB] {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def first = column[String]("first")
def last = column[String]("last")
def * = id.? ~: baseProjection <> (User.tupled, User.unapply _)
def * = (id.? ~: baseProjection).<>(User.tupled, User.unapply _)
def baseProjection = first ~ last
def forUpdate = baseProjection.shaped <>
({ case (f, l) => User(None, f, l) }, { (u:User) => Some((u.first, u.last)) })
def asFoo = forUpdate <> ((u: User) => Foo(u), (f: Foo[User]) => Some(f.value))
def forUpdate = baseProjection.shaped.<>({ case (f, l) => User(None, f, l) }, { (u:User) => Some((u.first, u.last)) })
def asFoo = forUpdate.<>((u: User) => Foo(u), (f: Foo[User]) => Some(f.value))
}
object users extends TableQuery(new Users(_)) {
val byID = this.findBy(_.id)
Expand All @@ -46,8 +45,8 @@ class JdbcMapperTest extends AsyncTest[JdbcTestDB] {
users.filter(_.last inSet Set("Bouvier", "Ferdinand")).size.result.map(_ shouldBe 1),
updateQ.update(User(None, "Marge", "Simpson")),
Query(users.filter(_.id === 1).exists).result.head.map(_ shouldBe true),
users.filter(_.id between(1, 2)).to[Set].result.map(_ shouldBe Set(User(Some(1), "Homer", "Simpson"), User(Some(2), "Marge", "Simpson"))),
users.filter(_.id between(1, 2)).map(_.asFoo).to[Set].result.map(_ shouldBe Set(Foo(User(None, "Homer", "Simpson")), Foo(User(None, "Marge", "Simpson")))),
users.filter(_.id.between(1, 2)).to[Set].result.map(_ shouldBe Set(User(Some(1), "Homer", "Simpson"), User(Some(2), "Marge", "Simpson"))),
users.filter(_.id.between(1, 2)).map(_.asFoo).to[Set].result.map(_ shouldBe Set(Foo(User(None, "Homer", "Simpson")), Foo(User(None, "Marge", "Simpson")))),
users.byID(3).result.head.map(_ shouldBe User(Some(3), "Carl", "Carlson")),
q1.result.head.map(_.should(_.isInstanceOf[User]))
)
Expand Down Expand Up @@ -116,7 +115,7 @@ class JdbcMapperTest extends AsyncTest[JdbcTestDB] {
def m1 = (
id,
(p1i1, p1i2, p1i3, p1i4, p1i5, p1i6).mapTo[Part],
(p2i1, p2i2, p2i3, p2i4, p2i5, p2i6) <> (Part.tupled, Part.unapply _),
(p2i1, p2i2, p2i3, p2i4, p2i5, p2i6).<>(Part.tupled, Part.unapply _),
(p3i1, p3i2, p3i3, p3i4, p3i5, p3i6).mapTo[Part],
(p4i1, p4i2, p4i3, p4i4, p4i5, p4i6).mapTo[Part]
).mapTo[Whole]
Expand All @@ -127,7 +126,7 @@ class JdbcMapperTest extends AsyncTest[JdbcTestDB] {
(p2i1, p2i2, p2i3, p2i4, p2i5, p2i6),
(p3i1, p3i2, p3i3, p3i4, p3i5, p3i6),
(p4i1, p4i2, p4i3, p4i4, p4i5, p4i6)
).shaped <> ({ case (id, p1, p2, p3, p4) =>
).shaped.<>({ case (id, p1, p2, p3, p4) =>
// We could do this without .shaped but then we'd have to write a type annotation for the parameters
Whole(id, Part.tupled.apply(p1), Part.tupled.apply(p2), Part.tupled.apply(p3), Part.tupled.apply(p4))
}, { (w: Whole) =>
Expand Down Expand Up @@ -172,9 +171,9 @@ class JdbcMapperTest extends AsyncTest[JdbcTestDB] {
def p2 = column[String]("p2")
def p3 = column[String]("p3")
def p4 = column[Int]("p4")
def part1 = (p1,p2) <> (Part1.tupled,Part1.unapply)
def part1 = (p1,p2).<>(Part1.tupled,Part1.unapply)
def part2 = (p3,p4).mapTo[Part2]
def * = (part1, part2) <> (Whole.tupled,Whole.unapply)
def * = (part1, part2).<>(Whole.tupled,Whole.unapply)
}
val T = TableQuery[T]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class MainTest extends AsyncTest[JdbcTestDB] { mainTest =>

val q4e = for (
u <- users if u.first inSetBind List("Homer", "Marge");
o <- orders if o.userID in (u.id, u.id)
o <- orders if o.userID.in(u.id, u.id)
) yield (u.first, o.orderID)
q4e.result.statements.toSeq.length.should(_ >= 1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ class RelationalMapperTest extends AsyncTest[RelationalTestDB] {
class T(tag: Tag) extends Table[Row](tag, "t".withUniquePostFix) {
val id = column[String]("id", O.PrimaryKey)
val name = column[Option[String]]("name")
val upperName = name.shaped <> (toLower, toUpper)
def * = (id, upperName) <> (Row.tupled, Row.unapply)
val upperName = name.shaped.<>(toLower, toUpper)
def * = (id, upperName).<>(Row.tupled, Row.unapply)
}
val ts = TableQuery[T]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class RewriteBooleanTest extends AsyncTest[RelationalTestDB] {
def addressId = column[Option[Int]]("address_id")
def isHomeowner = column[Boolean] ("is_homeowner")

def * = (id, name, age, addressId, isHomeowner) <> ((Person.apply _).tupled, Person.unapply _)
def * = (id, name, age, addressId, isHomeowner).<>((Person.apply _).tupled, Person.unapply _)
}

lazy val people = TableQuery[People]
Expand All @@ -29,7 +29,7 @@ class RewriteBooleanTest extends AsyncTest[RelationalTestDB] {
def city = column[String] ("city")
def isActive = column[Boolean]("is_active")

def * = (id, street, city, isActive) <> ((Address.apply _).tupled, Address.unapply _)
def * = (id, street, city, isActive).<>((Address.apply _).tupled, Address.unapply _)
}

lazy val addresses = TableQuery[Addresses]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,15 @@ class UnionTest extends AsyncTest[RelationalTestDB] {
val messageId = column[Long]("message_id")
val sentAt = column[Long]("sent_at")

def * = (id, dname, messageId, sentAt) <> (Delivery.tupled, Delivery.unapply)
def * = (id, dname, messageId, sentAt).<>(Delivery.tupled, Delivery.unapply)
}

class Messages(tag: Tag) extends Table[Message](tag, "m2") {
val id = column[Long]("message_id")
val mname = column[String]("mname")
val mbody = column[String]("mbody")

def * = (id, mname, mbody) <> (Message.tupled, Message.unapply)
def * = (id, mname, mbody).<>(Message.tupled, Message.unapply)
}


Expand Down Expand Up @@ -185,7 +185,7 @@ class UnionTest extends AsyncTest[RelationalTestDB] {
val dname = column[String]("dname")
val sentAt = column[Long]("sent_at")

def * = (id, dname, sentAt) <> (Delivery.tupled, Delivery.unapply)
def * = (id, dname, sentAt).<>(Delivery.tupled, Delivery.unapply)
}

def leftSide = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class GitHubActionsRunListener extends RunListener {
error(failure.getTestHeader + " failed an assumption")(failure.getMessage)

override def testRunStarted(description: Description) =
println(this + ": " + description.getTestClass + " started")
println(s"$this: ${description.getTestClass} started")

override def testRunFinished(result: Result) = {
val (runs, failures, ignores) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ object Benchmark {
for(i <- 0 to COUNT) test1(false)
val t1 = System.nanoTime()
val total = (t1-t0)/1000000.0
println(s"$COUNT runs tooks "+total+" ms ("+(total*1000.0/COUNT)+" µs per run)")
println(s"$COUNT runs tooks $total ms (${total*1000.0/COUNT} µs per run)")
}

class Users(tag: Tag) extends Table[(Int, String, String)](tag, "users") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ object UnboxedBenchmark extends App {
val as = TableQuery[ARow]

// Standard converters
val q1 = as.map(a => a.proj <> (A.tupled, A.unapply))
val q1 = as.map(a => a.proj.<>(A.tupled, A.unapply))

// Fast path
val q2 = as.map(a => a.proj <> (A.tupled, A.unapply)
val q2 = as.map(a => a.proj.<>(A.tupled, A.unapply)
fastPath(new FastPath(_) {
val (a, b, c, d) = (next[Int], next[Int], next[Int], next[Int])
override def read(r: Reader) = new A(a.read(r), b.read(r), c.read(r), d.read(r))
Expand All @@ -36,7 +36,7 @@ object UnboxedBenchmark extends App {

// Allocation-free fast path
val sharedA = new A(0, 0, 0, 0)
val q3 = as.map(a => a.proj <> (A.tupled, A.unapply)
val q3 = as.map(a => a.proj.<>(A.tupled, A.unapply)
fastPath(new FastPath(_) {
val (a, b, c, d) = (next[Int], next[Int], next[Int], next[Int])
override def read(r: Reader) = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class CodeGeneratorAllTest(val tdb: JdbcTestDB) extends DBTest {
class Categories(tag: Tag) extends Table[Category](tag, "categories") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name", O.Length(254))
def * = (id, name) <> (Category.tupled,Category.unapply)
def * = (id, name).<>(Category.tupled,Category.unapply)
def idx = index("IDX_NAME",name)
}
val categories = TableQuery[Categories]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ object GeneratedCodeTest {

(r.ts, r.ts2, r.ts3, r.ts4, r.ts5, r.ts6, r.ts7) match {
case (c.ts, c.ts2, c.ts3, c.ts4, c.ts5, now, c.ts7) => assertTrue(c.ts6.compareTo(r.ts6) <= diff)
case _ => fail
}
},
Suppliers.result.map(assertEquals(List(s), _)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import java.util.Properties
import java.util.logging.Logger

import com.typesafe.config.ConfigFactory
import org.junit.Test
import org.junit.{Ignore, Test}
import org.junit.Assert._
import slick.basic.DatabaseConfig
import slick.jdbc.{JdbcBackend, JdbcProfile}

import scala.concurrent.Await
import scala.concurrent.duration.Duration

@Ignore
class DataSourceTest {
@Test def testDataSourceJdbcDataSource: Unit = {
val dc = DatabaseConfig.forConfig[JdbcProfile]("ds1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class SqlActionBuilderTest {
#from SUPPLIERS
#where SUP_ID = ${id}""".stripMargin('#')

def dropNewLineChars(queryParts: Seq[Any]): Seq[Any] = queryParts.map(_.asInstanceOf[String].replace('\n', ' '))
def dropNewLineChars(queryParts: Seq[Any]): Seq[Any] = queryParts.map(_.asInstanceOf[String].replace('\n', ' ').replaceAll("\r", ""))

assertEquals(s1.queryParts, dropNewLineChars(s2.queryParts))
assertEquals(s1.queryParts, dropNewLineChars(s3.queryParts))
Expand Down
Loading