Index: contrib/search_api_facets/README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/search_api/contrib/search_api_facets/Attic/README.txt,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 README.txt
--- contrib/search_api_facets/README.txt	28 Sep 2010 16:44:54 -0000	1.1.2.2
+++ contrib/search_api_facets/README.txt	22 Feb 2011 11:33:09 -0000
@@ -6,7 +6,8 @@
 This module allows you to create facetted searches for any search executed via
 the Search API, no matter if executed by a search page, a view or any other
 module. The only thing you'll need is a search service class that supports the
-"search_api_facets" feature. Currently, only the "Solr search" supports this.
+"search_api_facets" feature. Currently, the "Database search" and "Solr search"
+modules supports this.
 
 
 
Index: contrib/search_api_db/service.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/search_api/contrib/search_api_db/Attic/service.inc,v
retrieving revision 1.1.2.34
diff -u -r1.1.2.34 service.inc
--- contrib/search_api_db/service.inc	17 Dec 2010 14:40:35 -0000	1.1.2.34
+++ contrib/search_api_db/service.inc	22 Feb 2011 11:33:09 -0000
@@ -69,6 +69,10 @@
     return $form;
   }
 
+  public function supportsFeature($feature) {
+    return $feature == 'search_api_facets';
+  }
+
   public function postUpdate() {
     return $this->server->options != $this->server->original->options;
   }
@@ -562,6 +566,10 @@
     $results['result count'] = $count_query->execute()->fetchField();
 
     if ($results['result count']) {
+      if ($query->getOption('search_api_facets')) {
+        $results['search_api_facets'] = $this->getFacets($query, clone $db_query);
+      }
+
       $query_options = $query->getOptions();
       if (isset($query_options['offset']) || isset($query_options['limit'])) {
         $offset = isset($query_options['offset']) ? $query_options['offset'] : 0;
@@ -981,6 +989,89 @@
   }
 
   /**
+   * Helper method for getting the facet values for a query.
+   */
+  protected function getFacets(SearchApiQueryInterface $query, SelectQueryInterface $db_query) {
+    // We only need the id field, not the score.
+    if (count($db_query->getFields()) != 1) {
+      throw new SearchApiException('Doch nicht.');//DEBUG
+    }
+    $expressions = &$db_query->getExpressions();
+    $expressions = array();
+    $group_by = &$db_query->getGroupBy();
+    $group_by = array();
+    $db_query->distinct();
+    if (!$db_query->preExecute()) {
+      return array();
+    }
+    $args = $db_query->getArguments();
+    $table = db_query_temporary((string) $db_query, $args, $this->query_options);
+
+    $fields = $this->options['indexes'][$query->getIndex()->machine_name];
+    $ret = array();
+    foreach ($query->getOption('search_api_facets') as $key => $facet) {
+      if (empty($fields[$facet['field']])) {
+        $this->warnings[] = t('Unknown facet field @field.', array('@field' => $facet['field']));
+        continue;
+      }
+      $field = $fields[$facet['field']];
+
+      $select = db_select($table, 't');
+      $alias = $this->getTableAlias($field, $select);
+      $select->addField($alias, search_api_is_text_type($field['type']) ? 'word' : 'value', 'value');
+      $select->addExpression('COUNT(DISTINCT t.item_id)', 'num');
+      $select->groupBy('value');
+      $select->orderBy('num', 'DESC');
+
+      $limit = $facet['limit'];
+      if ($limit) {
+        $select->range(0, $limit);
+      }
+      if ($facet['min_count'] > 1) {
+        $select->having('num >= :count', array(':count' => $facet['min_count']));
+      }
+      if ($facet['missing']) {
+        $inner_query = db_select($field['table'], 't1')
+          ->fields('t1', array('item_id'));
+        $missing_count = db_select($table, 't');
+        $missing_count->addExpression('COUNT(item_id)');
+        $missing_count->condition('item_id', $inner_query, 'NOT IN');
+        $missing_count = $missing_count->execute()->fetchField();
+        $missing_count = $missing_count >= $facet['min_count'] ? $missing_count : 0;
+      }
+      else {
+        $missing_count = 0;
+      }
+
+      $terms = array();
+      foreach ($select->execute() as $row) {
+        if ($missing_count && $missing_count > $row->num) {
+          $terms[] = array(
+            'count'  => $missing_count,
+            'filter' => '!',
+          );
+          $missing_count = 0;
+          if ($limit && count($terms) == $limit) {
+            break;
+          }
+        }
+        $terms[] = array(
+          'count' => $row->num,
+          'filter' => '"' . $row->value . '"',
+        );
+      }
+      if ($missing_count && (!$limit || count($terms) < $limit)) {
+        $terms[] = array(
+          'count'  => $missing_count,
+          'filter' => '!',
+        );
+      }
+      $ret[$key] = $terms;
+    }
+    return $ret;
+  }
+
+  /**
    * Helper method for setting the database to the one selected by the user.
    */
   protected function setDb() {
Index: contrib/search_api_db/README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/search_api/contrib/search_api_db/Attic/README.txt,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 README.txt
--- contrib/search_api_db/README.txt	20 Sep 2010 11:51:12 -0000	1.1.2.5
+++ contrib/search_api_db/README.txt	22 Feb 2011 11:33:08 -0000
@@ -17,6 +17,13 @@
 
 Due to SQL limitations, fulltext searches are always case-insensitive.
 
+Supported optional features
+---------------------------
+
+Regarding third-party features, this module supports the "search_api_facets"
+feature, introduced by the module of the same name. This lets you create
+facetted searches for any index lying on a database server.
+
 If you feel some service option is missing, or have other ideas for improving
 this implementation, please file a feature request in the project's issue queue,
 at [http://drupal.org/project/issues/search_api], using the "Database search"
