Exemplo n.º 1
0
static int AutoIncrementInit (TRI_key_generator_t* const generator,
                              const TRI_json_t* const options) {
  autoincrement_keygen_t* data;

  data = (autoincrement_keygen_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(autoincrement_keygen_t), false);

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

  // defaults
  data->_allowUserKeys = true;
  data->_lastValue     = 0;
  data->_offset        = 0;
  data->_increment     = 1;

  if (options != NULL) {
    TRI_json_t* option;

    option = TRI_LookupArrayJson(options, "allowUserKeys");
    if (option != NULL && option->_type == TRI_JSON_BOOLEAN) {
      data->_allowUserKeys = option->_value._boolean;
    }

    option = TRI_LookupArrayJson(options, "increment");
    if (option != NULL && option->_type == TRI_JSON_NUMBER) {
      data->_increment = (uint64_t) option->_value._number;
      if (data->_increment == 0 || data->_increment >= AUTOINCREMENT_MAX_INCREMENT) {
        TRI_Free(TRI_UNKNOWN_MEM_ZONE, data);

        return TRI_ERROR_ARANGO_INVALID_KEY_GENERATOR;
      }
    }

    option = TRI_LookupArrayJson(options, "offset");
    if (option != NULL && option->_type == TRI_JSON_NUMBER) {
      data->_offset = (uint64_t) option->_value._number;
      if (data->_offset >= AUTOINCREMENT_MAX_OFFSET) {
        TRI_Free(TRI_UNKNOWN_MEM_ZONE, data);

        return TRI_ERROR_ARANGO_INVALID_KEY_GENERATOR;
      }
    }
  }

  generator->_data = (void*) data;

  LOG_TRACE("created autoincrement key-generator with options (allowUserKeys: %d, increment: %llu, offset: %llu)",
            (int) data->_allowUserKeys,
            (unsigned long long) data->_increment,
            (unsigned long long) data->_offset);

  return TRI_ERROR_NO_ERROR;
}
Exemplo n.º 2
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;
    }
