static void test_bson_append_iter (void) { bson_iter_t iter; bson_bool_t r; bson_t b; bson_t c; bson_init(&b); bson_append_int32(&b, "a", 1, 1); bson_append_int32(&b, "b", 1, 2); bson_append_int32(&b, "c", 1, 3); bson_append_utf8(&b, "d", 1, "hello", 5); bson_init(&c); r = bson_iter_init_find(&iter, &b, "a"); assert(r); r = bson_append_iter(&c, NULL, 0, &iter); assert(r); r = bson_iter_init_find(&iter, &b, "c"); assert(r); r = bson_append_iter(&c, NULL, 0, &iter); assert(r); r = bson_iter_init_find(&iter, &b, "d"); assert(r); r = bson_append_iter(&c, "world", -1, &iter); assert(r); bson_iter_init(&iter, &c); r = bson_iter_next(&iter); assert(r); assert_cmpstr("a", bson_iter_key(&iter)); assert_cmpint(BSON_TYPE_INT32, ==, bson_iter_type(&iter)); assert_cmpint(1, ==, bson_iter_int32(&iter)); r = bson_iter_next(&iter); assert(r); assert_cmpstr("c", bson_iter_key(&iter)); assert_cmpint(BSON_TYPE_INT32, ==, bson_iter_type(&iter)); assert_cmpint(3, ==, bson_iter_int32(&iter)); r = bson_iter_next(&iter); assert(r); assert_cmpint(BSON_TYPE_UTF8, ==, bson_iter_type(&iter)); assert_cmpstr("world", bson_iter_key(&iter)); assert_cmpstr("hello", bson_iter_utf8(&iter, NULL)); bson_destroy(&b); bson_destroy(&c); }
void core::concatenate(const bsoncxx::document::view& view) { bson_t other; bson_init_static(&other, view.data(), view.length()); if (_impl->is_array()) { bson_iter_t iter; bson_iter_init(&iter, &other); while (bson_iter_next(&iter)) { stdx::string_view key = _impl->next_key(); bson_append_iter(_impl->back(), key.data(), key.length(), &iter); } } else { bson_concat(_impl->back(), &other); } }
mongoc_collection_t * mongoc_database_create_collection (mongoc_database_t *database, const char *name, const bson_t *options, bson_error_t *error) { mongoc_collection_t *collection = NULL; bson_iter_t iter; bson_t cmd; bool capped = false; bson_return_val_if_fail (database, NULL); bson_return_val_if_fail (name, NULL); if (strchr (name, '$')) { bson_set_error (error, MONGOC_ERROR_NAMESPACE, MONGOC_ERROR_NAMESPACE_INVALID, "The namespace \"%s\" is invalid.", name); return NULL; } if (options) { if (bson_iter_init_find (&iter, options, "capped")) { if (!BSON_ITER_HOLDS_BOOL (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"capped\" must be a boolean."); return NULL; } capped = bson_iter_bool (&iter); } if (bson_iter_init_find (&iter, options, "autoIndexId") && !BSON_ITER_HOLDS_BOOL (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"autoIndexId\" must be a boolean."); return NULL; } if (bson_iter_init_find (&iter, options, "size")) { if (!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"size\" must be an integer."); return NULL; } if (!capped) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"size\" parameter requires {\"capped\": true}"); return NULL; } } if (bson_iter_init_find (&iter, options, "max")) { if (!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"max\" must be an integer."); return NULL; } if (!capped) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"size\" parameter requires {\"capped\": true}"); return NULL; } } if (bson_iter_init_find (&iter, options, "storage")) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"storage\" parameter must be a document"); return NULL; } if (bson_iter_find (&iter, "wiredtiger")) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"wiredtiger\" option must take a document argument with a \"configString\" field"); return NULL; } if (bson_iter_find (&iter, "configString")) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"configString\" parameter must be a string"); return NULL; } } else { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"wiredtiger\" option must take a document argument with a \"configString\" field"); return NULL; } } } } bson_init (&cmd); BSON_APPEND_UTF8 (&cmd, "create", name); if (options) { if (!bson_iter_init (&iter, options)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"options\" is corrupt or invalid."); bson_destroy (&cmd); return NULL; } while (bson_iter_next (&iter)) { if (!bson_append_iter (&cmd, bson_iter_key (&iter), -1, &iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Failed to append \"options\" to create command."); bson_destroy (&cmd); return NULL; } } } if (mongoc_database_command_simple (database, &cmd, NULL, NULL, error)) { collection = _mongoc_collection_new (database->client, database->name, name, database->read_prefs, database->write_concern); } bson_destroy (&cmd); return collection; }
static void _mongoc_write_command_update_legacy (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, const mongoc_write_concern_t *write_concern, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error) { mongoc_rpc_t rpc; bson_iter_t iter, subiter, subsubiter; bson_t doc; bool has_update, has_selector, is_upsert; bson_t update, selector; bson_t *gle = NULL; const uint8_t *data = NULL; uint32_t len = 0; size_t err_offset; bool val = false; char ns [MONGOC_NAMESPACE_MAX + 1]; int32_t affected = 0; int vflags = (BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | BSON_VALIDATE_DOLLAR_KEYS | BSON_VALIDATE_DOT_KEYS); ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); bson_iter_init (&iter, command->documents); while (bson_iter_next (&iter)) { if (bson_iter_recurse (&iter, &subiter) && bson_iter_find (&subiter, "u") && BSON_ITER_HOLDS_DOCUMENT (&subiter)) { bson_iter_document (&subiter, &len, &data); bson_init_static (&doc, data, len); if (bson_iter_init (&subsubiter, &doc) && bson_iter_next (&subsubiter) && (bson_iter_key (&subsubiter) [0] != '$') && !bson_validate (&doc, (bson_validate_flags_t)vflags, &err_offset)) { result->failed = true; bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "update document is corrupt or contains " "invalid keys including $ or ."); EXIT; } } else { result->failed = true; bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "updates is malformed."); EXIT; } } bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); bson_iter_init (&iter, command->documents); while (bson_iter_next (&iter)) { rpc.update.msg_len = 0; rpc.update.request_id = 0; rpc.update.response_to = 0; rpc.update.opcode = MONGOC_OPCODE_UPDATE; rpc.update.zero = 0; rpc.update.collection = ns; rpc.update.flags = MONGOC_UPDATE_NONE; has_update = false; has_selector = false; is_upsert = false; bson_iter_recurse (&iter, &subiter); while (bson_iter_next (&subiter)) { if (strcmp (bson_iter_key (&subiter), "u") == 0) { bson_iter_document (&subiter, &len, &data); rpc.update.update = data; bson_init_static (&update, data, len); has_update = true; } else if (strcmp (bson_iter_key (&subiter), "q") == 0) { bson_iter_document (&subiter, &len, &data); rpc.update.selector = data; bson_init_static (&selector, data, len); has_selector = true; } else if (strcmp (bson_iter_key (&subiter), "multi") == 0) { val = bson_iter_bool (&subiter); if (val) { rpc.update.flags = (mongoc_update_flags_t)( rpc.update.flags | MONGOC_UPDATE_MULTI_UPDATE); } } else if (strcmp (bson_iter_key (&subiter), "upsert") == 0) { val = bson_iter_bool (&subiter); if (val) { rpc.update.flags = (mongoc_update_flags_t)( rpc.update.flags | MONGOC_UPDATE_UPSERT); } is_upsert = true; } } if (!mongoc_cluster_sendv_to_server (&client->cluster, &rpc, 1, server_stream, write_concern, error)) { result->failed = true; EXIT; } if (_mongoc_write_concern_needs_gle (write_concern)) { if (!_mongoc_client_recv_gle (client, server_stream, &gle, error)) { result->failed = true; EXIT; } if (bson_iter_init_find (&subiter, gle, "n") && BSON_ITER_HOLDS_INT32 (&subiter)) { affected = bson_iter_int32 (&subiter); } /* * CDRIVER-372: * * Versions of MongoDB before 2.6 don't return the _id for an * upsert if _id is not an ObjectId. */ if (is_upsert && affected && !bson_iter_init_find (&subiter, gle, "upserted") && bson_iter_init_find (&subiter, gle, "updatedExisting") && BSON_ITER_HOLDS_BOOL (&subiter) && !bson_iter_bool (&subiter)) { if (has_update && bson_iter_init_find (&subiter, &update, "_id")) { _ignore_value (bson_append_iter (gle, "upserted", 8, &subiter)); } else if (has_selector && bson_iter_init_find (&subiter, &selector, "_id")) { _ignore_value (bson_append_iter (gle, "upserted", 8, &subiter)); } } _mongoc_write_result_merge_legacy ( result, command, gle, MONGOC_ERROR_COLLECTION_UPDATE_FAILED, offset); offset++; bson_destroy (gle); } } EXIT; }
void _mongoc_matcher_op_to_bson (mongoc_matcher_op_t *op, /* IN */ bson_t *bson) /* IN */ { const char *str; bson_t child; bson_t child2; BSON_ASSERT (op); BSON_ASSERT (bson); switch (op->base.opcode) { case MONGOC_MATCHER_OPCODE_EQ: bson_append_iter (bson, op->compare.path, -1, &op->compare.iter); break; case MONGOC_MATCHER_OPCODE_GT: case MONGOC_MATCHER_OPCODE_GTE: case MONGOC_MATCHER_OPCODE_IN: case MONGOC_MATCHER_OPCODE_LT: case MONGOC_MATCHER_OPCODE_LTE: case MONGOC_MATCHER_OPCODE_NE: case MONGOC_MATCHER_OPCODE_NIN: switch ((int)op->base.opcode) { case MONGOC_MATCHER_OPCODE_GT: str = "$gt"; break; case MONGOC_MATCHER_OPCODE_GTE: str = "$gte"; break; case MONGOC_MATCHER_OPCODE_IN: str = "$in"; break; case MONGOC_MATCHER_OPCODE_LT: str = "$lt"; break; case MONGOC_MATCHER_OPCODE_LTE: str = "$lte"; break; case MONGOC_MATCHER_OPCODE_NE: str = "$ne"; break; case MONGOC_MATCHER_OPCODE_NIN: str = "$nin"; break; default: str = "???"; break; } bson_append_document_begin (bson, op->compare.path, -1, &child); bson_append_iter (&child, str, -1, &op->compare.iter); bson_append_document_end (bson, &child); break; case MONGOC_MATCHER_OPCODE_OR: case MONGOC_MATCHER_OPCODE_AND: case MONGOC_MATCHER_OPCODE_NOR: if (op->base.opcode == MONGOC_MATCHER_OPCODE_OR) { str = "$or"; } else if (op->base.opcode == MONGOC_MATCHER_OPCODE_AND) { str = "$and"; } else if (op->base.opcode == MONGOC_MATCHER_OPCODE_NOR) { str = "$nor"; } else { BSON_ASSERT (false); str = NULL; } bson_append_array_begin (bson, str, -1, &child); bson_append_document_begin (&child, "0", 1, &child2); _mongoc_matcher_op_to_bson (op->logical.left, &child2); bson_append_document_end (&child, &child2); if (op->logical.right) { bson_append_document_begin (&child, "1", 1, &child2); _mongoc_matcher_op_to_bson (op->logical.right, &child2); bson_append_document_end (&child, &child2); } bson_append_array_end (bson, &child); break; case MONGOC_MATCHER_OPCODE_NOT: bson_append_document_begin (bson, op->not.path, -1, &child); bson_append_document_begin (&child, "$not", 4, &child2); _mongoc_matcher_op_to_bson (op->not.child, &child2); bson_append_document_end (&child, &child2); bson_append_document_end (bson, &child); break; case MONGOC_MATCHER_OPCODE_EXISTS: BSON_APPEND_BOOL (bson, "$exists", op->exists.exists); break; case MONGOC_MATCHER_OPCODE_TYPE: BSON_APPEND_INT32 (bson, "$type", (int)op->type.type); break; default: BSON_ASSERT (false); break; } }