field_sql_storage_field_storage_query

Versions
7
field_sql_storage_field_storage_query($field_id, $conditions, $options)

Implements hook_field_storage_query().

Code

modules/field/modules/field_sql_storage/field_sql_storage.module, line 475

<?php
function field_sql_storage_field_storage_query($field_id, $conditions, $options) {
  $load_current = $options['age'] == FIELD_LOAD_CURRENT;

  $field = field_info_field_by_id($field_id);
  $field_name = $field['field_name'];
  $table = $load_current ? _field_sql_storage_tablename($field) : _field_sql_storage_revision_tablename($field);
  $field_columns = array_keys($field['columns']);

  // Build the query.
  $query = db_select($table, 't');
  $query->join('field_config_entity_type', 'e', 't.etid = e.etid');

  // Add conditions.
  foreach ($conditions as $condition) {
    // A condition is either a (column, value, operator) triple, or a
    // (column, value) pair with implied operator.
    @list($column, $value, $operator) = $condition;
    // Translate operator and value if needed.
    switch ($operator) {
      case 'STARTS_WITH':
        $operator = 'LIKE';
        $value .= '%';
        break;

      case 'ENDS_WITH':
        $operator = 'LIKE';
        $value = "$value%";
        break;

      case 'CONTAINS':
        $operator = 'LIKE';
        $value = "%$value%";
        break;
    }
    // Translate field columns into prefixed db columns.
    if (in_array($column, $field_columns)) {
      $column = _field_sql_storage_columnname($field_name, $column);
    }
    // Translate entity types into numeric ids. Expressing the condition on the
    // local 'etid' column rather than the JOINed 'type' column avoids a
    // filesort.
    if ($column == 'type') {
      $column = 't.etid';
      if (is_array($value)) {
        foreach (array_keys($value) as $key) {
          $value[$key] = _field_sql_storage_etid($value[$key]);
        }
      }
      else {
        $value = _field_sql_storage_etid($value);
      }
    }
    // Track condition on 'deleted'.
    if ($column == 'deleted') {
      $condition_deleted = TRUE;
    }

    $query->condition($column, $value, $operator);
  }

  // Exclude deleted data unless we have a condition on it.
  if (!isset($condition_deleted)) {
    $query->condition('deleted', 0);
  }

  // For a count query, return the count now.
  if ($options['count']) {
    $query->addExpression('COUNT(DISTINCT e.type,t.entity_id,t.revision_id)');
    return $query->execute()->fetchField();
  }

  // For a data query, add fields.
  $query
    ->fields('t', array('bundle', 'entity_id', 'revision_id'))
    ->fields('e', array('type'))
    // We need to ensure objects arrive in a consistent order for the
    // range() operation to work.
    ->orderBy('t.etid')
    ->orderBy('t.entity_id');

  // Initialize results array
  $return = array();

  // Getting $count objects possibly requires reading more than $count rows
  // since fields with multiple values span over several rows. We query for
  // batches of $count rows until we've either read $count objects or received
  // less rows than asked for.
  $obj_count = 0;
  do {
    if ($options['limit'] != FIELD_QUERY_NO_LIMIT) {
      $query->range($options['cursor'], $options['limit']);
    }
    $results = $query->execute();

    $row_count = 0;
    foreach ($results as $row) {
      $row_count++;
      $options['cursor']++;
      // If querying all revisions and the entity type has revisions, we need
      // to key the results by revision_ids.
      $entity_type = entity_get_info($row->type);
      $id = ($load_current || empty($entity_type['object keys']['revision'])) ? $row->entity_id : $row->revision_id;

      if (!isset($return[$row->type][$id])) {
        $return[$row->type][$id] = entity_create_stub_entity($row->type, array($row->entity_id, $row->revision_id, $row->bundle));
        $obj_count++;
      }
    }
  } while ($options['limit'] != FIELD_QUERY_NO_LIMIT && $row_count == $options['limit'] && $obj_count < $options['limit']);

  // The query is complete when the last batch returns less rows than asked
  // for.
  if ($row_count < $options['limit']) {
    $options['cursor'] = FIELD_QUERY_COMPLETE;
  }

  return $return;
}
?>
Login or register to post comments
 
 

All source code and documentation on this site is released under the terms of the GNU General Public License, version 2 and later. Drupal is a registered trademark of Dries Buytaert.