Beispiel #1
0
static TRI_json_t* MergeRecursive (TRI_memory_zone_t* zone,
                                   const TRI_json_t* const lhs,
                                   const TRI_json_t* const rhs,
                                   const bool nullMeansRemove) {
  size_t i, n;

  TRI_json_t* result = TRI_CopyJson(zone, lhs);

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

  n = rhs->_value._objects._length;
  for (i = 0; i < n; i += 2) {
    // enumerate all the replacement values
    TRI_json_t* key = TRI_AtVector(&rhs->_value._objects, i);
    TRI_json_t* value = TRI_AtVector(&rhs->_value._objects, i + 1);

    if (value->_type == TRI_JSON_NULL && nullMeansRemove) {
      // replacement value is a null and we don't want to store nulls => delete attribute from the result
      TRI_DeleteArrayJson(zone, result, key->_value._string.data);
    }
    else {
      // replacement value is not a null or we want to store nulls
      TRI_json_t* lhsValue = TRI_LookupArrayJson(lhs, key->_value._string.data);

      if (lhsValue == NULL) {
        // existing array does not have the attribute => append new attribute
        if (value->_type == TRI_JSON_ARRAY) {
          TRI_json_t* empty = TRI_CreateArrayJson(zone);
          TRI_json_t* merged = MergeRecursive(zone, empty, value, nullMeansRemove);
          TRI_Insert3ArrayJson(zone, result, key->_value._string.data, merged);

          TRI_FreeJson(zone, empty);
        }
        else {
          TRI_Insert3ArrayJson(zone, result, key->_value._string.data, TRI_CopyJson(zone, value));
        }
      }
      else {
        // existing array already has the attribute => replace attribute
        if (lhsValue->_type == TRI_JSON_ARRAY && value->_type == TRI_JSON_ARRAY) {
          TRI_json_t* merged = MergeRecursive(zone, lhsValue, value, nullMeansRemove);
          TRI_ReplaceArrayJson(zone, result, key->_value._string.data, merged);
          TRI_FreeJson(zone, merged);
        }
        else {
          TRI_ReplaceArrayJson(zone, result, key->_value._string.data, value);
        }
      }
    }

  }

  return result;
}
static TRI_aql_bind_parameter_t* CreateParameter (const char* const name,
                                                  const size_t nameLength,
                                                  const TRI_json_t* const value) {
  TRI_aql_bind_parameter_t* parameter;

  assert(name);
  assert(value);

  parameter = (TRI_aql_bind_parameter_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_aql_bind_parameter_t), false);

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

  parameter->_name = TRI_DuplicateString2Z(TRI_UNKNOWN_MEM_ZONE, name, nameLength);

  if (parameter->_name == NULL) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, parameter);

    return NULL;
  }

  parameter->_value = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, (TRI_json_t*) value);

  if (parameter->_value == NULL) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, parameter->_name);
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, parameter);

    return NULL;
  }

  return parameter;
}
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);
}
Beispiel #4
0
int TRI_SaveCollectionInfo (char const* path, const TRI_col_info_t* const info) {
  TRI_json_t* json;
  char* filename;
  bool ok;

  filename = TRI_Concatenate2File(path, TRI_COL_PARAMETER_FILE);

  // create a json info object
  json = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);
  if (json == NULL) {
    // out of memory
    LOG_ERROR("cannot save info block '%s': out of memory", filename);

    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

    return TRI_ERROR_OUT_OF_MEMORY;
  }

  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "version",     TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, info->_version));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "type",        TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, info->_type));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "cid",         TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, info->_cid));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "deleted",     TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, info->_deleted));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "maximalSize", TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, info->_maximalSize));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "name",        TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, info->_name));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "isVolatile",  TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, info->_isVolatile));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "waitForSync", TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, info->_waitForSync));

  if (info->_keyOptions) {
    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "keyOptions",     TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, info->_keyOptions));
  }

  // save json info to file
  ok = TRI_SaveJson(filename, json);
  TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);

  if (! ok) {
    LOG_ERROR("cannot save info block '%s': '%s'", filename, TRI_last_error());

    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
    return TRI_errno();
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  return TRI_ERROR_NO_ERROR;
}
Beispiel #5
0
void TRI_CopyCollectionInfo (TRI_col_info_t* dst, const TRI_col_info_t* const src) {
  assert(dst);
  memset(dst, 0, sizeof(TRI_col_info_t));

  dst->_version     = src->_version;
  dst->_type        = src->_type;
  dst->_cid         = src->_cid;
  dst->_rid         = src->_rid;

  dst->_deleted     = src->_deleted;
  dst->_isSystem    = src->_isSystem;
  dst->_isVolatile  = src->_isVolatile;
  dst->_maximalSize = src->_maximalSize;
  TRI_CopyString(dst->_name, src->_name, sizeof(dst->_name));
  dst->_waitForSync = src->_waitForSync;
  
  if (src->_keyOptions) {
    dst->_keyOptions  = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, src->_keyOptions);
  }
  else {
    dst->_keyOptions  = NULL;
  }
}
Beispiel #6
0
TRI_index_operator_t* TRI_CopyIndexOperator(TRI_index_operator_t* indexOperator) {

  TRI_index_operator_t*          newOperator;
  TRI_logical_index_operator_t*  newLogicalOperator;
  TRI_logical_index_operator_t*  oldLogicalOperator;
  TRI_relation_index_operator_t* newRelationOperator;
  TRI_relation_index_operator_t* oldRelationOperator;
  
  newOperator = NULL;
  
  if (indexOperator == NULL) {
    return NULL;
  }
  
  switch (indexOperator->_type) {
    case TRI_AND_INDEX_OPERATOR: 
    case TRI_NOT_INDEX_OPERATOR:
    case TRI_OR_INDEX_OPERATOR: {    
    
      oldLogicalOperator = (TRI_logical_index_operator_t*)(indexOperator);
      newLogicalOperator = (TRI_logical_index_operator_t*) (TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_logical_index_operator_t), false));
      
      if (newLogicalOperator == NULL) { // out of memory ?
        break;
      }
      
      newLogicalOperator->_base._type   = indexOperator->_type;
      newLogicalOperator->_base._shaper = indexOperator->_shaper;
      newLogicalOperator->_left         = TRI_CopyIndexOperator(oldLogicalOperator->_left);
      newLogicalOperator->_right        = TRI_CopyIndexOperator(oldLogicalOperator->_right);
      newOperator = &(newLogicalOperator->_base);      

      break;
      
    }
    
    case TRI_EQ_INDEX_OPERATOR: 
    case TRI_GE_INDEX_OPERATOR: 
    case TRI_GT_INDEX_OPERATOR: 
    case TRI_NE_INDEX_OPERATOR: 
    case TRI_LE_INDEX_OPERATOR: 
    case TRI_LT_INDEX_OPERATOR: 
    case TRI_IN_INDEX_OPERATOR: {
    
      oldRelationOperator = (TRI_relation_index_operator_t*)(indexOperator);
      newRelationOperator = (TRI_relation_index_operator_t*) (TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_relation_index_operator_t), false));
      
      if (newRelationOperator == NULL) { // out of memory?
        break;
      }
      
      newRelationOperator->_base._type   = indexOperator->_type;
      newRelationOperator->_base._shaper = indexOperator->_shaper;
      
      if (oldRelationOperator->_parameters != NULL) {
        newRelationOperator->_parameters = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, oldRelationOperator->_parameters);
      }
      else {
        newRelationOperator->_parameters = NULL;
      }
      
      if (oldRelationOperator->_fields != NULL) {
        newRelationOperator->_fields = TRI_CopyShapedJson(oldRelationOperator->_base._shaper, oldRelationOperator->_fields);
      }  
      else {
        newRelationOperator->_fields = NULL;
      }  
      
      newRelationOperator->_numFields    = oldRelationOperator->_numFields;
      newRelationOperator->_collection   = oldRelationOperator->_collection;

      newOperator = &(newRelationOperator->_base);      
      
      break;            
    }        
  }
  
  return newOperator;
}
Beispiel #7
0
int TRI_LoadCollectionInfo (char const* path, TRI_col_info_t* parameter) {
  TRI_json_t* json;
  char* filename;
  char* error = NULL;
  size_t i;
  size_t n;

  memset(parameter, 0, sizeof(TRI_col_info_t));

  // find parameter file
  filename = TRI_Concatenate2File(path, TRI_COL_PARAMETER_FILE);
  if (filename == NULL) {
    LOG_ERROR("cannot load parameter info for collection '%s', out of memory", path);

    return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
  }

  if (! TRI_ExistsFile(filename)) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
    return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_PARAMETER_FILE);
  }

  json = TRI_JsonFile(TRI_UNKNOWN_MEM_ZONE, filename, &error);

  if (json == NULL) {
    if (error != NULL) {
      LOG_ERROR("cannot open '%s', parameter block not readable: %s", filename, error);
      TRI_FreeString(TRI_CORE_MEM_ZONE, error);
    }
    else {
      LOG_ERROR("cannot open '%s', parameter block not readable", filename);
    }
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

    return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_PARAMETER_FILE);
  }

  if (json->_type != TRI_JSON_ARRAY) {
    LOG_ERROR("cannot open '%s', file does not contain a json array", filename);
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

    return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_PARAMETER_FILE);
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

  // convert json
  n = json->_value._objects._length;

  for (i = 0;  i < n;  i += 2) {
    TRI_json_t* key;
    TRI_json_t* value;

    key = TRI_AtVector(&json->_value._objects, i);
    value = TRI_AtVector(&json->_value._objects, i + 1);

    if (key->_type == TRI_JSON_STRING && value->_type == TRI_JSON_NUMBER) {
      if (TRI_EqualString(key->_value._string.data, "version")) {
        parameter->_version = value->_value._number;
      }
      else if (TRI_EqualString(key->_value._string.data, "type")) {
        parameter->_type = value->_value._number;
      }
      else if (TRI_EqualString(key->_value._string.data, "cid")) {
        parameter->_cid = value->_value._number;
      }
      else if (TRI_EqualString(key->_value._string.data, "maximalSize")) {
        parameter->_maximalSize = value->_value._number;
      }
    }
    else if (key->_type == TRI_JSON_STRING && value->_type == TRI_JSON_STRING) {
      if (TRI_EqualString(key->_value._string.data, "name")) {
        TRI_CopyString(parameter->_name, value->_value._string.data, sizeof(parameter->_name));

        parameter->_isSystem = TRI_IsSystemCollectionName(parameter->_name);
      }
    }
    else if (key->_type == TRI_JSON_STRING && value->_type == TRI_JSON_BOOLEAN) {
      if (TRI_EqualString(key->_value._string.data, "deleted")) {
        parameter->_deleted = value->_value._boolean;
      }
      else if (TRI_EqualString(key->_value._string.data, "isVolatile")) {
        parameter->_isVolatile = value->_value._boolean;
      }
      else if (TRI_EqualString(key->_value._string.data, "waitForSync")) {
        parameter->_waitForSync = value->_value._boolean;
      }
    }
    else if (key->_type == TRI_JSON_STRING && value->_type == TRI_JSON_ARRAY) {
      if (TRI_EqualString(key->_value._string.data, "keyOptions")) {
        parameter->_keyOptions = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, value);
      }
    }
  }

  TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
  return TRI_ERROR_NO_ERROR;
}
Beispiel #8
0
TRI_json_t* TRI_UnionizeListsJson (const TRI_json_t* const list1, 
                                   const TRI_json_t* const list2,
                                   const bool unique) {
  TRI_json_t* last = NULL;
  TRI_json_t* result;
  size_t i1, i2;
  size_t n1, n2;

  assert(list1);
  assert(list1->_type == TRI_JSON_LIST);
  assert(list2);
  assert(list2->_type == TRI_JSON_LIST);
  
  n1 = list1->_value._objects._length;
  n2 = list2->_value._objects._length;

  // special cases for empty lists
  if (n1 == 0 && !unique) {
    return TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, (TRI_json_t*) list2);
  }

  if (n2 == 0 && !unique) {
    return TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, (TRI_json_t*) list1);
  }

  // create result list
  result = TRI_CreateListJson(TRI_UNKNOWN_MEM_ZONE);
  if (!result) {
    return NULL;
  }

  // reset positions
  i1 = 0;
  i2 = 0;

  // iterate over lists
  while (true) {
    // pointers to elements in both lists
    TRI_json_t* p1;
    TRI_json_t* p2;

    if (i1 < n1 && i2 < n2) {
      int compareResult;

      // both lists not yet exhausted
      p1 = TRI_AtVector(&list1->_value._objects, i1);
      p2 = TRI_AtVector(&list2->_value._objects, i2);
      compareResult = TRI_CompareValuesJson(p1, p2);

      if (compareResult < 0) {
        // left element is smaller
        if (!unique || !last || TRI_CompareValuesJson(p1, last) > 0) {
          TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, p1);
          last = p1;
        }
        ++i1;
      } 
      else if (compareResult > 0) {
        // right element is smaller
        if (!unique || !last || TRI_CompareValuesJson(p2, last) > 0) {
          TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, p2);
          last = p2;
        }
        ++i2;
      }
      else {
        // both elements are equal
        if (!unique || !last || TRI_CompareValuesJson(p1, last) > 0) {
          TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, p1);
          last = p1;
          if (!unique) {
            TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, p2);
          }
        }
        ++i1;
        ++i2;
      }
    }
    else if (i1 < n1 && i2 >= n2) {
      // only right list is exhausted
      p1 = TRI_AtVector(&list1->_value._objects, i1);

      if (!unique || !last || TRI_CompareValuesJson(p1, last) > 0) {
        TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, p1);
        last = p1;
      }
      ++i1;
    }
    else if (i1 >= n1 && i2 < n2) {
      // only left list is exhausted
      p2 = TRI_AtVector(&list2->_value._objects, i2);

      if (!unique || !last || TRI_CompareValuesJson(p2, last) > 0) {
        TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, p2);
        last = p2;
      }
      ++i2;
    }
    else {
      // both lists exhausted, stop!
      break;
    }
  }

  return result;
}
static TRI_json_t* MergeRecursive (TRI_memory_zone_t* zone,
                                   TRI_json_t const* lhs,
                                   TRI_json_t const* rhs,
                                   bool nullMeansRemove,
                                   bool mergeObjects) {
    TRI_ASSERT(lhs != nullptr);

    std::unique_ptr<TRI_json_t> result(TRI_CopyJson(zone, lhs));

    if (result == nullptr) {
        return nullptr;
    }

    auto r = result.get(); // shortcut variable

    size_t const n = TRI_LengthVector(&rhs->_value._objects);

    for (size_t i = 0; i < n; i += 2) {
        // enumerate all the replacement values
        auto key   = static_cast<TRI_json_t const*>(TRI_AtVector(&rhs->_value._objects, i));
        auto value = static_cast<TRI_json_t const*>(TRI_AtVector(&rhs->_value._objects, i + 1));

        if (value->_type == TRI_JSON_NULL && nullMeansRemove) {
            // replacement value is a null and we don't want to store nulls => delete attribute from the result
            TRI_DeleteObjectJson(zone, r, key->_value._string.data);
        }
        else {
            // replacement value is not a null or we want to store nulls
            TRI_json_t const* lhsValue = TRI_LookupObjectJson(lhs, key->_value._string.data);

            if (lhsValue == nullptr) {
                // existing array does not have the attribute => append new attribute
                if (value->_type == TRI_JSON_OBJECT && nullMeansRemove) {
                    TRI_json_t empty;
                    TRI_InitObjectJson(TRI_UNKNOWN_MEM_ZONE, &empty);
                    TRI_json_t* merged = MergeRecursive(zone, &empty, value, nullMeansRemove, mergeObjects);

                    if (merged == nullptr) {
                        return nullptr;
                    }

                    TRI_json_t* copy = TRI_CopyJson(zone, value);

                    if (copy == nullptr) {
                        return nullptr;
                    }

                    TRI_Insert3ObjectJson(zone, r, key->_value._string.data, copy);
                }
                else {
                    TRI_Insert3ObjectJson(zone, r, key->_value._string.data, TRI_CopyJson(zone, value));
                }
            }
            else {
                // existing array already has the attribute => replace attribute
                if (lhsValue->_type == TRI_JSON_OBJECT && value->_type == TRI_JSON_OBJECT && mergeObjects) {
                    TRI_json_t* merged = MergeRecursive(zone, lhsValue, value, nullMeansRemove, mergeObjects);

                    if (merged == nullptr) {
                        return nullptr;
                    }

                    TRI_ReplaceObjectJson(zone, r, key->_value._string.data, merged);
                    TRI_FreeJson(zone, merged);
                }
                else {
                    TRI_ReplaceObjectJson(zone, r, key->_value._string.data, value);
                }
            }
        }

    }

    return result.release();
}