SlideShare a Scribd company logo
1 of 39
Patterns for Slick database
applications
Jan Christopher Vogt, EPFL
Slick Team

#scalax
Recap: What is Slick?
(for ( c <- coffees;
if c.sales > 999
) yield c.name).run

select "COF_NAME"
from
"COFFEES"
where "SALES" > 999
Agenda
ā€¢ Query composition and re-use
ā€¢ Getting rid of boiler plate in Slick 2.0
ā€“
ā€“
ā€“

outer joins / auto joins
auto increment
code generation

ā€¢ Dynamic Slick queries
Query composition and reuse
For-expression desugaring in Scala
for ( c <- coffees;
if c.sales > 999
) yield c.name

coffees
.withFilter(_.sales > 999)
.map(_.name)
Types in Slick
class Coffees(tag: Tag) extends Table[C](tag,"COFFEESā€) {
def * = (name, supId, price, sales, total) <> ...
val name = column[String]("COF_NAME", O.PrimaryKey)
val supId = column[Int]("SUP_ID")
val price = column[BigDecimal]("PRICE")
val sales = column[Int]("SALES")
val total = column[Int]("TOTAL")
}
lazy val coffees = TableQuery[Coffees]

<: Query[Coffees,C]

coffees.map(c => c.name)
(coffees:TableQuery[Coffees,_]).map(
(coffees
).map(
(c:Coffees) => (c.name Column[String])
(c.name:
(c
)
)
): Query[Column[String],String]
)
Table extensions
class Coffees(tag: Tag) extends Table[C](tag,"COFFEESā€) {
ā€¦
val price = column[BigDecimal]("PRICE")
val sales = column[Int]("SALES")
def

revenue = price.asColumnOf[Double] *
sales.asColumnOf[Double]

}

