Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.fullfacing.dsl
- import com.mongodb.casbah.Imports._
- import scala.util.parsing.combinator.syntactical.StandardTokenParsers
- /**
- * Project: com.fullfacing.dsl
- * Created on 2015/05/19.
- * ryno aka lemonxah -
- * https://github.com/lemonxah
- * http://stackoverflow.com/users/2919672/lemon-xah
- */
- sealed trait Statement
- case class GreaterOrEqual(field: String, value: String) extends Statement
- case class GreaterThan(field: String, value: String) extends Statement
- case class LessOrEqual(field: String, value: String) extends Statement
- case class LessThan(field: String, value: String) extends Statement
- case class Equals(field: String, value: String) extends Statement
- case class NotEquals(field: String, value: String) extends Statement
- sealed trait Literal[A] { val v: A }
- case class Field(v: String) extends Literal[String]
- case class StringValue(v: String) extends Literal[String]
- case class IntValue(v: Int) extends Literal[Int]
- case class LongValue(v: Long) extends Literal[Long]
- case class Operation(v: String) extends Literal[String]
- object Interpreter extends StandardTokenParsers with App {
- def result(s: String) = phrase(program)(new lexical.Scanner(s.split("&&").reduceLeft(_ + '\n' + _)))
- def program = stmt+
- def stmt = field ~ op ~ value ^^ {
- case field ~ o ~ value => (o.v match {
- case "==" => Equals
- case "!=" => NotEquals
- case "<" => LessThan
- case ">" => GreaterThan
- case ">=" => GreaterOrEqual
- case "<=" => LessOrEqual
- })(field.v, value.v.toString)
- }
- def field = stringLit ^^ {case s => Field(s) }
- def value = stringLit ^^ {case s => StringValue(s)} | numericLit ^^ {case s => IntValue(s.toInt)}
- def op = stringLit ^^ { case s => Operation(s)}
- def getStatements(s: String): Option[List[Statement]] = result(s) match {
- case Success(tree, _) => Some(tree)
- case e: NoSuccess =>
- println(e)
- None
- }
- object QueryLanguage {
- sealed trait QueryTrait {
- self: Query =>
- def and(q: Query): Query = Query(s"$self && $q")
- override def toString = self.q
- }
- case class Query(q: String) extends QueryTrait
- sealed trait Field[E] {
- val cn: String
- def ===(value: E): Query = combine("==", value)
- def !==(value: E): Query = combine("!=", value)
- def <(value: E): Query = combine("<", value)
- def >(value: E): Query = combine(">", value)
- def >=(value: E): Query = combine(">=", value)
- def <=(value: E): Query = combine("<=", value)
- def combine(op: String, value: E): Query = Query(s"'$cn' '$op' $value")
- }
- sealed trait StringField extends Field[String] {
- override def combine(op: String, value: String): Query = Query(s"'$cn' '$op' '$value'")
- }
- object Test {
- object name extends StringField { override val cn = "name"}
- object age extends Field[Int] { override val cn = "age"}
- object shoesize extends Field[Int] { override val cn = "shoesize"}
- object showsize extends Field[Int] { override val cn = "showsize"}
- }
- }
- import QueryLanguage._
- def statement = "'name' '==' 'Zandre' && 'age' '>' 21 && 'shoesize' '<' 12 && 'showsize' '>=' 22"
- def query = (Test.name === "Zandre") and (Test.age > 21) and (Test.shoesize < 12) and (Test.showsize >= 22)
- println(statement)
- println(query.q)
- def q = getStatements(query.q) match {
- case Some(list) => Some(list.map {
- case Equals(f, v) => f $eq v
- case GreaterOrEqual(f, v) => f $gte v
- case GreaterThan(f, v) => f $gt v
- case LessOrEqual(f, v) => f $lte v
- case LessThan(f, v) => f $lt v
- case NotEquals(f, v) => f $ne v
- }.foldLeft(MongoDBObject())(_ ++ _))
- case None => None
- }
- println(getStatements(statement))
- println(q)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement