/**
  * Sets up required mocks and the CommentStatistics service under test.
  */
 protected function setUp()
 {
     $this->statement = $this->getMockBuilder('Drupal\\Core\\Database\\Driver\\sqlite\\Statement')->disableOriginalConstructor()->getMock();
     $this->statement->expects($this->any())->method('fetchObject')->will($this->returnCallback(array($this, 'fetchObjectCallback')));
     $this->select = $this->getMockBuilder('Drupal\\Core\\Database\\Query\\Select')->disableOriginalConstructor()->getMock();
     $this->select->expects($this->any())->method('fields')->will($this->returnSelf());
     $this->select->expects($this->any())->method('condition')->will($this->returnSelf());
     $this->select->expects($this->any())->method('execute')->will($this->returnValue($this->statement));
     $this->database = $this->getMockBuilder('Drupal\\Core\\Database\\Connection')->disableOriginalConstructor()->getMock();
     $this->database->expects($this->once())->method('select')->will($this->returnValue($this->select));
     $this->commentStatistics = new CommentStatistics($this->database, $this->getMock('Drupal\\Core\\Session\\AccountInterface'), $this->getMock('Drupal\\Core\\Entity\\EntityManagerInterface'), $this->getMock('Drupal\\Core\\State\\StateInterface'));
 }
Example #2
0
 /**
  * Builds the SQL for the join this object represents.
  *
  * @param \Drupal\Core\Database\Query\SelectInterface $select_query
  *   The select query object.
  * @param string $table
  *   The base table to join.
  * @param \Drupal\views\Plugin\views\query\QueryPluginBase $view_query
  *   The source views query.
  */
 public function buildJoin($select_query, $table, $view_query)
 {
     if (empty($this->configuration['table formula'])) {
         $right_table = "{" . $this->table . "}";
     } else {
         $right_table = $this->configuration['table formula'];
     }
     // Add our join condition, using a subquery on the left instead of a field.
     $condition = "({$this->left_query}) = {$table['alias']}.{$this->field}";
     $arguments = array();
     // Tack on the extra.
     // This is just copied verbatim from the parent class, which itself has a
     //   bug: https://www.drupal.org/node/1118100.
     if (isset($this->extra)) {
         if (is_array($this->extra)) {
             $extras = array();
             foreach ($this->extra as $info) {
                 // Figure out the table name. Remember, only use aliases provided
                 // if at all possible.
                 $join_table = '';
                 if (!array_key_exists('table', $info)) {
                     $join_table = $table['alias'] . '.';
                 } elseif (isset($info['table'])) {
                     $join_table = $info['table'] . '.';
                 }
                 $placeholder = ':views_join_condition_' . $select_query->nextPlaceholder();
                 if (is_array($info['value'])) {
                     $operator = !empty($info['operator']) ? $info['operator'] : 'IN';
                     // Transform from IN() notation to = notation if just one value.
                     if (count($info['value']) == 1) {
                         $info['value'] = array_shift($info['value']);
                         $operator = $operator == 'NOT IN' ? '!=' : '=';
                     }
                 } else {
                     $operator = !empty($info['operator']) ? $info['operator'] : '=';
                 }
                 $extras[] = "{$join_table}{$info['field']} {$operator} {$placeholder}";
                 $arguments[$placeholder] = $info['value'];
             }
             if ($extras) {
                 if (count($extras) == 1) {
                     $condition .= ' AND ' . array_shift($extras);
                 } else {
                     $condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')';
                 }
             }
         } elseif ($this->extra && is_string($this->extra)) {
             $condition .= " AND ({$this->extra})";
         }
     }
     $select_query->addJoin($this->type, $right_table, $table['alias'], $condition, $arguments);
 }
