Example #1
0
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);
}