' . t('MongoDB implements a generic MongoDB interface.',
        array(
          '!project' => 'http://drupal.org/project/mongodb',
          '!mongo' => 'http://www.mongodb.org/',
        ));
      break;
  }
}
/**
 * Returns an MongoDB object.
 */
function mongodb($alias = 'default') {
  static $mongo_objects;
  $connections = variable_get('mongodb_connections', array());
  $connections += array('default' => array('host' => 'localhost', 'db' => 'drupal'));
  if (!isset($connections[$alias])) {
    $alias = 'default';
  }
  $connection = $connections[$alias];
  $host = $connection['host'];
  $db = $connection['db'];
  if (!isset($mongo_objects[$host][$db])) {
    $mongo = new Mongo($host);
    $mongo_objects[$host][$db] = $mongo->selectDB($db);
    $mongo_objects[$host][$db]->connection = $mongo;
  }
  return $mongo_objects[$host][$db];
}
/**
 * Returns a MongoCollection object.
 */
function mongodb_collection() {
  $args = array_filter(func_get_args());
  if (is_array($args[0])) {
    list($collection_name, $prefixed) = $args[0];
    $prefixed .= $collection_name;
  }
  else {
    // Avoid something. collection names if NULLs are passed in.
    $collection_name = implode('.', array_filter($args));
    $prefixed = mongodb_collection_name($collection_name);
  }
  $collections = variable_get('mongodb_collections', array());
  $alias = isset($collections[$collection_name]) ? $collections[$collection_name] : 'default';
  // Prefix the collection name for simpletest. It will be in the same DB as the
  // non-prefixed version so it's enough to prefix after choosing the mongodb
  // object.
  $mongodb_object = mongodb($alias);
  $collection = $mongodb_object->selectCollection(mongodb_collection_name($collection_name));
  $collection->connection = $mongodb_object->connection;
  return variable_get('mongodb_debug', FALSE) ? new mongoDebugCollection($collection) : $collection;
}
class mongoDebugCollection {
  function __construct($collection) {
    $this->collection = $collection;
  }
  function find($query = array(), $fields = array()) {
    debug('find');
    debug($query);
    debug($fields);
    return mongoDebugCursor($this->collection->find($query, $fields));
  }
  function __call($name, $arguments) {
    debug($name);
    debug($arguments);
    return call_user_func_array(array($this->collection, $name), $arguments);
  }
}
class mongoDebugCursor {
  function __construct($collection) {
    $this->collection = $collection;
  }
  function __call($name, $arguments) {
    debug($name);
    debug($arguments);
    return call_user_func_array(array($this->collection, $name), $arguments);
  }
}
/**
 * Returns the name to use for the collection, which works with prefixes and simpletest.
 */
function mongodb_collection_name($name) {
  global $db_prefix;
  static $simpletest_prefix;
  // We call this function earlier than the database is initalized so we would
  // read the parent collection without this.
  if (!isset($simpletest_prefix)) {
    if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);/", $_SERVER['HTTP_USER_AGENT'], $matches)) {
      $simpletest_prefix = $matches[1];
    }
    else {
      $simpletest_prefix = '';
    }
  }
  // However, once the test information is initialized, simpletest_prefix
  // is no longer needed.
  if (!empty($GLOBALS['drupal_test_info']['test_run_id'])) {
    $simpletest_prefix = $GLOBALS['drupal_test_info']['test_run_id'];
  }
  return $simpletest_prefix . $name;
}
function mongodb_test_group_finished() {
  $aliases = variable_get('mongodb_connections', array());
  $aliases['default'] = TRUE;
  foreach (array_keys($aliases) as $alias) {
    $db = mongodb($alias);
    foreach ($db->listCollections() as $collection) {
      if (preg_match('/\.simpletest\d+/', $collection)) {
        $db->dropCollection($collection);
      }
    }
  }
}
/**
 * Allow for the database connection we are using to be changed.
 *
 * @param $alias
 *   String the alias that we want to change the connection for.
 * @param $connection_name
 *   String the name of the connection we will use.
 */
function mongodb_set_active_connection($alias, $connection_name = 'default') {
  // No need to check if the connection is valid as mongodb() does this.
  $GLOBALS['conf']['mongodb_collections'][$alias] = $connection_name;
}
/**
 * Return the next id in a sequence.
 */
function mongodb_next_id($name, $existing_id = 0) {
  // Atomitcaly get the next id in the sequence.
  $mongo = mongodb();
  $cmd = array(
    'findandmodify' => mongodb_collection_name('sequence'),
    'query' => array('_id' => $name),
    'update' => array('$inc' => array('value' => 1)),
    'new' => TRUE,
  );
  // It's very likely that this is not necessary as command returns an array
  // not an exception. The increment will, however, will fix the problem of
  // the sequence not existing. Still, better safe than sorry.
  try {
    $sequence = $mongo->command($cmd);
    $value = isset($sequence['value']['value']) ? $sequence['value']['value'] : 0;
  }
  catch (Exception $e) {
  }
  if (0 < $existing_id - $value + 1) {
    $cmd = array(
      'findandmodify' => mongodb_collection_name('sequence'),
      'query' => array('_id' => $name),
      'update' => array('$inc' => array('value' => $existing_id - $value + 1)),
      'upsert' => TRUE,
      'new' => TRUE,
    );
    $sequence = $mongo->command($cmd);
    $value = isset($sequence['value']['value']) ? $sequence['value']['value'] : 0;
  }
  return $value;
}