Beispiel #1
0
std::unique_ptr<LiteParsedDocumentSourceForeignCollections> DocumentSourceOut::liteParse(
    const AggregationRequest& request, const BSONElement& spec) {
    uassert(ErrorCodes::TypeMismatch,
            str::stream() << "$out stage requires a string argument, but found "
                          << typeName(spec.type()),
            spec.type() == BSONType::String);

    NamespaceString targetNss(request.getNamespaceString().db(), spec.valueStringData());
    uassert(ErrorCodes::InvalidNamespace,
            str::stream() << "Invalid $out target namespace, " << targetNss.ns(),
            targetNss.isValid());

    ActionSet actions{ActionType::remove, ActionType::insert};
    if (request.shouldBypassDocumentValidation()) {
        actions.addAction(ActionType::bypassDocumentValidation);
    }

    PrivilegeVector privileges{Privilege(ResourcePattern::forExactNamespace(targetNss), actions)};

    return stdx::make_unique<LiteParsedDocumentSourceForeignCollections>(std::move(targetNss),
                                                                         std::move(privileges));
}
Beispiel #2
0
Status renameCollectionForApplyOps(OperationContext* opCtx,
                                   const std::string& dbName,
                                   const BSONElement& ui,
                                   const BSONObj& cmd) {

    const auto sourceNsElt = cmd.firstElement();
    const auto targetNsElt = cmd["to"];
    const auto dropSourceElt = cmd["dropSource"];
    uassert(ErrorCodes::TypeMismatch,
            "'renameCollection' must be of type String",
            sourceNsElt.type() == BSONType::String);
    uassert(ErrorCodes::TypeMismatch,
            "'to' must be of type String",
            targetNsElt.type() == BSONType::String);

    NamespaceString sourceNss(sourceNsElt.valueStringData());
    NamespaceString targetNss(targetNsElt.valueStringData());
    NamespaceString uiNss(getNamespaceFromUUID(opCtx, ui));
    NamespaceString dropSourceNss(getNamespaceFromUUID(opCtx, dropSourceElt));

    // If the UUID we're targeting already exists, rename from there no matter what.
    // When dropSource is specified, the rename is accross databases. In that case, ui indicates
    // the UUID of the new target collection and the dropSourceNss specifies the sourceNss.
    if (!uiNss.isEmpty()) {
        sourceNss = uiNss;
        // The cross-database rename was already done and just needs a local rename, but we may
        // still need to actually remove the source collection.
        auto dropSourceNss = getNamespaceFromUUID(opCtx, dropSourceElt);
        if (!dropSourceNss.isEmpty()) {
            BSONObjBuilder unusedBuilder;
            dropCollection(opCtx,
                           dropSourceNss,
                           unusedBuilder,
                           repl::OpTime(),
                           DropCollectionSystemCollectionMode::kAllowSystemCollectionDrops)
                .ignore();
        }
    } else if (!dropSourceNss.isEmpty()) {
        sourceNss = dropSourceNss;
    } else {
        // When replaying cross-database renames, both source and target collections may no longer
        // exist. Attempting a rename anyway could result in removing a newer collection of the
        // same name.
        uassert(ErrorCodes::NamespaceNotFound,
                str::stream() << "source collection (UUID "
                              << uassertStatusOK(UUID::parse(dropSourceElt))
                              << ") for rename to "
                              << targetNss.ns()
                              << " no longer exists",
                !dropSourceElt);
    }

    OptionalCollectionUUID targetUUID;
    if (!ui.eoo())
        targetUUID = uassertStatusOK(UUID::parse(ui));

    return renameCollectionCommon(opCtx,
                                  sourceNss,
                                  targetNss,
                                  targetUUID,
                                  cmd["dropTarget"].trueValue(),
                                  cmd["stayTemp"].trueValue());
}