NS_IMETHODIMP nsXPathResult::GetSnapshotLength(PRUint32 *aSnapshotLength) { if (!isSnapshot()) { return NS_ERROR_DOM_TYPE_ERR; } txNodeSet *nodeSet = NS_STATIC_CAST(txNodeSet*, mResult.get()); *aSnapshotLength = (PRUint32)nodeSet->size(); return NS_OK; }
nsresult nsXPathResult::SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType) { mResultType = aResultType; if ((isSnapshot() || isIterator() || isNode()) && aExprResult->getResultType() != txAExprResult::NODESET) { return NS_ERROR_DOM_TYPE_ERR; } if (mDocument) { mDocument->RemoveObserver(this); mDocument = nsnull; } mResult.set(aExprResult); if (!isIterator()) { return NS_OK; } mInvalidIteratorState = PR_FALSE; txNodeSet* nodeSet = NS_STATIC_CAST(txNodeSet*, aExprResult); nsCOMPtr<nsIDOMNode> node; if (nodeSet->size() > 0) { nsresult rv = txXPathNativeNode::getNode(nodeSet->get(0), getter_AddRefs(node)); NS_ENSURE_SUCCESS(rv, rv); // If we support the document() function in DOM-XPath we need to // observe all documents that we have resultnodes in. nsCOMPtr<nsIDOMDocument> document; node->GetOwnerDocument(getter_AddRefs(document)); if (document) { mDocument = do_QueryInterface(document); } else { mDocument = do_QueryInterface(node); } NS_ASSERTION(mDocument, "We need a document!"); if (mDocument) { mDocument->AddObserver(this); } } return NS_OK; }
NS_IMETHODIMP nsXPathResult::SnapshotItem(PRUint32 aIndex, nsIDOMNode **aResult) { if (!isSnapshot()) { return NS_ERROR_DOM_TYPE_ERR; } txNodeSet *nodeSet = NS_STATIC_CAST(txNodeSet*, mResult.get()); if (aIndex < (PRUint32)nodeSet->size()) { return txXPathNativeNode::getNode(nodeSet->get(aIndex), aResult); } *aResult = nsnull; return NS_OK; }
nsresult XPathResult::SetExprResult(txAExprResult* aExprResult, uint16_t aResultType, nsINode* aContextNode) { MOZ_ASSERT(aExprResult); if ((isSnapshot(aResultType) || isIterator(aResultType) || isNode(aResultType)) && aExprResult->getResultType() != txAExprResult::NODESET) { // The DOM spec doesn't really say what should happen when reusing an // XPathResult and an error is thrown. Let's not touch the XPathResult // in that case. return NS_ERROR_DOM_TYPE_ERR; } mResultType = aResultType; mContextNode = do_GetWeakReference(aContextNode); if (mDocument) { mDocument->RemoveMutationObserver(this); mDocument = nullptr; } mResultNodes.Clear(); // XXX This will keep the recycler alive, should we clear it? mResult = aExprResult; switch (mResultType) { case BOOLEAN_TYPE: { mBooleanResult = mResult->booleanValue(); break; } case NUMBER_TYPE: { mNumberResult = mResult->numberValue(); break; } case STRING_TYPE: { mResult->stringValue(mStringResult); break; } default: { MOZ_ASSERT(isNode() || isIterator() || isSnapshot()); } } if (aExprResult->getResultType() == txAExprResult::NODESET) { txNodeSet *nodeSet = static_cast<txNodeSet*>(aExprResult); int32_t i, count = nodeSet->size(); for (i = 0; i < count; ++i) { nsINode* node = txXPathNativeNode::getNode(nodeSet->get(i)); mResultNodes.AppendObject(node); } if (count > 0) { mResult = nullptr; } } if (!isIterator()) { return NS_OK; } mInvalidIteratorState = false; if (mResultNodes.Count() > 0) { // If we support the document() function in DOM-XPath we need to // observe all documents that we have resultnodes in. mDocument = mResultNodes[0]->OwnerDoc(); NS_ASSERTION(mDocument, "We need a document!"); if (mDocument) { mDocument->AddMutationObserver(this); } } return NS_OK; }
int main(int argc, char **argv) { struct options opt; // Note: in case we have string as member // bzero will corrupt the string object bzero((char*)&opt, sizeof(opt)); if (argc < 3) { cerr << "Usage : [--type] type [--create] [--delete] [-add] [--remove] [--print]" << endl; return -EINVAL; } if (parse(argc, argv, &opt) < 0) return -EINVAL; init_boost_logger(); BOOST_LOG_TRIVIAL(debug) << " --type " << opt.type << " --create " << opt.create << " --id " << opt.id << " --delete " << opt.clear << " --add " << opt.add << " --remove " << opt.erase << " --key " << opt.key << " --print " << opt.print << " --snapshot " << opt.snapshot; // Init Storage Media StorageResource sink(std::string(dbfile), dbsize); boost::shared_ptr<CoreIO> io = boost::shared_ptr<CoreIO>(new CoreIO(sink)); boost::shared_ptr<StorageAllocator> allocator = boost::shared_ptr<StorageAllocator>(new StorageAllocator(sink, 0, sink.size())); // Init Registry typedef Registry<CoreIO, StorageAllocator> GlobalReg; auto reg = boost::shared_ptr<GlobalReg>(new GlobalReg(MAX_READ, io, allocator)); size_t key, parent_key; if (opt.id) key = boost::hash_value(string(opt.id)); if (opt.parent) parent_key = boost::hash_value(string(opt.parent)); if (opt.snapshot && !isvalidkey(parent_key, reg)) { BOOST_LOG_TRIVIAL(error) << "Parent Entry not found! " << parent_key; return -ENOENT; } else if (!opt.snapshot && !opt.create && !isvalidkey(key, reg)) { BOOST_LOG_TRIVIAL(error) << "Entry not found! " << key; return -ENOENT; } auto type = opt.create ? opt.type : GetType(key, reg); bool snap = opt.create ? false : isSnapshot(key, reg); switch (type) { case db::registryrecord::LIST: { typedef PersistentLinkList<int, CoreIO, StorageAllocator> PMemLinkList; boost::shared_ptr<PMemLinkList> pList; if (opt.snapshot) reg->snapshot(key, parent_key); else pList = boost::shared_ptr<PMemLinkList> (new PMemLinkList(string(opt.id), reg, io, allocator)); if (opt.clear && pList && !snap) pList->clear(); if (opt.clear && snap) reg->remove(key); if (opt.add && pList && !snap) pList->push_back(opt.key); if (opt.erase && pList && !snap) pList->pop_back(); if (opt.print && pList) pList->print(); break; } default: BOOST_LOG_TRIVIAL(info) << "Unsupported!"; break; } return 0; }
StatusWith<Message> downconvertFindCommandRequest(const RemoteCommandRequest& request) { const auto& cmdObj = request.cmdObj; const NamespaceString nss(request.dbname, cmdObj.firstElement().String()); if (!nss.isValid()) { return {ErrorCodes::InvalidNamespace, str::stream() << "Invalid collection name: " << nss.ns()}; } const std::string& ns = nss.ns(); // It is a little heavy handed to use QueryRequest to convert the command object to // query() arguments but we get validation and consistent behavior with the find // command implementation on the remote server. auto qrStatus = QueryRequest::makeFromFindCommand(nss, cmdObj, false); if (!qrStatus.isOK()) { return qrStatus.getStatus(); } auto qr = std::move(qrStatus.getValue()); // We are downconverting a find command, and find command can only have ntoreturn // if it was generated by mongos. invariant(!qr->getNToReturn()); Query query(qr->getFilter()); if (!qr->getSort().isEmpty()) { query.sort(qr->getSort()); } if (!qr->getHint().isEmpty()) { query.hint(qr->getHint()); } if (!qr->getMin().isEmpty()) { query.minKey(qr->getMin()); } if (!qr->getMax().isEmpty()) { query.minKey(qr->getMax()); } if (qr->isExplain()) { query.explain(); } if (qr->isSnapshot()) { query.snapshot(); } const int nToReturn = qr->getLimit().value_or(0) * -1; const int nToSkip = qr->getSkip().value_or(0); const BSONObj* fieldsToReturn = &qr->getProj(); int queryOptions = qr->getOptions(); // non-const so we can set slaveOk if we need to const int batchSize = qr->getBatchSize().value_or(0); const int nextBatchSize = [batchSize, nToReturn]() { if (nToReturn == 0) return batchSize; if (batchSize == 0) return nToReturn; return batchSize < nToReturn ? batchSize : nToReturn; }(); // We can't downconvert all metadata, since we aren't sending a command, but we do need to // downconvert $secondaryOk to the slaveOK bit. auto ssm = rpc::ServerSelectionMetadata::readFromMetadata( request.metadata.getField(rpc::ServerSelectionMetadata::fieldName())); if (!ssm.isOK()) { return ssm.getStatus(); } if (ssm.getValue().isSecondaryOk()) { queryOptions |= mongo::QueryOption_SlaveOk; } Message message; assembleQueryRequest( ns, query.obj, nextBatchSize, nToSkip, fieldsToReturn, queryOptions, message); return {std::move(message)}; }