Exemplo n.º 3
0
uint64_t TRI_HashJsonByAttributes (TRI_json_t const* json,
                                   char const *attributes[],
                                   int nrAttributes,
                                   bool docComplete,
                                   int* error) {
  uint64_t hash;

  if (NULL != error) {
    *error = TRI_ERROR_NO_ERROR;
  }
  hash = TRI_FnvHashBlockInitial();
  if (TRI_IsArrayJson(json)) {
    int i;

    for (i = 0; i < nrAttributes; i++) {
      TRI_json_t const* subjson = TRI_LookupArrayJson(json, attributes[i]);

      if (NULL == subjson && !docComplete && NULL != error) {
        *error = TRI_ERROR_CLUSTER_NOT_ALL_SHARDING_ATTRIBUTES_GIVEN;
      }
      hash = HashJsonRecursive(hash, subjson);
    }
  }
  return hash;
}
Exemplo n.º 4
0
static int TraditionalInit (TRI_key_generator_t* const generator,
                            const TRI_json_t* const options) {
  traditional_keygen_t* data;

  data = (traditional_keygen_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(traditional_keygen_t), false);

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

  // defaults
  data->_allowUserKeys = true;

  if (options != NULL) {
    TRI_json_t* option;

    option = TRI_LookupArrayJson(options, "allowUserKeys");
    if (option != NULL && option->_type == TRI_JSON_BOOLEAN) {
      data->_allowUserKeys = option->_value._boolean;
    }
  }

  generator->_data = (void*) data;

  LOG_TRACE("created traditional key-generator with options (allowUserKeys: %d)",
            (int) data->_allowUserKeys);

  return TRI_ERROR_NO_ERROR;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
void TRI_FromJsonVocBaseDefaults (TRI_vocbase_defaults_t* defaults,
                                  TRI_json_t const* json) {
    TRI_json_t* optionJson;

    if (! TRI_IsArrayJson(json)) {
        return;
    }

    optionJson = TRI_LookupArrayJson(json, "removeOnDrop");

    if (TRI_IsBooleanJson(optionJson)) {
        defaults->removeOnDrop = optionJson->_value._boolean;
    }

    optionJson = TRI_LookupArrayJson(json, "removeOnCompacted");

    if (TRI_IsBooleanJson(optionJson)) {
        defaults->removeOnCompacted = optionJson->_value._boolean;
    }

    optionJson = TRI_LookupArrayJson(json, "waitForSync");

    if (TRI_IsBooleanJson(optionJson)) {
        defaults->defaultWaitForSync = optionJson->_value._boolean;
    }

    optionJson = TRI_LookupArrayJson(json, "forceSyncShapes");

    if (TRI_IsBooleanJson(optionJson)) {
        defaults->forceSyncShapes = optionJson->_value._boolean;
    }

    optionJson = TRI_LookupArrayJson(json, "forceSyncProperties");

    if (TRI_IsBooleanJson(optionJson)) {
        defaults->forceSyncProperties = optionJson->_value._boolean;
    }

    optionJson = TRI_LookupArrayJson(json, "requireAuthentication");

    if (TRI_IsBooleanJson(optionJson)) {
        defaults->requireAuthentication = optionJson->_value._boolean;
    }

    optionJson = TRI_LookupArrayJson(json, "authenticateSystemOnly");

    if (TRI_IsBooleanJson(optionJson)) {
        defaults->authenticateSystemOnly = optionJson->_value._boolean;
    }

    optionJson = TRI_LookupArrayJson(json, "defaultMaximalSize");

    if (TRI_IsNumberJson(optionJson)) {
        defaults->defaultMaximalSize = (TRI_voc_size_t) optionJson->_value._number;
    }
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
static TRI_doc_mptr_t CreateJson (TRI_doc_collection_t* collection,
                                  TRI_df_marker_type_e type,
                                  TRI_json_t const* json,
                                  void const* data,
                                  bool reuseId,
                                  bool release) {
  TRI_shaped_json_t* shaped;
  TRI_doc_mptr_t result;
  TRI_voc_did_t did = 0;
  TRI_voc_rid_t rid = 0;
 
  shaped = TRI_ShapedJsonJson(collection->_shaper, json);

  if (shaped == 0) {
    collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED);
    memset(&result, 0, sizeof(result));
    return result;
  }
  
  if (reuseId && json != NULL && json->_type == TRI_JSON_ARRAY) {
    TRI_json_t* id = TRI_LookupArrayJson((TRI_json_t*) json, "_id");
    TRI_json_t* rev = TRI_LookupArrayJson((TRI_json_t*) json, "_rev");

    if (id != NULL && id->_type == TRI_JSON_NUMBER && 
        rev != NULL && rev->_type == TRI_JSON_NUMBER) {
      // read existing document id and revision id from document
      did = (TRI_voc_did_t) id->_value._number;
      rid = (TRI_voc_rid_t) rev->_value._number;
    }
  }

  result = collection->create(collection, type, shaped, data, did, rid, release);

  TRI_FreeShapedJson(collection->_shaper, shaped);

  return result;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
double TRI_ToDoubleJson (TRI_json_t const* json, bool& failed) {
  TRI_ASSERT(json != nullptr);
  failed = false;
  switch (json->_type) {
    case TRI_JSON_UNUSED:
    case TRI_JSON_NULL:
      return 0.0;
    case TRI_JSON_BOOLEAN:
      return (json->_value._boolean ? 1.0 : 0.0);
    case TRI_JSON_NUMBER:
      return json->_value._number;
    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE:
      try {
        // try converting string to number
        double v = std::stod(json->_value._string.data);
        return v;
      }
      catch (...) {
        if (strlen(json->_value._string.data) == 0) {
          return 0.0;
        }
        // conversion failed
      }
      break;
    case TRI_JSON_ARRAY: {
      size_t const n = TRI_LengthArrayJson(json);

      if (n == 0) {
        return 0.0;
      }
      else if (n == 1) {
        return TRI_ToDoubleJson(TRI_LookupArrayJson(json, 0), failed);
      }
      break;
    }
    case TRI_JSON_OBJECT:
      break;
  }

  failed = true;
  // TODO: must convert to null here
  return 0.0;
}
Exemplo n.º 11
0
int64_t TRI_ToInt64Json (TRI_json_t const* json) {
  TRI_ASSERT(json != nullptr);
  switch (json->_type) {
    case TRI_JSON_UNUSED:
    case TRI_JSON_NULL:
      return 0;
    case TRI_JSON_BOOLEAN:
      return (json->_value._boolean ? 1 : 0);
    case TRI_JSON_NUMBER:
      return static_cast<int64_t>(json->_value._number);
    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE:
      try {
        // try converting string to number
        double v = std::stod(json->_value._string.data);
        return static_cast<int64_t>(v);
      }
      catch (...) {
        // conversion failed
      }
      break;
    case TRI_JSON_ARRAY: {
      size_t const n = TRI_LengthArrayJson(json);

      if (n == 0) {
        return 0;
      }
      else if (n == 1) {
        return TRI_ToInt64Json(TRI_LookupArrayJson(json, 0));
      }
      break;
    }
    case TRI_JSON_OBJECT:
      break;
  }
  
  // TODO: must convert to null here
  return 0;
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
DocumentAccessor& DocumentAccessor::at (int64_t index) {
  if (isArray()) {
    size_t length = TRI_LengthArrayJson(_current);

    if (index < 0) {
      // a negative position is allowed
      index = static_cast<int64_t>(length) + index; 
    }

    if (index >= 0 && index < static_cast<int64_t>(length)) {
      // only look up the value if it is within array bounds
      TRI_json_t const* found = TRI_LookupArrayJson(_current, static_cast<size_t>(index));

      if (found != nullptr) {
        _current = found;
        return *this;
      }
    }
    // fall-through intentional
  }

  setToNull();
  return *this;
}
Exemplo n.º 14
0
static int TraditionalInit (TRI_key_generator_t* const generator,
                            const TRI_json_t* const options) {
  traditional_keygen_t* data;

  data = (traditional_keygen_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(traditional_keygen_t), false);
  if (data == NULL) {
    return TRI_ERROR_OUT_OF_MEMORY;
  }

  // defaults
  data->_allowUserKeys = true;

  // compile regex for key validation
  if (regcomp(&data->_regex, "^(" TRI_VOC_KEY_REGEX ")$", REG_EXTENDED | REG_NOSUB) != 0) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, data);
    LOG_ERROR("cannot compile regular expression");

    return TRI_ERROR_INTERNAL;
  }

  if (options != NULL) {
    TRI_json_t* option;

    option = TRI_LookupArrayJson(options, "allowUserKeys");
    if (option != NULL && option->_type == TRI_JSON_BOOLEAN) {
      data->_allowUserKeys = option->_value._boolean;
    }
  }

  generator->_data = (void*) data;

  LOG_TRACE("created traditional key-generator with options (allowUserKeys: %d)",
            (int) data->_allowUserKeys);

  return TRI_ERROR_NO_ERROR;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
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:
      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 n;
      size_t i;

      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;
          
      assert(lhs->_type == TRI_JSON_ARRAY);
      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);
          assert(keyElement->_type == TRI_JSON_STRING);
          assert(keyElement->_value._string.data);

          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;
  }
}
Exemplo n.º 18
0
KeyGenerator* KeyGenerator::factory (TRI_json_t const* options) {
  KeyGenerator::GeneratorType type;

  bool const readOptions = TRI_IsArrayJson(options);

  if (readOptions) {
    type = generatorType(options);
  }
  else {
    type = TYPE_TRADITIONAL;
  }

  if (type == TYPE_UNKNOWN) {
    return nullptr;
  }

  bool allowUserKeys = true;

  if (readOptions) {
    TRI_json_t* option = TRI_LookupArrayJson(options, "allowUserKeys");

    if (TRI_IsBooleanJson(option)) {
      allowUserKeys = option->_value._boolean;
    }
  }

  if (type == TYPE_TRADITIONAL) {
    return new TraditionalKeyGenerator(allowUserKeys);
  }

  else if (type == TYPE_AUTOINCREMENT) {
    uint64_t offset = 0;
    uint64_t increment = 1;

    if (readOptions) {
      TRI_json_t* option;

      option = TRI_LookupArrayJson(options, "increment");

      if (TRI_IsNumberJson(option)) {
        increment = (uint64_t) option->_value._number;

        if (increment == 0 || increment >= (1ULL << 16)) {
          return nullptr;
        }
      }
    
      option = TRI_LookupArrayJson(options, "offset");

      if (TRI_IsNumberJson(option)) {
        offset = (uint64_t) option->_value._number;

        if (offset >= UINT64_MAX) {
          return nullptr;
        }
      }
    }

    return new AutoIncrementKeyGenerator(allowUserKeys, offset, increment);
  }

  return nullptr;
}
Exemplo n.º 19
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;
    }