Example #3
0
 /**
  * Preprocesses and validates the query.
  *
  * @return bool
  *   TRUE if the validation was successful, FALSE if not.
  *
  * @throws \Drupal\Core\Database\Query\FieldsOverlapException
  * @throws \Drupal\Core\Database\Query\NoFieldsException
  */
 protected function preExecute()
 {
     // Confirm that the user did not try to specify an identical
     // field and default field.
     if (array_intersect($this->insertFields, $this->defaultFields)) {
         throw new FieldsOverlapException('You may not specify the same field to have a value and a schema-default value.');
     }
     if (!empty($this->fromQuery)) {
         // We have to assume that the used aliases match the insert fields.
         // Regular fields are added to the query before expressions, maintain the
         // same order for the insert fields.
         // This behavior can be overridden by calling fields() manually as only the
         // first call to fields() does have an effect.
         $this->fields(array_merge(array_keys($this->fromQuery->getFields()), array_keys($this->fromQuery->getExpressions())));
     } else {
         // Don't execute query without fields.
         if (count($this->insertFields) + count($this->defaultFields) == 0) {
             throw new NoFieldsException('There are no fields available to insert with.');
         }
     }
     // If no values have been added, silently ignore this query. This can happen
     // if values are added conditionally, so we don't want to throw an
     // exception.
     if (!isset($this->insertValues[0]) && count($this->insertFields) > 0 && empty($this->fromQuery)) {
         return FALSE;
     }
     return TRUE;
 }
 /**
  * Translates the string operators to SQL equivalents.
  *
  * @param array $condition
  *   The condition array.
  * @param \Drupal\Core\Database\Query\SelectInterface $sql_query
  *   Select query instance.
  * @param bool|null $case_sensitive
  *   If the condition should be case sensitive or not, NULL if the field does
  *   not define it.
  *
  * @see \Drupal\Core\Database\Query\ConditionInterface::condition()
  */
 public static function translateCondition(&$condition, SelectInterface $sql_query, $case_sensitive)
 {
     // There is nothing to do for IN () queries except for PostgreSQL for which
     // the condition arguments need to have case lowered to support not case
     // sensitive fields.
     if (is_array($condition['value'])) {
         $entityQueryCondition = Database::getConnection()->getDriverClass('EntityQuery\\Condition');
         $entityQueryCondition::translateCondition($condition, $case_sensitive);
         return;
     }
     // Ensure that the default operator is set to simplify the cases below.
     if (empty($condition['operator'])) {
         $condition['operator'] = '=';
     }
     switch ($condition['operator']) {
         case '=':
             // If a field explicitly requests that queries should not be case
             // sensitive, use the LIKE operator, otherwise keep =.
             if ($case_sensitive === FALSE) {
                 $condition['value'] = $sql_query->escapeLike($condition['value']);
                 $condition['operator'] = 'LIKE';
             }
             break;
         case '<>':
             // If a field explicitly requests that queries should not be case
             // sensitive, use the NOT LIKE operator, otherwise keep <>.
             if ($case_sensitive === FALSE) {
                 $condition['value'] = $sql_query->escapeLike($condition['value']);
                 $condition['operator'] = 'NOT LIKE';
             }
             break;
         case 'STARTS_WITH':
             if ($case_sensitive) {
                 $condition['operator'] = 'LIKE BINARY';
             } else {
                 $condition['operator'] = 'LIKE';
             }
             $condition['value'] = $sql_query->escapeLike($condition['value']) . '%';
             break;
         case 'CONTAINS':
             if ($case_sensitive) {
                 $condition['operator'] = 'LIKE BINARY';
             } else {
                 $condition['operator'] = 'LIKE';
             }
             $condition['value'] = '%' . $sql_query->escapeLike($condition['value']) . '%';
             break;
         case 'ENDS_WITH':
             if ($case_sensitive) {
                 $condition['operator'] = 'LIKE BINARY';
             } else {
                 $condition['operator'] = 'LIKE';
             }
             $condition['value'] = '%' . $sql_query->escapeLike($condition['value']);
             break;
     }
 }
Example #5
0
 protected function addJoin($type, $table, $join_condition, $langcode)
 {
     $arguments = array();
     if ($langcode) {
         $placeholder = ':langcode' . $this->sqlQuery->nextPlaceholder();
         $join_condition .= ' AND %alias.langcode = ' . $placeholder;
         $arguments[$placeholder] = $langcode;
     }
     return $this->sqlQuery->addJoin($type, $table, NULL, $join_condition, $arguments);
 }