coffees.map(c => c.revenue)
Query extensions
implicit class QueryExtensions[T,E]
( val q: Query[T,E] ){
def page(no: Int, pageSize: Int = 10)
: Query[T,E]
= q.drop( (no-1)*pageSize ).take(pageSize)
}
suppliers.page(5)
coffees.sortBy(_.name).page(5)
Query extensions by Table
implicit class CoffeesExtensions
( val q: Query[Coffees,C] ){
def byName( name: Column[String] )
: Query[Coffees,C]
= q.filter(_.name === name).sortBy(_.name)
}
coffees.byName("ColumbianDecaf").page(5)
Query extensions for joins
implicit class CoffeesExtensions2( val q: Query[Coffees,C] ){
def withSuppliers
(s: Query[Suppliers,S] = Tables.suppliers)
: Query[(Coffees,Suppliers),(C,S)]
= q.join(s).on(_.supId===_.id)
def suppliers
(s: Query[Suppliers, S] = Tables.suppliers)
: Query[Suppliers, S]
= q.withSuppliers(s).map(_._2)
}
coffees.withSuppliers() : Query[(Coffees,Suppliers),(C,S)
coffees.withSuppliers( suppliers.filter(_.city === "Henderson") )
// buyable coffees
coffeeShops.coffees().suppliers().withCoffees()
Query extensions by Interface
trait HasSuppliers{ def supId: Column[Int] }
class Coffees(ā€¦)
extends Table... with HasSuppliers {ā€¦}
class CofInventory(ā€¦) extends Table... with HasSuppliers {ā€¦}
implicit class HasSuppliersExtensions[T <: HasSupplier,E]
( val q: Query[T,E] ){
def bySupId(id: Column[Int]): Query[T,E]
= q.filter( _.supId === id )
def withSuppliers
(s: Query[Suppliers,S] = Tables.suppliers)
: Query[(T,Suppliers),(E,S)]
= q.join(s).on(_.supId===_.id)
def suppliers ...
}
// available quantities of coffees
cofInventory.withSuppliers()
.map{ case (i,s) =>
i.quantity.asColumnOf[String] ++ " of " ++ i.cofName ++ " at " ++ s.name
}
Query extensions summary
ā€¢ Mindshift required!
Think code, not monolithic query strings.
ā€¢ Stay completely lazy!
Keep Query[ā€¦]s as long as you can.
ā€¢ Re-use!
Write query functions or extensions
methods for shorter, better and DRY code.
Getting rid of boilerplate
Auto joins
Auto joins
implicit class QueryExtensions2[T,E]
( val q: Query[T,E] ){
def autoJoin[T2,E2]
( q2:Query[T2,E2] )
( implicit condition: (T,T2) => Column[Boolean] )
: Query[(T,T2),(E,E2)]
= q.join(q2).on(condition)
}
implicit def joinCondition1
= (c:Coffees,s:Suppliers) => c.supId === s.id
coffees.autoJoin( suppliers ) : Query[(Coffees,Suppliers),(C,S)]
coffees.autoJoin( suppliers ).map(_._2).autoJoin(cofInventory)
Auto incrementing inserts
Auto incrementing inserts
val supplier
= Supplier( 0, "Arabian Coffees Inc.", ... )
// now ignores auto-increment column
suppliers.insert( supplier )
// includes auto-increment column
suppliers.forceInsert( supplier )
Code generatION
Code generator for Slick code
// runner for default config
import scala.slick.meta.codegen.SourceCodeGenerator
SourceCodeGenerator.main(
Array(
"scala.slick.driver.H2Driver",
"org.h2.Driver",
"jdbc:h2:mem:test",
"src/main/scala/", // base src folder
"demo" // package
)
)
Generated code
package demo
object Tables extends {
val profile = scala.slick.driver.H2Driver
} with Tables
trait Tables {
val profile: scala.slick.driver.JdbcProfile
import profile.simple._
case class CoffeeRow(name: String, supId: Int, ...)
implicit def GetCoffees
= GetResult{r => CoffeeRow.tupled((r.<<, ... )) }
class Coffees(tag: Tag) extends Table[CoffeeRow](ā€¦){ā€¦}
...
OUTER JOINS
Outer join limitation in Slick
suppliers.leftJoin(coffees)
.on(_.id === _.supId)
.run // SlickException: Read NULL value ...
id

name

name

supId

1

Superior Coffee

NULL

NULL

2

Acme, Inc.

Colombian

2

2

Acme, Inc.

French_Roast

2

LEFT JOIN
id

name

name

supId

1

Superior Coffee

Colombian

2

2

Acme, Inc.

French_Roast

2
Outer join pattern
suppliers.leftJoin(coffees)
.on(_.id === _.supId)
.map{ case(s,c) => (s,(c.name.?,c.supId.?,ā€¦)) }
.run
.map{ case (s,c) =>
(s,c._1.map(_ => Coffee(c._1.get,c._2.get,ā€¦))) }
// Generated outer join helper
suppliers.leftJoin(coffees)
.on(_.id === _.supId)
.map{ case(s,c) => (s,c.?) }
.run
CUSTOMIZABLE Code
generatION
Using code generator as a library
val metaModel = db.withSession{ implicit session =>
profile.metaModel // e.g. H2Driver.metaModel
}
import scala.slick.meta.codegen.SourceCodeGenerator
val codegen = new SourceCodeGenerator(metaModel){
// <- customize here
}
codegen.writeToFile(
profile = "scala.slick.driver.H2Driverā€,
folder = "src/main/scala/",
pkg = "demo",
container = "Tables",
fileName="Tables.scala" )
Adjust name mapping
import scala.slick.util.StringExtensions._
val codegen =
new SourceCodeGenerator(metaModel){
override def tableName
= _.toLowerCase.toCamelCase
override def entityName
= tableName(_).dropRight(1)
}
Generate auto-join conditions 1
class CustomizedCodeGenerator(metaModel: Model)
extends SourceCodeGenerator(metaModel){
override def code = {
super.code + "nn" + s"""
/** implicit join conditions for auto joins */
object AutoJoins{
${indent(joins.mkString("n"))}
}
""".trim()
}
ā€¦
Generate auto-join conditions 2
ā€¦
val joins = tables.flatMap( _.foreignKeys.map{ foreignKey =>
import foreignKey._
val fkt = referencingTable.tableClassName
val pkt = referencedTable.tableClassName
val columns = referencingColumns.map(_.name) zip
referencedColumns.map(_.name)
s"implicit def autojoin${name.capitalize} "+
" = (left:${fkt},right:${pkt}) => " +
columns.map{
case (lcol,rcol) =>
"left."+lcol + " === " + "right."+rcol
}.mkString(" && ")
}
Other uses of Slick code generation
ā€¢ Glue code (Play, etc.)
ā€¢ n-n join code
ā€¢ Migrating databases (warning: types
change)
(generate from MySQL, create in
Postgres)
ā€¢ Generate repetitive regarding data model
(aka model driven software engineering)
ā€¢ Generate DDL for external model
Use code generation wisely
ā€¢ Donā€™t loose language-level abstraction
ā€¢ Add your generator and data model to
version control
ā€¢ Complete but new and therefor
experimental in Slick
Dynamic Queries
Common use case for web apps
Dynamically decide
ā€¢ displayed columns
ā€¢ filter conditions
ā€¢ sort columns / order
Dynamic column
class Coffees(tag: Tag)
extends Table[CoffeeRow](ā€¦){
val name = column[String]("COF_NAME",ā€¦)
}

coffees.map(c => c.name)
coffees.map(c =>
c.column[String]("COF_NAME")
)

Be careful about security!
Example: sortDynamic

suppliers.sortDynamic("street.desc,city.desc")
sortDynamic 1
implicit class QueryExtensions3[E,T<: Table[E]]
( val query: Query[T,E] ){
def sortDynamic(sortString: String) : Query[T,E] = {
// split string into useful pieces
val sortKeys = sortString.split(',').toList.map(
_.split('.').map(_.toUpperCase).toList )
sortDynamicImpl(sortKeys)
}
private def sortDynamicImpl(sortKeys: List[Seq[String]]) = ???
}

suppliers.sortDynamic("street.desc,city.desc")
sortDynamic 2
...
private def sortDynamicImpl(sortKeys: List[Seq[String]]) : Query[T,E] = {
sortKeys match {
case key :: tail =>
sortDynamicImpl( tail ).sortBy( table =>
key match {
case name :: Nil =>
table.column[String](name).asc
case name :: "ASC" :: Nil => table.column[String](name).asc
case name :: "DESC" :: Nil => table.column[String](name).desc
case o => throw new Exception("invalid sorting key: "+o)
}
)
case Nil => query
}
}
}
suppliers.sortDynamic("street.desc,city.desc")
Summary
ā€¢ Query composition and re-use
ā€¢ Getting rid of boiler plate in Slick 2.0
ā€“
ā€“
ā€“

outer joins / auto joins
auto increment
code generation

ā€¢ Dynamic Slick queries
Thank you

#scalax
slick.typesafe.com
@cvogt
http://slick.typesafe.com/talks/
https://github.com/cvogt/slick-presentation/tree/scala-exchange-2013
filterDynamic
coffees.filterDynamic("COF_NAME like Decaf")

More Related Content

What's hot

WASMļ¼ˆWebAssemblyļ¼‰å…„門 ćƒšć‚¢ćƒŖćƒ³ć‚°ę¼”ē®—ć‚„ć£ć¦ćæ恟
WASMļ¼ˆWebAssemblyļ¼‰å…„門 ćƒšć‚¢ćƒŖćƒ³ć‚°ę¼”ē®—ć‚„ć£ć¦ćæ恟WASMļ¼ˆWebAssemblyļ¼‰å…„門 ćƒšć‚¢ćƒŖćƒ³ć‚°ę¼”ē®—ć‚„ć£ć¦ćæ恟
WASMļ¼ˆWebAssemblyļ¼‰å…„門 ćƒšć‚¢ćƒŖćƒ³ć‚°ę¼”ē®—ć‚„ć£ć¦ćæ恟MITSUNARI Shigeo
Ā 
JJUG CCC 2017 Fall ć‚Ŗ惬ć‚Ŗ惬JVMč؀čŖžć‚’ä½œć£ć¦ćæ悋
JJUG CCC 2017 Fall ć‚Ŗ惬ć‚Ŗ惬JVMč؀čŖžć‚’ä½œć£ć¦ćæ悋JJUG CCC 2017 Fall ć‚Ŗ惬ć‚Ŗ惬JVMč؀čŖžć‚’ä½œć£ć¦ćæ悋
JJUG CCC 2017 Fall ć‚Ŗ惬ć‚Ŗ惬JVMč؀čŖžć‚’ä½œć£ć¦ćæ悋Koichi Sakata
Ā 
Scala 初åæƒč€…ćŒē±³ē”°ć®č£œé”Œć‚’ Scala ć§č€ƒćˆć¦ćæ恟
Scala 初åæƒč€…ćŒē±³ē”°ć®č£œé”Œć‚’ Scala ć§č€ƒćˆć¦ćæ恟Scala 初åæƒč€…ćŒē±³ē”°ć®č£œé”Œć‚’ Scala ć§č€ƒćˆć¦ćæ恟
Scala 初åæƒč€…ćŒē±³ē”°ć®č£œé”Œć‚’ Scala ć§č€ƒćˆć¦ćæ恟Kazuyuki TAKASE
Ā 
AWSć‚¹ćƒćƒƒćƒˆć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć®ēœŸé«„
AWSć‚¹ćƒćƒƒćƒˆć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć®ēœŸé«„AWSć‚¹ćƒćƒƒćƒˆć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć®ēœŸé«„
AWSć‚¹ćƒćƒƒćƒˆć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć®ēœŸé«„外道 ēˆ¶
Ā 
Rustć§ę„½ć—ć‚€ē«¶ęŠ€ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°
Rustć§ę„½ć—ć‚€ē«¶ęŠ€ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°Rustć§ę„½ć—ć‚€ē«¶ęŠ€ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°
Rustć§ę„½ć—ć‚€ē«¶ęŠ€ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°yoshrc
Ā 
Reflection power pointpresentation ppt
Reflection power pointpresentation pptReflection power pointpresentation ppt
Reflection power pointpresentation pptRohit Vipin Mathews
Ā 
V8 javascript engine for ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰ćƒ‡ćƒ™ćƒ­ćƒƒćƒ‘ćƒ¼
V8 javascript engine for ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰ćƒ‡ćƒ™ćƒ­ćƒƒćƒ‘ćƒ¼V8 javascript engine for ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰ćƒ‡ćƒ™ćƒ­ćƒƒćƒ‘ćƒ¼
V8 javascript engine for ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰ćƒ‡ćƒ™ćƒ­ćƒƒćƒ‘ćƒ¼Taketoshi 青野偄利
Ā 
å…„é–€Transducers
å…„é–€Transducerså…„é–€Transducers
å…„é–€Transducerssohta
Ā 
Firebase A/B Testing悒ä½æć£ć¦ć‚µćƒ¼ćƒå“ć¾ć§A/Bćƒ†ć‚¹ćƒˆć—ćŸč©±(Android)
Firebase A/B Testing悒ä½æć£ć¦ć‚µćƒ¼ćƒå“ć¾ć§A/Bćƒ†ć‚¹ćƒˆć—ćŸč©±(Android)Firebase A/B Testing悒ä½æć£ć¦ć‚µćƒ¼ćƒå“ć¾ć§A/Bćƒ†ć‚¹ćƒˆć—ćŸč©±(Android)
Firebase A/B Testing悒ä½æć£ć¦ć‚µćƒ¼ćƒå“ć¾ć§A/Bćƒ†ć‚¹ćƒˆć—ćŸč©±(Android)gree_tech
Ā 
SQLäøŠē“šč€…ć“ćēŸ„ć£ć¦ę¬²ć—ć„ć€ćŖ恜O/Rćƒžćƒƒćƒ‘ćƒ¼ćŒé‡č¦ć‹ļ¼Ÿ
SQLäøŠē“šč€…ć“ćēŸ„ć£ć¦ę¬²ć—ć„ć€ćŖ恜O/Rćƒžćƒƒćƒ‘ćƒ¼ćŒé‡č¦ć‹ļ¼ŸSQLäøŠē“šč€…ć“ćēŸ„ć£ć¦ę¬²ć—ć„ć€ćŖ恜O/Rćƒžćƒƒćƒ‘ćƒ¼ćŒé‡č¦ć‹ļ¼Ÿ
SQLäøŠē“šč€…ć“ćēŸ„ć£ć¦ę¬²ć—ć„ć€ćŖ恜O/Rćƒžćƒƒćƒ‘ćƒ¼ćŒé‡č¦ć‹ļ¼Ÿkwatch
Ā 
ćƒ‰ćƒ”ć‚¤ćƒ³ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®č¦‹ć¤ć‘ę–¹ćƒ»ä½œć‚Šę–¹ćƒ»č‚²ć¦ę–¹
ćƒ‰ćƒ”ć‚¤ćƒ³ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®č¦‹ć¤ć‘ę–¹ćƒ»ä½œć‚Šę–¹ćƒ»č‚²ć¦ę–¹ćƒ‰ćƒ”ć‚¤ćƒ³ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®č¦‹ć¤ć‘ę–¹ćƒ»ä½œć‚Šę–¹ćƒ»č‚²ć¦ę–¹
ćƒ‰ćƒ”ć‚¤ćƒ³ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®č¦‹ć¤ć‘ę–¹ćƒ»ä½œć‚Šę–¹ćƒ»č‚²ć¦ę–¹å¢—ē”° äŗØ
Ā 
åˆęŽ¢ Kotlin Multiplatform
åˆęŽ¢ Kotlin MultiplatformåˆęŽ¢ Kotlin Multiplatform
åˆęŽ¢ Kotlin MultiplatformShengyou Fan
Ā 
[JJUG CCC 2021 Spring]Eclipse ćƒ¦ćƒ¼ć‚¶ć®ćŸć‚ć® VSCode ć®ć‚¹ć‚¹ćƒ”
[JJUG CCC 2021 Spring]Eclipse ćƒ¦ćƒ¼ć‚¶ć®ćŸć‚ć® VSCode ć®ć‚¹ć‚¹ćƒ”[JJUG CCC 2021 Spring]Eclipse ćƒ¦ćƒ¼ć‚¶ć®ćŸć‚ć® VSCode ć®ć‚¹ć‚¹ćƒ”
[JJUG CCC 2021 Spring]Eclipse ćƒ¦ćƒ¼ć‚¶ć®ćŸć‚ć® VSCode ć®ć‚¹ć‚¹ćƒ”Satoshi Takami
Ā 
å®Ÿč·µćƒ»ęœ€å¼·ęœ€é€Ÿć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å‹‰å¼·ä¼š ē¬¬äø‰å›žč¬›ē¾©č³‡ę–™(ćƒÆćƒ¼ć‚Æć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚ŗ & AtCoder)
å®Ÿč·µćƒ»ęœ€å¼·ęœ€é€Ÿć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å‹‰å¼·ä¼š ē¬¬äø‰å›žč¬›ē¾©č³‡ę–™(ćƒÆćƒ¼ć‚Æć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚ŗ & AtCoder)å®Ÿč·µćƒ»ęœ€å¼·ęœ€é€Ÿć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å‹‰å¼·ä¼š ē¬¬äø‰å›žč¬›ē¾©č³‡ę–™(ćƒÆćƒ¼ć‚Æć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚ŗ & AtCoder)
å®Ÿč·µćƒ»ęœ€å¼·ęœ€é€Ÿć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å‹‰å¼·ä¼š ē¬¬äø‰å›žč¬›ē¾©č³‡ę–™(ćƒÆćƒ¼ć‚Æć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚ŗ & AtCoder)AtCoder Inc.
Ā 
č»¢ē½®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØTop k-query
č»¢ē½®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØTop k-queryč»¢ē½®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØTop k-query
č»¢ē½®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØTop k-queryę­£åæ— åŖ坂
Ā 
GraalVM恮ē“¹ä»‹ćØTruffle恧PHPć½ć„č؀čŖžć‚’å®Ÿč£…ć—ćŸć‚‰ēˆ†é€Ÿć ć£ćŸč©±
GraalVM恮ē“¹ä»‹ćØTruffle恧PHPć½ć„č؀čŖžć‚’å®Ÿč£…ć—ćŸć‚‰ēˆ†é€Ÿć ć£ćŸč©±GraalVM恮ē“¹ä»‹ćØTruffle恧PHPć½ć„č؀čŖžć‚’å®Ÿč£…ć—ćŸć‚‰ēˆ†é€Ÿć ć£ćŸč©±
GraalVM恮ē“¹ä»‹ćØTruffle恧PHPć½ć„č؀čŖžć‚’å®Ÿč£…ć—ćŸć‚‰ēˆ†é€Ÿć ć£ćŸč©±ćŖ恊恍 恍恗恠
Ā 
ć‚Ŗćƒšć‚¢ćƒ³ćƒ—ćØć‚¢ćƒŠćƒ­ć‚°č؈ē®—ę©Ÿ
ć‚Ŗćƒšć‚¢ćƒ³ćƒ—ćØć‚¢ćƒŠćƒ­ć‚°č؈ē®—ę©Ÿć‚Ŗćƒšć‚¢ćƒ³ćƒ—ćØć‚¢ćƒŠćƒ­ć‚°č؈ē®—ę©Ÿ
ć‚Ŗćƒšć‚¢ćƒ³ćƒ—ćØć‚¢ćƒŠćƒ­ć‚°č؈ē®—ę©ŸToshiyuki Masui
Ā 
悄恕恗恄ꕓꕰ論
悄恕恗恄ꕓꕰ論悄恕恗恄ꕓꕰ論
悄恕恗恄ꕓꕰ論Kazuma Mikami
Ā 

What's hot (20)

WASMļ¼ˆWebAssemblyļ¼‰å…„門 ćƒšć‚¢ćƒŖćƒ³ć‚°ę¼”ē®—ć‚„ć£ć¦ćæ恟
WASMļ¼ˆWebAssemblyļ¼‰å…„門 ćƒšć‚¢ćƒŖćƒ³ć‚°ę¼”ē®—ć‚„ć£ć¦ćæ恟WASMļ¼ˆWebAssemblyļ¼‰å…„門 ćƒšć‚¢ćƒŖćƒ³ć‚°ę¼”ē®—ć‚„ć£ć¦ćæ恟
WASMļ¼ˆWebAssemblyļ¼‰å…„門 ćƒšć‚¢ćƒŖćƒ³ć‚°ę¼”ē®—ć‚„ć£ć¦ćæ恟
Ā 
JJUG CCC 2017 Fall ć‚Ŗ惬ć‚Ŗ惬JVMč؀čŖžć‚’ä½œć£ć¦ćæ悋
JJUG CCC 2017 Fall ć‚Ŗ惬ć‚Ŗ惬JVMč؀čŖžć‚’ä½œć£ć¦ćæ悋JJUG CCC 2017 Fall ć‚Ŗ惬ć‚Ŗ惬JVMč؀čŖžć‚’ä½œć£ć¦ćæ悋
JJUG CCC 2017 Fall ć‚Ŗ惬ć‚Ŗ惬JVMč؀čŖžć‚’ä½œć£ć¦ćæ悋
Ā 
Scala 初åæƒč€…ćŒē±³ē”°ć®č£œé”Œć‚’ Scala ć§č€ƒćˆć¦ćæ恟
Scala 初åæƒč€…ćŒē±³ē”°ć®č£œé”Œć‚’ Scala ć§č€ƒćˆć¦ćæ恟Scala 初åæƒč€…ćŒē±³ē”°ć®č£œé”Œć‚’ Scala ć§č€ƒćˆć¦ćæ恟
Scala 初åæƒč€…ćŒē±³ē”°ć®č£œé”Œć‚’ Scala ć§č€ƒćˆć¦ćæ恟
Ā 
AWSć‚¹ćƒćƒƒćƒˆć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć®ēœŸé«„
AWSć‚¹ćƒćƒƒćƒˆć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć®ēœŸé«„AWSć‚¹ćƒćƒƒćƒˆć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć®ēœŸé«„
AWSć‚¹ćƒćƒƒćƒˆć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć®ēœŸé«„
Ā 
Rustć§ę„½ć—ć‚€ē«¶ęŠ€ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°
Rustć§ę„½ć—ć‚€ē«¶ęŠ€ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°Rustć§ę„½ć—ć‚€ē«¶ęŠ€ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°
Rustć§ę„½ć—ć‚€ē«¶ęŠ€ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°
Ā 
Reflection power pointpresentation ppt
Reflection power pointpresentation pptReflection power pointpresentation ppt
Reflection power pointpresentation ppt
Ā 
V8 javascript engine for ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰ćƒ‡ćƒ™ćƒ­ćƒƒćƒ‘ćƒ¼
V8 javascript engine for ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰ćƒ‡ćƒ™ćƒ­ćƒƒćƒ‘ćƒ¼V8 javascript engine for ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰ćƒ‡ćƒ™ćƒ­ćƒƒćƒ‘ćƒ¼
V8 javascript engine for ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰ćƒ‡ćƒ™ćƒ­ćƒƒćƒ‘ćƒ¼
Ā 
å…„é–€Transducers
å…„é–€Transducerså…„é–€Transducers
å…„é–€Transducers
Ā 
Firebase A/B Testing悒ä½æć£ć¦ć‚µćƒ¼ćƒå“ć¾ć§A/Bćƒ†ć‚¹ćƒˆć—ćŸč©±(Android)
Firebase A/B Testing悒ä½æć£ć¦ć‚µćƒ¼ćƒå“ć¾ć§A/Bćƒ†ć‚¹ćƒˆć—ćŸč©±(Android)Firebase A/B Testing悒ä½æć£ć¦ć‚µćƒ¼ćƒå“ć¾ć§A/Bćƒ†ć‚¹ćƒˆć—ćŸč©±(Android)
Firebase A/B Testing悒ä½æć£ć¦ć‚µćƒ¼ćƒå“ć¾ć§A/Bćƒ†ć‚¹ćƒˆć—ćŸč©±(Android)
Ā 
SQLäøŠē“šč€…ć“ćēŸ„ć£ć¦ę¬²ć—ć„ć€ćŖ恜O/Rćƒžćƒƒćƒ‘ćƒ¼ćŒé‡č¦ć‹ļ¼Ÿ
SQLäøŠē“šč€…ć“ćēŸ„ć£ć¦ę¬²ć—ć„ć€ćŖ恜O/Rćƒžćƒƒćƒ‘ćƒ¼ćŒé‡č¦ć‹ļ¼ŸSQLäøŠē“šč€…ć“ćēŸ„ć£ć¦ę¬²ć—ć„ć€ćŖ恜O/Rćƒžćƒƒćƒ‘ćƒ¼ćŒé‡č¦ć‹ļ¼Ÿ
SQLäøŠē“šč€…ć“ćēŸ„ć£ć¦ę¬²ć—ć„ć€ćŖ恜O/Rćƒžćƒƒćƒ‘ćƒ¼ćŒé‡č¦ć‹ļ¼Ÿ
Ā 
ćƒ‰ćƒ”ć‚¤ćƒ³ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®č¦‹ć¤ć‘ę–¹ćƒ»ä½œć‚Šę–¹ćƒ»č‚²ć¦ę–¹
ćƒ‰ćƒ”ć‚¤ćƒ³ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®č¦‹ć¤ć‘ę–¹ćƒ»ä½œć‚Šę–¹ćƒ»č‚²ć¦ę–¹ćƒ‰ćƒ”ć‚¤ćƒ³ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®č¦‹ć¤ć‘ę–¹ćƒ»ä½œć‚Šę–¹ćƒ»č‚²ć¦ę–¹
ćƒ‰ćƒ”ć‚¤ćƒ³ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®č¦‹ć¤ć‘ę–¹ćƒ»ä½œć‚Šę–¹ćƒ»č‚²ć¦ę–¹
Ā 
åˆęŽ¢ Kotlin Multiplatform
åˆęŽ¢ Kotlin MultiplatformåˆęŽ¢ Kotlin Multiplatform
åˆęŽ¢ Kotlin Multiplatform
Ā 
[JJUG CCC 2021 Spring]Eclipse ćƒ¦ćƒ¼ć‚¶ć®ćŸć‚ć® VSCode ć®ć‚¹ć‚¹ćƒ”
[JJUG CCC 2021 Spring]Eclipse ćƒ¦ćƒ¼ć‚¶ć®ćŸć‚ć® VSCode ć®ć‚¹ć‚¹ćƒ”[JJUG CCC 2021 Spring]Eclipse ćƒ¦ćƒ¼ć‚¶ć®ćŸć‚ć® VSCode ć®ć‚¹ć‚¹ćƒ”
[JJUG CCC 2021 Spring]Eclipse ćƒ¦ćƒ¼ć‚¶ć®ćŸć‚ć® VSCode ć®ć‚¹ć‚¹ćƒ”
Ā 
ę–‡å­—åˆ—ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠
ę–‡å­—åˆ—ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ę–‡å­—åˆ—ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠
ę–‡å­—åˆ—ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠
Ā 
å®Ÿč·µćƒ»ęœ€å¼·ęœ€é€Ÿć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å‹‰å¼·ä¼š ē¬¬äø‰å›žč¬›ē¾©č³‡ę–™(ćƒÆćƒ¼ć‚Æć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚ŗ & AtCoder)
å®Ÿč·µćƒ»ęœ€å¼·ęœ€é€Ÿć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å‹‰å¼·ä¼š ē¬¬äø‰å›žč¬›ē¾©č³‡ę–™(ćƒÆćƒ¼ć‚Æć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚ŗ & AtCoder)å®Ÿč·µćƒ»ęœ€å¼·ęœ€é€Ÿć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å‹‰å¼·ä¼š ē¬¬äø‰å›žč¬›ē¾©č³‡ę–™(ćƒÆćƒ¼ć‚Æć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚ŗ & AtCoder)
å®Ÿč·µćƒ»ęœ€å¼·ęœ€é€Ÿć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å‹‰å¼·ä¼š ē¬¬äø‰å›žč¬›ē¾©č³‡ę–™(ćƒÆćƒ¼ć‚Æć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚ŗ & AtCoder)
Ā 
ćƒ—ćƒ­ć‚°ćƒ©ćƒ ć‚’é«˜é€ŸåŒ–ć™ć‚‹č©±
ćƒ—ćƒ­ć‚°ćƒ©ćƒ ć‚’é«˜é€ŸåŒ–ć™ć‚‹č©±ćƒ—ćƒ­ć‚°ćƒ©ćƒ ć‚’é«˜é€ŸåŒ–ć™ć‚‹č©±
ćƒ—ćƒ­ć‚°ćƒ©ćƒ ć‚’é«˜é€ŸåŒ–ć™ć‚‹č©±
Ā 
č»¢ē½®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØTop k-query
č»¢ē½®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØTop k-queryč»¢ē½®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØTop k-query
č»¢ē½®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØTop k-query
Ā 
GraalVM恮ē“¹ä»‹ćØTruffle恧PHPć½ć„č؀čŖžć‚’å®Ÿč£…ć—ćŸć‚‰ēˆ†é€Ÿć ć£ćŸč©±
GraalVM恮ē“¹ä»‹ćØTruffle恧PHPć½ć„č؀čŖžć‚’å®Ÿč£…ć—ćŸć‚‰ēˆ†é€Ÿć ć£ćŸč©±GraalVM恮ē“¹ä»‹ćØTruffle恧PHPć½ć„č؀čŖžć‚’å®Ÿč£…ć—ćŸć‚‰ēˆ†é€Ÿć ć£ćŸč©±
GraalVM恮ē“¹ä»‹ćØTruffle恧PHPć½ć„č؀čŖžć‚’å®Ÿč£…ć—ćŸć‚‰ēˆ†é€Ÿć ć£ćŸč©±
Ā 
ć‚Ŗćƒšć‚¢ćƒ³ćƒ—ćØć‚¢ćƒŠćƒ­ć‚°č؈ē®—ę©Ÿ
ć‚Ŗćƒšć‚¢ćƒ³ćƒ—ćØć‚¢ćƒŠćƒ­ć‚°č؈ē®—ę©Ÿć‚Ŗćƒšć‚¢ćƒ³ćƒ—ćØć‚¢ćƒŠćƒ­ć‚°č؈ē®—ę©Ÿ
ć‚Ŗćƒšć‚¢ćƒ³ćƒ—ćØć‚¢ćƒŠćƒ­ć‚°č؈ē®—ę©Ÿ
Ā 
悄恕恗恄ꕓꕰ論
悄恕恗恄ꕓꕰ論悄恕恗恄ꕓꕰ論
悄恕恗恄ꕓꕰ論
Ā 

Viewers also liked

Slick: Bringing Scalaā€™s Powerful Features to Your Database Access
Slick: Bringing Scalaā€™s Powerful Features to Your Database Access Slick: Bringing Scalaā€™s Powerful Features to Your Database Access
Slick: Bringing Scalaā€™s Powerful Features to Your Database Access Rebecca Grenier
Ā 
Slick 3.0 functional programming and db side effects
Slick 3.0   functional programming and db side effectsSlick 3.0   functional programming and db side effects
Slick 3.0 functional programming and db side effectsJoost de Vries
Ā 
Reactive Database Access With Slick 3
Reactive Database Access With Slick 3Reactive Database Access With Slick 3
Reactive Database Access With Slick 3Igor Mielientiev
Ā 
Slick: A control plane for middleboxes
Slick: A control plane for middleboxesSlick: A control plane for middleboxes
Slick: A control plane for middleboxesOpen Networking Summits
Ā 
Building Scalable, Distributed Job Queues with Redis and Redis::Client
Building Scalable, Distributed Job Queues with Redis and Redis::ClientBuilding Scalable, Distributed Job Queues with Redis and Redis::Client
Building Scalable, Distributed Job Queues with Redis and Redis::ClientMike Friedman
Ā 
Domain Driven Design Experience Report
Domain Driven Design Experience ReportDomain Driven Design Experience Report
Domain Driven Design Experience ReportSkills Matter
Ā 
Slick ā€“ the modern way to access your Data
Slick ā€“ the modern way to access your DataSlick ā€“ the modern way to access your Data
Slick ā€“ the modern way to access your DataJochen Huelss
Ā 
å®Ÿęˆ¦Scala
å®Ÿęˆ¦Scalaå®Ÿęˆ¦Scala
å®Ÿęˆ¦ScalaYuto Suzuki
Ā 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickHermann Hueck
Ā 
Slick - The Structured Way
Slick - The Structured WaySlick - The Structured Way
Slick - The Structured WayYennick Trevels
Ā 
CQRS and what it means for your architecture
CQRS and what it means for your architectureCQRS and what it means for your architecture
CQRS and what it means for your architectureRichard Banks
Ā 
Reactive database access with Slick3
Reactive database access with Slick3Reactive database access with Slick3
Reactive database access with Slick3takezoe
Ā 
Architecting Microservices in .Net
Architecting Microservices in .NetArchitecting Microservices in .Net
Architecting Microservices in .NetRichard Banks
Ā 
Akka in Practice: Designing Actor-based Applications
Akka in Practice: Designing Actor-based ApplicationsAkka in Practice: Designing Actor-based Applications
Akka in Practice: Designing Actor-based ApplicationsNLJUG
Ā 
Modern SQL in Open Source and Commercial Databases
Modern SQL in Open Source and Commercial DatabasesModern SQL in Open Source and Commercial Databases
Modern SQL in Open Source and Commercial DatabasesMarkus Winand
Ā 

Viewers also liked (16)

Slick: Bringing Scalaā€™s Powerful Features to Your Database Access
Slick: Bringing Scalaā€™s Powerful Features to Your Database Access Slick: Bringing Scalaā€™s Powerful Features to Your Database Access
Slick: Bringing Scalaā€™s Powerful Features to Your Database Access
Ā 
Slick 3.0 functional programming and db side effects
Slick 3.0   functional programming and db side effectsSlick 3.0   functional programming and db side effects
Slick 3.0 functional programming and db side effects
Ā 
Reactive Database Access With Slick 3
Reactive Database Access With Slick 3Reactive Database Access With Slick 3
Reactive Database Access With Slick 3
Ā 
Slick: A control plane for middleboxes
Slick: A control plane for middleboxesSlick: A control plane for middleboxes
Slick: A control plane for middleboxes
Ā 
Building Scalable, Distributed Job Queues with Redis and Redis::Client
Building Scalable, Distributed Job Queues with Redis and Redis::ClientBuilding Scalable, Distributed Job Queues with Redis and Redis::Client
Building Scalable, Distributed Job Queues with Redis and Redis::Client
Ā 
Domain Driven Design Experience Report
Domain Driven Design Experience ReportDomain Driven Design Experience Report
Domain Driven Design Experience Report
Ā 
Slick ā€“ the modern way to access your Data
Slick ā€“ the modern way to access your DataSlick ā€“ the modern way to access your Data
Slick ā€“ the modern way to access your Data
Ā 
å®Ÿęˆ¦Scala
å®Ÿęˆ¦Scalaå®Ÿęˆ¦Scala
å®Ÿęˆ¦Scala
Ā 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with Slick
Ā 
Slick - The Structured Way
Slick - The Structured WaySlick - The Structured Way
Slick - The Structured Way
Ā 
CQRS and what it means for your architecture
CQRS and what it means for your architectureCQRS and what it means for your architecture
CQRS and what it means for your architecture
Ā 
Reactive database access with Slick3
Reactive database access with Slick3Reactive database access with Slick3
Reactive database access with Slick3
Ā 
Spark Hands-on
Spark Hands-onSpark Hands-on
Spark Hands-on
Ā 
Architecting Microservices in .Net
Architecting Microservices in .NetArchitecting Microservices in .Net
Architecting Microservices in .Net
Ā 
Akka in Practice: Designing Actor-based Applications
Akka in Practice: Designing Actor-based ApplicationsAkka in Practice: Designing Actor-based Applications
Akka in Practice: Designing Actor-based Applications
Ā 
Modern SQL in Open Source and Commercial Databases
Modern SQL in Open Source and Commercial DatabasesModern SQL in Open Source and Commercial Databases
Modern SQL in Open Source and Commercial Databases
Ā 

Similar to Patterns for slick database applications

The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196Mahmoud Samir Fayed
Ā 
Rainer Grimm, ā€œFunctional Programming in C++11ā€
Rainer Grimm, ā€œFunctional Programming in C++11ā€Rainer Grimm, ā€œFunctional Programming in C++11ā€
Rainer Grimm, ā€œFunctional Programming in C++11ā€Platonov Sergey
Ā 
Mock Hell PyCon DE and PyData Berlin 2019
Mock Hell PyCon DE and PyData Berlin 2019Mock Hell PyCon DE and PyData Berlin 2019
Mock Hell PyCon DE and PyData Berlin 2019Edwin Jung
Ā 
The Ring programming language version 1.5.2 book - Part 29 of 181
The Ring programming language version 1.5.2 book - Part 29 of 181The Ring programming language version 1.5.2 book - Part 29 of 181
The Ring programming language version 1.5.2 book - Part 29 of 181Mahmoud Samir Fayed
Ā 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
Ā 
The Ring programming language version 1.10 book - Part 54 of 212
The Ring programming language version 1.10 book - Part 54 of 212The Ring programming language version 1.10 book - Part 54 of 212
The Ring programming language version 1.10 book - Part 54 of 212Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.4.1 book - Part 13 of 31
The Ring programming language version 1.4.1 book - Part 13 of 31The Ring programming language version 1.4.1 book - Part 13 of 31
The Ring programming language version 1.4.1 book - Part 13 of 31Mahmoud Samir Fayed
Ā 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
Ā 
The Ring programming language version 1.8 book - Part 50 of 202
The Ring programming language version 1.8 book - Part 50 of 202The Ring programming language version 1.8 book - Part 50 of 202
The Ring programming language version 1.8 book - Part 50 of 202Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.4 book - Part 8 of 30
The Ring programming language version 1.4 book - Part 8 of 30The Ring programming language version 1.4 book - Part 8 of 30
The Ring programming language version 1.4 book - Part 8 of 30Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.9 book - Part 53 of 210
The Ring programming language version 1.9 book - Part 53 of 210The Ring programming language version 1.9 book - Part 53 of 210
The Ring programming language version 1.9 book - Part 53 of 210Mahmoud Samir Fayed
Ā 
R programming language
R programming languageR programming language
R programming languageAlberto Minetti
Ā 
The Ring programming language version 1.5.3 book - Part 40 of 184
The Ring programming language version 1.5.3 book - Part 40 of 184The Ring programming language version 1.5.3 book - Part 40 of 184
The Ring programming language version 1.5.3 book - Part 40 of 184Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.5.1 book - Part 43 of 180
The Ring programming language version 1.5.1 book - Part 43 of 180The Ring programming language version 1.5.1 book - Part 43 of 180
The Ring programming language version 1.5.1 book - Part 43 of 180Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.5.1 book - Part 28 of 180
The Ring programming language version 1.5.1 book - Part 28 of 180The Ring programming language version 1.5.1 book - Part 28 of 180
The Ring programming language version 1.5.1 book - Part 28 of 180Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84Mahmoud Samir Fayed
Ā 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189Mahmoud Samir Fayed
Ā 

Similar to Patterns for slick database applications (20)

The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31
Ā 
The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196
Ā 
Rainer Grimm, ā€œFunctional Programming in C++11ā€
Rainer Grimm, ā€œFunctional Programming in C++11ā€Rainer Grimm, ā€œFunctional Programming in C++11ā€
Rainer Grimm, ā€œFunctional Programming in C++11ā€
Ā 
Mock Hell PyCon DE and PyData Berlin 2019
Mock Hell PyCon DE and PyData Berlin 2019Mock Hell PyCon DE and PyData Berlin 2019
Mock Hell PyCon DE and PyData Berlin 2019
Ā 
The Ring programming language version 1.5.2 book - Part 29 of 181
The Ring programming language version 1.5.2 book - Part 29 of 181The Ring programming language version 1.5.2 book - Part 29 of 181
The Ring programming language version 1.5.2 book - Part 29 of 181
Ā 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Ā 
The Ring programming language version 1.10 book - Part 54 of 212
The Ring programming language version 1.10 book - Part 54 of 212The Ring programming language version 1.10 book - Part 54 of 212
The Ring programming language version 1.10 book - Part 54 of 212
Ā 
The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184
Ā 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184
Ā 
The Ring programming language version 1.4.1 book - Part 13 of 31
The Ring programming language version 1.4.1 book - Part 13 of 31The Ring programming language version 1.4.1 book - Part 13 of 31
The Ring programming language version 1.4.1 book - Part 13 of 31
Ā 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
Ā 
The Ring programming language version 1.8 book - Part 50 of 202
The Ring programming language version 1.8 book - Part 50 of 202The Ring programming language version 1.8 book - Part 50 of 202
The Ring programming language version 1.8 book - Part 50 of 202
Ā 
The Ring programming language version 1.4 book - Part 8 of 30
The Ring programming language version 1.4 book - Part 8 of 30The Ring programming language version 1.4 book - Part 8 of 30
The Ring programming language version 1.4 book - Part 8 of 30
Ā 
The Ring programming language version 1.9 book - Part 53 of 210
The Ring programming language version 1.9 book - Part 53 of 210The Ring programming language version 1.9 book - Part 53 of 210
The Ring programming language version 1.9 book - Part 53 of 210
Ā 
R programming language
R programming languageR programming language
R programming language
Ā 
The Ring programming language version 1.5.3 book - Part 40 of 184
The Ring programming language version 1.5.3 book - Part 40 of 184The Ring programming language version 1.5.3 book - Part 40 of 184
The Ring programming language version 1.5.3 book - Part 40 of 184
Ā 
The Ring programming language version 1.5.1 book - Part 43 of 180
The Ring programming language version 1.5.1 book - Part 43 of 180The Ring programming language version 1.5.1 book - Part 43 of 180
The Ring programming language version 1.5.1 book - Part 43 of 180
Ā 
The Ring programming language version 1.5.1 book - Part 28 of 180
The Ring programming language version 1.5.1 book - Part 28 of 180The Ring programming language version 1.5.1 book - Part 28 of 180
The Ring programming language version 1.5.1 book - Part 28 of 180
Ā 
The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84The Ring programming language version 1.2 book - Part 32 of 84
The Ring programming language version 1.2 book - Part 32 of 84
Ā 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189
Ā 

More from Skills Matter

5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard LawrenceSkills Matter
Ā 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmSkills Matter
Ā 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimSkills Matter
Ā 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Skills Matter
Ā 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlSkills Matter
Ā 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsSkills Matter
Ā 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Skills Matter
Ā 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Skills Matter
Ā 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldSkills Matter
Ā 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Skills Matter
Ā 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Skills Matter
Ā 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingSkills Matter
Ā 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveSkills Matter
Ā 
Serendipity-neo4j
Serendipity-neo4jSerendipity-neo4j
Serendipity-neo4jSkills Matter
Ā 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSkills Matter
Ā 
Lug presentation
Lug presentationLug presentation
Lug presentationSkills Matter
Ā 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tSkills Matter
Ā 

More from Skills Matter (20)

5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence
Ā 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Ā 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheim
Ā 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Ā 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Ā 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.js
Ā 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Ā 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Ā 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Ā 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Ā 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#
Ā 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testing
Ā 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-dive
Ā 
Serendipity-neo4j
Serendipity-neo4jSerendipity-neo4j
Serendipity-neo4j
Ā 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
Ā 
Plug 20110217
Plug   20110217Plug   20110217
Plug 20110217
Ā 
Lug presentation
Lug presentationLug presentation
Lug presentation
Ā 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_t
Ā 
Plug saiku
Plug   saikuPlug   saiku
Plug saiku
Ā 
Huguk lily
Huguk lilyHuguk lily
Huguk lily
Ā 

Recently uploaded

The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfFIDO Alliance
Ā 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Skynet Technologies
Ā 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfSrushith Repakula
Ā 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewDianaGray10
Ā 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceSamy Fodil
Ā 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptxFIDO Alliance
Ā 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform EngineeringMarcus Vechiato
Ā 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024Lorenzo Miniero
Ā 
Vector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptxVector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptxjbellis
Ā 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger FoundationHyperleger Tokyo Meetup
Ā 
Top 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTop 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTopCSSGallery
Ā 
ā€œIamnobody89757ā€ Understanding the Mysterious of Digital Identity.pdf
ā€œIamnobody89757ā€ Understanding the Mysterious of Digital Identity.pdfā€œIamnobody89757ā€ Understanding the Mysterious of Digital Identity.pdf
ā€œIamnobody89757ā€ Understanding the Mysterious of Digital Identity.pdfMuhammad Subhan
Ā 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfFIDO Alliance
Ā 
ERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctBrainSell Technologies
Ā 
Portal Kombat : extension du rƩseau de propagande russe
Portal Kombat : extension du rƩseau de propagande russePortal Kombat : extension du rƩseau de propagande russe
Portal Kombat : extension du rĆ©seau de propagande russeäø­ 央ē¤¾
Ā 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfFIDO Alliance
Ā 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Paige Cruz
Ā 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Hiroshi SHIBATA
Ā 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfalexjohnson7307
Ā 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch TuesdayIvanti
Ā 

Recently uploaded (20)

The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
Ā 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Ā 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
Ā 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
Ā 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
Ā 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Ā 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
Ā 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
Ā 
Vector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptxVector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptx
Ā 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
Ā 
Top 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTop 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development Companies
Ā 
ā€œIamnobody89757ā€ Understanding the Mysterious of Digital Identity.pdf
ā€œIamnobody89757ā€ Understanding the Mysterious of Digital Identity.pdfā€œIamnobody89757ā€ Understanding the Mysterious of Digital Identity.pdf
ā€œIamnobody89757ā€ Understanding the Mysterious of Digital Identity.pdf
Ā 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Ā 
ERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage Intacct
Ā 
Portal Kombat : extension du rƩseau de propagande russe
Portal Kombat : extension du rƩseau de propagande russePortal Kombat : extension du rƩseau de propagande russe
Portal Kombat : extension du rƩseau de propagande russe
Ā 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Ā 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Ā 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024
Ā 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdf
Ā 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
Ā 

Patterns for slick database applications

  • 1. Patterns for Slick database applications Jan Christopher Vogt, EPFL Slick Team #scalax
  • 2. Recap: What is Slick? (for ( c <- coffees; if c.sales > 999 ) yield c.name).run select "COF_NAME" from "COFFEES" where "SALES" > 999
  • 3. Agenda ā€¢ Query composition and re-use ā€¢ Getting rid of boiler plate in Slick 2.0 ā€“ ā€“ ā€“ outer joins / auto joins auto increment code generation ā€¢ Dynamic Slick queries
  • 5. For-expression desugaring in Scala for ( c <- coffees; if c.sales > 999 ) yield c.name coffees .withFilter(_.sales > 999) .map(_.name)
  • 6. Types in Slick class Coffees(tag: Tag) extends Table[C](tag,"COFFEESā€) { def * = (name, supId, price, sales, total) <> ... val name = column[String]("COF_NAME", O.PrimaryKey) val supId = column[Int]("SUP_ID") val price = column[BigDecimal]("PRICE") val sales = column[Int]("SALES") val total = column[Int]("TOTAL") } lazy val coffees = TableQuery[Coffees] <: Query[Coffees,C] coffees.map(c => c.name) (coffees:TableQuery[Coffees,_]).map( (coffees ).map( (c:Coffees) => (c.name Column[String]) (c.name: (c ) ) ): Query[Column[String],String] )
  • 7. Table extensions class Coffees(tag: Tag) extends Table[C](tag,"COFFEESā€) { ā€¦ val price = column[BigDecimal]("PRICE") val sales = column[Int]("SALES") def revenue = price.asColumnOf[Double] * sales.asColumnOf[Double] } coffees.map(c => c.revenue)
  • 8. Query extensions implicit class QueryExtensions[T,E] ( val q: Query[T,E] ){ def page(no: Int, pageSize: Int = 10) : Query[T,E] = q.drop( (no-1)*pageSize ).take(pageSize) } suppliers.page(5) coffees.sortBy(_.name).page(5)
  • 9. Query extensions by Table implicit class CoffeesExtensions ( val q: Query[Coffees,C] ){ def byName( name: Column[String] ) : Query[Coffees,C] = q.filter(_.name === name).sortBy(_.name) } coffees.byName("ColumbianDecaf").page(5)
  • 10. Query extensions for joins implicit class CoffeesExtensions2( val q: Query[Coffees,C] ){ def withSuppliers (s: Query[Suppliers,S] = Tables.suppliers) : Query[(Coffees,Suppliers),(C,S)] = q.join(s).on(_.supId===_.id) def suppliers (s: Query[Suppliers, S] = Tables.suppliers) : Query[Suppliers, S] = q.withSuppliers(s).map(_._2) } coffees.withSuppliers() : Query[(Coffees,Suppliers),(C,S) coffees.withSuppliers( suppliers.filter(_.city === "Henderson") ) // buyable coffees coffeeShops.coffees().suppliers().withCoffees()
  • 11. Query extensions by Interface trait HasSuppliers{ def supId: Column[Int] } class Coffees(ā€¦) extends Table... with HasSuppliers {ā€¦} class CofInventory(ā€¦) extends Table... with HasSuppliers {ā€¦} implicit class HasSuppliersExtensions[T <: HasSupplier,E] ( val q: Query[T,E] ){ def bySupId(id: Column[Int]): Query[T,E] = q.filter( _.supId === id ) def withSuppliers (s: Query[Suppliers,S] = Tables.suppliers) : Query[(T,Suppliers),(E,S)] = q.join(s).on(_.supId===_.id) def suppliers ... } // available quantities of coffees cofInventory.withSuppliers() .map{ case (i,s) => i.quantity.asColumnOf[String] ++ " of " ++ i.cofName ++ " at " ++ s.name }
  • 12. Query extensions summary ā€¢ Mindshift required! Think code, not monolithic query strings. ā€¢ Stay completely lazy! Keep Query[ā€¦]s as long as you can. ā€¢ Re-use! Write query functions or extensions methods for shorter, better and DRY code.
  • 13. Getting rid of boilerplate
  • 15. Auto joins implicit class QueryExtensions2[T,E] ( val q: Query[T,E] ){ def autoJoin[T2,E2] ( q2:Query[T2,E2] ) ( implicit condition: (T,T2) => Column[Boolean] ) : Query[(T,T2),(E,E2)] = q.join(q2).on(condition) } implicit def joinCondition1 = (c:Coffees,s:Suppliers) => c.supId === s.id coffees.autoJoin( suppliers ) : Query[(Coffees,Suppliers),(C,S)] coffees.autoJoin( suppliers ).map(_._2).autoJoin(cofInventory)
  • 17. Auto incrementing inserts val supplier = Supplier( 0, "Arabian Coffees Inc.", ... ) // now ignores auto-increment column suppliers.insert( supplier ) // includes auto-increment column suppliers.forceInsert( supplier )
  • 19. Code generator for Slick code // runner for default config import scala.slick.meta.codegen.SourceCodeGenerator SourceCodeGenerator.main( Array( "scala.slick.driver.H2Driver", "org.h2.Driver", "jdbc:h2:mem:test", "src/main/scala/", // base src folder "demo" // package ) )
  • 20. Generated code package demo object Tables extends { val profile = scala.slick.driver.H2Driver } with Tables trait Tables { val profile: scala.slick.driver.JdbcProfile import profile.simple._ case class CoffeeRow(name: String, supId: Int, ...) implicit def GetCoffees = GetResult{r => CoffeeRow.tupled((r.<<, ... )) } class Coffees(tag: Tag) extends Table[CoffeeRow](ā€¦){ā€¦} ...
  • 22. Outer join limitation in Slick suppliers.leftJoin(coffees) .on(_.id === _.supId) .run // SlickException: Read NULL value ... id name name supId 1 Superior Coffee NULL NULL 2 Acme, Inc. Colombian 2 2 Acme, Inc. French_Roast 2 LEFT JOIN id name name supId 1 Superior Coffee Colombian 2 2 Acme, Inc. French_Roast 2
  • 23. Outer join pattern suppliers.leftJoin(coffees) .on(_.id === _.supId) .map{ case(s,c) => (s,(c.name.?,c.supId.?,ā€¦)) } .run .map{ case (s,c) => (s,c._1.map(_ => Coffee(c._1.get,c._2.get,ā€¦))) } // Generated outer join helper suppliers.leftJoin(coffees) .on(_.id === _.supId) .map{ case(s,c) => (s,c.?) } .run
  • 25. Using code generator as a library val metaModel = db.withSession{ implicit session => profile.metaModel // e.g. H2Driver.metaModel } import scala.slick.meta.codegen.SourceCodeGenerator val codegen = new SourceCodeGenerator(metaModel){ // <- customize here } codegen.writeToFile( profile = "scala.slick.driver.H2Driverā€, folder = "src/main/scala/", pkg = "demo", container = "Tables", fileName="Tables.scala" )
  • 26. Adjust name mapping import scala.slick.util.StringExtensions._ val codegen = new SourceCodeGenerator(metaModel){ override def tableName = _.toLowerCase.toCamelCase override def entityName = tableName(_).dropRight(1) }
  • 27. Generate auto-join conditions 1 class CustomizedCodeGenerator(metaModel: Model) extends SourceCodeGenerator(metaModel){ override def code = { super.code + "nn" + s""" /** implicit join conditions for auto joins */ object AutoJoins{ ${indent(joins.mkString("n"))} } """.trim() } ā€¦
  • 28. Generate auto-join conditions 2 ā€¦ val joins = tables.flatMap( _.foreignKeys.map{ foreignKey => import foreignKey._ val fkt = referencingTable.tableClassName val pkt = referencedTable.tableClassName val columns = referencingColumns.map(_.name) zip referencedColumns.map(_.name) s"implicit def autojoin${name.capitalize} "+ " = (left:${fkt},right:${pkt}) => " + columns.map{ case (lcol,rcol) => "left."+lcol + " === " + "right."+rcol }.mkString(" && ") }
  • 29. Other uses of Slick code generation ā€¢ Glue code (Play, etc.) ā€¢ n-n join code ā€¢ Migrating databases (warning: types change) (generate from MySQL, create in Postgres) ā€¢ Generate repetitive regarding data model (aka model driven software engineering) ā€¢ Generate DDL for external model
  • 30. Use code generation wisely ā€¢ Donā€™t loose language-level abstraction ā€¢ Add your generator and data model to version control ā€¢ Complete but new and therefor experimental in Slick
  • 32. Common use case for web apps Dynamically decide ā€¢ displayed columns ā€¢ filter conditions ā€¢ sort columns / order
  • 33. Dynamic column class Coffees(tag: Tag) extends Table[CoffeeRow](ā€¦){ val name = column[String]("COF_NAME",ā€¦) } coffees.map(c => c.name) coffees.map(c => c.column[String]("COF_NAME") ) Be careful about security!
  • 35. sortDynamic 1 implicit class QueryExtensions3[E,T<: Table[E]] ( val query: Query[T,E] ){ def sortDynamic(sortString: String) : Query[T,E] = { // split string into useful pieces val sortKeys = sortString.split(',').toList.map( _.split('.').map(_.toUpperCase).toList ) sortDynamicImpl(sortKeys) } private def sortDynamicImpl(sortKeys: List[Seq[String]]) = ??? } suppliers.sortDynamic("street.desc,city.desc")
  • 36. sortDynamic 2 ... private def sortDynamicImpl(sortKeys: List[Seq[String]]) : Query[T,E] = { sortKeys match { case key :: tail => sortDynamicImpl( tail ).sortBy( table => key match { case name :: Nil => table.column[String](name).asc case name :: "ASC" :: Nil => table.column[String](name).asc case name :: "DESC" :: Nil => table.column[String](name).desc case o => throw new Exception("invalid sorting key: "+o) } ) case Nil => query } } } suppliers.sortDynamic("street.desc,city.desc")
  • 37. Summary ā€¢ Query composition and re-use ā€¢ Getting rid of boiler plate in Slick 2.0 ā€“ ā€“ ā€“ outer joins / auto joins auto increment code generation ā€¢ Dynamic Slick queries

Editor's Notes

  1. Not an introductory talk, but with some Scala knowledge you should be able to follow even if you donā€™t know Slick &lt;number&gt;
  2. underlines -&gt; implicit conversions lazy query builder, explicit execution &lt;number&gt;
  3. &lt;number&gt;
  4. Embrace! Slickā€™s single coolest features! &lt;number&gt;
  5. C is element type alias, can be tuple or case class Table is row prototype &lt;number&gt;
  6. asColumn &lt;number&gt;
  7. C is element type of Coffees here, can be Coffee case class or Tuple &lt;number&gt;
  8. thatā€™s the way to do association in slick, because it is lazy, composes val can put into method &lt;number&gt;
  9. string computed server side, which means still lazy and composable &lt;number&gt;
  10. none of what we have seen actually executed the query. just composed. call .run for ONE roundtrip &lt;number&gt;
  11. Run from shell or sbt as sourceGenerator or using separate &lt;number&gt;
  12. // not tied to a driver // entity class // table class // GetResult // Slick Hlists for &gt; 22 columns. &lt;number&gt;
  13. not big problem, when select exact &lt;number&gt;
  14. needs staged sbt build or manual execution &lt;number&gt;
  15. interfaces still useful &lt;number&gt;
  16. Limitations: - type is string - using db name Can use reflection instead &lt;number&gt;
  17. &lt;number&gt;
  18. https://github.com/cvogt/slick-presentation/tree/scala-exchange-2013 &lt;number&gt;