Example #1
0
static void
test_concat (void)
{
   bson_t bcon, expected, child, child2;

   bson_init (&bcon);
   bson_init (&expected);
   bson_init (&child);
   bson_init (&child2);

   bson_append_utf8 (&child, "hello", -1, "world", -1);
   bson_append_document (&expected, "foo", -1, &child);

   BCON_APPEND (&bcon, "foo", "{", BCON(&child), "}");

   bson_eq_bson (&bcon, &expected);

   bson_reinit (&bcon);
   bson_reinit (&expected);
   bson_reinit (&child);

   bson_append_utf8 (&child, "0", -1, "bar", -1);
   bson_append_utf8 (&child, "1", -1, "baz", -1);
   bson_append_array (&expected, "foo", -1, &child);

   bson_append_utf8 (&child2, "0", -1, "baz", -1);
   BCON_APPEND (&bcon, "foo", "[", "bar", BCON(&child2), "]");

   bson_eq_bson (&bcon, &expected);

   bson_destroy (&bcon);
   bson_destroy (&child);
   bson_destroy (&child2);
   bson_destroy (&expected);
}
Example #2
0
static int
set_clar_status_func(
        struct xuser_cnts_state *data,
        int user_id,
        int clar_id,
        const ej_uuid_t *p_clar_uuid)
{
    struct xuser_mongo_cnts_state *state = (struct xuser_mongo_cnts_state *) data;
    struct team_extra *extra = do_get_entry(state, user_id);
    if (!extra) return -1;
    if (!p_clar_uuid) return -1;
    int r = team_extra_add_clar_uuid(extra, p_clar_uuid);
    if (r <= 0) return r;
    if (ej_uuid_is_nonempty(extra->uuid)) {
        bson *arr = ej_bson_unparse_array_uuid(extra->clar_uuids, extra->clar_uuids_size);
        bson *doc = bson_new();
        bson_append_array(doc, "clar_uuids", arr);
        bson_free(arr); arr = NULL;
        bson_finish(doc);
        return do_update(state, extra, NULL, doc);
    } else {
        return do_insert(state, extra);
    }
    return -1;
}
Example #3
0
static void
test_bson_build_child_array (void)
{
   bson_t b;
   bson_t child;
   bson_t *b2;
   bson_t *child2;

   bson_init(&b);
   assert(bson_append_array_begin(&b, "foo", -1, &child));
   assert(bson_append_utf8(&child, "0", -1, "baz", -1));
   assert(bson_append_array_end(&b, &child));

   b2 = bson_new();
   child2 = bson_new();
   assert(bson_append_utf8(child2, "0", -1, "baz", -1));
   assert(bson_append_array(b2, "foo", -1, child2));
   bson_destroy(child2);

   assert(b.len == b2->len);
   assert_bson_equal(&b, b2);

   bson_destroy(&b);
   bson_destroy(b2);
}
Example #4
0
bson_t * bson_pipeline_query1_create()
{
    bson_t *bson_pipeline_query = bson_new();
    bson_t *bson1, *bson2, *bson3, *bson4;
    
    bson1 = bson_new();
    
    bson2 = bson_new();
    bson3 = bson_new();
    
    bson_append_utf8(bson3, "_id", -1, "$action", -1);
    
    bson4 = bson_new();
    bson_append_int32(bson4, "$sum", -1, 1);
    bson_append_document(bson3, "count", -1, bson4);
    bson_append_document(bson2, "$group", -1, bson3);
    bson_append_document(bson1, "0", -1, bson2);
    
    
    bson2 = bson_new();
    bson3 = bson_new();
    
    bson_append_int32(bson3, "count", -1, -1);
    bson_append_document(bson2, "$sort", -1, bson3);
    bson_append_document(bson1, "1", -1, bson2);
    
    
    bson_append_array(bson_pipeline_query, "pipeline", -1, bson1);
    
    return bson_pipeline_query;
}
Example #5
0
static void
append_write_err (bson_t *doc,
                  uint32_t code,
                  const char *errmsg,
                  size_t errmsg_len,
                  const bson_t *errinfo)
{
   bson_t array = BSON_INITIALIZER;
   bson_t child;

   BSON_ASSERT (errmsg);

   /* writeErrors: [{index: 0, code: code, errmsg: errmsg, errInfo: {...}}] */
   bson_append_document_begin (&array, "0", 1, &child);
   bson_append_int32 (&child, "index", 5, 0);
   bson_append_int32 (&child, "code", 4, (int32_t) code);
   bson_append_utf8 (&child, "errmsg", 6, errmsg, (int) errmsg_len);
   if (errinfo) {
      bson_append_document (&child, "errInfo", 7, errinfo);
   }

   bson_append_document_end (&array, &child);
   bson_append_array (doc, "writeErrors", 11, &array);

   bson_destroy (&array);
}
Example #6
0
void core::append(const types::b_array& value) {
    stdx::string_view key = _impl->next_key();
    bson_t bson;
    bson_init_static(&bson, value.value.data(), value.value.length());

    bson_append_array(_impl->back(), key.data(), key.length(), &bson);
}
Example #7
0
void
test_bson_array (void)
{
  bson *b, *e1, *e2;

  e1 = bson_new ();
  bson_append_int32 (e1, "0", 1984);
  bson_append_string (e1, "1", "hello world", -1);
  bson_finish (e1);

  e2 = bson_new ();
  bson_append_string (e2, "0", "bar", -1);
  ok (bson_append_array (e2, "1", e1),
      "bson_append_array() works");
  bson_finish (e2);
  bson_free (e1);

  b = bson_new ();
  ok (bson_append_array (b, "0", e2),
      "bson_append_array() works still");
  bson_finish (b);
  bson_free (e2);

  cmp_ok (bson_size (b), "==", 58, "BSON array element size check");
  ok (memcmp (bson_data (b),
	      "\072\000\000\000\004\060\000\062\000\000\000\002\060\000\004"
	      "\000\000\000\142\141\162\000\004\061\000\037\000\000\000\020"
	      "\060\000\300\007\000\000\002\061\000\014\000\000\000\150\145"
	      "\154\154\157\040\167\157\162\154\144\000\000\000\000",
	      bson_size (b)) == 0,
      "BSON array element contents check");

  bson_free (b);

  e1 = bson_new ();
  bson_append_int32 (e1, "0", 1984);
  b = bson_new ();

  ok (bson_append_array (b, "array", e1) == FALSE,
      "bson_append_array() with an unfinished array should fail");
  bson_finish (e1);
  ok (bson_append_array (b, NULL, e1) == FALSE,
      "bson_append_array() with a NULL name should fail");
  ok (bson_append_array (b, "foo", NULL) == FALSE,
      "bson_append_array() with a NULL array should fail");
  ok (bson_append_array (NULL, "foo", e1) == FALSE,
      "bson_append_array() with a NULL BSON should fail");
  bson_finish (b);
  cmp_ok (bson_size (b), "==", 5,
	  "BSON object should be empty");

  ok (bson_append_array (b, "array", e1) == FALSE,
      "Appending to a finished element should fail");

  bson_free (e1);
  bson_free (b);
}
Example #8
0
static void
test_bson_as_json (void)
{
   bson_oid_t oid;
   bson_decimal128_t decimal128;
   bson_t *b;
   bson_t *b2;
   char *str;
   size_t len;
   int i;

   decimal128.high = 0x3040000000000000ULL;
   decimal128.low  = 0x000000000000000B;
   bson_oid_init_from_string(&oid, "123412341234abcdabcdabcd");

   b = bson_new();
   assert(bson_append_utf8(b, "utf8", -1, "bar", -1));
   assert(bson_append_int32(b, "int32", -1, 1234));
   assert(bson_append_int64(b, "int64", -1, 4321));
   assert(bson_append_double(b, "double", -1, 123.4));
   assert(bson_append_undefined(b, "undefined", -1));
   assert(bson_append_null(b, "null", -1));
   assert(bson_append_oid(b, "oid", -1, &oid));
   assert(bson_append_bool(b, "true", -1, true));
   assert(bson_append_bool(b, "false", -1, false));
   assert(bson_append_time_t(b, "date", -1, time(NULL)));
   assert(bson_append_timestamp(b, "timestamp", -1, (uint32_t)time(NULL), 1234));
   assert(bson_append_regex(b, "regex", -1, "^abcd", "xi"));
   assert(bson_append_dbpointer(b, "dbpointer", -1, "mycollection", &oid));
   assert(bson_append_minkey(b, "minkey", -1));
   assert(bson_append_maxkey(b, "maxkey", -1));
   assert(bson_append_symbol(b, "symbol", -1, "var a = {};", -1));
   assert(bson_append_decimal128(b, "decimal128", -1, &decimal128));

   b2 = bson_new();
   assert(bson_append_int32(b2, "0", -1, 60));
   assert(bson_append_document(b, "document", -1, b2));
   assert(bson_append_array(b, "array", -1, b2));

   {
      const uint8_t binary[] = { 0, 1, 2, 3, 4 };
      assert(bson_append_binary(b, "binary", -1, BSON_SUBTYPE_BINARY,
                                binary, sizeof binary));
   }

   for (i = 0; i < 1000; i++) {
      str = bson_as_json(b, &len);
      bson_free(str);
   }

   bson_destroy(b);
   bson_destroy(b2);
}
Example #9
0
static void
json_key_to_bson_key (bson *b, void *val,
		      const gchar *key)
{
  switch (json_object_get_type (val))
    {
    case json_type_boolean:
      bson_append_boolean (b, key, json_object_get_boolean (val));
      break;
    case json_type_double:
      bson_append_double (b, key, json_object_get_double (val));
      break;
    case json_type_int:
      bson_append_int32 (b, key, json_object_get_int (val));
      break;
    case json_type_string:
      bson_append_string (b, key, json_object_get_string (val), -1);
      break;
    case json_type_object:
      {
	bson *sub;

	sub = json_to_bson (val);
	bson_append_document (b, key, sub);
	bson_free (sub);
	break;
      }
    case json_type_array:
      {
	gint pos;
	bson *sub;

	sub = bson_new ();

	for (pos = 0; pos < json_object_array_length (val); pos++)
	  {
	    gchar *nk = g_strdup_printf ("%d", pos);

	    json_key_to_bson_key (sub, json_object_array_get_idx (val, pos),
				  nk);
	    g_free (nk);
	  }
	bson_finish (sub);

	bson_append_array (b, key, sub);
	bson_free (sub);
	break;
      }
    default:
      break;
    }
}
Example #10
0
bson_t * bson_pipeline_query4_create()
{
    bson_t *bson_pipeline_query = bson_new();
    bson_t *bson1, *bson2, *bson3, *bson4;
    
    bson1 = bson_new();
    
    bson2 = bson_new();
    bson3 = bson_new();
    
    bson_append_utf8(bson3, "modelName", -1, "movies", -1);
    bson_append_document(bson2, "$match", -1, bson3);
    bson_append_document(bson1, "0", -1, bson2);
    
    
    bson2 = bson_new();
    bson3 = bson_new();
    
    bson_append_utf8(bson3, "action", -1, "Liked", -1);
    bson_append_document(bson2, "$match", -1, bson3);
    bson_append_document(bson1, "1", -1, bson2);
    bson2 = bson_new();
    bson3 = bson_new();
    
    bson_append_utf8(bson3, "_id", -1, "$title", -1);
    
    bson4 = bson_new();
    bson_append_int32(bson4, "$sum", -1, 1);
    bson_append_document(bson3, "count", -1, bson4);
    bson_append_document(bson2, "$group", -1, bson3);
    bson_append_document(bson1, "2", -1, bson2);
    
    
    bson2 = bson_new();
    bson3 = bson_new();
    
    bson_append_int32(bson3, "count", -1, -1);
    bson_append_document(bson2, "$sort", -1, bson3);
    bson_append_document(bson1, "3", -1, bson2);
    
    
    bson2 = bson_new();
    bson_append_int32(bson2, "$limit", -1, 15);
    
    bson_append_document(bson1, "4", -1, bson2);
    
    
    bson_append_array(bson_pipeline_query, "pipeline", -1, bson1);
    
    return bson_pipeline_query;
}
Example #11
0
bson *
team_extra_bson_unparse(const struct team_extra *extra)
{
    bson *res = bson_new();
    ej_bson_append_uuid(res, "_id", &extra->uuid);
    bson_append_int32(res, "user_id", extra->user_id);
    bson_append_int32(res, "contest_id", extra->contest_id);
    if (extra->disq_comment) {
        bson_append_string(res, "disq_comment", extra->disq_comment, strlen(extra->disq_comment));
    }
    bson_append_int32(res, "status", extra->status);
    bson_append_int32(res, "run_fields", extra->run_fields);
    if (extra->clar_map_size > 0) {
        bson *arr = bson_new();
        for (int i = 0, j = 0; i < extra->clar_map_size; ++i) {
            if (extra->clar_map[i / BPE] & (1UL << i % BPE)) {
                unsigned char buf[32];
                sprintf(buf, "%d", j++);
                bson_append_int32(arr, buf, i);
            }
        }
        bson_finish(arr);
        bson_append_document(res, "viewed_clars", arr);
        bson_free(arr); arr = NULL;
    }
    if (extra->clar_uuids_size > 0) {
        bson *arr = NULL;
        bson_append_array(res, "clar_uuids", (arr = ej_bson_unparse_array_uuid(extra->clar_uuids, extra->clar_uuids_size)));
        bson_free(arr); arr = NULL;
    }
    if (extra->warn_u > 0) {
        bson *arr = team_warnings_bson_unparse(extra->warns, extra->warn_u);
        bson_append_array(res, "warnings", arr);
        bson_free(arr); arr = NULL;
    }
    bson_finish(res);
    return res;
}
Example #12
0
static void json_append_to_bson(bson* b, char *key, struct json_object *val)
{
    if (!b || !key || !val) return;

    struct array_list *list;
    enum json_type type;
    bson *sub;
    char tok[64];

    type = json_object_get_type(val);

    switch (type) {
    case json_type_boolean:
        bson_append_boolean(b, key, json_object_get_boolean(val));
        break;
    case json_type_int:
        bson_append_int32(b, key, json_object_get_int(val));
        break;
    case json_type_double:
        bson_append_double(b, key, json_object_get_double(val));
        break;
    case json_type_string:
        bson_append_string(b, key, json_object_get_string(val), -1);
        break;
    case json_type_array:
        sub = bson_new();

        list = json_object_get_array(val);
        for (int pos = 0; pos < list->length; pos++) {
            sprintf(tok, "%d", pos);
            json_append_to_bson(sub, tok, (struct json_object*)list->array[pos]);
        }
        
        bson_finish(sub);
        bson_append_array(b, key, sub);
        bson_free(sub);
        break;
    case json_type_object:
        sub = mbson_new_from_jsonobj(val, true, false);
        bson_append_document(b, key, sub);
        bson_free(sub);
        break;
    default:
        break;
    }
    
    
}
Example #13
0
static void
append_upserted (bson_t *doc, const bson_value_t *upserted_id)
{
   bson_t array = BSON_INITIALIZER;
   bson_t child;

   /* append upserted: [{index: 0, _id: upserted_id}]*/
   bson_append_document_begin (&array, "0", 1, &child);
   bson_append_int32 (&child, "index", 5, 0);
   bson_append_value (&child, "_id", 3, upserted_id);
   bson_append_document_end (&array, &child);

   bson_append_array (doc, "upserted", 8, &array);

   bson_destroy (&array);
}
Example #14
0
bson *
test_bson_generate_full (void)
{
  bson *b, *d, *a, *scope;
  guint8 oid[] = "1234567890ab";

  a = bson_new ();
  bson_append_int32 (a, "0", 32);
  bson_append_int64 (a, "1", (gint64)-42);
  bson_finish (a);

  d = bson_new ();
  bson_append_string (d, "name", "sub-document", -1);
  bson_append_int32 (d, "answer", 42);
  bson_finish (d);

  scope = bson_new ();
  bson_append_string (scope, "v", "hello world", -1);
  bson_finish (scope);

  b = bson_new ();
  bson_append_double (b, "double", 3.14);
  bson_append_string (b, "str", "hello world", -1);
  bson_append_document (b, "doc", d);
  bson_append_array (b, "array", a);
  bson_append_binary (b, "binary0", BSON_BINARY_SUBTYPE_GENERIC,
                      (guint8 *)"foo\0bar", 7);
  bson_append_oid (b, "_id", oid);
  bson_append_boolean (b, "TRUE", FALSE);
  bson_append_utc_datetime (b, "date", 1294860709000);
  bson_append_timestamp (b, "ts", 1294860709000);
  bson_append_null (b, "null");
  bson_append_regex (b, "foobar", "s/foo.*bar/", "i");
  bson_append_javascript (b, "alert", "alert (\"hello world!\");", -1);
  bson_append_symbol (b, "sex", "Marilyn Monroe", -1);
  bson_append_javascript_w_scope (b, "print", "alert (v);", -1, scope);
  bson_append_int32 (b, "int32", 32);
  bson_append_int64 (b, "int64", (gint64)-42);
  bson_finish (b);

  bson_free (d);
  bson_free (a);
  bson_free (scope);

  return b;
}
Example #15
0
static void
test_bson_append_array (void)
{
   bson_t *b;
   bson_t *b2;

   b = bson_new();
   b2 = bson_new();
   assert(bson_append_utf8(b2, "0", -1, "hello", -1));
   assert(bson_append_utf8(b2, "1", -1, "world", -1));
   assert(bson_append_array(b, "array", -1, b2));
   bson_destroy(b2);
   b2 = get_bson("test23.bson");
   assert_bson_equal(b, b2);
   bson_destroy(b);
   bson_destroy(b2);
}
Example #16
0
static void
test_inline_array (void)
{
   bson_t bcon, expected, child;

   bson_init (&bcon);
   bson_init (&expected);
   bson_init (&child);

   bson_append_utf8 (&child, "0", -1, "baz", -1);
   bson_append_array (&expected, "foo", -1, &child);

   BCON_APPEND (&bcon, "foo", "[", "baz", "]");

   bson_eq_bson (&bcon, &expected);

   bson_destroy (&bcon);
   bson_destroy (&child);
   bson_destroy (&expected);
}
Example #17
0
static void
test_inline_nested (void)
{
   bson_t bcon, expected, foo, bar, third;

   bson_init (&bcon);
   bson_init (&expected);
   bson_init (&foo);
   bson_init (&bar);
   bson_init (&third);

   bson_append_utf8 (&third, "hello", -1, "world", -1);
   bson_append_int32 (&bar, "0", -1, 1);
   bson_append_int32 (&bar, "1", -1, 2);
   bson_append_document (&bar, "2", -1, &third);
   bson_append_array (&foo, "bar", -1, &bar);
   bson_append_document (&expected, "foo", -1, &foo);

   BCON_APPEND (&bcon,
                "foo",
                "{",
                "bar",
                "[",
                BCON_INT32 (1),
                BCON_INT32 (2),
                "{",
                "hello",
                "world",
                "}",
                "]",
                "}");

   bson_eq_bson (&bcon, &expected);

   bson_destroy (&bcon);
   bson_destroy (&expected);
   bson_destroy (&foo);
   bson_destroy (&bar);
   bson_destroy (&third);
}
Example #18
0
static void
append_write_concern_err (bson_t *doc, const char *errmsg, size_t errmsg_len)
{
   bson_t array = BSON_INITIALIZER;
   bson_t child;
   bson_t errinfo;

   BSON_ASSERT (errmsg);

   /* writeConcernErrors: [{code: 64,
    *                       errmsg: errmsg,
    *                       errInfo: {wtimeout: true}}] */
   bson_append_document_begin (&array, "0", 1, &child);
   bson_append_int32 (&child, "code", 4, 64);
   bson_append_utf8 (&child, "errmsg", 6, errmsg, (int) errmsg_len);
   bson_append_document_begin (&child, "errInfo", 7, &errinfo);
   bson_append_bool (&errinfo, "wtimeout", 8, true);
   bson_append_document_end (&child, &errinfo);
   bson_append_document_end (&array, &child);
   bson_append_array (doc, "writeConcernErrors", 18, &array);

   bson_destroy (&array);
}
Example #19
0
bool
mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk,
                                             const bson_t *selector,
                                             const bson_t *document,
                                             const bson_t *opts,
                                             bson_error_t *error) /* OUT */
{
   mongoc_bulk_update_many_opts_t update_opts;
   bool ret;

   ENTRY;

   BULK_RETURN_IF_PRIOR_ERROR;

   if (!_mongoc_bulk_update_many_opts_parse (
          bulk->client, opts, &update_opts, error)) {
      _mongoc_bulk_update_many_opts_cleanup (&update_opts);
      RETURN (false);
   }

   if (!bson_empty (&update_opts.arrayFilters)) {
      bson_append_array (
         &update_opts.extra, "arrayFilters", 12, &update_opts.arrayFilters);
   }

   ret = _mongoc_bulk_operation_update_with_opts (bulk,
                                                  selector,
                                                  document,
                                                  &update_opts.update,
                                                  &update_opts.extra,
                                                  true /* multi */,
                                                  error);

   _mongoc_bulk_update_many_opts_cleanup (&update_opts);
   RETURN (ret);
}
Example #20
0
static void
test_bson_iter_recurse (void)
{
   bson_iter_t iter;
   bson_iter_t child;
   bson_t b;
   bson_t cb;

   bson_init(&b);
   bson_init(&cb);
   assert(bson_append_int32(&cb, "0", 1, 0));
   assert(bson_append_int32(&cb, "1", 1, 1));
   assert(bson_append_int32(&cb, "2", 1, 2));
   assert(bson_append_array(&b, "key", -1, &cb));
   assert(bson_iter_init_find(&iter, &b, "key"));
   assert(BSON_ITER_HOLDS_ARRAY(&iter));
   assert(bson_iter_recurse(&iter, &child));
   assert(bson_iter_find(&child, "0"));
   assert(bson_iter_find(&child, "1"));
   assert(bson_iter_find(&child, "2"));
   assert(!bson_iter_next(&child));
   bson_destroy(&b);
   bson_destroy(&cb);
}
Example #21
0
mongoc_cursor_t *
_mongoc_cursor_new (mongoc_client_t           *client,
                    const char                *db_and_collection,
                    mongoc_query_flags_t       flags,
                    bson_uint32_t              skip,
                    bson_uint32_t              limit,
                    bson_uint32_t              batch_size,
                    bson_bool_t                is_command,
                    const bson_t              *query,
                    const bson_t              *fields,
                    const mongoc_read_prefs_t *read_prefs)
{
   mongoc_read_mode_t mode;
   mongoc_cursor_t *cursor;
   const bson_t *tags;
   const char *mode_str;
   bson_t child;

   ENTRY;

   BSON_ASSERT(client);
   BSON_ASSERT(db_and_collection);
   BSON_ASSERT(query);

   /* we can't have exhaust queries with limits */
   BSON_ASSERT (!((flags & MONGOC_QUERY_EXHAUST) && limit));

   /* we can't have exhaust queries with sharded clusters */
   BSON_ASSERT (!((flags & MONGOC_QUERY_EXHAUST) && client->cluster.isdbgrid));

   /*
    * Cursors execute their query lazily. This sadly means that we must copy
    * some extra data around between the bson_t structures. This should be
    * small in most cases, so it reduces to a pure memcpy. The benefit to this
    * design is simplified error handling by API consumers.
    */

   cursor = bson_malloc0(sizeof *cursor);
   cursor->client = client;
   strncpy(cursor->ns, db_and_collection, sizeof cursor->ns - 1);
   cursor->nslen = strlen(cursor->ns);
   cursor->flags = flags;
   cursor->skip = skip;
   cursor->limit = limit;
   cursor->batch_size = cursor->batch_size;

   cursor->is_command = is_command;

   if (!bson_has_field (query, "$query")) {
      bson_init (&cursor->query);
      bson_append_document (&cursor->query, "$query", 6, query);
   } else {
      bson_copy_to (query, &cursor->query);
   }

   if (read_prefs) {
      cursor->read_prefs = mongoc_read_prefs_copy (read_prefs);

      mode = mongoc_read_prefs_get_mode (read_prefs);
      tags = mongoc_read_prefs_get_tags (read_prefs);

      if (mode != MONGOC_READ_PRIMARY) {
         flags |= MONGOC_QUERY_SLAVE_OK;

         if ((mode != MONGOC_READ_SECONDARY_PREFERRED) || tags) {
            bson_append_document_begin (&cursor->query, "$readPreference",
                                        15, &child);
            mode_str = _mongoc_cursor_get_read_mode_string (mode);
            bson_append_utf8 (&child, "mode", 4, mode_str, -1);
            if (tags) {
               bson_append_array (&child, "tags", 4, tags);
            }
            bson_append_document_end (&cursor->query, &child);
         }
      }
   }

   if (fields) {
      bson_copy_to(fields, &cursor->fields);
   } else {
      bson_init(&cursor->fields);
   }

   _mongoc_buffer_init(&cursor->buffer, NULL, 0, NULL);

   mongoc_counter_cursors_active_inc();

   RETURN(cursor);
}
Example #22
0
static void
test_bson_append_general (void)
{
   bson_uint8_t bytes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x23, 0x45 };
   bson_oid_t oid;
   bson_t *bson;
   bson_t *array;
   bson_t *subdoc;

   bson = bson_new();
   assert(bson_append_int32(bson, "int", -1, 1));
   assert_bson_equal_file(bson, "test1.bson");
   bson_destroy(bson);

   bson = bson_new();
   assert(bson_append_int64(bson, "int64", -1, 1));
   assert_bson_equal_file(bson, "test2.bson");
   bson_destroy(bson);

   bson = bson_new();
   assert(bson_append_double(bson, "double", -1, 1.123));
   assert_bson_equal_file(bson, "test3.bson");
   bson_destroy(bson);

   bson = bson_new();
   assert(bson_append_utf8(bson, "string", -1, "some string", -1));
   assert_bson_equal_file(bson, "test5.bson");
   bson_destroy(bson);

   bson = bson_new();
   array = bson_new();
   assert(bson_append_int32(array, "0", -1, 1));
   assert(bson_append_int32(array, "1", -1, 2));
   assert(bson_append_int32(array, "2", -1, 3));
   assert(bson_append_int32(array, "3", -1, 4));
   assert(bson_append_int32(array, "4", -1, 5));
   assert(bson_append_int32(array, "5", -1, 6));
   assert(bson_append_array(bson, "array[int]", -1, array));
   assert_bson_equal_file(bson, "test6.bson");
   bson_destroy(array);
   bson_destroy(bson);

   bson = bson_new();
   array = bson_new();
   assert(bson_append_double(array, "0", -1, 1.123));
   assert(bson_append_double(array, "1", -1, 2.123));
   assert(bson_append_array(bson, "array[double]", -1, array));
   assert_bson_equal_file(bson, "test7.bson");
   bson_destroy(array);
   bson_destroy(bson);

   bson = bson_new();
   subdoc = bson_new();
   assert(bson_append_int32(subdoc, "int", -1, 1));
   assert(bson_append_document(bson, "document", -1, subdoc));
   assert_bson_equal_file(bson, "test8.bson");
   bson_destroy(subdoc);
   bson_destroy(bson);

   bson = bson_new();
   assert(bson_append_null(bson, "null", -1));
   assert_bson_equal_file(bson, "test9.bson");
   bson_destroy(bson);

   bson = bson_new();
   assert(bson_append_regex(bson, "regex", -1, "1234", "i"));
   assert_bson_equal_file(bson, "test10.bson");
   bson_destroy(bson);

   bson = bson_new();
   assert(bson_append_utf8(bson, "hello", -1, "world", -1));
   assert_bson_equal_file(bson, "test11.bson");
   bson_destroy(bson);

   bson = bson_new();
   array = bson_new();
   assert(bson_append_utf8(array, "0", -1, "awesome", -1));
   assert(bson_append_double(array, "1", -1, 5.05));
   assert(bson_append_int32(array, "2", -1, 1986));
   assert(bson_append_array(bson, "BSON", -1, array));
   assert_bson_equal_file(bson, "test12.bson");
   bson_destroy(bson);
   bson_destroy(array);

   bson = bson_new();
   memcpy(&oid, bytes, sizeof oid);
   assert(bson_append_oid(bson, "_id", -1, &oid));
   subdoc = bson_new();
   assert(bson_append_oid(subdoc, "_id", -1, &oid));
   array = bson_new();
   assert(bson_append_utf8(array, "0", -1, "1", -1));
   assert(bson_append_utf8(array, "1", -1, "2", -1));
   assert(bson_append_utf8(array, "2", -1, "3", -1));
   assert(bson_append_utf8(array, "3", -1, "4", -1));
   assert(bson_append_array(subdoc, "tags", -1, array));
   bson_destroy(array);
   assert(bson_append_utf8(subdoc, "text", -1, "asdfanother", -1));
   array = bson_new();
   assert(bson_append_utf8(array, "name", -1, "blah", -1));
   assert(bson_append_document(subdoc, "source", -1, array));
   bson_destroy(array);
   assert(bson_append_document(bson, "document", -1, subdoc));
   bson_destroy(subdoc);
   array = bson_new();
   assert(bson_append_utf8(array, "0", -1, "source", -1));
   assert(bson_append_array(bson, "type", -1, array));
   bson_destroy(array);
   array = bson_new();
   assert(bson_append_utf8(array, "0", -1, "server_created_at", -1));
   assert(bson_append_array(bson, "missing", -1, array));
   bson_destroy(array);
   assert_bson_equal_file(bson, "test17.bson");
   bson_destroy(bson);
}
Example #23
0
static void on_stack_change(jsonsl_t parser, jsonsl_action_t action, struct jsonsl_state_st * state, const jsonsl_char_t * at)
{
/*	printf("%c%c", action, state->type);
	if (state->type == JSONSL_T_SPECIAL) {
		printf("%c", state->special_flags);
	}
	printf("%d", state->pos_begin);
	if (action == JSONSL_ACTION_POP) {
		printf("-%d", state->pos_cur);
	}
	printf("\n");
*/
	struct bson_state * bstate = (struct bson_state *) parser->data;

	if (action == JSONSL_ACTION_PUSH) {

		if (state->type == JSONSL_T_OBJECT || state->type == JSONSL_T_LIST) {

			if (bstate->cur_entry > -1) {
				bstate->cur_entry++;
				bstate->entry[bstate->cur_entry].key = (bstring) state->data;
			} else {
				bstate->cur_entry = 0;
				bstate->entry[bstate->cur_entry].key = NULL;
			}

			bstate->entry[bstate->cur_entry].bson = bson_new();
			bstate->entry[bstate->cur_entry].array_index = 0;
		}

	} else if (action == JSONSL_ACTION_POP) {

		if (state->type == JSONSL_T_HKEY) {

			state->data = read_string(bstate->text + state->pos_begin, state->pos_cur - state->pos_begin);

		} else if (state->type == JSONSL_T_OBJECT || state->type == JSONSL_T_LIST) {

			if (bstate->cur_entry > 0) {
				struct bson_entry * entry = &(bstate->entry[bstate->cur_entry]);
				struct bson_entry * parent = &(bstate->entry[bstate->cur_entry - 1]);
				if (state->type == JSONSL_T_OBJECT) {
					bson_append_document(parent->bson, bdata(entry->key), blength(entry->key), entry->bson);
				} else {
					bson_append_array(parent->bson, bdata(entry->key), blength(entry->key), entry->bson);
				}
			}

			bstate->cur_entry--;

		} else {

			bstring key = (bstring) state->data;
			if (key == NULL) {
				key = bformat("%d", bstate->entry[bstate->cur_entry].array_index);
				bstate->entry[bstate->cur_entry].array_index++;
			}

			if (state->type == JSONSL_T_SPECIAL) {

				if (state->special_flags & JSONSL_SPECIALf_BOOLEAN) {
					bson_append_bool(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key), state->special_flags & JSONSL_SPECIALf_TRUE);

				} else if (state->special_flags & JSONSL_SPECIALf_NULL) {
					bson_append_null(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key));

				} else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
					size_t length = state->pos_cur - state->pos_begin;
					char num[length + 1];
					* (num + length) = '\0';
					memcpy(num, bstate->text + state->pos_begin, length);

					if (state->special_flags & JSONSL_SPECIALf_NUMNOINT) {
						bson_append_double(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key), atof(num));
					} else {
						bson_append_int64(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key), atoi(num));
					}
				}

			} else {
				bstring value = read_string(bstate->text + state->pos_begin, state->pos_cur - state->pos_begin);
				bson_append_utf8(bstate->entry[bstate->cur_entry].bson, bdata(key), blength(key), bdata(value), blength(value));
			}
		}
	}
}
/** save a gridfs file */
bool
mongoc_gridfs_file_save (mongoc_gridfs_file_t *file)
{
   bson_t *selector, *update, child;
   const char *md5;
   const char *filename;
   const char *content_type;
   const bson_t *aliases;
   const bson_t *metadata;
   bool r;

   ENTRY;

   if (!file->is_dirty) {
      return 1;
   }

   if (file->page && _mongoc_gridfs_file_page_is_dirty (file->page)) {
      _mongoc_gridfs_file_flush_page (file);
   }

   md5 = mongoc_gridfs_file_get_md5 (file);
   filename = mongoc_gridfs_file_get_filename (file);
   content_type = mongoc_gridfs_file_get_content_type (file);
   aliases = mongoc_gridfs_file_get_aliases (file);
   metadata = mongoc_gridfs_file_get_metadata (file);

   selector = bson_new ();
   bson_append_value (selector, "_id", -1, &file->files_id);

   update = bson_new ();
   bson_append_document_begin (update, "$set", -1, &child);
   bson_append_int64 (&child, "length", -1, file->length);
   bson_append_int32 (&child, "chunkSize", -1, file->chunk_size);
   bson_append_date_time (&child, "uploadDate", -1, file->upload_date);

   if (md5) {
      bson_append_utf8 (&child, "md5", -1, md5, -1);
   }

   if (filename) {
      bson_append_utf8 (&child, "filename", -1, filename, -1);
   }

   if (content_type) {
      bson_append_utf8 (&child, "contentType", -1, content_type, -1);
   }

   if (aliases) {
      bson_append_array (&child, "aliases", -1, aliases);
   }

   if (metadata) {
      bson_append_document (&child, "metadata", -1, metadata);
   }

   bson_append_document_end (update, &child);

   r = mongoc_collection_update (file->gridfs->files, MONGOC_UPDATE_UPSERT,
                                 selector, update, NULL, &file->error);

   file->failed = !r;


   bson_destroy (selector);
   bson_destroy (update);

   file->is_dirty = 0;

   RETURN (r);
}
/* Update result with the read prefs, following Server Selection Spec.
 * The driver must have discovered the server is a mongos.
 */
