Ejemplo n.º 1
0
 public function interpretQuery(TokenSequencerInterface $query)
 {
     $this->reset();
     $this->query = $query;
     $sql = "DELETE FROM " . $this->renderArbitraryReference($query->getEntityMetadata()->getCollection());
     while ($token = $query->getNextToken()) {
         $sql .= " " . $this->renderToken($token);
     }
     return $sql;
 }
Ejemplo n.º 2
0
 /**
  * @param TokenSequencerInterface $query
  * @param $condition
  * @param bool|false $prefixFieldWithCollection
  * @param bool|true $addLogicOperator
  * @throws RepositoryException
  */
 protected function addConditionToQuery(TokenSequencerInterface $query, $condition, $prefixFieldWithCollection = false, $addLogicOperator = true)
 {
     // normalise $condition
     $field = $condition["field"];
     $op = strtolower($condition["op"]);
     $value = $condition["value"];
     $inverted = !empty($condition["inverted"]);
     $related = $field;
     if ($query->getEntityMetadata()->hasRelationship($field)) {
         $relationship = $query->getEntityMetadata()->getRelationship($field);
         if (empty($relationship) || $relationship[EntityMetadata::METADATA_RELATIONSHIP_TYPE] == EntityMetadata::RELATIONSHIP_TYPE_ONE_TO_MANY) {
             $ourField = null;
         } else {
             $ourField = empty($relationship[EntityMetadata::METADATA_RELATIONSHIP_OUR_FIELD]) ? null : $relationship[EntityMetadata::METADATA_RELATIONSHIP_OUR_FIELD];
             if (empty($ourField) && $relationship[EntityMetadata::METADATA_RELATIONSHIP_TYPE] == EntityMetadata::RELATIONSHIP_TYPE_MANY_TO_MANY) {
                 // our field is the join collection field which references the foreign collection
                 $joinCollection = $relationship[EntityMetadata::METADATA_RELATIONSHIP_JOIN_TABLE];
                 $childMetadata = $this->metadataProvider->getEntityMetadata($relationship[EntityMetadata::METADATA_ENTITY]);
                 $ourField = $joinCollection . "." . $childMetadata->getCollection() . "_" . $childMetadata->getPrimaryKey();
             }
         }
         if (empty($ourField)) {
             throw new RepositoryException("No field could be found for the relationship '{$field}'");
         }
         $field = $ourField;
         $related = $relationship;
     }
     // if any value is an entity, get the value from the entity for the field we're looking for
     if (is_array($value)) {
         foreach ($value as $i => $entity) {
             $value[$i] = $this->getRelatedValueFromEntity($entity, $related);
         }
     } else {
         $value = $this->getRelatedValueFromEntity($value, $related);
     }
     if ($prefixFieldWithCollection && strpos($field, ".") === false) {
         $field = $this->collectionName . "." . $field;
     }
     // sprinkle with logic operators to taste
     if ($addLogicOperator) {
         // We do not need to allow for the OR operator. Complex queries that require OR are best written in custom methods
         $query->andL();
     }
     if ($inverted) {
         $query->notL();
     }
     // add condition to the query
     $query->ref($field)->op($op);
     switch ($op) {
         case "in":
             $query->closure($value);
             break;
         case "between":
             $query->val($value[0])->andL()->val($value[1]);
             break;
         default:
             $query->val($value);
             break;
     }
 }
Ejemplo n.º 3
0
 public function interpretQuery(TokenSequencerInterface $query)
 {
     $this->reset();
     $this->query = $query;
     $includes = $query->getIncludes();
     $mainMetadata = $query->getEntityMetadata();
     $mainCollection = $mainMetadata->getCollection();
     $token = $query->getNextToken();
     $this->fields = [];
     while (!empty($token) && in_array($token->getType(), ["function", "field"])) {
         if ($token->getType() == "function") {
             /** @var Value $token */
             // render the aggregate function SQL e.g. COUNT(*), SUM(field), etc...
             $fieldSql = $this->renderFunction($token);
             // create an alias for this aggregate and append the SQL
             $collectionAlias = $this->findFreeAlias($token->getValue(), $this->fields);
             $fieldSql .= $this->renderAlias($collectionAlias);
         } else {
             /** @var Reference $token */
             $fieldName = $mainCollection . "." . $token->getValue();
             $collectionAlias = $this->getSelectFieldAlias($fieldName);
             $fieldSql = $this->renderArbitraryReference($fieldName, $collectionAlias);
         }
         // add the sql to the fields array and load the next token
         $this->fields[$collectionAlias] = $fieldSql;
         $token = $query->getNextToken();
     }
     // if we had no aggregate functions in the sequence, then this is a standard select query
     // so, we need to get the fields to return from the entity metadata for each
     if (empty($this->fields)) {
         $metadata = $mainMetadata;
         $collectionAlias = $mainCollection;
         do {
             if (empty($metadata)) {
                 continue;
             }
             // for each entity field, create an aliased SQL reference
             $entityFields = $metadata->getFieldNames();
             sort($entityFields);
             foreach ($entityFields as $field) {
                 $field = $collectionAlias . "." . $field;
                 $thisFieldAlias = $this->getSelectFieldAlias($field);
                 $this->fields[$thisFieldAlias] = $this->renderArbitraryReference($field, $thisFieldAlias);
             }
         } while (list($collectionAlias, $metadata) = each($includes));
     }
     if (empty($this->fields)) {
         throw new InterpretationException("Cannot interpret find query, there are no fields to return");
     }
     // if this query has an include, it's more complex and requires separate processing
     if (count($includes) > 0) {
         return $this->renderIncludeQuery($token);
     }
     // simple, no include query. Render all remaining tokens
     $sql = "SELECT " . implode(", ", $this->fields) . " FROM " . $this->renderArbitraryReference($mainCollection);
     // render all other tokens
     do {
         if (empty($token)) {
             break;
         }
         $sql .= " " . $this->renderToken($token);
     } while ($token = $this->query->getNextToken());
     return $sql;
 }