Exemplo n.º 20
0
static int AutoIncrementInit (TRI_key_generator_t* const generator,
                              const TRI_json_t* const options) {
  autoincrement_keygen_t* data;

  data = (autoincrement_keygen_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(autoincrement_keygen_t), false);
  if (data == NULL) {
    return TRI_ERROR_OUT_OF_MEMORY;
  }

  // defaults
  data->_allowUserKeys = true;
  data->_lastValue     = 0;
  data->_offset        = 0;
  data->_increment     = 1;

  // compile regex for key validation
  if (regcomp(&data->_regex, "^(" TRI_VOC_ID_REGEX ")$", REG_EXTENDED | REG_NOSUB) != 0) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, data);
    LOG_ERROR("cannot compile regular expression");

    return TRI_ERROR_INTERNAL;
  }

  if (options != NULL) {
    TRI_json_t* option;

    option = TRI_LookupArrayJson(options, "allowUserKeys");
    if (option != NULL && option->_type == TRI_JSON_BOOLEAN) {
      data->_allowUserKeys = option->_value._boolean;
    }

    option = TRI_LookupArrayJson(options, "increment");
    if (option != NULL && option->_type == TRI_JSON_NUMBER) {
      data->_increment = (uint64_t) option->_value._number;
      if (data->_increment == 0 || data->_increment >= AUTOINCREMENT_MAX_INCREMENT) {
        regfree(&data->_regex);
        TRI_Free(TRI_UNKNOWN_MEM_ZONE, data);

        return TRI_ERROR_BAD_PARAMETER;
      }
    }

    option = TRI_LookupArrayJson(options, "offset");
    if (option != NULL && option->_type == TRI_JSON_NUMBER) {
      data->_offset = (uint64_t) option->_value._number;
      if (data->_offset >= AUTOINCREMENT_MAX_OFFSET) {
        regfree(&data->_regex);
        TRI_Free(TRI_UNKNOWN_MEM_ZONE, data);

        return TRI_ERROR_BAD_PARAMETER;
      }
    }
  }

  generator->_data = (void*) data;

  LOG_TRACE("created autoincrement key-generator with options (allowUserKeys: %d, increment: %llu, offset: %llu)",
            (int) data->_allowUserKeys,
            (unsigned long long) data->_increment,
            (unsigned long long) data->_offset);

  return TRI_ERROR_NO_ERROR;
}
Exemplo n.º 21
0
static bool isEqualJson(TRI_json_t* left, TRI_json_t* right) {

    if (left == NULL && right == NULL) {
        return true;
    }

    if (left == NULL || right == NULL) {
        return false;
    }

    if (left->_type != right->_type) {
        return false;
    }

    switch (left->_type) {

    case TRI_JSON_UNUSED: {
        return true;
    }

    case TRI_JSON_NULL: {
        return true;
    }

    case TRI_JSON_BOOLEAN: {
        return (left->_value._boolean == right->_value._boolean);
    }

    case TRI_JSON_NUMBER: {
        return (left->_value._number == right->_value._number);
    }

    case TRI_JSON_STRING: {
        return (strcmp(left->_value._string.data, right->_value._string.data) == 0);
    }

    case TRI_JSON_ARRAY: {
        int j;

        if (left->_value._objects._length != right->_value._objects._length) {
            return false;
        }

        for (j = 0; j < (left->_value._objects._length / 2); ++j) {
            TRI_json_t* leftName;
            TRI_json_t* leftValue;
            TRI_json_t* rightValue;

            leftName = (TRI_json_t*)(TRI_AtVector(&(left->_value._objects),2*j));
            if (leftName == NULL) {
                return false;
            }

            leftValue  = (TRI_json_t*)(TRI_AtVector(&(left->_value._objects),(2*j) + 1));
            rightValue = TRI_LookupArrayJson(right, leftName->_value._string.data);

            if (isEqualJson(leftValue, rightValue)) {
                continue;
            }
            return false;
        }

        return true;
    }

    case TRI_JSON_LIST: {
        int j;

        if (left->_value._objects._length != right->_value._objects._length) {
            return false;
        }

        for (j = 0; j < left->_value._objects._length; ++j) {
            TRI_json_t* subLeft;
            TRI_json_t* subRight;
            subLeft  = (TRI_json_t*)(TRI_AtVector(&(left->_value._objects),j));
            subRight = (TRI_json_t*)(TRI_AtVector(&(right->_value._objects),j));
            if (isEqualJson(subLeft, subRight)) {
                continue;
            }
            return false;
        }

        return true;
    }

    default: {
        assert(false);
    }
    }

    return false; // shut the vc++ up
}