// static
long long DeleteStage::getNumDeleted(const PlanExecutor& exec) {
    invariant(exec.getRootStage()->isEOF());
    invariant(exec.getRootStage()->stageType() == STAGE_DELETE);
    DeleteStage* deleteStage = static_cast<DeleteStage*>(exec.getRootStage());
    const DeleteStats* deleteStats =
        static_cast<const DeleteStats*>(deleteStage->getSpecificStats());
    return deleteStats->docsDeleted;
}
Example #2
0
long long DeleteExecutor::execute(Database* db) {
    uassertStatusOK(prepare());

    // If we've already done the in-lock preparation, this is a no-op.
    uassertStatusOK(prepareInLock(db));
    invariant(_exec.get());

    uassertStatusOK(_exec->executePlan());

    // Extract the number of documents deleted from the DeleteStage stats.
    invariant(_exec->getRootStage()->stageType() == STAGE_DELETE);
    DeleteStage* deleteStage = static_cast<DeleteStage*>(_exec->getRootStage());
    const DeleteStats* deleteStats =
        static_cast<const DeleteStats*>(deleteStage->getSpecificStats());
    return deleteStats->docsDeleted;
}
    long long DeleteExecutor::execute(Database* db) {
        uassertStatusOK(prepare());
        uassert(17417,
                mongoutils::str::stream() <<
                "DeleteExecutor::prepare() failed to parse query " << _request->getQuery(),
                _isQueryParsed);

        const NamespaceString& ns(_request->getNamespaceString());
        if (!_request->isGod()) {
            if (ns.isSystem()) {
                uassert(12050,
                        "cannot delete from system namespace",
                        legalClientSystemNS(ns.ns(), true));
            }
            if (ns.ns().find('$') != string::npos) {
                log() << "cannot delete from collection with reserved $ in name: " << ns << endl;
                uasserted(10100, "cannot delete from collection with reserved $ in name");
            }
        }

        Collection* collection = db->getCollection(_request->getOpCtx(), ns.ns());
        if (NULL == collection) {
            return 0;
        }

        uassert(10101,
                str::stream() << "cannot remove from a capped collection: " << ns.ns(),
                !collection->isCapped());

        uassert(ErrorCodes::NotMaster,
                str::stream() << "Not primary while removing from " << ns.ns(),
                !_request->shouldCallLogOp() ||
                repl::getGlobalReplicationCoordinator()->canAcceptWritesForDatabase(ns.db()));

        PlanExecutor* rawExec;
        if (_canonicalQuery.get()) {
            // This is the non-idhack branch.
            uassertStatusOK(getExecutorDelete(_request->getOpCtx(), collection,
                                              _canonicalQuery.release(), _request->isMulti(),
                                              _request->shouldCallLogOp(), &rawExec));
        }
        else {
            // This is the idhack branch.
            uassertStatusOK(getExecutorDelete(_request->getOpCtx(), collection, ns.ns(),
                                              _request->getQuery(), _request->isMulti(),
                                              _request->shouldCallLogOp(), &rawExec));
        }
        scoped_ptr<PlanExecutor> exec(rawExec);

        // Concurrently mutating state (by us) so we need to register 'exec'.
        const ScopedExecutorRegistration safety(exec.get());

        uassertStatusOK(exec->executePlan());

        // Extract the number of documents deleted from the DeleteStage stats.
        invariant(exec->getRootStage()->stageType() == STAGE_DELETE);
        DeleteStage* deleteStage = static_cast<DeleteStage*>(exec->getRootStage());
        const DeleteStats* deleteStats =
            static_cast<const DeleteStats*>(deleteStage->getSpecificStats());
        return deleteStats->docsDeleted;
    }