bool RestEdgesHandler::getEdgesForVertex (std::string const& id, std::vector<traverser::TraverserExpression*> const& expressions, TRI_edge_direction_e direction, SingleCollectionReadOnlyTransaction& trx, triagens::basics::Json& result, size_t& scannedIndex, size_t& filtered) { triagens::arango::traverser::VertexId start; try { start = triagens::arango::traverser::IdStringToVertexId ( trx.resolver(), id ); } catch (triagens::basics::Exception& e) { handleError(e); return false; } TRI_document_collection_t* docCol = trx.trxCollection()->_collection->_collection; std::vector<TRI_doc_mptr_copy_t>&& edges = TRI_LookupEdgesDocumentCollection( docCol, direction, start.cid, const_cast<char*>(start.key) ); // generate result result.reserve(edges.size()); scannedIndex += edges.size(); if (expressions.empty()) { for (auto& e : edges) { DocumentAccessor da(trx.resolver(), docCol, &e); result.add(da.toJson()); } } else { for (auto& e : edges) { bool add = true; // Expressions symbolize an and, so all have to be matched for (auto& exp : expressions) { if (exp->isEdgeAccess && ! exp->matchesCheck(e, docCol, trx.resolver())) { ++filtered; add = false; break; } } if (add) { DocumentAccessor da(trx.resolver(), docCol, &e); result.add(da.toJson()); } } } return true; }
void RestVocbaseBaseHandler::generateDocument (SingleCollectionReadOnlyTransaction<RestTransactionContext>& trx, TRI_voc_cid_t cid, TRI_doc_mptr_copy_t const& mptr, TRI_shaper_t* shaper, bool generateBody) { CollectionNameResolver const* resolver = trx.resolver(); char const* key = TRI_EXTRACT_MARKER_KEY(&mptr); // PROTECTED by trx from above string const&& id = DocumentHelper::assembleDocumentId(resolver->getCollectionName(cid), key); TRI_json_t augmented; TRI_InitArray2Json(TRI_UNKNOWN_MEM_ZONE, &augmented, 5); TRI_json_t* idJson = TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, id.c_str(), id.size()); if (idJson != nullptr) { TRI_Insert2ArrayJson(TRI_UNKNOWN_MEM_ZONE, &augmented, "_id", idJson); } // convert rid from uint64_t to string string const&& rid = StringUtils::itoa(mptr._rid); TRI_json_t* rev = TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, rid.c_str(), rid.size()); if (rev != nullptr) { TRI_Insert2ArrayJson(TRI_UNKNOWN_MEM_ZONE, &augmented, TRI_VOC_ATTRIBUTE_REV, rev); } TRI_json_t* keyJson = TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, key, strlen(key)); if (keyJson) { TRI_Insert2ArrayJson(TRI_UNKNOWN_MEM_ZONE, &augmented, TRI_VOC_ATTRIBUTE_KEY, keyJson); } TRI_df_marker_type_t type = static_cast<TRI_df_marker_t const*>(mptr.getDataPtr())->_type; // PROTECTED by trx passed from above if (type == TRI_DOC_MARKER_KEY_EDGE) { TRI_doc_edge_key_marker_t const* marker = static_cast<TRI_doc_edge_key_marker_t const*>(mptr.getDataPtr()); // PROTECTED by trx passed from above string const&& from = DocumentHelper::assembleDocumentId(resolver->getCollectionNameCluster(marker->_fromCid), string((char*) marker + marker->_offsetFromKey)); string const&& to = DocumentHelper::assembleDocumentId(resolver->getCollectionNameCluster(marker->_toCid), string((char*) marker + marker->_offsetToKey)); TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, &augmented, TRI_VOC_ATTRIBUTE_FROM, TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, from.c_str(), from.size())); TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, &augmented, TRI_VOC_ATTRIBUTE_TO, TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, to.c_str(), to.size())); } else if (type == TRI_WAL_MARKER_EDGE) { triagens::wal::edge_marker_t const* marker = static_cast<triagens::wal::edge_marker_t const*>(mptr.getDataPtr()); // PROTECTED by trx passed from above string const&& from = DocumentHelper::assembleDocumentId(resolver->getCollectionNameCluster(marker->_fromCid), string((char*) marker + marker->_offsetFromKey)); string const&& to = DocumentHelper::assembleDocumentId(resolver->getCollectionNameCluster(marker->_toCid), string((char*) marker + marker->_offsetToKey)); TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, &augmented, TRI_VOC_ATTRIBUTE_FROM, TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, from.c_str(), from.size())); TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, &augmented, TRI_VOC_ATTRIBUTE_TO, TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, to.c_str(), to.size())); } // add document identifier to buffer TRI_string_buffer_t buffer; // convert object to string TRI_InitStringBuffer(&buffer, TRI_UNKNOWN_MEM_ZONE); TRI_shaped_json_t shapedJson; TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, mptr.getDataPtr()); // PROTECTED by trx passed from above TRI_StringifyAugmentedShapedJson(shaper, &buffer, &shapedJson, &augmented); TRI_DestroyJson(TRI_UNKNOWN_MEM_ZONE, &augmented); if (idJson) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, idJson); } if (rev) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, rev); } if (keyJson) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, keyJson); } // and generate a response _response = createResponse(HttpResponse::OK); _response->setContentType("application/json; charset=utf-8"); _response->setHeader("etag", 4, "\"" + rid + "\""); if (generateBody) { _response->body().appendText(TRI_BeginStringBuffer(&buffer), TRI_LengthStringBuffer(&buffer)); } else { _response->headResponse(TRI_LengthStringBuffer(&buffer)); } TRI_DestroyStringBuffer(&buffer); }