예제 #1
0
TRI_json_t* TRI_JsonReplicationApplier (TRI_replication_applier_t* applier) {
  TRI_replication_applier_state_t state;
  TRI_replication_applier_configuration_t config;
  TRI_json_t* server;
  TRI_json_t* json;
  int res;

  res = TRI_StateReplicationApplier(applier, &state);

  if (res != TRI_ERROR_NO_ERROR) {
    return NULL;
  }
    
  json = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);

  if (json == NULL) {
    TRI_DestroyStateReplicationApplier(&state);

    return NULL;
  }
  
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "state", JsonState(&state));
    
  // add server info
  server = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);

  if (server != NULL) {
    TRI_server_id_t serverId;

    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, server, "version", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, TRI_VERSION));

    serverId = TRI_GetIdServer();  
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, server, "serverId", TRI_CreateStringJson(TRI_CORE_MEM_ZONE, TRI_StringUInt64(serverId)));

    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "server", server);
  }
   
  TRI_InitConfigurationReplicationApplier(&config);

  TRI_ReadLockReadWriteLock(&applier->_statusLock);
  TRI_CopyConfigurationReplicationApplier(&applier->_configuration, &config);
  TRI_ReadUnlockReadWriteLock(&applier->_statusLock);

  if (config._endpoint != NULL) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "endpoint", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config._endpoint));
  }
  
  if (config._database != NULL) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "database", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config._database));
  }

  TRI_DestroyConfigurationReplicationApplier(&config);
  TRI_DestroyStateReplicationApplier(&state);

  return json;
}
예제 #2
0
static TRI_json_t* JsonGeo2Index (TRI_index_t const* idx) {
  TRI_json_t* json;
  TRI_json_t* fields;
  TRI_shape_path_t const* path;
  char const* latitude;
  char const* longitude;

  TRI_geo_index_t const* geo = (TRI_geo_index_t const*) idx;
  TRI_document_collection_t* document = idx->_collection;

  // convert latitude to string
  path = document->getShaper()->lookupAttributePathByPid(document->getShaper(), geo->_latitude);  // ONLY IN INDEX, PROTECTED by RUNTIME

  if (path == 0) {
    return nullptr;
  }

  latitude = TRI_NAME_SHAPE_PATH(path);

  // convert longitude to string
  path = document->getShaper()->lookupAttributePathByPid(document->getShaper(), geo->_longitude);  // ONLY IN INDEX, PROTECTED by RUNTIME

  if (path == 0) {
    return nullptr;
  }

  longitude = TRI_NAME_SHAPE_PATH(path);

  // create json
  json = TRI_JsonIndex(TRI_CORE_MEM_ZONE, idx);

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

  // "constraint" and "unique" are identical for geo indexes.
  // we return "constraint" just for downwards-compatibility
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "constraint", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, idx->_unique));

  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "ignoreNull", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, geo->base._ignoreNull));

  fields = TRI_CreateListJson(TRI_CORE_MEM_ZONE);
  TRI_PushBack3ListJson(TRI_CORE_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, latitude));
  TRI_PushBack3ListJson(TRI_CORE_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, longitude));
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "fields", fields);

  return json;
}
예제 #3
0
static inline TRI_json_t* GetRowProtoType (TRI_aql_explain_t* const explain,
                                           const TRI_aql_node_type_e type) {
  TRI_json_t* row;

  row = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);

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

  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                       row,
                       "id",
                       TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) ++explain->_count));

  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                       row,
                       "loopLevel",
                       TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) explain->_level));

  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                       row,
                       "type",
                       TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, TRI_NodeNameAql(type)));

  return row;
}
예제 #4
0
TRI_json_t* TraditionalKeyGenerator::toJson (TRI_memory_zone_t* zone) const {
  TRI_json_t* json = TRI_CreateArrayJson(zone);

  if (json != nullptr) {
    TRI_Insert3ArrayJson(zone, json, "type", TRI_CreateStringCopyJson(zone, name().c_str()));
    TRI_Insert3ArrayJson(zone, json, "allowUserKeys", TRI_CreateBooleanJson(zone, _allowUserKeys));
  }

  return json;
}
예제 #5
0
TRI_json_t* AutoIncrementKeyGenerator::toJson (TRI_memory_zone_t* zone) const {
  TRI_json_t* json = TRI_CreateArrayJson(zone);

  if (json != nullptr) {
    TRI_Insert3ArrayJson(zone, json, "type", TRI_CreateStringCopyJson(zone, name().c_str()));
    TRI_Insert3ArrayJson(zone, json, "allowUserKeys", TRI_CreateBooleanJson(zone, _allowUserKeys));
    TRI_Insert3ArrayJson(zone, json, "offset", TRI_CreateNumberJson(zone, (double) _offset));
    TRI_Insert3ArrayJson(zone, json, "increment", TRI_CreateNumberJson(zone, (double) _increment));
  }

  return json;
}
예제 #6
0
static TRI_json_t* NodeDescription (const TRI_aql_node_t* const node) {
  TRI_string_buffer_t buffer;
  TRI_json_t* result;

  assert(node);

  TRI_InitStringBuffer(&buffer, TRI_UNKNOWN_MEM_ZONE);
  
  TRI_NodeStringAql(&buffer, node);

  result = TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, buffer._buffer);
  TRI_DestroyStringBuffer(&buffer);

  return result;
}
예제 #7
0
static TRI_json_t* NodeType (const TRI_aql_node_t* const node) {
  TRI_json_t* result;
  TRI_string_buffer_t buffer;

  assert(node);
  
  TRI_InitStringBuffer(&buffer, TRI_UNKNOWN_MEM_ZONE);

  TRI_AppendStringStringBuffer(&buffer, TRI_NodeGroupAql(node, true));

  result = TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, buffer._buffer);
  
  TRI_DestroyStringBuffer(&buffer);

  return result;
}
예제 #8
0
static TRI_json_t* TraditionalToJson (const TRI_key_generator_t* const generator) {
  TRI_json_t* json;

  traditional_keygen_t* data;
  data = (traditional_keygen_t*) generator->_data;
  assert(data != NULL);

  json = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);

  if (json != NULL) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "type", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, TraditionalName));
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "allowUserKeys", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, data->_allowUserKeys));
  }

  return json;
}
예제 #9
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;
}
예제 #10
0
static TRI_json_t* AutoIncrementToJson (const TRI_key_generator_t* const generator) {
  TRI_json_t* json;

  autoincrement_keygen_t* data;
  data = (autoincrement_keygen_t*) generator->_data;
  assert(data != NULL);

  json = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);

  if (json != NULL) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "type", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, AutoIncrementName));
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "allowUserKeys", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, data->_allowUserKeys));
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "offset", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) data->_offset));
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "increment", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) data->_increment));
  }

  return json;
}
예제 #11
0
static TRI_json_t* JsonHashIndex (TRI_index_t* idx,
                                  TRI_primary_collection_t const* primary) {
  TRI_json_t* json;
  TRI_json_t* fields;
  TRI_hash_index_t* hashIndex;
  char const** fieldList;
  size_t j;

  // .............................................................................
  // Recast as a hash index
  // .............................................................................

  hashIndex = (TRI_hash_index_t*) idx;

  // .............................................................................
  // Allocate sufficent memory for the field list
  // .............................................................................

  fieldList = TRI_FieldListByPathList(primary->_shaper, &hashIndex->_paths);

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

  // ..........................................................................
  // create json object and fill it
  // ..........................................................................

  json = TRI_JsonIndex(TRI_CORE_MEM_ZONE, idx);

  fields = TRI_CreateListJson(TRI_CORE_MEM_ZONE);
  for (j = 0; j < hashIndex->_paths._length; ++j) {
    TRI_PushBack3ListJson(TRI_CORE_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, fieldList[j]));
  }
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "fields", fields);

  TRI_Free(TRI_CORE_MEM_ZONE, fieldList);

  return json;
}
예제 #12
0
TRI_json_t* TRI_NodeJsonAql (TRI_aql_context_t* const context,
                             const TRI_aql_node_t* const node) {
  switch (node->_type) {
    case TRI_AQL_NODE_VALUE: {
      switch (node->_value._type) {
        case TRI_AQL_TYPE_FAIL:
        case TRI_AQL_TYPE_NULL:
          return TRI_CreateNullJson(TRI_UNKNOWN_MEM_ZONE);
        case TRI_AQL_TYPE_BOOL:
          return TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._bool);
        case TRI_AQL_TYPE_INT:
          return TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) node->_value._value._int);
        case TRI_AQL_TYPE_DOUBLE:
          return TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._double);
        case TRI_AQL_TYPE_STRING:
          return TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._string);
      }
    }
    case TRI_AQL_NODE_LIST: {
      TRI_json_t* result = TRI_CreateListJson(TRI_UNKNOWN_MEM_ZONE);

      if (result) {
        size_t i, n;

        n = node->_members._length;
        for (i = 0; i < n; ++i) {
          TRI_json_t* subValue = TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(node, i));

          if (subValue) {
            TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, result, subValue);
          }
        }
      }
      return result;
    }
    case TRI_AQL_NODE_ARRAY: {
      TRI_json_t* result = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);

      if (result) {
        size_t i, n;

        n = node->_members._length;
        for (i = 0; i < n; ++i) {
          TRI_aql_node_t* element = TRI_AQL_NODE_MEMBER(node, i);
          TRI_json_t* subValue = TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(element, 0));

          if (subValue) {
            TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                                 result,
                                 TRI_AQL_NODE_STRING(element),
                                 subValue);
          }
        }
      }
      return result;
    }
    default: {
      return NULL;
    }
  }
}
예제 #13
0
static TRI_json_t* JsonState (TRI_replication_applier_state_t const* state) {
  TRI_json_t* json;
  TRI_json_t* last;
  TRI_json_t* progress;
  TRI_json_t* error;
  char* lastString;
  char timeString[24];
  
  json = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 9);

  // add replication state
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "running", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, state->_active));
 
  // lastAppliedContinuousTick 
  if (state->_lastAppliedContinuousTick > 0) {
    lastString = TRI_StringUInt64(state->_lastAppliedContinuousTick);
    last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString);
  }
  else {
    last = TRI_CreateNullJson(TRI_CORE_MEM_ZONE);
  }
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastAppliedContinuousTick", last);
  
  // lastProcessedContinuousTick 
  if (state->_lastProcessedContinuousTick > 0) {
    lastString = TRI_StringUInt64(state->_lastProcessedContinuousTick);
    last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString);
  }
  else {
    last = TRI_CreateNullJson(TRI_CORE_MEM_ZONE);
  }
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastProcessedContinuousTick", last);
  
  // lastAvailableContinuousTick 
  if (state->_lastAvailableContinuousTick > 0) {
    lastString = TRI_StringUInt64(state->_lastAvailableContinuousTick);
    last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString);
  }
  else {
    last = TRI_CreateNullJson(TRI_CORE_MEM_ZONE);
  }
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastAvailableContinuousTick", last);
  
  // progress
  progress = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 2);
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, progress, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_progressTime));

  if (state->_progressMsg != NULL) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, progress, "message", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_progressMsg));
  }
  
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, progress, "failedConnects", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_failedConnects));

  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "progress", progress); 
  
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "totalRequests", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_totalRequests));
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "totalFailedConnects", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_totalFailedConnects));
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "totalEvents", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_totalEvents));

  // lastError
  error = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);

  if (error != NULL) {
    if (state->_lastError._code > 0) {
      TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_lastError._time));
 
      if (state->_lastError._msg != NULL) {
        TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "errorMessage", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_lastError._msg));
      }
    }

    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "errorNum", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_lastError._code));
  
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastError", error);
  }
  
  TRI_GetTimeStampReplication(timeString, sizeof(timeString) - 1);
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, timeString));
  
  return json;
}
예제 #14
0
static TRI_json_t* JsonConfiguration (TRI_replication_applier_configuration_t const* config,
                                      bool includePassword) {
  TRI_json_t* json;

  json = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 9);

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

  if (config->_endpoint != NULL) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                         json, 
                         "endpoint", 
                         TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_endpoint));
  }
  
  if (config->_database != NULL) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                         json, 
                         "database", 
                         TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_database));
  }
  
  if (config->_username != NULL) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                         json, 
                         "username", 
                         TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_username));
  }
  
  if (config->_password != NULL && includePassword) {
    TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                         json, 
                         "password", 
                         TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_password));
  }

  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                       json, 
                       "requestTimeout", 
                       TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, config->_requestTimeout));
  
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                       json, 
                       "connectTimeout", 
                       TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, config->_connectTimeout));

