Пример #1
0
static generator_type_e GeneratorType (const TRI_json_t* const parameters) {
  TRI_json_t* type;
  const char* typeName;

  if (parameters == NULL || parameters->_type != TRI_JSON_ARRAY) {
    return TYPE_TRADITIONAL;
  }

  type = TRI_LookupArrayJson(parameters, "type");

  if (! TRI_IsStringJson(type)) {
    return TYPE_TRADITIONAL;
  }

  typeName = type->_value._string.data;

  if (TRI_CaseEqualString(typeName, TraditionalName)) {
    return TYPE_TRADITIONAL;
  }

  if (TRI_CaseEqualString(typeName, AutoIncrementName)) {
    return TYPE_AUTOINCREMENT;
  }

  // error
  return TYPE_UNKNOWN;
}
Пример #2
0
static TRI_json_t* GetMergedKeyList (const TRI_json_t* const lhs,
                                     const TRI_json_t* const rhs) {
  TRI_json_t* keys;
  TRI_json_t* unique;
  size_t i, n;

  TRI_ASSERT(lhs->_type == TRI_JSON_ARRAY);
  TRI_ASSERT(rhs->_type == TRI_JSON_ARRAY);

  keys = TRI_CreateList2Json(TRI_UNKNOWN_MEM_ZONE,
                             lhs->_value._objects._length + rhs->_value._objects._length);

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

  n = lhs->_value._objects._length;

  for (i = 0 ; i < n; i += 2) {
    TRI_json_t* key = TRI_AtVector(&lhs->_value._objects, i);

    TRI_ASSERT(TRI_IsStringJson(key));
    TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, keys, key);
  }


  n = rhs->_value._objects._length;

  for (i = 0 ; i < n; i += 2) {
    TRI_json_t* key = TRI_AtVector(&rhs->_value._objects, i);

    TRI_ASSERT(TRI_IsStringJson(key));
    TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, keys, key);
  }

  // sort the key list in place
  TRI_SortListJson(keys);

  // list is now sorted
  unique = TRI_UniquifyListJson(keys);

  TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, keys);

  return unique; // might be NULL
}
Пример #3
0
static uint64_t FastHashJsonRecursive (uint64_t hash,
                                       TRI_json_t const* object) {
    if (nullptr == object) {
        return fasthash64(static_cast<const void*>("null"), 4, hash);
    }

    switch (object->_type) {
    case TRI_JSON_UNUSED: {
        return hash;
    }

    case TRI_JSON_NULL: {
        return fasthash64(static_cast<const void*>("null"), 4, hash);
    }

    case TRI_JSON_BOOLEAN: {
        if (object->_value._boolean) {
            return fasthash64(static_cast<const void*>("true"), 4, hash);
        }
        return fasthash64(static_cast<const void*>("false"), 5, hash);
    }

    case TRI_JSON_NUMBER: {
        return fasthash64(static_cast<const void*>(&object->_value._number), sizeof(object->_value._number), hash);
    }

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE: {
        return fasthash64(static_cast<const void*>(object->_value._string.data), object->_value._string.length, hash);
    }

    case TRI_JSON_OBJECT: {
        hash = fasthash64(static_cast<const void*>("object"), 6, hash);
        size_t const n = TRI_LengthVector(&object->_value._objects);
        for (size_t i = 0;  i < n;  i += 2) {
            auto subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
            TRI_ASSERT(TRI_IsStringJson(subjson));
            hash = FastHashJsonRecursive(hash, subjson);
            subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i + 1));
            hash = FastHashJsonRecursive(hash, subjson);
        }
        return hash;
    }

    case TRI_JSON_ARRAY: {
        hash = fasthash64(static_cast<const void*>("array"), 5, hash);
        size_t const n = TRI_LengthVector(&object->_value._objects);
        for (size_t i = 0;  i < n;  ++i) {
            auto subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
            hash = FastHashJsonRecursive(hash, subjson);
        }
    }
    }

    return hash;   // never reached
}
Пример #4
0
static TRI_json_t* GetMergedKeyArray (TRI_json_t const* lhs,
                                      TRI_json_t const* rhs) {
    TRI_ASSERT(lhs->_type == TRI_JSON_OBJECT);
    TRI_ASSERT(rhs->_type == TRI_JSON_OBJECT);

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

    std::unique_ptr<TRI_json_t> keys(TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE, n));

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

    if (TRI_CapacityVector(&(keys.get()->_value._objects)) < n) {
        return nullptr;
    }

    n = TRI_LengthVector(&lhs->_value._objects);

    for (size_t i = 0 ; i < n; i += 2) {
        auto key = static_cast<TRI_json_t const*>(TRI_AtVector(&lhs->_value._objects, i));

        TRI_ASSERT(TRI_IsStringJson(key));
        TRI_PushBackArrayJson(TRI_UNKNOWN_MEM_ZONE, keys.get(), key);
    }


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

    for (size_t i = 0 ; i < n; i += 2) {
        auto key = static_cast<TRI_json_t const*>(TRI_AtVector(&rhs->_value._objects, i));

        TRI_ASSERT(TRI_IsStringJson(key));
        TRI_PushBackArrayJson(TRI_UNKNOWN_MEM_ZONE, keys.get(), key);
    }

    // sort the key array in place
    TRI_SortArrayJson(keys.get());

    // array is now sorted
    return TRI_UniquifyArrayJson(keys.get());
}
Пример #5
0
static TRI_aql_node_t* InjectParameter (TRI_aql_statement_walker_t* const walker,
                                        TRI_aql_node_t* node) {
  TRI_aql_bind_parameter_t* bind;
  TRI_associative_pointer_t* bindValues;
  TRI_aql_context_t* context;
  char* name;

  if (node == NULL || 
      node->_type != TRI_AQL_NODE_PARAMETER) {
    return node;
  }

  // we found a parameter node
  context = (TRI_aql_context_t*) walker->_data;
  assert(context);

  bindValues = (TRI_associative_pointer_t*) &context->_parameters._values;
  assert(bindValues);

  name = TRI_AQL_NODE_STRING(node);
  assert(name);

  bind = (TRI_aql_bind_parameter_t*) TRI_LookupByKeyAssociativePointer(bindValues, name);

  if (bind) {
    if (*name == '@') {
      // a collection name bind parameter
      if (TRI_IsStringJson(bind->_value)) {
        char* collectionName = TRI_RegisterStringAql(context,
                                                     bind->_value->_value._string.data,
                                                     bind->_value->_value._string.length - 1,
                                                     false);

        node = TRI_CreateNodeCollectionAql(context, collectionName);
      }
      else {
        TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_BIND_PARAMETER_TYPE, name);
        node = NULL;
      }
    }
    else {
      node = TRI_JsonNodeAql(context, bind->_value);
    }

    if (node == NULL) {
      TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_BIND_PARAMETERS_INVALID, NULL);
    }
  }

  return node;
}
Пример #6
0
    void ImportHelper::handleResult (SimpleHttpResult* result) {
      if (! result) {
        return;
      }

      stringstream& r = result->getBody();

      TRI_json_t* json = TRI_JsonString(TRI_UNKNOWN_MEM_ZONE, r.str().c_str());

      if (json) {
        // get the "error" flag. This returns a pointer, not a copy
        TRI_json_t* error = TRI_LookupArrayJson(json, "error");

        if (error) {
          if (error->_type == TRI_JSON_BOOLEAN && error->_value._boolean) {
            _hasError = true;

            // get the error message. This returns a pointer, not a copy
            TRI_json_t* errorMessage = TRI_LookupArrayJson(json, "errorMessage");

            if (TRI_IsStringJson(errorMessage)) {
              _errorMessage = string(errorMessage->_value._string.data, errorMessage->_value._string.length);
            }
          }
        }

        TRI_json_t* importResult;

        // look up the "created" flag. This returns a pointer, not a copy
        importResult= TRI_LookupArrayJson(json, "created");
        if (importResult) {
          if (importResult->_type == TRI_JSON_NUMBER) {
            _numberOk += (size_t) importResult->_value._number;
          }
        }

        // look up the "errors" flag. This returns a pointer, not a copy
        importResult= TRI_LookupArrayJson(json, "errors");
        if (importResult) {
          if (importResult->_type == TRI_JSON_NUMBER) {
            _numberError += (size_t) importResult->_value._number;
          }
        }

        // this will free the json struct will a sub-elements
        TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
      }

      delete result;
    }
