bsoncxx::stdx::optional<bsoncxx::document::value> collection::find_one_and_update(
    bsoncxx::document::view filter, bsoncxx::document::view update,
    const options::find_one_and_update& options) {
    scoped_bson_t bson_filter{filter};
    scoped_bson_t bson_update{update};
    scoped_bson_t bson_sort{options.sort()};
    scoped_bson_t bson_projection{options.projection()};

    scoped_bson_t reply;
    reply.flag_init();

    bson_error_t error;

    options::return_document rd =
        options.return_document().value_or(options::return_document::k_before);

    bool r = libmongoc::collection_find_and_modify(
        _impl->collection_t, bson_filter.bson(), bson_sort.bson(), bson_update.bson(),
        bson_projection.bson(), false, options.upsert().value_or(false),
        rd == options::return_document::k_after, reply.bson(), &error);

    if (!r) {
        throw std::runtime_error("baddd");
    }

    bsoncxx::document::view result = reply.view();

    if (result["value"].type() == bsoncxx::type::k_null)
        return bsoncxx::stdx::optional<bsoncxx::document::value>{};

    bsoncxx::builder::stream::document b;
    b << bsoncxx::builder::stream::concatenate{result["value"].get_document()};
    return b.extract();
}
stdx::optional<bsoncxx::document::value> collection::find_one_and_update(
    view_or_value filter, view_or_value update, const options::find_one_and_update& options) {
    auto opts = libmongoc::find_and_modify_opts_new();
    auto opts_cleanup = make_guard([&opts] { libmongoc::find_and_modify_opts_destroy(opts); });
    int flags = ::MONGOC_FIND_AND_MODIFY_NONE;
    scoped_bson_t bson_update{update};
    scoped_bson_t bson_sort{options.sort()};
    scoped_bson_t bson_projection{options.projection()};

    libmongoc::find_and_modify_opts_set_update(opts, bson_update.bson());

    if (options.bypass_document_validation()) {
        libmongoc::find_and_modify_opts_set_bypass_document_validation(
            opts, *options.bypass_document_validation());
    }

    if (options.sort()) {
        libmongoc::find_and_modify_opts_set_sort(opts, bson_sort.bson());
    }

    if (options.projection()) {
        libmongoc::find_and_modify_opts_set_fields(opts, bson_projection.bson());
    }

    if (options.upsert().value_or(false)) {
        flags |= ::MONGOC_FIND_AND_MODIFY_UPSERT;
    }

    if (options.return_document() == options::return_document::k_after) {
        flags |= ::MONGOC_FIND_AND_MODIFY_RETURN_NEW;
    }

    // TODO: use options.max_time() when available in the C driver

    libmongoc::find_and_modify_opts_set_flags(opts,
                                              static_cast<::mongoc_find_and_modify_flags_t>(flags));

    return find_and_modify(_get_impl().collection_t, filter, opts);
}
Beispiel #3
0
stdx::optional<bsoncxx::document::value> collection::find_one_and_update(
    view_or_value filter, view_or_value update, const options::find_one_and_update& options) {
    auto opts = libmongoc::find_and_modify_opts_new();
    auto opts_cleanup = make_guard([&opts] { libmongoc::find_and_modify_opts_destroy(opts); });
    int flags = ::MONGOC_FIND_AND_MODIFY_NONE;

    libmongoc::find_and_modify_opts_set_update(opts, scoped_bson_t{update}.bson());

    if (options.bypass_document_validation()) {
        libmongoc::find_and_modify_opts_set_bypass_document_validation(
            opts, *options.bypass_document_validation());
    }

    if (options.collation()) {
        scoped_bson_t bson_collation{make_document(kvp("collation", *options.collation()))};
        libmongoc::find_and_modify_opts_append(opts, bson_collation.bson());
    }

    if (options.sort()) {
        libmongoc::find_and_modify_opts_set_sort(opts, scoped_bson_t{*options.sort()}.bson());
    }

    if (options.projection()) {
        libmongoc::find_and_modify_opts_set_fields(opts,
                                                   scoped_bson_t{*options.projection()}.bson());
    }

    if (options.upsert().value_or(false)) {
        flags |= ::MONGOC_FIND_AND_MODIFY_UPSERT;
    }

    if (options.return_document() == options::return_document::k_after) {
        flags |= ::MONGOC_FIND_AND_MODIFY_RETURN_NEW;
    }

    if (options.max_time()) {
        libmongoc::find_and_modify_opts_set_max_time_ms(opts, options.max_time()->count());
    }

    libmongoc::find_and_modify_opts_set_flags(opts,
                                              static_cast<::mongoc_find_and_modify_flags_t>(flags));

    return find_and_modify(_get_impl().collection_t, filter, opts);
}
Beispiel #4
0
stdx::optional<bsoncxx::document::value> collection::find_one_and_update(
    view_or_value filter, view_or_value update, const options::find_one_and_update& options) {
    bsoncxx::builder::basic::document command_doc;
    bsoncxx::builder::basic::document options_doc;

    command_doc.append(
        kvp("findAndModify", libmongoc::collection_get_name(_get_impl().collection_t)));

    options_doc.append(kvp("query", filter));

    options_doc.append(kvp("update", update));

    if (options.sort()) {
        options_doc.append(kvp("sort", *options.sort()));
    }

    if (options.return_document() == options::return_document::k_after) {
        options_doc.append(kvp("new", true));
    }

    if (options.bypass_document_validation()) {
        options_doc.append(kvp("bypassDocumentValidation", *options.bypass_document_validation()));
    }

    if (options.collation()) {
        options_doc.append(kvp("collation", *options.collation()));
    }

    if (options.projection()) {
        options_doc.append(kvp("fields", *options.projection()));
    }

    if (options.upsert().value_or(false)) {
        options_doc.append(kvp("upsert", *options.upsert()));
    }

    if (options.max_time()) {
        options_doc.append(kvp("maxTimeMS", bsoncxx::types::b_int64{options.max_time()->count()}));
    }

    return find_and_modify(
        _get_impl().collection_t, command_doc.view(), options_doc.view(), options.write_concern());
}