Example #6
0
 /**
  * {@inheritdoc}
  */
 public static function translateCondition(&$condition, SelectInterface $sql_query, $case_sensitive)
 {
     if (is_array($condition['value']) && $case_sensitive === FALSE) {
         $condition['where'] = 'LOWER(' . $sql_query->escapeField($condition['real_field']) . ') ' . $condition['operator'] . ' (';
         $condition['where_args'] = [];
         $n = 1;
         // Only use the array values in case an associative array is passed as an
         // argument following similar pattern in
         // \Drupal\Core\Database\Connection::expandArguments().
         foreach ($condition['value'] as $value) {
             $condition['where'] .= 'LOWER(:value' . $n . '),';
             $condition['where_args'][':value' . $n] = $value;
             $n++;
         }
         $condition['where'] = trim($condition['where'], ',');
         $condition['where'] .= ')';
         return;
     }
     parent::translateCondition($condition, $sql_query, $case_sensitive);
 }
Example #7
0
 /**
  * Translates the string operators to SQL equivalents.
  *
  * @param array $condition
  *   The condition array.
  * @param \Drupal\Core\Database\Query\SelectInterface $sql_query
  *   Select query instance.
  * @param bool|null $case_sensitive
  *   If the condition should be case sensitive or not, NULL if the field does
  *   not define it.
  *
  * @see \Drupal\Core\Database\Query\ConditionInterface::condition()
  */
 public static function translateCondition(&$condition, SelectInterface $sql_query, $case_sensitive)
 {
     // // There is nothing we can do for IN ().
     if (is_array($condition['value'])) {
         return;
     }
     // Ensure that the default operator is set to simplify the cases below.
     if (empty($condition['operator'])) {
         $condition['operator'] = '=';
     }
     switch ($condition['operator']) {
         case '=':
             // If a field explicitly requests that queries should not be case
             // sensitive, use the LIKE operator, otherwise keep =.
             if ($case_sensitive === FALSE) {
                 $condition['value'] = $sql_query->escapeLike($condition['value']);
                 $condition['operator'] = 'LIKE';
             }
             break;
         case '<>':
             // If a field explicitly requests that queries should not be case
             // sensitive, use the NOT LIKE operator, otherwise keep <>.
             if ($case_sensitive === FALSE) {
                 $condition['value'] = $sql_query->escapeLike($condition['value']);
                 $condition['operator'] = 'NOT LIKE';
             }
             break;
         case 'STARTS_WITH':
             if ($case_sensitive) {
                 $condition['operator'] = 'LIKE BINARY';
             } else {
                 $condition['operator'] = 'LIKE';
             }
             $condition['value'] = $sql_query->escapeLike($condition['value']) . '%';
             break;
         case 'CONTAINS':
             if ($case_sensitive) {
                 $condition['operator'] = 'LIKE BINARY';
             } else {
                 $condition['operator'] = 'LIKE';
             }
             $condition['value'] = '%' . $sql_query->escapeLike($condition['value']) . '%';
             break;
         case 'ENDS_WITH':
             if ($case_sensitive) {
                 $condition['operator'] = 'LIKE BINARY';
             } else {
                 $condition['operator'] = 'LIKE';
             }
             $condition['value'] = '%' . $sql_query->escapeLike($condition['value']);
             break;
     }
 }
 /**
  * {@inheritdoc}
  */
 public function entityQueryAlter(SelectInterface $query)
 {
     if (\Drupal::currentUser()->hasPermission('administer users')) {
         // In addition, if the user is administrator, we need to make sure to
         // match the anonymous user, that doesn't actually have a name in the
         // database.
         $conditions =& $query->conditions();
         foreach ($conditions as $key => $condition) {
             if ($key !== '#conjunction' && is_string($condition['field']) && $condition['field'] === 'users_field_data.name') {
                 // Remove the condition.
                 unset($conditions[$key]);
                 // Re-add the condition and a condition on uid = 0 so that we end up
                 // with a query in the form:
                 // WHERE (name LIKE :name) OR (:anonymous_name LIKE :name AND uid = 0)
                 $or = db_or();
                 $or->condition($condition['field'], $condition['value'], $condition['operator']);
                 // Sadly, the Database layer doesn't allow us to build a condition
                 // in the form ':placeholder = :placeholder2', because the 'field'
                 // part of a condition is always escaped.
                 // As a (cheap) workaround, we separately build a condition with no
                 // field, and concatenate the field and the condition separately.
                 $value_part = db_and();
                 $value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
                 $value_part->compile(Database::getConnection(), $query);
                 $or->condition(db_and()->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => user_format_name(user_load(0))))->condition('base_table.uid', 0));
                 $query->condition($or);
             }
         }
     }
     // Add the filter by role option.
     if (!empty($this->fieldDefinition->getSetting('handler_settings')['filter'])) {
         $filter_settings = $this->fieldDefinition->getSetting('handler_settings')['filter'];
         if ($filter_settings['type'] == 'role') {
             $tables = $query->getTables();
             $base_table = $tables['base_table']['alias'];
             $query->join('users_roles', 'ur', $base_table . '.uid = ur.uid');
             $query->condition('ur.rid', $filter_settings['role']);
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function entityQueryAlter(SelectInterface $query)
 {
     $tables = $query->getTables();
     $data_table = 'comment_field_data';
     if (!isset($tables['comment_field_data']['alias'])) {
         // If no conditions join against the comment data table, it should be
         // joined manually to allow node access processing.
         $query->innerJoin($data_table, NULL, "base_table.cid = {$data_table}.cid AND {$data_table}.default_langcode = 1");
     }
     // The Comment module doesn't implement any proper comment access,
     // and as a consequence doesn't make sure that comments cannot be viewed
     // when the user doesn't have access to the node.
     $node_alias = $query->innerJoin('node_field_data', 'n', '%alias.nid = ' . $data_table . '.entity_id AND ' . $data_table . ".entity_type = 'node'");
     // Pass the query to the node access control.
     $this->reAlterQuery($query, 'node_access', $node_alias);
     // Passing the query to node_query_node_access_alter() is sadly
     // insufficient for nodes.
     // @see SelectionEntityTypeNode::entityQueryAlter()
     if (!\Drupal::currentUser()->hasPermission('bypass node access') && !count(\Drupal::moduleHandler()->getImplementations('node_grants'))) {
         $query->condition($node_alias . '.status', 1);
     }
 }
Example #10
0
 protected function addJoin($type, $table, $join_condition, $langcode)
 {
     $arguments = array();
     if ($langcode) {
         $entity_type_id = $this->sqlQuery->getMetaData('entity_type');
         $entity_type = $this->entityManager->getDefinition($entity_type_id);
         // Only the data table follows the entity language key, dedicated field
         // tables have an hard-coded 'langcode' column.
         $langcode_key = $entity_type->getDataTable() == $table ? $entity_type->getKey('langcode') : 'langcode';
         $placeholder = ':langcode' . $this->sqlQuery->nextPlaceholder();
         $join_condition .= ' AND %alias.' . $langcode_key . ' = ' . $placeholder;
         $arguments[$placeholder] = $langcode;
     }
     return $this->sqlQuery->addJoin($type, $table, NULL, $join_condition, $arguments);
 }
Example #11
0
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     parent::setUp();
     // Create a Mock database connection object.
     $this->connection = $this->getMockBuilder('Drupal\\Core\\Database\\Connection')->disableOriginalConstructor()->getMock();
     // Create a Mock Statement object
     $this->statement = $this->getMockBuilder('Drupal\\Core\\Database\\Driver\\sqlite\\Statement')->disableOriginalConstructor()->getMock();
     // Create a Mock Select object and set expectations.
     $this->select = $this->getMockBuilder('Drupal\\Core\\Database\\Query\\Select')->disableOriginalConstructor()->getMock();
     $this->select->expects($this->any())->method('fields')->will($this->returnSelf());
     $this->select->expects($this->any())->method('condition')->will($this->returnSelf());
     $this->select->expects($this->any())->method('range')->will($this->returnSelf());
     $this->select->expects($this->any())->method('orderBy')->will($this->returnSelf());
     $this->select->expects($this->any())->method('execute')->will($this->returnValue($this->statement));
     $this->connection->expects($this->any())->method('select')->will($this->returnValue($this->select));
     // Create a Mock Delete object and set expectations.
     $this->delete = $this->getMockBuilder('Drupal\\Core\\Database\\Query\\Delete')->disableOriginalConstructor()->getMock();
     $this->delete->expects($this->any())->method('condition')->will($this->returnSelf());
     $this->delete->expects($this->any())->method('execute')->will($this->returnValue($this->statement));
 }
Example #12
0
 /**
  * {@inheritdoc}
  */
 public function entityQueryAlter(SelectInterface $query)
 {
     // Bail out early if we do not need to match the Anonymous user.
     $handler_settings = $this->configuration['handler_settings'];
     if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) {
         return;
     }
     if ($this->currentUser->hasPermission('administer users')) {
         // In addition, if the user is administrator, we need to make sure to
         // match the anonymous user, that doesn't actually have a name in the
         // database.
         $conditions =& $query->conditions();
         foreach ($conditions as $key => $condition) {
             if ($key !== '#conjunction' && is_string($condition['field']) && $condition['field'] === 'users_field_data.name') {
                 // Remove the condition.
                 unset($conditions[$key]);
                 // Re-add the condition and a condition on uid = 0 so that we end up
                 // with a query in the form:
                 // WHERE (name LIKE :name) OR (:anonymous_name LIKE :name AND uid = 0)
                 $or = db_or();
                 $or->condition($condition['field'], $condition['value'], $condition['operator']);
                 // Sadly, the Database layer doesn't allow us to build a condition
                 // in the form ':placeholder = :placeholder2', because the 'field'
                 // part of a condition is always escaped.
                 // As a (cheap) workaround, we separately build a condition with no
                 // field, and concatenate the field and the condition separately.
                 $value_part = db_and();
                 $value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
                 $value_part->compile($this->connection, $query);
                 $or->condition(db_and()->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => user_format_name($this->userStorage->load(0))))->condition('base_table.uid', 0));
                 $query->condition($or);
             }
         }
     }
 }
