Repository: incubator-s2graph
Updated Branches:
  refs/heads/master 2083d136e -> 558264490


Refactor WhereParser to accept GraphElement, not Edge only.


Project: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/commit/3b692fbe
Tree: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/tree/3b692fbe
Diff: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/diff/3b692fbe

Branch: refs/heads/master
Commit: 3b692fbead9accd6f9d0d9764800e15e945c90bb
Parents: 32eb344
Author: DO YUNG YOON <steams...@apache.org>
Authored: Fri Jun 15 14:59:13 2018 +0900
Committer: DO YUNG YOON <steams...@apache.org>
Committed: Fri Jun 15 14:59:13 2018 +0900

----------------------------------------------------------------------
 .../s2graph/core/S2EdgePropertyHelper.scala     |   2 +-
 .../s2graph/core/parsers/WhereParser.scala      | 102 +++++++++++--------
 .../s2graph/core/parsers/WhereParserTest.scala  |  22 +++-
 3 files changed, 81 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/3b692fbe/s2core/src/main/scala/org/apache/s2graph/core/S2EdgePropertyHelper.scala
----------------------------------------------------------------------
diff --git 
a/s2core/src/main/scala/org/apache/s2graph/core/S2EdgePropertyHelper.scala 
b/s2core/src/main/scala/org/apache/s2graph/core/S2EdgePropertyHelper.scala
index 8c609a0..03d9d4c 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/S2EdgePropertyHelper.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/S2EdgePropertyHelper.scala
@@ -55,7 +55,7 @@ object S2EdgePropertyHelper {
       case "label" => 
Option(InnerValLikeWithTs(InnerVal.withStr(e.innerLabel.label, 
e.innerLabel.schemaVersion), e.ts))
       case "direction" => 
Option(InnerValLikeWithTs(InnerVal.withStr(e.getDirection(), 
e.innerLabel.schemaVersion), e.ts))
       case _ =>
-        e.innerLabel.metaPropsInvMap.get(key).map(labelMeta => 
e.propertyValueInner(labelMeta))
+        e.innerLabel.metaPropsInvMap.get(key).map(labelMeta => 
propertyValueInner(e, labelMeta))
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/3b692fbe/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala
----------------------------------------------------------------------
diff --git 
a/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala 
b/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala
index 75e9657..f0d42b2 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala
@@ -19,11 +19,10 @@
 
 package org.apache.s2graph.core.parsers
 
-import org.apache.s2graph.core.GraphExceptions.{LabelNotExistException, 
WhereParserException}
-import org.apache.s2graph.core.schema.{Label, LabelMeta}
-import org.apache.s2graph.core.types.InnerValLike
-import org.apache.s2graph.core.{S2EdgeLike}
+import org.apache.s2graph.core.GraphExceptions.WhereParserException
 import org.apache.s2graph.core.JSONParser._
+import org.apache.s2graph.core._
+import org.apache.s2graph.core.types.InnerValLike
 
 import scala.annotation.tailrec
 import scala.util.Try
@@ -32,21 +31,40 @@ import scala.util.parsing.combinator.JavaTokenParsers
 trait ExtractValue {
   val parent = "_parent."
 
-  def propToInnerVal(edge: S2EdgeLike, key: String) = {
-    val (propKey, parentEdge) = findParentEdge(edge, key)
+  private def throwEx(key: String) = {
+    throw WhereParserException(s"Where clause contains not existing property 
name: $key")
+  }
 
-    val label = parentEdge.innerLabel
-    val metaPropInvMap = label.metaPropsInvMap
-    val labelMeta = metaPropInvMap.getOrElse(propKey, throw 
WhereParserException(s"Where clause contains not existing property name: 
$propKey"))
+  def propToInnerVal(element: GraphElement, key: String): InnerValLike = {
+    element match {
+      case e: S2EdgeLike => edgePropToInnerVal(e, key)
+      case v: S2VertexLike => vertexPropToInnerVal(v, key)
+      case _ => throw new IllegalArgumentException("only 
S2EdgeLike/S2VertexLike supported.")
+    }
+  }
 
-    labelMeta match {
-      case LabelMeta.from => parentEdge.srcVertex.innerId
-      case LabelMeta.to => parentEdge.tgtVertex.innerId
-      case _ => parentEdge.propertyValueInner(labelMeta).innerVal
+  def valueToCompare(element: GraphElement, key: String, value: String): 
InnerValLike = {
+    element match {
+      case e: S2EdgeLike => edgeValueToCompare(e, key, value)
+      case v: S2VertexLike => vertexValueToCompare(v, key, value)
+      case _ => throw new IllegalArgumentException("only 
S2EdgeLike/S2VertexLike supported.")
     }
   }
 
-  def valueToCompare(edge: S2EdgeLike, key: String, value: String) = {
+  private def edgePropToInnerVal(edge: S2EdgeLike, key: String): InnerValLike 
= {
+    val (propKey, parentEdge) = findParentEdge(edge, key)
+
+    val innerValLikeWithTs =
+      S2EdgePropertyHelper.propertyValue(parentEdge, 
propKey).getOrElse(throwEx(propKey))
+
+    innerValLikeWithTs.innerVal
+  }
+
+  private def vertexPropToInnerVal(vertex: S2VertexLike, key: String): 
InnerValLike = {
+    S2VertexPropertyHelper.propertyValue(vertex, key).getOrElse(throwEx(key))
+  }
+
+  private def edgeValueToCompare(edge: S2EdgeLike, key: String, value: 
String): InnerValLike = {
     val label = edge.innerLabel
     if (value.startsWith(parent) || label.metaPropsInvMap.contains(value)) 
propToInnerVal(edge, value)
     else {
@@ -63,6 +81,12 @@ trait ExtractValue {
     }
   }
 
+  private def vertexValueToCompare(vertex: S2VertexLike, key: String, value: 
String): InnerValLike = {
+    val columnMeta = vertex.serviceColumn.metasInvMap.getOrElse(key, throw 
WhereParserException(s"Where clause contains not existing property name: $key"))
+
+    toInnerVal(value, columnMeta.dataType, vertex.serviceColumn.schemaVersion)
+  }
+
   @tailrec
   private def findParent(edge: S2EdgeLike, depth: Int): S2EdgeLike =
     if (depth > 0) findParent(edge.getParentEdges().head.edge, depth - 1)
@@ -87,11 +111,11 @@ trait Clause extends ExtractValue {
 
   def or(otherField: Clause): Clause = Or(this, otherField)
 
-  def filter(edge: S2EdgeLike): Boolean
+  def filter(element: GraphElement): Boolean
 
-  def binaryOp(binOp: (InnerValLike, InnerValLike) => Boolean)(propKey: 
String, value: String)(edge: S2EdgeLike): Boolean = {
-    val propValue = propToInnerVal(edge, propKey)
-    val compValue = valueToCompare(edge, propKey, value)
+  def binaryOp(binOp: (InnerValLike, InnerValLike) => Boolean)(propKey: 
String, value: String)(element: GraphElement): Boolean = {
+    val propValue = propToInnerVal(element, propKey)
+    val compValue = valueToCompare(element, propKey, value)
 
     binOp(propValue, compValue)
   }
@@ -106,29 +130,27 @@ object Where {
 }
 
 case class Where(clauses: Seq[Clause] = Seq.empty[Clause]) {
-  def filter(edge: S2EdgeLike) =
-    if (clauses.isEmpty) true else clauses.map(_.filter(edge)).forall(identity)
+  def filter(element: GraphElement) =
+    if (clauses.isEmpty) true else 
clauses.map(_.filter(element)).forall(identity)
 }
 
 case class Gt(propKey: String, value: String) extends Clause {
-  override def filter(edge: S2EdgeLike): Boolean = binaryOp(_ > _)(propKey, 
value)(edge)
+  override def filter(element: GraphElement): Boolean = binaryOp(_ > 
_)(propKey, value)(element)
 }
 
 case class Lt(propKey: String, value: String) extends Clause {
-  override def filter(edge: S2EdgeLike): Boolean = binaryOp(_ < _)(propKey, 
value)(edge)
+  override def filter(element: GraphElement): Boolean = binaryOp(_ < 
_)(propKey, value)(element)
 }
 
 case class Eq(propKey: String, value: String) extends Clause {
-  override def filter(edge: S2EdgeLike): Boolean = binaryOp(_ == _)(propKey, 
value)(edge)
+  override def filter(element: GraphElement): Boolean = binaryOp(_ == 
_)(propKey, value)(element)
 }
 
 case class InWithoutParent(propKey: String, values: Set[String]) extends 
Clause {
-  override def filter(edge: S2EdgeLike): Boolean = {
-    val label = edge.innerLabel
-
-    val propVal = propToInnerVal(edge, propKey)
+  override def filter(element: GraphElement): Boolean = {
+    val propVal = propToInnerVal(element, propKey)
     val innerVaLs = values.map { value =>
-      toInnerVal(value, label.metaPropsInvMap(propKey).dataType, 
label.schemaVersion)
+      valueToCompare(element, propKey, value)
     }
 
     innerVaLs(propVal)
@@ -136,41 +158,41 @@ case class InWithoutParent(propKey: String, values: 
Set[String]) extends Clause
 }
 
 case class Contains(propKey: String, value: String) extends Clause {
-  override def filter(edge: S2EdgeLike): Boolean = {
-    val propVal = propToInnerVal(edge, propKey)
+  override def filter(element: GraphElement): Boolean = {
+    val propVal = propToInnerVal(element, propKey)
     propVal.value.toString.contains(value)
   }
 }
 
 case class IN(propKey: String, values: Set[String]) extends Clause {
-  override def filter(edge: S2EdgeLike): Boolean = {
-    val propVal = propToInnerVal(edge, propKey)
+  override def filter(element: GraphElement): Boolean = {
+    val propVal = propToInnerVal(element, propKey)
     values.exists { value =>
-      valueToCompare(edge, propKey, value) == propVal
+      valueToCompare(element, propKey, value) == propVal
     }
   }
 }
 
 case class Between(propKey: String, minValue: String, maxValue: String) 
extends Clause {
-  override def filter(edge: S2EdgeLike): Boolean = {
-    val propVal = propToInnerVal(edge, propKey)
-    val minVal = valueToCompare(edge, propKey, minValue)
-    val maxVal = valueToCompare(edge, propKey, maxValue)
+  override def filter(element: GraphElement): Boolean = {
+    val propVal = propToInnerVal(element, propKey)
+    val minVal = valueToCompare(element, propKey, minValue)
+    val maxVal = valueToCompare(element, propKey, maxValue)
 
     minVal <= propVal && propVal <= maxVal
   }
 }
 
 case class Not(self: Clause) extends Clause {
-  override def filter(edge: S2EdgeLike) = !self.filter(edge)
+  override def filter(element: GraphElement) = !self.filter(element)
 }
 
 case class And(left: Clause, right: Clause) extends Clause {
-  override def filter(edge: S2EdgeLike) = left.filter(edge) && 
right.filter(edge)
+  override def filter(element: GraphElement) = left.filter(element) && 
right.filter(element)
 }
 
 case class Or(left: Clause, right: Clause) extends Clause {
-  override def filter(edge: S2EdgeLike) = left.filter(edge) || 
right.filter(edge)
+  override def filter(element: GraphElement) = left.filter(element) || 
right.filter(element)
 }
 
 object WhereParser {

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/3b692fbe/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala
----------------------------------------------------------------------
diff --git 
a/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala 
b/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala
index 342d9c6..0859d9c 100644
--- 
a/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala
+++ 
b/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala
@@ -20,7 +20,7 @@
 package org.apache.s2graph.core.parsers
 
 import org.apache.s2graph.core._
-import org.apache.s2graph.core.schema.{ServiceColumn, Label, LabelMeta}
+import org.apache.s2graph.core.schema._
 import org.apache.s2graph.core.rest.TemplateHelper
 import org.apache.s2graph.core.types._
 import org.apache.s2graph.core.utils.logger
@@ -37,11 +37,11 @@ class WhereParserTest extends FunSuite with Matchers with 
TestCommonWithModels {
   val ts = System.currentTimeMillis()
   val dummyTs = LabelMeta.timestamp -> InnerValLikeWithTs.withLong(ts, ts, 
label.schemaVersion)
 
-  def validate(label: Label)(edge: S2EdgeLike)(sql: String)(expected: Boolean) 
= {
+  def validate(label: Label)(element: GraphElement)(sql: String)(expected: 
Boolean) = {
     def debug(whereOpt: Try[Where]) = {
       println("==================")
       println(s"$whereOpt")
-      println(s"$edge")
+      println(s"$element")
       println("==================")
     }
 
@@ -50,7 +50,7 @@ class WhereParserTest extends FunSuite with Matchers with 
TestCommonWithModels {
       debug(whereOpt)
       whereOpt.get // touch exception
     } else {
-      val ret = whereOpt.get.filter(edge)
+      val ret = whereOpt.get.filter(element)
       if (ret != expected) {
         debug(whereOpt)
       }
@@ -294,4 +294,18 @@ class WhereParserTest extends FunSuite with Matchers with 
TestCommonWithModels {
     println(whereOpt)
   }
 
+  test("test vertex with WhereParser.") {
+    val service = Service.findByName(serviceName).getOrElse(throw new 
IllegalStateException(s"$serviceName is not found."))
+    val column = ServiceColumn.find(service.id.get, 
columnName).getOrElse(throw new IllegalStateException(s"$columnName is not 
found."))
+
+    val vertexId = builder.newVertexId(service, column, 1)
+    val states = Map(ColumnMeta.lastModifiedAtColumn -> InnerVal.withLong(10, 
column.schemaVersion))
+    val vertex = builder.newVertex(vertexId)
+    S2Vertex.fillPropsWithTs(vertex, states)
+
+    val f = validate(label)(vertex) _
+    f(s"lastModifiedAt < 1")(false)
+    f(s"lastModifiedAt > 1")(true)
+    f(s"lastModifiedAt = 10")(true)
+  }
 }

Reply via email to