bool
_mongoc_cursor_cursorid_next (mongoc_cursor_t *cursor, const bson_t **bson)
{
   mongoc_cursor_cursorid_t *cid;
   bool refreshed = false;

   ENTRY;

   *bson = NULL;

   cid = (mongoc_cursor_cursorid_t *) cursor->iface_data;
   BSON_ASSERT (cid);

   if (!cursor->sent) {
      if (!_mongoc_cursor_cursorid_prime (cursor)) {
         GOTO (done);
      }
   }

again:

   /* Two paths:
    * - Mongo 3.2+, sent "getMore" cmd, we're reading reply's "nextBatch" array
    * - Mongo 2.6 to 3, after "aggregate" or similar command we sent OP_GETMORE,
    *   we're reading the raw reply
    */
   if (cid->in_batch) {
      _mongoc_cursor_cursorid_read_from_batch (cursor, bson);

      if (*bson) {
         GOTO (done);
      }

      cid->in_batch = false;
   } else if (cid->in_reader) {
      _mongoc_read_from_buffer (cursor, bson);

      if (*bson) {
         GOTO (done);
      }

      cid->in_reader = false;
   }

   if (!refreshed && mongoc_cursor_get_id (cursor)) {
      if (!_mongoc_cursor_cursorid_get_more (cursor)) {
         GOTO (done);
      }

      refreshed = true;
      GOTO (again);
   }

done:
   if (!*bson && mongoc_cursor_get_id (cursor) == 0) {
      cursor->done = 1;
   }

   RETURN (*bson != NULL);
}
Пример #2
0
mongoc_cursor_t *
mongoc_database_find_collections (mongoc_database_t *database,
                                  const bson_t      *filter,
                                  bson_error_t      *error)
{
   mongoc_cursor_t *cursor;
   mongoc_read_prefs_t *read_prefs;
   bson_t cmd = BSON_INITIALIZER;
   bson_t child;
   bson_error_t lerror;

   BSON_ASSERT (database);

   BSON_APPEND_INT32 (&cmd, "listCollections", 1);

   if (filter) {
      BSON_APPEND_DOCUMENT (&cmd, "filter", filter);
      BSON_APPEND_DOCUMENT_BEGIN (&cmd, "cursor", &child);
      bson_append_document_end (&cmd, &child);
   }

   read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);

   cursor = _mongoc_cursor_new (database->client, database->name,
                                MONGOC_QUERY_SLAVE_OK, 0, 0, 0, true,
                                NULL, NULL, NULL, NULL);

   _mongoc_cursor_cursorid_init (cursor, &cmd);

   if (_mongoc_cursor_cursorid_prime (cursor)) {
       /* intentionally empty */
   } else {
      if (mongoc_cursor_error (cursor, &lerror)) {
         if (lerror.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND) {
            /* We are talking to a server that doesn' support listCollections. */
            /* clear out the error. */
            memset (&lerror, 0, sizeof lerror);
            /* try again with using system.namespaces */
            mongoc_cursor_destroy (cursor);
            cursor = _mongoc_database_find_collections_legacy (
               database, filter, error);
         } else if (error) {
            memcpy (error, &lerror, sizeof *error);
         }
      }
   }

   bson_destroy (&cmd);
   mongoc_read_prefs_destroy (read_prefs);

   return cursor;
}