Example #13
0
 /**
  * Generates a hash from a query object, to be used as part of the cache key.
  *
  * This smart caching strategy saves Drupal from querying and rendering to
  * HTML when the underlying query is unchanged.
  *
  * Expensive queries should use the query builder to create the query and then
  * call this function. Executing the query and formatting results should
  * happen in a #pre_render callback.
  *
  * @param \Drupal\Core\Database\Query\SelectInterface $query
  *   A select query object.
  *
  * @return string
  *   A hash of the query arguments.
  */
 public static function keyFromQuery(SelectInterface $query)
 {
     $query->preExecute();
     $keys = array((string) $query, $query->getArguments());
     return hash('sha256', serialize($keys));
 }
Example #14
0
  /**
   * Adds fields to the query.
   *
   * @param \Drupal\Core\Database\Query\SelectInterface $query
   *   The drupal query object.
   */
  protected function compileFields($query) {
    foreach ($this->fields as $field) {
      $string = '';
      if (!empty($field['table'])) {
        $string .= $field['table'] . '.';
      }
      $string .= $field['field'];
      $fieldname = (!empty($field['alias']) ? $field['alias'] : $string);

      if (!empty($field['count'])) {
        // Retained for compatibility.
        $field['function'] = 'count';
      }

      if (!empty($field['function'])) {
        $info = $this->getAggregationInfo();
        if (!empty($info[$field['function']]['method']) && is_callable(array($this, $info[$field['function']]['method']))) {
          $string = $this::{$info[$field['function']]['method']}($field['function'], $string);
          $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array();
          $query->addExpression($string, $fieldname, $placeholders);
        }

        $this->hasAggregate = TRUE;
      }
      // This is a formula, using no tables.
      elseif (empty($field['table'])) {
        $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array();
        $query->addExpression($string, $fieldname, $placeholders);
      }
      elseif ($this->distinct && !in_array($fieldname, $this->groupby)) {
        $query->addField(!empty($field['table']) ? $field['table'] : $this->view->storage->get('base_table'), $field['field'], $fieldname);
      }
      elseif (empty($field['aggregate'])) {
        $query->addField(!empty($field['table']) ? $field['table'] : $this->view->storage->get('base_table'), $field['field'], $fieldname);
      }

      if ($this->getCountOptimized) {
        // We only want the first field in this case.
        break;
      }
    }
  }
