SlideShare a Scribd company logo
1 of 57
Download to read offline
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?

More Related Content

What's hot

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
 

What's hot (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
 

Viewers also liked

지식의 시각화
지식의 시각화지식의 시각화
지식의 시각화은지 조
 
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
 

Viewers also liked (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
 

Similar to 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
 

Similar to 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
 

Recently uploaded

Air Compressor reciprocating single stage
Air Compressor reciprocating single stageAir Compressor reciprocating single stage
Air Compressor reciprocating single stageAbc194748
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . pptDineshKumar4165
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfJiananWang21
 
Work-Permit-Receiver-in-Saudi-Aramco.pptx
Work-Permit-Receiver-in-Saudi-Aramco.pptxWork-Permit-Receiver-in-Saudi-Aramco.pptx
Work-Permit-Receiver-in-Saudi-Aramco.pptxJuliansyahHarahap1
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesMayuraD1
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VDineshKumar4165
 
Bridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptxBridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptxnuruddin69
 
A Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna MunicipalityA Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna MunicipalityMorshed Ahmed Rahath
 
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxA CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxmaisarahman1
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARKOUSTAV SARKAR
 
Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptNANDHAKUMARA10
 
Rums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfRums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfsmsksolar
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Servicemeghakumariji156
 
Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaOmar Fathy
 
Learn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic MarksLearn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic MarksMagic Marks
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.Kamal Acharya
 
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptxHOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptxSCMS School of Architecture
 
DC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationDC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationBhangaleSonal
 
School management system project Report.pdf
School management system project Report.pdfSchool management system project Report.pdf
School management system project Report.pdfKamal Acharya
 

Recently uploaded (20)

Air Compressor reciprocating single stage
Air Compressor reciprocating single stageAir Compressor reciprocating single stage
Air Compressor reciprocating single stage
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . ppt
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
Work-Permit-Receiver-in-Saudi-Aramco.pptx
Work-Permit-Receiver-in-Saudi-Aramco.pptxWork-Permit-Receiver-in-Saudi-Aramco.pptx
Work-Permit-Receiver-in-Saudi-Aramco.pptx
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakes
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - V
 
Bridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptxBridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptx
 
A Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna MunicipalityA Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna Municipality
 
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxA CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
 
Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.ppt
 
Rums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfRums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdf
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
 
Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS Lambda
 
Learn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic MarksLearn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic Marks
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.
 
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptxHOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
HOA1&2 - Module 3 - PREHISTORCI ARCHITECTURE OF KERALA.pptx
 
DC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationDC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equation
 
School management system project Report.pdf
School management system project Report.pdfSchool management system project Report.pdf
School management system project Report.pdf
 

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