Exemple #1
0
static char* ExtractStringShapedJson (TRI_shaper_t* shaper,
                                      TRI_shaped_json_t const* document,
                                      char const* path) {
  TRI_json_t* json;
  TRI_shape_pid_t pid;
  TRI_shape_t const* shape;
  TRI_shaped_json_t shaped;
  bool ok;
  char* result;

  pid = shaper->findAttributePathByName(shaper, path);

  ok = TRI_ExtractShapedJsonVocShaper(shaper, document, 0, pid, &shaped, &shape);

  if (! ok || shape == NULL) {
    return NULL;
  }

  json = TRI_JsonShapedJson(shaper, &shaped);

  if (json == NULL) {
    return NULL;
  }

  if (json->_type != TRI_JSON_STRING) {
    return NULL;
  }

  result = TRI_DuplicateString2(json->_value._string.data, json->_value._string.length);

  TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);

  return result;
}
triagens::basics::Json DocumentAccessor::toJson () {
  if (_current == nullptr) {
    // we're still pointing to the original document
    auto shaper = _document->getShaper();

    // fetch document from mptr
    TRI_shaped_json_t shaped;
    TRI_EXTRACT_SHAPED_JSON_MARKER(shaped, _mptr->getDataPtr());
    triagens::basics::Json json(shaper->memoryZone(), TRI_JsonShapedJson(shaper, &shaped));

    // add internal attributes

    // _id, _key, _rev
    char const* key = TRI_EXTRACT_MARKER_KEY(_mptr);
    std::string id(_resolver->getCollectionName(_document->_info._cid));
    id.push_back('/');
    id.append(key);
    json(TRI_VOC_ATTRIBUTE_ID, triagens::basics::Json(id));
    json(TRI_VOC_ATTRIBUTE_REV, triagens::basics::Json(std::to_string(TRI_EXTRACT_MARKER_RID(_mptr))));
    json(TRI_VOC_ATTRIBUTE_KEY, triagens::basics::Json(key));
      
    if (TRI_IS_EDGE_MARKER(_mptr)) {
      // _from
      std::string from(_resolver->getCollectionNameCluster(TRI_EXTRACT_MARKER_FROM_CID(_mptr)));
      from.push_back('/');
      from.append(TRI_EXTRACT_MARKER_FROM_KEY(_mptr));
      json(TRI_VOC_ATTRIBUTE_FROM, triagens::basics::Json(from));
        
      // _to
      std::string to(_resolver->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(_mptr)));
      to.push_back('/');
      to.append(TRI_EXTRACT_MARKER_TO_KEY(_mptr));
      json(TRI_VOC_ATTRIBUTE_TO, triagens::basics::Json(to));
    }

    return json;
  }

  if (_current == _json.get()) {
    // _current points at the JSON that we own

    // steal the JSON
    TRI_json_t* value = _json.release();
    setToNull();
    return triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, value);
  }

  TRI_json_t* copy = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, _current);

  if (copy != nullptr) {
    _json.release();
    return triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, copy);
  }
  // fall-through intentional

  return triagens::basics::Json(triagens::basics::Json::Null);
}
Exemple #3
0
static bool ExtractBooleanShapedJson (TRI_shaper_t* shaper,
                                      TRI_shaped_json_t const* document,
                                      char const* path,
                                      bool* found) {
  TRI_json_t* json;
  TRI_shape_pid_t pid;
  TRI_shape_t const* shape;
  TRI_shaped_json_t shaped;
  bool result;
  bool ok;

  if (found != NULL) {
    *found = false;
  }

  pid = shaper->findAttributePathByName(shaper, path);
  ok = TRI_ExtractShapedJsonVocShaper(shaper, document, 0, pid, &shaped, &shape);

  if (! ok || shape == NULL) {
    return false;
  }

  json = TRI_JsonShapedJson(shaper, &shaped);

  if (json == NULL) {
    return false;
  }

  if (json->_type != TRI_JSON_BOOLEAN) {
    return false;
  }

  if (found != NULL) {
    *found = true;
  }

  result = json->_value._boolean;

  TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);

  return result;
}
void DocumentAccessor::lookupDocumentAttribute (char const* name, size_t nameLength) {
  if (*name == '_' && name[1] != '\0') {
    if (name[1] == 'k' && nameLength == 4 && memcmp(name, TRI_VOC_ATTRIBUTE_KEY, nameLength) == 0) {
      // _key value is copied into JSON
      char const* key = TRI_EXTRACT_MARKER_KEY(_mptr);
      if (key == nullptr) {
        setToNull();
        return;
      }
      _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, key, strlen(key)));

      if (_json.get() == nullptr) {
        THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
      }

      _current = _json.get();
      return;
    }

    if (name[1] == 'i' && nameLength == 3 && memcmp(name, TRI_VOC_ATTRIBUTE_ID, nameLength) == 0) {
      // _id
      char buffer[512]; // big enough for max key length + max collection name length
      size_t pos = _resolver->getCollectionName(&buffer[0], _document->_info._cid);
      buffer[pos++] = '/';
      char const* key = TRI_EXTRACT_MARKER_KEY(_mptr);
      if (key == nullptr) {
        setToNull();
        return;
      }
      size_t len = strlen(key);
      memcpy(&buffer[pos], key, len);
      buffer[pos + len] = '\0';
      _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len));
      if (_json.get() == nullptr) {
        THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
      }
      _current = _json.get();
      return;
    }

    if (name[1] == 'r' && nameLength == 4 && memcmp(name, TRI_VOC_ATTRIBUTE_REV, nameLength) == 0) {
      // _rev
      char buffer[21];
      TRI_voc_rid_t rid = TRI_EXTRACT_MARKER_RID(_mptr);
      size_t len = TRI_StringUInt64InPlace(rid, &buffer[0]);
      _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], len));
      if (_json.get() == nullptr) {
        THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
      }
      _current = _json.get();
      return;
    }

    if (TRI_IS_EDGE_MARKER(_mptr)) {
      if (name[1] == 'f' && nameLength == 5 && memcmp(name, TRI_VOC_ATTRIBUTE_FROM, nameLength) == 0) {
        // _from
        char buffer[512]; // big enough for max key length + max collection name length
        size_t pos = _resolver->getCollectionNameCluster(&buffer[0], TRI_EXTRACT_MARKER_FROM_CID(_mptr));
        buffer[pos++] = '/';
        char const* key = TRI_EXTRACT_MARKER_FROM_KEY(_mptr);
        if (key == nullptr) {
          setToNull();
          return;
        }
        size_t len = strlen(key);
        memcpy(&buffer[pos], key, len);
        buffer[pos + len] = '\0';
        _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len));
        if (_json.get() == nullptr) {
          THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
        }
        _current = _json.get();
        return;
      }

      if (name[1] == 't' && nameLength == 3 && memcmp(name, TRI_VOC_ATTRIBUTE_TO, nameLength) == 0) {
        // to
        char buffer[512]; // big enough for max key length + max collection name length
        size_t pos = _resolver->getCollectionNameCluster(&buffer[0], TRI_EXTRACT_MARKER_TO_CID(_mptr));
        buffer[pos++] = '/';
        char const* key = TRI_EXTRACT_MARKER_TO_KEY(_mptr);
        if (key == nullptr) {
          setToNull();
          return;
        }
        size_t len = strlen(key);
        memcpy(&buffer[pos], key, len);
        buffer[pos + len] = '\0';
        _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len));
        if (_json.get() == nullptr) {
          THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
        }
        _current = _json.get();
        return;
      }
    }

    // fall-through intentional
  }

  auto shaper = _document->getShaper();

  TRI_shape_pid_t pid = shaper->lookupAttributePathByName(name);

  if (pid == 0) {
    // attribute does not exist
    setToNull();
    return;
  }

  // attribute exists
  TRI_shaped_json_t document;
  TRI_EXTRACT_SHAPED_JSON_MARKER(document, _mptr->getDataPtr());

  TRI_shaped_json_t json;
  TRI_shape_t const* shape;

  bool ok = shaper->extractShapedJson(&document, 0, pid, &json, &shape);

  if (ok && shape != nullptr) {
    _json.reset(TRI_JsonShapedJson(shaper, &json));
    if (_json.get() == nullptr) {
      THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
    }
    _current = _json.get();
    return;
  }

  // not found
  setToNull();
}
Exemple #5
0
int BitarrayIndex_generateInsertBitMask (BitarrayIndex* baIndex,
        const TRI_bitarray_index_key_t* element,
        TRI_bitarray_mask_t* mask) {
    TRI_shaper_t* shaper;
    int j;
    int shiftLeft;
    int result;

    // ...........................................................................
    // some safety checks first
    // ...........................................................................

    if (baIndex == NULL || element == NULL) {
        return TRI_ERROR_INTERNAL;
    }

    if (element->collection == NULL) {
        return TRI_ERROR_INTERNAL;
    }

    // ...........................................................................
    // We could be trying to store an 'undefined' document into the bitarray
    // We determine this implicitly. If element->numFields b == 0, then we
    // assume that the document did not have any matching attributes, yet since
    // we are here we wish to store this fact.
    // ...........................................................................

    if (!baIndex->_supportUndef && (element->numFields == 0 || element->fields == NULL)) {
        return TRI_ERROR_INTERNAL;
    }


    if (baIndex->_supportUndef && element->numFields == 0) {
        mask->_mask       = 1;
        mask->_ignoreMask = 0;
        return TRI_ERROR_NO_ERROR;
    }


    // ...........................................................................
    // attempt to convert the stored TRI_shaped_json_t into TRI_Json_t so that
    // we can make a comparison between what values the bitarray index requires
    // and what values the document has sent.
    // ...........................................................................

    shaper      = ((TRI_primary_collection_t*)(element->collection))->_shaper;
    mask->_mask = 0;
    shiftLeft   = 0;

    for (j = 0; j < baIndex->_values._length; ++j) {
        TRI_json_t* valueList;
        TRI_json_t* value;
        uint64_t    tempMask;

        value      = TRI_JsonShapedJson(shaper, &(element->fields[j])); // from shaped json to simple json
        valueList  = (TRI_json_t*)(TRI_AtVector(&(baIndex->_values),j));
        tempMask   = 0;


        // .........................................................................
        // value is now the shaped json converted into plain json for comparison
        // ........................................................................

        result = BitarrayIndex_generateEqualBitMaskHelper(valueList, value, &tempMask);

        // ............................................................................
        // remove the json entry created from the shaped json
        // ............................................................................

        TRI_FreeJson(shaper->_memoryZone, value);

        if (result != TRI_ERROR_NO_ERROR) {
            return result;
        }

        mask->_mask = mask->_mask | (tempMask << shiftLeft);

        shiftLeft += valueList->_value._objects._length;
    }

    return TRI_ERROR_NO_ERROR;
}