Example #15
0
 /**
  * Extends a query object for URL redirect filters.
  *
  * @param $query
  *   Query object that should be filtered.
  * @param $keys
  *   The filter string to use.
  */
 protected function filterQuery(SelectInterface $query, array $fields, $keys = '')
 {
     if ($keys && $fields) {
         // Replace wildcards with PDO wildcards.
         $conditions = db_or();
         $wildcard = '%' . trim(preg_replace('!\\*+!', '%', db_like($keys)), '%') . '%';
         foreach ($fields as $field) {
             $conditions->condition($field, $wildcard, 'LIKE');
         }
         $query->condition($conditions);
     }
 }
Example #16
0
 /**
  * Implementation of MigrateSource::performRewind().
  *
  * We could simply execute the query and be functionally correct, but
  * we will take advantage of the PDO-based API to optimize the query up-front.
  */
 protected function initializeIterator()
 {
     $this->prepareQuery();
     $high_water_property = $this->migration->get('highWaterProperty');
     // Get the key values, for potential use in joining to the map table.
     $keys = array();
     // The rules for determining what conditions to add to the query are as
     // follows (applying first applicable rule)
     // 1. If the map is joinable, join it. We will want to accept all rows
     //    which are either not in the map, or marked in the map as NEEDS_UPDATE.
     //    Note that if high water fields are in play, we want to accept all rows
     //    above the high water mark in addition to those selected by the map
     //    conditions, so we need to OR them together (but AND with any existing
     //    conditions in the query). So, ultimately the SQL condition will look
     //    like (original conditions) AND (map IS NULL OR map needs update
     //      OR above high water).
     $conditions = $this->query->orConditionGroup();
     $condition_added = FALSE;
     if (empty($this->configuration['ignore_map']) && $this->mapJoinable()) {
         // Build the join to the map table. Because the source key could have
         // multiple fields, we need to build things up.
         $count = 1;
         $map_join = '';
         $delimiter = '';
         foreach ($this->getIds() as $field_name => $field_schema) {
             if (isset($field_schema['alias'])) {
                 $field_name = $field_schema['alias'] . '.' . $field_name;
             }
             $map_join .= "{$delimiter}{$field_name} = map.sourceid" . $count++;
             $delimiter = ' AND ';
         }
         $alias = $this->query->leftJoin($this->migration->getIdMap()->getQualifiedMapTableName(), 'map', $map_join);
         $conditions->isNull($alias . '.sourceid1');
         $conditions->condition($alias . '.source_row_status', MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
         $condition_added = TRUE;
         // And as long as we have the map table, add its data to the row.
         $n = count($this->getIds());
         for ($count = 1; $count <= $n; $count++) {
             $map_key = 'sourceid' . $count;
             $this->query->addField($alias, $map_key, "migrate_map_{$map_key}");
         }
         if ($n = count($this->migration->get('destinationIds'))) {
             for ($count = 1; $count <= $n; $count++) {
                 $map_key = 'destid' . $count++;
                 $this->query->addField($alias, $map_key, "migrate_map_{$map_key}");
             }
         }
         $this->query->addField($alias, 'source_row_status', 'migrate_map_source_row_status');
     }
     // 2. If we are using high water marks, also include rows above the mark.
     //    But, include all rows if the high water mark is not set.
     if (isset($high_water_property['name']) && ($high_water = $this->migration->getHighWater()) !== '') {
         if (isset($high_water_property['alias'])) {
             $high_water = $high_water_property['alias'] . '.' . $high_water_property['name'];
         } else {
             $high_water = $high_water_property['name'];
         }
         $conditions->condition($high_water, $high_water, '>');
         $condition_added = TRUE;
     }
     if ($condition_added) {
         $this->query->condition($conditions);
     }
     return new \IteratorIterator($this->query->execute());
 }
Example #17
0
 public function notExists(SelectInterface $select)
 {
     $this->query->notExists($select);
     return $this;
 }
Example #18
0
 /**
  * Executes a select query while making sure the database table exists.
  *
  * @param \Drupal\Core\Database\Query\SelectInterface $query
  *   The select object to be executed.
  *
  * @return \Drupal\Core\Database\StatementInterface|null
  *   A prepared statement, or NULL if the query is not valid.
  *
  * @throws \Exception
  *   Thrown if the table could not be created or the database connection
  *   failed.
  */
 protected function safeExecuteSelect(SelectInterface $query)
 {
     try {
         return $query->execute();
     } catch (\Exception $e) {
         // If there was an exception, try to create the table.
         if ($this->ensureTableExists()) {
             return $query->execute();
         }
         // Some other failure that we can not recover from.
         throw $e;
     }
 }
Example #19
0
 /**
  * Creates a temporary table from a select query.
  *
  * Will return the name of a table containing the item IDs of all results, or
  * FALSE on failure.
  *
  * @param \Drupal\Core\Database\Query\SelectInterface $db_query
  *   The select query whose results should be stored in the temporary table.
  *
  * @return string|false
  *   The name of the temporary table, or FALSE on failure.
  */
 protected function getTemporaryResultsTable(SelectInterface $db_query)
 {
     // We only need the id field, not the score.
     $fields =& $db_query->getFields();
     unset($fields['score']);
     if (count($fields) != 1 || !isset($fields['item_id'])) {
         $this->getLogger()->warning('Error while adding facets: only "item_id" field should be used, used are: @fields.', array('@fields' => implode(', ', array_keys($fields))));
         return FALSE;
     }
     $expressions =& $db_query->getExpressions();
     $expressions = array();
     // If there's a GROUP BY for item_id, we leave that, all others need to be
     // discarded.
     $group_by =& $db_query->getGroupBy();
     $group_by = array_intersect_key($group_by, array('t.item_id' => TRUE));
     $db_query->distinct();
     if (!$db_query->preExecute()) {
         return FALSE;
     }
     $args = $db_query->getArguments();
     try {
         $result = $this->database->queryTemporary((string) $db_query, $args);
     } catch (\PDOException $e) {
         watchdog_exception('search_api', $e, '%type while trying to create a temporary table: @message in %function (line %line of %file).');
         return FALSE;
     }
     return $result;
 }
Example #20
0
 /**
  * Returns whether the query requires GROUP BY and ORDER BY MIN/MAX.
  *
  * @return bool
  */
 protected function isSimpleQuery()
 {
     return !$this->pager && !$this->range && !$this->count || $this->sqlQuery->getMetaData('simple_query');
 }
Example #21
0
 /**
  * Adapt our query for translations.
  *
  * @param \Drupal\Core\Database\Query\SelectInterface
  *   The generated query.
  */
 protected function handleTranslations(SelectInterface $query)
 {
     // Check whether or not we want translations.
     if (empty($this->configuration['translations'])) {
         // No translations: Yield untranslated nodes, or default translations.
         $query->where('n.tnid = 0 OR n.tnid = n.nid');
     } else {
         // Translations: Yield only non-default translations.
         $query->where('n.tnid <> 0 AND n.tnid <> n.nid');
     }
 }
Example #22
0
 /**
  * Creates a temporary table from a select query.
  *
  * Will return the name of a table containing the item IDs of all results, or
  * FALSE on failure.
  *
  * @param \Drupal\Core\Database\Query\SelectInterface $db_query
  *   The select query whose results should be stored in the temporary table.
  *
  * @return string|false
  *   The name of the temporary table, or FALSE on failure.
  */
 protected function getTemporaryResultsTable(SelectInterface $db_query) {
   // We only need the id field, not the score.
   $fields = &$db_query->getFields();
   unset($fields['score']);
   if (count($fields) != 1 || !isset($fields['item_id'])) {
     $this->getLogger()->warning('Error while adding facets: only "item_id" field should be used, used are: @fields.', array('@fields' => implode(', ', array_keys($fields))));
     return FALSE;
   }
   $expressions = &$db_query->getExpressions();
   $expressions = array();
   $db_query->distinct();
   if (!$db_query->preExecute()) {
     return FALSE;
   }
   $args = $db_query->getArguments();
   return $this->database->queryTemporary((string) $db_query, $args);
 }