1 | <?php |
||
27 | class QueryResultCollection implements IQueryResultCollection |
||
28 | { |
||
29 | /** |
||
30 | * @var \SplObjectStorage |
||
31 | */ |
||
32 | protected $storage; |
||
33 | |||
34 | /** |
||
35 | * @var callable |
||
36 | */ |
||
37 | protected $traversableFactory; |
||
38 | |||
39 | public function __construct(callable $traversableFactory = null) |
||
44 | |||
45 | public function optimizeQuery(O\Expression $queryExpression) |
||
69 | |||
70 | protected function removeGetTrueIteratorCall(O\Expression $queryExpression) |
||
85 | |||
86 | public function saveResults(O\Expression $expression, $results) |
||
90 | |||
91 | public function clearResults() |
||
95 | |||
96 | public function removeResults(O\Expression $queryExpression) |
||
100 | |||
101 | public function tryComputeResults(O\Expression $queryExpression, &$results) |
||
102 | { |
||
103 | if (isset($this->storage[$queryExpression])) { |
||
104 | $results = $this->storage[$queryExpression]; |
||
105 | |||
106 | return true; |
||
107 | } |
||
108 | |||
109 | $foundApplicableResults = false; |
||
110 | |||
111 | //Searches the query expression tree and checks if any parent expressions have saved results |
||
112 | //If so, the expression tree is updated with a Traversable implementation with the saved results |
||
113 | $applicableScopeFinder = |
||
114 | function (O\Expression $expression, O\ExpressionWalker $self) use (&$foundApplicableResults) { |
||
115 | if (isset($this->storage[$expression])) { |
||
116 | $foundApplicableResults = true; |
||
117 | |||
118 | return O\Expression::value($this->newTraversable($this->storage[$expression])); |
||
119 | } |
||
120 | |||
121 | if ($expression instanceof O\ValueExpression) { |
||
122 | return $expression; |
||
123 | } |
||
124 | |||
125 | /** @var $expression O\TraversalExpression */ |
||
126 | |||
127 | return $expression->updateValue($self->walk($expression->getValue())); |
||
128 | }; |
||
129 | |||
130 | $traversalWalker = new O\DynamicExpressionWalker([ |
||
131 | O\TraversalExpression::getType() => $applicableScopeFinder, |
||
132 | O\ValueExpression::getType() => $applicableScopeFinder |
||
133 | ]); |
||
134 | |||
135 | $remainingQueryExpression = $traversalWalker->walk($queryExpression); |
||
136 | |||
137 | //If found applicable results, execute the updated expression tree against the Traversable |
||
138 | //implementation to compute the result of the query. |
||
139 | $results = $foundApplicableResults ? $remainingQueryExpression->evaluate() : null; |
||
140 | |||
141 | return $foundApplicableResults; |
||
142 | } |
||
143 | |||
144 | public function computeResults(O\Expression $expression) |
||
154 | |||
155 | protected function newTraversable($values) |
||
161 | } |
||
162 |