Permalink
Browse files

Improve queryBuilder, request on action instead of timeline, then, fi…

…lter on joins too ...
  • Loading branch information...
1 parent 8a66553 commit 31109c02072d157be7058b56bf63041a1ed95385 @stephpy committed Dec 28, 2012
@@ -3,6 +3,8 @@
namespace Spy\TimelineBundle\Driver\ORM\QueryBuilder;
use Spy\Timeline\Driver\QueryBuilder\Criteria\Asserter;
+use Spy\TimelineBundle\Driver\ORM\QueryBuilder\Criteria\CriteriaCollection;
+use Spy\TimelineBundle\Driver\ORM\QueryBuilder\Criteria\CriteriaField;
/**
* AsserterVisitor
@@ -13,112 +15,28 @@
class AsserterVisitor implements VisitorInterface
{
/**
- * @var Asserter
+ * @var string
*/
- protected $asserter;
-
- /**
- * @var float
- */
- protected $aliasNumber = 1;
-
- /**
- * @var array
- */
- protected $parameters = array();
+ protected $dql;
/**
* {@inheritdoc}
*/
- public function visit($asserter)
+ public function visit($asserter, CriteriaCollection $criteriaCollection)
{
if (!$asserter instanceof Asserter) {
throw new \Exception('AsserterVisitor accepts only Asserter instance');
}
- $this->asserter = $asserter;
+ $this->dql = $criteriaCollection->addFromAsserter($asserter)
+ ->getDql();
}
/**
* {@inheritdoc}
*/
public function getDql()
{
- $field = $this->getFieldDqlKey();
- $key = str_replace('.', '_', $field).uniqid();
- $value = $this->asserter->getValue();
-
- if ($value instanceof \DateTime) {
- $value = $value->format('Y-m-d H:i:s');
- }
-
- if ('identifier' === $this->asserter->getField()) {
- if (is_scalar($value)) {
- $value = (string) $value;
- }
-
- $value = serialize($value); // identifier is a serialized field.
- }
-
- $this->parameters[$key] = $value;
- $operator = $this->asserter->getOperator();
-
- switch ($operator) {
- case Asserter::ASSERTER_IN:
- case Asserter::ASSERTER_NOT_IN:
- return $field.' '.$operator.' (:'.$key.')';
- break;
- default:
- return $field.' '.$operator.' :'.$key;
- break;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function getNbJoinsNeeded()
- {
- $field = $this->asserter->getField();
-
- return in_array(QueryBuilder::getFieldLocation($field), array(
- 'actionComponent',
- 'component'
- )) ? 1 : 0;
+ return $this->dql;
}
-
- /**
- * {@inheritdoc}
- */
- public function getParameters()
- {
- return $this->parameters;
- }
-
- /**
- * @param integer $aliasNumber aliasNumber
- */
- public function setAliasNumber($aliasNumber)
- {
- $this->aliasNumber = $aliasNumber;
- }
-
- /**
- * @param string $field field
- * @param integer|empty $number number
- *
- * @return string
- */
- public function getFieldDqlKey()
- {
- $field = $this->asserter->getField();
-
- $fieldLocation = QueryBuilder::getFieldLocation($field);
- if (in_array($fieldLocation, array('actionComponent', 'component'))) {
- $fieldLocation .= $this->aliasNumber;
- }
-
- return sprintf('%s.%s', $fieldLocation, $field);
- }
-
}
@@ -0,0 +1,50 @@
+<?php
+
+namespace Spy\TimelineBundle\Driver\ORM\QueryBuilder\Criteria;
+
+use Spy\Timeline\Driver\QueryBuilder\Criteria\Asserter;
+
+/**
+ * CriteriaCollection
+ *
+ * @author Stephane PY <py.stephane1@gmail.com>
+ */
+class CriteriaCollection implements \IteratorAggregate
+{
+ /**
+ * @var array
+ */
+ protected $criterias = array();
+
+ /**
+ * @var integer
+ */
+ protected $aliasNumber = 1;
+
+ /**
+ * @param Asserter $asserter asserter
+ *
+ * @return CriteriaField
+ */
+ public function addFromAsserter(Asserter $asserter)
+ {
+ $criteria = new CriteriaField();
+ $criteria->createFromAsserter($asserter, $this->aliasNumber);
+
+ if ($criteria->isNeedJoin()) {
+ $this->aliasNumber++;
+ }
+
+ $this->criterias[] = $criteria;
+
+ return $criteria;
+ }
+
+ /**
+ * @return ArrayIterator
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->criterias);
+ }
+}
@@ -0,0 +1,130 @@
+<?php
+
+namespace Spy\TimelineBundle\Driver\ORM\QueryBuilder\Criteria;
+
+use Spy\Timeline\Driver\QueryBuilder\Criteria\Asserter;
+use Spy\TimelineBundle\Driver\ORM\QueryBuilder\QueryBuilder;
+
+/**
+ * CriteriaField
+ *
+ * @author Stephane PY <py.stephane1@gmail.com>
+ */
+class CriteriaField
+{
+ /**
+ * @var string
+ */
+ protected $location;
+
+ /**
+ * @var integer
+ */
+ protected $aliasNumber;
+
+ /**
+ * @var boolean
+ */
+ protected $isNeedJoin = false;
+
+ /**
+ * @var array
+ */
+ protected $parameters = array();
+
+ /**
+ * @var string
+ */
+ protected $dql;
+
+ /**
+ * @param Asserter $asserter asserter
+ * @param integer $aliasNumber aliasNumber
+ */
+ public function createFromAsserter(Asserter $asserter, $aliasNumber)
+ {
+ $this->aliasNumber = $aliasNumber;
+ $field = $asserter->getField();
+ $this->location = QueryBuilder::getFieldLocation($field);
+ $this->isNeedJoin = in_array($this->location, array('timeline', 'actionComponent', 'component'));
+ $locationSql = $this->isNeedJoin ? $this->location.$aliasNumber : $this->location;
+ $sqlDefinition = sprintf('%s.%s', $locationSql, $field);
+
+ $parameterKey = str_replace('.', '_', $sqlDefinition).uniqid();
+ $this->parameters[$parameterKey] = $this->transformValue($asserter->getValue(), $field);
+
+ $operator = $asserter->getOperator();
+ switch ($operator) {
+ case Asserter::ASSERTER_IN:
+ case Asserter::ASSERTER_NOT_IN:
+ $this->dql = $sqlDefinition.' '.$operator.' (:'.$parameterKey.')';
+ break;
+ default:
+ $this->dql = $sqlDefinition.' '.$operator.' :'.$parameterKey;
+ break;
+ }
+ }
+
+ /**
+ * @param mixed $value value
+ * @param string $field field
+ *
+ * @return mixed
+ */
+ public function transformValue($value, $field)
+ {
+ if ($value instanceof \DateTime) {
+ $value = $value->format('Y-m-d H:i:s');
+ }
+
+ if ('identifier' === $field) {
+ if (is_scalar($value)) {
+ $value = (string) $value;
+ }
+
+ $value = serialize($value); // identifier is a serialized field.
+ }
+
+ return $value;
+ }
+
+ /**
+ * @return string
+ */
+ public function getLocation()
+ {
+ return $this->location;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isNeedJoin()
+ {
+ return $this->isNeedJoin;
+ }
+
+ /**
+ * @return array
+ */
+ public function getParameters()
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDql()
+ {
+ return $this->dql;
+ }
+
+ /**
+ * @return integer
+ */
+ public function getAliasNumber()
+ {
+ return $this->aliasNumber;
+ }
+}
Oops, something went wrong.

0 comments on commit 31109c0

Please sign in to comment.