Пример #7
0
bool TRI_AddParameterValuesAql (TRI_aql_context_t* const context,
                                const TRI_json_t* const parameters) {
  size_t i;
  size_t n;

  assert(context);

  if (parameters == NULL) {
    // no bind parameters, direclty return
    return true;
  }

  if (parameters->_type != TRI_JSON_ARRAY) {
    // parameters must be a list
    TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_BIND_PARAMETERS_INVALID, NULL);
    return false;
  }

  n = parameters->_value._objects._length;
  if (n == 0) {
    // empty list, this is ok
    return true;
  }

  for (i = 0; i < n; i += 2) {
    TRI_json_t* name = TRI_AtVector(&parameters->_value._objects, i);
    TRI_json_t* value = TRI_AtVector(&parameters->_value._objects, i + 1);
    TRI_aql_bind_parameter_t* parameter;

    assert(TRI_IsStringJson(name));
    assert(value);

    parameter = CreateParameter(name->_value._string.data, 
                                name->_value._string.length - 1,
                                value);

    if (parameter == NULL) {
      TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);

      return false;
    }

    TRI_InsertKeyAssociativePointer(&context->_parameters._values, parameter->_name, parameter, false);
  }

  return true;
}
Пример #8
0
static int ReadTick (TRI_json_t const* json,
                     char const* attributeName,
                     TRI_voc_tick_t* dst) {
  TRI_json_t* tick;

  assert(json != NULL);
  assert(json->_type == TRI_JSON_ARRAY);
                                     
  tick = TRI_LookupArrayJson(json, attributeName);

  if (! TRI_IsStringJson(tick)) {
    return TRI_ERROR_REPLICATION_INVALID_APPLIER_STATE;
  }

  *dst = (TRI_voc_tick_t) TRI_UInt64String2(tick->_value._string.data, tick->_value._string.length -1);

  return TRI_ERROR_NO_ERROR;
}
Пример #9
0
KeyGenerator::GeneratorType KeyGenerator::generatorType (TRI_json_t const* parameters) {
  if (! TRI_IsArrayJson(parameters)) {
    return KeyGenerator::TYPE_TRADITIONAL;
  }

  TRI_json_t const* type = TRI_LookupArrayJson(parameters, "type");

  if (! TRI_IsStringJson(type)) {
    return KeyGenerator::TYPE_TRADITIONAL;
  }

  char const* typeName = type->_value._string.data;

  if (TRI_CaseEqualString(typeName, TraditionalKeyGenerator::name().c_str())) {
    return KeyGenerator::TYPE_TRADITIONAL;
  }

  if (TRI_CaseEqualString(typeName, AutoIncrementKeyGenerator::name().c_str())) {
    return KeyGenerator::TYPE_AUTOINCREMENT;
  }

  // error
  return KeyGenerator::TYPE_UNKNOWN;
}
Пример #10
0
static uint64_t HashJsonRecursive (uint64_t hash, TRI_json_t const* object) {
  size_t n;
  size_t i;
  uint64_t tmphash;
  TRI_json_t const* subjson;

  if (0 == object) {
    return HashBlock(hash, "null", 4);   // strlen("null")
  }
  switch (object->_type) {
    case TRI_JSON_UNUSED: {
      return hash;
    }

    case TRI_JSON_NULL: {
      return HashBlock(hash, "null", 4);   // strlen("null")
    }

    case TRI_JSON_BOOLEAN: {
      if (object->_value._boolean) {
        return HashBlock(hash, "true", 4);  // strlen("true")
      }
      else {
        return HashBlock(hash, "false", 5);  // strlen("true")
      }
    }

    case TRI_JSON_NUMBER: {
      return HashBlock(hash, (char const*) &(object->_value._number), sizeof(object->_value._number));
    }

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE: {
      return HashBlock(hash,
                       object->_value._string.data,
                       object->_value._string.length);
    }

    case TRI_JSON_ARRAY: {
      hash = HashBlock(hash, "array", 5);   // strlen("array")
      n = object->_value._objects._length;
      tmphash = hash;
      for (i = 0;  i < n;  i += 2) {
        subjson = (const TRI_json_t*) TRI_AtVector(&object->_value._objects, i);
        TRI_ASSERT(TRI_IsStringJson(subjson));
        tmphash ^= HashJsonRecursive(hash, subjson);
        subjson = (const TRI_json_t*) TRI_AtVector(&object->_value._objects,
                                                   i+1);
        tmphash ^= HashJsonRecursive(hash, subjson);
      }
      return tmphash;
    }

    case TRI_JSON_LIST: {
      hash = HashBlock(hash, "list", 4);   // strlen("list")
      n = object->_value._objects._length;
      for (i = 0;  i < n;  ++i) {
        subjson = (const TRI_json_t*) TRI_AtVector(&object->_value._objects, i);
        hash = HashJsonRecursive(hash, subjson);
      }
      return hash;
    }
  }
  return hash;   // never reached
}
Пример #11
0
bool TRI_HasDuplicateKeyJson (TRI_json_t const* object) {
  if (object && object->_type == TRI_JSON_ARRAY) {
    const size_t n = object->_value._objects._length;
    const bool hasMultipleElements = (n > 2);

    // if we don't have attributes, we do not need to check for duplicates
    // if we only have one attribute, we don't need to check for duplicates in
    // the array, but we need to recursively validate the array values (if
    // array value itself is an array)
    if (n > 0) {
      TRI_associative_pointer_t hash;
      size_t i;

      if (hasMultipleElements) {
        TRI_InitAssociativePointer(&hash,
          TRI_UNKNOWN_MEM_ZONE,
          &TRI_HashStringKeyAssociativePointer,
          &TRI_HashStringKeyAssociativePointer,
          &TRI_EqualStringKeyAssociativePointer,
          0);
      }

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

        key = TRI_AtVector(&object->_value._objects, i);

        if (! TRI_IsStringJson(key)) {
          continue;
        }

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

        // recursively check sub-array elements
        if (value->_type == TRI_JSON_ARRAY && TRI_HasDuplicateKeyJson(value)) {
          // duplicate found in sub-array
          if (hasMultipleElements) {
            TRI_DestroyAssociativePointer(&hash);
          }

          return true;
        }

        if (hasMultipleElements) {
          void* previous = TRI_InsertKeyAssociativePointer(&hash, key->_value._string.data, key->_value._string.data, false);
          if (previous != NULL) {
            // duplicate found
            TRI_DestroyAssociativePointer(&hash);

            return true;
          }
        }
      }

      if (hasMultipleElements) {
        TRI_DestroyAssociativePointer(&hash);
      }
    }
  }

  // no duplicate found
  return false;
}
Пример #12
0
int TRI_CompareValuesJson (const TRI_json_t* const lhs,
                           const TRI_json_t* const rhs) {
  // note: both lhs and rhs may be NULL!
  int lWeight = TypeWeight(lhs);
  int rWeight = TypeWeight(rhs);

  if (lWeight < rWeight) {
    return -1;
  }

  if (lWeight > rWeight) {
    return 1;
  }

  // lhs and rhs have equal weights
  if (lhs == NULL) {
    // both lhs and rhs are NULL, so they are equal
    return 0;
  }

  switch (lhs->_type) {
    case TRI_JSON_UNUSED:
    case TRI_JSON_NULL:
      return 0; // null == null;

    case TRI_JSON_BOOLEAN:
      if (lhs->_value._boolean == rhs->_value._boolean) {
        return 0;
      }

      if (!lhs->_value._boolean && rhs->_value._boolean) {
        return -1;
      }

      return 1;

    case TRI_JSON_NUMBER:
      if (lhs->_value._number == rhs->_value._number) {
        return 0;
      }

      if (lhs->_value._number < rhs->_value._number) {
        return -1;
      }

      return 1;

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE:
      // same for STRING and STRING_REFERENCE
      return strcmp(lhs->_value._string.data, rhs->_value._string.data);

    case TRI_JSON_LIST: {
      size_t nl = lhs->_value._objects._length;
      size_t nr = rhs->_value._objects._length;
      size_t i, n;

      if (nl > nr) {
        n = nl;
      }
      else {
        n = nr;
      }

      for (i = 0; i < n; ++i) {
        TRI_json_t* lhsValue;
        TRI_json_t* rhsValue;
        int result;

        lhsValue = (i >= nl) ? NULL : TRI_AtVector(&lhs->_value._objects, i);
        rhsValue = (i >= nr) ? NULL : TRI_AtVector(&rhs->_value._objects, i);
        result = TRI_CompareValuesJson(lhsValue, rhsValue);
        if (result != 0) {
          return result;
        }
      }

      return 0;
    }

    case TRI_JSON_ARRAY: {
      TRI_json_t* keys;

      TRI_ASSERT(lhs->_type == TRI_JSON_ARRAY);
      TRI_ASSERT(rhs->_type == TRI_JSON_ARRAY);

      keys = GetMergedKeyList(lhs, rhs);

      if (keys != NULL) {
        size_t i, n;

        n = keys->_value._objects._length;
        for (i = 0; i < n; ++i) {
          TRI_json_t* keyElement;
          TRI_json_t* lhsValue;
          TRI_json_t* rhsValue;
          int result;

          keyElement = TRI_AtVector(&keys->_value._objects, i);
          TRI_ASSERT(TRI_IsStringJson(keyElement));

          lhsValue = TRI_LookupArrayJson((TRI_json_t*) lhs, keyElement->_value._string.data); // may be NULL
          rhsValue = TRI_LookupArrayJson((TRI_json_t*) rhs, keyElement->_value._string.data); // may be NULL

          result = TRI_CompareValuesJson(lhsValue, rhsValue);

          if (result != 0) {
            TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, keys);
            return result;
          }
        }

        TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, keys);
      }

      return 0;
    }

    default:
      return 0;
  }
}
Пример #13
0
static uint64_t HashJsonRecursive (uint64_t hash,
                                   TRI_json_t const* object) {
    if (nullptr == object) {
        return HashBlock(hash, "null", 4);   // strlen("null")
    }

    switch (object->_type) {
    case TRI_JSON_UNUSED: {
        return hash;
    }

    case TRI_JSON_NULL: {
        return HashBlock(hash, "null", 4);   // strlen("null")
    }

    case TRI_JSON_BOOLEAN: {
        if (object->_value._boolean) {
            return HashBlock(hash, "true", 4);  // strlen("true")
        }
        else {
            return HashBlock(hash, "false", 5);  // strlen("true")
        }
    }

    case TRI_JSON_NUMBER: {
        return HashBlock(hash, (char const*) &(object->_value._number), sizeof(object->_value._number));
    }

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE: {
        return HashBlock(hash,
                         object->_value._string.data,
                         object->_value._string.length);
    }

    case TRI_JSON_OBJECT: {
        hash = HashBlock(hash, "array", 5);   // strlen("array")
        size_t const n = TRI_LengthVector(&object->_value._objects);
        uint64_t tmphash = hash;
        for (size_t i = 0;  i < n;  i += 2) {
            auto subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
            TRI_ASSERT(TRI_IsStringJson(subjson));
            tmphash ^= HashJsonRecursive(hash, subjson);
            subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i + 1));
            tmphash ^= HashJsonRecursive(hash, subjson);
        }
        return tmphash;
    }

    case TRI_JSON_ARRAY: {
        hash = HashBlock(hash, "list", 4);   // strlen("list")
        size_t const n = TRI_LengthVector(&object->_value._objects);
        for (size_t i = 0;  i < n;  ++i) {
            auto subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
            hash = HashJsonRecursive(hash, subjson);
        }
        return hash;
    }
    }
    return hash;   // never reached
}
Пример #14
0
int TRI_CompareValuesJson (TRI_json_t const* lhs,
                           TRI_json_t const* rhs,
                           bool useUTF8) {
    // note: both lhs and rhs may be NULL!
    {
        int lWeight = TypeWeight(lhs);
        int rWeight = TypeWeight(rhs);

        if (lWeight < rWeight) {
            return -1;
        }

        if (lWeight > rWeight) {
            return 1;
        }

        TRI_ASSERT_EXPENSIVE(lWeight == rWeight);
    }

    // lhs and rhs have equal weights

    if (lhs == nullptr || rhs == nullptr) {
        // either lhs or rhs is a nullptr. we cannot be sure here that both are nullptrs.
        // there can also exist the situation that lhs is a nullptr and rhs is a JSON null value
        // (or vice versa). Anyway, the compare value is the same for both,
        return 0;
    }

    switch (lhs->_type) {
    case TRI_JSON_UNUSED:
    case TRI_JSON_NULL: {
        return 0; // null == null;
    }

    case TRI_JSON_BOOLEAN: {
        if (lhs->_value._boolean == rhs->_value._boolean) {
            return 0;
        }

        if (! lhs->_value._boolean && rhs->_value._boolean) {
            return -1;
        }

        return 1;
    }

    case TRI_JSON_NUMBER: {
        if (lhs->_value._number == rhs->_value._number) {
            return 0;
        }

        if (lhs->_value._number < rhs->_value._number) {
            return -1;
        }

        return 1;
    }

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE: {
        // same for STRING and STRING_REFERENCE
        TRI_ASSERT(lhs->_value._string.data != nullptr);
        TRI_ASSERT(rhs->_value._string.data != nullptr);

        int res;
        size_t const nl = lhs->_value._string.length - 1;
        size_t const nr = rhs->_value._string.length - 1;
        if (useUTF8) {
            res = TRI_compare_utf8(lhs->_value._string.data,
                                   nl,
                                   rhs->_value._string.data,
                                   nr);
        }
        else {
            // beware of strings containing NUL bytes
            size_t len = nl < nr ? nl : nr;
            res = memcmp(lhs->_value._string.data, rhs->_value._string.data, len);
        }
        if (res < 0) {
            return -1;
        }
        else if (res > 0) {
            return 1;
        }
        // res == 0
        if (nl == nr) {
            return 0;
        }
        // res == 0, but different string lengths
        return nl < nr ? -1 : 1;
    }

    case TRI_JSON_ARRAY: {
        size_t const nl = TRI_LengthVector(&lhs->_value._objects);
        size_t const nr = TRI_LengthVector(&rhs->_value._objects);
        size_t n;

        if (nl > nr) {
            n = nl;
        }
        else {
            n = nr;
        }

        for (size_t i = 0; i < n; ++i) {
            auto lhsValue = (i >= nl) ? nullptr : static_cast<TRI_json_t const*>(TRI_AtVector(&lhs->_value._objects, i));
            auto rhsValue = (i >= nr) ? nullptr : static_cast<TRI_json_t const*>(TRI_AtVector(&rhs->_value._objects, i));

            int result = TRI_CompareValuesJson(lhsValue, rhsValue, useUTF8);

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

        return 0;
    }

    case TRI_JSON_OBJECT: {
        TRI_ASSERT(lhs->_type == TRI_JSON_OBJECT);
        TRI_ASSERT(rhs->_type == TRI_JSON_OBJECT);

        std::unique_ptr<TRI_json_t> keys(GetMergedKeyArray(lhs, rhs));

        if (keys != nullptr) {
            auto json = keys.get();
            size_t const n = TRI_LengthVector(&json->_value._objects);

            for (size_t i = 0; i < n; ++i) {
                auto keyElement = static_cast<TRI_json_t const*>(TRI_AtVector(&json->_value._objects, i));
                TRI_ASSERT(TRI_IsStringJson(keyElement));

                TRI_json_t const* lhsValue = TRI_LookupObjectJson(lhs, keyElement->_value._string.data); // may be NULL
                TRI_json_t const* rhsValue = TRI_LookupObjectJson(rhs, keyElement->_value._string.data); // may be NULL

                int result = TRI_CompareValuesJson(lhsValue, rhsValue, useUTF8);

                if (result != 0) {
                    return result;
                }
            }
        }
        // fall-through to returning 0
    }

    }

    return 0;
}
Пример #15
0
int TRI_LoadStateReplicationApplier (TRI_vocbase_t* vocbase,
                                     TRI_replication_applier_state_t* state) {
  TRI_json_t* json;
  TRI_json_t* serverId;
  char* filename;
  int res;
  
  TRI_InitStateReplicationApplier(state);
  filename = GetStateFilename(vocbase);

  if (filename == NULL) {
    return TRI_ERROR_OUT_OF_MEMORY;
  }

  LOG_TRACE("looking for replication state file '%s'", filename);

  if (! TRI_ExistsFile(filename)) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

    return TRI_ERROR_FILE_NOT_FOUND;
  }
  
  LOG_TRACE("replication state file '%s' found", filename);

  json  = TRI_JsonFile(TRI_CORE_MEM_ZONE, filename, NULL);
  TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

  if (! TRI_IsArrayJson(json)) {
    if (json != NULL) {
      TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
    }

    return TRI_ERROR_REPLICATION_INVALID_APPLIER_STATE;
  }

  res = TRI_ERROR_NO_ERROR;

  // read the server id
  serverId = TRI_LookupArrayJson(json, "serverId");

  if (! TRI_IsStringJson(serverId)) {
    res = TRI_ERROR_REPLICATION_INVALID_APPLIER_STATE;
  }
  else {
    state->_serverId = TRI_UInt64String2(serverId->_value._string.data, 
                                         serverId->_value._string.length - 1);
  }

  if (res == TRI_ERROR_NO_ERROR) {
    // read the ticks
    res |= ReadTick(json, "lastAppliedContinuousTick", &state->_lastAppliedContinuousTick); 

    // set processed = applied
    state->_lastProcessedContinuousTick = state->_lastAppliedContinuousTick;
  }

  TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
  
  LOG_TRACE("replication state file read successfully");

  return res;
}
Пример #16
0
static int LoadConfiguration (TRI_vocbase_t* vocbase,
                              TRI_replication_applier_configuration_t* config) {
  TRI_json_t* json;
  TRI_json_t* value;
  char* filename;
  int res;
   
  TRI_DestroyConfigurationReplicationApplier(config);
  TRI_InitConfigurationReplicationApplier(config);
  filename = GetConfigurationFilename(vocbase);

  if (! TRI_ExistsFile(filename)) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

    return TRI_ERROR_FILE_NOT_FOUND;
  }
  
  json  = TRI_JsonFile(TRI_CORE_MEM_ZONE, filename, NULL);
  TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

  if (! TRI_IsArrayJson(json)) {
    if (json != NULL) {
      TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
    }

    return TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION;
  }

  res = TRI_ERROR_NO_ERROR;

  if (config->_endpoint != NULL) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, config->_endpoint);
    config->_endpoint = NULL;
  }
  if (config->_database != NULL) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, config->_database);
    config->_database = NULL;
  }
  if (config->_username != NULL) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, config->_username);
    config->_username = NULL;
  }
  if (config->_password != NULL) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, config->_password);
    config->_password = NULL;
  }

  // read the endpoint
  value = TRI_LookupArrayJson(json, "endpoint");

  if (! TRI_IsStringJson(value)) {
    res = TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION;
  }
  else {
    config->_endpoint = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE, 
                                              value->_value._string.data, 
                                              value->_value._string.length - 1);
  }
  
  // read the database name
  value = TRI_LookupArrayJson(json, "database");

  if (! TRI_IsStringJson(value)) {
    config->_database = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, 
                                             vocbase->_name); 
  }
  else {
    config->_database = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE, 
                                              value->_value._string.data, 
                                              value->_value._string.length - 1);
  }

  // read username / password
  value = TRI_LookupArrayJson(json, "username");

  if (TRI_IsStringJson(value)) {
    config->_username = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE, 
                                              value->_value._string.data, 
                                              value->_value._string.length - 1);
  }
  
  value = TRI_LookupArrayJson(json, "password");

  if (TRI_IsStringJson(value)) {
    config->_password = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE, 
                                              value->_value._string.data, 
                                              value->_value._string.length - 1);
  }

  value = TRI_LookupArrayJson(json, "requestTimeout");

  if (TRI_IsNumberJson(value)) {
    config->_requestTimeout = value->_value._number;
  }
  
  value = TRI_LookupArrayJson(json, "connectTimeout");

  if (TRI_IsNumberJson(value)) {
    config->_connectTimeout = value->_value._number;
  }
  
  value = TRI_LookupArrayJson(json, "maxConnectRetries");

  if (TRI_IsNumberJson(value)) {
    config->_maxConnectRetries = (uint64_t) value->_value._number;
  }
  
  value = TRI_LookupArrayJson(json, "chunkSize");

  if (TRI_IsNumberJson(value)) {
    config->_chunkSize = (uint64_t) value->_value._number;
  }

  value = TRI_LookupArrayJson(json, "autoStart");

  if (TRI_IsBooleanJson(value)) {
    config->_autoStart = value->_value._boolean;
  }
  
  value = TRI_LookupArrayJson(json, "adaptivePolling");

  if (TRI_IsBooleanJson(value)) {
    config->_adaptivePolling = value->_value._boolean;
  }

  TRI_FreeJson(TRI_CORE_MEM_ZONE, json);

  return res;
}
Пример #17
0
    void ImportHelper::handleResult (SimpleHttpResult* result) {
      if (result == 0) {
        return;
      }

      TRI_json_t* json = TRI_JsonString(TRI_UNKNOWN_MEM_ZONE,
                                        result->getBody().c_str());

      if (json != 0) {
        // error details
        TRI_json_t const* details = TRI_LookupArrayJson(json, "details");

        if (TRI_IsListJson(details)) {
          const size_t n = details->_value._objects._length;

          for (size_t i = 0; i < n; ++i) {
            TRI_json_t const* detail = (TRI_json_t const*) TRI_AtVector(&details->_value._objects, i);

            if (TRI_IsStringJson(detail)) {
              LOG_WARNING("%s", detail->_value._string.data);
            }
          }
        }

        // get the "error" flag. This returns a pointer, not a copy
        TRI_json_t const* error = TRI_LookupArrayJson(json, "error");

        if (TRI_IsBooleanJson(error) &&
            error->_value._boolean) {
          _hasError = true;

          // get the error message. This returns a pointer, not a copy
          TRI_json_t const* errorMessage = TRI_LookupArrayJson(json, "errorMessage");

          if (TRI_IsStringJson(errorMessage)) {
            _errorMessage = string(errorMessage->_value._string.data, errorMessage->_value._string.length - 1);
          }
        }

        TRI_json_t const* importResult;

        // look up the "created" flag. This returns a pointer, not a copy
        importResult = TRI_LookupArrayJson(json, "created");

        if (TRI_IsNumberJson(importResult)) {
          _numberOk += (size_t) importResult->_value._number;
        }

        // look up the "errors" flag. This returns a pointer, not a copy
        importResult = TRI_LookupArrayJson(json, "errors");

        if (TRI_IsNumberJson(importResult)) {
          _numberError += (size_t) importResult->_value._number;
        }

        // this will free the json struct will a sub-elements
        TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
      }

      delete result;
    }
