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); }
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; }
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); }
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; }
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); }
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); }
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); }
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); }
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; } }
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; }
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; }
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; } }
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); }
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; }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }