uint64_t VelocyPackHelper::hashByAttributes( VPackSlice slice, std::vector<std::string> const& attributes, bool docComplete, int& error, std::string const& key) { uint64_t hash = TRI_FnvHashBlockInitial(); error = TRI_ERROR_NO_ERROR; slice = slice.resolveExternal(); if (slice.isObject()) { for (auto const& attr : attributes) { VPackSlice sub = slice.get(attr).resolveExternal(); if (sub.isNone()) { if (attr == StaticStrings::KeyString && !key.empty()) { VPackBuilder temporaryBuilder; temporaryBuilder.add(VPackValue(key)); hash = temporaryBuilder.slice().normalizedHash(hash); continue; } if (!docComplete) { error = TRI_ERROR_CLUSTER_NOT_ALL_SHARDING_ATTRIBUTES_GIVEN; } // Null is equal to None/not present sub = VPackSlice::nullSlice(); } hash = sub.normalizedHash(hash); } } return hash; }
void arangodb::traverser::ShortestPath::vertexToVelocyPack(Transaction* trx, ManagedDocumentResult* mmdr, size_t position, VPackBuilder& builder) { TRI_ASSERT(position < length()); VPackSlice v = _vertices[position]; TRI_ASSERT(v.isString()); std::string collection = v.copyString(); size_t p = collection.find("/"); TRI_ASSERT(p != std::string::npos); TransactionBuilderLeaser searchBuilder(trx); searchBuilder->add(VPackValue(collection.substr(p + 1))); collection = collection.substr(0, p); int res = trx->documentFastPath(collection, mmdr, searchBuilder->slice(), builder, true); if (res != TRI_ERROR_NO_ERROR) { builder.clear(); // Just in case... builder.add(basics::VelocyPackHelper::NullValue()); } }
void VelocyPackHelper::SanitizeExternals(VPackSlice const input, VPackBuilder& output) { if (input.isExternal()) { output.add(input.resolveExternal()); } else if (input.isObject()) { output.openObject(); for (auto const& it : VPackObjectIterator(input)) { output.add(VPackValue(it.key.copyString())); SanitizeExternals(it.value, output); } output.close(); } else if (input.isArray()) { output.openArray(); for (auto const& it : VPackArrayIterator(input)) { SanitizeExternals(it, output); } output.close(); } else { output.add(input); } }
void arangodb::traverser::TraverserOptions::LookupInfo::buildEngineInfo( VPackBuilder& result) const { result.openObject(); result.add(VPackValue("handle")); // We only run toVelocyPack on Coordinator. TRI_ASSERT(idxHandles.size() == 1); result.openObject(); idxHandles[0].toVelocyPack(result, false); result.close(); result.add(VPackValue("expression")); result.openObject(); // We need to encapsulate the expression into an expression object result.add(VPackValue("expression")); expression->toVelocyPack(result, true); result.close(); result.add(VPackValue("condition")); indexCondition->toVelocyPack(result, true); result.add("condNeedUpdate", VPackValue(conditionNeedUpdate)); result.add("condMemberToUpdate", VPackValue(conditionMemberToUpdate)); result.close(); }
static int V8ToVPack(BuilderContext& context, v8::Handle<v8::Value> const parameter, std::string const& attributeName, bool inObject) { if (parameter->IsNull() || parameter->IsUndefined()) { AddValue(context, attributeName, inObject, VPackValue(VPackValueType::Null)); return TRI_ERROR_NO_ERROR; } if (parameter->IsBoolean()) { AddValue(context, attributeName, inObject, VPackValue(parameter->ToBoolean()->Value())); return TRI_ERROR_NO_ERROR; } if (parameter->IsNumber()) { if (parameter->IsInt32()) { AddValue(context, attributeName, inObject, VPackValue(parameter->ToInt32()->Value())); return TRI_ERROR_NO_ERROR; } if (parameter->IsUint32()) { AddValue(context, attributeName, inObject, VPackValue(parameter->ToUint32()->Value())); return TRI_ERROR_NO_ERROR; } AddValue(context, attributeName, inObject, VPackValue(parameter->ToNumber()->Value())); return TRI_ERROR_NO_ERROR; } if (parameter->IsString()) { v8::String::Utf8Value str(parameter->ToString()); if (*str == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String)); return TRI_ERROR_NO_ERROR; } if (parameter->IsArray()) { v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(parameter); AddValue(context, attributeName, inObject, VPackValue(VPackValueType::Array)); uint32_t const n = array->Length(); for (uint32_t i = 0; i < n; ++i) { v8::Handle<v8::Value> value = array->Get(i); if (value->IsUndefined()) { // ignore array values which are undefined continue; } if (++context.level > MaxLevels) { // too much recursion return TRI_ERROR_BAD_PARAMETER; } int res = V8ToVPack<performAllChecks>(context, value, NoAttribute, false); --context.level; if (res != TRI_ERROR_NO_ERROR) { return res; } } if (!context.keepTopLevelOpen || context.level > 0) { context.builder.close(); } return TRI_ERROR_NO_ERROR; } if (parameter->IsObject()) { if (performAllChecks) { if (parameter->IsBooleanObject()) { AddValue(context, attributeName, inObject, VPackValue(v8::Handle<v8::BooleanObject>::Cast(parameter) ->BooleanValue())); return TRI_ERROR_NO_ERROR; } if (parameter->IsNumberObject()) { AddValue(context, attributeName, inObject, VPackValue(v8::Handle<v8::NumberObject>::Cast(parameter) ->NumberValue())); return TRI_ERROR_NO_ERROR; } if (parameter->IsStringObject()) { v8::String::Utf8Value str(parameter->ToString()); if (*str == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String)); return TRI_ERROR_NO_ERROR; } if (parameter->IsRegExp() || parameter->IsFunction() || parameter->IsExternal()) { return TRI_ERROR_BAD_PARAMETER; } } v8::Handle<v8::Object> o = parameter->ToObject(); if (performAllChecks) { // first check if the object has a "toJSON" function if (o->Has(context.toJsonKey)) { // call it if yes v8::Handle<v8::Value> func = o->Get(context.toJsonKey); if (func->IsFunction()) { v8::Handle<v8::Function> toJson = v8::Handle<v8::Function>::Cast(func); v8::Handle<v8::Value> args; v8::Handle<v8::Value> converted = toJson->Call(o, 0, &args); if (!converted.IsEmpty()) { // return whatever toJSON returned v8::String::Utf8Value str(converted->ToString()); if (*str == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } // this passes ownership for the utf8 string to the JSON object AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String)); return TRI_ERROR_NO_ERROR; } } // fall-through intentional } } v8::Handle<v8::Array> names = o->GetOwnPropertyNames(); uint32_t const n = names->Length(); AddValue(context, attributeName, inObject, VPackValue(VPackValueType::Object)); for (uint32_t i = 0; i < n; ++i) { // process attribute name v8::Handle<v8::Value> key = names->Get(i); v8::String::Utf8Value str(key); if (*str == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } v8::Handle<v8::Value> value = o->Get(key); if (value->IsUndefined()) { // ignore object values which are undefined continue; } if (++context.level > MaxLevels) { // too much recursion return TRI_ERROR_BAD_PARAMETER; } int res = V8ToVPack<performAllChecks>(context, value, *str, true); --context.level; if (res != TRI_ERROR_NO_ERROR) { return res; } } if (!context.keepTopLevelOpen || context.level > 0) { context.builder.close(); } return TRI_ERROR_NO_ERROR; } return TRI_ERROR_BAD_PARAMETER; }
bool TraverserExpression::matchesCheck(arangodb::Transaction* trx, VPackSlice const& element) const { TRI_ASSERT(trx != nullptr); VPackSlice base = arangodb::basics::VelocyPackHelper::EmptyObjectValue(); VPackSlice value = element.resolveExternal(); // initialize compare value to Null VPackSlice result = arangodb::basics::VelocyPackHelper::NullValue(); // perform recursive check. this may modify value if (recursiveCheck(varAccess, value, base)) { result = value; } // hack for _id attribute TransactionBuilderLeaser builder(trx); if (result.isCustom() && base.isObject()) { builder->add(VPackValue(trx->extractIdString(base))); result = builder->slice(); } TRI_ASSERT(compareTo != nullptr); VPackOptions* options = trx->transactionContext()->getVPackOptions(); switch (comparisonType) { case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_EQ: return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), false, options) == 0; case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_NE: return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), false, options) != 0; case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_LT: return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), true, options) < 0; case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_LE: return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), true, options) <= 0; case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_GE: return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), true, options) >= 0; case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_GT: return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), true, options) > 0; case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_IN: { // In means any of the elements in compareTo is identical VPackSlice compareArray = compareTo->slice(); for (auto const& cmp : VPackArrayIterator(compareArray)) { if (arangodb::basics::VelocyPackHelper::compare(result, cmp, false, options) == 0) { // One is identical return true; } } // If we get here non is identical return false; } case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_NIN: { // NIN means none of the elements in compareTo is identical VPackSlice compareArray = compareTo->slice(); for (auto const& cmp : VPackArrayIterator(compareArray)) { if (arangodb::basics::VelocyPackHelper::compare(result, cmp, false, options) == 0) { // One is identical return false; } } // If we get here non is identical return true; } default: TRI_ASSERT(false); } return false; }
void arangodb::traverser::TraverserOptions::buildEngineInfo(VPackBuilder& result) const { result.openObject(); result.add("minDepth", VPackValue(minDepth)); result.add("maxDepth", VPackValue(maxDepth)); result.add("bfs", VPackValue(useBreadthFirst)); result.add(VPackValue("uniqueVertices")); switch (uniqueVertices) { case UniquenessLevel::NONE: result.add(VPackValue(0)); break; case UniquenessLevel::PATH: result.add(VPackValue(1)); break; case UniquenessLevel::GLOBAL: result.add(VPackValue(2)); break; } result.add(VPackValue("uniqueEdges")); switch (uniqueEdges) { case UniquenessLevel::NONE: result.add(VPackValue(0)); break; case UniquenessLevel::PATH: result.add(VPackValue(1)); break; case UniquenessLevel::GLOBAL: result.add(VPackValue(2)); break; } result.add(VPackValue("baseLookupInfos")); result.openArray(); for (auto const& it: _baseLookupInfos) { it.buildEngineInfo(result); } result.close(); if (!_depthLookupInfo.empty()) { result.add(VPackValue("depthLookupInfo")); result.openObject(); for (auto const& pair : _depthLookupInfo) { result.add(VPackValue(basics::StringUtils::itoa(pair.first))); result.openArray(); for (auto const& it : pair.second) { it.buildEngineInfo(result); } result.close(); } result.close(); } if (!_vertexExpressions.empty()) { result.add(VPackValue("vertexExpressions")); result.openObject(); for (auto const& pair : _vertexExpressions) { result.add(VPackValue(basics::StringUtils::itoa(pair.first))); result.openObject(); result.add(VPackValue("expression")); pair.second->toVelocyPack(result, true); result.close(); } result.close(); } if (_baseVertexExpression != nullptr) { result.add(VPackValue("baseVertexExpression")); result.openObject(); result.add(VPackValue("expression")); _baseVertexExpression->toVelocyPack(result, true); result.close(); } result.add(VPackValue("tmpVar")); _tmpVar->toVelocyPack(result); result.close(); }