static void
_apply_read_preferences_mongos (const mongoc_read_prefs_t *read_prefs,
                                const bson_t *query_bson,
                                mongoc_apply_read_prefs_result_t *result /* OUT */)
{
   mongoc_read_mode_t mode;
   const bson_t *tags = NULL;
   bson_t child;
   const char *mode_str;

   mode = mongoc_read_prefs_get_mode (read_prefs);
   if (read_prefs) {
      tags = mongoc_read_prefs_get_tags (read_prefs);
   }

   /* Server Selection Spec says:
    *
    * For mode 'primary', drivers MUST NOT set the slaveOK wire protocol flag
    *   and MUST NOT use $readPreference
    *
    * For mode 'secondary', drivers MUST set the slaveOK wire protocol flag and
    *   MUST also use $readPreference
    *
    * For mode 'primaryPreferred', drivers MUST set the slaveOK wire protocol
    *   flag and MUST also use $readPreference
    *
    * For mode 'secondaryPreferred', drivers MUST set the slaveOK wire protocol
    *   flag. If the read preference contains a non-empty tag_sets parameter,
    *   drivers MUST use $readPreference; otherwise, drivers MUST NOT use
    *   $readPreference
    *
    * For mode 'nearest', drivers MUST set the slaveOK wire protocol flag and
    *   MUST also use $readPreference
    */
   if (mode == MONGOC_READ_SECONDARY_PREFERRED && bson_empty0 (tags)) {
      result->flags |= MONGOC_QUERY_SLAVE_OK;

   } else if (mode != MONGOC_READ_PRIMARY) {
      result->flags |= MONGOC_QUERY_SLAVE_OK;

      /* Server Selection Spec: "When any $ modifier is used, including the
       * $readPreference modifier, the query MUST be provided using the $query
       * modifier".
       *
       * This applies to commands, too.
       */
      result->query_with_read_prefs = bson_new ();
      result->query_owned = true;

      if (bson_has_field (query_bson, "$query")) {
         bson_concat (result->query_with_read_prefs, query_bson);
      } else {
         bson_append_document (result->query_with_read_prefs,
                               "$query", 6, query_bson);
      }

      bson_append_document_begin (result->query_with_read_prefs,
                                  "$readPreference", 15, &child);
      mode_str = _get_read_mode_string (mode);
      bson_append_utf8 (&child, "mode", 4, mode_str, -1);
      if (!bson_empty0 (tags)) {
         bson_append_array (&child, "tags", 4, tags);
      }

      bson_append_document_end (result->query_with_read_prefs, &child);
   }
}
Example #26
0
static struct xuser_team_extras *
get_entries_func(
        struct xuser_cnts_state *data,
        int count,
        int *user_ids)
{
    struct xuser_mongo_cnts_state *state = (struct xuser_mongo_cnts_state *) data;
    int *loc_users = NULL;
    int loc_count = count, query_count = 0;
    struct xuser_mongo_team_extras *res = NULL;
    bson **query_results = NULL;
    struct team_extra *extra = NULL;

    if (count <= 0 || !user_ids) return NULL;

    XCALLOC(res, 1);
    res->b.free = xuser_mongo_team_extras_free;
    res->b.get = xuser_mongo_team_extras_get;
    res->state = state;

    /*
    fprintf(stderr, "[ ");
    for (int ii = 0; ii < count; ++ii)
        fprintf(stderr, " %d", user_ids[ii]);
    fprintf(stderr, " ]\n");
    */

    XCALLOC(loc_users, loc_count);
    memcpy(loc_users, user_ids, loc_count * sizeof(user_ids[0]));
    qsort(loc_users, loc_count, sizeof(loc_users[0]), isort_func);

    /*
    fprintf(stderr, "[ ");
    for (int ii = 0; ii < loc_count; ++ii)
        fprintf(stderr, " %d", loc_users[ii]);
    fprintf(stderr, " ]\n");
    */

    /*
    fprintf(stderr, "<");
    for (int ii = 0; ii < state->u; ++ii)
        fprintf(stderr, " %d", state->v[ii]->user_id);
    fprintf(stderr, " >\n");
    */

    // copy the existing users
    for (int i1 = 0, i2 = 0; i1 < state->u && i2 < loc_count; ) {
        if (state->v[i1]->user_id == loc_users[i2]) {
            // copy that user
            loc_users[i2++] = 0;
            ++i1;
        } else if (state->v[i1]->user_id < loc_users[i2]) {
            ++i1;
        } else {
            ++i2;
        }
    }

    /*
    fprintf(stderr, "[ ");
    for (int ii = 0; ii < loc_count; ++ii)
        fprintf(stderr, " %d", loc_users[ii]);
    fprintf(stderr, " ]\n");
    */

    // compress the user_ids
    int i1 = 0, i2 = 0;
    for (; i2 < loc_count; ++i2) {
        if (loc_users[i2] > 0) {
            if (i1 == i2) {
                ++i1;
            } else {
                loc_users[i1++] = loc_users[i2];
            }
        }
    }
    loc_count = i1;

    /*
    fprintf(stderr, "[ ");
    for (int ii = 0; ii < loc_count; ++ii)
        fprintf(stderr, " %d", loc_users[ii]);
    fprintf(stderr, " ]\n");
    */

    if (loc_count <= 0) goto done;

    bson *arr = ej_bson_unparse_array_int(loc_users, loc_count);
    bson *indoc = bson_new();
    bson_append_array(indoc, "$in", arr);
    bson_finish(indoc);
    bson_free(arr); arr = NULL;
    bson *query = bson_new();
    bson_append_int32(query, "contest_id", state->contest_id);
    bson_append_document(query, "user_id", indoc);
    bson_finish(query);
    bson_free(indoc); indoc = NULL;

    query_count = state->plugin_state->common->i->query(state->plugin_state->common, "xuser", 0, loc_count, query, NULL, &query_results);
    if (query_count > 0) {
        for (i1 = 0; i1 < query_count; ++i1) {
            if ((extra = team_extra_bson_parse(query_results[i1]))) {
                insert_entry(state, extra->user_id, extra, -1);
            }
            bson_free(query_results[i1]); query_results[i1] = NULL;
        }
    }
    bson_free(query); query = NULL;
    xfree(query_results); query_results = NULL;

    // remove existing entries from loc_count
    for (i1 = 0, i2 = 0; i1 < state->u && i2 < loc_count; ) {
        if (state->v[i1]->user_id == loc_users[i2]) {
            // copy that user
            loc_users[i2++] = 0;
            ++i1;
        } else if (state->v[i1]->user_id < loc_users[i2]) {
            ++i1;
        } else {
            ++i2;
        }
    }
    i1 = 0; i2 = 0;
    for (; i2 < loc_count; ++i2) {
        if (loc_users[i2] > 0) {
            if (i1 == i2) {
                ++i1;
            } else {
                loc_users[i1++] = loc_users[i2];
            }
        }
    }
    loc_count = i1;

    /*
    fprintf(stderr, "[ ");
    for (int ii = 0; ii < loc_count; ++ii)
        fprintf(stderr, " %d", loc_users[ii]);
    fprintf(stderr, " ]\n");
    */

    for (i1 = 0; i1 < loc_count; ++i1) {
        struct team_extra *extra = NULL;
        XCALLOC(extra, 1);
        extra->user_id = loc_users[i1];
        extra->contest_id = state->contest_id;
        insert_entry(state, extra->user_id, extra, -1);
    }

    /*
    fprintf(stderr, "<");
    for (int ii = 0; ii < state->u; ++ii)
        fprintf(stderr, " %d", state->v[ii]->user_id);
    fprintf(stderr, " >\n");
    */

done:
    return &res->b;
}
mongoc_cursor_t *
_mongoc_cursor_new (mongoc_client_t           *client,
                    const char                *db_and_collection,
                    mongoc_query_flags_t       flags,
                    uint32_t                   skip,
                    uint32_t                   limit,
                    uint32_t                   batch_size,
                    bool                       is_command,
                    const bson_t              *query,
                    const bson_t              *fields,
                    const mongoc_read_prefs_t *read_prefs)
{
   mongoc_read_prefs_t *local_read_prefs = NULL;
   mongoc_read_mode_t mode;
   mongoc_cursor_t *cursor;
   const bson_t *tags;
   bson_iter_t iter;
   const char *key;
   const char *mode_str;
   bson_t child;
   bool found = false;
   int i;

   ENTRY;

   BSON_ASSERT (client);
   BSON_ASSERT (db_and_collection);
   BSON_ASSERT (query);

   if (!read_prefs) {
      read_prefs = client->read_prefs;
   }

   cursor = bson_malloc0 (sizeof *cursor);

   /*
    * CDRIVER-244:
    *
    * If this is a command, we need to verify we can send it to the location
    * specified by the read preferences. Otherwise, log a warning that we
    * are rerouting to the primary instance.
    */
   if (is_command &&
       read_prefs &&
       (mongoc_read_prefs_get_mode (read_prefs) != MONGOC_READ_PRIMARY) &&
       bson_iter_init (&iter, query) &&
       bson_iter_next (&iter) &&
       (key = bson_iter_key (&iter))) {
      for (i = 0; gSecondaryOkCommands [i]; i++) {
         if (0 == strcasecmp (key, gSecondaryOkCommands [i])) {
            found = true;
            break;
         }
      }
      if (!found) {
         cursor->redir_primary = true;
         local_read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
         read_prefs = local_read_prefs;
         MONGOC_INFO ("Database command \"%s\" rerouted to primary node", key);
      }
   }

   /*
    * Cursors execute their query lazily. This sadly means that we must copy
    * some extra data around between the bson_t structures. This should be
    * small in most cases, so it reduces to a pure memcpy. The benefit to this
    * design is simplified error handling by API consumers.
    */

   cursor->client = client;
   bson_strncpy (cursor->ns, db_and_collection, sizeof cursor->ns);
   cursor->nslen = (uint32_t)strlen(cursor->ns);
   cursor->flags = flags;
   cursor->skip = skip;
   cursor->limit = limit;
   cursor->batch_size = batch_size;
   cursor->is_command = is_command;

#define MARK_FAILED(c) \
   do { \
      (c)->failed = true; \
      (c)->done = true; \
      (c)->end_of_event = true; \
      (c)->sent = true; \
   } while (0)

   /* we can't have exhaust queries with limits */
   if ((flags & MONGOC_QUERY_EXHAUST) && limit) {
      bson_set_error (&cursor->error,
                      MONGOC_ERROR_CURSOR,
                      MONGOC_ERROR_CURSOR_INVALID_CURSOR,
                      "Cannot specify MONGOC_QUERY_EXHAUST and set a limit.");
      MARK_FAILED (cursor);
      GOTO (finish);
   }

   /* we can't have exhaust queries with sharded clusters */
   if ((flags & MONGOC_QUERY_EXHAUST) &&
       (client->cluster.mode == MONGOC_CLUSTER_SHARDED_CLUSTER)) {
      bson_set_error (&cursor->error,
                      MONGOC_ERROR_CURSOR,
                      MONGOC_ERROR_CURSOR_INVALID_CURSOR,
                      "Cannot specify MONGOC_QUERY_EXHAUST with sharded cluster.");
      MARK_FAILED (cursor);
      GOTO (finish);
   }

   /*
    * Check types of various optional parameters.
    */
   if (!is_command) {
      if (bson_iter_init_find (&iter, query, "$explain") &&
          !(BSON_ITER_HOLDS_BOOL (&iter) || BSON_ITER_HOLDS_INT32 (&iter))) {
         bson_set_error (&cursor->error,
                         MONGOC_ERROR_CURSOR,
                         MONGOC_ERROR_CURSOR_INVALID_CURSOR,
                         "$explain must be a boolean.");
         MARK_FAILED (cursor);
         GOTO (finish);
      }

      if (bson_iter_init_find (&iter, query, "$snapshot") &&
          !BSON_ITER_HOLDS_BOOL (&iter) &&
          !BSON_ITER_HOLDS_INT32 (&iter)) {
         bson_set_error (&cursor->error,
                         MONGOC_ERROR_CURSOR,
                         MONGOC_ERROR_CURSOR_INVALID_CURSOR,
                         "$snapshot must be a boolean.");
         MARK_FAILED (cursor);
         GOTO (finish);
      }
   }

   if (!cursor->is_command && !bson_has_field (query, "$query")) {
      bson_init (&cursor->query);
      bson_append_document (&cursor->query, "$query", 6, query);
   } else {
      bson_copy_to (query, &cursor->query);
   }

   if (read_prefs) {
      cursor->read_prefs = mongoc_read_prefs_copy (read_prefs);

      mode = mongoc_read_prefs_get_mode (read_prefs);
      tags = mongoc_read_prefs_get_tags (read_prefs);

      if (mode != MONGOC_READ_PRIMARY) {
         flags |= MONGOC_QUERY_SLAVE_OK;

         if ((mode != MONGOC_READ_SECONDARY_PREFERRED) || tags) {
            bson_append_document_begin (&cursor->query, "$readPreference",
                                        15, &child);
            mode_str = _mongoc_cursor_get_read_mode_string (mode);
            bson_append_utf8 (&child, "mode", 4, mode_str, -1);
            if (tags) {
               bson_append_array (&child, "tags", 4, tags);
            }
            bson_append_document_end (&cursor->query, &child);
         }
      }
   }

   if (fields) {
      bson_copy_to(fields, &cursor->fields);
   } else {
      bson_init(&cursor->fields);
   }

   _mongoc_buffer_init(&cursor->buffer, NULL, 0, NULL);

finish:
   mongoc_counter_cursors_active_inc();

   if (local_read_prefs) {
      mongoc_read_prefs_destroy (local_read_prefs);
   }

   RETURN (cursor);
}