"Fossies" - the Fresh Open Source Software Archive

Member "drupal-8.9.10/core/lib/Drupal/Core/Database/Driver/pgsql/Select.php" (26 Nov 2020, 4890 Bytes) of package /linux/www/drupal-8.9.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Select.php" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.0.8_vs_9.1.0-rc1.

    1 <?php
    2 
    3 namespace Drupal\Core\Database\Driver\pgsql;
    4 
    5 use Drupal\Core\Database\Query\Select as QuerySelect;
    6 
    7 /**
    8  * @addtogroup database
    9  * @{
   10  */
   11 
   12 /**
   13  * PostgreSQL implementation of \Drupal\Core\Database\Query\Select.
   14  */
   15 class Select extends QuerySelect {
   16 
   17   public function orderRandom() {
   18     $alias = $this->addExpression('RANDOM()', 'random_field');
   19     $this->orderBy($alias);
   20     return $this;
   21   }
   22 
   23   /**
   24    * Overrides SelectQuery::orderBy().
   25    *
   26    * PostgreSQL adheres strictly to the SQL-92 standard and requires that when
   27    * using DISTINCT or GROUP BY conditions, fields and expressions that are
   28    * ordered on also need to be selected. This is a best effort implementation
   29    * to handle the cases that can be automated by adding the field if it is not
   30    * yet selected.
   31    *
   32    * @code
   33    *   $query = \Drupal::database()->select('example', 'e');
   34    *   $query->join('example_revision', 'er', 'e.vid = er.vid');
   35    *   $query
   36    *     ->distinct()
   37    *     ->fields('e')
   38    *     ->orderBy('timestamp');
   39    * @endcode
   40    *
   41    * In this query, it is not possible (without relying on the schema) to know
   42    * whether timestamp belongs to example_revision and needs to be added or
   43    * belongs to node and is already selected. Queries like this will need to be
   44    * corrected in the original query by adding an explicit call to
   45    * SelectQuery::addField() or SelectQuery::fields().
   46    *
   47    * Since this has a small performance impact, both by the additional
   48    * processing in this function and in the database that needs to return the
   49    * additional fields, this is done as an override instead of implementing it
   50    * directly in SelectQuery::orderBy().
   51    */
   52   public function orderBy($field, $direction = 'ASC') {
   53     // Only allow ASC and DESC, default to ASC.
   54     // Emulate MySQL default behavior to sort NULL values first for ascending,
   55     // and last for descending.
   56     // @see http://www.postgresql.org/docs/9.3/static/queries-order.html
   57     $direction = strtoupper($direction) == 'DESC' ? 'DESC NULLS LAST' : 'ASC NULLS FIRST';
   58     $this->order[$field] = $direction;
   59 
   60     if ($this->hasTag('entity_query')) {
   61       return $this;
   62     }
   63 
   64     // If there is a table alias specified, split it up.
   65     if (strpos($field, '.') !== FALSE) {
   66       list($table, $table_field) = explode('.', $field);
   67     }
   68     // Figure out if the field has already been added.
   69     foreach ($this->fields as $existing_field) {
   70       if (!empty($table)) {
   71         // If table alias is given, check if field and table exists.
   72         if ($existing_field['table'] == $table && $existing_field['field'] == $table_field) {
   73           return $this;
   74         }
   75       }
   76       else {
   77         // If there is no table, simply check if the field exists as a field or
   78         // an aliased field.
   79         if ($existing_field['alias'] == $field) {
   80           return $this;
   81         }
   82       }
   83     }
   84 
   85     // Also check expression aliases.
   86     foreach ($this->expressions as $expression) {
   87       if ($expression['alias'] == $this->connection->escapeAlias($field)) {
   88         return $this;
   89       }
   90     }
   91 
   92     // If a table loads all fields, it can not be added again. It would
   93     // result in an ambiguous alias error because that field would be loaded
   94     // twice: Once through table_alias.* and once directly. If the field
   95     // actually belongs to a different table, it must be added manually.
   96     foreach ($this->tables as $table) {
   97       if (!empty($table['all_fields'])) {
   98         return $this;
   99       }
  100     }
  101 
  102     // If $field contains an characters which are not allowed in a field name
  103     // it is considered an expression, these can't be handled automatically
  104     // either.
  105     if ($this->connection->escapeField($field) != $field) {
  106       return $this;
  107     }
  108 
  109     // This is a case that can be handled automatically, add the field.
  110     $this->addField(NULL, $field);
  111     return $this;
  112   }
  113 
  114   /**
  115    * {@inheritdoc}
  116    */
  117   public function addExpression($expression, $alias = NULL, $arguments = []) {
  118     if (empty($alias)) {
  119       $alias = 'expression';
  120     }
  121 
  122     // This implements counting in the same manner as the parent method.
  123     $alias_candidate = $alias;
  124     $count = 2;
  125     while (!empty($this->expressions[$alias_candidate])) {
  126       $alias_candidate = $alias . '_' . $count++;
  127     }
  128     $alias = $alias_candidate;
  129 
  130     $this->expressions[$alias] = [
  131       'expression' => $expression,
  132       'alias' => $this->connection->escapeAlias($alias_candidate),
  133       'arguments' => $arguments,
  134     ];
  135 
  136     return $alias;
  137   }
  138 
  139   /**
  140    * {@inheritdoc}
  141    */
  142   public function execute() {
  143     $this->connection->addSavepoint();
  144     try {
  145       $result = parent::execute();
  146     }
  147     catch (\Exception $e) {
  148       $this->connection->rollbackSavepoint();
  149       throw $e;
  150     }
  151     $this->connection->releaseSavepoint();
  152 
  153     return $result;
  154   }
  155 
  156 }
  157 
  158 /**
  159  * @} End of "addtogroup database".
  160  */