예제 #1
0
/*
 * If error is not set, set code from first document in array like
 * [{"code": 64, "errmsg": "duplicate"}, ...]. Format the error message
 * from all errors in array.
 */
static void
_set_error_from_response (bson_t *bson_array,
                          mongoc_error_domain_t domain,
                          const char *error_type,
                          bson_error_t *error /* OUT */)
{
   bson_iter_t array_iter;
   bson_iter_t doc_iter;
   bson_string_t *compound_err;
   const char *errmsg = NULL;
   int32_t code = 0;
   uint32_t n_keys, i;

   compound_err = bson_string_new (NULL);
   n_keys = bson_count_keys (bson_array);
   if (n_keys > 1) {
      bson_string_append_printf (
         compound_err, "Multiple %s errors: ", error_type);
   }

   if (!bson_empty0 (bson_array) && bson_iter_init (&array_iter, bson_array)) {
      /* get first code and all error messages */
      i = 0;

      while (bson_iter_next (&array_iter)) {
         if (BSON_ITER_HOLDS_DOCUMENT (&array_iter) &&
             bson_iter_recurse (&array_iter, &doc_iter)) {
            /* parse doc, which is like {"code": 64, "errmsg": "duplicate"} */
            while (bson_iter_next (&doc_iter)) {
               /* use the first error code we find */
               if (BSON_ITER_IS_KEY (&doc_iter, "code") && code == 0) {
                  code = bson_iter_int32 (&doc_iter);
               } else if (BSON_ITER_IS_KEY (&doc_iter, "errmsg")) {
                  errmsg = bson_iter_utf8 (&doc_iter, NULL);

                  /* build message like 'Multiple write errors: "foo", "bar"' */
                  if (n_keys > 1) {
                     bson_string_append_printf (compound_err, "\"%s\"", errmsg);
                     if (i < n_keys - 1) {
                        bson_string_append (compound_err, ", ");
                     }
                  } else {
                     /* single error message */
                     bson_string_append (compound_err, errmsg);
                  }
               }
            }

            i++;
         }
      }

      if (code && compound_err->len) {
         bson_set_error (
            error, domain, (uint32_t) code, "%s", compound_err->str);
      }
   }

   bson_string_free (compound_err, true);
}
/*
 * Start iterating the reply to an "aggregate", "find", "getMore" etc. command:
 *
 *    {cursor: {id: 1234, ns: "db.collection", firstBatch: [...]}}
 */
bool
_mongoc_cursor_cursorid_start_batch (mongoc_cursor_t *cursor)
{
   mongoc_cursor_cursorid_t *cid;
   bson_iter_t iter;
   bson_iter_t child;
   const char *ns;
   uint32_t nslen;

   cid = (mongoc_cursor_cursorid_t *)cursor->iface_data;

   BSON_ASSERT (cid);

   if (bson_iter_init_find (&iter, &cid->array, "cursor") &&
       BSON_ITER_HOLDS_DOCUMENT (&iter) &&
       bson_iter_recurse (&iter, &child)) {
      while (bson_iter_next (&child)) {
         if (BSON_ITER_IS_KEY (&child, "id")) {
            cursor->rpc.reply.cursor_id = bson_iter_as_int64 (&child);
         } else if (BSON_ITER_IS_KEY (&child, "ns")) {
            ns = bson_iter_utf8 (&child, &nslen);
            _mongoc_set_cursor_ns (cursor, ns, nslen);
         } else if (BSON_ITER_IS_KEY (&child, "firstBatch") ||
                    BSON_ITER_IS_KEY (&child, "nextBatch")) {
            if (BSON_ITER_HOLDS_ARRAY (&child) &&
                bson_iter_recurse (&child, &cid->batch_iter)) {
               cid->in_batch = true;
            }
         }
      }
   }

   return cid->in_batch;
}
예제 #3
0
int32_t
_mongoc_write_result_merge_arrays (uint32_t offset,
                                   mongoc_write_result_t *result, /* IN */
                                   bson_t *dest,                  /* IN */
                                   bson_iter_t *iter)             /* IN */
{
   const bson_value_t *value;
   bson_iter_t ar;
   bson_iter_t citer;
   int32_t idx;
   int32_t count = 0;
   int32_t aridx;
   bson_t child;
   const char *keyptr = NULL;
   char key[12];
   int len;

   ENTRY;

   BSON_ASSERT (result);
   BSON_ASSERT (dest);
   BSON_ASSERT (iter);
   BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (iter));

   aridx = bson_count_keys (dest);

   if (bson_iter_recurse (iter, &ar)) {
      while (bson_iter_next (&ar)) {
         if (BSON_ITER_HOLDS_DOCUMENT (&ar) &&
             bson_iter_recurse (&ar, &citer)) {
            len =
               (int) bson_uint32_to_string (aridx++, &keyptr, key, sizeof key);
            bson_append_document_begin (dest, keyptr, len, &child);
            while (bson_iter_next (&citer)) {
               if (BSON_ITER_IS_KEY (&citer, "index")) {
                  idx = bson_iter_int32 (&citer) + offset;
                  BSON_APPEND_INT32 (&child, "index", idx);
               } else {
                  value = bson_iter_value (&citer);
                  BSON_APPEND_VALUE (&child, bson_iter_key (&citer), value);
               }
            }
            bson_append_document_end (dest, &child);
            count++;
         }
      }
   }

   RETURN (count);
}
/**
 * _mongoc_parse_wc_err:
 * @doc: (in): A bson document.
 * @error: (out): A bson_error_t.
 *
 * Parses a document, usually a server reply,
 * looking for a writeConcernError. Returns true if
 * there is a writeConcernError, false otherwise.
 */