/* TODO: decide about the fate of this...
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                       json, 
                       "ignoreErrors", 
                       TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) config->_ignoreErrors));
*/
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                       json, 
                       "maxConnectRetries", 
                       TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) config->_maxConnectRetries));
  
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                       json, 
                       "chunkSize", 
                       TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) config->_chunkSize));
  
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                       json, 
                       "autoStart",
                       TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, config->_autoStart));
  
  TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, 
                       json, 
                       "adaptivePolling",
                       TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, config->_adaptivePolling));

  return json;
}
예제 #15
0
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();
}
예제 #16
0
static TRI_aql_node_t* ProcessStatement (TRI_aql_statement_walker_t* const walker,
                                         TRI_aql_node_t* node) {
  TRI_aql_explain_t* explain;
  TRI_aql_node_type_e type = node->_type;

  explain = (TRI_aql_explain_t*) walker->_data;

  switch (type) {
    case TRI_AQL_NODE_SCOPE_START: {
      TRI_aql_scope_t* scope = (TRI_aql_scope_t*) TRI_AQL_NODE_DATA(node);

      assert(scope);

      if (scope->_type != TRI_AQL_SCOPE_SUBQUERY && scope->_type != TRI_AQL_SCOPE_MAIN) {
        ++explain->_level;
      }
      break;
    }

    case TRI_AQL_NODE_SCOPE_END: {
      TRI_aql_scope_t* scope = (TRI_aql_scope_t*) TRI_AQL_NODE_DATA(node);

      assert(scope);
      if (scope->_type != TRI_AQL_SCOPE_SUBQUERY && scope->_type != TRI_AQL_SCOPE_MAIN) {
        --explain->_level;
      }
      break;
    }

    case TRI_AQL_NODE_EXPAND: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, TRI_AQL_NODE_REFERENCE);

      if (row != NULL) {
        TRI_aql_node_t* variableNode = TRI_AQL_NODE_MEMBER(node, 0);

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             row,
                             "resultVariable",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, TRI_AQL_NODE_STRING(variableNode)));

        AddNodeValue(row, TRI_AQL_NODE_MEMBER(node, 2));
        AddRow(explain, row);
      }

      row = GetRowProtoType(explain, TRI_AQL_NODE_EXPAND);

      if (row != NULL) {
        TRI_aql_node_t* variableNode = TRI_AQL_NODE_MEMBER(node, 1);

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             row,
                             "resultVariable",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, TRI_AQL_NODE_STRING(variableNode)));

        AddNodeValue(row, TRI_AQL_NODE_MEMBER(node, 3));
        AddRow(explain, row);
      }
      break;
    }

    case TRI_AQL_NODE_SUBQUERY: 
    case TRI_AQL_NODE_SUBQUERY_CACHED: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, node->_type);

      if (row != NULL) {
        TRI_aql_node_t* variableNode = TRI_AQL_NODE_MEMBER(node, 0);

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             row,
                             "resultVariable",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, TRI_AQL_NODE_STRING(variableNode)));

        AddRow(explain, row);
      }
      break;
    }

    case TRI_AQL_NODE_FOR: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, node->_type);
      
      if (row != NULL) {
        TRI_aql_node_t* variableNode = TRI_AQL_NODE_MEMBER(node, 0);
        TRI_aql_node_t* expressionNode = TRI_AQL_NODE_MEMBER(node, 1);
        TRI_aql_for_hint_t* hint;

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             row,
                             "resultVariable",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, TRI_AQL_NODE_STRING(variableNode)));

        hint = TRI_AQL_NODE_DATA(node);
        if (hint != NULL &&
            hint->_limit._status == TRI_AQL_LIMIT_USE) {
          TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                               row,
                               "limit",
                               TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, true));
        }

        AddNodeValue(row, expressionNode);
        AddRow(explain, row);
      }
      break;
    }

    case TRI_AQL_NODE_RETURN:
    case TRI_AQL_NODE_RETURN_EMPTY: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, node->_type);

      if (row != NULL) {
        TRI_aql_node_t* expressionNode = TRI_AQL_NODE_MEMBER(node, 0);

        AddNodeValue(row, expressionNode);
        AddRow(explain, row);
      }
      break;
    }

    case TRI_AQL_NODE_FILTER: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, node->_type);

      if (row != NULL) {
        TRI_aql_node_t* expressionNode = TRI_AQL_NODE_MEMBER(node, 0);

        AddNodeValue(row, expressionNode);
        AddRow(explain, row);
      }
      break;
    }

    case TRI_AQL_NODE_LET: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, node->_type);

      if (row != NULL) {
        TRI_aql_node_t* variableNode = TRI_AQL_NODE_MEMBER(node, 0);
        TRI_aql_node_t* expressionNode = TRI_AQL_NODE_MEMBER(node, 1);

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             row,
                             "resultVariable",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, TRI_AQL_NODE_STRING(variableNode)));

        AddNodeValue(row, expressionNode);
        AddRow(explain, row);
      }
      break;
    }

    case TRI_AQL_NODE_SORT: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, node->_type);

      if (row != NULL) {
        TRI_aql_node_t* listNode = TRI_AQL_NODE_MEMBER(node, 0);

        AddNodeValue(row, listNode);
        AddRow(explain, row);
      }
      break;
    }

    case TRI_AQL_NODE_LIMIT: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, node->_type);

      if (row != NULL) {
        TRI_aql_node_t* offsetNode = TRI_AQL_NODE_MEMBER(node, 0);
        TRI_aql_node_t* countNode  = TRI_AQL_NODE_MEMBER(node, 1);

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             row,
                             "offset",
                             TRI_NodeJsonAql(explain->_context, offsetNode));

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             row,
                             "count",
                             TRI_NodeJsonAql(explain->_context, countNode));

        AddRow(explain, row);
      }
      break;
    }

    case TRI_AQL_NODE_COLLECT: {
      TRI_json_t* row;

      row = GetRowProtoType(explain, node->_type);

      if (row != NULL) {
        TRI_aql_node_t* listNode = TRI_AQL_NODE_MEMBER(node, 0);

        if (node->_members._length > 1) {
          TRI_aql_node_t* variableNode = TRI_AQL_NODE_MEMBER(node, 1);
  
          TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                               row,
                               "resultVariable",
                               TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, TRI_AQL_NODE_STRING(variableNode)));
        }

        AddNodeValue(row, listNode);
        AddRow(explain, row);
      }
      break;
    }

    default: {
    }
  }

  return NULL;
}
예제 #17
0
TRI_json_t* TRI_GetJsonCollectionHintAql (TRI_aql_collection_hint_t* const hint) {
  TRI_json_t* result;

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

  result = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);

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

  if (hint->_index == NULL) {
    // full table scan
    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                         result,
                         "accessType",
                         TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, "all"));
  }
  else {
    // index usage
    TRI_index_t* idx = hint->_index->_idx;
    TRI_json_t* indexDescription;

    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                         result,
                         "accessType",
                         TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, "index"));

    indexDescription = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);
    if (indexDescription != NULL) {
      TRI_string_buffer_t* buffer;
      char* idString = GetIndexIdString(hint);

      // index id
      if (idString != NULL) {
        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             indexDescription,
                             "id",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, idString));

        TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, idString);
      }

      // index type
      TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                           indexDescription,
                           "type",
                           TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, idx->typeName(idx)));

      // index attributes
      buffer = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);
      if (buffer != NULL) {
        size_t i;

        for (i = 0; i < idx->_fields._length; i++) {
          if (i > 0) {
            TRI_AppendStringStringBuffer(buffer, ", ");
          }
          TRI_AppendStringStringBuffer(buffer, idx->_fields._buffer[i]);
        }

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             indexDescription,
                             "attributes",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, buffer->_buffer));

        TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
      }

    }

    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                         result,
                         "index",
                         indexDescription);
  }

  if (hint->_limit._status == TRI_AQL_LIMIT_USE) {
    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                         result,
                         "limit",
                         TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) hint->_limit._offset + (double) hint->_limit._limit));
  }

  return result;
}