/
SingleStepTrail.scala
93 lines (74 loc) · 3.23 KB
/
SingleStepTrail.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* Copyright (c) 2002-2012 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.cypher.internal.pipes.matching
import org.neo4j.graphdb.{PropertyContainer, Direction}
import org.neo4j.cypher.internal.commands.{True, Pattern, Predicate}
import org.neo4j.graphdb.DynamicRelationshipType._
import org.neo4j.cypher.internal.symbols.{RelationshipType, NodeType, SymbolTable}
final case class SingleStepTrail(next: Trail,
dir: Direction,
relName: String,
typ: Seq[String],
start: String,
relPred: Option[Predicate],
nodePred: Option[Predicate],
pattern: Pattern) extends Trail {
def end = next.end
def pathDescription = next.pathDescription ++ Seq(relName, end)
def toSteps(id: Int) = {
val steps = next.toSteps(id + 1)
val relPredicate = relPred.getOrElse(True())
val nodePredicate = nodePred.getOrElse(True())
Some(SingleStep(id, typ, dir, steps, relPredicate, nodePredicate))
}
def size = next.size + 1
protected[matching] def decompose(p: Seq[PropertyContainer], m: Map[String, Any]): Iterator[(Seq[PropertyContainer], Map[String, Any])] =
if (p.size < 2) {
Iterator()
} else {
val thisRel = p.tail.head
val thisNode = p.head
val a = m.get(relName)
val b = m.get(start)
if ((a.nonEmpty && a.get != thisRel)||(b.nonEmpty && b.get != thisNode)) {
Iterator()
} else {
val newMap = m + (relName -> thisRel) + (start -> thisNode)
next.decompose(p.tail.tail, newMap)
}
}
def symbols(table: SymbolTable): SymbolTable =
next.symbols(table).add(start, NodeType()).add(relName, RelationshipType())
def contains(target: String): Boolean = next.contains(target) || target == end
def predicates = nodePred.toSeq ++ relPred.toSeq ++ next.predicates
def patterns = next.patterns :+ pattern
override def toString = {
val left = if (Direction.INCOMING == dir) "<" else ""
val right = if (Direction.OUTGOING == dir) ">" else ""
val t = typ match {
case List() => ""
case x => typ.mkString(":", "|", "")
}
"(%s)%s-[%s%s]-%s%s".format(start, left, relName, t, right, next.toString)
}
def nodeNames = Seq(start) ++ next.nodeNames
def add(f: (String) => Trail) = copy(next = next.add(f))
def filter(f: (Trail) => Boolean):Iterable[Trail] = Some(this).filter(f) ++ next.filter(f)
}