bool
_mongoc_parse_wc_err (const bson_t *doc, bson_error_t *error) {
   bson_iter_t iter;
   bson_iter_t inner;

   if (bson_iter_init_find(&iter, doc, "writeConcernError") &&
       BSON_ITER_HOLDS_DOCUMENT (&iter))
   {
      const char *errmsg = NULL;
      int32_t code = 0;
      bson_iter_recurse(&iter, &inner);
      while (bson_iter_next(&inner)) {
         if (BSON_ITER_IS_KEY (&inner, "code")) {
            code = bson_iter_int32 (&inner);
         } else if (BSON_ITER_IS_KEY (&inner, "errmsg")) {
            errmsg = bson_iter_utf8 (&inner, NULL);
         }
      }
      bson_set_error(error, MONGOC_ERROR_WRITE_CONCERN, code,
                     "Write Concern error: %s", errmsg);
      return true;
   }
   return false;
}
예제 #5
0
static void
test_index_offset (void)
{
   mongoc_bulk_operation_t *bulk;
   mongoc_collection_t *collection;
   mongoc_client_t *client;
   bson_error_t error;
   bson_iter_t iter;
   bson_iter_t ar;
   bson_iter_t citer;
   bson_t reply;
   bson_t *sel;
   bson_t *doc;
   bool r;

   client = mongoc_client_new (gTestUri);
   assert (client);

   collection = get_test_collection (client, "test_index_offset");
   assert (collection);

   doc = bson_new ();
   BSON_APPEND_INT32 (doc, "abcd", 1234);
   r = mongoc_collection_insert (collection, MONGOC_INSERT_NONE, doc, NULL, &error);
   assert (r);
   bson_destroy (doc);

   bulk = mongoc_collection_create_bulk_operation (collection, true, NULL);
   assert (bulk);

   sel = BCON_NEW ("abcd", BCON_INT32 (1234));
   doc = BCON_NEW ("$set", "{", "hello", "there", "}");

   mongoc_bulk_operation_delete_one (bulk, sel);
   mongoc_bulk_operation_update (bulk, sel, doc, true);

   r = mongoc_bulk_operation_execute (bulk, &reply, &error);
   assert (r);

   assert (bson_iter_init_find (&iter, &reply, "nUpserted"));
   assert (BSON_ITER_HOLDS_INT32 (&iter));
   assert (bson_iter_int32 (&iter) == 1);

   assert (bson_iter_init_find (&iter, &reply, "nMatched"));
   assert (BSON_ITER_HOLDS_INT32 (&iter));
   assert (bson_iter_int32 (&iter) == 0);

   assert (bson_iter_init_find (&iter, &reply, "nRemoved"));
   assert (BSON_ITER_HOLDS_INT32 (&iter));
   assert (bson_iter_int32 (&iter) == 1);

   assert (bson_iter_init_find (&iter, &reply, "nInserted"));
   assert (BSON_ITER_HOLDS_INT32 (&iter));
   assert (bson_iter_int32 (&iter) == 0);

   if (bson_iter_init_find (&iter, &reply, "nModified")) {
      assert (BSON_ITER_HOLDS_INT32 (&iter));
      assert (bson_iter_int32 (&iter) == 0);
   }

   assert (bson_iter_init_find (&iter, &reply, "upserted"));
   assert (BSON_ITER_HOLDS_ARRAY (&iter));
   assert (bson_iter_recurse (&iter, &ar));
   assert (bson_iter_next (&ar));
   assert (BSON_ITER_HOLDS_DOCUMENT (&ar));
   assert (bson_iter_recurse (&ar, &citer));
   assert (bson_iter_next (&citer));
   assert (BSON_ITER_IS_KEY (&citer, "index"));
   assert (bson_iter_int32 (&citer) == 1);
   assert (bson_iter_next (&citer));
   assert (BSON_ITER_IS_KEY (&citer, "_id"));
   assert (BSON_ITER_HOLDS_OID (&citer));
   assert (!bson_iter_next (&citer));
   assert (!bson_iter_next (&ar));

   assert (bson_iter_init_find (&iter, &reply, "writeErrors"));
   assert (BSON_ITER_HOLDS_ARRAY (&iter));
   assert (bson_iter_recurse (&iter, &ar));
   assert (!bson_iter_next (&ar));

   bson_destroy (&reply);

   r = mongoc_collection_drop (collection, &error);
   assert (r);

   mongoc_bulk_operation_destroy (bulk);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);

   bson_destroy (doc);
   bson_destroy (sel);
}