Пример #18
0
mrb_value MR_ObjectJson (mrb_state* mrb, TRI_json_t const* json) {
  switch (json->_type) {
    case TRI_JSON_UNUSED:
      return mrb_nil_value();

    case TRI_JSON_NULL:
      return mrb_nil_value();

    case TRI_JSON_BOOLEAN:
      return json->_value._boolean ? mrb_true_value() : mrb_false_value();

    case TRI_JSON_NUMBER:
      return mrb_float_value(mrb, json->_value._number);

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE:
      // same for STRING and STRING_REFERENCE
      return mrb_str_new(mrb, json->_value._string.data, json->_value._string.length - 1);

    case TRI_JSON_ARRAY: {
      size_t n;
      size_t i;
      mrb_value a;
      TRI_json_t* sub;
      mrb_value key;
      mrb_value val;

      n = json->_value._objects._length;
      a = mrb_hash_new_capa(mrb, n);

      for (i = 0;  i < n;  i += 2) {
        sub = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
 
        if (! TRI_IsStringJson(sub)) {
          continue;
        }

        key = mrb_str_new(mrb, sub->_value._string.data, sub->_value._string.length - 1);
        sub = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i + 1);
        val = MR_ObjectJson(mrb, sub);

        mrb_hash_set(mrb, a, key, val);
      }

      return a;
    }

    case TRI_JSON_LIST: {
      size_t n;
      size_t i;
      mrb_value a;
      TRI_json_t* elm;
      mrb_value val;

      n = json->_value._objects._length;
      a = mrb_ary_new_capa(mrb, n);

      for (i = 0;  i < n;  ++i) {
        elm = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
        val = MR_ObjectJson(mrb, elm);

        mrb_ary_set(mrb, a, i, val);
      }

      return a;
    }
  }

  return mrb_nil_value();
}
Пример #19
0
TRI_aql_node_t* TRI_JsonNodeAql (TRI_aql_context_t* const context,
                                 const TRI_json_t* const json) {
    TRI_aql_node_t* node = NULL;
    char* value;

    switch (json->_type) {
    case TRI_JSON_UNUSED:
        break;

    case TRI_JSON_NULL:
        node = TRI_CreateNodeValueNullAql(context);
        break;

    case TRI_JSON_BOOLEAN:
        node = TRI_CreateNodeValueBoolAql(context, json->_value._boolean);
        break;

    case TRI_JSON_NUMBER:
        node = TRI_CreateNodeValueDoubleAql(context, json->_value._number);
        break;

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE:
        // the conversion is the same for both...
        value = TRI_RegisterStringAql(context,
                                      json->_value._string.data,
                                      json->_value._string.length - 1,
                                      false);
        node = TRI_CreateNodeValueStringAql(context, value);
        break;

    case TRI_JSON_LIST: {
        node = TRI_CreateNodeListAql(context);

        if (node != NULL) {
            size_t i, n;

            n = json->_value._objects._length;

            for (i = 0; i < n; ++i) {
                TRI_json_t* subJson;
                TRI_aql_node_t* member;

                subJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
                member = TRI_JsonNodeAql(context, subJson);

                if (member) {
                    TRI_PushBackVectorPointer(&node->_members, (void*) member);
                }
                else {
                    TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
                    return NULL;
                }
            }
        }
        break;
    }
    case TRI_JSON_ARRAY: {
        node = TRI_CreateNodeArrayAql(context);

        if (node != NULL) {
            size_t i, n;

            n = json->_value._objects._length;

            for (i = 0; i < n; i += 2) {
                TRI_json_t* nameJson;
                TRI_json_t* valueJson;
                TRI_aql_node_t* member;
                TRI_aql_node_t* valueNode;
                char* name;

                // json_t containing the array element name
                nameJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);

                assert(TRI_IsStringJson(nameJson));
                name = TRI_RegisterStringAql(context,
                                             nameJson->_value._string.data,
                                             nameJson->_value._string.length - 1,
                                             false);
                if (name == NULL) {
                    TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
                    return NULL;
                }

                // json_t containing the array element value
                valueJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i + 1);
                assert(valueJson);

                valueNode = TRI_JsonNodeAql(context, valueJson);
                if (! valueNode) {
                    TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
                    return NULL;
                }

                member = TRI_CreateNodeArrayElementAql(context, name, valueNode);
                if (member) {
                    TRI_PushBackVectorPointer(&node->_members, (void*) member);
                }
                else {
                    TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
                    return NULL;
                }
            }
        }
        break;
    }
    }

    if (node == NULL) {
        TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
    }

    return node;
}