SlideShare ist ein Scribd-Unternehmen logo
1 von 57
Downloaden Sie, um offline zu lesen
N
Embedding a language into string
interpolator
Mikhail Limanskiy
June 10, 2015
String interpolation is easy
val language = "English"
String interpolation is easy
val language = "English"
val embedded = s"Embedded $language"
MongoDB
MongoDB is a document oriented database, storing BSON documents.
db.people.insert({ name: "John Doe", age: 42 })
MongoDB
MongoDB is a document oriented database, storing BSON documents.
db.people.insert({ name: "John Doe", age: 42 })
db.people.insert({
name: "William Smith",
age: 28,
phone: [ "1234567", "7654321" ]
})
MongoDB
MongoDB is a document oriented database, storing BSON documents.
db.people.insert({ name: "John Doe", age: 42 })
db.people.insert({
name: "William Smith",
age: 28,
phone: [ "1234567", "7654321" ]
})
db.people.insert({
name: "Alice White",
age: 29,
address: {
country: "UK",
city: "London"
}
})
MongoDB
MongoDB is a document oriented database, storing BSON documents.
db.people.insert({ name: "John Doe", age: 42 })
db.people.insert({
name: "William Smith",
age: 28,
phone: [ "1234567", "7654321" ]
})
db.people.insert({
name: "Alice White",
age: 29,
address: {
country: "UK",
city: "London"
}
})
db.people.insert({ name : "Ivan Petrov", age : 28 })
Search and update
Quering:
db.people.find({ name: "John Doe"})
db.people.find({ age: { $lt : 30 }})
db.people.find({ phone: { $not: { $size : 0 }}})
Search and update
Quering:
db.people.find({ name: "John Doe"})
db.people.find({ age: { $lt : 30 }})
db.people.find({ phone: { $not: { $size : 0 }}})
db.people.update({ age : 42},
{ $set : { name : "Ford Prefect" } })
Search and update
Quering:
db.people.find({ name: "John Doe"})
db.people.find({ age: { $lt : 30 }})
db.people.find({ phone: { $not: { $size : 0 }}})
db.people.update({ age : 42},
{ $set : { name : "Ford Prefect" } })
db.people.aggregate(
[ { $group : { _id : "$age", count : {$sum : 1} } },
{ $sort : { count : -1 } },
{ $limit : 5 }
])
MongoDB in Scala
There are three main drivers for MongoDB:
Casbah – synchronous, on top of Java driver.
MongoDB in Scala
There are three main drivers for MongoDB:
Casbah – synchronous, on top of Java driver.
ReactiveMongo – asynchronous, built on Akka actors.
MongoDB in Scala
There are three main drivers for MongoDB:
Casbah – synchronous, on top of Java driver.
ReactiveMongo – asynchronous, built on Akka actors.
Tepkin – reactive, on top of Akka IO and Akka Streams.
How Casbah API looks like
val name = "John Doe"
people.insert(MongoDBObject(
"name" -> "James Bond",
"age" -> 80,
"phone" -> List("007007"),
"address" -> MongoDBObject("country" -> "UK")))
How Casbah API looks like
val name = "John Doe"
people.insert(MongoDBObject(
"name" -> "James Bond",
"age" -> 80,
"phone" -> List("007007"),
"address" -> MongoDBObject("country" -> "UK")))
val a = people.findOne(MongoDBObject("name" -> name))
val b = people.find(MongoDBObject("age" ->
MongoDBObject("$lt" -> 30)))
How Casbah API looks like
val name = "John Doe"
people.insert(MongoDBObject(
"name" -> "James Bond",
"age" -> 80,
"phone" -> List("007007"),
"address" -> MongoDBObject("country" -> "UK")))
val a = people.findOne(MongoDBObject("name" -> name))
val b = people.find(MongoDBObject("age" ->
MongoDBObject("$lt" -> 30)))
// Using Casbah DSL
val c = people.find("age" $lt 30)
val d = people.find("phone" -> $not(_ $size 0))
How Casbah API looks like
val name = "John Doe"
people.insert(MongoDBObject(
"name" -> "James Bond",
"age" -> 80,
"phone" -> List("007007"),
"address" -> MongoDBObject("country" -> "UK")))
val a = people.findOne(MongoDBObject("name" -> name))
val b = people.find(MongoDBObject("age" ->
MongoDBObject("$lt" -> 30)))
// Using Casbah DSL
val c = people.find("age" $lt 30)
val d = people.find("phone" -> $not(_ $size 0))
people.update(MongoDBObject("age" -> 42),
$set("name" -> "Ford Prefect"))
How Casbah API looks like
val name = "John Doe"
people.insert(MongoDBObject(
"name" -> "James Bond",
"age" -> 80,
"phone" -> List("007007"),
"address" -> MongoDBObject("country" -> "UK")))
val a = people.findOne(MongoDBObject("name" -> name))
val b = people.find(MongoDBObject("age" ->
MongoDBObject("$lt" -> 30)))
// Using Casbah DSL
val c = people.find("age" $lt 30)
val d = people.find("phone" -> $not(_ $size 0))
people.update(MongoDBObject("age" -> 42),
$set("name" -> "Ford Prefect"))
val e = people.aggregate(List(
MongoDBObject("$group" ->
MongoDBObject("_id" -> "$age", "count" ->
MongoDBObject("$sum" -> 1))),
MongoDBObject("$sort" -> MongoDBObject("count" -> -1)),
MongoDBObject("$limit" -> 5)))
How Casbah API looks like
ReactiveMongo
// Future[BSONDocument]
val a = people.find(BSONDocument("name" -> "John Doe"))
.one[BSONDocument]
// Future[List[Person]]
val b = people.find(BSONDocument("age" ->
BSONDocument("$lt" -> 30))
).cursor[Person].collect[List]()
val futureUpdate = people.update(
BSONDocument("age" -> 42),
BSONDocument("$set" -> BSONDocument("name" -> "Ford Prefect")))
// Future
val e = db.command(RawCommand(BSONDocument(
"aggregate" -> "people",
"pipeline" -> BSONArray(
BSONDocument("$group" ->
BSONDocument("_id" -> "$age",
"count" -> BSONDocument("$sum" -> 1))),
BSONDocument("$sort" -> BSONDocument("count" -> -1)),
BSONDocument("$limit" -> 5)))))
Why?
Meet MongoQuery
Using MongoQuery with Casbah:
import com.github.limansky.mongoquery.casbah._
val name = "John Doe"
val a = people.findOne(mq"{ name : $name }")
Meet MongoQuery
Using MongoQuery with Casbah:
import com.github.limansky.mongoquery.casbah._
val name = "John Doe"
val a = people.findOne(mq"{ name : $name }")
val b = people.find(mq"{age : { $$lt : 30 }}")
Meet MongoQuery
Using MongoQuery with Casbah:
import com.github.limansky.mongoquery.casbah._
val name = "John Doe"
val a = people.findOne(mq"{ name : $name }")
val b = people.find(mq"{age : { $$lt : 30 }}")
val d = people.find(
mq"{ phone : { $$not : { $$size : 0 }}}")
people.update(mq"{ age : 42 }",
mq"{ $$set { name : 'Ford Prefect' }}")
val e = people.aggregate(List(
mq"""{ $$group :
{ _id : "$$age", count : { $$sum : 1 }}}""",
mq"{ $$sort : { count : -1 }}",
mq"{ $$limit : 5}"))
String interpolation
implicit class MongoHelper(val sc: StringContext)
extends AnyVal {
def mq(args: Any*): DBObject = {
Parser.parseQuery(sc.parts, args) match {
case Success(v, _) =>
createObject(v)
case NoSuccess(msg, _) =>
throw new MqException(s"Invalid object: $msg")
}
}
}
String interpolation
implicit class MongoHelper(val sc: StringContext)
extends AnyVal {
def mq(args: Any*): DBObject = {
Parser.parseQuery(sc.parts, args) match {
case Success(v, _) =>
createObject(v)
case NoSuccess(msg, _) =>
throw new MqException(s"Invalid object: $msg")
}
}
}
mq"{ name : $name }"
sc.parts == List("{ name: ", " }")
args = List(name)
String interpolation
Wrapping it into macro
implicit class MongoHelper(val sc: StringContext) extends AnyVal {
def mq(args: Any*): DBObject = macro MongoHelper.mq_impl
}
object MongoHelper {
def mq_impl(c: Context)(args: c.Expr[Any]*):
c.Expr[DBObject] = ???
}
Wrapping it into macro
implicit class MongoHelper(val sc: StringContext) extends AnyVal {
def mq(args: Any*): DBObject = macro MongoHelper.mq_impl
}
object MongoHelper {
def mq_impl(c: Context)(args: c.Expr[Any]*):
c.Expr[DBObject] = {
import c.universe._
val q"$cn(scala.StringContext.apply(..$pTrees))"
= c.prefix.tree
val parsed = parse(c)(pTrees)
wrapObject(c)(parsed, args.map(_.tree).iterator)
}
}
Wrapping it into macro
object MongoHelper {
def parse(c: Context)(pTrees: List[c.Tree]) = {
import c.universe._
val parts = pTrees map {
case Literal(Constant(s: String)) => s
}
parser.parse(parts) match {
case Success(v, _) => v
case NoSuccess(msg, reader) =>
val partIndex = reader.asInstanceOf[PartReader].part
val pos = pTrees(partIndex).pos
c.abort(pos.withPoint(pos.point + reader.offset)),
s"Invalid BSON object: $msg")
}
}
}
Parsing BSON
mq"{ name : $name, age : { $$gte : 18, $$lte : $max }}"
Parsing BSON
mq"{ name : $name, age : { $$gte : 18, $$lte : $max }}"
Lexical
List("{", Field("name"), ":", Placeholder , ",", Field("age"),
":", "{", Keyword("$gte"), ":", NumericLit(18), ",",
Keyword("$lte"), ":", Placeholder , ",", "}", "}")
Parsing BSON
mq"{ name : $name, age : { $$gte : 18, $$lte : $max }}"
Lexical
List("{", Field("name"), ":", Placeholder , ",", Field("age"),
":", "{", Keyword("$gte"), ":", NumericLit(18), ",",
Keyword("$lte"), ":", Placeholder , ",", "}", "}")
Syntactical
Object(List(
(Member("name"), Placeholder),
(Member("age"), Object(List(
(Keyword("$gte"), 18),
(Keyword("$lte"), Placeholder))
))
))
Create objects
protected def wrapObject(c: Context)(obj: Object,
args: Iterator[c.Tree]): c.Expr[DBType] = {
val dbparts = obj.members.map {
case (lv, v) => (lv.asString , wrapValue(c)(v, args))
}
c.Expr(q"com.mongodb.casbah.commons.MongoDBObject(..$dbparts)")
}
Wrapping values
protected def wrapValue(c: Context) (value: Any,
args: Iterator[c.Tree]): c.Expr[Any] = {
import c.universe._
value match {
case BSON.Placeholder =>
c.Expr(args.next())
Wrapping values
protected def wrapValue(c: Context) (value: Any,
args: Iterator[c.Tree]): c.Expr[Any] = {
import c.universe._
value match {
case BSON.Placeholder =>
c.Expr(args.next())
case o: BSON.Object =>
wrapObject(c)(o, args)
Wrapping values
protected def wrapValue(c: Context) (value: Any,
args: Iterator[c.Tree]): c.Expr[Any] = {
import c.universe._
value match {
case BSON.Placeholder =>
c.Expr(args.next())
case o: BSON.Object =>
wrapObject(c)(o, args)
case BSON.Id(id) =>
c.Expr(q"new org.bson.types.ObjectId($id)")
Wrapping values
protected def wrapValue(c: Context) (value: Any,
args: Iterator[c.Tree]): c.Expr[Any] = {
import c.universe._
value match {
case BSON.Placeholder =>
c.Expr(args.next())
case o: BSON.Object =>
wrapObject(c)(o, args)
case BSON.Id(id) =>
c.Expr(q"new org.bson.types.ObjectId($id)")
case a: List[_] =>
val wrapped = a.map(i => wrapValue(c)(i, args))
c.Expr[List[Any]](q"List(..$wrapped)")
Wrapping values
protected def wrapValue(c: Context) (value: Any,
args: Iterator[c.Tree]): c.Expr[Any] = {
import c.universe._
value match {
case BSON.Placeholder =>
c.Expr(args.next())
case o: BSON.Object =>
wrapObject(c)(o, args)
case BSON.Id(id) =>
c.Expr(q"new org.bson.types.ObjectId($id)")
case a: List[_] =>
val wrapped = a.map(i => wrapValue(c)(i, args))
c.Expr[List[Any]](q"List(..$wrapped)")
case v =>
c.Expr[Any](Literal(Constant(v)))
}
}
Type safety
mqt – typechecking interpolator
case class Phone(kind: String, number: String)
case class Person(name: String, age: Int, phone: List[Phone])
mqt – typechecking interpolator
case class Phone(kind: String, number: String)
case class Person(name: String, age: Int, phone: List[Phone])
// OK
persons.update(mq"{}", mqt"{ $$inc : { age : 1 } }"[Person])
persons.find(mqt"{ phone.number : '223322' }"[Person])
mqt – typechecking interpolator
case class Phone(kind: String, number: String)
case class Person(name: String, age: Int, phone: List[Phone])
// OK
persons.update(mq"{}", mqt"{ $$inc : { age : 1 } }"[Person])
persons.find(mqt"{ phone.number : '223322' }"[Person])
// COMPILE ERROR
persons.update(mq"{}", mqt"""{$$set : { nme : "Joe" }}"""[Person])
persons.find(mqt"{ name.1 : 'Joe' }"[Person])
persons.find(mqt"{ phone.num : '223322' }"[Person])
Passing type into intepolator
implicit class MongoHelper(val sc: StringContext) extends AnyVal {
def mq(args: Any*): DBObject = macro MongoHelper.mq_impl
def mqt(args: Any*) = new QueryWrapper
}
class QueryWrapper {
def apply[T]: DBObject = macro MongoHelper.mqt_impl[T]
}
object MongoHelper {
def mqt_impl[T: c.WeakTypeTag](c: Context):
c.Expr[DBObject] = ???
}
Inside mqt_impl
def mqt_impl[T: c.WeakTypeTag](c: Context): c.Expr[DBObject] = {
val q"$cn(scala.StringContext.apply(..$pTrees)).mqt(..$aTrees)"
= c.prefix.tree
val args = aTrees.map(c.Expr(_))
val parsed = parse(c)(pTrees)
checkObject(c)(c.weakTypeOf[T], parsed)
wrapObject(c)(parsed, args.iterator)
}
Verifing the type
def checkType(c: Context)(tpe: c.Type, obj: Object) = {
import c.universe._
val ctor = tpe.decl(termNames.CONSTRUCTOR).asMethod
val params = ctor.paramLists.head
val className = t.typeSymbol.name.toString
val fields = params.map(s => s.name.toString -> s).toMap
obj.members.foreach { case (m, _) =>
if (!fields.contains(m.name)) {
c.abort(c.enclosingPosition ,
s"Class $className doesn't contain field '${m.name}'")
}
}
}
Testing interpolator
it should "support nested objects" in {
val q = mq"""{ user : "Joe", age : {$$gt : 25}}"""
q should equal(MongoDBObject("user" -> "Joe",
"age" -> MongoDBObject("$gt" -> 25)))
}
Testing error scenarios
import scala.reflect.runtime.{ universe => ru }
class CompileTest extends FlatSpec {
val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader]
val cp = cl.getURLs.map(_.getFile).mkString(File.pathSeparator)
val mirror = ru.runtimeMirror(cl)
val tb = mirror.mkToolBox(options = s"-cp $cp")
Testing error scenarios
import scala.reflect.runtime.{ universe => ru }
class CompileTest extends FlatSpec {
val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader]
val cp = cl.getURLs.map(_.getFile).mkString(File.pathSeparator)
val mirror = ru.runtimeMirror(cl)
val tb = mirror.mkToolBox(options = s"-cp $cp")
def getError(q: String): String = {
val e = intercept[ToolBoxError] {
tb.eval(tb.parse(q))
}
e.message
}
Testing error scenarios
import scala.reflect.runtime.{ universe => ru }
class CompileTest extends FlatSpec {
val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader]
val cp = cl.getURLs.map(_.getFile).mkString(File.pathSeparator)
val mirror = ru.runtimeMirror(cl)
val tb = mirror.mkToolBox(options = s"-cp $cp")
def getError(q: String): String = {
val e = intercept[ToolBoxError] {
tb.eval(tb.parse(q))
}
e.message
}
it should "fail on malformed BSON objects" in {
val e = getError("""mq"{ test 5 }" """)
e should include("`:' expected , but 5 found")
}
}
Summary
Cons
Not easy to implement
Summary
Cons
Not easy to implement
Not highlighted in IDE
Summary
Cons
Not easy to implement
Not highlighted in IDE
Pros
Summary
Cons
Not easy to implement
Not highlighted in IDE
Pros
Less limitations on language structure
Summary
Cons
Not easy to implement
Not highlighted in IDE
Pros
Less limitations on language structure
Can preserve existing language
Summary
Cons
Not easy to implement
Not highlighted in IDE
Pros
Less limitations on language structure
Can preserve existing language
Martin said that string interpolation is cool
k
Thanks. Questions?

Weitere ähnliche Inhalte

Was ist angesagt?

MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation FrameworkTyler Brock
 
Agg framework selectgroup feb2015 v2
Agg framework selectgroup feb2015 v2Agg framework selectgroup feb2015 v2
Agg framework selectgroup feb2015 v2MongoDB
 
Webinar: Exploring the Aggregation Framework
Webinar: Exploring the Aggregation FrameworkWebinar: Exploring the Aggregation Framework
Webinar: Exploring the Aggregation FrameworkMongoDB
 
Doing More with MongoDB Aggregation
Doing More with MongoDB AggregationDoing More with MongoDB Aggregation
Doing More with MongoDB AggregationMongoDB
 
Aggregation in MongoDB
Aggregation in MongoDBAggregation in MongoDB
Aggregation in MongoDBKishor Parkhe
 
Aggregation Framework MongoDB Days Munich
Aggregation Framework MongoDB Days MunichAggregation Framework MongoDB Days Munich
Aggregation Framework MongoDB Days MunichNorberto Leite
 
MongoDB Europe 2016 - Advanced MongoDB Aggregation Pipelines
MongoDB Europe 2016 - Advanced MongoDB Aggregation PipelinesMongoDB Europe 2016 - Advanced MongoDB Aggregation Pipelines
MongoDB Europe 2016 - Advanced MongoDB Aggregation PipelinesMongoDB
 
The Aggregation Framework
The Aggregation FrameworkThe Aggregation Framework
The Aggregation FrameworkMongoDB
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation FrameworkCaserta
 
Aggregation Framework
Aggregation FrameworkAggregation Framework
Aggregation FrameworkMongoDB
 
San Francisco Java User Group
San Francisco Java User GroupSan Francisco Java User Group
San Francisco Java User Groupkchodorow
 
はじめてのMongoDB
はじめてのMongoDBはじめてのMongoDB
はじめてのMongoDBTakahiro Inoue
 
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDBMongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDBMongoDB
 
20110514 mongo dbチューニング
20110514 mongo dbチューニング20110514 mongo dbチューニング
20110514 mongo dbチューニングYuichi Matsuo
 
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.GeeksLab Odessa
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance TuningPuneet Behl
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)Night Sailer
 
How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6Maxime Beugnet
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapHoward Lewis Ship
 

Was ist angesagt? (20)

MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
 
Agg framework selectgroup feb2015 v2
Agg framework selectgroup feb2015 v2Agg framework selectgroup feb2015 v2
Agg framework selectgroup feb2015 v2
 
Webinar: Exploring the Aggregation Framework
Webinar: Exploring the Aggregation FrameworkWebinar: Exploring the Aggregation Framework
Webinar: Exploring the Aggregation Framework
 
Indexing
IndexingIndexing
Indexing
 
Doing More with MongoDB Aggregation
Doing More with MongoDB AggregationDoing More with MongoDB Aggregation
Doing More with MongoDB Aggregation
 
Aggregation in MongoDB
Aggregation in MongoDBAggregation in MongoDB
Aggregation in MongoDB
 
Aggregation Framework MongoDB Days Munich
Aggregation Framework MongoDB Days MunichAggregation Framework MongoDB Days Munich
Aggregation Framework MongoDB Days Munich
 
MongoDB Europe 2016 - Advanced MongoDB Aggregation Pipelines
MongoDB Europe 2016 - Advanced MongoDB Aggregation PipelinesMongoDB Europe 2016 - Advanced MongoDB Aggregation Pipelines
MongoDB Europe 2016 - Advanced MongoDB Aggregation Pipelines
 
The Aggregation Framework
The Aggregation FrameworkThe Aggregation Framework
The Aggregation Framework
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
 
Aggregation Framework
Aggregation FrameworkAggregation Framework
Aggregation Framework
 
San Francisco Java User Group
San Francisco Java User GroupSan Francisco Java User Group
San Francisco Java User Group
 
はじめてのMongoDB
はじめてのMongoDBはじめてのMongoDB
はじめてのMongoDB
 
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDBMongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
 
20110514 mongo dbチューニング
20110514 mongo dbチューニング20110514 mongo dbチューニング
20110514 mongo dbチューニング
 
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
Java/Scala Lab: Борис Трофимов - Обжигающая Big Data.
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6How to leverage what's new in MongoDB 3.6
How to leverage what's new in MongoDB 3.6
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
 

Andere mochten auch

지식의 시각화
지식의 시각화지식의 시각화
지식의 시각화은지 조
 
2016 Spring Career Fair Guide
2016 Spring Career Fair Guide2016 Spring Career Fair Guide
2016 Spring Career Fair GuideAbigail Berthold
 
σημειώσεις μαθήματος εισαγωγή στον τουρισμό και την τουριστική οικονομία
σημειώσεις μαθήματος εισαγωγή στον τουρισμό και την τουριστική οικονομίασημειώσεις μαθήματος εισαγωγή στον τουρισμό και την τουριστική οικονομία
σημειώσεις μαθήματος εισαγωγή στον τουρισμό και την τουριστική οικονομίαAnastasia Skendou
 
Reuben L Stewart Risk Manager 2015
Reuben L Stewart Risk Manager 2015Reuben L Stewart Risk Manager 2015
Reuben L Stewart Risk Manager 2015Reuben Stewart
 
Ús del guionet
Ús del guionetÚs del guionet
Ús del guionetmarijocemi
 
Pf mat42 f1_2013_cad2
Pf mat42 f1_2013_cad2Pf mat42 f1_2013_cad2
Pf mat42 f1_2013_cad2eb23briteiros
 
Speaking - cloud computing and the sysop professional - how to get ready
Speaking - cloud computing and the sysop professional - how to get readySpeaking - cloud computing and the sysop professional - how to get ready
Speaking - cloud computing and the sysop professional - how to get readyEduardo Coelho
 
DESARROLLO SUSTENTABLE
DESARROLLO SUSTENTABLEDESARROLLO SUSTENTABLE
DESARROLLO SUSTENTABLEAngiee Garcia
 

Andere mochten auch (13)

confianza
confianzaconfianza
confianza
 
Risk Assessment
Risk AssessmentRisk Assessment
Risk Assessment
 
지식의 시각화
지식의 시각화지식의 시각화
지식의 시각화
 
2016 Spring Career Fair Guide
2016 Spring Career Fair Guide2016 Spring Career Fair Guide
2016 Spring Career Fair Guide
 
ResumeFeb2016
ResumeFeb2016ResumeFeb2016
ResumeFeb2016
 
Matematicas produccion 54 corregida
Matematicas produccion 54 corregidaMatematicas produccion 54 corregida
Matematicas produccion 54 corregida
 
σημειώσεις μαθήματος εισαγωγή στον τουρισμό και την τουριστική οικονομία
σημειώσεις μαθήματος εισαγωγή στον τουρισμό και την τουριστική οικονομίασημειώσεις μαθήματος εισαγωγή στον τουρισμό και την τουριστική οικονομία
σημειώσεις μαθήματος εισαγωγή στον τουρισμό και την τουριστική οικονομία
 
Reuben L Stewart Risk Manager 2015
Reuben L Stewart Risk Manager 2015Reuben L Stewart Risk Manager 2015
Reuben L Stewart Risk Manager 2015
 
Ús del guionet
Ús del guionetÚs del guionet
Ús del guionet
 
Pf mat42 f1_2013_cad2
Pf mat42 f1_2013_cad2Pf mat42 f1_2013_cad2
Pf mat42 f1_2013_cad2
 
Speaking - cloud computing and the sysop professional - how to get ready
Speaking - cloud computing and the sysop professional - how to get readySpeaking - cloud computing and the sysop professional - how to get ready
Speaking - cloud computing and the sysop professional - how to get ready
 
DESARROLLO SUSTENTABLE
DESARROLLO SUSTENTABLEDESARROLLO SUSTENTABLE
DESARROLLO SUSTENTABLE
 
Tarjeta de presentación
Tarjeta de presentaciónTarjeta de presentación
Tarjeta de presentación
 

Ähnlich wie Embedding a language into string interpolator

Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Andrii Lashchenko
 
jQuery Datatables With MongDb
jQuery Datatables With MongDbjQuery Datatables With MongDb
jQuery Datatables With MongDbsliimohara
 
Introduction to MongoDB and Workshop
Introduction to MongoDB and WorkshopIntroduction to MongoDB and Workshop
Introduction to MongoDB and WorkshopAhmedabadJavaMeetup
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
 
Webinar: General Technical Overview of MongoDB for Dev Teams
Webinar: General Technical Overview of MongoDB for Dev TeamsWebinar: General Technical Overview of MongoDB for Dev Teams
Webinar: General Technical Overview of MongoDB for Dev TeamsMongoDB
 
Apache CouchDB Presentation @ Sept. 2104 GTALUG Meeting
Apache CouchDB Presentation @ Sept. 2104 GTALUG MeetingApache CouchDB Presentation @ Sept. 2104 GTALUG Meeting
Apache CouchDB Presentation @ Sept. 2104 GTALUG MeetingMyles Braithwaite
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBMongoDB
 
Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languagesArthur Xavier
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Oliver Gierke
 
Mongo Presentation by Metatagg Solutions
Mongo Presentation by Metatagg SolutionsMongo Presentation by Metatagg Solutions
Mongo Presentation by Metatagg SolutionsMetatagg Solutions
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring DataOliver Gierke
 
Introduction to NOSQL And MongoDB
Introduction to NOSQL And MongoDBIntroduction to NOSQL And MongoDB
Introduction to NOSQL And MongoDBBehrouz Bakhtiari
 
Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Leonardo Soto
 
Herding types with Scala macros
Herding types with Scala macrosHerding types with Scala macros
Herding types with Scala macrosMarina Sigaeva
 

Ähnlich wie Embedding a language into string interpolator (20)

Querying mongo db
Querying mongo dbQuerying mongo db
Querying mongo db
 
Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.
 
Polyglot Persistence
Polyglot PersistencePolyglot Persistence
Polyglot Persistence
 
jQuery Datatables With MongDb
jQuery Datatables With MongDbjQuery Datatables With MongDb
jQuery Datatables With MongDb
 
Introduction to MongoDB and Workshop
Introduction to MongoDB and WorkshopIntroduction to MongoDB and Workshop
Introduction to MongoDB and Workshop
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
Latinoware
LatinowareLatinoware
Latinoware
 
Webinar: General Technical Overview of MongoDB for Dev Teams
Webinar: General Technical Overview of MongoDB for Dev TeamsWebinar: General Technical Overview of MongoDB for Dev Teams
Webinar: General Technical Overview of MongoDB for Dev Teams
 
Apache CouchDB Presentation @ Sept. 2104 GTALUG Meeting
Apache CouchDB Presentation @ Sept. 2104 GTALUG MeetingApache CouchDB Presentation @ Sept. 2104 GTALUG Meeting
Apache CouchDB Presentation @ Sept. 2104 GTALUG Meeting
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDB
 
Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languages
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!
 
Starting out with MongoDB
Starting out with MongoDBStarting out with MongoDB
Starting out with MongoDB
 
Mongo Presentation by Metatagg Solutions
Mongo Presentation by Metatagg SolutionsMongo Presentation by Metatagg Solutions
Mongo Presentation by Metatagg Solutions
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring Data
 
Introduction to NOSQL And MongoDB
Introduction to NOSQL And MongoDBIntroduction to NOSQL And MongoDB
Introduction to NOSQL And MongoDB
 
Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)
 
Herding types with Scala macros
Herding types with Scala macrosHerding types with Scala macros
Herding types with Scala macros
 
MongoDB
MongoDB MongoDB
MongoDB
 

Kürzlich hochgeladen

Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...Call Girls in Nagpur High Profile
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxAsutosh Ranjan
 
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxthe ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxhumanexperienceaaa
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...RajaP95
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations120cr0395
 
Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingrakeshbaidya232001
 
SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )Tsuyoshi Horigome
 
Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxpranjaldaimarysona
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...ranjana rawat
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingrknatarajan
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxupamatechverse
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVRajaP95
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130Suhani Kapoor
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 

Kürzlich hochgeladen (20)

9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxthe ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations
 
Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writing
 
SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )
 
Processing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptxProcessing & Properties of Floor and Wall Tiles.pptx
Processing & Properties of Floor and Wall Tiles.pptx
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptx
 
★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 

Embedding a language into string interpolator

  • 1. N Embedding a language into string interpolator Mikhail Limanskiy June 10, 2015
  • 2. String interpolation is easy val language = "English"
  • 3. String interpolation is easy val language = "English" val embedded = s"Embedded $language"
  • 4. MongoDB MongoDB is a document oriented database, storing BSON documents. db.people.insert({ name: "John Doe", age: 42 })
  • 5. MongoDB MongoDB is a document oriented database, storing BSON documents. db.people.insert({ name: "John Doe", age: 42 }) db.people.insert({ name: "William Smith", age: 28, phone: [ "1234567", "7654321" ] })
  • 6. MongoDB MongoDB is a document oriented database, storing BSON documents. db.people.insert({ name: "John Doe", age: 42 }) db.people.insert({ name: "William Smith", age: 28, phone: [ "1234567", "7654321" ] }) db.people.insert({ name: "Alice White", age: 29, address: { country: "UK", city: "London" } })
  • 7. MongoDB MongoDB is a document oriented database, storing BSON documents. db.people.insert({ name: "John Doe", age: 42 }) db.people.insert({ name: "William Smith", age: 28, phone: [ "1234567", "7654321" ] }) db.people.insert({ name: "Alice White", age: 29, address: { country: "UK", city: "London" } }) db.people.insert({ name : "Ivan Petrov", age : 28 })
  • 8. Search and update Quering: db.people.find({ name: "John Doe"}) db.people.find({ age: { $lt : 30 }}) db.people.find({ phone: { $not: { $size : 0 }}})
  • 9. Search and update Quering: db.people.find({ name: "John Doe"}) db.people.find({ age: { $lt : 30 }}) db.people.find({ phone: { $not: { $size : 0 }}}) db.people.update({ age : 42}, { $set : { name : "Ford Prefect" } })
  • 10. Search and update Quering: db.people.find({ name: "John Doe"}) db.people.find({ age: { $lt : 30 }}) db.people.find({ phone: { $not: { $size : 0 }}}) db.people.update({ age : 42}, { $set : { name : "Ford Prefect" } }) db.people.aggregate( [ { $group : { _id : "$age", count : {$sum : 1} } }, { $sort : { count : -1 } }, { $limit : 5 } ])
  • 11. MongoDB in Scala There are three main drivers for MongoDB: Casbah – synchronous, on top of Java driver.
  • 12. MongoDB in Scala There are three main drivers for MongoDB: Casbah – synchronous, on top of Java driver. ReactiveMongo – asynchronous, built on Akka actors.
  • 13. MongoDB in Scala There are three main drivers for MongoDB: Casbah – synchronous, on top of Java driver. ReactiveMongo – asynchronous, built on Akka actors. Tepkin – reactive, on top of Akka IO and Akka Streams.
  • 14. How Casbah API looks like val name = "John Doe" people.insert(MongoDBObject( "name" -> "James Bond", "age" -> 80, "phone" -> List("007007"), "address" -> MongoDBObject("country" -> "UK")))
  • 15. How Casbah API looks like val name = "John Doe" people.insert(MongoDBObject( "name" -> "James Bond", "age" -> 80, "phone" -> List("007007"), "address" -> MongoDBObject("country" -> "UK"))) val a = people.findOne(MongoDBObject("name" -> name)) val b = people.find(MongoDBObject("age" -> MongoDBObject("$lt" -> 30)))
  • 16. How Casbah API looks like val name = "John Doe" people.insert(MongoDBObject( "name" -> "James Bond", "age" -> 80, "phone" -> List("007007"), "address" -> MongoDBObject("country" -> "UK"))) val a = people.findOne(MongoDBObject("name" -> name)) val b = people.find(MongoDBObject("age" -> MongoDBObject("$lt" -> 30))) // Using Casbah DSL val c = people.find("age" $lt 30) val d = people.find("phone" -> $not(_ $size 0))
  • 17. How Casbah API looks like val name = "John Doe" people.insert(MongoDBObject( "name" -> "James Bond", "age" -> 80, "phone" -> List("007007"), "address" -> MongoDBObject("country" -> "UK"))) val a = people.findOne(MongoDBObject("name" -> name)) val b = people.find(MongoDBObject("age" -> MongoDBObject("$lt" -> 30))) // Using Casbah DSL val c = people.find("age" $lt 30) val d = people.find("phone" -> $not(_ $size 0)) people.update(MongoDBObject("age" -> 42), $set("name" -> "Ford Prefect"))
  • 18. How Casbah API looks like val name = "John Doe" people.insert(MongoDBObject( "name" -> "James Bond", "age" -> 80, "phone" -> List("007007"), "address" -> MongoDBObject("country" -> "UK"))) val a = people.findOne(MongoDBObject("name" -> name)) val b = people.find(MongoDBObject("age" -> MongoDBObject("$lt" -> 30))) // Using Casbah DSL val c = people.find("age" $lt 30) val d = people.find("phone" -> $not(_ $size 0)) people.update(MongoDBObject("age" -> 42), $set("name" -> "Ford Prefect")) val e = people.aggregate(List( MongoDBObject("$group" -> MongoDBObject("_id" -> "$age", "count" -> MongoDBObject("$sum" -> 1))), MongoDBObject("$sort" -> MongoDBObject("count" -> -1)), MongoDBObject("$limit" -> 5)))
  • 19. How Casbah API looks like
  • 20. ReactiveMongo // Future[BSONDocument] val a = people.find(BSONDocument("name" -> "John Doe")) .one[BSONDocument] // Future[List[Person]] val b = people.find(BSONDocument("age" -> BSONDocument("$lt" -> 30)) ).cursor[Person].collect[List]() val futureUpdate = people.update( BSONDocument("age" -> 42), BSONDocument("$set" -> BSONDocument("name" -> "Ford Prefect"))) // Future val e = db.command(RawCommand(BSONDocument( "aggregate" -> "people", "pipeline" -> BSONArray( BSONDocument("$group" -> BSONDocument("_id" -> "$age", "count" -> BSONDocument("$sum" -> 1))), BSONDocument("$sort" -> BSONDocument("count" -> -1)), BSONDocument("$limit" -> 5)))))
  • 21. Why?
  • 22. Meet MongoQuery Using MongoQuery with Casbah: import com.github.limansky.mongoquery.casbah._ val name = "John Doe" val a = people.findOne(mq"{ name : $name }")
  • 23. Meet MongoQuery Using MongoQuery with Casbah: import com.github.limansky.mongoquery.casbah._ val name = "John Doe" val a = people.findOne(mq"{ name : $name }") val b = people.find(mq"{age : { $$lt : 30 }}")
  • 24. Meet MongoQuery Using MongoQuery with Casbah: import com.github.limansky.mongoquery.casbah._ val name = "John Doe" val a = people.findOne(mq"{ name : $name }") val b = people.find(mq"{age : { $$lt : 30 }}") val d = people.find( mq"{ phone : { $$not : { $$size : 0 }}}") people.update(mq"{ age : 42 }", mq"{ $$set { name : 'Ford Prefect' }}") val e = people.aggregate(List( mq"""{ $$group : { _id : "$$age", count : { $$sum : 1 }}}""", mq"{ $$sort : { count : -1 }}", mq"{ $$limit : 5}"))
  • 25. String interpolation implicit class MongoHelper(val sc: StringContext) extends AnyVal { def mq(args: Any*): DBObject = { Parser.parseQuery(sc.parts, args) match { case Success(v, _) => createObject(v) case NoSuccess(msg, _) => throw new MqException(s"Invalid object: $msg") } } }
  • 26. String interpolation implicit class MongoHelper(val sc: StringContext) extends AnyVal { def mq(args: Any*): DBObject = { Parser.parseQuery(sc.parts, args) match { case Success(v, _) => createObject(v) case NoSuccess(msg, _) => throw new MqException(s"Invalid object: $msg") } } } mq"{ name : $name }" sc.parts == List("{ name: ", " }") args = List(name)
  • 28. Wrapping it into macro implicit class MongoHelper(val sc: StringContext) extends AnyVal { def mq(args: Any*): DBObject = macro MongoHelper.mq_impl } object MongoHelper { def mq_impl(c: Context)(args: c.Expr[Any]*): c.Expr[DBObject] = ??? }
  • 29. Wrapping it into macro implicit class MongoHelper(val sc: StringContext) extends AnyVal { def mq(args: Any*): DBObject = macro MongoHelper.mq_impl } object MongoHelper { def mq_impl(c: Context)(args: c.Expr[Any]*): c.Expr[DBObject] = { import c.universe._ val q"$cn(scala.StringContext.apply(..$pTrees))" = c.prefix.tree val parsed = parse(c)(pTrees) wrapObject(c)(parsed, args.map(_.tree).iterator) } }
  • 30. Wrapping it into macro object MongoHelper { def parse(c: Context)(pTrees: List[c.Tree]) = { import c.universe._ val parts = pTrees map { case Literal(Constant(s: String)) => s } parser.parse(parts) match { case Success(v, _) => v case NoSuccess(msg, reader) => val partIndex = reader.asInstanceOf[PartReader].part val pos = pTrees(partIndex).pos c.abort(pos.withPoint(pos.point + reader.offset)), s"Invalid BSON object: $msg") } } }
  • 31. Parsing BSON mq"{ name : $name, age : { $$gte : 18, $$lte : $max }}"
  • 32. Parsing BSON mq"{ name : $name, age : { $$gte : 18, $$lte : $max }}" Lexical List("{", Field("name"), ":", Placeholder , ",", Field("age"), ":", "{", Keyword("$gte"), ":", NumericLit(18), ",", Keyword("$lte"), ":", Placeholder , ",", "}", "}")
  • 33. Parsing BSON mq"{ name : $name, age : { $$gte : 18, $$lte : $max }}" Lexical List("{", Field("name"), ":", Placeholder , ",", Field("age"), ":", "{", Keyword("$gte"), ":", NumericLit(18), ",", Keyword("$lte"), ":", Placeholder , ",", "}", "}") Syntactical Object(List( (Member("name"), Placeholder), (Member("age"), Object(List( (Keyword("$gte"), 18), (Keyword("$lte"), Placeholder)) )) ))
  • 34. Create objects protected def wrapObject(c: Context)(obj: Object, args: Iterator[c.Tree]): c.Expr[DBType] = { val dbparts = obj.members.map { case (lv, v) => (lv.asString , wrapValue(c)(v, args)) } c.Expr(q"com.mongodb.casbah.commons.MongoDBObject(..$dbparts)") }
  • 35. Wrapping values protected def wrapValue(c: Context) (value: Any, args: Iterator[c.Tree]): c.Expr[Any] = { import c.universe._ value match { case BSON.Placeholder => c.Expr(args.next())
  • 36. Wrapping values protected def wrapValue(c: Context) (value: Any, args: Iterator[c.Tree]): c.Expr[Any] = { import c.universe._ value match { case BSON.Placeholder => c.Expr(args.next()) case o: BSON.Object => wrapObject(c)(o, args)
  • 37. Wrapping values protected def wrapValue(c: Context) (value: Any, args: Iterator[c.Tree]): c.Expr[Any] = { import c.universe._ value match { case BSON.Placeholder => c.Expr(args.next()) case o: BSON.Object => wrapObject(c)(o, args) case BSON.Id(id) => c.Expr(q"new org.bson.types.ObjectId($id)")
  • 38. Wrapping values protected def wrapValue(c: Context) (value: Any, args: Iterator[c.Tree]): c.Expr[Any] = { import c.universe._ value match { case BSON.Placeholder => c.Expr(args.next()) case o: BSON.Object => wrapObject(c)(o, args) case BSON.Id(id) => c.Expr(q"new org.bson.types.ObjectId($id)") case a: List[_] => val wrapped = a.map(i => wrapValue(c)(i, args)) c.Expr[List[Any]](q"List(..$wrapped)")
  • 39. Wrapping values protected def wrapValue(c: Context) (value: Any, args: Iterator[c.Tree]): c.Expr[Any] = { import c.universe._ value match { case BSON.Placeholder => c.Expr(args.next()) case o: BSON.Object => wrapObject(c)(o, args) case BSON.Id(id) => c.Expr(q"new org.bson.types.ObjectId($id)") case a: List[_] => val wrapped = a.map(i => wrapValue(c)(i, args)) c.Expr[List[Any]](q"List(..$wrapped)") case v => c.Expr[Any](Literal(Constant(v))) } }
  • 41. mqt – typechecking interpolator case class Phone(kind: String, number: String) case class Person(name: String, age: Int, phone: List[Phone])
  • 42. mqt – typechecking interpolator case class Phone(kind: String, number: String) case class Person(name: String, age: Int, phone: List[Phone]) // OK persons.update(mq"{}", mqt"{ $$inc : { age : 1 } }"[Person]) persons.find(mqt"{ phone.number : '223322' }"[Person])
  • 43. mqt – typechecking interpolator case class Phone(kind: String, number: String) case class Person(name: String, age: Int, phone: List[Phone]) // OK persons.update(mq"{}", mqt"{ $$inc : { age : 1 } }"[Person]) persons.find(mqt"{ phone.number : '223322' }"[Person]) // COMPILE ERROR persons.update(mq"{}", mqt"""{$$set : { nme : "Joe" }}"""[Person]) persons.find(mqt"{ name.1 : 'Joe' }"[Person]) persons.find(mqt"{ phone.num : '223322' }"[Person])
  • 44. Passing type into intepolator implicit class MongoHelper(val sc: StringContext) extends AnyVal { def mq(args: Any*): DBObject = macro MongoHelper.mq_impl def mqt(args: Any*) = new QueryWrapper } class QueryWrapper { def apply[T]: DBObject = macro MongoHelper.mqt_impl[T] } object MongoHelper { def mqt_impl[T: c.WeakTypeTag](c: Context): c.Expr[DBObject] = ??? }
  • 45. Inside mqt_impl def mqt_impl[T: c.WeakTypeTag](c: Context): c.Expr[DBObject] = { val q"$cn(scala.StringContext.apply(..$pTrees)).mqt(..$aTrees)" = c.prefix.tree val args = aTrees.map(c.Expr(_)) val parsed = parse(c)(pTrees) checkObject(c)(c.weakTypeOf[T], parsed) wrapObject(c)(parsed, args.iterator) }
  • 46. Verifing the type def checkType(c: Context)(tpe: c.Type, obj: Object) = { import c.universe._ val ctor = tpe.decl(termNames.CONSTRUCTOR).asMethod val params = ctor.paramLists.head val className = t.typeSymbol.name.toString val fields = params.map(s => s.name.toString -> s).toMap obj.members.foreach { case (m, _) => if (!fields.contains(m.name)) { c.abort(c.enclosingPosition , s"Class $className doesn't contain field '${m.name}'") } } }
  • 47. Testing interpolator it should "support nested objects" in { val q = mq"""{ user : "Joe", age : {$$gt : 25}}""" q should equal(MongoDBObject("user" -> "Joe", "age" -> MongoDBObject("$gt" -> 25))) }
  • 48. Testing error scenarios import scala.reflect.runtime.{ universe => ru } class CompileTest extends FlatSpec { val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader] val cp = cl.getURLs.map(_.getFile).mkString(File.pathSeparator) val mirror = ru.runtimeMirror(cl) val tb = mirror.mkToolBox(options = s"-cp $cp")
  • 49. Testing error scenarios import scala.reflect.runtime.{ universe => ru } class CompileTest extends FlatSpec { val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader] val cp = cl.getURLs.map(_.getFile).mkString(File.pathSeparator) val mirror = ru.runtimeMirror(cl) val tb = mirror.mkToolBox(options = s"-cp $cp") def getError(q: String): String = { val e = intercept[ToolBoxError] { tb.eval(tb.parse(q)) } e.message }
  • 50. Testing error scenarios import scala.reflect.runtime.{ universe => ru } class CompileTest extends FlatSpec { val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader] val cp = cl.getURLs.map(_.getFile).mkString(File.pathSeparator) val mirror = ru.runtimeMirror(cl) val tb = mirror.mkToolBox(options = s"-cp $cp") def getError(q: String): String = { val e = intercept[ToolBoxError] { tb.eval(tb.parse(q)) } e.message } it should "fail on malformed BSON objects" in { val e = getError("""mq"{ test 5 }" """) e should include("`:' expected , but 5 found") } }
  • 52. Summary Cons Not easy to implement Not highlighted in IDE
  • 53. Summary Cons Not easy to implement Not highlighted in IDE Pros
  • 54. Summary Cons Not easy to implement Not highlighted in IDE Pros Less limitations on language structure
  • 55. Summary Cons Not easy to implement Not highlighted in IDE Pros Less limitations on language structure Can preserve existing language
  • 56. Summary Cons Not easy to implement Not highlighted in IDE Pros Less limitations on language structure Can preserve existing language Martin said that string interpolation is cool