From 8b1fe2f4451a2b5981e3a37af6e905008ea844c2 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 29 Nov 2022 15:29:51 +0100 Subject: [PATCH 1/2] removed databind code --- README.md | 281 - pom.xml | 84 +- .../java/com/arangodb/velocypack/Type.java | 55 - .../java/com/arangodb/velocypack/VPack.java | 1080 --- .../VPackAnnotationFieldFilter.java | 35 - .../VPackAnnotationFieldNaming.java | 33 - .../VPackDeserializationContext.java | 33 - .../velocypack/VPackDeserializer.java | 33 - .../VPackDeserializerParameterizedType.java | 36 - .../velocypack/VPackFieldNamingStrategy.java | 33 - .../velocypack/VPackInstanceCreator.java | 31 - .../velocypack/VPackJsonDeserializer.java | 33 - .../velocypack/VPackJsonSerializer.java | 33 - .../velocypack/VPackKeyMapAdapter.java | 33 - .../com/arangodb/velocypack/VPackModule.java | 31 - .../com/arangodb/velocypack/VPackParser.java | 497 -- .../velocypack/VPackParserModule.java | 31 - .../velocypack/VPackParserSetupContext.java | 41 - .../velocypack/VPackSerializationContext.java | 33 - .../arangodb/velocypack/VPackSerializer.java | 34 - .../velocypack/VPackSetupContext.java | 76 - .../com/arangodb/velocypack/VPackSlice.java | 9 - .../velocypack/annotations/Expose.java | 40 - .../annotations/SerializedName.java | 38 - .../velocypack/annotations/VPackCreator.java | 36 - .../annotations/VPackDeserialize.java | 43 - .../annotations/VPackPOJOBuilder.java | 60 - .../internal/VPackBuilderUtils.java | 232 - .../velocypack/internal/VPackCache.java | 337 - .../internal/VPackCreatorMethodUtils.java | 126 - .../internal/VPackDeserializers.java | 243 - .../internal/VPackInstanceCreators.java | 69 - .../internal/VPackKeyMapAdapters.java | 176 - .../velocypack/internal/VPackSerializers.java | 227 - .../java/com/arangodb/velocypack/Bench.java | 171 - .../arangodb/velocypack/JsonStringTest.java | 75 - .../arangodb/velocypack/VPackBuilderTest.java | 1 - .../arangodb/velocypack/VPackModuleTest.java | 63 - .../arangodb/velocypack/VPackParserTest.java | 570 -- .../VPackSerializeDeserializeTest.java | 4177 ---------- .../arangodb/velocypack/VPackSliceTest.java | 19 - .../velocypack/VPackWithoutTypeHintTest.java | 320 - .../velocypack/immutable/AllArgsPerson.java | 112 - .../immutable/AnnotatedExternalBuilder.java | 49 - .../immutable/FactoryMethodPerson.java | 125 - .../velocypack/immutable/ImmutablesTest.java | 214 - .../velocypack/immutable/LombokPerson.java | 42 - .../arangodb/velocypack/immutable/Person.java | 52 - .../velocypack/immutable/PersonBean.java | 86 - .../PersonWithAnnotatedExternalBuilder.java | 69 - .../immutable/PersonWithExternalBuilder.java | 42 - .../immutable/PersonWithFriends.java | 45 - .../immutable/PersonWithInnerBuilder.java | 114 - .../immutable/PersonWithoutAnnotations.java | 37 - src/test/resources/api-docs.json | 7377 ----------------- 55 files changed, 1 insertion(+), 17971 deletions(-) delete mode 100644 src/main/java/com/arangodb/velocypack/Type.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPack.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackAnnotationFieldFilter.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackAnnotationFieldNaming.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackDeserializationContext.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackDeserializer.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackDeserializerParameterizedType.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackFieldNamingStrategy.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackInstanceCreator.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackJsonDeserializer.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackJsonSerializer.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackKeyMapAdapter.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackModule.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackParser.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackParserModule.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackParserSetupContext.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackSerializationContext.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackSerializer.java delete mode 100644 src/main/java/com/arangodb/velocypack/VPackSetupContext.java delete mode 100644 src/main/java/com/arangodb/velocypack/annotations/Expose.java delete mode 100644 src/main/java/com/arangodb/velocypack/annotations/SerializedName.java delete mode 100644 src/main/java/com/arangodb/velocypack/annotations/VPackCreator.java delete mode 100644 src/main/java/com/arangodb/velocypack/annotations/VPackDeserialize.java delete mode 100644 src/main/java/com/arangodb/velocypack/annotations/VPackPOJOBuilder.java delete mode 100644 src/main/java/com/arangodb/velocypack/internal/VPackBuilderUtils.java delete mode 100644 src/main/java/com/arangodb/velocypack/internal/VPackCache.java delete mode 100644 src/main/java/com/arangodb/velocypack/internal/VPackCreatorMethodUtils.java delete mode 100644 src/main/java/com/arangodb/velocypack/internal/VPackDeserializers.java delete mode 100644 src/main/java/com/arangodb/velocypack/internal/VPackInstanceCreators.java delete mode 100644 src/main/java/com/arangodb/velocypack/internal/VPackKeyMapAdapters.java delete mode 100644 src/main/java/com/arangodb/velocypack/internal/VPackSerializers.java delete mode 100644 src/test/java/com/arangodb/velocypack/Bench.java delete mode 100644 src/test/java/com/arangodb/velocypack/JsonStringTest.java delete mode 100644 src/test/java/com/arangodb/velocypack/VPackModuleTest.java delete mode 100644 src/test/java/com/arangodb/velocypack/VPackParserTest.java delete mode 100644 src/test/java/com/arangodb/velocypack/VPackSerializeDeserializeTest.java delete mode 100644 src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/AllArgsPerson.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/AnnotatedExternalBuilder.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/FactoryMethodPerson.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/ImmutablesTest.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/LombokPerson.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/Person.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/PersonBean.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/PersonWithAnnotatedExternalBuilder.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/PersonWithExternalBuilder.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/PersonWithFriends.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/PersonWithInnerBuilder.java delete mode 100644 src/test/java/com/arangodb/velocypack/immutable/PersonWithoutAnnotations.java delete mode 100644 src/test/resources/api-docs.json diff --git a/README.md b/README.md index 15fa617..8ca9732 100644 --- a/README.md +++ b/README.md @@ -97,287 +97,6 @@ mvn clean install -DskipTests=true -Dgpg.skip=true -Dmaven.javadoc.skip=true -B VPackSlice slice = builder.slice(); // create slice ``` -## serialize POJO - -```Java - MyBean entity = new MyBean(); - VPack vpack = new VPack.Builder().build(); - VPackSlice slice = vpack.serialize(entity); -``` - -## deserialize VelocyPack - -```Java - VPackSlice slice = ... - VPack vpack = new VPack.Builder().build(); - MyBean entity = vpack.deserialize(slice, MyBean.class); -``` - -## parse Json to VelocPack - -```Java - String json = ... - VPackParser parser = new VPackParser.Builder().build(); - VPackSlice slice = parser.fromJson(json); -``` - -## parse VelocyPack to Json - -```Java - VPackSlice slice = ... - VPackParser parser = new VPackParser.Builder().build(); - String json = parser.toJson(slice); -``` - -# Registering modules - -Both `VPack` and `VPackParser` allow registering of modules which can offer custom serializers/deserializers for additional types. - -## VPackModule - -```Java - VPackModule module = ... - VPack vpack = new VPack.Builder().registerModule(module).build(); -``` - -## VPackParserModule - -```Java - VPackParserModule module = ... - VPackParser parser = VPackParser.Builder().registerModule(module).build(); -``` - -# Configure serialization / deserialization - -## POJOs - -The class `VPack` can serialize/deserialize POJOs. They need at least a constructor without parameter. Also [Builder deserialization](#builder-deserialization), -[All-Arguments-Constructor deserialization](#all-arguments-constructor-deserialization) and [Static Factory Method deserialization](#static-factory-method-deserialization) are supported. - - -```Java - public class MyObject { - - private String name; - private Gender gender; - private int age; - - public MyObject() { - super(); - } - - } -``` - -## serialized fieldnames - -To use a different serialized name for a field, use the annotation `SerializedName`. - -```Java - public class MyObject { - - @SerializedName("title") - private String name; - - private Gender gender; - private int age; - - public MyObject() { - super(); - } - - } -``` - -## ignore fields - -To ignore fields at serialization/deserialization, use the annotation `Expose` - -```Java - public class MyObject { - - @Expose - private String name; - @Expose(serialize = true, deserialize = false) - private Gender gender; - private int age; - - public MyObject() { - super(); - } - - } -``` - -## custom de-/serializer - -```Java - VPack vpack = new VPack.Builder() - .registerDeserializer(MyObject.class, new VPackDeserializer() { - @Override - public MyObject deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - - final MyObject obj = new MyObject(); - obj.setName(vpack.get("name").getAsString()); - return obj; - } - }).registerSerializer(MyObject.class, new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final MyObject value, - final VPackSerializationContext context) throws VPackException { - - builder.add(attribute, ValueType.OBJECT); - builder.add("name", value.getName()); - builder.close(); - } - }).build(); -``` - - -# Builder deserialization - -Deserialization using builders is supported using the following annotations: - -## @VPackPOJOBuilder - -It allows specifying the builder setters and build method. It has the following fields: - -- `buildMethodName: String`: the build method to call on the builder object after having set all the attributes -- `withSetterPrefix: String`: the prefix of the builder setters - -This annotation can target: -- the builder class having a public no-arg constructor, eg: -```java -@VPackPOJOBuilder(buildMethodName = "build", withSetterPrefix = "set") -public class Builder { - public Builder() { - // ... - } - - public MyClass build() { - // ... - } - - // ... -} -``` -- a public static factory method which returns the builder, eg: -```java -public class MyClass { - @VPackPOJOBuilder(buildMethodName = "build", withSetterPrefix = "with") - public static Builder builder() { - //... - } - // ... -} -``` - -## @VPackDeserialize - -It allows to specify the builder class that will be used during the deserialization. It has the following fields: -- `builder: Class`: builder class to use -- `builderConfig: VPackPOJOBuilder`: it allows specifying the builder setters and build method, useful in case the -builder code is auto generated and you cannot add `@VPackPOJOBuilder` to it. - -This annotation can target: -- `setter`: allows specifying the builder for the setter argument -- `field`: allows specifying the builder for the field -- `class`: allows specifying the builder for the class -- `parameter`: allows specifying the builder for a constructor (or factory method) parameter - -Example: -```java -@VPackDeserialize(builder = MyClassBuilder.class, - builderConfig = @VPackPOJOBuilder(buildMethodName = "build", - withSetterPrefix = "with")) -public class MyClass { - // ... -} -``` - - -# All-Arguments-Constructor deserialization - -Deserialization using All-Arguments-Constructor is supported annotating the constructor with `@VPackCreator` and -annotating each of its parameters with `@SerializedName("name")`, eg: - -```java -public class Person { - private final String name; - private final int age; - - @VPackCreator - public Person( - @SerializedName("name") String name, - @SerializedName("age") int age - ) { - this.name = name; - this.age = age; - } - // ... -} -``` - - -# Static Factory Method deserialization - -Deserialization using Static Factory Method is supported annotating the method with `@VPackCreator` and -annotating each of its parameters with `@SerializedName("name")`, eg: - -```java -public class Person { - private final String name; - private final int age; - - private Person(String name, int age) { - this.name = name; - this.age = age; - } - - @VPackCreator - public static Person of( - @SerializedName("name") String name, - @SerializedName("age") int age - ) { - return new Person(name, age); - } - - // ... -} -``` - - -# Kotlin data classes - -Deserialization of Kotlin data classes is supported annotating the constructor with `@VPackCreator` and annotating each of -its parameters with `@SerializedName("name")`, eg: - -```kotlin -data class Person @VPackCreator constructor( - @SerializedName("name") val name: String, - @SerializedName("age") val age: Int -) -``` - - -# Scala case classes - -Deserialization of Scala case classes is supported annotating the constructor with `@VPackCreator` and annotating each of -its parameters with `@SerializedName("name")`, eg: - -```scala -case class CasePerson @VPackCreator()( - @SerializedName("name") val name: String, - @SerializedName("age") val age: Int - ) -``` - # Learn more diff --git a/pom.xml b/pom.xml index 5a05e5b..975e102 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.arangodb velocypack - 2.5.4 + 3.0.0-SNAPSHOT 2017 jar @@ -57,42 +57,6 @@ - - org.apache.maven.plugins - maven-shade-plugin - 3.2.1 - - true - true - - - com.fasterxml.jackson.core:jackson-core - - - - - com.fasterxml.jackson - com.arangodb.velocypack.deps.com.fasterxml.jackson - - - - - - META-INF/services/com.fasterxml.jackson.core.JsonFactory - - - - - - - package - - shade - - - - org.sonatype.plugins nexus-staging-maven-plugin @@ -229,10 +193,6 @@ slf4j-api 1.7.30 - - com.fasterxml.jackson.core - jackson-core - ch.qos.logback logback-classic @@ -251,36 +211,6 @@ 1.3 test - - org.openjdk.jmh - jmh-core - 1.26 - test - - - org.openjdk.jmh - jmh-generator-annprocess - 1.26 - test - - - org.immutables - value - 2.8.8 - test - - - org.projectlombok - lombok - 1.18.20 - test - - - com.arangodb - jackson-dataformat-velocypack - 2.0.0 - test - org.graalvm.sdk graal-sdk @@ -289,18 +219,6 @@ - - - - com.fasterxml.jackson - jackson-bom - 2.12.3 - import - pom - - - - https://github.com/arangodb/java-velocypack scm:git:git://github.com/arangodb/java-velocypack.git diff --git a/src/main/java/com/arangodb/velocypack/Type.java b/src/main/java/com/arangodb/velocypack/Type.java deleted file mode 100644 index 3aed0e6..0000000 --- a/src/main/java/com/arangodb/velocypack/Type.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import java.lang.reflect.ParameterizedType; - -/** - * @author Mark Vollmary - * - */ -public class Type { - - private final java.lang.reflect.Type type; - - protected Type() { - super(); - type = getTypeParameter(getClass()); - } - - protected Type(final java.lang.reflect.Type type) { - super(); - this.type = type; - } - - private static java.lang.reflect.Type getTypeParameter(final Class clazz) { - final java.lang.reflect.Type superclass = clazz.getGenericSuperclass(); - if (superclass instanceof Class) { - throw new RuntimeException("Missing type parameter."); - } - return ((ParameterizedType) superclass).getActualTypeArguments()[0]; - } - - public java.lang.reflect.Type getType() { - return type; - } - -} diff --git a/src/main/java/com/arangodb/velocypack/VPack.java b/src/main/java/com/arangodb/velocypack/VPack.java deleted file mode 100644 index 929b52d..0000000 --- a/src/main/java/com/arangodb/velocypack/VPack.java +++ /dev/null @@ -1,1080 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.VPackBuilder.BuilderOptions; -import com.arangodb.velocypack.annotations.Expose; -import com.arangodb.velocypack.annotations.SerializedName; -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; -import com.arangodb.velocypack.exception.VPackException; -import com.arangodb.velocypack.exception.VPackParserException; -import com.arangodb.velocypack.internal.*; -import com.arangodb.velocypack.internal.VPackBuilderUtils.BuilderInfo; -import com.arangodb.velocypack.internal.VPackCache.FieldInfo; -import com.arangodb.velocypack.internal.VPackCreatorMethodUtils.ParameterInfo; -import com.arangodb.velocypack.internal.VPackCreatorMethodUtils.VPackCreatorMethodInfo; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.lang.reflect.*; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.*; -import java.util.Map.Entry; - -/** - * @author Mark Vollmary - */ -@SuppressWarnings({"unchecked", "rawtypes"}) -public class VPack { - - private static final String ATTR_KEY = "key"; - private static final String ATTR_VALUE = "value"; - private static final String DEFAULT_TYPE_KEY = "_class"; - private static final boolean DEFAULT_USE_TYPE_HINTS = true; - - private final Map> serializers; - private final Map> enclosingSerializers; - private final Map> deserializers; - private final Map> deserializersWithSelfNullHandle; - private final Map>> deserializersByName; - private final Map>> deserializersByNameWithSelfNullHandle; - private final Map> instanceCreators; - private final Map> keyMapAdapters; - - private final BuilderOptions builderOptions; - private final VPackCache cache; - private final VPackSerializationContext serializationContext; - private final VPackDeserializationContext deserializationContext; - private final boolean serializeNullValues; - private final String typeKey; - private final boolean useTypeHints; - private final VPackBuilderUtils builderUtils; - private final VPackCreatorMethodUtils vPackCreatorMethodUtils; - - public static class Builder implements VPackSetupContext { - private final Map> serializers; - private final Map> enclosingSerializers; - private final Map> deserializers; - private final Map> deserializersWithSelfNullHandle; - private final Map>> deserializersByName; - private final Map>> deserializersByNameWithSelfNullHandle; - private final Map> instanceCreators; - private final BuilderOptions builderOptions; - private boolean serializeNullValues; - private VPackFieldNamingStrategy fieldNamingStrategy; - private final Map, VPackAnnotationFieldFilter> annotationFieldFilter; - private final Map, VPackAnnotationFieldNaming> annotationFieldNaming; - private final Map> keyMapAdapters; - private String typeKey; - private Boolean useTypeHints; - - public Builder() { - super(); - serializers = new HashMap<>(); - enclosingSerializers = new HashMap<>(); - deserializers = new HashMap<>(); - deserializersWithSelfNullHandle = new HashMap<>(); - deserializersByName = new HashMap<>(); - deserializersByNameWithSelfNullHandle = new HashMap<>(); - instanceCreators = new HashMap<>(); - builderOptions = new DefaultVPackBuilderOptions(); - serializeNullValues = false; - annotationFieldFilter = new HashMap<>(); - annotationFieldNaming = new HashMap<>(); - keyMapAdapters = new HashMap<>(); - typeKey = null; - useTypeHints = null; - - instanceCreators.put(Iterable.class, VPackInstanceCreators.ITERABLE); - instanceCreators.put(Collection.class, VPackInstanceCreators.COLLECTION); - instanceCreators.put(List.class, VPackInstanceCreators.LIST); - instanceCreators.put(Set.class, VPackInstanceCreators.SET); - instanceCreators.put(Map.class, VPackInstanceCreators.MAP); - - serializers.put(String.class, VPackSerializers.STRING); - serializers.put(Boolean.class, VPackSerializers.BOOLEAN); - serializers.put(boolean.class, VPackSerializers.BOOLEAN); - serializers.put(Integer.class, VPackSerializers.INTEGER); - serializers.put(int.class, VPackSerializers.INTEGER); - serializers.put(Long.class, VPackSerializers.LONG); - serializers.put(long.class, VPackSerializers.LONG); - serializers.put(Short.class, VPackSerializers.SHORT); - serializers.put(short.class, VPackSerializers.SHORT); - serializers.put(Double.class, VPackSerializers.DOUBLE); - serializers.put(double.class, VPackSerializers.DOUBLE); - serializers.put(Float.class, VPackSerializers.FLOAT); - serializers.put(float.class, VPackSerializers.FLOAT); - serializers.put(BigInteger.class, VPackSerializers.BIG_INTEGER); - serializers.put(BigDecimal.class, VPackSerializers.BIG_DECIMAL); - serializers.put(Number.class, VPackSerializers.NUMBER); - serializers.put(Character.class, VPackSerializers.CHARACTER); - serializers.put(char.class, VPackSerializers.CHARACTER); - serializers.put(Date.class, VPackSerializers.DATE); - serializers.put(java.sql.Date.class, VPackSerializers.SQL_DATE); - serializers.put(java.sql.Timestamp.class, VPackSerializers.SQL_TIMESTAMP); - serializers.put(VPackSlice.class, VPackSerializers.VPACK); - serializers.put(UUID.class, VPackSerializers.UUID); - serializers.put(byte[].class, VPackSerializers.BYTE_ARRAY); - serializers.put(Byte.class, VPackSerializers.BYTE); - serializers.put(byte.class, VPackSerializers.BYTE); - - deserializers.put(String.class, VPackDeserializers.STRING); - deserializers.put(Boolean.class, VPackDeserializers.BOOLEAN); - deserializers.put(boolean.class, VPackDeserializers.BOOLEAN); - deserializers.put(Integer.class, VPackDeserializers.INTEGER); - deserializers.put(int.class, VPackDeserializers.INTEGER); - deserializers.put(Long.class, VPackDeserializers.LONG); - deserializers.put(long.class, VPackDeserializers.LONG); - deserializers.put(Short.class, VPackDeserializers.SHORT); - deserializers.put(short.class, VPackDeserializers.SHORT); - deserializers.put(Double.class, VPackDeserializers.DOUBLE); - deserializers.put(double.class, VPackDeserializers.DOUBLE); - deserializers.put(Float.class, VPackDeserializers.FLOAT); - deserializers.put(float.class, VPackDeserializers.FLOAT); - deserializers.put(BigInteger.class, VPackDeserializers.BIG_INTEGER); - deserializers.put(BigDecimal.class, VPackDeserializers.BIG_DECIMAL); - deserializers.put(Number.class, VPackDeserializers.NUMBER); - deserializers.put(Character.class, VPackDeserializers.CHARACTER); - deserializers.put(char.class, VPackDeserializers.CHARACTER); - deserializers.put(Date.class, VPackDeserializers.DATE); - deserializers.put(java.sql.Date.class, VPackDeserializers.SQL_DATE); - deserializers.put(java.sql.Timestamp.class, VPackDeserializers.SQL_TIMESTAMP); - deserializers.put(VPackSlice.class, VPackDeserializers.VPACK); - deserializers.put(UUID.class, VPackDeserializers.UUID); - deserializers.put(byte[].class, VPackDeserializers.BYTE_ARRAY); - deserializers.put(Byte.class, VPackDeserializers.BYTE); - deserializers.put(byte.class, VPackDeserializers.BYTE); - - annotationFieldFilter.put(Expose.class, new VPackAnnotationFieldFilter() { - @Override - public boolean serialize(final Expose annotation) { - return annotation.serialize(); - } - - @Override - public boolean deserialize(final Expose annotation) { - return annotation.deserialize(); - } - }); - annotationFieldNaming.put(SerializedName.class, new VPackAnnotationFieldNaming() { - @Override - public String name(final SerializedName annotation) { - return annotation.value(); - } - }); - } - - @Override - public VPack.Builder registerSerializer(final Type type, final VPackSerializer serializer) { - serializers.put(type, serializer); - return this; - } - - @Override - public VPack.Builder registerEnclosingSerializer(final Type type, final VPackSerializer serializer) { - enclosingSerializers.put(type, serializer); - return this; - } - - @Override - public VPack.Builder registerDeserializer(final Type type, final VPackDeserializer deserializer) { - return registerDeserializer(type, deserializer, false); - } - - @Override - public Builder registerDeserializer( - final Type type, - final VPackDeserializer deserializer, - final boolean includeNullValues) { - if (includeNullValues) { - deserializersWithSelfNullHandle.put(type, deserializer); - } - deserializers.put(type, deserializer); - return this; - } - - @Override - public VPack.Builder registerDeserializer( - final String fieldName, - final Type type, - final VPackDeserializer deserializer) { - return registerDeserializer(fieldName, type, deserializer, false); - } - - @Override - public Builder registerDeserializer( - final String fieldName, - final Type type, - final VPackDeserializer deserializer, - final boolean includeNullValues) { - if (includeNullValues) { - Map> byName = deserializersByNameWithSelfNullHandle.get(fieldName); - if (byName == null) { - byName = new HashMap<>(); - deserializersByNameWithSelfNullHandle.put(fieldName, byName); - } - byName.put(type, deserializer); - } - Map> byName = deserializersByName.get(fieldName); - if (byName == null) { - byName = new HashMap<>(); - deserializersByName.put(fieldName, byName); - } - byName.put(type, deserializer); - return this; - } - - @Override - public VPack.Builder registerInstanceCreator(final Type type, final VPackInstanceCreator creator) { - instanceCreators.put(type, creator); - return this; - } - - @Override - public VPack.Builder buildUnindexedArrays(final boolean buildUnindexedArrays) { - builderOptions.setBuildUnindexedArrays(buildUnindexedArrays); - return this; - } - - @Override - public VPack.Builder buildUnindexedObjects(final boolean buildUnindexedObjects) { - builderOptions.setBuildUnindexedObjects(buildUnindexedObjects); - return this; - } - - @Override - public VPack.Builder serializeNullValues(final boolean serializeNullValues) { - this.serializeNullValues = serializeNullValues; - return this; - } - - @Override - public VPack.Builder fieldNamingStrategy(final VPackFieldNamingStrategy fieldNamingStrategy) { - this.fieldNamingStrategy = fieldNamingStrategy; - return this; - } - - @Override - public VPack.Builder annotationFieldFilter( - final Class type, - final VPackAnnotationFieldFilter fieldFilter) { - annotationFieldFilter.put(type, fieldFilter); - return this; - } - - @Override - public VPack.Builder annotationFieldNaming( - final Class type, - final VPackAnnotationFieldNaming fieldNaming) { - annotationFieldNaming.put(type, fieldNaming); - return this; - } - - @Override - public Builder registerModule(final VPackModule module) { - module.setup(VPack.Builder.this); - return this; - } - - @Override - public Builder registerModules(final VPackModule... modules) { - for (final VPackModule module : modules) { - registerModule(module); - } - return this; - } - - /** - * Register an adapter to convert keys in {@link java.util.Map} which are not from type - * {@link java.lang.String}. - * - * @param type the type the adapter should used for - * @param adapter the adapter - * @return {@link VPack.Builder} - */ - @Override - public Builder registerKeyMapAdapter(final Type type, final VPackKeyMapAdapter adapter) { - keyMapAdapters.put(type, adapter); - return this; - } - - /** - * Set the name of the serialized field with the type information - * - * @param typeKey Name of the field with type information - * @return {@link VPack.Builder} - */ - @Override - public VPack.Builder typeKey(final String typeKey) { - this.typeKey = typeKey; - return this; - } - - /** - * Enables storing type information of the serialized object - * - * @param useTypeHints (default: {@code true}) - * @return {@link VPack.Builder} - */ - @Override - public VPack.Builder useTypeHints(final boolean useTypeHints) { - this.useTypeHints = useTypeHints; - return this; - } - - public synchronized VPack build() { - return new VPack(new HashMap<>(serializers), new HashMap<>(enclosingSerializers), new HashMap<>(deserializers), - new HashMap<>(deserializersWithSelfNullHandle), - new HashMap<>(instanceCreators), builderOptions, serializeNullValues, - fieldNamingStrategy, new HashMap<>(deserializersByName), - new HashMap<>(deserializersByNameWithSelfNullHandle), - new HashMap<>(annotationFieldFilter), new HashMap<>(annotationFieldNaming), - keyMapAdapters, - typeKey != null ? typeKey : DEFAULT_TYPE_KEY, - useTypeHints != null ? useTypeHints : DEFAULT_USE_TYPE_HINTS - ); - } - - } - - private VPack(final Map> serializers, - final Map> enclosingSerializers, final Map> deserializers, - final Map> deserializersWithSelfNullHandle, - final Map> instanceCreators, final BuilderOptions builderOptions, - final boolean serializeNullValues, final VPackFieldNamingStrategy fieldNamingStrategy, - final Map>> deserializersByName, - final Map>> deserializersByNameWithSelfNullHandle, - final Map, VPackAnnotationFieldFilter> annotationFieldFilter, - final Map, VPackAnnotationFieldNaming> annotationFieldNaming, - final Map> keyMapAdapters, final String typeKey, final boolean useTypeHints) { - super(); - this.serializers = serializers; - this.enclosingSerializers = enclosingSerializers; - this.deserializers = deserializers; - this.deserializersWithSelfNullHandle = deserializersWithSelfNullHandle; - this.instanceCreators = instanceCreators; - this.builderOptions = builderOptions; - this.serializeNullValues = serializeNullValues; - this.deserializersByName = deserializersByName; - this.deserializersByNameWithSelfNullHandle = deserializersByNameWithSelfNullHandle; - this.keyMapAdapters = keyMapAdapters; - this.typeKey = typeKey; - this.useTypeHints = useTypeHints; - - builderUtils = new VPackBuilderUtils(); - vPackCreatorMethodUtils = new VPackCreatorMethodUtils(); - cache = new VPackCache(fieldNamingStrategy, annotationFieldFilter, annotationFieldNaming); - serializationContext = new VPackSerializationContext() { - @Override - public void serialize(final VPackBuilder builder, final String attribute, final Object entity) - throws VPackParserException { - VPack.this.serialize(attribute, entity, entity != null ? entity.getClass() : null, builder, - Collections.emptyMap()); - } - }; - deserializationContext = new VPackDeserializationContext() { - @Override - public T deserialize(final VPackSlice vpack, final Type type) throws VPackParserException { - return VPack.this.deserialize(vpack, type); - } - }; - keyMapAdapters.put(String.class, VPackKeyMapAdapters.STRING); - keyMapAdapters.put(Boolean.class, VPackKeyMapAdapters.BOOLEAN); - keyMapAdapters.put(Integer.class, VPackKeyMapAdapters.INTEGER); - keyMapAdapters.put(Long.class, VPackKeyMapAdapters.LONG); - keyMapAdapters.put(Short.class, VPackKeyMapAdapters.SHORT); - keyMapAdapters.put(Double.class, VPackKeyMapAdapters.DOUBLE); - keyMapAdapters.put(Float.class, VPackKeyMapAdapters.FLOAT); - keyMapAdapters.put(BigInteger.class, VPackKeyMapAdapters.BIG_INTEGER); - keyMapAdapters.put(BigDecimal.class, VPackKeyMapAdapters.BIG_DECIMAL); - keyMapAdapters.put(Number.class, VPackKeyMapAdapters.NUMBER); - keyMapAdapters.put(Character.class, VPackKeyMapAdapters.CHARACTER); - } - - public T deserialize(final VPackSlice vpack, final Type type) throws VPackParserException { - if (type == VPackSlice.class) { - return (T) vpack; - } - final T entity; - try { - entity = (T) getValue(null, vpack, type, null); - } catch (final Exception e) { - throw new VPackParserException(e); - } - return entity; - } - - private VPackDeserializer getDeserializer(final String fieldName, final Type type) { - return getDeserializer(fieldName, type, deserializers, deserializersByName); - } - - private VPackDeserializer getDeserializerWithSelfNullHandle(final String fieldName, final Type type) { - return getDeserializer(fieldName, type, deserializersWithSelfNullHandle, deserializersByNameWithSelfNullHandle); - } - - private VPackDeserializer getDeserializer( - final String fieldName, - final Type type, - final Map> deserializers, - final Map>> deserializersByName) { - VPackDeserializer deserializer = null; - final Map> byName = deserializersByName.get(fieldName); - if (byName != null) { - deserializer = byName.get(type); - } - if (deserializer == null) { - deserializer = deserializers.get(type); - } - if (deserializer == null && ParameterizedType.class.isAssignableFrom(type.getClass())) { - deserializer = getDeserializer(fieldName, ((ParameterizedType) type).getRawType(), deserializers, - deserializersByName); - } - return deserializer; - } - - private Method getBuildMethod(Class clazz, String name) throws NoSuchMethodException { - Method build = clazz.getDeclaredMethod(name); - if (Modifier.isStatic(build.getModifiers())) - throw new NoSuchMethodException("Cannot find build method: " + clazz.getName() + "." + name + "() "); - return build; - } - - private T deserializeObject( - final VPackSlice parent, final VPackSlice vpack, final Type type, final String fieldName) - throws ReflectiveOperationException, VPackException { - return deserializeObject(parent, vpack, type, fieldName, null); - } - - private T deserializeObject( - final VPackSlice parent, - final VPackSlice vpack, - final Type type, - final String fieldName, - final AnnotatedElement referencingElement) throws ReflectiveOperationException, VPackException { - final T entity; - - final VPackDeserializer deserializer = getDeserializer(fieldName, type); - final BuilderInfo builderInfo = builderUtils.getBuilderInfo(type, referencingElement); - final VPackCreatorMethodInfo factoryMethodInfo = vPackCreatorMethodUtils.getCreatorMethodInfo(type); - - if (builderInfo != null) { - Object builder = builderInfo.createBuilder(); - deserializeBuilder(builder, vpack, builderInfo.annotation); - Method build = getBuildMethod(builder.getClass(), builderInfo.annotation.buildMethodName); - entity = (T) build.invoke(builder); - } else if (factoryMethodInfo != null) { - entity = (T) deserializeFactoryMethod(factoryMethodInfo, vpack); - } else if (deserializer != null) { - if (VPackDeserializerParameterizedType.class.isAssignableFrom(deserializer.getClass()) - && ParameterizedType.class.isAssignableFrom(type.getClass())) { - entity = ((VPackDeserializerParameterizedType) deserializer) - .deserialize(parent, vpack, deserializationContext, (ParameterizedType) type); - } else { - entity = ((VPackDeserializer) deserializer).deserialize(parent, vpack, deserializationContext); - } - } else if (type == Object.class) { - entity = (T) getValue(parent, vpack, getType(vpack), fieldName); - } else { - entity = createInstance(type); - deserializeFields(entity, vpack); - } - return entity; - } - - private Type determineType(final VPackSlice vpack, final Type type) { - if (!useTypeHints || !vpack.isObject()) { - return type; - } - final VPackSlice clazz = vpack.get(typeKey); - try { - return clazz.isString() ? Class.forName(clazz.getAsString()) : type; - } catch (final ClassNotFoundException e) { - throw new VPackParserException(e); - } - } - - private Type getType(final VPackSlice vpack) { - final Type type; - if (vpack.isObject()) { - type = Map.class; - } else if (vpack.isString()) { - type = String.class; - } else if (vpack.isBoolean()) { - type = Boolean.class; - } else if (vpack.isArray()) { - type = Iterable.class; - } else if (vpack.isDate()) { - type = Date.class; - } else if (vpack.isDouble()) { - type = Double.class; - } else if (vpack.isNumber()) { - type = Number.class; - } else if (vpack.isCustom()) { - type = String.class; - } else { - type = null; - } - return type; - } - - private T createInstance(final Type type) throws ReflectiveOperationException { - final T entity; - final VPackInstanceCreator creator = instanceCreators.get(type); - if (creator != null) { - entity = (T) creator.createInstance(); - } else if (type instanceof ParameterizedType) { - entity = createInstance(((ParameterizedType) type).getRawType()); - } else { - entity = ((Class) type).newInstance(); - } - return entity; - } - - private void deserializeFields(final Object entity, final VPackSlice vpack) - throws ReflectiveOperationException, VPackException { - final Map fields = cache.getFields(entity.getClass()); - for (final Iterator> iterator = vpack.objectIterator(); iterator.hasNext(); ) { - final Entry next = iterator.next(); - final FieldInfo fieldInfo = fields.get(next.getKey()); - if (fieldInfo != null && fieldInfo.isDeserialize()) { - deserializeField(vpack, next.getValue(), entity, fieldInfo); - } - } - } - - private Object deserializeFactoryMethod(final VPackCreatorMethodInfo factoryMethodInfo, final VPackSlice vpack) - throws ReflectiveOperationException, VPackException { - LinkedHashMap parameters = cache.getParameters(factoryMethodInfo.getExecutable()); - Map parameterValuesMap = new HashMap<>(); - - for (final Iterator> iterator = vpack.objectIterator(); iterator.hasNext(); ) { - final Entry next = iterator.next(); - final ParameterInfo parameterInfo = parameters.get(next.getKey()); - parameterValuesMap.put(parameterInfo.name, - getValue(vpack, next.getValue(), parameterInfo.type, parameterInfo.name, - parameterInfo.referencingElement)); - } - - Object[] parameterValues = new Object[parameters.size()]; - int i = 0; - for (String key : parameters.keySet()) { - parameterValues[i++] = parameterValuesMap.get(key); - } - - return factoryMethodInfo.create(parameterValues); - } - - private void deserializeBuilder( - final Object builder, final VPackSlice vpack, VPackPOJOBuilder.Value annotation) - throws ReflectiveOperationException, VPackException { - final Map setters = cache.getBuiderSetters(builder.getClass(), annotation.withSetterPrefix); - for (final Iterator> iterator = vpack.objectIterator(); iterator.hasNext(); ) { - final Entry next = iterator.next(); - final FieldInfo fieldInfo = setters.get(next.getKey()); - if (fieldInfo != null && fieldInfo.isDeserialize()) { - deserializeField(vpack, next.getValue(), builder, fieldInfo); - } - } - } - - private void deserializeField( - final VPackSlice parent, final VPackSlice vpack, final Object entity, final FieldInfo fieldInfo) - throws ReflectiveOperationException, VPackException { - if (!vpack.isNone()) { - final Object value = getValue(parent, vpack, fieldInfo.getType(), fieldInfo.getFieldName(), - fieldInfo.getReferencingElement()); - fieldInfo.set(entity, value); - } - } - - private Object getValue( - final VPackSlice parent, final VPackSlice vpack, final Type type, final String fieldName) - throws ReflectiveOperationException, VPackException { - return getValue(parent, vpack, type, fieldName, null); - } - - private Object getValue( - final VPackSlice parent, - final VPackSlice vpack, - final Type type, - final String fieldName, - final AnnotatedElement referencingElement) throws ReflectiveOperationException, VPackException { - final Object value; - final Type realType = determineType(vpack, type); - if (vpack.isNull()) { - final VPackDeserializer deserializer = getDeserializerWithSelfNullHandle(fieldName, realType); - if (deserializer != null) { - if (VPackDeserializerParameterizedType.class.isAssignableFrom(deserializer.getClass()) - && ParameterizedType.class.isAssignableFrom(realType.getClass())) { - value = ((VPackDeserializerParameterizedType) deserializer) - .deserialize(parent, vpack, deserializationContext, (ParameterizedType) realType); - } else { - value = ((VPackDeserializer) deserializer).deserialize(parent, vpack, - deserializationContext); - } - } else { - value = null; - } - } else { - final VPackDeserializer deserializer = getDeserializer(fieldName, realType); - if (deserializer != null) { - if (VPackDeserializerParameterizedType.class.isAssignableFrom(deserializer.getClass()) - && ParameterizedType.class.isAssignableFrom(realType.getClass())) { - value = ((VPackDeserializerParameterizedType) deserializer).deserialize(parent, vpack, - deserializationContext, (ParameterizedType) realType); - } else { - value = ((VPackDeserializer) deserializer).deserialize(parent, vpack, - deserializationContext); - } - } else if (realType instanceof ParameterizedType) { - final ParameterizedType pType = (ParameterizedType) realType; - final Type rawType = pType.getRawType(); - if (Iterable.class.isAssignableFrom((Class) rawType)) { - value = deserializeIterable(parent, vpack, realType, pType.getActualTypeArguments()[0]); - } else if (Map.class.isAssignableFrom((Class) rawType)) { - final Type[] parameterizedTypes = pType.getActualTypeArguments(); - value = deserializeMap(parent, vpack, realType, parameterizedTypes[0], parameterizedTypes[1]); - } else { - value = deserializeObject(parent, vpack, realType, fieldName, referencingElement); - } - } else if (realType instanceof WildcardType) { - final WildcardType wType = (WildcardType) realType; - final Type rawType = wType.getUpperBounds()[0]; - value = getValue( - parent, - vpack, - rawType, - fieldName, - referencingElement - ); - } else if (realType instanceof GenericArrayType) { - throw new VPackParserException(new IllegalArgumentException("Generic arrays are not supported!")); - } else if (Iterable.class.isAssignableFrom((Class) realType)) { - value = deserializeIterable(parent, vpack, realType, Object.class); - } else if (Map.class.isAssignableFrom((Class) realType)) { - value = deserializeMap(parent, vpack, realType, String.class, Object.class); - } else if (((Class) realType).isArray()) { - value = deserializeArray(parent, vpack, realType); - } else if (((Class) realType).isEnum()) { - value = Enum.valueOf((Class) realType, vpack.getAsString()); - } else { - value = deserializeObject(parent, vpack, realType, fieldName, referencingElement); - } - } - return value; - } - - private Object deserializeArray(final VPackSlice parent, final VPackSlice vpack, final Type type) - throws ReflectiveOperationException, VPackException { - final int length = vpack.getLength(); - final Class componentType = ((Class) type).getComponentType(); - final Object value = Array.newInstance(componentType, length); - int i = 0; - for (final Iterator iterator = vpack.arrayIterator(); iterator.hasNext(); ) { - Array.set(value, i++, getValue(parent, iterator.next(), componentType, null)); - } - return value; - } - - private Object deserializeIterable( - final VPackSlice parent, final VPackSlice vpack, final Type type, final Type contentType) - throws ReflectiveOperationException, VPackException { - final Collection value = createInstance(type); - final long length = vpack.getLength(); - if (length > 0) { - for (int i = 0; i < length; i++) { - value.add(getValue(parent, vpack.get(i), contentType, null)); - } - } - return value; - } - - private Object deserializeMap( - final VPackSlice parent, final VPackSlice vpack, final Type type, final Type keyType, final Type valueType) - throws ReflectiveOperationException, VPackException { - final int length = vpack.getLength(); - final Map value = createInstance(type); - if (length > 0) { - final VPackKeyMapAdapter keyMapAdapter = getKeyMapAdapter(keyType); - if (keyMapAdapter != null) { - for (final Iterator> iterator = vpack.objectIterator(); iterator - .hasNext(); ) { - final Entry next = iterator.next(); - final Object name = keyMapAdapter.deserialize(next.getKey()); - value.put(name, getValue(vpack, next.getValue(), valueType, name.toString())); - } - } else { - for (int i = 0; i < vpack.getLength(); i++) { - final VPackSlice entry = vpack.get(i); - final Object mapKey = getValue(parent, entry.get(ATTR_KEY), keyType, null); - final Object mapValue = getValue(parent, entry.get(ATTR_VALUE), valueType, null); - value.put(mapKey, mapValue); - } - } - } - return value; - } - - public static class SerializeOptions { - private Type type; - private Map additionalFields; - - public SerializeOptions() { - super(); - type = null; - additionalFields = Collections.emptyMap(); - } - - public Type getType() { - return type; - } - - /** - * @param type The source type of the Object. - * @return options - */ - public SerializeOptions type(final Type type) { - this.type = type; - return this; - } - - public Map getAdditionalFields() { - return additionalFields; - } - - /** - * @param additionalFields Additional Key/Value pairs to include in the created VelocyPack. - * @return options - */ - public SerializeOptions additionalFields(final Map additionalFields) { - this.additionalFields = additionalFields; - return this; - } - } - - /** - * Serialize a given Object to VelocyPack - * - * @param entity The Object to serialize. - * @return the serialized VelocyPack - * @throws VPackParserException - */ - public VPackSlice serialize(final Object entity) throws VPackParserException { - return serialize(entity, new SerializeOptions().type(entity.getClass())); - } - - /** - * Serialize a given Object to VelocyPack - * - * @param entity The Object to serialize. - * @param additionalFields Additional Key/Value pairs to include in the created VelocyPack. - * @return the serialized VelocyPack - * @throws VPackParserException - * @deprecated use {@link #serialize(Object, SerializeOptions)} instead - */ - @Deprecated - public VPackSlice serialize(final Object entity, final Map additionalFields) - throws VPackParserException { - return serialize(entity, new SerializeOptions().type(entity.getClass()).additionalFields(additionalFields)); - } - - /** - * Serialize a given Object to VelocyPack - * - * @param entity The Object to serialize. - * @param type The source type of the Object. - * @return the serialized VelocyPack - * @throws VPackParserException - * @deprecated use {@link #serialize(Object, SerializeOptions)} instead - */ - @Deprecated - public VPackSlice serialize(final Object entity, final Type type) throws VPackParserException { - return serialize(entity, new SerializeOptions().type(type)); - } - - /** - * Serialize a given Object to VelocyPack - * - * @param entity The Object to serialize. - * @param type The source type of the Object. - * @param additionalFields Additional Key/Value pairs to include in the created VelocyPack. - * @return the serialized VelocyPack - * @throws VPackParserException - * @deprecated use {@link #serialize(Object, SerializeOptions)} instead - */ - @Deprecated - public VPackSlice serialize(final Object entity, final Type type, final Map additionalFields) - throws VPackParserException { - return serialize(entity, new SerializeOptions().type(type).additionalFields(additionalFields)); - } - - /** - * Serialize a given Object to VelocyPack - * - * @param entity The Object to serialize. - * @param options Additional options - * @return the serialized VelocyPack - * @throws VPackParserException - */ - public VPackSlice serialize(final Object entity, final SerializeOptions options) throws VPackParserException { - Type type = options.getType(); - if (type == null) { - type = entity.getClass(); - } - if (type == VPackSlice.class) { - return (VPackSlice) entity; - } - final VPackBuilder builder = new VPackBuilder(builderOptions); - serialize(null, entity, type, builder, new HashMap<>(options.getAdditionalFields())); - return builder.slice(); - } - - private void serialize( - final String name, - final Object entity, - final Type type, - final VPackBuilder builder, - final Map additionalFields) throws VPackParserException { - try { - addValue(name, type, entity, builder, null, additionalFields); - } catch (final Exception e) { - throw new VPackParserException(e); - } - } - - private void serializeObject( - final String name, - final Object entity, - final VPackBuilder builder, - final Map additionalFields) throws ReflectiveOperationException, VPackException { - - final Class type = entity.getClass(); - - final VPackSerializer serializer = getSerializer(type); - if (serializer != null) { - ((VPackSerializer) serializer).serialize(builder, name, entity, serializationContext); - } else { - - builder.add(name, ValueType.OBJECT); - serializeFields(entity, builder, additionalFields); - builder.close(true); - } - } - - private void serializeFields( - final Object entity, - final VPackBuilder builder, - final Map additionalFields) throws ReflectiveOperationException, VPackException { - final Map fields = cache.getFields(entity.getClass()); - for (final FieldInfo fieldInfo : fields.values()) { - if (fieldInfo.isSerialize()) { - serializeField(entity, builder, fieldInfo, Collections.emptyMap()); - } - } - for (final Entry entry : additionalFields.entrySet()) { - final String key = entry.getKey(); - if (!fields.containsKey(key)) { - final Object value = entry.getValue(); - addValue(key, value != null ? value.getClass() : null, value, builder, null, - Collections.emptyMap()); - } - } - } - - private void serializeField( - final Object entity, - final VPackBuilder builder, - final FieldInfo fieldInfo, - final Map additionalFields) throws ReflectiveOperationException, VPackException { - - final String fieldName = fieldInfo.getFieldName(); - final Type type = fieldInfo.getType(); - final Object value = fieldInfo.get(entity); - addValue(fieldName, type, value, builder, fieldInfo, additionalFields); - } - - private void addValue( - final String name, - final Type type, - final Object value, - final VPackBuilder builder, - final FieldInfo fieldInfo, - final Map additionalFields) throws ReflectiveOperationException, VPackException { - - if (value == null) { - if (serializeNullValues) { - builder.add(name, ValueType.NULL); - } - } else { - final VPackSerializer serializer = getSerializer(type); - if (serializer != null) { - ((VPackSerializer) serializer).serialize(builder, name, value, serializationContext); - } else if (type instanceof ParameterizedType) { - final ParameterizedType pType = (ParameterizedType) type; - final Type rawType = pType.getRawType(); - if (Iterable.class.isAssignableFrom((Class) rawType)) { - serializeIterable(name, value, builder, pType.getActualTypeArguments()[0]); - } else if (Map.class.isAssignableFrom((Class) rawType)) { - serializeMap(name, value, builder, pType.getActualTypeArguments()[0], additionalFields); - } else { - serializeObject(name, value, builder, additionalFields); - } - } else if (type instanceof WildcardType) { - final WildcardType wType = (WildcardType) type; - final Type rawType = wType.getUpperBounds()[0]; - addValue(name, rawType, value, builder, fieldInfo, additionalFields); - } else if (type instanceof Class && Iterable.class.isAssignableFrom((Class) type)) { - serializeIterable(name, value, builder, null); - } else if (type instanceof Class && Map.class.isAssignableFrom((Class) type)) { - serializeMap(name, value, builder, String.class, additionalFields); - } else if (type instanceof Class && ((Class) type).isArray()) { - final Type elemType = ((Class) type).getComponentType(); - serializeArray(name, value, builder, elemType); - } else if (type instanceof Class && ((Class) type).isEnum()) { - builder.add(name, ((Enum) value).name()); - } else if (shouldAddTypeHint(type, value, fieldInfo)) { - addValue(name, value.getClass(), value, builder, fieldInfo, - Collections.singletonMap(typeKey, value.getClass().getName())); - } else if (value instanceof Iterable) { - serializeIterable(name, value, builder, null); - } else if (value instanceof Map) { - serializeMap(name, value, builder, String.class, additionalFields); - } else if (value.getClass().isArray()) { - serializeArray(name, value, builder, null); - } else { - serializeObject(name, value, builder, additionalFields); - } - } - } - - private boolean shouldAddTypeHint( - final Type type, - final Object value, - final FieldInfo fieldInfo - ) { - if (!useTypeHints) { - return false; - } - final AnnotatedElement referencingElement = fieldInfo != null ? fieldInfo.getReferencingElement() : null; - final BuilderInfo builderInfo = builderUtils.getBuilderInfo(type, referencingElement); - if (builderInfo != null) { - return false; - } - - final VPackCreatorMethodInfo factoryMethodInfo = vPackCreatorMethodUtils.getCreatorMethodInfo(type); - if (factoryMethodInfo != null) { - return false; - } - - return type != value.getClass(); - } - - private void serializeArray(final String name, final Object value, final VPackBuilder builder, final Type type) - throws ReflectiveOperationException, VPackException { - builder.add(name, ValueType.ARRAY); - for (int i = 0; i < Array.getLength(value); i++) { - final Object element = Array.get(value, i); - if (element != null) { - final Type t = type != null ? type : element.getClass(); - addValue(null, t, element, builder, null, Collections.emptyMap()); - } else { - builder.add(ValueType.NULL); - } - } - builder.close(); - } - - private void serializeIterable(final String name, final Object value, final VPackBuilder builder, final Type type) - throws ReflectiveOperationException, VPackException { - builder.add(name, ValueType.ARRAY); - for (final Object element : (Iterable) value) { - final Type t = type != null ? type : element != null ? element.getClass() : null; - addValue(null, t, element, builder, null, Collections.emptyMap()); - } - builder.close(); - } - - private void serializeMap( - final String name, - final Object value, - final VPackBuilder builder, - final Type keyType, - final Map additionalFields) throws ReflectiveOperationException, VPackException { - final Map map = (Map) value; - if (map.size() > 0) { - final VPackKeyMapAdapter keyMapAdapter = getKeyMapAdapter(keyType); - if (keyMapAdapter != null) { - builder.add(name, ValueType.OBJECT); - final Set> entrySet = map.entrySet(); - for (final Entry entry : entrySet) { - final Object entryValue = entry.getValue(); - addValue(keyMapAdapter.serialize(entry.getKey()), - entryValue != null ? entryValue.getClass() : Object.class, entry.getValue(), builder, null, - Collections.emptyMap()); - } - for (final Entry entry : additionalFields.entrySet()) { - final String key = entry.getKey(); - if (!map.containsKey(key)) { - final Object additionalValue = entry.getValue(); - addValue(key, additionalValue != null ? additionalValue.getClass() : null, additionalValue, - builder, null, Collections.emptyMap()); - } - } - } else { - builder.add(name, ValueType.ARRAY); - final Set> entrySet = map.entrySet(); - for (final Entry entry : entrySet) { - builder.add((String) null, ValueType.OBJECT); - addValue(ATTR_KEY, entry.getKey().getClass(), entry.getKey(), builder, null, - Collections.emptyMap()); - addValue(ATTR_VALUE, entry.getValue().getClass(), entry.getValue(), builder, null, - Collections.emptyMap()); - builder.close(); - } - } - } else { - builder.add(name, ValueType.OBJECT); - } - builder.close(); - } - - private VPackKeyMapAdapter getKeyMapAdapter(final Type type) { - VPackKeyMapAdapter adapter = keyMapAdapters.get(type); - if (adapter == null && Enum.class.isAssignableFrom((Class) type)) { - adapter = VPackKeyMapAdapters.createEnumAdapter(type); - } - return (VPackKeyMapAdapter) adapter; - } - - private VPackSerializer getSerializer(final Type type) { - VPackSerializer serializer = serializers.get(type); - if (serializer == null) { - if (type instanceof Class && ((Class) type).isMemberClass()) { - serializer = enclosingSerializers.get(((Class) type).getEnclosingClass()); - } - } - if (serializer == null && ParameterizedType.class.isAssignableFrom(type.getClass())) { - serializer = getSerializer(((ParameterizedType) type).getRawType()); - } - return serializer; - } -} diff --git a/src/main/java/com/arangodb/velocypack/VPackAnnotationFieldFilter.java b/src/main/java/com/arangodb/velocypack/VPackAnnotationFieldFilter.java deleted file mode 100644 index bbe5cb5..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackAnnotationFieldFilter.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import java.lang.annotation.Annotation; - -/** - * @author Mark Vollmary - * - */ -public interface VPackAnnotationFieldFilter { - - boolean serialize(A annotation); - - boolean deserialize(A annotation); - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackAnnotationFieldNaming.java b/src/main/java/com/arangodb/velocypack/VPackAnnotationFieldNaming.java deleted file mode 100644 index 6adf1af..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackAnnotationFieldNaming.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import java.lang.annotation.Annotation; - -/** - * @author Mark Vollmary - * - */ -public interface VPackAnnotationFieldNaming { - - String name(A annotation); - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackDeserializationContext.java b/src/main/java/com/arangodb/velocypack/VPackDeserializationContext.java deleted file mode 100644 index 42d638d..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackDeserializationContext.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.exception.VPackParserException; - -/** - * @author Mark Vollmary - * - */ -public interface VPackDeserializationContext { - - T deserialize(final VPackSlice vpack, final java.lang.reflect.Type type) throws VPackParserException; - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackDeserializer.java b/src/main/java/com/arangodb/velocypack/VPackDeserializer.java deleted file mode 100644 index 2379165..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackDeserializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.exception.VPackException; - -/** - * @author Mark Vollmary - * - */ -public interface VPackDeserializer { - - T deserialize(VPackSlice parent, VPackSlice vpack, VPackDeserializationContext context) throws VPackException; - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackDeserializerParameterizedType.java b/src/main/java/com/arangodb/velocypack/VPackDeserializerParameterizedType.java deleted file mode 100644 index a2572e4..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackDeserializerParameterizedType.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import java.lang.reflect.ParameterizedType; - -import com.arangodb.velocypack.exception.VPackException; - -/** - * @author Mark Vollmary - * - */ -public interface VPackDeserializerParameterizedType extends VPackDeserializer { - - T deserialize(VPackSlice parent, VPackSlice vpack, VPackDeserializationContext context, ParameterizedType type) - throws VPackException; - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackFieldNamingStrategy.java b/src/main/java/com/arangodb/velocypack/VPackFieldNamingStrategy.java deleted file mode 100644 index a2729a8..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackFieldNamingStrategy.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import java.lang.reflect.Field; - -/** - * @author Mark Vollmary - * - */ -public interface VPackFieldNamingStrategy { - - String translateName(Field field); - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackInstanceCreator.java b/src/main/java/com/arangodb/velocypack/VPackInstanceCreator.java deleted file mode 100644 index 6b50b8e..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackInstanceCreator.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -/** - * @author Mark Vollmary - * - */ -public interface VPackInstanceCreator { - - T createInstance(); - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackJsonDeserializer.java b/src/main/java/com/arangodb/velocypack/VPackJsonDeserializer.java deleted file mode 100644 index 97a066f..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackJsonDeserializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.exception.VPackException; - -/** - * @author Mark Vollmary - * - */ -public interface VPackJsonDeserializer { - - void deserialize(VPackSlice parent, String attribute, VPackSlice vpack, StringBuilder json) throws VPackException; - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackJsonSerializer.java b/src/main/java/com/arangodb/velocypack/VPackJsonSerializer.java deleted file mode 100644 index 4e7e78b..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackJsonSerializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.exception.VPackException; - -/** - * @author Mark Vollmary - * - */ -public interface VPackJsonSerializer { - - void serialize(VPackBuilder builder, String attribute, T value) throws VPackException; - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackKeyMapAdapter.java b/src/main/java/com/arangodb/velocypack/VPackKeyMapAdapter.java deleted file mode 100644 index 9121c15..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackKeyMapAdapter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -/** - * @author Mark Vollmary - * - */ -public interface VPackKeyMapAdapter { - - String serialize(T key); - - T deserialize(String key); - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackModule.java b/src/main/java/com/arangodb/velocypack/VPackModule.java deleted file mode 100644 index 954b63b..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackModule.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -/** - * @author Mark Vollmary - * - */ -public interface VPackModule { - - > void setup(C context); - -} \ No newline at end of file diff --git a/src/main/java/com/arangodb/velocypack/VPackParser.java b/src/main/java/com/arangodb/velocypack/VPackParser.java deleted file mode 100644 index 9963ae1..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackParser.java +++ /dev/null @@ -1,497 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.exception.VPackBuilderException; -import com.arangodb.velocypack.exception.VPackException; -import com.arangodb.velocypack.internal.util.DateUtil; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -/** - * @author Mark Vollmary - */ -public class VPackParser { - - private static final char OBJECT_OPEN = '{'; - private static final char OBJECT_CLOSE = '}'; - private static final char ARRAY_OPEN = '['; - private static final char ARRAY_CLOSE = ']'; - private static final char FIELD = ':'; - private static final char SEPARATOR = ','; - private static final String NULL = "null"; - private static final String NON_REPRESENTABLE_TYPE = "(non-representable type)"; - - private static final JsonFactory jf = new JsonFactory(); - private final Map deserializers; - private final Map> deserializersByName; - private final Map, VPackJsonSerializer> serializers; - private final Map, VPackJsonSerializer>> serializersByName; - - public static class Builder implements VPackParserSetupContext { - private final Map deserializers; - private final Map> deserializersByName; - private final Map, VPackJsonSerializer> serializers; - private final Map, VPackJsonSerializer>> serializersByName; - - public Builder() { - super(); - deserializers = new HashMap<>(); - deserializersByName = new HashMap<>(); - serializers = new HashMap<>(); - serializersByName = new HashMap<>(); - } - - @Override - public VPackParser.Builder registerDeserializer( - final String attribute, - final ValueType type, - final VPackJsonDeserializer deserializer) { - Map byName = deserializersByName.get(attribute); - if (byName == null) { - byName = new HashMap<>(); - deserializersByName.put(attribute, byName); - } - byName.put(type, deserializer); - return this; - } - - @Override - public VPackParser.Builder registerDeserializer( - final ValueType type, - final VPackJsonDeserializer deserializer) { - deserializers.put(type, deserializer); - return this; - } - - @Override - public VPackParser.Builder registerSerializer( - final String attribute, - final Class type, - final VPackJsonSerializer serializer) { - Map, VPackJsonSerializer> byName = serializersByName.get(attribute); - if (byName == null) { - byName = new HashMap<>(); - serializersByName.put(attribute, byName); - } - byName.put(type, serializer); - return this; - } - - @Override - public VPackParser.Builder registerSerializer( - final Class type, - final VPackJsonSerializer serializer) { - serializers.put(type, serializer); - return this; - } - - @Override - public Builder registerModule(final VPackParserModule module) { - module.setup(VPackParser.Builder.this); - return this; - } - - @Override - public Builder registerModules(final VPackParserModule... modules) { - for (final VPackParserModule module : modules) { - registerModule(module); - } - return this; - } - - public synchronized VPackParser build() { - return new VPackParser(new HashMap<>(serializers), - new HashMap<>(serializersByName), - new HashMap<>(deserializers), new HashMap<>(deserializersByName)); - } - } - - /** - * @deprecated use {@link VPack.Builder#build()} instead - */ - @Deprecated - public VPackParser() { - this(new HashMap, VPackJsonSerializer>(), - new HashMap, VPackJsonSerializer>>(), - new HashMap(), - new HashMap>()); - } - - private VPackParser(final Map, VPackJsonSerializer> serializers, - final Map, VPackJsonSerializer>> serializersByName, - final Map deserializers, - final Map> deserializersByName) { - super(); - this.serializers = serializers; - this.serializersByName = serializersByName; - this.deserializers = deserializers; - this.deserializersByName = deserializersByName; - } - - /** - * @param attribute - * @param type - * @param deserializer - * @return this - * @deprecated use {@link VPackParser.Builder#registerDeserializer(String, ValueType, VPackJsonDeserializer)} - * instead - */ - @Deprecated - public VPackParser registerDeserializer( - final String attribute, - final ValueType type, - final VPackJsonDeserializer deserializer) { - Map byName = deserializersByName.get(attribute); - if (byName == null) { - byName = new HashMap<>(); - deserializersByName.put(attribute, byName); - } - byName.put(type, deserializer); - return this; - } - - /** - * @param type - * @param deserializer - * @return this - * @deprecated use {@link VPackParser.Builder#registerDeserializer(ValueType, VPackJsonDeserializer)} instead - */ - @Deprecated - public VPackParser registerDeserializer(final ValueType type, final VPackJsonDeserializer deserializer) { - deserializers.put(type, deserializer); - return this; - } - - /** - * @param attribute - * @param type - * @param serializer - * @return this - * @deprecated use {@link VPackParser.Builder#registerSerializer(String, Class, VPackJsonSerializer)} instead - */ - @Deprecated - public VPackParser registerSerializer( - final String attribute, - final Class type, - final VPackJsonSerializer serializer) { - Map, VPackJsonSerializer> byName = serializersByName.get(attribute); - if (byName == null) { - byName = new HashMap<>(); - serializersByName.put(attribute, byName); - } - byName.put(type, serializer); - return this; - } - - /** - * @param type - * @param serializer - * @return this - * @deprecated use {@link VPackParser.Builder#registerSerializer(Class, VPackJsonSerializer)} instead - */ - @Deprecated - public VPackParser registerSerializer(final Class type, final VPackJsonSerializer serializer) { - serializers.put(type, serializer); - return this; - } - - public String toJson(final VPackSlice vpack) throws VPackException { - return toJson(vpack, false); - } - - public String toJson(final VPackSlice vpack, final boolean includeNullValues) throws VPackException { - final StringBuilder json = new StringBuilder(); - parse(null, null, vpack, json, includeNullValues); - return json.toString(); - } - - private VPackJsonDeserializer getDeserializer(final String attribute, final ValueType type) { - VPackJsonDeserializer deserializer = null; - final Map byName = deserializersByName.get(attribute); - if (byName != null) { - deserializer = byName.get(type); - } - if (deserializer == null) { - deserializer = deserializers.get(type); - } - return deserializer; - } - - private VPackJsonSerializer getSerializer(final String attribute, final Class type) { - VPackJsonSerializer serializer = null; - final Map, VPackJsonSerializer> byName = serializersByName.get(attribute); - if (byName != null) { - serializer = byName.get(type); - } - if (serializer == null) { - serializer = serializers.get(type); - } - return serializer; - } - - private void parse( - final VPackSlice parent, - final String attribute, - final VPackSlice value, - final StringBuilder json, - final boolean includeNullValues) throws VPackException { - - VPackJsonDeserializer deserializer = null; - if (attribute != null) { - appendField(attribute, json); - deserializer = getDeserializer(attribute, value.getType()); - } - if (deserializer != null) { - deserializer.deserialize(parent, attribute, value, json); - } else { - if (value.isObject()) { - parseObject(value, json, includeNullValues); - } else if (value.isArray()) { - parseArray(value, json, includeNullValues); - } else if (value.isBoolean()) { - json.append(value.getAsBoolean()); - } else if (value.isString()) { - json.append(toJSONString(value.getAsString())); - } else if (value.isDouble()) { - json.append(value.getAsDouble()); - } else if (value.isInt()) { - json.append(value.getAsLong()); - } else if (value.isNumber()) { - json.append(value.getAsNumber()); - } else if (value.isDate()) { - json.append(toJSONString(DateUtil.format(value.getAsDate()))); - } else if (value.isNull()) { - json.append(NULL); - } else { - json.append((NON_REPRESENTABLE_TYPE)); - } - } - } - - private static void appendField(final String attribute, final StringBuilder json) { - json.append(toJSONString(attribute)).append(FIELD); - } - - private void parseObject(final VPackSlice value, final StringBuilder json, final boolean includeNullValues) - throws VPackException { - json.append(OBJECT_OPEN); - int added = 0; - for (final Iterator> iterator = value.objectIterator(); iterator.hasNext(); ) { - final Entry next = iterator.next(); - final VPackSlice nextValue = next.getValue(); - if (!nextValue.isNull() || includeNullValues) { - if (added++ > 0) { - json.append(SEPARATOR); - } - parse(value, next.getKey(), nextValue, json, includeNullValues); - } - } - json.append(OBJECT_CLOSE); - } - - private void parseArray(final VPackSlice value, final StringBuilder json, final boolean includeNullValues) - throws VPackException { - json.append(ARRAY_OPEN); - int added = 0; - for (final Iterator iterator = value.arrayIterator(); iterator.hasNext(); ) { - final VPackSlice valueAt = iterator.next(); - if (!valueAt.isNull() || includeNullValues) { - if (added++ > 0) { - json.append(SEPARATOR); - } - parse(value, null, valueAt, json, includeNullValues); - } - } - json.append(ARRAY_CLOSE); - } - - public VPackSlice fromJson(final String json) throws VPackException { - return fromJson(json, false); - } - - public VPackSlice fromJson(final String json, final VPackBuilder builder) throws VPackException { - return fromJson(json, false, builder); - } - - public VPackSlice fromJson(final String json, final boolean includeNullValues) throws VPackException { - return fromJson(json, includeNullValues, new VPackBuilder()); - } - - public VPackSlice fromJson(final String json, final boolean includeNullValues, final VPackBuilder builder) throws VPackException { - try { - parse(json, builder, includeNullValues); - } catch (final IOException e) { - throw new VPackBuilderException(e); - } - return builder.slice(); - } - - public VPackSlice fromJson(final Iterable jsons) throws VPackException { - return fromJson(jsons, false); - } - - public VPackSlice fromJson(final Iterable jsons, final VPackBuilder builder) throws VPackException { - return fromJson(jsons, false, builder); - } - - public VPackSlice fromJson(final Iterable jsons, final boolean includeNullValues) throws VPackException { - return fromJson(jsons, includeNullValues, new VPackBuilder()); - } - - public VPackSlice fromJson(final Iterable jsons, final boolean includeNullValues, final VPackBuilder builder) throws VPackException { - try { - builder.add(ValueType.ARRAY); - for (final String json : jsons) { - parse(json, builder, includeNullValues); - } - } catch (final IOException e) { - throw new VPackBuilderException(e); - } - builder.close(); - return builder.slice(); - } - - private void parse(final String json, final VPackBuilder builder, final boolean includeNullValues) - throws IOException { - final JsonParser parser = jf.createParser(json); - String fieldName = null; - JsonToken token; - while (!parser.isClosed() && (token = parser.nextToken()) != null) { - switch (token) { - case START_OBJECT: - case VALUE_EMBEDDED_OBJECT: - builder.add(fieldName, ValueType.OBJECT); - fieldName = null; - break; - case START_ARRAY: - builder.add(fieldName, ValueType.ARRAY); - fieldName = null; - break; - case END_OBJECT: - case END_ARRAY: - builder.close(); - break; - case FIELD_NAME: - fieldName = parser.getCurrentName(); - break; - case VALUE_TRUE: - case VALUE_FALSE: - parseValue(builder, fieldName, parser.getBooleanValue()); - fieldName = null; - break; - case VALUE_NULL: - if (includeNullValues) { - builder.add(fieldName, ValueType.NULL); - } - fieldName = null; - break; - case VALUE_NUMBER_FLOAT: - parseValue(builder, fieldName, parser.getDoubleValue()); - fieldName = null; - break; - case VALUE_NUMBER_INT: - parseValue(builder, fieldName, parser.getLongValue()); - fieldName = null; - break; - case VALUE_STRING: - parseValue(builder, fieldName, parser.getValueAsString()); - fieldName = null; - break; - case NOT_AVAILABLE: - fieldName = null; - default: - break; - } - } - - } - - @SuppressWarnings("unchecked") - private void parseValue(final VPackBuilder builder, final String fieldName, final Object value) { - final VPackJsonSerializer serializer = getSerializer(fieldName, value.getClass()); - if (serializer != null) { - ((VPackJsonSerializer) serializer).serialize(builder, fieldName, value); - } else if (String.class.isAssignableFrom(value.getClass())) { - builder.add(fieldName, (String) value); - } else if (Boolean.class.isAssignableFrom(value.getClass())) { - builder.add(fieldName, (Boolean) value); - } else if (Double.class.isAssignableFrom(value.getClass())) { - builder.add(fieldName, (Double) value); - } else if (Long.class.isAssignableFrom(value.getClass())) { - builder.add(fieldName, (Long) value); - } - } - - public static String toJSONString(final String text) { - if (text == null) { - return null; - } - - StringBuilder w = new StringBuilder(text.length()) - .append('"'); - - int len = text.length(); - for (int i = 0; i < len; i++) { - char c = text.charAt(i); - switch (c) { - case '\\': - case '"': - w.append('\\'); - w.append(c); - break; - case '\b': - w.append("\\b"); - break; - case '\t': - w.append("\\t"); - break; - case '\n': - w.append("\\n"); - break; - case '\f': - w.append("\\f"); - break; - case '\r': - w.append("\\r"); - break; - default: - if (c <= '\u001f') { - w.append("\\u"); - String hhhh = Integer.toHexString(c); - w.append("0000", 0, 4 - hhhh.length()); - w.append(hhhh); - } else { - w.append(c); - } - } - } - return w.append('"').toString(); - } - -} \ No newline at end of file diff --git a/src/main/java/com/arangodb/velocypack/VPackParserModule.java b/src/main/java/com/arangodb/velocypack/VPackParserModule.java deleted file mode 100644 index 675f1d1..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackParserModule.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -/** - * @author Mark Vollmary - * - */ -public interface VPackParserModule { - - > void setup(C context); - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackParserSetupContext.java b/src/main/java/com/arangodb/velocypack/VPackParserSetupContext.java deleted file mode 100644 index ba1469d..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackParserSetupContext.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -/** - * @author Mark Vollmary - * - */ -public interface VPackParserSetupContext> { - - C registerDeserializer(final String attribute, final ValueType type, final VPackJsonDeserializer deserializer); - - C registerDeserializer(final ValueType type, final VPackJsonDeserializer deserializer); - - C registerSerializer(final String attribute, final Class type, final VPackJsonSerializer serializer); - - C registerSerializer(final Class type, final VPackJsonSerializer serializer); - - C registerModule(VPackParserModule module); - - C registerModules(VPackParserModule... modules); - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackSerializationContext.java b/src/main/java/com/arangodb/velocypack/VPackSerializationContext.java deleted file mode 100644 index 7302ac2..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackSerializationContext.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.exception.VPackParserException; - -/** - * @author Mark Vollmary - * - */ -public interface VPackSerializationContext { - - void serialize(final VPackBuilder builder, final String attribute, final Object entity) throws VPackParserException; - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackSerializer.java b/src/main/java/com/arangodb/velocypack/VPackSerializer.java deleted file mode 100644 index 3a58c6d..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackSerializer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.exception.VPackException; - -/** - * @author Mark Vollmary - * - */ -public interface VPackSerializer { - - void serialize(VPackBuilder builder, String attribute, T value, VPackSerializationContext context) - throws VPackException; - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackSetupContext.java b/src/main/java/com/arangodb/velocypack/VPackSetupContext.java deleted file mode 100644 index 7598b51..0000000 --- a/src/main/java/com/arangodb/velocypack/VPackSetupContext.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; - -/** - * @author Mark Vollmary - * - */ -public interface VPackSetupContext> { - - C registerSerializer(final Type type, final VPackSerializer serializer); - - C registerEnclosingSerializer(final Type type, final VPackSerializer serializer); - - C registerDeserializer(final Type type, final VPackDeserializer deserializer); - - C registerDeserializer(final Type type, final VPackDeserializer deserializer, boolean includeNullValues); - - C registerDeserializer(final String fieldName, final Type type, final VPackDeserializer deserializer); - - C registerDeserializer( - final String fieldName, - final Type type, - final VPackDeserializer deserializer, - boolean includeNullValues); - - C registerInstanceCreator(final Type type, final VPackInstanceCreator creator); - - C buildUnindexedArrays(final boolean buildUnindexedArrays); - - C buildUnindexedObjects(final boolean buildUnindexedObjects); - - C serializeNullValues(final boolean serializeNullValues); - - C fieldNamingStrategy(final VPackFieldNamingStrategy fieldNamingStrategy); - - C annotationFieldFilter( - final Class type, - final VPackAnnotationFieldFilter fieldFilter); - - C annotationFieldNaming( - final Class type, - final VPackAnnotationFieldNaming fieldNaming); - - C registerKeyMapAdapter(final Type type, final VPackKeyMapAdapter adapter); - - C registerModule(VPackModule module); - - C registerModules(VPackModule... modules); - - C typeKey(final String typeKey); - - C useTypeHints(final boolean useTypeHints); - -} diff --git a/src/main/java/com/arangodb/velocypack/VPackSlice.java b/src/main/java/com/arangodb/velocypack/VPackSlice.java index d9bd32c..fff4eed 100644 --- a/src/main/java/com/arangodb/velocypack/VPackSlice.java +++ b/src/main/java/com/arangodb/velocypack/VPackSlice.java @@ -941,15 +941,6 @@ private void doGetSchemaDescription(StringBuilder sb, int level) { } } - @Override - public String toString() { - try { - return new VPackParser.Builder().build().toJson(this, true); - } catch (final VPackException e) { - return super.toString(); - } - } - @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/com/arangodb/velocypack/annotations/Expose.java b/src/main/java/com/arangodb/velocypack/annotations/Expose.java deleted file mode 100644 index 57aaffd..0000000 --- a/src/main/java/com/arangodb/velocypack/annotations/Expose.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Mark Vollmary - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface Expose { - - boolean serialize() default true; - - boolean deserialize() default true; - -} diff --git a/src/main/java/com/arangodb/velocypack/annotations/SerializedName.java b/src/main/java/com/arangodb/velocypack/annotations/SerializedName.java deleted file mode 100644 index a377b66..0000000 --- a/src/main/java/com/arangodb/velocypack/annotations/SerializedName.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Mark Vollmary - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) -public @interface SerializedName { - - String value(); - -} diff --git a/src/main/java/com/arangodb/velocypack/annotations/VPackCreator.java b/src/main/java/com/arangodb/velocypack/annotations/VPackCreator.java deleted file mode 100644 index d760d27..0000000 --- a/src/main/java/com/arangodb/velocypack/annotations/VPackCreator.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ - -@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR }) -@Retention(RetentionPolicy.RUNTIME) -public @interface VPackCreator { - -} diff --git a/src/main/java/com/arangodb/velocypack/annotations/VPackDeserialize.java b/src/main/java/com/arangodb/velocypack/annotations/VPackDeserialize.java deleted file mode 100644 index a87b994..0000000 --- a/src/main/java/com/arangodb/velocypack/annotations/VPackDeserialize.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER }) -@Retention(RetentionPolicy.RUNTIME) -public @interface VPackDeserialize { - - String UNDEFINED_BUILD_METHOD_NAME = "__UNDEFINED_BUILD_METHOD_NAME__"; - String UNDEFINED_WITH_PREFIX = "__UNDEFINED_WITH_PREFIX__"; - - Class builder(); - - VPackPOJOBuilder builderConfig() default @VPackPOJOBuilder(buildMethodName = UNDEFINED_BUILD_METHOD_NAME, - withSetterPrefix = UNDEFINED_WITH_PREFIX); - -} diff --git a/src/main/java/com/arangodb/velocypack/annotations/VPackPOJOBuilder.java b/src/main/java/com/arangodb/velocypack/annotations/VPackPOJOBuilder.java deleted file mode 100644 index edcffaa..0000000 --- a/src/main/java/com/arangodb/velocypack/annotations/VPackPOJOBuilder.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.METHOD }) -public @interface VPackPOJOBuilder { - - String DEFAULT_BUILD_METHOD_NAME = "build"; - String DEFAULT_WITH_PREFIX = ""; - - String buildMethodName() default DEFAULT_BUILD_METHOD_NAME; - - String withSetterPrefix() default DEFAULT_WITH_PREFIX; - - class Value { - public final String buildMethodName; - public final String withSetterPrefix; - - public Value() { - this(DEFAULT_BUILD_METHOD_NAME, DEFAULT_WITH_PREFIX); - } - - public Value(VPackPOJOBuilder annotation) { - this(annotation.buildMethodName(), annotation.withSetterPrefix()); - } - - public Value(String buildMethodName, String withSetterPrefix) { - this.buildMethodName = buildMethodName; - this.withSetterPrefix = withSetterPrefix; - } - } - -} diff --git a/src/main/java/com/arangodb/velocypack/internal/VPackBuilderUtils.java b/src/main/java/com/arangodb/velocypack/internal/VPackBuilderUtils.java deleted file mode 100644 index b7a67c1..0000000 --- a/src/main/java/com/arangodb/velocypack/internal/VPackBuilderUtils.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.internal; - -import com.arangodb.velocypack.annotations.VPackDeserialize; -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; - -import java.lang.annotation.Annotation; -import java.lang.reflect.*; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Michele Rastelli - */ -public class VPackBuilderUtils { - private final Map cache; - - public abstract static class BuilderInfo { - - public Class builderClass; - - public VPackPOJOBuilder.Value annotation; - - public BuilderInfo(Class builderClass, VPackPOJOBuilder.Value annotation) { - this.builderClass = builderClass; - this.annotation = annotation; - } - - public abstract Object createBuilder() throws ReflectiveOperationException; - - } - - private static class CacheKey { - private final Type type; - private final AnnotatedElement referencingElement; - - public CacheKey(Type type, AnnotatedElement referencingElement) { - this.type = type; - this.referencingElement = referencingElement; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - CacheKey cacheKey = (CacheKey) o; - return Objects.equals(type, cacheKey.type) && Objects - .equals(referencingElement, cacheKey.referencingElement); - } - - @Override - public int hashCode() { - return Objects.hash(type, referencingElement); - } - - } - - public VPackBuilderUtils() { - cache = new ConcurrentHashMap<>(); - } - - public BuilderInfo getBuilderInfo(Type type, AnnotatedElement referencingElement) { - if (type instanceof ParameterizedType) - return getBuilderInfo(((ParameterizedType) type).getRawType(), referencingElement); - - if (type instanceof WildcardType) - return getBuilderInfo(((WildcardType) type).getUpperBounds()[0], referencingElement); - - if (!(type instanceof Class)) - return null; - - final Class clazz = (Class) type; - - final CacheKey key = new CacheKey(clazz, referencingElement); - BuilderInfo fromCache = cache.get(key); - if (fromCache != null) - return fromCache; - - BuilderInfo builderInfo; - - builderInfo = getReferencingElementInfo(referencingElement); - if (builderInfo == null) { - builderInfo = getDeserializeClassInfo(clazz); - } - if (builderInfo == null) { - builderInfo = getBuilderMethodInfo(clazz); - } - if (builderInfo == null) { - builderInfo = getInnerBuilderInfo(clazz); - } - - if (builderInfo == null) { - return null; - } - - // search builder info in class referenced by @VPackDeserialize.builder - if (builderInfo.annotation == null) { - Class builderClass = builderInfo.builderClass; - BuilderInfo additionalBuilderInfo = getBuilderMethodInfo(builderClass); - if (additionalBuilderInfo == null) { - additionalBuilderInfo = getBuilderInfo(builderClass); - } - if (additionalBuilderInfo != null) { - builderInfo = additionalBuilderInfo; - } - } - - if (builderInfo.annotation == null) { - builderInfo.annotation = new VPackPOJOBuilder.Value(); - } - - cache.put(key, builderInfo); - return builderInfo; - } - - private BuilderInfo getBuilderMethodInfo(final Class clazz) { - for (final Method method : clazz.getDeclaredMethods()) { - for (final Annotation annotation : method.getDeclaredAnnotations()) { - if (annotation instanceof VPackPOJOBuilder) { - return new BuilderInfo(method.getReturnType(), mapVPackPOJOBuilder((VPackPOJOBuilder) annotation)) { - @Override - public Object createBuilder() throws ReflectiveOperationException { - return method.invoke(null); - } - }; - } - } - } - - return null; - } - - private BuilderInfo getInnerBuilderInfo(final Class clazz) { - for (final Class innerClass : clazz.getDeclaredClasses()) { - for (final Annotation annotation : innerClass.getDeclaredAnnotations()) { - if (annotation instanceof VPackPOJOBuilder) { - return new BuilderInfo(innerClass, mapVPackPOJOBuilder((VPackPOJOBuilder) annotation)) { - @Override - public Object createBuilder() throws ReflectiveOperationException { - return innerClass.newInstance(); - } - }; - } - } - } - - return null; - } - - private BuilderInfo getBuilderInfo(final Class clazz) { - for (final Annotation annotation : clazz.getDeclaredAnnotations()) { - if (annotation instanceof VPackPOJOBuilder) { - return new BuilderInfo(clazz, mapVPackPOJOBuilder((VPackPOJOBuilder) annotation)) { - @Override - public Object createBuilder() throws ReflectiveOperationException { - return clazz.newInstance(); - } - }; - } - } - - return null; - } - - private BuilderInfo getDeserializeClassInfo(final Class clazz) { - for (final Annotation annotation : clazz.getDeclaredAnnotations()) { - if (annotation instanceof VPackDeserialize) { - final VPackDeserialize vPackDeserialize = (VPackDeserialize) annotation; - return new BuilderInfo(vPackDeserialize.builder(), - mapVPackPOJOBuilder(vPackDeserialize.builderConfig())) { - @Override - public Object createBuilder() throws ReflectiveOperationException { - return vPackDeserialize.builder().newInstance(); - } - }; - } - } - - return null; - } - - private BuilderInfo getReferencingElementInfo(AnnotatedElement ref) { - if (ref == null) - return null; - - for (final Annotation annotation : ref.getDeclaredAnnotations()) { - if (annotation instanceof VPackDeserialize) { - final VPackDeserialize vPackDeserialize = (VPackDeserialize) annotation; - return new BuilderInfo(vPackDeserialize.builder(), - mapVPackPOJOBuilder(vPackDeserialize.builderConfig())) { - @Override - public Object createBuilder() throws ReflectiveOperationException { - return vPackDeserialize.builder().newInstance(); - } - }; - } - } - - return null; - } - - private VPackPOJOBuilder.Value mapVPackPOJOBuilder(VPackPOJOBuilder annotation) { - if (annotation.withSetterPrefix().equals(VPackDeserialize.UNDEFINED_WITH_PREFIX) && annotation.buildMethodName() - .equals(VPackDeserialize.UNDEFINED_BUILD_METHOD_NAME)) { - return null; - } - - return new VPackPOJOBuilder.Value(annotation); - } -} diff --git a/src/main/java/com/arangodb/velocypack/internal/VPackCache.java b/src/main/java/com/arangodb/velocypack/internal/VPackCache.java deleted file mode 100644 index 9ad4b94..0000000 --- a/src/main/java/com/arangodb/velocypack/internal/VPackCache.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.internal; - -import com.arangodb.velocypack.VPackAnnotationFieldFilter; -import com.arangodb.velocypack.VPackAnnotationFieldNaming; -import com.arangodb.velocypack.VPackFieldNamingStrategy; -import com.arangodb.velocypack.internal.VPackCreatorMethodUtils.ParameterInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.annotation.Annotation; -import java.lang.reflect.*; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Mark Vollmary - * - */ -public class VPackCache { - - public abstract static class FieldInfo { - private final AnnotatedElement referencingElement; - private final Type type; - private final String fieldName; - private final boolean serialize; - private final boolean deserialize; - - private FieldInfo( - final AnnotatedElement referencingElement, - final Type type, - final String fieldName, - final boolean serialize, - final boolean deserialize) { - super(); - this.referencingElement = referencingElement; - this.type = type; - this.fieldName = fieldName; - this.serialize = serialize; - this.deserialize = deserialize; - } - - public AnnotatedElement getReferencingElement() { - return referencingElement; - } - - public Type getType() { - return type; - } - - public String getFieldName() { - return fieldName; - } - - public boolean isSerialize() { - return serialize; - } - - public boolean isDeserialize() { - return deserialize; - } - - public abstract void set(Object obj, Object value) throws ReflectiveOperationException; - - public abstract Object get(Object obj) throws ReflectiveOperationException; - } - - private static final Logger LOGGER = LoggerFactory.getLogger(VPackCache.class); - - private final Map> cache; - private final Map> parameterCreatorCache; - private final Comparator> fieldComparator; - private final VPackFieldNamingStrategy fieldNamingStrategy; - - private final Map, VPackAnnotationFieldFilter> annotationFilter; - private final Map, VPackAnnotationFieldNaming> annotationFieldNaming; - - public VPackCache( - final VPackFieldNamingStrategy fieldNamingStrategy, - final Map, VPackAnnotationFieldFilter> annotationFieldFilter, - final Map, VPackAnnotationFieldNaming> annotationFieldNaming) { - super(); - cache = new ConcurrentHashMap<>(); - parameterCreatorCache = new ConcurrentHashMap<>(); - fieldComparator = new Comparator>() { - @Override - public int compare(final Entry o1, final Entry o2) { - return o1.getKey().compareTo(o2.getKey()); - } - }; - this.fieldNamingStrategy = fieldNamingStrategy; - this.annotationFilter = annotationFieldFilter; - this.annotationFieldNaming = annotationFieldNaming; - } - - public Map getFields(final Type entityClass) { - Map fields = cache.get(entityClass); - if (fields == null) { - fields = new HashMap<>(); - Class tmp = (Class) entityClass; - while (tmp != null && tmp != Object.class) { - final Field[] declaredFields = tmp.getDeclaredFields(); - for (final Field field : declaredFields) { - if (!field.isSynthetic() && !Modifier.isStatic(field.getModifiers()) && !Modifier - .isTransient(field.getModifiers())) { - field.setAccessible(true); - final FieldInfo fieldInfo = createFieldInfo(field); - if (fieldInfo.serialize || fieldInfo.deserialize) { - fields.put(fieldInfo.getFieldName(), fieldInfo); - } - } - } - tmp = tmp.getSuperclass(); - } - fields = sort(fields.entrySet()); - cache.put(entityClass, fields); - } - return fields; - } - - public LinkedHashMap getParameters(final Executable factoryMethod) { - LinkedHashMap fromCache = parameterCreatorCache.get(factoryMethod); - if (fromCache != null) { - return fromCache; - } - - LinkedHashMap fields = new LinkedHashMap<>(); - for (Parameter parameter : factoryMethod.getParameters()) { - final ParameterInfo parameterInfo = createParameterInfo(parameter); - fields.put(parameterInfo.name, parameterInfo); - } - - parameterCreatorCache.put(factoryMethod, fields); - return fields; - } - - private boolean matchSetter(final Method method, String withSetterPrefix) { - // check name - if (!method.getName().startsWith(withSetterPrefix)) - return false; - - int modifiers = method.getModifiers(); - - // check modifiers - if (method.isSynthetic() || Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)) - return false; - - // check public - if (!Modifier.isPublic(modifiers)) - return false; - - // check parameters - if (method.getGenericParameterTypes().length != 1) - return false; - - return true; - } - - public Map getBuiderSetters(final Type entityClass, String withSetterPrefix) { - Map fields = cache.get(entityClass); - if (fields == null) { - fields = new HashMap<>(); - Class tmp = (Class) entityClass; - while (tmp != null && tmp != Object.class) { - final Method[] declaredMethods = tmp.getDeclaredMethods(); - for (final Method method : declaredMethods) { - if (matchSetter(method, withSetterPrefix)) { - final FieldInfo fieldInfo = createSetterInfo(method, withSetterPrefix); - if (fieldInfo.serialize || fieldInfo.deserialize) { - fields.put(fieldInfo.getFieldName(), fieldInfo); - } - } - } - tmp = tmp.getSuperclass(); - } - fields = sort(fields.entrySet()); - cache.put(entityClass, fields); - } - return fields; - } - - private Map sort(final Set> entrySet) { - final Map sorted = new LinkedHashMap<>(); - final List> tmp = new ArrayList<>(entrySet); - Collections.sort(tmp, fieldComparator); - for (final Entry entry : tmp) { - sorted.put(entry.getKey(), entry.getValue()); - } - return sorted; - } - - @SuppressWarnings("unchecked") - private FieldInfo createFieldInfo(final Field field) { - String fieldName = field.getName(); - if (fieldNamingStrategy != null) { - fieldName = fieldNamingStrategy.translateName(field); - } - boolean found = false; - for (final Entry, VPackAnnotationFieldNaming> entry : annotationFieldNaming - .entrySet()) { - final Annotation annotation = field.getAnnotation(entry.getKey()); - if (annotation != null) { - fieldName = ((VPackAnnotationFieldNaming) entry.getValue()).name(annotation); - if (found) { - LOGGER.warn(String.format( - "Found additional annotation %s for field %s. Override previous annotation informations.", - entry.getKey().getSimpleName(), field.getName())); - } - found = true; - } - } - boolean serialize = true; - boolean deserialize = true; - found = false; - for (final Entry, VPackAnnotationFieldFilter> entry : annotationFilter - .entrySet()) { - final Annotation annotation = field.getAnnotation(entry.getKey()); - if (annotation != null) { - final VPackAnnotationFieldFilter filter = (VPackAnnotationFieldFilter) entry - .getValue(); - serialize = filter.serialize(annotation); - deserialize = filter.deserialize(annotation); - if (found) { - LOGGER.warn(String.format( - "Found additional annotation %s for field %s. Override previous annotation informations.", - entry.getKey().getSimpleName(), field.getName())); - } - found = true; - } - } - final Class clazz = field.getType(); - final Type type = (clazz == Object.class) ? Object.class : field.getGenericType(); - return new FieldInfo(field, type, fieldName, serialize, deserialize) { - @Override - public void set(final Object obj, final Object value) throws IllegalAccessException { - field.set(obj, value); - } - - @Override - public Object get(final Object obj) throws IllegalAccessException { - return field.get(obj); - } - }; - } - - @SuppressWarnings("unchecked") - private ParameterInfo createParameterInfo(final Parameter parameter) { - String fieldName = parameter.getName(); - for (final Entry, VPackAnnotationFieldNaming> entry : annotationFieldNaming - .entrySet()) { - final Annotation annotation = parameter.getAnnotation(entry.getKey()); - if (annotation != null) { - fieldName = ((VPackAnnotationFieldNaming) entry.getValue()).name(annotation); - } - } - final Class clazz = parameter.getType(); - final Type type = (clazz == Object.class) ? Object.class : parameter.getParameterizedType(); - return new ParameterInfo(parameter, type, fieldName); - } - - @SuppressWarnings("unchecked") - private FieldInfo createSetterInfo(final Method setter, String withSetterPrefix) { - int prefixLength = withSetterPrefix.length(); - String setterName = setter.getName(); - String fieldName = setterName.substring(prefixLength, prefixLength + 1).toLowerCase() + setterName - .substring(prefixLength + 1); - - boolean found = false; - for (final Entry, VPackAnnotationFieldNaming> entry : annotationFieldNaming - .entrySet()) { - final Annotation annotation = setter.getAnnotation(entry.getKey()); - if (annotation != null) { - fieldName = ((VPackAnnotationFieldNaming) entry.getValue()).name(annotation); - if (found) { - LOGGER.warn(String.format( - "Found additional annotation %s for field %s. Override previous annotation informations.", - entry.getKey().getSimpleName(), setter.getName())); - } - found = true; - } - } - boolean serialize = true; - boolean deserialize = true; - found = false; - for (final Entry, VPackAnnotationFieldFilter> entry : annotationFilter - .entrySet()) { - final Annotation annotation = setter.getAnnotation(entry.getKey()); - if (annotation != null) { - final VPackAnnotationFieldFilter filter = (VPackAnnotationFieldFilter) entry - .getValue(); - serialize = filter.serialize(annotation); - deserialize = filter.deserialize(annotation); - if (found) { - LOGGER.warn(String.format( - "Found additional annotation %s for field %s. Override previous annotation informations.", - entry.getKey().getSimpleName(), setter.getName())); - } - found = true; - } - } - - final Class clazz = setter.getParameterTypes()[0]; - final Type type = (clazz == Object.class) ? Object.class : setter.getGenericParameterTypes()[0]; - return new FieldInfo(setter, type, fieldName, serialize, deserialize) { - @Override - public void set(final Object obj, final Object value) throws ReflectiveOperationException { - setter.invoke(obj, value); - } - - @Override - public Object get(final Object obj) { - throw new UnsupportedOperationException(); - } - }; - } - -} diff --git a/src/main/java/com/arangodb/velocypack/internal/VPackCreatorMethodUtils.java b/src/main/java/com/arangodb/velocypack/internal/VPackCreatorMethodUtils.java deleted file mode 100644 index 322db5d..0000000 --- a/src/main/java/com/arangodb/velocypack/internal/VPackCreatorMethodUtils.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.internal; - -import com.arangodb.velocypack.annotations.VPackCreator; - -import java.lang.annotation.Annotation; -import java.lang.reflect.*; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Michele Rastelli - */ -public class VPackCreatorMethodUtils { - private final Map cache; - - public static class ParameterInfo { - public final AnnotatedElement referencingElement; - public final Type type; - public final String name; - - public ParameterInfo(AnnotatedElement referencingElement, Type type, String name) { - this.referencingElement = referencingElement; - this.type = type; - this.name = name; - } - } - - public interface VPackCreatorMethodInfo { - Executable getExecutable(); - - Object create(Object... args) throws ReflectiveOperationException; - } - - private class FactoryMethodInfo implements VPackCreatorMethodInfo { - private final Method factoryMethod; - - public FactoryMethodInfo(final Method factoryMethod) { - this.factoryMethod = factoryMethod; - } - - @Override - public Executable getExecutable() { - return factoryMethod; - } - - @Override - public Object create(Object... args) throws ReflectiveOperationException { - return factoryMethod.invoke(null, args); - } - } - - private class AllArgsConstructorInfo implements VPackCreatorMethodInfo { - private final Constructor constructor; - - public AllArgsConstructorInfo(final Constructor constructor) { - this.constructor = constructor; - } - - @Override - public Executable getExecutable() { - return constructor; - } - - @Override - public Object create(Object... args) throws ReflectiveOperationException { - return constructor.newInstance(args); - } - } - - public VPackCreatorMethodUtils() { - cache = new ConcurrentHashMap<>(); - } - - public VPackCreatorMethodInfo getCreatorMethodInfo(Type type) { - if (!(type instanceof Class)) - return null; - - VPackCreatorMethodInfo fromCache = cache.get(type); - if (fromCache != null) - return fromCache; - - Class clazz = (Class) type; - for (final Method method : clazz.getDeclaredMethods()) { - for (final Annotation annotation : method.getDeclaredAnnotations()) { - if (annotation instanceof VPackCreator) { - FactoryMethodInfo info = new FactoryMethodInfo(method); - cache.put(type, info); - return info; - } - } - } - - for (final Constructor constructor : clazz.getDeclaredConstructors()) { - for (final Annotation annotation : constructor.getDeclaredAnnotations()) { - if (annotation instanceof VPackCreator) { - AllArgsConstructorInfo info = new AllArgsConstructorInfo(constructor); - cache.put(type, info); - return info; - } - } - } - - return null; - } - -} diff --git a/src/main/java/com/arangodb/velocypack/internal/VPackDeserializers.java b/src/main/java/com/arangodb/velocypack/internal/VPackDeserializers.java deleted file mode 100644 index e23c71e..0000000 --- a/src/main/java/com/arangodb/velocypack/internal/VPackDeserializers.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.internal; - -import com.arangodb.velocypack.VPackDeserializationContext; -import com.arangodb.velocypack.VPackDeserializer; -import com.arangodb.velocypack.VPackSlice; -import com.arangodb.velocypack.exception.VPackException; -import com.arangodb.velocypack.exception.VPackParserException; -import com.arangodb.velocypack.internal.util.DateUtil; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Timestamp; -import java.text.ParseException; -import java.util.Base64; -import java.util.Date; -import java.util.UUID; - -/** - * @author Mark Vollmary - * - */ -public class VPackDeserializers { - - private VPackDeserializers() { - super(); - } - - public static final VPackDeserializer STRING = new VPackDeserializer() { - @Override - public String deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsString(); - } - }; - public static final VPackDeserializer BOOLEAN = new VPackDeserializer() { - @Override - public Boolean deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsBoolean(); - } - }; - public static final VPackDeserializer INTEGER = new VPackDeserializer() { - @Override - public Integer deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsInt(); - } - }; - public static final VPackDeserializer LONG = new VPackDeserializer() { - @Override - public Long deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsLong(); - } - }; - public static final VPackDeserializer SHORT = new VPackDeserializer() { - @Override - public Short deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsShort(); - } - }; - public static final VPackDeserializer DOUBLE = new VPackDeserializer() { - @Override - public Double deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsDouble(); - } - }; - public static final VPackDeserializer FLOAT = new VPackDeserializer() { - @Override - public Float deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsFloat(); - } - }; - public static final VPackDeserializer BIG_INTEGER = new VPackDeserializer() { - @Override - public BigInteger deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsBigInteger(); - } - }; - public static final VPackDeserializer BIG_DECIMAL = new VPackDeserializer() { - @Override - public BigDecimal deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsBigDecimal(); - } - }; - public static final VPackDeserializer NUMBER = new VPackDeserializer() { - @Override - public Number deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsNumber(); - } - }; - public static final VPackDeserializer CHARACTER = new VPackDeserializer() { - @Override - public Character deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsChar(); - } - }; - public static final VPackDeserializer DATE = new VPackDeserializer() { - @Override - public Date deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - final Date date; - if (vpack.isString()) { - try { - date = DateUtil.parse(vpack.getAsString()); - } catch (final ParseException e) { - throw new VPackParserException(e); - } - } else { - date = vpack.getAsDate(); - } - return date; - } - }; - public static final VPackDeserializer SQL_DATE = new VPackDeserializer() { - - @Override - public java.sql.Date deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - final java.sql.Date date; - if (vpack.isString()) { - try { - date = new java.sql.Date(DateUtil.parse(vpack.getAsString()).getTime()); - } catch (final ParseException e) { - throw new VPackParserException(e); - } - } else { - date = vpack.getAsSQLDate(); - } - return date; - } - }; - public static final VPackDeserializer SQL_TIMESTAMP = new VPackDeserializer() { - @Override - public Timestamp deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - final java.sql.Timestamp date; - if (vpack.isString()) { - try { - date = new java.sql.Timestamp(DateUtil.parse(vpack.getAsString()).getTime()); - } catch (final ParseException e) { - throw new VPackParserException(e); - } - } else { - date = vpack.getAsSQLTimestamp(); - } - return date; - } - }; - public static final VPackDeserializer VPACK = new VPackDeserializer() { - @Override - public VPackSlice deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack; - } - }; - public static final VPackDeserializer UUID = new VPackDeserializer() { - @Override - public UUID deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return java.util.UUID.fromString(vpack.getAsString()); - } - }; - public static final VPackDeserializer BYTE_ARRAY = new VPackDeserializer() { - @Override - public byte[] deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return Base64.getDecoder().decode(vpack.getAsString()); - } - - }; - public static final VPackDeserializer BYTE = new VPackDeserializer() { - @Override - public Byte deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) { - return vpack.getAsByte(); - } - }; - -} diff --git a/src/main/java/com/arangodb/velocypack/internal/VPackInstanceCreators.java b/src/main/java/com/arangodb/velocypack/internal/VPackInstanceCreators.java deleted file mode 100644 index 857aa39..0000000 --- a/src/main/java/com/arangodb/velocypack/internal/VPackInstanceCreators.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.internal; - -import com.arangodb.velocypack.VPackInstanceCreator; - -import java.util.*; - -/** - * @author Mark Vollmary - * - */ -@SuppressWarnings("rawtypes") -public class VPackInstanceCreators { - - private VPackInstanceCreators() { - super(); - } - - public static final VPackInstanceCreator ITERABLE = new VPackInstanceCreator() { - @Override - public Iterable createInstance() { - return new ArrayList(); - } - }; - public static final VPackInstanceCreator COLLECTION = new VPackInstanceCreator() { - @Override - public Collection createInstance() { - return new ArrayList(); - } - }; - public static final VPackInstanceCreator LIST = new VPackInstanceCreator() { - @Override - public List createInstance() { - return new ArrayList(); - } - }; - public static final VPackInstanceCreator SET = new VPackInstanceCreator() { - @Override - public Set createInstance() { - return new LinkedHashSet(); - } - }; - public static final VPackInstanceCreator MAP = new VPackInstanceCreator() { - @Override - public Map createInstance() { - return new LinkedHashMap(); - } - }; - -} diff --git a/src/main/java/com/arangodb/velocypack/internal/VPackKeyMapAdapters.java b/src/main/java/com/arangodb/velocypack/internal/VPackKeyMapAdapters.java deleted file mode 100644 index 7824e16..0000000 --- a/src/main/java/com/arangodb/velocypack/internal/VPackKeyMapAdapters.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.internal; - -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; - -import com.arangodb.velocypack.VPackKeyMapAdapter; - -/** - * @author Mark Vollmary - * - */ -public class VPackKeyMapAdapters { - - private VPackKeyMapAdapters() { - super(); - } - - public static VPackKeyMapAdapter> createEnumAdapter(final Type type) { - return new VPackKeyMapAdapter>() { - @Override - public String serialize(final Enum key) { - return key.name(); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Enum deserialize(final String key) { - final Class enumType = (Class) type; - return Enum.valueOf(enumType, key); - } - }; - } - - public static final VPackKeyMapAdapter STRING = new VPackKeyMapAdapter() { - @Override - public String serialize(final String key) { - return key; - } - - @Override - public String deserialize(final String key) { - return key; - } - }; - public static final VPackKeyMapAdapter BOOLEAN = new VPackKeyMapAdapter() { - @Override - public String serialize(final Boolean key) { - return key.toString(); - } - - @Override - public Boolean deserialize(final String key) { - return Boolean.valueOf(key); - } - }; - public static final VPackKeyMapAdapter INTEGER = new VPackKeyMapAdapter() { - @Override - public String serialize(final Integer key) { - return key.toString(); - } - - @Override - public Integer deserialize(final String key) { - return Integer.valueOf(key); - } - }; - public static final VPackKeyMapAdapter LONG = new VPackKeyMapAdapter() { - @Override - public String serialize(final Long key) { - return key.toString(); - } - - @Override - public Long deserialize(final String key) { - return Long.valueOf(key); - } - }; - public static final VPackKeyMapAdapter SHORT = new VPackKeyMapAdapter() { - @Override - public String serialize(final Short key) { - return key.toString(); - } - - @Override - public Short deserialize(final String key) { - return Short.valueOf(key); - } - }; - public static final VPackKeyMapAdapter DOUBLE = new VPackKeyMapAdapter() { - @Override - public String serialize(final Double key) { - return key.toString(); - } - - @Override - public Double deserialize(final String key) { - return Double.valueOf(key); - } - }; - public static final VPackKeyMapAdapter FLOAT = new VPackKeyMapAdapter() { - @Override - public String serialize(final Float key) { - return key.toString(); - } - - @Override - public Float deserialize(final String key) { - return Float.valueOf(key); - } - }; - public static final VPackKeyMapAdapter BIG_INTEGER = new VPackKeyMapAdapter() { - @Override - public String serialize(final BigInteger key) { - return key.toString(); - } - - @Override - public BigInteger deserialize(final String key) { - return new BigInteger(key); - } - }; - public static final VPackKeyMapAdapter BIG_DECIMAL = new VPackKeyMapAdapter() { - @Override - public String serialize(final BigDecimal key) { - return key.toString(); - } - - @Override - public BigDecimal deserialize(final String key) { - return new BigDecimal(key); - } - }; - public static final VPackKeyMapAdapter NUMBER = new VPackKeyMapAdapter() { - @Override - public String serialize(final Number key) { - return key.toString(); - } - - @Override - public Number deserialize(final String key) { - return Double.valueOf(key); - } - }; - public static final VPackKeyMapAdapter CHARACTER = new VPackKeyMapAdapter() { - @Override - public String serialize(final Character key) { - return key.toString(); - } - - @Override - public Character deserialize(final String key) { - return key.charAt(0); - } - }; -} diff --git a/src/main/java/com/arangodb/velocypack/internal/VPackSerializers.java b/src/main/java/com/arangodb/velocypack/internal/VPackSerializers.java deleted file mode 100644 index 1b8bb60..0000000 --- a/src/main/java/com/arangodb/velocypack/internal/VPackSerializers.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.internal; - -import com.arangodb.velocypack.VPackBuilder; -import com.arangodb.velocypack.VPackSerializationContext; -import com.arangodb.velocypack.VPackSerializer; -import com.arangodb.velocypack.VPackSlice; -import com.arangodb.velocypack.exception.VPackException; -import com.arangodb.velocypack.internal.util.DateUtil; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Timestamp; -import java.util.Base64; -import java.util.Date; -import java.util.UUID; - -/** - * @author Mark Vollmary - * - */ -public class VPackSerializers { - - private VPackSerializers() { - super(); - } - - public static final VPackSerializer STRING = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final String value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer BOOLEAN = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Boolean value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer INTEGER = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Integer value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer LONG = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Long value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer SHORT = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Short value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer DOUBLE = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Double value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer FLOAT = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Float value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer BIG_INTEGER = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final BigInteger value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer BIG_DECIMAL = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final BigDecimal value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer NUMBER = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Number value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, (Double) value); - } - }; - public static final VPackSerializer CHARACTER = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Character value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer DATE = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Date value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, DateUtil.format(value)); - } - }; - public static final VPackSerializer SQL_DATE = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final java.sql.Date value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, DateUtil.format(value)); - } - }; - public static final VPackSerializer SQL_TIMESTAMP = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Timestamp value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, DateUtil.format(value)); - } - }; - public static final VPackSerializer VPACK = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final VPackSlice value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value); - } - }; - public static final VPackSerializer UUID = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final java.util.UUID value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, value.toString()); - } - }; - public static final VPackSerializer BYTE_ARRAY = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final byte[] value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, Base64.getEncoder().encodeToString(value)); - } - }; - public static final VPackSerializer BYTE = new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final Byte value, - final VPackSerializationContext context) { - builder.add(attribute, value); - } - }; -} diff --git a/src/test/java/com/arangodb/velocypack/Bench.java b/src/test/java/com/arangodb/velocypack/Bench.java deleted file mode 100644 index f9b7da5..0000000 --- a/src/test/java/com/arangodb/velocypack/Bench.java +++ /dev/null @@ -1,171 +0,0 @@ -package com.arangodb.velocypack; - -import com.arangodb.jackson.dataformat.velocypack.VPackMapper; -import com.arangodb.velocypack.exception.VPackBuilderException; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.openjdk.jmh.annotations.*; -import org.openjdk.jmh.infra.Blackhole; -import org.openjdk.jmh.profile.GCProfiler; -import org.openjdk.jmh.results.format.ResultFormatType; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.RunnerException; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; - -import java.io.IOException; -import java.io.StringWriter; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.concurrent.TimeUnit; - -@Warmup(iterations = 8, time = 1) -@Measurement(iterations = 30, time = 1) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(TimeUnit.MILLISECONDS) -@Fork(1) -public class Bench { - @State(Scope.Benchmark) - public static class Data { - - public final String str; - public final VPackSlice slice; - public final VPackSlice koko = buildKoko(); - - public Data() { - try { - this.str = new String( - Files.readAllBytes( - Paths.get(this.getClass().getResource("/api-docs.json").toURI()) - ) - ); - } catch (Exception e) { - throw new RuntimeException(e); - } - - VPackParser parser = new VPackParser.Builder().build(); - slice = parser.fromJson(str); - } - - public VPackSlice buildKoko() { - VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("name", "Koko"); - builder.add("species", "Gorilla"); - builder.add("language", "GSL"); - builder.add("knownSigns", 1000); - builder.add("knownEnglishWords", 2000); - builder.add("age", 46); - builder.add("hairy", true); - builder.add("iq", 80); - builder.add("pet", "All Ball"); - builder.close(); - return builder.slice(); - } - - } - - public static void main(String[] args) throws RunnerException, IOException { - String datetime = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date()); - Path target = Files.createDirectories(Paths.get("target", "jmh-result")); - - ArrayList jvmArgs = new ArrayList<>(); - jvmArgs.add("-Xms256m"); - jvmArgs.add("-Xmx256m"); - if (Integer.parseInt(System.getProperty("java.version").split("\\.")[0]) >= 11) { - jvmArgs.add("-XX:StartFlightRecording=filename=" + target.resolve(datetime + ".jfr") + ",settings=profile"); - } - - Options opt = new OptionsBuilder() - .include(Bench.class.getSimpleName()) - .addProfiler(GCProfiler.class) - .jvmArgs(jvmArgs.toArray(new String[0])) - .resultFormat(ResultFormatType.JSON) - .result(target.resolve(datetime + ".json").toString()) - .build(); - - new Runner(opt).run(); - } - - - @OutputTimeUnit(TimeUnit.NANOSECONDS) - @Benchmark - public void builder(Data data, Blackhole bh) { - bh.consume(data.buildKoko()); - } - - @OutputTimeUnit(TimeUnit.NANOSECONDS) - @Benchmark - public void sliceGet(Data data, Blackhole bh) { - VPackSlice koko = data.koko; - bh.consume(koko.get("name")); - bh.consume(koko.get("species")); - bh.consume(koko.get("language")); - bh.consume(koko.get("knownSigns")); - bh.consume(koko.get("knownEnglishWords")); - bh.consume(koko.get("age")); - bh.consume(koko.get("hairy")); - bh.consume(koko.get("iq")); - bh.consume(koko.get("pet")); - } - - @Benchmark - public void fromJson(Data data, Blackhole bh) { - VPackParser parser = new VPackParser.Builder().build(); - VPackSlice slice = parser.fromJson(data.str); - bh.consume(slice); - } - - @Benchmark - public void fromJsonJackson(Data data, Blackhole bh) throws JsonProcessingException { - JsonNode vpackNode = new ObjectMapper().readTree(data.str); - byte[] vpack = new VPackMapper().writeValueAsBytes(vpackNode); - bh.consume(vpack); - } - - @Benchmark - public void toJson(Data data, Blackhole bh) { - VPackParser parser = new VPackParser.Builder().build(); - String str = parser.toJson(data.slice); - bh.consume(str); - } - - @Benchmark - public void toJsonJackson(Data data, Blackhole bh) throws IOException { - JsonNode vpackNode = new VPackMapper().readTree(data.slice.toByteArray()); - String str = new ObjectMapper().writeValueAsString(vpackNode); - bh.consume(str); - } - - @Benchmark - public void toJsonString(Data data, Blackhole bh) { - String json = VPackParser.toJSONString(data.str); - bh.consume(json); - } - - @Benchmark - public void toJsonStringJackson(Data data, Blackhole bh) { - String json = toJSONStringJackson(data.str); - bh.consume(json); - } - - private static String toJSONStringJackson(final String text) { - final StringWriter writer = new StringWriter(); - try { - final JsonGenerator generator = new JsonFactory().createGenerator(writer); - generator.writeString(text); - generator.close(); - } catch (final IOException e) { - throw new VPackBuilderException(e); - } - return writer.toString(); - } - -} diff --git a/src/test/java/com/arangodb/velocypack/JsonStringTest.java b/src/test/java/com/arangodb/velocypack/JsonStringTest.java deleted file mode 100644 index 957f7e3..0000000 --- a/src/test/java/com/arangodb/velocypack/JsonStringTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.arangodb.velocypack; - -import org.graalvm.polyglot.Context; -import org.graalvm.polyglot.Value; -import org.junit.Test; - -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.Assume.assumeTrue; - -public class JsonStringTest { - private static List allChars = generateAllInputChars(); - private Context context; - private Value jsStringify; - private Value jsParse; - private final String stringifyFn = "(function stringify(x){return JSON.stringify(x);})"; - private final String parseFn = "(function parse(x){return JSON.parse(x);})"; - - @Test - public void stringToJsonRoundTrip() { - assumeTrue("This test requires GraalVM", org.graalvm.home.Version.getCurrent().isRelease()); - - context = Context.create(); - jsStringify = context.eval("js", stringifyFn); - jsParse = context.eval("js", parseFn); - - VPack vpack = new VPack.Builder().build(); - VPackParser parser = new VPackParser.Builder().build(); - - // chars - allChars.forEach(value -> { - String expected = jsStringify.execute(value).as(String.class); - assertThat(jsParse.execute(expected).as(String.class), is(value)); - assertThat(VPackParser.toJSONString(value), is(expected)); - assertThat(parser.toJson(vpack.serialize(value)), is(expected)); - assertThat(parser.fromJson(expected).getAsString(), is(value)); - }); - - // random strings - IntStream.range(0, 1000) - .mapToObj(i -> generateRandomString(100)) - .forEach(value -> { - String expected = jsStringify.execute(value).as(String.class); - assertThat(jsParse.execute(expected).as(String.class), is(value)); - assertThat(VPackParser.toJSONString(value), is(expected)); - assertThat(parser.toJson(vpack.serialize(value)), is(expected)); - assertThat(parser.fromJson(expected).getAsString(), is(value)); - }); - - context.close(); - } - - private static List generateAllInputChars() { - return IntStream - .range(0, Character.MAX_CODE_POINT + 1) - .mapToObj(codePoint -> new String(Character.toChars(codePoint))) - .filter(s -> !Character.isLowSurrogate(s.charAt(0)) && - (!Character.isHighSurrogate(s.charAt(0)) || s.length() != 1)) - .collect(Collectors.toList()); - } - - private String generateRandomString(int length) { - int max = allChars.size(); - Random r = new Random(); - return IntStream.range(0, length) - .mapToObj(i -> allChars.get(r.nextInt(max))) - .collect(Collectors.joining()); - } - -} diff --git a/src/test/java/com/arangodb/velocypack/VPackBuilderTest.java b/src/test/java/com/arangodb/velocypack/VPackBuilderTest.java index 80669ff..7f76846 100644 --- a/src/test/java/com/arangodb/velocypack/VPackBuilderTest.java +++ b/src/test/java/com/arangodb/velocypack/VPackBuilderTest.java @@ -113,7 +113,6 @@ public void addByte() throws VPackException { builder.add(value); final VPackSlice slice = builder.slice(); - System.out.println(slice); assertThat(slice.isByte(), is(true)); assertThat(slice.getAsByte(), is(value)); } diff --git a/src/test/java/com/arangodb/velocypack/VPackModuleTest.java b/src/test/java/com/arangodb/velocypack/VPackModuleTest.java deleted file mode 100644 index 5935dc3..0000000 --- a/src/test/java/com/arangodb/velocypack/VPackModuleTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -import org.junit.Test; - -import com.arangodb.velocypack.exception.VPackException; - -/** - * @author Mark Vollmary - * - */ -public class VPackModuleTest { - - private static class TestVPackModule implements VPackModule { - - @Override - public > void setup(final C context) { - context.registerSerializer(String.class, new VPackSerializer() { - - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final String value, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, "test"); - } - }); - } - - } - - @Test - public void registerModule() { - final VPack vpack = new VPack.Builder().registerModule(new TestVPackModule()).build(); - final VPackSlice value = vpack.serialize("notest"); - assertThat(value.isString(), is(true)); - assertThat(value.getAsString(), is("test")); - } - -} diff --git a/src/test/java/com/arangodb/velocypack/VPackParserTest.java b/src/test/java/com/arangodb/velocypack/VPackParserTest.java deleted file mode 100644 index fd0aa11..0000000 --- a/src/test/java/com/arangodb/velocypack/VPackParserTest.java +++ /dev/null @@ -1,570 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -import java.util.Date; - -import org.junit.Test; - -import com.arangodb.velocypack.exception.VPackException; - -/** - * @author Mark Vollmary - * - */ -public class VPackParserTest { - - @Test - public void toJsonObject1Field() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", "test"); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("{\"a\":\"test\"}")); - } - - @Test - public void toJsonObject2Fields() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", "test"); - builder.add("b", true); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("{\"a\":\"test\",\"b\":true}")); - } - - @Test - public void toJsonObjectStringField() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", "test"); - builder.add("b", "test"); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("{\"a\":\"test\",\"b\":\"test\"}")); - } - - @Test - public void toJsonObjectBooleanField() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", true); - builder.add("b", false); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("{\"a\":true,\"b\":false}")); - } - - @Test - public void toJsonObjectNumberField() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", 5); - builder.add("b", 5.5); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("{\"a\":5,\"b\":5.5}")); - } - - @Test - public void toJsonArrayInObject() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", ValueType.ARRAY); - builder.add(1); - builder.add(2); - builder.add(3); - builder.close(); - builder.add("b", ValueType.ARRAY); - builder.add("a"); - builder.add("b"); - builder.add("c"); - builder.close(); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("{\"a\":[1,2,3],\"b\":[\"a\",\"b\",\"c\"]}")); - } - - @Test - public void toJsonObjectInObject() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", ValueType.OBJECT); - builder.add("aa", "test"); - builder.add("ab", true); - builder.close(); - builder.add("b", ValueType.OBJECT); - builder.add("ba", "test"); - builder.add("bb", 5.5); - builder.close(); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("{\"a\":{\"aa\":\"test\",\"ab\":true},\"b\":{\"ba\":\"test\",\"bb\":5.5}}")); - } - - @Test - public void toJsonObjectInArray() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.ARRAY); - builder.add(ValueType.OBJECT); - builder.add("a", "test"); - builder.close(); - builder.add(ValueType.OBJECT); - builder.add("a", "test"); - builder.close(); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("[{\"a\":\"test\"},{\"a\":\"test\"}]")); - } - - @Test - public void toJsonArrayInArray() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.ARRAY); - builder.add(ValueType.ARRAY); - builder.add(1); - builder.add(2); - builder.add(3); - builder.close(); - builder.add(ValueType.ARRAY); - builder.add("a"); - builder.add("b"); - builder.add("c"); - builder.close(); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice()); - assertThat(json, is("[[1,2,3],[\"a\",\"b\",\"c\"]]")); - } - - @Test - public void toJsonExcludeNullValueInObject() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", ValueType.NULL); - builder.add("b", (String) null); - builder.add("c", "test"); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice(), false); - assertThat(json, is("{\"c\":\"test\"}")); - } - - @Test - public void toJsonIncludeNullValueInObject() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", ValueType.NULL); - builder.add("b", (String) null); - builder.add("c", "test"); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice(), true); - assertThat(json, is("{\"a\":null,\"b\":null,\"c\":\"test\"}")); - } - - @Test - public void toJsonExcludeNullValueInArray() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.ARRAY); - builder.add(ValueType.NULL); - builder.add((String) null); - builder.add("test"); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice(), false); - assertThat(json, is("[\"test\"]")); - } - - @Test - public void toJsonIncludeNullValueInArray() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.ARRAY); - builder.add(ValueType.NULL); - builder.add((String) null); - builder.add("test"); - builder.close(); - final String json = new VPackParser.Builder().build().toJson(builder.slice(), true); - assertThat(json, is("[null,null,\"test\"]")); - } - - @Test - public void fromJsonObject1Field() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("{\"a\":\"test\"}"); - assertThat(vpack.isObject(), is(true)); - final VPackSlice a = vpack.get("a"); - assertThat(a.isString(), is(true)); - assertThat(a.getAsString(), is("test")); - } - - @Test - public void fromJsonObject2Fields() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("{\"a\":\"test\",\"b\":true}"); - assertThat(vpack.isObject(), is(true)); - final VPackSlice a = vpack.get("a"); - assertThat(a.isString(), is(true)); - assertThat(a.getAsString(), is("test")); - final VPackSlice b = vpack.get("b"); - assertThat(b.isBoolean(), is(true)); - assertThat(b.getAsBoolean(), is(true)); - } - - @Test - public void fromJsonObjectStringField() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("{\"a\":\"test1\",\"b\":\"test2\"}"); - assertThat(vpack.isObject(), is(true)); - final VPackSlice a = vpack.get("a"); - assertThat(a.isString(), is(true)); - assertThat(a.getAsString(), is("test1")); - final VPackSlice b = vpack.get("b"); - assertThat(b.isString(), is(true)); - assertThat(b.getAsString(), is("test2")); - } - - @Test - public void fromJsonObjectBooleanField() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("{\"a\":true,\"b\":false}"); - assertThat(vpack.isObject(), is(true)); - final VPackSlice a = vpack.get("a"); - assertThat(a.isBoolean(), is(true)); - assertThat(a.getAsBoolean(), is(true)); - final VPackSlice b = vpack.get("b"); - assertThat(b.isBoolean(), is(true)); - assertThat(b.getAsBoolean(), is(false)); - } - - @Test - public void fromJsonObjectNumberField() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("{\"a\":5,\"b\":5.5}"); - assertThat(vpack.isObject(), is(true)); - final VPackSlice a = vpack.get("a"); - assertThat(a.isInteger(), is(true)); - assertThat(a.getAsInt(), is(5)); - final VPackSlice b = vpack.get("b"); - assertThat(b.isDouble(), is(true)); - assertThat(b.getAsDouble(), is(5.5)); - } - - @Test - public void fromJsonArrayInObject() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build() - .fromJson("{\"a\":[1,2,3],\"b\":[\"a\",\"b\",\"c\"]}"); - assertThat(vpack.isObject(), is(true)); - final VPackSlice a = vpack.get("a"); - assertThat(a.isArray(), is(true)); - assertThat(a.size(), is(3)); - assertThat(a.get(0).isInteger(), is(true)); - assertThat(a.get(0).getAsInt(), is(1)); - assertThat(a.get(1).isInteger(), is(true)); - assertThat(a.get(1).getAsInt(), is(2)); - assertThat(a.get(2).isInteger(), is(true)); - assertThat(a.get(2).getAsInt(), is(3)); - final VPackSlice b = vpack.get("b"); - assertThat(b.isArray(), is(true)); - assertThat(b.size(), is(3)); - assertThat(b.get(0).isString(), is(true)); - assertThat(b.get(0).getAsString(), is("a")); - assertThat(b.get(1).isString(), is(true)); - assertThat(b.get(1).getAsString(), is("b")); - assertThat(b.get(2).isString(), is(true)); - assertThat(b.get(2).getAsString(), is("c")); - } - - @Test - public void fromJsonObjectInObject() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build() - .fromJson("{\"a\":{\"aa\":\"test\",\"ab\":true},\"b\":{\"ba\":\"test\",\"bb\":5.5}}"); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.size(), is(2)); - final VPackSlice a = vpack.get("a"); - assertThat(a.isObject(), is(true)); - assertThat(a.size(), is(2)); - final VPackSlice aa = a.get("aa"); - assertThat(aa.isString(), is(true)); - assertThat(aa.getAsString(), is("test")); - final VPackSlice ab = a.get("ab"); - assertThat(ab.isBoolean(), is(true)); - assertThat(ab.getAsBoolean(), is(true)); - final VPackSlice b = vpack.get("b"); - assertThat(b.isObject(), is(true)); - assertThat(b.size(), is(2)); - final VPackSlice ba = b.get("ba"); - assertThat(ba.isString(), is(true)); - assertThat(ba.getAsString(), is("test")); - final VPackSlice bb = b.get("bb"); - assertThat(bb.isDouble(), is(true)); - assertThat(bb.getAsDouble(), is(5.5)); - } - - @Test - public void fromJsonObjectInArray() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("[{\"a\":\"test\"},{\"a\":\"test\"}]"); - assertThat(vpack.isArray(), is(true)); - assertThat(vpack.size(), is(2)); - final VPackSlice z = vpack.get(0); - assertThat(z.isObject(), is(true)); - assertThat(z.size(), is(1)); - final VPackSlice za = z.get("a"); - assertThat(za.isString(), is(true)); - assertThat(za.getAsString(), is("test")); - final VPackSlice o = vpack.get(1); - assertThat(o.isObject(), is(true)); - assertThat(o.size(), is(1)); - final VPackSlice oa = o.get("a"); - assertThat(oa.isString(), is(true)); - assertThat(oa.getAsString(), is("test")); - } - - @Test - public void fromJsonArrayInArray() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("[[1,2,3],[\"a\",\"b\",\"c\"]]"); - assertThat(vpack.isArray(), is(true)); - assertThat(vpack.size(), is(2)); - final VPackSlice z = vpack.get(0); - assertThat(z.isArray(), is(true)); - assertThat(z.size(), is(3)); - assertThat(z.get(0).isInteger(), is(true)); - assertThat(z.get(0).getAsInt(), is(1)); - assertThat(z.get(1).isInteger(), is(true)); - assertThat(z.get(1).getAsInt(), is(2)); - assertThat(z.get(2).isInteger(), is(true)); - assertThat(z.get(2).getAsInt(), is(3)); - final VPackSlice o = vpack.get(1); - assertThat(o.isArray(), is(true)); - assertThat(o.size(), is(3)); - assertThat(o.get(0).isString(), is(true)); - assertThat(o.get(0).getAsString(), is("a")); - assertThat(o.get(1).isString(), is(true)); - assertThat(o.get(1).getAsString(), is("b")); - assertThat(o.get(2).isString(), is(true)); - assertThat(o.get(2).getAsString(), is("c")); - } - - @Test - public void fromJsonExcludeNullValueInObject() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("{\"a\":null,\"b\":null,\"c\":\"test\"}", - false); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.size(), is(1)); - assertThat(vpack.get("a").isNone(), is(true)); - assertThat(vpack.get("b").isNone(), is(true)); - assertThat(vpack.get("c").isString(), is(true)); - assertThat(vpack.get("c").getAsString(), is("test")); - } - - @Test - public void fromJsonIncludeNullValueInObject() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("{\"a\":null,\"b\":null,\"c\":\"test\"}", - true); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.size(), is(3)); - assertThat(vpack.get("a").isNull(), is(true)); - assertThat(vpack.get("b").isNull(), is(true)); - assertThat(vpack.get("c").isString(), is(true)); - assertThat(vpack.get("c").getAsString(), is("test")); - } - - @Test - public void fromJsonExcludeNullValueInArray() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("[null,null,\"test\"]", false); - assertThat(vpack.isArray(), is(true)); - assertThat(vpack.size(), is(1)); - assertThat(vpack.get(0).isString(), is(true)); - assertThat(vpack.get(0).getAsString(), is("test")); - } - - @Test - public void fromJsonIncludeNullValueInArray() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder().build().fromJson("[null,null,\"test\"]", true); - assertThat(vpack.isArray(), is(true)); - assertThat(vpack.size(), is(3)); - assertThat(vpack.get(0).isNull(), is(true)); - assertThat(vpack.get(1).isNull(), is(true)); - assertThat(vpack.get(2).isString(), is(true)); - assertThat(vpack.get(2).getAsString(), is("test")); - } - - @Test - public void customDeserializer() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", "a"); - builder.add("b", "b"); - builder.close(); - final VPackJsonDeserializer deserializer = new VPackJsonDeserializer() { - @Override - public void deserialize( - final VPackSlice parent, - final String attribute, - final VPackSlice vpack, - final StringBuilder json) throws VPackException { - json.append(VPackParser.toJSONString(vpack.getAsString() + "1")); - } - }; - final String json = new VPackParser.Builder().registerDeserializer(ValueType.STRING, deserializer).build() - .toJson(builder.slice()); - assertThat(json, is("{\"a\":\"a1\",\"b\":\"b1\"}")); - } - - @Test - public void customDeserializerByName() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", "a"); - builder.add("b", "b"); - builder.close(); - final String json = new VPackParser.Builder() - .registerDeserializer("a", ValueType.STRING, new VPackJsonDeserializer() { - @Override - public void deserialize( - final VPackSlice parent, - final String attribute, - final VPackSlice vpack, - final StringBuilder json) throws VPackException { - json.append(VPackParser.toJSONString(vpack.getAsString() + "1")); - } - }).build().toJson(builder.slice()); - assertThat(json, is("{\"a\":\"a1\",\"b\":\"b\"}")); - } - - @Test - public void customSerializer() throws VPackException { - final VPackSlice vpack = new VPackParser.Builder() - .registerSerializer(String.class, new VPackJsonSerializer() { - @Override - public void serialize(final VPackBuilder builder, final String attribute, final String value) - throws VPackException { - builder.add(attribute, value + "1"); - } - }).build().fromJson("{\"a\":\"a\"}"); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.get("a").isString(), is(true)); - assertThat(vpack.get("a").getAsString(), is("a1")); - } - - @Test - public void customSerializerByName() { - final String json = "{\"a\":\"a\",\"b\":\"b\"}"; - final VPackSlice vpack = new VPackParser.Builder() - .registerSerializer("a", String.class, new VPackJsonSerializer() { - @Override - public void serialize(final VPackBuilder builder, final String attribute, final String value) - throws VPackException { - builder.add(attribute, value + "1"); - } - }).build().fromJson(json); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.get("a").isString(), is(true)); - assertThat(vpack.get("a").getAsString(), is("a1")); - assertThat(vpack.get("b").isString(), is(true)); - assertThat(vpack.get("b").getAsString(), is("b")); - } - - @Test - public void dateToJson() { - final VPackSlice vpack = new VPackBuilder().add(new Date(1478766992059L)).slice(); - final VPackParser parser = new VPackParser.Builder().build(); - assertThat(parser.toJson(vpack), containsString("2016-11-10T")); - assertThat(parser.toJson(vpack), containsString(":36:32.059Z")); - } - - @Test - public void bytelength() { - final String name1 = "{\"name1\":\"job_04_detail_1\",\"seven__\":\"123456789\",\"_key\":\"191d936d-1eb9-4094-9c1c-9e0ba1d01867\",\"lang\":\"it\",\"value\":\"[CTO]\\n Ha supervisionato e gestito il reparto di R&D per il software, 1234567 formulando una visione di lungo periodo con la Direzione dell'Azienda.\"}"; - final String name = "{\"name\":\"job_04_detail_1\",\"seven__\":\"123456789\",\"_key\":\"191d936d-1eb9-4094-9c1c-9e0ba1d01867\",\"lang\":\"it\",\"value\":\"[CTO]\\n Ha supervisionato e gestito il reparto di R&D per il software, 1234567 formulando una visione di lungo periodo con la Direzione dell'Azienda.\"}"; - - final VPackParser vpacker = new VPackParser.Builder().build(); - { - final VPackSlice vpack = vpacker.fromJson(name1); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.get("name1").isString(), is(true)); - assertThat(vpack.get("name1").getAsString(), is("job_04_detail_1")); - - } - { - final VPackSlice vpack = vpacker.fromJson(name); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.get("name").isString(), is(true)); - assertThat(vpack.get("name").getAsString(), is("job_04_detail_1")); - } - } - - @Test - public void arrayWithObjectsIncludingNull() { - final String json = "{\"values\": [ {\"a\": null}, {\"b\": null}]}"; - final VPackParser parser = new VPackParser.Builder().build(); - final VPackSlice slice = parser.fromJson(json, true); - assertThat(slice.toString(), is("{\"values\":[{\"a\":null},{\"b\":null}]}")); - } - - @Test - public void arrayWithObjectsExcludingNull() { - final String json = "{\"values\": [ {\"a\": null}, {\"b\": null}]}"; - final VPackParser parser = new VPackParser.Builder().build(); - final VPackSlice slice = parser.fromJson(json); - assertThat(slice.toString(), is("{\"values\":[{},{}]}")); - } - - @Test - public void negativeInt() { - final VPackParser parser = new VPackParser.Builder().build(); - final String json = parser.toJson(new VPackBuilder().add(-32).slice()); - assertThat(json, is("-32")); - } - - @Test - public void negativeIntAsJson() throws VPackException { - final VPackParser parser = new VPackParser.Builder().build(); - final String json = parser.toJson(new VPackBuilder().add(-100).slice()); - assertThat(json, is("-100")); - } - - @Test - public void negativeIntAsJson2() throws VPackException { - final VPackParser parser = new VPackParser.Builder().build(); - final String json = parser.toJson(new VPackBuilder().add(-300).slice()); - assertThat(json, is("-300")); - } - - @Test - public void negativeLongAsJson() throws VPackException { - final VPackParser parser = new VPackParser.Builder().build(); - final String json = parser.toJson(new VPackBuilder().add(-100L).slice()); - assertThat(json, is("-100")); - } - - @Test - public void negativeLongAsJson2() throws VPackException { - final VPackParser parser = new VPackParser.Builder().build(); - final String json = parser.toJson(new VPackBuilder().add(-300L).slice()); - assertThat(json, is("-300")); - } - - @Test - public void negativeLongAsJson3() throws VPackException { - final VPackParser parser = new VPackParser.Builder().build(); - final String json = parser.toJson(new VPackBuilder().add(-62135596800L).slice()); - assertThat(json, is("-62135596800")); - } - -} diff --git a/src/test/java/com/arangodb/velocypack/VPackSerializeDeserializeTest.java b/src/test/java/com/arangodb/velocypack/VPackSerializeDeserializeTest.java deleted file mode 100644 index 5c106fa..0000000 --- a/src/test/java/com/arangodb/velocypack/VPackSerializeDeserializeTest.java +++ /dev/null @@ -1,4177 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import com.arangodb.velocypack.VPack.SerializeOptions; -import com.arangodb.velocypack.annotations.Expose; -import com.arangodb.velocypack.annotations.SerializedName; -import com.arangodb.velocypack.exception.VPackException; -import org.junit.Test; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Field; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.Map.Entry; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; - -/** - * @author Mark Vollmary - * - */ -public class VPackSerializeDeserializeTest { - - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");// ISO 8601 - static { - DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); - } - - protected static class TestEntityBoolean { - private boolean a = true; - private boolean b = false; - private Boolean c = Boolean.TRUE; - private Boolean d = Boolean.FALSE; - - public boolean isA() { - return a; - } - - public void setA(final boolean a) { - this.a = a; - } - - public boolean isB() { - return b; - } - - public void setB(final boolean b) { - this.b = b; - } - - public Boolean getC() { - return c; - } - - public void setC(final Boolean c) { - this.c = c; - } - - public Boolean getD() { - return d; - } - - public void setD(final Boolean d) { - this.d = d; - } - } - - @Test - public void fromBoolean() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityBoolean()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice a = vpack.get("a"); - assertThat(a.isBoolean(), is(true)); - assertThat(a.getAsBoolean(), is(true)); - } - { - final VPackSlice b = vpack.get("b"); - assertThat(b.isBoolean(), is(true)); - assertThat(b.getAsBoolean(), is(false)); - } - { - final VPackSlice c = vpack.get("c"); - assertThat(c.isBoolean(), is(true)); - assertThat(c.getAsBoolean(), is(true)); - } - { - final VPackSlice d = vpack.get("d"); - assertThat(d.isBoolean(), is(true)); - assertThat(d.getAsBoolean(), is(false)); - } - } - - @Test - public void toBoolean() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("a", false); - builder.add("b", true); - builder.add("c", Boolean.FALSE); - builder.add("d", Boolean.TRUE); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityBoolean entity = new VPack.Builder().build().deserialize(vpack, TestEntityBoolean.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.a, is(false)); - assertThat(entity.b, is(true)); - assertThat(entity.c, is(Boolean.FALSE)); - assertThat(entity.d, is(Boolean.TRUE)); - } - - protected static class TestEntityString { - private String s = "test"; - private Character c1 = 't'; - private char c2 = 't'; - - public String getS() { - return s; - } - - public void setS(final String s) { - this.s = s; - } - - public Character getC1() { - return c1; - } - - public void setC1(final Character c1) { - this.c1 = c1; - } - - public char getC2() { - return c2; - } - - public void setC2(final char c2) { - this.c2 = c2; - } - } - - @Test - public void fromStrings() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityString()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice s = vpack.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("test")); - } - { - final VPackSlice c1 = vpack.get("c1"); - assertThat(c1.isString(), is(true)); - assertThat(c1.getAsChar(), is('t')); - } - { - final VPackSlice c2 = vpack.get("c2"); - assertThat(c2.isString(), is(true)); - assertThat(c2.getAsChar(), is('t')); - } - } - - @Test - public void toStrings() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("s", "abc"); - builder.add("c1", 'd'); - builder.add("c2", 'd'); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityString entity = new VPack.Builder().build().deserialize(vpack, TestEntityString.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.s, is("abc")); - assertThat(entity.c1, is('d')); - assertThat(entity.c1, is('d')); - } - - protected static class TestEntityInteger { - private int i1 = 1; - private Integer i2 = 1; - - public int getI1() { - return i1; - } - - public void setI1(final int i1) { - this.i1 = i1; - } - - public Integer getI2() { - return i2; - } - - public void setI2(final Integer i2) { - this.i2 = i2; - } - } - - @Test - public void fromInteger() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityInteger()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice i1 = vpack.get("i1"); - assertThat(i1.isInteger(), is(true)); - assertThat(i1.getAsInt(), is(1)); - } - { - final VPackSlice i2 = vpack.get("i2"); - assertThat(i2.isInteger(), is(true)); - assertThat(i2.getAsInt(), is(1)); - } - } - - @Test - public void fromNegativeInteger() throws VPackException { - final TestEntityInteger entity = new TestEntityInteger(); - entity.i1 = -50; - entity.i2 = -50; - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice i1 = vpack.get("i1"); - assertThat(i1.isInteger(), is(true)); - assertThat(i1.getAsInt(), is(-50)); - } - { - final VPackSlice i2 = vpack.get("i2"); - assertThat(i2.isInteger(), is(true)); - assertThat(i2.getAsInt(), is(-50)); - } - } - - @Test - public void toInteger() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("i1", 2); - builder.add("i2", 3); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityInteger entity = new VPack.Builder().build().deserialize(vpack, TestEntityInteger.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.i1, is(2)); - assertThat(entity.i2, is(3)); - } - - @Test - public void toNegativeInteger() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("i1", -50); - builder.add("i2", -50); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityInteger entity = new VPack.Builder().build().deserialize(vpack, TestEntityInteger.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.i1, is(-50)); - assertThat(entity.i2, is(-50)); - } - - protected static class TestEntityLong { - private long l1 = 1; - private Long l2 = 1L; - - public long getL1() { - return l1; - } - - public void setL1(final long l1) { - this.l1 = l1; - } - - public Long getL2() { - return l2; - } - - public void setL2(final Long l2) { - this.l2 = l2; - } - } - - @Test - public void fromLong() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityLong()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice l1 = vpack.get("l1"); - assertThat(l1.isInteger(), is(true)); - assertThat(l1.getAsLong(), is(1L)); - } - { - final VPackSlice l2 = vpack.get("l2"); - assertThat(l2.isInteger(), is(true)); - assertThat(l2.getAsLong(), is(1L)); - } - } - - @Test - public void fromNegativeLong() throws VPackException { - final TestEntityLong entity = new TestEntityLong(); - entity.l1 = -100L; - entity.l2 = (long) -300; - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice l1 = vpack.get("l1"); - assertThat(l1.isInteger(), is(true)); - assertThat(l1.getAsLong(), is(-100L)); - } - { - final VPackSlice l2 = vpack.get("l2"); - assertThat(l2.isInteger(), is(true)); - assertThat(l2.getAsLong(), is(-300L)); - } - } - - @Test - public void toLong() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("l1", 2); - builder.add("l2", 3); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityLong entity = new VPack.Builder().build().deserialize(vpack, TestEntityLong.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.l1, is(2L)); - assertThat(entity.l2, is(3L)); - } - - @Test - public void toNegativeLong() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("l1", -100L); - builder.add("l2", -300L); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityLong entity = new VPack.Builder().build().deserialize(vpack, TestEntityLong.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.l1, is(-100L)); - assertThat(entity.l2, is((long) -300)); - } - - @Test - public void negativeLong() throws VPackException { - final TestEntityLong entity = new TestEntityLong(); - entity.l1 = -100L; - entity.l2 = (long) -300; - final VPack vp = new VPack.Builder().build(); - final TestEntityLong out = vp.deserialize(vp.serialize(entity), TestEntityLong.class); - assertThat(out.l1, is(entity.l1)); - assertThat(out.l2, is(entity.l2)); - } - - @Test - public void intToLong() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("l1", 100); - builder.add("l2", 300); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityLong entity = new VPack.Builder().build().deserialize(vpack, TestEntityLong.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.l1, is(100L)); - assertThat(entity.l2, is(300L)); - } - - @Test - public void negativeIntToLong() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("l1", -100); - builder.add("l2", -300); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityLong entity = new VPack.Builder().build().deserialize(vpack, TestEntityLong.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.l1, is(-100L)); - assertThat(entity.l2, is((long) -300)); - } - - @Test - public void negativeLongToInt() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("i1", -100L); - builder.add("i2", -300L); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityInteger entity = new VPack.Builder().build().deserialize(vpack, TestEntityInteger.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.i1, is(-100)); - assertThat(entity.i2, is(-300)); - } - - @Test - public void negativeLongToShort() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("s1", -100L); - builder.add("s2", -300L); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityShort entity = new VPack.Builder().build().deserialize(vpack, TestEntityShort.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.s1, is((short) -100)); - assertThat(entity.s2, is((short) -300)); - } - - @Test - public void negativeShortToLong() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("l1", (short) -100); - builder.add("l2", (short) -300); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityLong entity = new VPack.Builder().build().deserialize(vpack, TestEntityLong.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.l1, is(-100L)); - assertThat(entity.l2, is((long) -300)); - } - - protected static class TestEntityFloat { - private float f1 = 1; - private Float f2 = 1F; - - public float getF1() { - return f1; - } - - public void setF1(final float f1) { - this.f1 = f1; - } - - public Float getF2() { - return f2; - } - - public void setF2(final Float f2) { - this.f2 = f2; - } - } - - @Test - public void fromFloat() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityFloat()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice f1 = vpack.get("f1"); - assertThat(f1.isDouble(), is(true)); - assertThat(f1.getAsFloat(), is(1.0F)); - } - { - final VPackSlice f2 = vpack.get("f2"); - assertThat(f2.isDouble(), is(true)); - assertThat(f2.getAsFloat(), is(1.0F)); - } - } - - @Test - public void toFloat() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("f1", 2F); - builder.add("f2", 3F); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityFloat entity = new VPack.Builder().build().deserialize(vpack, TestEntityFloat.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.f1, is(2F)); - assertThat(entity.f2, is(3f)); - } - - protected static class TestEntityShort { - private short s1 = 1; - private Short s2 = 1; - - public short getS1() { - return s1; - } - - public void setS1(final short s1) { - this.s1 = s1; - } - - public Short getS2() { - return s2; - } - - public void setS2(final Short s2) { - this.s2 = s2; - } - } - - @Test - public void fromShort() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityShort()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice s1 = vpack.get("s1"); - assertThat(s1.isInteger(), is(true)); - assertThat(s1.getAsShort(), is((short) 1)); - } - { - final VPackSlice s2 = vpack.get("s2"); - assertThat(s2.isInteger(), is(true)); - assertThat(s2.getAsShort(), is((short) 1)); - } - } - - @Test - public void toShort() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("s1", 2); - builder.add("s2", 3); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityShort entity = new VPack.Builder().build().deserialize(vpack, TestEntityShort.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.s1, is((short) 2)); - assertThat(entity.s2, is((short) 3)); - } - - protected static class TestEntityByte { - private byte b1 = 1; // short integer path - private Byte b2 = 100; // integer path - - public byte getB1() { - return b1; - } - - public void setB1(final byte b1) { - this.b1 = b1; - } - - public Byte getB2() { - return b2; - } - - public void setB2(final Byte b2) { - this.b2 = b2; - } - } - - @Test - public void fromByte() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityByte()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice b1 = vpack.get("b1"); - assertThat(b1.isInteger(), is(true)); - assertThat(b1.getAsByte(), is((byte) 1)); - } - { - final VPackSlice b2 = vpack.get("b2"); - assertThat(b2.isInteger(), is(true)); - assertThat(b2.getAsByte(), is((byte) 100)); - } - } - - @Test - public void toByte() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("b1", 30); // integer path - builder.add("b2", 4); // short integer path - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityByte entity = new VPack.Builder().build().deserialize(vpack, TestEntityByte.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.b1, is((byte) 30)); - assertThat(entity.b2, is((byte) 4)); - } - - protected static class TestEntityDouble { - private Double d1 = 1.5; - private double d2 = 1.5; - - public Double getD1() { - return d1; - } - - public void setD1(final Double d1) { - this.d1 = d1; - } - - public double getD2() { - return d2; - } - - public void setD2(final double d2) { - this.d2 = d2; - } - } - - @Test - public void fromDouble() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityDouble()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice d1 = vpack.get("d1"); - assertThat(d1.isDouble(), is(true)); - assertThat(d1.getAsDouble(), is(1.5)); - } - { - final VPackSlice d2 = vpack.get("d2"); - assertThat(d2.isDouble(), is(true)); - assertThat(d2.getAsDouble(), is(1.5)); - } - } - - @Test - public void toDouble() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("d1", 2.25); - builder.add("d2", 3.75); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityDouble entity = new VPack.Builder().build().deserialize(vpack, TestEntityDouble.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.d1, is(2.25)); - assertThat(entity.d2, is(3.75)); - } - - protected static class TestEntityBigNumber { - private BigInteger bi = BigInteger.valueOf(1L); - private BigDecimal bd = BigDecimal.valueOf(1.5); - private BigDecimal bdi = BigDecimal.valueOf(1); - - public BigInteger getBi() { - return bi; - } - - public void setBi(final BigInteger bi) { - this.bi = bi; - } - - public BigDecimal getBd() { - return bd; - } - - public void setBd(final BigDecimal bd) { - this.bd = bd; - } - - public BigDecimal getBdi() { - return bdi; - } - - public void setBdi(final BigDecimal bdi) { - this.bdi = bdi; - } - } - - @Test - public void fromBigNumbers() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityBigNumber()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice bi = vpack.get("bi"); - assertThat(bi.isString(), is(true)); - assertThat(bi.getAsBigInteger(), is(BigInteger.valueOf(1L))); - } - { - final VPackSlice bd = vpack.get("bd"); - assertThat(bd.isString(), is(true)); - assertThat(bd.getAsBigDecimal(), is(BigDecimal.valueOf(1.5))); - } - { - final VPackSlice bdi = vpack.get("bdi"); - assertThat(bdi.isString(), is(true)); - assertThat(bdi.getAsBigDecimal(), is(BigDecimal.valueOf(1))); - } - } - - @Test - public void toBigNumbers() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("bi", BigInteger.valueOf(2)); - builder.add("bd", BigDecimal.valueOf(3.75)); - builder.add("bdi", BigDecimal.valueOf(3)); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityBigNumber entity = new VPack.Builder().build().deserialize(vpack, TestEntityBigNumber.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.bi, is(BigInteger.valueOf(2))); - assertThat(entity.bd, is(BigDecimal.valueOf(3.75))); - assertThat(entity.bdi, is(BigDecimal.valueOf(3))); - } - - @Test - public void bigDecimal() { - final BigDecimal fromDouble = BigDecimal.valueOf(-710.01); - final BigDecimal fromString = new BigDecimal("-710.01"); - assertThat(fromDouble, is(fromString)); - assertThat(new VPackBuilder().add(fromDouble).slice().getAsBigDecimal(), is(fromDouble)); - assertThat(new VPackBuilder().add(fromString).slice().getAsBigDecimal(), is(fromDouble)); - } - - @Test - public void deserializeIntAsBigDecimal() { - final int integer = Integer.MAX_VALUE; - final BigDecimal fromInt = BigDecimal.valueOf(integer); - assertThat(new VPackBuilder().add(integer).slice().getAsBigDecimal(), is(fromInt)); - } - - @Test - public void deserializeLongAsBigDecimal() { - final long lng = Long.MAX_VALUE; - final BigDecimal fromLng = BigDecimal.valueOf(lng); - assertThat(new VPackBuilder().add(lng).slice().getAsBigDecimal(), is(fromLng)); - } - - protected static class TestEntityArray { - private String[] a1 = { "a", "b", "cd" }; - private int[] a2 = { 1, 2, 3, 4, 5 }; - private boolean[] a3 = { true, true, false }; - private TestEnum[] a4 = TestEnum.values(); - - public String[] getA1() { - return a1; - } - - public void setA1(final String[] a1) { - this.a1 = a1; - } - - public int[] getA2() { - return a2; - } - - public void setA2(final int[] a2) { - this.a2 = a2; - } - - public boolean[] getA3() { - return a3; - } - - public void setA3(final boolean[] a3) { - this.a3 = a3; - } - - public TestEnum[] getA4() { - return a4; - } - - public void setA4(final TestEnum[] a4) { - this.a4 = a4; - } - - } - - @Test - public void fromArray() throws VPackException { - final TestEntityArray entity = new TestEntityArray(); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice a1 = vpack.get("a1"); - assertThat(a1.isArray(), is(true)); - assertThat(a1.getLength(), is(entity.a1.length)); - for (int i = 0; i < a1.getLength(); i++) { - assertThat(a1.get(i).getAsString(), is(entity.a1[i])); - } - } - { - final VPackSlice a2 = vpack.get("a2"); - assertThat(a2.isArray(), is(true)); - assertThat(a2.getLength(), is(entity.a2.length)); - for (int i = 0; i < a2.getLength(); i++) { - assertThat(a2.get(i).getAsInt(), is(entity.a2[i])); - } - } - { - final VPackSlice a3 = vpack.get("a3"); - assertThat(a3.isArray(), is(true)); - assertThat(a3.getLength(), is(entity.a3.length)); - for (int i = 0; i < a3.getLength(); i++) { - assertThat(a3.get(i).getAsBoolean(), is(entity.a3[i])); - } - } - { - final VPackSlice a4 = vpack.get("a4"); - assertThat(a4.isArray(), is(true)); - assertThat(a4.getLength(), is(entity.a4.length)); - for (int i = 0; i < a4.getLength(); i++) { - assertThat(TestEnum.valueOf(a4.get(i).getAsString()), is(entity.a4[i])); - } - } - } - - @Test - public void toArray() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - { - builder.add("a1", ValueType.ARRAY); - builder.add("a"); - builder.add("b"); - builder.add("c"); - builder.close(); - } - { - builder.add("a2", ValueType.ARRAY); - builder.add(1); - builder.add(2); - builder.add(3); - builder.add(4); - builder.close(); - } - { - builder.add("a3", ValueType.ARRAY); - builder.add(false); - builder.add(true); - builder.close(); - } - { - builder.add("a4", ValueType.ARRAY); - builder.add(TestEnum.A.name()); - builder.add(TestEnum.B.name()); - builder.close(); - } - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityArray entity = new VPack.Builder().build().deserialize(vpack, TestEntityArray.class); - assertThat(entity, is(notNullValue())); - { - assertThat(entity.a1.length, is(3)); - assertThat(entity.a1[0], is("a")); - assertThat(entity.a1[1], is("b")); - assertThat(entity.a1[2], is("c")); - } - { - assertThat(entity.a2.length, is(4)); - assertThat(entity.a2[0], is(1)); - assertThat(entity.a2[1], is(2)); - assertThat(entity.a2[2], is(3)); - assertThat(entity.a2[3], is(4)); - } - { - assertThat(entity.a3.length, is(2)); - assertThat(entity.a3[0], is(false)); - assertThat(entity.a3[1], is(true)); - } - { - assertThat(entity.a4.length, is(2)); - assertThat(entity.a4[0], is(TestEnum.A)); - assertThat(entity.a4[1], is(TestEnum.B)); - } - } - - @Test - public void fromArrayWithNull() { - final TestEntityArray entity = new TestEntityArray(); - entity.a1 = new String[] { "foo", null }; - - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - - final VPackSlice a1 = vpack.get("a1"); - assertThat(a1.isArray(), is(true)); - assertThat(a1.size(), is(2)); - assertThat(a1.get(0).isString(), is(true)); - assertThat(a1.get(0).getAsString(), is("foo")); - assertThat(a1.get(1).isNull(), is(true)); - } - - protected enum TestEnum { - A, B, C - } - - protected static class TestEntityEnum { - private TestEnum e1 = TestEnum.A; - - public TestEnum getE1() { - return e1; - } - - public void setE1(final TestEnum e1) { - this.e1 = e1; - } - } - - @Test - public void fromEnum() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityEnum()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice e1 = vpack.get("e1"); - assertThat(e1.isString(), is(true)); - assertThat(TestEnum.valueOf(e1.getAsString()), is(TestEnum.A)); - } - } - - @Test - public void toEnum() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("e1", TestEnum.B.name()); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityEnum entity = new VPack.Builder().build().deserialize(vpack, TestEntityEnum.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.e1, is(TestEnum.B)); - } - - protected static class TestEntityObject { - private TestEntityLong o1 = new TestEntityLong(); - private TestEntityArray o2 = new TestEntityArray(); - - public TestEntityLong getO1() { - return o1; - } - - public void setO1(final TestEntityLong o1) { - this.o1 = o1; - } - - public TestEntityArray getO2() { - return o2; - } - - public void setO2(final TestEntityArray o2) { - this.o2 = o2; - } - } - - @Test - public void fromObject() throws VPackException { - final TestEntityObject entity = new TestEntityObject(); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice o1 = vpack.get("o1"); - assertThat(o1.isObject(), is(true)); - { - final VPackSlice l1 = o1.get("l1"); - assertThat(l1.isInteger(), is(true)); - assertThat(l1.getAsLong(), is(1L)); - } - { - final VPackSlice l2 = o1.get("l2"); - assertThat(l2.isInteger(), is(true)); - assertThat(l2.getAsLong(), is(1L)); - } - } - { - final VPackSlice o2 = vpack.get("o2"); - assertThat(o2.isObject(), is(true)); - { - final VPackSlice a1 = o2.get("a1"); - assertThat(a1.isArray(), is(true)); - assertThat(a1.getLength(), is(entity.o2.a1.length)); - for (int i = 0; i < a1.getLength(); i++) { - assertThat(a1.get(i).getAsString(), is(entity.o2.a1[i])); - } - } - { - final VPackSlice a2 = o2.get("a2"); - assertThat(a2.isArray(), is(true)); - assertThat(a2.getLength(), is(entity.o2.a2.length)); - for (int i = 0; i < a2.getLength(); i++) { - assertThat(a2.get(i).getAsInt(), is(entity.o2.a2[i])); - } - } - { - final VPackSlice a3 = o2.get("a3"); - assertThat(a3.isArray(), is(true)); - assertThat(a3.getLength(), is(entity.o2.a3.length)); - for (int i = 0; i < a3.getLength(); i++) { - assertThat(a3.get(i).getAsBoolean(), is(entity.o2.a3[i])); - } - } - { - final VPackSlice a4 = o2.get("a4"); - assertThat(a4.isArray(), is(true)); - assertThat(a4.getLength(), is(entity.o2.a4.length)); - for (int i = 0; i < a4.getLength(); i++) { - assertThat(TestEnum.valueOf(a4.get(i).getAsString()), is(entity.o2.a4[i])); - } - } - } - } - - @Test - public void toObject() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - { - builder.add("o1", ValueType.OBJECT); - builder.add("l1", 5L); - builder.add("l2", 5L); - builder.close(); - } - { - builder.add("o2", ValueType.OBJECT); - { - builder.add("a1", ValueType.ARRAY); - builder.add("a"); - builder.add("b"); - builder.add("c"); - builder.close(); - } - { - builder.add("a2", ValueType.ARRAY); - builder.add(1); - builder.add(2); - builder.add(3); - builder.add(4); - builder.close(); - } - { - builder.add("a3", ValueType.ARRAY); - builder.add(false); - builder.add(true); - builder.close(); - } - { - builder.add("a4", ValueType.ARRAY); - builder.add(TestEnum.A.name()); - builder.add(TestEnum.B.name()); - builder.close(); - } - builder.close(); - } - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityObject entity = new VPack.Builder().build().deserialize(vpack, TestEntityObject.class); - assertThat(entity, is(notNullValue())); - { - assertThat(entity.o1.l1, is(5L)); - assertThat(entity.o1.l2, is(5L)); - } - { - assertThat(entity.o2.a1.length, is(3)); - assertThat(entity.o2.a1[0], is("a")); - assertThat(entity.o2.a1[1], is("b")); - assertThat(entity.o2.a1[2], is("c")); - } - { - assertThat(entity.o2.a2.length, is(4)); - assertThat(entity.o2.a2[0], is(1)); - assertThat(entity.o2.a2[1], is(2)); - assertThat(entity.o2.a2[2], is(3)); - assertThat(entity.o2.a2[3], is(4)); - } - { - assertThat(entity.o2.a3.length, is(2)); - assertThat(entity.o2.a3[0], is(false)); - assertThat(entity.o2.a3[1], is(true)); - } - { - assertThat(entity.o2.a4.length, is(2)); - assertThat(entity.o2.a4[0], is(TestEnum.A)); - assertThat(entity.o2.a4[1], is(TestEnum.B)); - } - } - - protected static class TestEntityArrayInArray { - private long[][] a1; - - public long[][] getA1() { - return a1; - } - - public void setA1(final long[][] a1) { - this.a1 = a1; - } - } - - @Test - public void fromArrayInArray() throws VPackException { - final TestEntityArrayInArray entity = new TestEntityArrayInArray(); - entity.a1 = new long[][] { { 1, 2, 3 }, { 4, 5, 6 } }; - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice a1 = vpack.get("a1"); - assertThat(a1.isArray(), is(true)); - assertThat(a1.getLength(), is(entity.a1.length)); - for (int i = 0; i < a1.getLength(); i++) { - final VPackSlice at = a1.get(i); - assertThat(at.isArray(), is(true)); - assertThat(at.getLength(), is(entity.a1[i].length)); - for (int j = 0; j < at.getLength(); j++) { - final VPackSlice atat = at.get(j); - assertThat(atat.isInteger(), is(true)); - assertThat(atat.getAsLong(), is(entity.a1[i][j])); - } - } - } - } - - @Test - public void toArrayInArray() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - { - builder.add("a1", ValueType.ARRAY); - { - builder.add(ValueType.ARRAY); - builder.add(1); - builder.add(2); - builder.add(3); - builder.close(); - } - { - builder.add(ValueType.ARRAY); - builder.add(4); - builder.add(5); - builder.add(6); - builder.close(); - } - builder.close(); - } - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityArrayInArray entity = new VPack.Builder().build().deserialize(vpack, - TestEntityArrayInArray.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.a1.length, is(2)); - { - assertThat(entity.a1[0].length, is(3)); - assertThat(entity.a1[0][0], is(1L)); - assertThat(entity.a1[0][1], is(2L)); - assertThat(entity.a1[0][2], is(3L)); - } - { - assertThat(entity.a1[1].length, is(3)); - assertThat(entity.a1[1][0], is(4L)); - assertThat(entity.a1[1][1], is(5L)); - assertThat(entity.a1[1][2], is(6L)); - } - } - - @SuppressWarnings("serial") - protected static class TestCollection extends LinkedList { - - } - - protected static class TestEntityCollectionExtendedWithNulls { - - protected TestCollection a1; - - public TestCollection getA1() { - return a1; - } - - public void setA1(final TestCollection a1) { - this.a1 = a1; - } - - } - - @Test - public void fromCollectionExtendedWithNulls() { - - final TestCollection collection = new TestCollection(); - collection.add("one"); - collection.add(null); - collection.add("two"); - - final TestEntityCollectionExtendedWithNulls entity = new TestEntityCollectionExtendedWithNulls(); - entity.setA1(collection); - - final VPackSlice vpack = new VPack.Builder().serializeNullValues(true).build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice a1 = vpack.get("a1"); - assertThat(a1.isArray(), is(true)); - assertThat(a1.getLength(), is(entity.a1.size())); - - VPackSlice at = a1.get(0); - assertThat(at.isString(), is(true)); - assertThat(at.getAsString(), is(entity.a1.get(0))); - at = a1.get(1); - assertThat(at.isNull(), is(true)); - at = a1.get(2); - assertThat(at.isString(), is(true)); - assertThat(at.getAsString(), is(entity.a1.get(2))); - } - } - - @Test - public void toCollectionExtendedWithNulls() { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - { - builder.add("a1", ValueType.ARRAY); - builder.add("one"); - builder.add(ValueType.NULL); - builder.add("two"); - builder.close(); - } - builder.close(); - } - - final VPackSlice vpack = builder.slice(); - final TestEntityCollectionExtendedWithNulls entity = new VPack.Builder().build().deserialize(vpack, - TestEntityCollectionExtendedWithNulls.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.getA1(), is(notNullValue())); - assertThat(entity.getA1().size(), is(3)); - assertThat(entity.getA1(), contains("one", null, "two")); - } - - protected static class TestEntityArrayInArrayInArray { - - private double[][][] a1; - - public double[][][] getA1() { - return a1; - } - - public void setA1(final double[][][] a1) { - this.a1 = a1; - } - - } - - @Test - public void fromArrayInArrayInArray() throws VPackException { - final TestEntityArrayInArrayInArray entity = new TestEntityArrayInArrayInArray(); - entity.setA1(new double[][][] { { { 1.5, 2.25 }, { 10.5, 20.25 } }, { { 100.5 }, { 200.25 } } }); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice a1 = vpack.get("a1"); - assertThat(a1.isArray(), is(true)); - assertThat(a1.getLength(), is(entity.a1.length)); - for (int i = 0; i < a1.getLength(); i++) { - final VPackSlice at = a1.get(i); - assertThat(at.isArray(), is(true)); - assertThat(at.getLength(), is(entity.a1[i].length)); - for (int j = 0; j < at.getLength(); j++) { - final VPackSlice atat = at.get(j); - assertThat(atat.isArray(), is(true)); - assertThat(atat.getLength(), is(entity.a1[i][j].length)); - for (int k = 0; k < atat.getLength(); k++) { - final VPackSlice atatat = atat.get(k); - assertThat(atatat.isDouble(), is(true)); - assertThat(atatat.getAsDouble(), is(entity.a1[i][j][k])); - } - } - } - } - } - - @Test - public void toArrayInArrayInArray() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - { - builder.add("a1", ValueType.ARRAY); - builder.add(ValueType.ARRAY); - { - builder.add(ValueType.ARRAY); - builder.add(1.5); - builder.add(2.5); - builder.add(3.5); - builder.close(); - } - { - builder.add(ValueType.ARRAY); - builder.add(4.5); - builder.add(5.5); - builder.add(6.5); - builder.close(); - } - { - builder.add(ValueType.ARRAY); - builder.add(7.5); - builder.add(8.5); - builder.add(9.5); - builder.close(); - } - builder.close(); - builder.add(ValueType.ARRAY); - { - builder.add(ValueType.ARRAY); - builder.add(1.5); - builder.add(2.5); - builder.add(3.5); - builder.close(); - } - { - builder.add(ValueType.ARRAY); - builder.add(4.5); - builder.add(5.5); - builder.add(6.5); - builder.close(); - } - { - builder.add(ValueType.ARRAY); - builder.add(7.5); - builder.add(8.5); - builder.add(9.5); - builder.close(); - } - builder.close(); - builder.close(); - } - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityArrayInArrayInArray entity = new VPack.Builder().build().deserialize(vpack, - TestEntityArrayInArrayInArray.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.a1.length, is(2)); - { - assertThat(entity.a1[0].length, is(3)); - assertThat(entity.a1[0][0].length, is(3)); - assertThat(entity.a1[0][0][0], is(1.5)); - assertThat(entity.a1[0][0][1], is(2.5)); - assertThat(entity.a1[0][0][2], is(3.5)); - assertThat(entity.a1[0][1].length, is(3)); - assertThat(entity.a1[0][1][0], is(4.5)); - assertThat(entity.a1[0][1][1], is(5.5)); - assertThat(entity.a1[0][1][2], is(6.5)); - assertThat(entity.a1[0][2].length, is(3)); - assertThat(entity.a1[0][2][0], is(7.5)); - assertThat(entity.a1[0][2][1], is(8.5)); - assertThat(entity.a1[0][2][2], is(9.5)); - } - { - assertThat(entity.a1[1].length, is(3)); - assertThat(entity.a1[1][0].length, is(3)); - assertThat(entity.a1[1][0][0], is(1.5)); - assertThat(entity.a1[1][0][1], is(2.5)); - assertThat(entity.a1[1][0][2], is(3.5)); - assertThat(entity.a1[1][1].length, is(3)); - assertThat(entity.a1[1][1][0], is(4.5)); - assertThat(entity.a1[1][1][1], is(5.5)); - assertThat(entity.a1[1][1][2], is(6.5)); - assertThat(entity.a1[1][2].length, is(3)); - assertThat(entity.a1[1][2][0], is(7.5)); - assertThat(entity.a1[1][2][1], is(8.5)); - assertThat(entity.a1[1][2][2], is(9.5)); - } - } - - protected static class TestEntityObjectInArray { - private TestEntityString[] a1; - - public TestEntityString[] getA1() { - return a1; - } - - public void setA1(final TestEntityString[] a1) { - this.a1 = a1; - } - } - - @Test - public void fromObjectInArray() throws VPackException { - final TestEntityObjectInArray entity = new TestEntityObjectInArray(); - { - final TestEntityString[] a1 = new TestEntityString[2]; - final TestEntityString s = new TestEntityString(); - s.setS("abc"); - a1[0] = s; - a1[1] = s; - entity.setA1(a1); - } - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice a1 = vpack.get("a1"); - assertThat(a1.isArray(), is(true)); - assertThat(a1.getLength(), is(2)); - for (int i = 0; i < a1.getLength(); i++) { - final VPackSlice at = a1.get(i); - assertThat(at.isObject(), is(true)); - final VPackSlice s = at.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("abc")); - } - } - } - - @Test - public void toObjectInArray() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("a1", ValueType.ARRAY); - { - builder.add(ValueType.OBJECT); - builder.add("s", "abc"); - builder.close(); - } - builder.close(); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityObjectInArray entity = new VPack.Builder().build().deserialize(vpack, - TestEntityObjectInArray.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.a1, is(notNullValue())); - assertThat(entity.a1.length, is(1)); - final TestEntityString st = entity.a1[0]; - assertThat(st, is(notNullValue())); - assertThat(st.s, is("abc")); - } - - protected static class TestEntityA { - private String a = "a"; - - public String getA() { - return a; - } - - public void setA(final String a) { - this.a = a; - } - } - - protected static class TestEntityB extends TestEntityA { - private String b = "b"; - - public String getB() { - return b; - } - - public void setB(final String b) { - this.b = b; - } - } - - @Test - public void fromInheritance() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityB()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.getLength(), is(2)); - { - final VPackSlice a = vpack.get("a"); - assertThat(a.isString(), is(true)); - assertThat(a.getAsString(), is("a")); - } - { - final VPackSlice b = vpack.get("b"); - assertThat(b.isString(), is(true)); - assertThat(b.getAsString(), is("b")); - } - } - - @Test - public void toInheritance() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("a", "test"); - builder.add("b", "test"); - builder.close(); - } - final VPackSlice vpack = builder.slice(); - { - final TestEntityA entity = new VPack.Builder().build().deserialize(vpack, TestEntityA.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.getA(), is("test")); - } - { - final TestEntityB entity = new VPack.Builder().build().deserialize(vpack, TestEntityB.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.getA(), is("test")); - assertThat(entity.getB(), is("test")); - } - } - - protected static class TestEntityC { - private TestEntityD d; - - public TestEntityD getD() { - return d; - } - - public void setD(final TestEntityD d) { - this.d = d; - } - } - - protected interface TestEntityD { - String getD(); - - void setD(String d); - } - - protected static class TestEntityDImpl implements TestEntityD { - private String d = "d"; - - @Override - public String getD() { - return d; - } - - @Override - public void setD(final String d) { - this.d = d; - } - } - - @Test - public void fromInterface() throws VPackException { - final TestEntityC entity = new TestEntityC(); - entity.setD(new TestEntityDImpl()); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice d = vpack.get("d"); - assertThat(d.isObject(), is(true)); - final VPackSlice dd = d.get("d"); - assertThat(dd.isString(), is(true)); - assertThat(dd.getAsString(), is("d")); - } - } - - @Test - public void toInterface() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("d", ValueType.OBJECT); - builder.add("d", "test"); - builder.close(); - builder.close(); - } - final VPackSlice slice = builder.slice(); - final VPack vPack = new VPack.Builder() - .registerInstanceCreator(TestEntityD.class, new VPackInstanceCreator() { - @Override - public TestEntityD createInstance() { - return new TestEntityDImpl(); - } - }).build(); - final TestEntityC entity = vPack.deserialize(slice, TestEntityC.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.d, is(notNullValue())); - assertThat(entity.d.getD(), is("test")); - } - - protected static class TestEntityCollection { - private Collection c1 = new LinkedList<>(); - private List c2 = new ArrayList<>(); - private ArrayList c3 = new ArrayList<>(); - private Set c4 = new LinkedHashSet<>(); - private HashSet c5 = new HashSet<>(); - - public TestEntityCollection() { - super(); - } - - public Collection getC1() { - return c1; - } - - public void setC1(final Collection c1) { - this.c1 = c1; - } - - public List getC2() { - return c2; - } - - public void setC2(final List c2) { - this.c2 = c2; - } - - public ArrayList getC3() { - return c3; - } - - public void setC3(final ArrayList c3) { - this.c3 = c3; - } - - public Set getC4() { - return c4; - } - - public void setC4(final Set c4) { - this.c4 = c4; - } - - public HashSet getC5() { - return c5; - } - - public void setC5(final HashSet c5) { - this.c5 = c5; - } - } - - @Test - public void fromCollection() throws VPackException { - final TestEntityCollection entity = new TestEntityCollection(); - { - entity.c1.add("test"); - entity.c2.add("test"); - entity.c3.add("test"); - entity.c4.add("test"); - entity.c5.add("test"); - } - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice c1 = vpack.get("c1"); - assertThat(c1.isArray(), is(true)); - assertThat(c1.getLength(), is(1)); - assertThat(c1.get(0).getAsString(), is("test")); - } - { - final VPackSlice c2 = vpack.get("c2"); - assertThat(c2.isArray(), is(true)); - assertThat(c2.getLength(), is(1)); - assertThat(c2.get(0).getAsString(), is("test")); - } - { - final VPackSlice c3 = vpack.get("c3"); - assertThat(c3.isArray(), is(true)); - assertThat(c3.getLength(), is(1)); - assertThat(c3.get(0).getAsString(), is("test")); - } - { - final VPackSlice c4 = vpack.get("c4"); - assertThat(c4.isArray(), is(true)); - assertThat(c4.getLength(), is(1)); - assertThat(c4.get(0).getAsString(), is("test")); - } - { - final VPackSlice c5 = vpack.get("c5"); - assertThat(c5.isArray(), is(true)); - assertThat(c5.getLength(), is(1)); - assertThat(c5.get(0).getAsString(), is("test")); - } - } - - @Test - public void toCollection() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - { - builder.add("c1", ValueType.ARRAY); - builder.add("test1"); - builder.add("test2"); - builder.close(); - } - { - builder.add("c2", ValueType.ARRAY); - builder.add("test1"); - builder.add("test2"); - builder.close(); - } - { - builder.add("c3", ValueType.ARRAY); - builder.add("test1"); - builder.add("test2"); - builder.close(); - } - { - builder.add("c4", ValueType.ARRAY); - builder.add("test1"); - builder.add("test2"); - builder.close(); - } - { - builder.add("c5", ValueType.ARRAY); - builder.add("test1"); - builder.add("test2"); - builder.close(); - } - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityCollection entity = new VPack.Builder().build().deserialize(vpack, TestEntityCollection.class); - assertThat(entity, is(notNullValue())); - { - checkCollection(entity.c1); - checkCollection(entity.c2); - checkCollection(entity.c3); - checkCollection(entity.c4); - checkCollection(entity.c5); - } - } - - private void checkCollection(final Collection col) { - assertThat(col, is(notNullValue())); - assertThat(col.size(), is(2)); - for (final String next : col) { - assertThat("test1".equals(next) || "test2".equals(next), is(true)); - } - } - - protected static class TestEntityCollectionWithObjects { - private Collection c1; - private Set c2; - - public Collection getC1() { - return c1; - } - - public void setC1(final Collection c1) { - this.c1 = c1; - } - - public Set getC2() { - return c2; - } - - public void setC2(final Set c2) { - this.c2 = c2; - } - } - - @Test - public void fromCollectionWithObjects() throws VPackException { - final TestEntityCollectionWithObjects entity = new TestEntityCollectionWithObjects(); - { - final Collection c1 = new ArrayList<>(); - c1.add(new TestEntityString()); - c1.add(new TestEntityString()); - entity.setC1(c1); - final Set c2 = new HashSet<>(); - c2.add(new TestEntityArray()); - entity.setC2(c2); - } - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice c1 = vpack.get("c1"); - assertThat(c1.isArray(), is(true)); - assertThat(c1.getLength(), is(2)); - assertThat(c1.get(0).isObject(), is(true)); - assertThat(c1.get(1).isObject(), is(true)); - { - final VPackSlice s = c1.get(0).get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("test")); - } - } - { - final VPackSlice c2 = vpack.get("c2"); - assertThat(c2.isArray(), is(true)); - assertThat(c2.getLength(), is(1)); - assertThat(c2.get(0).isObject(), is(true)); - { - final VPackSlice a2 = c2.get(0).get("a2"); - assertThat(a2.isArray(), is(true)); - assertThat(a2.getLength(), is(5)); - for (int i = 0; i < a2.getLength(); i++) { - final VPackSlice at = a2.get(i); - assertThat(at.isInteger(), is(true)); - assertThat(at.getAsInt(), is(i + 1)); - } - } - } - } - - @Test - public void toCollectionWithObjects() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - { - builder.add("c1", ValueType.ARRAY); - builder.add(ValueType.OBJECT); - builder.add("s", "abc"); - builder.close(); - builder.close(); - } - { - builder.add("c2", ValueType.ARRAY); - builder.add(ValueType.OBJECT); - builder.add("a2", ValueType.ARRAY); - for (int i = 0; i < 10; i++) { - builder.add(i); - } - builder.close(); - builder.close(); - builder.close(); - } - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityCollectionWithObjects entity = new VPack.Builder().build().deserialize(vpack, - TestEntityCollectionWithObjects.class); - assertThat(entity, is(notNullValue())); - { - assertThat(entity.c1, is(notNullValue())); - assertThat(entity.c1.size(), is(1)); - assertThat(entity.c1.iterator().next().s, is("abc")); - } - { - assertThat(entity.c2, is(notNullValue())); - assertThat(entity.c2.size(), is(1)); - final int[] array = entity.c2.iterator().next().a2; - for (int i = 0; i < array.length; i++) { - assertThat(array[i], is(i)); - } - } - } - - protected static class TestEntityMap { - private Map m1; - private HashMap m2; - private Map m3; - - public Map getM1() { - return m1; - } - - public void setM1(final Map m1) { - this.m1 = m1; - } - - public HashMap getM2() { - return m2; - } - - public void setM2(final HashMap m2) { - this.m2 = m2; - } - - public Map getM3() { - return m3; - } - - public void setM3(final Map m3) { - this.m3 = m3; - } - } - - @Test - public void fromMap() throws VPackException { - final TestEntityMap entity = new TestEntityMap(); - { - final Map m1 = new LinkedHashMap<>(); - m1.put("a", "b"); - m1.put("c", "d"); - entity.setM1(m1); - final HashMap m2 = new HashMap<>(); - m2.put(1, "a"); - m2.put(2, "b"); - entity.setM2(m2); - final Map m3 = new HashMap<>(); - final TestEntityString s = new TestEntityString(); - s.setS("abc"); - m3.put("a", s); - entity.setM3(m3); - } - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice m1 = vpack.get("m1"); - assertThat(m1.isObject(), is(true)); - assertThat(m1.getLength(), is(2)); - { - final VPackSlice a = m1.get("a"); - assertThat(a.isString(), is(true)); - assertThat(a.getAsString(), is("b")); - } - { - final VPackSlice c = m1.get("c"); - assertThat(c.isString(), is(true)); - assertThat(c.getAsString(), is("d")); - } - } - { - final VPackSlice m2 = vpack.get("m2"); - assertThat(m2.isObject(), is(true)); - assertThat(m2.getLength(), is(2)); - { - final VPackSlice one = m2.get("1"); - assertThat(one.isString(), is(true)); - assertThat(one.getAsString(), is("a")); - } - { - final VPackSlice two = m2.get("2"); - assertThat(two.isString(), is(true)); - assertThat(two.getAsString(), is("b")); - } - } - { - final VPackSlice m3 = vpack.get("m3"); - assertThat(m3.isObject(), is(true)); - assertThat(m3.getLength(), is(1)); - final VPackSlice a = m3.get("a"); - assertThat(a.isObject(), is(true)); - final VPackSlice s = a.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("abc")); - } - } - - @Test - public void toMap() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - { - builder.add("m1", ValueType.OBJECT); - builder.add("a", "a"); - builder.add("b", "b"); - builder.close(); - } - { - builder.add("m2", ValueType.OBJECT); - builder.add("1", "a"); - builder.add("-1", "a"); - builder.close(); - } - { - builder.add("m3", ValueType.OBJECT); - builder.add("a", ValueType.OBJECT); - builder.add("s", "abc"); - builder.close(); - builder.close(); - } - builder.close(); - } - final VPackSlice vpack = builder.slice(); - final TestEntityMap entity = new VPack.Builder().build().deserialize(vpack, TestEntityMap.class); - assertThat(entity, is(notNullValue())); - { - assertThat(entity.m1, is(notNullValue())); - assertThat(entity.m1.size(), is(2)); - final String a = entity.m1.get("a"); - assertThat(a, is(notNullValue())); - assertThat(a, is("a")); - final String b = entity.m1.get("b"); - assertThat(b, is(notNullValue())); - assertThat(b, is("b")); - } - { - assertThat(entity.m2, is(notNullValue())); - assertThat(entity.m2.size(), is(2)); - final String one = entity.m2.get(1); - assertThat(one, is(notNullValue())); - assertThat(one, is("a")); - final String oneNegative = entity.m2.get(-1); - assertThat(oneNegative, is(notNullValue())); - assertThat(oneNegative, is("a")); - } - { - assertThat(entity.m3, is(notNullValue())); - assertThat(entity.m3.size(), is(1)); - final TestEntityString a = entity.m3.get("a"); - assertThat(a, is(notNullValue())); - assertThat(a.s, is("abc")); - } - } - - protected static class TestEntityMapStringableKey { - private Map m1; - private Map m2; - private Map m3; - private Map m4; - private Map m5; - private Map m6; - private Map m7; - private Map m8; - private Map m9; - private Map m10; - private Map m11; - - public Map getM1() { - return m1; - } - - public void setM1(final Map m1) { - this.m1 = m1; - } - - public Map getM2() { - return m2; - } - - public void setM2(final Map m2) { - this.m2 = m2; - } - - public Map getM3() { - return m3; - } - - public void setM3(final Map m3) { - this.m3 = m3; - } - - public Map getM4() { - return m4; - } - - public void setM4(final Map m4) { - this.m4 = m4; - } - - public Map getM5() { - return m5; - } - - public void setM5(final Map m5) { - this.m5 = m5; - } - - public Map getM6() { - return m6; - } - - public void setM6(final Map m6) { - this.m6 = m6; - } - - public Map getM7() { - return m7; - } - - public void setM7(final Map m7) { - this.m7 = m7; - } - - public Map getM8() { - return m8; - } - - public void setM8(final Map m8) { - this.m8 = m8; - } - - public Map getM9() { - return m9; - } - - public void setM9(final Map m9) { - this.m9 = m9; - } - - public Map getM10() { - return m10; - } - - public void setM10(final Map m10) { - this.m10 = m10; - } - - public Map getM11() { - return m11; - } - - public void setM11(final Map m11) { - this.m11 = m11; - } - - } - - @Test - public void fromMapStringableKey() throws VPackException { - final TestEntityMapStringableKey entity = new TestEntityMapStringableKey(); - final String value = "test"; - { - final Map m1 = new HashMap<>(); - m1.put(true, value); - m1.put(false, value); - entity.setM1(m1); - } - { - final Map m2 = new HashMap<>(); - m2.put(1, value); - m2.put(2, value); - entity.setM2(m2); - } - { - final Map m3 = new HashMap<>(); - m3.put(1L, value); - m3.put(2L, value); - entity.setM3(m3); - } - { - final Map m4 = new HashMap<>(); - m4.put(1.5F, value); - m4.put(2.25F, value); - entity.setM4(m4); - } - { - final Map m5 = new HashMap<>(); - m5.put(new Short("1"), value); - m5.put(new Short("2"), value); - entity.setM5(m5); - } - { - final Map m6 = new HashMap<>(); - m6.put(1.5, value); - m6.put(2.25, value); - entity.setM6(m6); - } - { - final Map m7 = new HashMap<>(); - m7.put(1.5, value); - m7.put(1L, value); - entity.setM7(m7); - } - { - final Map m8 = new HashMap<>(); - m8.put(new BigInteger("1"), value); - m8.put(new BigInteger("2"), value); - entity.setM8(m8); - } - { - final Map m9 = new HashMap<>(); - m9.put(new BigDecimal("1.5"), value); - m9.put(new BigDecimal("2.25"), value); - entity.setM9(m9); - } - { - final Map m10 = new HashMap<>(); - m10.put('1', value); - m10.put('a', value); - entity.setM10(m10); - } - { - final Map m11 = new HashMap<>(); - m11.put(TestEnum.A, value); - m11.put(TestEnum.B, value); - entity.setM11(m11); - } - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice m1 = vpack.get("m1"); - assertThat(m1.isObject(), is(true)); - assertThat(m1.getLength(), is(2)); - checkMapAttribute(m1.get("true")); - checkMapAttribute(m1.get("false")); - } - { - final VPackSlice m2 = vpack.get("m2"); - assertThat(m2.isObject(), is(true)); - assertThat(m2.getLength(), is(2)); - checkMapAttribute(m2.get("1")); - checkMapAttribute(m2.get("2")); - } - { - final VPackSlice m3 = vpack.get("m3"); - assertThat(m3.isObject(), is(true)); - assertThat(m3.getLength(), is(2)); - checkMapAttribute(m3.get("1")); - checkMapAttribute(m3.get("2")); - } - { - final VPackSlice m4 = vpack.get("m4"); - assertThat(m4.isObject(), is(true)); - assertThat(m4.getLength(), is(2)); - checkMapAttribute(m4.get("1.5")); - checkMapAttribute(m4.get("2.25")); - } - { - final VPackSlice m5 = vpack.get("m5"); - assertThat(m5.isObject(), is(true)); - assertThat(m5.getLength(), is(2)); - checkMapAttribute(m5.get("1")); - checkMapAttribute(m5.get("2")); - } - { - final VPackSlice m6 = vpack.get("m6"); - assertThat(m6.isObject(), is(true)); - assertThat(m6.getLength(), is(2)); - checkMapAttribute(m6.get("1.5")); - checkMapAttribute(m6.get("2.25")); - } - { - final VPackSlice m7 = vpack.get("m7"); - assertThat(m7.isObject(), is(true)); - assertThat(m7.getLength(), is(2)); - checkMapAttribute(m7.get("1.5")); - checkMapAttribute(m7.get("1")); - } - { - final VPackSlice m8 = vpack.get("m8"); - assertThat(m8.isObject(), is(true)); - assertThat(m8.getLength(), is(2)); - checkMapAttribute(m8.get("1")); - checkMapAttribute(m8.get("2")); - } - { - final VPackSlice m9 = vpack.get("m9"); - assertThat(m9.isObject(), is(true)); - assertThat(m9.getLength(), is(2)); - checkMapAttribute(m9.get("1.5")); - checkMapAttribute(m9.get("2.25")); - } - { - final VPackSlice m10 = vpack.get("m10"); - assertThat(m10.isObject(), is(true)); - assertThat(m10.getLength(), is(2)); - checkMapAttribute(m10.get("1")); - checkMapAttribute(m10.get("a")); - } - { - final VPackSlice m11 = vpack.get("m11"); - assertThat(m11.isObject(), is(true)); - assertThat(m11.getLength(), is(2)); - checkMapAttribute(m11.get(TestEnum.A.name())); - checkMapAttribute(m11.get(TestEnum.B.name())); - } - } - - @Test - public void toMapSringableKey() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - { - builder.add("m1", ValueType.OBJECT); - builder.add("true", "test"); - builder.add("false", "test"); - builder.close(); - } - { - builder.add("m2", ValueType.OBJECT); - builder.add("1", "test"); - builder.add("2", "test"); - builder.close(); - } - { - builder.add("m3", ValueType.OBJECT); - builder.add("1", "test"); - builder.add("2", "test"); - builder.close(); - } - { - builder.add("m4", ValueType.OBJECT); - builder.add("1.5", "test"); - builder.add("2.25", "test"); - builder.close(); - } - { - builder.add("m5", ValueType.OBJECT); - builder.add("1", "test"); - builder.add("2", "test"); - builder.close(); - } - { - builder.add("m6", ValueType.OBJECT); - builder.add("1.5", "test"); - builder.add("2.25", "test"); - builder.close(); - } - { - builder.add("m7", ValueType.OBJECT); - builder.add("1.5", "test"); - builder.add("1", "test"); - builder.close(); - } - { - builder.add("m8", ValueType.OBJECT); - builder.add("1", "test"); - builder.add("2", "test"); - builder.close(); - } - { - builder.add("m9", ValueType.OBJECT); - builder.add("1.5", "test"); - builder.add("2.25", "test"); - builder.close(); - } - { - builder.add("m10", ValueType.OBJECT); - builder.add("1", "test"); - builder.add("a", "test"); - builder.close(); - } - { - builder.add("m11", ValueType.OBJECT); - builder.add(TestEnum.A.name(), "test"); - builder.add(TestEnum.B.name(), "test"); - builder.close(); - } - builder.close(); - final TestEntityMapStringableKey entity = new VPack.Builder().build().deserialize(builder.slice(), - TestEntityMapStringableKey.class); - { - assertThat(entity.m1.size(), is(2)); - checkMapAttribute(entity.m1.get(true)); - checkMapAttribute(entity.m1.get(false)); - } - { - assertThat(entity.m2.size(), is(2)); - checkMapAttribute(entity.m2.get(1)); - checkMapAttribute(entity.m2.get(2)); - } - { - assertThat(entity.m3.size(), is(2)); - checkMapAttribute(entity.m3.get(1L)); - checkMapAttribute(entity.m3.get(2L)); - } - { - assertThat(entity.m4.size(), is(2)); - checkMapAttribute(entity.m4.get(1.5F)); - checkMapAttribute(entity.m4.get(2.25F)); - } - { - assertThat(entity.m5.size(), is(2)); - checkMapAttribute(entity.m5.get(new Short("1"))); - checkMapAttribute(entity.m5.get(new Short("2"))); - } - { - assertThat(entity.m6.size(), is(2)); - checkMapAttribute(entity.m6.get(1.5)); - checkMapAttribute(entity.m6.get(2.25)); - } - { - assertThat(entity.m7.size(), is(2)); - checkMapAttribute(entity.m7.get(1.5)); - checkMapAttribute(entity.m7.get((double) 1L)); - } - { - assertThat(entity.m8.size(), is(2)); - checkMapAttribute(entity.m8.get(new BigInteger("1"))); - checkMapAttribute(entity.m8.get(new BigInteger("2"))); - } - { - assertThat(entity.m9.size(), is(2)); - checkMapAttribute(entity.m9.get(new BigDecimal("1.5"))); - checkMapAttribute(entity.m9.get(new BigDecimal("2.25"))); - } - { - assertThat(entity.m10.size(), is(2)); - checkMapAttribute(entity.m10.get('1')); - checkMapAttribute(entity.m10.get('a')); - } - { - assertThat(entity.m11.size(), is(2)); - checkMapAttribute(entity.m11.get(TestEnum.A)); - checkMapAttribute(entity.m11.get(TestEnum.B)); - } - } - - private void checkMapAttribute(final VPackSlice attr) { - assertThat(attr.isString(), is(true)); - assertThat(attr.getAsString(), is("test")); - } - - private void checkMapAttribute(final String attr) { - assertThat(attr, is("test")); - } - - protected static class TestEntityMapWithObjectKey { - private Map m1; - private Map m2; - - public Map getM1() { - return m1; - } - - public void setM1(final Map m1) { - this.m1 = m1; - } - - public Map getM2() { - return m2; - } - - public void setM2(final Map m2) { - this.m2 = m2; - } - } - - @Test - public void fromMapWithObjectKey() throws VPackException { - final TestEntityMapWithObjectKey entity = new TestEntityMapWithObjectKey(); - { - final Map m1 = new HashMap<>(); - m1.put(new TestEntityLong(), new TestEntityCollection()); - m1.put(new TestEntityLong(), new TestEntityCollection()); - entity.setM1(m1); - } - { - final Map m2 = new HashMap<>(); - m2.put(new TestEntityLong(), "test"); - m2.put(new TestEntityLong(), "test"); - m2.put(new TestEntityLong(), "test"); - entity.setM2(m2); - } - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice m1 = vpack.get("m1"); - assertThat(m1.isArray(), is(true)); - assertThat(m1.getLength(), is(2)); - for (int i = 0; i < m1.getLength(); i++) { - final VPackSlice at = m1.get(i); - assertThat(at.isObject(), is(true)); - assertThat(at.getLength(), is(2)); - { - final VPackSlice key = at.get("key"); - assertThat(key.isObject(), is(true)); - final VPackSlice l1 = key.get("l1"); - assertThat(l1.isInteger(), is(true)); - assertThat(l1.getAsLong(), is(1L)); - } - { - final VPackSlice value = at.get("value"); - assertThat(value.isObject(), is(true)); - final VPackSlice c1 = value.get("c1"); - assertThat(c1.isArray(), is(true)); - } - } - } - { - final VPackSlice m2 = vpack.get("m2"); - assertThat(m2.isArray(), is(true)); - assertThat(m2.getLength(), is(3)); - for (int i = 0; i < m2.getLength(); i++) { - final VPackSlice at = m2.get(i); - assertThat(at.isObject(), is(true)); - assertThat(at.getLength(), is(2)); - { - final VPackSlice key = at.get("key"); - assertThat(key.isObject(), is(true)); - final VPackSlice l1 = key.get("l1"); - assertThat(l1.isInteger(), is(true)); - assertThat(l1.getAsLong(), is(1L)); - } - { - final VPackSlice value = at.get("value"); - assertThat(value.isString(), is(true)); - assertThat(value.getAsString(), is("test")); - } - } - } - } - - @Test - public void toMapWithObjectKey() throws VPackException { - final int size = 2; - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - { - builder.add("m1", ValueType.ARRAY); - for (int i = 0; i < size; i++) { - builder.add(ValueType.OBJECT); - { - builder.add("key", ValueType.OBJECT); - builder.add("l1", 5L); - builder.close(); - } - { - builder.add("value", ValueType.OBJECT); - builder.add("c1", ValueType.ARRAY); - builder.add("test"); - builder.close(); - builder.close(); - } - builder.close(); - } - builder.close(); - } - { - builder.add("m2", ValueType.ARRAY); - for (int i = 0; i < size; i++) { - builder.add(ValueType.OBJECT); - { - builder.add("key", ValueType.OBJECT); - builder.add("l1", 5L); - builder.close(); - } - { - builder.add("value", "test"); - } - builder.close(); - } - builder.close(); - } - builder.close(); - final TestEntityMapWithObjectKey entity = new VPack.Builder().build().deserialize(builder.slice(), - TestEntityMapWithObjectKey.class); - assertThat(entity, is(notNullValue())); - { - assertThat(entity.m1, is(notNullValue())); - assertThat(entity.m1.size(), is(size)); - for (final Entry entry : entity.m1.entrySet()) { - assertThat(entry.getKey().l1, is(5L)); - assertThat(entry.getValue().c1.size(), is(1)); - assertThat(entry.getValue().c1.iterator().next(), is("test")); - } - } - { - assertThat(entity.m2, is(notNullValue())); - assertThat(entity.m2.size(), is(2)); - for (final Entry entry : entity.m2.entrySet()) { - assertThat(entry.getKey().l1, is(5L)); - assertThat(entry.getValue(), is("test")); - } - } - } - - protected static class TestEntityEmpty { - - } - - @Test - public void fromEmptyObject() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityEmpty()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.getLength(), is(0)); - } - - @Test - public void toEmptyObject() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.close(); - final TestEntityEmpty entity = new VPack.Builder().build().deserialize(builder.slice(), TestEntityEmpty.class); - assertThat(entity, is(notNullValue())); - } - - protected static class TestEntityEmptyMap { - private Map m; - - public Map getM() { - return m; - } - - public void setM(final Map m) { - this.m = m; - } - } - - @Test - public void fromEmptyMap() throws VPackException { - final TestEntityEmptyMap entity = new TestEntityEmptyMap(); - entity.setM(new HashMap()); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.getLength(), is(1)); - final VPackSlice m = vpack.get("m"); - assertThat(m.isObject(), is(true)); - assertThat(m.getLength(), is(0)); - } - - @Test - public void toEmptyMap() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("m", ValueType.OBJECT); - builder.close(); - builder.close(); - final TestEntityEmptyMap entity = new VPack.Builder().build().deserialize(builder.slice(), - TestEntityEmptyMap.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.m, is(notNullValue())); - assertThat(entity.m.size(), is(0)); - } - - protected static class TestEntityBaseAttributes { - private String _key = "test1"; - private String _rev = "test2"; - private String _id = "test3"; - private String _from = "test4"; - private String _to = "test5"; - - public String get_key() { - return _key; - } - - public void set_key(final String _key) { - this._key = _key; - } - - public String get_rev() { - return _rev; - } - - public void set_rev(final String _rev) { - this._rev = _rev; - } - - public String get_id() { - return _id; - } - - public void set_id(final String _id) { - this._id = _id; - } - - public String get_from() { - return _from; - } - - public void set_from(final String _from) { - this._from = _from; - } - - public String get_to() { - return _to; - } - - public void set_to(final String _to) { - this._to = _to; - } - - } - - @Test - public void fromObjectWithAttributeAdapter() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityBaseAttributes()); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.getLength(), is(5)); - { - final VPackSlice key = vpack.get("_key"); - assertThat(key.isString(), is(true)); - assertThat(key.getAsString(), is("test1")); - } - { - final VPackSlice rev = vpack.get("_rev"); - assertThat(rev.isString(), is(true)); - assertThat(rev.getAsString(), is("test2")); - } - { - final VPackSlice id = vpack.get("_id"); - assertThat(id.isString(), is(true)); - assertThat(id.getAsString(), is("test3")); - } - { - final VPackSlice from = vpack.get("_from"); - assertThat(from.isString(), is(true)); - assertThat(from.getAsString(), is("test4")); - } - { - final VPackSlice to = vpack.get("_to"); - assertThat(to.isString(), is(true)); - assertThat(to.getAsString(), is("test5")); - } - } - - @Test - public void toObjectWithAttributeAdapter() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("_key", "a"); - builder.add("_rev", "b"); - builder.add("_id", "c"); - builder.add("_from", "d"); - builder.add("_to", "e"); - builder.close(); - } - final TestEntityBaseAttributes entity = new VPack.Builder().build().deserialize(builder.slice(), - TestEntityBaseAttributes.class); - assertThat(entity, is(notNullValue())); - assertThat(entity._key, is("a")); - assertThat(entity._rev, is("b")); - assertThat(entity._id, is("c")); - assertThat(entity._from, is("d")); - assertThat(entity._to, is("e")); - } - - @Test - public void fromMapWithAttributeAdapter() throws VPackException { - final TestEntityMap entity = new TestEntityMap(); - { - final Map m1 = new HashMap<>(); - m1.put("_key", "test1"); - m1.put("_rev", "test2"); - m1.put("_id", "test3"); - m1.put("_from", "test4"); - m1.put("_to", "test5"); - entity.setM1(m1); - } - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack.isObject(), is(true)); - final VPackSlice m1 = vpack.get("m1"); - assertThat(m1.isObject(), is(true)); - assertThat(m1.getLength(), is(5)); - { - final VPackSlice key = m1.get("_key"); - assertThat(key.isString(), is(true)); - assertThat(key.getAsString(), is("test1")); - } - { - final VPackSlice rev = m1.get("_rev"); - assertThat(rev.isString(), is(true)); - assertThat(rev.getAsString(), is("test2")); - } - { - final VPackSlice id = m1.get("_id"); - assertThat(id.isString(), is(true)); - assertThat(id.getAsString(), is("test3")); - } - { - final VPackSlice from = m1.get("_from"); - assertThat(from.isString(), is(true)); - assertThat(from.getAsString(), is("test4")); - } - { - final VPackSlice to = m1.get("_to"); - assertThat(to.isString(), is(true)); - assertThat(to.getAsString(), is("test5")); - } - } - - @Test - public void toMapWithAttributeAdapter() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - { - builder.add(ValueType.OBJECT); - builder.add("m1", ValueType.OBJECT); - builder.add("_key", "a"); - builder.add("_rev", "b"); - builder.add("_id", "c"); - builder.add("_from", "d"); - builder.add("_to", "e"); - builder.close(); - builder.close(); - } - final TestEntityMap entity = new VPack.Builder().build().deserialize(builder.slice(), TestEntityMap.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.m1, is(notNullValue())); - assertThat(entity.m1.size(), is(5)); - } - - @Test - public void customSerializer() throws VPackException { - final String value = "abc"; - final VPack vp = new VPack.Builder() - .registerSerializer(TestEntityString.class, new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final TestEntityString entity, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, ValueType.OBJECT); - builder.add("not-s", entity.s); - builder.close(); - } - }).build(); - final TestEntityString entity = new TestEntityString(); - entity.setS(value); - final VPackSlice vpack = vp.serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice s = vpack.get("not-s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is(value)); - } - } - - @Test - public void customDeserializer() throws VPackException { - final String value = "abc"; - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("not-s", value); - builder.close(); - final VPack vp = new VPack.Builder() - .registerDeserializer(TestEntityString.class, new VPackDeserializer() { - @Override - public TestEntityString deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - final TestEntityString entity = new TestEntityString(); - final VPackSlice nots = vpack.get("not-s"); - if (nots.isString()) { - entity.s = nots.getAsString(); - } - return entity; - } - }).build(); - final TestEntityString entity = vp.deserialize(builder.slice(), TestEntityString.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.s, is(notNullValue())); - assertThat(entity.s, is(value)); - } - - @Test - public void customDeserializerByName() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("s", "test"); - builder.close(); - final TestEntityString entity = new VPack.Builder() - .registerDeserializer("s", String.class, new VPackDeserializer() { - @Override - public String deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return vpack.getAsString() + "s"; - } - - }).build().deserialize(builder.slice(), TestEntityString.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.s, is(notNullValue())); - assertThat(entity.s, is("tests")); - } - - @Test - public void customDeserializerByNameWrongType() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("s", "test"); - builder.close(); - final TestEntityString entity = new VPack.Builder() - .registerDeserializer("s", Integer.class, new VPackDeserializer() { - @Override - public String deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return "fail"; - } - }).build().deserialize(builder.slice(), TestEntityString.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.s, is(notNullValue())); - assertThat(entity.s, is("test")); - } - - @Test - public void customSerializerWithContext() throws VPackException { - final VPack vp = new VPack.Builder() - .registerSerializer(TestEntityObject.class, new VPackSerializer() { - @Override - public void serialize( - final VPackBuilder builder, - final String attribute, - final TestEntityObject entity, - final VPackSerializationContext context) throws VPackException { - builder.add(attribute, ValueType.OBJECT); - context.serialize(builder, "test", entity.o1); - builder.close(); - } - }).build(); - final TestEntityObject entity = new TestEntityObject(); - final VPackSlice vpack = vp.serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - final VPackSlice test = vpack.get("test"); - assertThat(test.isObject(), is(true)); - final VPackSlice l1 = test.get("l1"); - assertThat(l1.isInteger(), is(true)); - assertThat(l1.getAsInt(), is(1)); - } - } - - @Test - public void customDeserializerWithContext() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("test", ValueType.OBJECT); - builder.add("l1", 5); - builder.close(); - builder.close(); - final VPack vp = new VPack.Builder() - .registerDeserializer(TestEntityObject.class, new VPackDeserializer() { - @Override - public TestEntityObject deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - final TestEntityObject entity = new TestEntityObject(); - entity.o1 = context.deserialize(vpack.get("test"), TestEntityLong.class); - return entity; - } - }).build(); - final TestEntityObject entity = vp.deserialize(builder.slice(), TestEntityObject.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.o1, is(notNullValue())); - assertThat(entity.o1.l1, is(5L)); - } - - protected static class TestEntitySerializeAnnotation { - - @SerializedName("abc") - private String test = "test"; - - public String getTest() { - return test; - } - - public void setTest(final String test) { - this.test = test; - } - - } - - @Test - public void fromSerializedName() throws VPackException { - final TestEntitySerializeAnnotation entity = new TestEntitySerializeAnnotation(); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.getLength(), is(1)); - final VPackSlice abc = vpack.get("abc"); - assertThat(abc.isString(), is(true)); - assertThat(abc.getAsString(), is("test")); - } - - @Test - public void toSerializedName() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("abc", "test2"); - builder.close(); - final TestEntitySerializeAnnotation entity = new VPack.Builder().build().deserialize(builder.slice(), - TestEntitySerializeAnnotation.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.test, is(notNullValue())); - assertThat(entity.test, is("test2")); - } - - protected static class TestEntityExpose { - private String a; - @Expose - private String b; - @Expose() - private String c; - @Expose(deserialize = false) - private String d; - @Expose(serialize = false) - private String e; - @Expose(serialize = false, deserialize = false) - private String f; - - public String getA() { - return a; - } - - public void setA(final String a) { - this.a = a; - } - - public String getB() { - return b; - } - - public void setB(final String b) { - this.b = b; - } - - public String getC() { - return c; - } - - public void setC(final String c) { - this.c = c; - } - - public String getD() { - return d; - } - - public void setD(final String d) { - this.d = d; - } - - public String getE() { - return e; - } - - public void setE(final String e) { - this.e = e; - } - - public String getF() { - return f; - } - - public void setF(final String f) { - this.f = f; - } - } - - @Test - public void fromExpose() throws VPackException { - final TestEntityExpose entity = new TestEntityExpose(); - entity.a = entity.b = entity.c = entity.d = entity.e = entity.f = "test"; - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.getLength(), is(4)); - { - final VPackSlice a = vpack.get("a"); - assertThat(a.isString(), is(true)); - assertThat(a.getAsString(), is("test")); - } - { - final VPackSlice b = vpack.get("b"); - assertThat(b.isString(), is(true)); - assertThat(b.getAsString(), is("test")); - } - { - final VPackSlice c = vpack.get("c"); - assertThat(c.isString(), is(true)); - assertThat(c.getAsString(), is("test")); - } - { - final VPackSlice d = vpack.get("d"); - assertThat(d.isString(), is(true)); - assertThat(d.getAsString(), is("test")); - } - } - - @Test - public void toExpose() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", "test"); - builder.add("b", "test"); - builder.add("c", "test"); - builder.add("d", "test"); - builder.add("e", "test"); - builder.add("f", "test"); - builder.close(); - final TestEntityExpose entity = new VPack.Builder().build().deserialize(builder.slice(), - TestEntityExpose.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.a, is(notNullValue())); - assertThat(entity.a, is("test")); - assertThat(entity.b, is(notNullValue())); - assertThat(entity.b, is("test")); - assertThat(entity.c, is(notNullValue())); - assertThat(entity.c, is("test")); - assertThat(entity.e, is(notNullValue())); - assertThat(entity.e, is("test")); - assertThat(entity.d, is(nullValue())); - assertThat(entity.f, is(nullValue())); - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - private @interface CustomFilterAnnotation { - boolean serialize() - - default true; - - boolean deserialize() default true; - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - private @interface CustomNamingAnnotation { - String name(); - } - - private static class CustomAnEntity { - @CustomFilterAnnotation(serialize = false) - private String a = null; - @CustomFilterAnnotation(deserialize = false) - private String b = null; - @CustomNamingAnnotation(name = "d") - @CustomFilterAnnotation(deserialize = false) - private String c = null; - - public CustomAnEntity() { - super(); - } - } - - @Test - public void fromCutsomAnnotation() { - final CustomAnEntity entity = new CustomAnEntity(); - entity.a = "1"; - entity.b = "2"; - entity.c = "3"; - final VPackSlice vpack = new VPack.Builder().annotationFieldFilter(CustomFilterAnnotation.class, - new VPackAnnotationFieldFilter() { - - @Override - public boolean serialize(final CustomFilterAnnotation annotation) { - return annotation.serialize(); - } - - @Override - public boolean deserialize(final CustomFilterAnnotation annotation) { - return annotation.deserialize(); - } - }).annotationFieldNaming(CustomNamingAnnotation.class, - new VPackAnnotationFieldNaming() { - @Override - public String name(final CustomNamingAnnotation annotation) { - return annotation.name(); - } - }).build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.get("a").isNone(), is(true)); - assertThat(vpack.get("b").isString(), is(true)); - assertThat(vpack.get("b").getAsString(), is("2")); - assertThat(vpack.get("c").isNone(), is(true)); - assertThat(vpack.get("d").isString(), is(true)); - assertThat(vpack.get("d").getAsString(), is("3")); - } - - @Test - public void toCustomAnnotation() { - final VPackSlice vpack = new VPackBuilder().add(ValueType.OBJECT).add("a", "1").add("b", "2").add("c", "3") - .add("d", "4").close().slice(); - - final CustomAnEntity entity = new VPack.Builder().annotationFieldFilter(CustomFilterAnnotation.class, - new VPackAnnotationFieldFilter() { - - @Override - public boolean serialize(final CustomFilterAnnotation annotation) { - return annotation.serialize(); - } - - @Override - public boolean deserialize(final CustomFilterAnnotation annotation) { - return annotation.deserialize(); - } - }).annotationFieldNaming(CustomNamingAnnotation.class, - new VPackAnnotationFieldNaming() { - @Override - public String name(final CustomNamingAnnotation annotation) { - return annotation.name(); - } - }).build().deserialize(vpack, CustomAnEntity.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.a, is("1")); - assertThat(entity.b, is(nullValue())); - assertThat(entity.c, is(nullValue())); - } - - @Test - public void directFromCollection() throws VPackException { - final Collection list = new ArrayList<>(); - list.add("test"); - final VPackSlice vpack = new VPack.Builder().build().serialize(list); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isArray(), is(true)); - assertThat(vpack.size(), is(1)); - final VPackSlice test = vpack.get(0); - assertThat(test.isString(), is(true)); - assertThat(test.getAsString(), is("test")); - } - - @Test - public void directFromCollectionWithType() throws VPackException { - final Collection list = new ArrayList<>(); - list.add(new TestEntityString()); - list.add(new TestEntityString()); - - final VPackSlice vpack = new VPack.Builder().build().serialize(list, - new SerializeOptions().type(new Type>() { - }.getType())); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isArray(), is(true)); - assertThat(vpack.getLength(), is(list.size())); - for (int i = 0; i < list.size(); i++) { - final VPackSlice entry = vpack.get(i); - assertThat(entry.isObject(), is(true)); - assertThat(entry.getLength(), is(3)); - final VPackSlice s = entry.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("test")); - } - } - - @Test - public void directToCollection() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.ARRAY); - builder.add(ValueType.OBJECT); - builder.add("s", "abc"); - builder.close(); - builder.close(); - final List list = new VPack.Builder().build().deserialize(builder.slice(), - new Type>() { - }.getType()); - assertThat(list, is(notNullValue())); - assertThat(list.size(), is(1)); - final TestEntityString entry = list.get(0); - assertThat(entry.s, is("abc")); - } - - @Test - public void directFromStringMap() throws VPackException { - final Map map = new HashMap<>(); - map.put("a", new TestEntityString()); - map.put("b", new TestEntityString()); - - final VPackSlice vpack = new VPack.Builder().build().serialize(map, - new SerializeOptions().type(new Type>() { - }.getType())); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.getLength(), is(2)); - final VPackSlice a = vpack.get("a"); - checkStringEntity(a); - } - - @Test - public void directToStringMap() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", ValueType.OBJECT); - builder.add("s", "abc"); - builder.close(); - builder.close(); - final Map map = new VPack.Builder().build().deserialize(builder.slice(), - new Type>() { - }.getType()); - assertThat(map, is(notNullValue())); - assertThat(map.size(), is(1)); - final TestEntityString a = map.get("a"); - assertThat(a, is(notNullValue())); - assertThat(a.s, is("abc")); - } - - @Test - public void directFromObjectMap() throws VPackException { - final Map map = new HashMap<>(); - map.put(new TestEntityString(), new TestEntityString()); - map.put(new TestEntityString(), new TestEntityString()); - - final VPackSlice vpack = new VPack.Builder().build().serialize(map, - new SerializeOptions().type(new Type>() { - }.getType())); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isArray(), is(true)); - assertThat(vpack.getLength(), is(map.size())); - for (int i = 0; i < map.size(); i++) { - final VPackSlice entry = vpack.get(i); - final VPackSlice key = entry.get("key"); - checkStringEntity(key); - final VPackSlice value = entry.get("value"); - checkStringEntity(value); - } - } - - @Test - public void directFromMap() throws VPackException { - final Map map = new HashMap<>(); - final TestEntityA entity = new TestEntityA(); - entity.a = "test"; - map.put("test", entity); - final VPackSlice vpack = new VPack.Builder().build().serialize(map); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - final VPackSlice test = vpack.get("test"); - assertThat(test.isObject(), is(true)); - final VPackSlice a = test.get("a"); - assertThat(a.isString(), is(true)); - assertThat(a.getAsString(), is("test")); - } - - @Test - public void directFromMapWithinMap() throws VPackException { - final Map map = new HashMap<>(); - final Map map2 = new HashMap<>(); - map2.put("b", "test"); - map.put("a", map2); - final VPackSlice vpack = new VPack.Builder().build().serialize(map); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.size(), is(1)); - final VPackSlice a = vpack.get("a"); - assertThat(a.isObject(), is(true)); - assertThat(a.size(), is(1)); - final VPackSlice b = a.get("b"); - assertThat(b.isString(), is(true)); - assertThat(b.getAsString(), is("test")); - } - - private void checkStringEntity(final VPackSlice vpack) throws VPackException { - final TestEntityString expected = new TestEntityString(); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.getLength(), is(3)); - final VPackSlice s = vpack.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is(expected.s)); - final VPackSlice c1 = vpack.get("c1"); - assertThat(c1.isString(), is(true)); - assertThat(c1.getAsChar(), is(expected.c1)); - final VPackSlice c2 = vpack.get("c2"); - assertThat(c2.isString(), is(true)); - assertThat(c2.getAsChar(), is(expected.c2)); - } - - @Test - public void directToObjectMap() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.ARRAY); - builder.add(ValueType.OBJECT); - builder.add("key", ValueType.OBJECT); - builder.add("s", "abc"); - builder.close(); - builder.add("value", ValueType.OBJECT); - builder.add("s", "abc"); - builder.close(); - builder.close(); - builder.close(); - final Map map = new VPack.Builder().build().deserialize(builder.slice(), - new Type>() { - }.getType()); - assertThat(map, is(notNullValue())); - assertThat(map.size(), is(1)); - for (final Entry entry : map.entrySet()) { - assertThat(entry.getKey().s, is("abc")); - assertThat(entry.getValue().s, is("abc")); - } - } - - @SuppressWarnings("unchecked") - @Test - public void directToMapWithinMap() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("a", ValueType.OBJECT); - builder.add("b", "test"); - builder.add("c", true); - builder.add("d", 1L); - builder.add("e", 1.5); - final Date date = new Date(); - builder.add("f", date); - builder.add("g", ValueType.ARRAY); - builder.close(); - builder.close(); - builder.close(); - final Map map = new VPack.Builder().build().deserialize(builder.slice(), Map.class); - assertThat(map, is(notNullValue())); - assertThat(map.size(), is(1)); - final Object a = map.get("a"); - assertThat(Map.class.isAssignableFrom(a.getClass()), is(true)); - assert a instanceof Map; - final Map mapA = (Map) a; - assertThat(mapA.size(), is(6)); - final Object b = mapA.get("b"); - assertThat(String.class.isAssignableFrom(b.getClass()), is(true)); - assertThat(b.toString(), is("test")); - final Object c = mapA.get("c"); - assertThat(Boolean.class.isAssignableFrom(c.getClass()), is(true)); - assert c instanceof Boolean; - assertThat((Boolean) c, is(true)); - final Object d = mapA.get("d"); - assertThat(Number.class.isAssignableFrom(d.getClass()), is(true)); - assert d instanceof Number; - assertThat(((Number) d).longValue(), is(1L)); - final Object e = mapA.get("e"); - assertThat(Double.class.isAssignableFrom(e.getClass()), is(true)); - assert e instanceof Double; - assertThat((Double) e, is(1.5)); - final Object f = mapA.get("f"); - assertThat(Date.class.isAssignableFrom(f.getClass()), is(true)); - assert f instanceof Date; - assertThat((Date) f, is(date)); - final Object g = mapA.get("g"); - assertThat(Collection.class.isAssignableFrom(g.getClass()), is(true)); - assertThat(List.class.isAssignableFrom(g.getClass()), is(true)); - } - - @Test - public void dontSerializeNullValues() throws VPackException { - final VPack serializer = new VPack.Builder().serializeNullValues(false).build(); - final TestEntityString entity = new TestEntityString(); - entity.setS(null); - final VPackSlice vpack = serializer.serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - final VPackSlice s = vpack.get("s"); - assertThat(s.isNone(), is(true)); - } - - @Test - public void serializeNullValue() throws VPackException { - final VPack serializer = new VPack.Builder().serializeNullValues(true).build(); - final TestEntityString entity = new TestEntityString(); - entity.setS(null); - final VPackSlice vpack = serializer.serialize(entity); - assertThat(vpack, is(notNullValue())); - final VPackSlice s = vpack.get("s"); - assertThat(s.isNull(), is(true)); - } - - @Test - public void toNullValue() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("s", ValueType.NULL); - builder.close(); - final TestEntityString entity = new VPack.Builder().build().deserialize(builder.slice(), - TestEntityString.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.s, is(nullValue())); - assertThat(entity.c1, is(notNullValue())); - assertThat(entity.c2, is(notNullValue())); - } - - @Test - public void additionalFields() throws VPackException { - final TestEntityString entity = new TestEntityString(); - final Map additionalFields = new HashMap<>(); - additionalFields.put("a", "test"); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity, - new SerializeOptions().additionalFields(additionalFields)); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.getLength(), is(4)); - final VPackSlice s = vpack.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("test")); - final VPackSlice a = vpack.get("a"); - assertThat(a.isString(), is(true)); - assertThat(a.getAsString(), is("test")); - } - - @Test - public void additionalFieldsNestedPojo() { - final Map value = new HashMap<>(); - value.put("foo", "bar"); - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityObject(), - new SerializeOptions().additionalFields(value)); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.size(), is(3)); - assertThat(vpack.get("foo").isString(), is(true)); - assertThat(vpack.get("foo").getAsString(), is("bar")); - - assertThat(vpack.get("o1").isObject(), is(true)); - assertThat(vpack.get("o1").get("foo").isNone(), is(true)); - assertThat(vpack.get("o2").isObject(), is(true)); - assertThat(vpack.get("o2").get("foo").isNone(), is(true)); - } - - @Test - public void additionalFieldsNestedMap() { - final Map value = new HashMap<>(); - value.put("n", new HashMap()); - final Map additionalFields = new HashMap<>(); - additionalFields.put("foo", "bar"); - final VPackSlice vpack = new VPack.Builder().build().serialize(value, - new SerializeOptions().additionalFields(additionalFields)); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.size(), is(2)); - assertThat(vpack.get("foo").isString(), is(true)); - assertThat(vpack.get("foo").getAsString(), is("bar")); - - assertThat(vpack.get("n").isObject(), is(true)); - assertThat(vpack.get("n").size(), is(0)); - } - - @Test - public void additionalDuplicatedFields() throws VPackException { - final TestEntityString entity = new TestEntityString(); - final Map additionalFields = new HashMap<>(); - additionalFields.put("s", "test1"); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity, - new SerializeOptions().additionalFields(additionalFields)); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.getLength(), is(3)); - final VPackSlice s = vpack.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("test")); - } - - @Test - public void additionalNullFieldsExcludeNull() throws VPackException { - final TestEntityString entity = new TestEntityString(); - final Map additionalFields = new HashMap<>(); - additionalFields.put("a", null); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity, - new SerializeOptions().additionalFields(additionalFields)); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.getLength(), is(3)); - final VPackSlice s = vpack.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("test")); - } - - @Test - public void additionalNullFieldsIncludeNull() throws VPackException { - final TestEntityString entity = new TestEntityString(); - final Map additionalFields = new HashMap<>(); - additionalFields.put("a", null); - final VPack serializer = new VPack.Builder().serializeNullValues(true).build(); - final VPackSlice vpack = serializer.serialize(entity, - new SerializeOptions().additionalFields(additionalFields)); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.getLength(), is(4)); - final VPackSlice s = vpack.get("s"); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("test")); - final VPackSlice a = vpack.get("a"); - assertThat(a.isNull(), is(true)); - } - - @Test - public void toSimpleString() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add("test"); - final String s = new VPack.Builder().build().deserialize(builder.slice(), String.class); - assertThat(s, is(notNullValue())); - assertThat(s, is("test")); - } - - @Test - public void fromSimpleString() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize("test"); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isString(), is(true)); - assertThat(vpack.getAsString(), is("test")); - } - - protected static class TestEntityTyped { - private T e; - } - - @Test - public void fromStringTypedEntity() throws VPackException { - final TestEntityTyped entity = new TestEntityTyped<>(); - entity.e = "test"; - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - final VPackSlice e = vpack.get("e"); - assertThat(e, is(notNullValue())); - assertThat(e.isString(), is(true)); - assertThat(e.getAsString(), is("test")); - } - - @Test - public void fromObjectTypedEntity() throws VPackException { - final TestEntityTyped entity = new TestEntityTyped<>(); - entity.e = new TestEntityString(); - entity.e.s = "test2"; - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - final VPackSlice e = vpack.get("e"); - assertThat(e, is(notNullValue())); - assertThat(e.isObject(), is(true)); - final VPackSlice s = e.get("s"); - assertThat(s, is(notNullValue())); - assertThat(s.isString(), is(true)); - assertThat(s.getAsString(), is("test2")); - } - - @Test - public void fromTypedTypedEntity() throws VPackException { - final TestEntityTyped> entity = new TestEntityTyped<>(); - entity.e = new TestEntityTyped<>(); - entity.e.e = "test"; - final VPackSlice vpack = new VPack.Builder().build().serialize(entity, - new SerializeOptions().type(new Type>>() { - }.getType())); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - final VPackSlice e = vpack.get("e"); - assertThat(e, is(notNullValue())); - assertThat(e.isObject(), is(true)); - final VPackSlice e2 = e.get("e"); - assertThat(e2, is(notNullValue())); - assertThat(e2.isString(), is(true)); - assertThat(e2.getAsString(), is("test")); - } - - @Test - public void fieldNamingStrategySerialize() throws VPackException { - final VPackSlice vpack = new VPack.Builder().fieldNamingStrategy(new VPackFieldNamingStrategy() { - @Override - public String translateName(final Field field) { - return "bla"; - } - }).build().serialize(new TestEntityA()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - final VPackSlice bla = vpack.get("bla"); - assertThat(bla.isString(), is(true)); - assertThat(bla.getAsString(), is("a")); - } - - @Test - public void fieldNamingStrategyDeserialize() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("bla", "test"); - builder.close(); - final TestEntityA entity = new VPack.Builder().fieldNamingStrategy(new VPackFieldNamingStrategy() { - @Override - public String translateName(final Field field) { - return "bla"; - } - }).build().deserialize(builder.slice(), TestEntityA.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.a, is("test")); - } - - @Test - public void serializeVPack() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add("test"); - final VPackSlice slice = builder.slice(); - final VPackSlice vpack = new VPack.Builder().build().serialize(slice); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isString(), is(true)); - assertThat(vpack.getAsString(), is("test")); - } - - @Test - public void deserializeVPack() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add("test"); - final VPackSlice slice = builder.slice(); - final VPackSlice vpack = new VPack.Builder().build().deserialize(slice, slice.getClass()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isString(), is(true)); - assertThat(vpack.getAsString(), is("test")); - } - - protected static class TestEntityDate { - private java.util.Date utilDate = new Date(1474988621); - private java.sql.Date sqlDate = new java.sql.Date(1474988621); - private java.sql.Timestamp timestamp = new java.sql.Timestamp(1474988621); - - public java.util.Date getUtilDate() { - return utilDate; - } - - public void setUtilDate(final java.util.Date utilDate) { - this.utilDate = utilDate; - } - - public java.sql.Date getSqlDate() { - return sqlDate; - } - - public void setSqlDate(final java.sql.Date sqlDate) { - this.sqlDate = sqlDate; - } - - public java.sql.Timestamp getTimestamp() { - return timestamp; - } - - public void setTimestamp(final java.sql.Timestamp timestamp) { - this.timestamp = timestamp; - } - - } - - @Test - public void fromDate() throws VPackException { - final VPackSlice vpack = new VPack.Builder().build().serialize(new TestEntityDate()); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - { - assertThat(vpack.get("utilDate").isString(), is(true)); - assertThat(vpack.get("utilDate").getAsString(), is(DATE_FORMAT.format(new Date(1474988621)))); - } - { - assertThat(vpack.get("sqlDate").isString(), is(true)); - assertThat(vpack.get("sqlDate").getAsString(), is(DATE_FORMAT.format(new java.sql.Date(1474988621)))); - } - { - assertThat(vpack.get("timestamp").isString(), is(true)); - assertThat(vpack.get("timestamp").getAsString(), - is(DATE_FORMAT.format(new java.sql.Timestamp(1474988621)))); - } - } - - @Test - public void toDate() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("utilDate", new Date(1475062216)); - builder.add("sqlDate", new java.sql.Date(1475062216)); - builder.add("timestamp", new java.sql.Timestamp(1475062216)); - builder.close(); - - final TestEntityDate entity = new VPack.Builder().build().deserialize(builder.slice(), TestEntityDate.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.utilDate, is(new Date(1475062216))); - assertThat(entity.sqlDate, is(new java.sql.Date(1475062216))); - assertThat(entity.timestamp, is(new java.sql.Timestamp(1475062216))); - } - - @Test - public void toDateFromString() throws VPackException { - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("utilDate", DATE_FORMAT.format(new Date(1475062216))); - builder.add("sqlDate", DATE_FORMAT.format(new java.sql.Date(1475062216))); - builder.add("timestamp", DATE_FORMAT.format(new java.sql.Timestamp(1475062216))); - builder.close(); - - final TestEntityDate entity = new VPack.Builder().build().deserialize(builder.slice(), TestEntityDate.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.utilDate, is(new Date(1475062216))); - assertThat(entity.sqlDate, is(new java.sql.Date(1475062216))); - assertThat(entity.timestamp, is(new java.sql.Timestamp(1475062216))); - } - - protected static class TestEntityUUID { - private UUID uuid; - - public UUID getUuid() { - return uuid; - } - - public void setUuid(final UUID uuid) { - this.uuid = uuid; - } - } - - @Test - public void fromUUID() { - final TestEntityUUID entity = new TestEntityUUID(); - entity.setUuid(UUID.randomUUID()); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - - final VPackSlice uuid = vpack.get("uuid"); - assertThat(uuid.isString(), is(true)); - assertThat(uuid.getAsString(), is(entity.uuid.toString())); - } - - @Test - public void toUUID() { - final UUID uuid = UUID.randomUUID(); - final VPackBuilder builder = new VPackBuilder(); - builder.add(ValueType.OBJECT); - builder.add("uuid", uuid.toString()); - builder.close(); - - final TestEntityUUID entity = new VPack.Builder().build().deserialize(builder.slice(), TestEntityUUID.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.uuid, is(uuid)); - } - - @Test - public void uuid() { - final TestEntityUUID entity = new TestEntityUUID(); - entity.setUuid(UUID.randomUUID()); - final VPack vpacker = new VPack.Builder().build(); - final VPackSlice vpack = vpacker.serialize(entity); - final TestEntityUUID entity2 = vpacker.deserialize(vpack, TestEntityUUID.class); - assertThat(entity2, is(notNullValue())); - assertThat(entity2.getUuid(), is(entity.getUuid())); - } - - private static class TransientEntity { - private transient String foo; - - public TransientEntity() { - super(); - } - } - - @Test - public void fromTransient() { - final TransientEntity entity = new TransientEntity(); - entity.foo = "bar"; - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.get("foo").isNone(), is(true)); - } - - @Test - public void toTransient() { - final VPackSlice vpack = new VPackBuilder().add(ValueType.OBJECT).add("foo", "bar").close().slice(); - final TransientEntity entity = new VPack.Builder().build().deserialize(vpack, TransientEntity.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.foo, is(nullValue())); - } - - private static class BinaryEntity { - private byte[] foo; - - public BinaryEntity() { - super(); - } - } - - @Test - public void fromBinary() { - final BinaryEntity entity = new BinaryEntity(); - entity.foo = "bar".getBytes(); - final VPackSlice vpack = new VPack.Builder().build().serialize(entity); - assertThat(vpack, is(notNullValue())); - assertThat(vpack.isObject(), is(true)); - assertThat(vpack.get("foo").isString(), is(true)); - assertThat(vpack.get("foo").getAsString(), is(Base64.getEncoder().encodeToString(entity.foo))); - } - - @Test - public void toBinary() { - final String value = Base64.getEncoder().encodeToString("bar".getBytes()); - final VPackSlice vpack = new VPackBuilder().add(ValueType.OBJECT).add("foo", value).close().slice(); - final BinaryEntity entity = new VPack.Builder().build().deserialize(vpack, BinaryEntity.class); - assertThat(entity, is(notNullValue())); - assertThat(entity.foo, is("bar".getBytes())); - } - - @Test - public void asFloatingNumber() { - final VPackSlice vpack = new VPackBuilder().add(ValueType.OBJECT).add("value", 12000).close().slice(); - assertThat(vpack.get("value").getAsInt(), is(12000)); - assertThat(vpack.get("value").getAsFloat(), is(12000F)); - assertThat(vpack.get("value").getAsDouble(), is(12000.)); - } - - private static class TestEntityObjectKeyMap { - private Map map; - - public TestEntityObjectKeyMap() { - super(); - } - } - - @Test - public void keyMapAdapter() { - final VPack vpack = new VPack.Builder() - .registerKeyMapAdapter(TestEntityA.class, new VPackKeyMapAdapter() { - @Override - public String serialize(final TestEntityA key) { - return key.getA(); - } - - @Override - public TestEntityA deserialize(final String key) { - final TestEntityA e = new TestEntityA(); - e.setA(key); - return e; - } - }).build(); - - final TestEntityObjectKeyMap entityIn = new TestEntityObjectKeyMap(); - entityIn.map = new HashMap<>(); - final TestEntityA key = new TestEntityA(); - key.setA("b"); - entityIn.map.put(key, "test"); - - final VPackSlice slice = vpack.serialize(entityIn); - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("map").isObject(), is(true)); - assertThat(slice.get("map").size(), is(1)); - assertThat(slice.get("map").get("b").getAsString(), is("test")); - - final TestEntityObjectKeyMap entityOut = vpack.deserialize(slice, TestEntityObjectKeyMap.class); - assertThat(entityOut.map.size(), is(1)); - final Entry entry = entityOut.map.entrySet().iterator().next(); - assertThat(entry.getKey().a, is("b")); - assertThat(entry.getValue().toString(), is("test")); - } - - private static class TestEntityNullHandle1 { - private TestEntityNullHandle2 e; - - public TestEntityNullHandle1() { - super(); - } - - } - - private static class TestEntityNullHandle2 { - - public TestEntityNullHandle2() { - super(); - } - - } - - @Test - public void customDeserializerWithSelfNullHandle() { - final VPack vpack = new VPack.Builder() - .registerDeserializer(TestEntityNullHandle2.class, new VPackDeserializer() { - @Override - public TestEntityNullHandle2 deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return new TestEntityNullHandle2(); - } - }, true).serializeNullValues(true).build(); - final TestEntityNullHandle1 entityIn = new TestEntityNullHandle1(); - entityIn.e = null; - final VPackSlice slice = vpack.serialize(entityIn); - final TestEntityNullHandle1 entityOut = vpack.deserialize(slice, TestEntityNullHandle1.class); - assertThat(entityOut.e, is(notNullValue())); - } - - @Test - public void customDeserializerWithoutSelfNullHandle() { - final VPack vpack = new VPack.Builder() - .registerDeserializer(TestEntityNullHandle2.class, new VPackDeserializer() { - @Override - public TestEntityNullHandle2 deserialize( - final VPackSlice parent, - final VPackSlice vpack, - final VPackDeserializationContext context) throws VPackException { - return new TestEntityNullHandle2(); - } - }, false).serializeNullValues(true).build(); - final TestEntityNullHandle1 entityIn = new TestEntityNullHandle1(); - entityIn.e = null; - final VPackSlice slice = vpack.serialize(entityIn); - final TestEntityNullHandle1 entityOut = vpack.deserialize(slice, TestEntityNullHandle1.class); - assertThat(entityOut.e, is(nullValue())); - } - - static class TestEntityTypeInfo { - - } - - static class TestEntityGenericA { - T value; - } - - @Test - public void genericType() { - final TestEntityGenericA entity = new TestEntityGenericA<>(); - entity.value = new TestEntityTypeInfo(); - - final VPack vpack = new VPack.Builder().build(); - final VPackSlice slice = vpack.serialize(entity); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isObject(), is(true)); - assertThat(slice.get("value").get("_class").isString(), is(true)); - assertThat(slice.get("value").get("_class").getAsString(), - is("com.arangodb.velocypack.VPackSerializeDeserializeTest$TestEntityTypeInfo")); - - final TestEntityGenericA entityOut = vpack.deserialize(slice, TestEntityGenericA.class); - assertThat(entityOut, is(notNullValue())); - assertThat(entityOut.value, is(notNullValue())); - } - - static class TestEntityGenericList { - List value; - } - - @Test - public void genericList() { - final TestEntityGenericList entity = new TestEntityGenericList<>(); - entity.value = new ArrayList<>(); - entity.value.add(new TestEntityTypeInfo()); - - final VPack vpack = new VPack.Builder().build(); - final VPackSlice slice = vpack.serialize(entity); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - assertThat(slice.get("value").get(0).isObject(), is(true)); - assertThat(slice.get("value").get(0).get("_class").isString(), is(true)); - assertThat(slice.get("value").get(0).get("_class").getAsString(), - is("com.arangodb.velocypack.VPackSerializeDeserializeTest$TestEntityTypeInfo")); - - final TestEntityGenericList entityOut = vpack.deserialize(slice, - TestEntityGenericList.class); - assertThat(entityOut, is(notNullValue())); - assertThat(entityOut.value, is(notNullValue())); - assertThat(entityOut.value.size(), is(1)); - assertThat(entityOut.value.get(0), is(notNullValue())); - } - - static class TestEntityObjectList { - List value; - } - - @Test - public void objectList() { - final TestEntityObjectList entity = new TestEntityObjectList(); - entity.value = new ArrayList<>(); - entity.value.add(new TestEntityTypeInfo()); - - final VPack vpack = new VPack.Builder().build(); - final VPackSlice slice = vpack.serialize(entity); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - assertThat(slice.get("value").get(0).isObject(), is(true)); - assertThat(slice.get("value").get(0).get("_class").isString(), is(true)); - assertThat(slice.get("value").get(0).get("_class").getAsString(), - is("com.arangodb.velocypack.VPackSerializeDeserializeTest$TestEntityTypeInfo")); - - final TestEntityObjectList entityOut = vpack.deserialize(slice, TestEntityObjectList.class); - assertThat(entityOut, is(notNullValue())); - assertThat(entityOut.value, is(notNullValue())); - assertThat(entityOut.value.size(), is(1)); - assertThat(entityOut.value.get(0) instanceof TestEntityTypeInfo, is(true)); - } - - static class TestEntityObjectArray { - Object[] value; - } - - @Test - public void heterogeneousArray() { - final TestEntityObjectArray entity = new TestEntityObjectArray(); - entity.value = new Object[]{new TestEntityTypeInfo()}; - - final VPack vpack = new VPack.Builder().build(); - final VPackSlice slice = vpack.serialize(entity); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - assertThat(slice.get("value").get(0).isObject(), is(true)); - assertThat(slice.get("value").get(0).get("_class").isString(), is(true)); - assertThat(slice.get("value").get(0).get("_class").getAsString(), - is("com.arangodb.velocypack.VPackSerializeDeserializeTest$TestEntityTypeInfo")); - - final TestEntityObjectArray entityOut = vpack.deserialize(slice, TestEntityObjectArray.class); - assertThat(entityOut, is(notNullValue())); - assertThat(entityOut.value, is(notNullValue())); - assertThat(entityOut.value.length, is(1)); - assertThat(entityOut.value[0] instanceof TestEntityTypeInfo, is(true)); - } - - static class TestEntityTypeInfoArray { - TestEntityTypeInfo[] value; - } - - @Test - public void homogeneousArray() { - final TestEntityTypeInfoArray entity = new TestEntityTypeInfoArray(); - entity.value = new TestEntityTypeInfo[]{new TestEntityTypeInfo()}; - - final VPack vpack = new VPack.Builder().build(); - final VPackSlice slice = vpack.serialize(entity); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - assertThat(slice.get("value").get(0).isObject(), is(true)); - assertThat(slice.get("value").get(0).get("_class").isNone(), is(true)); - - final TestEntityTypeInfoArray entityOut = vpack.deserialize(slice, TestEntityTypeInfoArray.class); - assertThat(entityOut, is(notNullValue())); - assertThat(entityOut.value, is(notNullValue())); - assertThat(entityOut.value.length, is(1)); - assertThat(entityOut.value[0], notNullValue()); - } - - public static class Limb { - } - - public static class Leg extends Limb { - - public String name; - - public Leg() { - } - - public Leg(final String name) { - this.name = name; - } - } - - public static abstract class Animal { - public List arms; - public L rightLeg; - } - - public static class Husky extends Animal { - } - - @Test - public void huskyTestWauWau() { - final VPack vpack = new VPack.Builder().build(); - final Husky tom = new Husky(); - tom.rightLeg = new Leg("right leg"); - tom.arms = new ArrayList<>(Arrays.asList(new Leg("right arm"), new Leg("left arm"))); - - final Husky tomInMirror = vpack.deserialize(vpack.serialize(tom), Husky.class); - assertThat(tomInMirror, is(notNullValue())); - assertThat(tomInMirror.rightLeg, is(notNullValue())); - assertThat(tomInMirror.rightLeg.name, is("right leg")); - assertThat(tomInMirror.arms.size(), is(2)); - } - -} diff --git a/src/test/java/com/arangodb/velocypack/VPackSliceTest.java b/src/test/java/com/arangodb/velocypack/VPackSliceTest.java index 422b31e..3b7fb8f 100644 --- a/src/test/java/com/arangodb/velocypack/VPackSliceTest.java +++ b/src/test/java/com/arangodb/velocypack/VPackSliceTest.java @@ -1522,23 +1522,4 @@ protected void testReadTags(int size) { assertFalse(s.hasTag(50 * size)); } - @Test - public void getSchemaDescription() { - VPackParser parser = new VPackParser.Builder().build(); - VPackSlice slice = parser.fromJson("{\n" + - " \"key1\": [\n" + - " {\n" + - " \"arrKey1\": \"foo\",\n" + - " \"arrKey2\": []\n" + - " }\n" + - " ],\n" + - " \"key2\": \"bla\",\n" + - " \"key3\": 11,\n" + - " \"key4\": {\n" + - " \"subKey1\": null,\n" + - " \"subKey2\": false\n" + - " }\n" + - "}\n", true); - System.out.println(slice.getSchemaDescription()); - } } diff --git a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java deleted file mode 100644 index aa3846a..0000000 --- a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.util.*; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; - -/** - * @author Michele Rastelli - */ -@RunWith(Parameterized.class) -public class VPackWithoutTypeHintTest { - - private final boolean useTypeHints; - - @Parameterized.Parameters - public static Collection useTypeHint() { - return Arrays.asList(true, false); - } - - public VPackWithoutTypeHintTest(final boolean useTypeHints) { - this.useTypeHints = useTypeHints; - } - - public static class NestedArray { - public String[] value; - } - - @Test - public void nestedArrayWithoutTypeInformation() { - NestedArray input = new NestedArray(); - input.value = new String[]{"a", "b", "c"}; - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHints) - assertThat(slice.get("_class").isNone(), is(true)); - - NestedArray output = vpack.deserialize(slice, NestedArray.class); - assertThat(output.value, instanceOf(String[].class)); - - assertThat(output.value, equalTo(input.value)); - } - - public static class NestedIterable { - public Iterable value; - } - - @Test - public void nestedIterableWithoutTypeInformation() { - NestedIterable input = new NestedIterable(); - input.value = Arrays.asList("a", "b", "c"); - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHints) - assertThat(slice.get("_class").isNone(), is(true)); - - NestedIterable output = vpack.deserialize(slice, NestedIterable.class); - assertThat(output.value, instanceOf(List.class)); - - assertThat(output.value, equalTo(input.value)); - } - - public static class NestedCollection { - public Collection value; - } - - @Test - public void nestedCollectionWithoutTypeInformation() { - NestedCollection input = new NestedCollection(); - input.value = Arrays.asList("a", "b", "c"); - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHints) - assertThat(slice.get("_class").isNone(), is(true)); - - NestedCollection output = vpack.deserialize(slice, NestedCollection.class); - assertThat(output.value, instanceOf(List.class)); - - assertThat(output.value, equalTo(input.value)); - } - - public static class NestedMap { - public Map value; - } - - @Test - public void nestedMapWithoutTypeInformation() { - Map map = new HashMap<>(); - map.put("a", "b"); - - NestedMap input = new NestedMap(); - input.value = map; - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isObject(), is(true)); - if (!useTypeHints) { - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); - } - NestedMap output = vpack.deserialize(slice, NestedMap.class); - assertThat(output.value, instanceOf(Map.class)); - - assertThat(output.value, equalTo(input.value)); - } - - public static class NestedObject { - public Object value; - } - - @Test - public void nestedObjectListWithoutTypeInformation() { - NestedObject input = new NestedObject(); - input.value = Arrays.asList("a", "b", "c"); - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHints) - assertThat(slice.get("_class").isNone(), is(true)); - - NestedObject output = vpack.deserialize(slice, NestedObject.class); - assertThat(output.value, instanceOf(List.class)); - - assertThat(output.value, equalTo(input.value)); - } - - @Test - public void nestedObjectArrayWithoutTypeInformation() { - NestedObject input = new NestedObject(); - input.value = new String[]{"a", "b", "c"}; - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHints) - assertThat(slice.get("_class").isNone(), is(true)); - - NestedObject output = vpack.deserialize(slice, NestedObject.class); - assertThat(output.value, instanceOf(List.class)); - - assertThat(((List) output.value).toArray(), equalTo(input.value)); - } - - @Test - public void nestedObjectMapWithoutTypeInformation() { - Map map = new HashMap<>(); - map.put("a", "b"); - - NestedObject input = new NestedObject(); - input.value = map; - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isObject(), is(true)); - if (!useTypeHints) { - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); - } - - NestedObject output = vpack.deserialize(slice, NestedObject.class); - assertThat(output.value, instanceOf(Map.class)); - - ((Map) output.value).remove("_class"); - assertThat(output.value, equalTo(input.value)); - } - - public static class NestedGeneric { - public T value; - } - - @Test - public void nestedGenericOfArrayWithoutTypeInformation() { - NestedGeneric input = new NestedGeneric<>(); - input.value = new String[]{"a", "b", "c"}; - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHints) - assertThat(slice.get("_class").isNone(), is(true)); - - NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); - assertThat(output.value, instanceOf(List.class)); - - assertThat(output.value, equalTo(Arrays.asList(input.value))); - } - - @Test - public void nestedGenericOfIterableWithoutTypeInformation() { - NestedGeneric> input = new NestedGeneric<>(); - input.value = Arrays.asList("a", "b", "c"); - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHints) - assertThat(slice.get("_class").isNone(), is(true)); - - NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); - assertThat(output.value, instanceOf(List.class)); - - assertThat(output.value, equalTo(input.value)); - } - - @Test - public void nestedGenericOfCollectionWithoutTypeInformation() { - NestedGeneric> input = new NestedGeneric<>(); - input.value = Arrays.asList("a", "b", "c"); - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHints) - assertThat(slice.get("_class").isNone(), is(true)); - - NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); - assertThat(output.value, instanceOf(List.class)); - - assertThat(output.value, equalTo(input.value)); - } - - @Test - public void nestedGenericOfMapWithoutTypeInformation() { - Map map = new HashMap<>(); - map.put("a", "b"); - - NestedGeneric> input = new NestedGeneric<>(); - input.value = map; - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isObject(), is(true)); - if (!useTypeHints) { - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); - } - - NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); - assertThat(output.value, instanceOf(Map.class)); - - ((Map) output.value).remove("_class"); - assertThat(output.value, equalTo(input.value)); - } - - @Test - public void nestedGenericOfObjectWithoutTypeInformation() { - Map map = new HashMap<>(); - map.put("a", "b"); - - NestedGeneric input = new NestedGeneric<>(); - input.value = map; - - final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isObject(), is(true)); - if (!useTypeHints) { - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); - } - - NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); - assertThat(output.value, instanceOf(Map.class)); - - ((Map) output.value).remove("_class"); - assertThat(output.value, equalTo(input.value)); - } - -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/AllArgsPerson.java b/src/test/java/com/arangodb/velocypack/immutable/AllArgsPerson.java deleted file mode 100644 index 1e765d2..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/AllArgsPerson.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.SerializedName; -import com.arangodb.velocypack.annotations.VPackCreator; - -import java.util.Objects; - -/** - * @author Michele Rastelli - */ -public class AllArgsPerson { - - private final String name; - private final int age; - private final LombokPerson lombokPerson; - private final PersonBean personBean; - private final PersonWithAnnotatedExternalBuilder personWithAnnotatedExternalBuilder; - @SerializedName("person-with-inner-builder") - private final PersonWithInnerBuilder personWithInnerBuilder; - - @VPackCreator - public AllArgsPerson( - @SerializedName("name") - String name, - @SerializedName("age") - int age, - @SerializedName("lombokPerson") - LombokPerson lombokPerson, - @SerializedName("personBean") - PersonBean personBean, - @SerializedName("personWithAnnotatedExternalBuilder") - PersonWithAnnotatedExternalBuilder personWithAnnotatedExternalBuilder, - @SerializedName("person-with-inner-builder") - PersonWithInnerBuilder personWithInnerBuilder) { - this.name = name; - this.age = age; - this.lombokPerson = lombokPerson; - this.personBean = personBean; - this.personWithAnnotatedExternalBuilder = personWithAnnotatedExternalBuilder; - this.personWithInnerBuilder = personWithInnerBuilder; - } - - public String getName() { - return name; - } - - public int getAge() { - return age; - } - - public LombokPerson getLombokPerson() { - return lombokPerson; - } - - public PersonBean getPersonBean() { - return personBean; - } - - public PersonWithAnnotatedExternalBuilder getPersonWithAnnotatedExternalBuilder() { - return personWithAnnotatedExternalBuilder; - } - - public PersonWithInnerBuilder getPersonWithInnerBuilder() { - return personWithInnerBuilder; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - AllArgsPerson that = (AllArgsPerson) o; - return age == that.age && Objects.equals(name, that.name) && Objects.equals(lombokPerson, that.lombokPerson) - && Objects.equals(personBean, that.personBean) && Objects - .equals(personWithAnnotatedExternalBuilder, that.personWithAnnotatedExternalBuilder) && Objects - .equals(personWithInnerBuilder, that.personWithInnerBuilder); - } - - @Override - public int hashCode() { - return Objects - .hash(name, age, lombokPerson, personBean, personWithAnnotatedExternalBuilder, personWithInnerBuilder); - } - - @Override - public String toString() { - return "FactoryMethodPerson{" + "name='" + name + '\'' + ", age=" + age + ", lombokPerson=" + lombokPerson - + ", personBean=" + personBean + ", personWithAnnotatedExternalBuilder=" - + personWithAnnotatedExternalBuilder + ", personWithInnerBuilder=" + personWithInnerBuilder + '}'; - } -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/AnnotatedExternalBuilder.java b/src/test/java/com/arangodb/velocypack/immutable/AnnotatedExternalBuilder.java deleted file mode 100644 index adf57a5..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/AnnotatedExternalBuilder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; - -@VPackPOJOBuilder(buildMethodName = "buildIt", - withSetterPrefix = "with") -public class AnnotatedExternalBuilder { - private String name; - private int age; - - public AnnotatedExternalBuilder() { - } - - public AnnotatedExternalBuilder withName(String name) { - this.name = name; - return this; - } - - public AnnotatedExternalBuilder withAge(int age) { - this.age = age; - return this; - } - - public PersonWithAnnotatedExternalBuilder buildIt() { - return new PersonWithAnnotatedExternalBuilder(name, age); - } - -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/FactoryMethodPerson.java b/src/test/java/com/arangodb/velocypack/immutable/FactoryMethodPerson.java deleted file mode 100644 index 7628876..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/FactoryMethodPerson.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.SerializedName; -import com.arangodb.velocypack.annotations.VPackCreator; - -import java.util.Objects; - -/** - * @author Michele Rastelli - */ -public class FactoryMethodPerson { - - private final String name; - private final int age; - private final LombokPerson lombokPerson; - private final PersonBean personBean; - private final PersonWithAnnotatedExternalBuilder personWithAnnotatedExternalBuilder; - @SerializedName("person-with-inner-builder") - private final PersonWithInnerBuilder personWithInnerBuilder; - - public FactoryMethodPerson( - String name, - int age, - LombokPerson lombokPerson, - PersonBean personBean, - PersonWithAnnotatedExternalBuilder personWithAnnotatedExternalBuilder, - PersonWithInnerBuilder personWithInnerBuilder) { - this.name = name; - this.age = age; - this.lombokPerson = lombokPerson; - this.personBean = personBean; - this.personWithAnnotatedExternalBuilder = personWithAnnotatedExternalBuilder; - this.personWithInnerBuilder = personWithInnerBuilder; - } - - @VPackCreator - public static FactoryMethodPerson of( - @SerializedName("name") - String name, - @SerializedName("age") - int age, - @SerializedName("lombokPerson") - LombokPerson lombokPerson, - @SerializedName("personBean") - PersonBean personBean, - @SerializedName("personWithAnnotatedExternalBuilder") - PersonWithAnnotatedExternalBuilder personWithAnnotatedExternalBuilder, - @SerializedName("person-with-inner-builder") - PersonWithInnerBuilder personWithInnerBuilder - - ) { - return new FactoryMethodPerson(name, age, lombokPerson, personBean, personWithAnnotatedExternalBuilder, - personWithInnerBuilder); - } - - public String getName() { - return name; - } - - public int getAge() { - return age; - } - - public LombokPerson getLombokPerson() { - return lombokPerson; - } - - public PersonBean getPersonBean() { - return personBean; - } - - public PersonWithAnnotatedExternalBuilder getPersonWithAnnotatedExternalBuilder() { - return personWithAnnotatedExternalBuilder; - } - - public PersonWithInnerBuilder getPersonWithInnerBuilder() { - return personWithInnerBuilder; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - FactoryMethodPerson that = (FactoryMethodPerson) o; - return age == that.age && Objects.equals(name, that.name) && Objects.equals(lombokPerson, that.lombokPerson) - && Objects.equals(personBean, that.personBean) && Objects - .equals(personWithAnnotatedExternalBuilder, that.personWithAnnotatedExternalBuilder) && Objects - .equals(personWithInnerBuilder, that.personWithInnerBuilder); - } - - @Override - public int hashCode() { - return Objects - .hash(name, age, lombokPerson, personBean, personWithAnnotatedExternalBuilder, personWithInnerBuilder); - } - - @Override - public String toString() { - return "FactoryMethodPerson{" + "name='" + name + '\'' + ", age=" + age + ", lombokPerson=" + lombokPerson - + ", personBean=" + personBean + ", personWithAnnotatedExternalBuilder=" - + personWithAnnotatedExternalBuilder + ", personWithInnerBuilder=" + personWithInnerBuilder + '}'; - } -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/ImmutablesTest.java b/src/test/java/com/arangodb/velocypack/immutable/ImmutablesTest.java deleted file mode 100644 index 58c67f3..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/ImmutablesTest.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.VPack; -import com.arangodb.velocypack.VPackSlice; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; - -/** - * Note: all tests are repeated 3 times to check the behavior when hitting the cache {@link com.arangodb.velocypack.internal.VPackCache} - * @author Michele Rastelli - */ -public class ImmutablesTest { - - @Test - public void serdePerson() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - Person original = Person.builderFunction() - .withName("name") - .withAge(99) - .withSecondNames(Arrays.asList("aaa", "bbb", "ccc")) - .withAddresses(Arrays.asList( - Collections.singletonMap("home", "Avocado Street 14"), - Collections.singletonMap("work", "Java Street 14") - )) - .buildIt(); - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - Person deserialized = vpack.deserialize(serialized, Person.class); - System.out.println(deserialized); - assertThat(deserialized, is(original)); - } - } - - @Test - public void serdePersonWithBuilder() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - PersonWithInnerBuilder original = new PersonWithInnerBuilder.Builder().setFullName("name").setAge(99) - .setFriend(new ImmutablePersonWithoutAnnotations.Builder().withName("friend").withAge(88).buildIt()) - .build(); - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - PersonWithInnerBuilder deserialized = vpack.deserialize(serialized, PersonWithInnerBuilder.class); - System.out.println(deserialized); - assertThat(deserialized.getFullName(), is(original.getFullName())); - assertThat(deserialized.getAge(), is(nullValue())); - } - } - - @Test - public void serdePersonWithExternalBuilder() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - PersonWithExternalBuilder original = new ImmutablePersonWithExternalBuilder.Builder().withName("name") - .withAge(99).buildIt(); - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - PersonWithExternalBuilder deserialized = vpack.deserialize(serialized, PersonWithExternalBuilder.class); - System.out.println(deserialized); - assertThat(deserialized, is(original)); - } - } - - @Test - public void personBean() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - PersonBean original = new PersonBean(); - original.setName("name"); - original.setAge(77); - original.setFriend( - new ImmutablePersonWithoutAnnotations.Builder().withName("friend").withAge(66).buildIt()); - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - PersonBean deserialized = vpack.deserialize(serialized, PersonBean.class); - System.out.println(deserialized); - assertThat(deserialized, is(original)); - } - } - - @Test - public void lombokBuilder() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - LombokPerson original = LombokPerson.builder().age(5).name("lombok").build(); - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - LombokPerson deserialized = vpack.deserialize(serialized, LombokPerson.class); - System.out.println(deserialized); - assertThat(deserialized, is(original)); - } - } - - @Test - public void annotatedExternalBuilder() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - PersonWithAnnotatedExternalBuilder original = new AnnotatedExternalBuilder() - .withName("PersonWithAnnotatedExternalBuilder").withAge(2).buildIt(); - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - PersonWithAnnotatedExternalBuilder deserialized = vpack - .deserialize(serialized, PersonWithAnnotatedExternalBuilder.class); - System.out.println(deserialized); - assertThat(deserialized, is(original)); - } - } - - @Test - public void allArgsFactoryMethod() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - PersonBean personBean = new PersonBean(); - personBean.setName("personBean"); - personBean.setAge(9); - personBean.setFriend(new ImmutablePersonWithoutAnnotations.Builder().withName("bla").withAge(0).buildIt()); - FactoryMethodPerson original = FactoryMethodPerson - .of("name", 99, LombokPerson.builder().name("lombok").age(99).build(), personBean, - new AnnotatedExternalBuilder().withName("PersonWithAnnotatedExternalBuilder").withAge(2) - .buildIt(), - new PersonWithInnerBuilder.Builder().setFullName("innerBuilder").build()); - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - FactoryMethodPerson deserialized = vpack.deserialize(serialized, FactoryMethodPerson.class); - System.out.println(deserialized); - assertThat(deserialized, is(original)); - } - } - - @Test - public void allArgsConstructor() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - PersonBean personBean = new PersonBean(); - personBean.setName("personBean"); - personBean.setAge(9); - personBean.setFriend(new ImmutablePersonWithoutAnnotations.Builder().withName("bla").withAge(0).buildIt()); - AllArgsPerson original = new AllArgsPerson("name", 99, - LombokPerson.builder().name("lombok").age(99).build(), personBean, - new AnnotatedExternalBuilder().withName("PersonWithAnnotatedExternalBuilder").withAge(2).buildIt(), - new PersonWithInnerBuilder.Builder().setFullName("innerBuilder").build()); - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - AllArgsPerson deserialized = vpack.deserialize(serialized, AllArgsPerson.class); - System.out.println(deserialized); - assertThat(deserialized, is(original)); - } - } - - @Test - public void covariantCollection() { - VPack vpack = new VPack.Builder().build(); - for (int i = 0; i < 3; i++) { - PersonWithFriends original = PersonWithFriends.builder() - .name("name") - .age(987) - .friends(Collections.singletonList( - Person.builderFunction() - .withName("name") - .withAge(99) - .withSecondNames(Arrays.asList("aaa", "bbb", "ccc")) - .withAddresses(Arrays.asList( - Collections.singletonMap("home", "Avocado Street 14"), - Collections.singletonMap("work", "Java Street 14") - )) - .buildIt() - )) - .build(); - - System.out.println(original); - VPackSlice serialized = vpack.serialize(original); - System.out.println(serialized); - PersonWithFriends deserialized = vpack.deserialize(serialized, PersonWithFriends.class); - System.out.println(deserialized); - assertThat(deserialized, is(original)); - } - } - -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/LombokPerson.java b/src/test/java/com/arangodb/velocypack/immutable/LombokPerson.java deleted file mode 100644 index 7e74ca7..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/LombokPerson.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; -import lombok.Builder; -import lombok.Data; - -/** - * @author Michele Rastelli - */ -@Data -@Builder -public class LombokPerson { - - @VPackPOJOBuilder - public static LombokPersonBuilder builder() { - return new LombokPersonBuilder(); - } - - private String name; - - private int age; -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/Person.java b/src/test/java/com/arangodb/velocypack/immutable/Person.java deleted file mode 100644 index 2abc1bc..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/Person.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; -import org.immutables.value.Value; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * @author Michele Rastelli - */ -@Value.Immutable -@Value.Style(init = "with*", - build = "buildIt") -public abstract class Person { - - @VPackPOJOBuilder(buildMethodName = "buildIt", - withSetterPrefix = "with") - public static ImmutablePerson.Builder builderFunction() { - return ImmutablePerson.builder(); - } - - abstract String getName(); - - abstract int getAge(); - - abstract Set getSecondNames(); - - abstract List> getAddresses(); - -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/PersonBean.java b/src/test/java/com/arangodb/velocypack/immutable/PersonBean.java deleted file mode 100644 index ee2f40e..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/PersonBean.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - - -import com.arangodb.velocypack.annotations.VPackDeserialize; -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; - -import java.util.Objects; - -/** - * @author Michele Rastelli - */ -public class PersonBean { - private String name; - private int age; - @VPackDeserialize(builder = ImmutablePersonWithoutAnnotations.Builder.class, - builderConfig = @VPackPOJOBuilder(buildMethodName = "buildIt", - withSetterPrefix = "with")) - private PersonWithoutAnnotations friend; - - public PersonBean() { - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - - public PersonWithoutAnnotations getFriend() { - return friend; - } - - public void setFriend(PersonWithoutAnnotations friend) { - this.friend = friend; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - PersonBean that = (PersonBean) o; - return age == that.age && Objects.equals(name, that.name) && Objects.equals(friend, that.friend); - } - - @Override - public int hashCode() { - return Objects.hash(name, age, friend); - } - - @Override - public String toString() { - return "PersonBean{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}'; - } -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/PersonWithAnnotatedExternalBuilder.java b/src/test/java/com/arangodb/velocypack/immutable/PersonWithAnnotatedExternalBuilder.java deleted file mode 100644 index e36a1b6..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/PersonWithAnnotatedExternalBuilder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.VPackDeserialize; - -import java.util.Objects; - -/** - * @author Michele Rastelli - */ -@VPackDeserialize(builder = AnnotatedExternalBuilder.class) -public class PersonWithAnnotatedExternalBuilder { - - private final String name; - private final int age; - - public PersonWithAnnotatedExternalBuilder(String name, int age) { - this.name = name; - this.age = age; - } - - public String getName() { - return name; - } - - public int getAge() { - return age; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - PersonWithAnnotatedExternalBuilder that = (PersonWithAnnotatedExternalBuilder) o; - return age == that.age && Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hash(name, age); - } - - @Override - public String toString() { - return "PersonWithAnnotatedExternalBuilder{" + "name='" + name + '\'' + ", age=" + age + '}'; - } -} - diff --git a/src/test/java/com/arangodb/velocypack/immutable/PersonWithExternalBuilder.java b/src/test/java/com/arangodb/velocypack/immutable/PersonWithExternalBuilder.java deleted file mode 100644 index 2c95081..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/PersonWithExternalBuilder.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.VPackDeserialize; -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; -import org.immutables.value.Value; - -/** - * @author Michele Rastelli - */ -@Value.Immutable -@Value.Style(init = "with*", - build = "buildIt", - builder = "new") -@VPackDeserialize(builder = ImmutablePersonWithExternalBuilder.Builder.class, - builderConfig = @VPackPOJOBuilder(buildMethodName = "buildIt", - withSetterPrefix = "with")) -public abstract class PersonWithExternalBuilder { - - abstract String getName(); - - abstract int getAge(); -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/PersonWithFriends.java b/src/test/java/com/arangodb/velocypack/immutable/PersonWithFriends.java deleted file mode 100644 index 451128a..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/PersonWithFriends.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; -import org.immutables.value.Value; - -import java.util.List; - -/** - * @author Michele Rastelli - */ -@Value.Immutable -public abstract class PersonWithFriends { - - @VPackPOJOBuilder - public static ImmutablePersonWithFriends.Builder builder() { - return ImmutablePersonWithFriends.builder(); - } - - abstract String getName(); - - abstract int getAge(); - - abstract List getFriends(); - -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/PersonWithInnerBuilder.java b/src/test/java/com/arangodb/velocypack/immutable/PersonWithInnerBuilder.java deleted file mode 100644 index aca867c..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/PersonWithInnerBuilder.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import com.arangodb.velocypack.annotations.Expose; -import com.arangodb.velocypack.annotations.SerializedName; -import com.arangodb.velocypack.annotations.VPackDeserialize; -import com.arangodb.velocypack.annotations.VPackPOJOBuilder; - -import java.util.Objects; - -/** - * @author Michele Rastelli - */ -public class PersonWithInnerBuilder { - - @SerializedName("name") - private String fullName; - private Integer age; - private PersonWithoutAnnotations friend; - - public PersonWithInnerBuilder( - String fullName, Integer age, PersonWithoutAnnotations friend) { - this.fullName = fullName; - this.age = age; - this.friend = friend; - } - - public String getFullName() { - return fullName; - } - - public Integer getAge() { - return age; - } - - public PersonWithoutAnnotations getFriend() { - return friend; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - PersonWithInnerBuilder that = (PersonWithInnerBuilder) o; - return Objects.equals(fullName, that.fullName) && Objects.equals(age, that.age) && Objects - .equals(friend, that.friend); - } - - @Override - public int hashCode() { - return Objects.hash(fullName, age, friend); - } - - @Override - public String toString() { - return "PersonWithInnerBuilder{" + "fullName='" + fullName + '\'' + ", age=" + age + ", friend=" + friend + '}'; - } - - @VPackPOJOBuilder(withSetterPrefix = "set") - public static final class Builder { - - private String fullName; - private Integer age; - private PersonWithoutAnnotations friend; - - public Builder() { - } - - @SerializedName("name") - public final Builder setFullName(String fullName) { - this.fullName = fullName; - return this; - } - - @Expose(deserialize = false) - public final Builder setAge(Integer age) { - this.age = age; - return this; - } - - @VPackDeserialize(builder = ImmutablePersonWithoutAnnotations.Builder.class, - builderConfig = @VPackPOJOBuilder(buildMethodName = "buildIt", - withSetterPrefix = "with")) - public final Builder setFriend(PersonWithoutAnnotations friend) { - this.friend = friend; - return this; - } - - public PersonWithInnerBuilder build() { - return new PersonWithInnerBuilder(fullName, age, friend); - } - } -} diff --git a/src/test/java/com/arangodb/velocypack/immutable/PersonWithoutAnnotations.java b/src/test/java/com/arangodb/velocypack/immutable/PersonWithoutAnnotations.java deleted file mode 100644 index 3ac02ff..0000000 --- a/src/test/java/com/arangodb/velocypack/immutable/PersonWithoutAnnotations.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package com.arangodb.velocypack.immutable; - -import org.immutables.value.Value; - -/** - * @author Michele Rastelli - */ -@Value.Immutable -@Value.Style(init = "with*", - build = "buildIt", - builder = "new") -public abstract class PersonWithoutAnnotations { - - abstract String getName(); - - abstract int getAge(); -} diff --git a/src/test/resources/api-docs.json b/src/test/resources/api-docs.json deleted file mode 100644 index d23f573..0000000 --- a/src/test/resources/api-docs.json +++ /dev/null @@ -1,7377 +0,0 @@ -{ - "basePath": "/", - "definitions": { - "JSA_get_api_collection_figures_rc_200": { - "properties": { - "count": { - "description": "The number of documents currently present in the collection.
", - "format": "int64", - "type": "integer" - }, - "figures": { - "$ref": "#/definitions/collection_figures" - }, - "journalSize": { - "description": "The maximal size of a journal or datafile in bytes.
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "count", - "journalSize" - ], - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "JSA_put_api_simple_any": { - "properties": { - "collection": { - "description": "The identifier or name of the collection to query.
Returns a JSON object with the document stored in the attribute document if the collection contains at least one document. If the collection is empty, the document attrbute contains null.
", - "type": "string" - } - }, - "required": [ - "collection" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_by_example": { - "properties": { - "collection": { - "description": "The name of the collection to query.
", - "type": "string" - }, - "example": { - "description": "The example document.
", - "type": "string" - }, - "limit": { - "description": "The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
", - "type": "string" - }, - "skip": { - "description": "The number of documents to skip in the query (optional).
", - "type": "string" - } - }, - "required": [ - "collection", - "example", - "skip", - "limit" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_first": { - "properties": { - "collection": { - "description": "the name of the collection
", - "type": "string" - }, - "count": { - "description": "the number of documents to return at most. Specifying count is optional. If it is not specified, it defaults to 1.
", - "type": "string" - } - }, - "required": [ - "collection" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_first_example": { - "properties": { - "collection": { - "description": "The name of the collection to query.
", - "type": "string" - }, - "example": { - "description": "The example document.
", - "type": "string" - } - }, - "required": [ - "collection", - "example" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_fulltext": { - "properties": { - "attribute": { - "description": "The attribute that contains the texts.
", - "type": "string" - }, - "collection": { - "description": "The name of the collection to query.
", - "type": "string" - }, - "index": { - "description": "The identifier of the fulltext-index to use.
", - "type": "string" - }, - "limit": { - "description": "The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
", - "type": "string" - }, - "query": { - "description": "The fulltext query. Please refer to [Fulltext queries](../SimpleQueries/FulltextQueries.html) for details.
", - "type": "string" - }, - "skip": { - "description": "The number of documents to skip in the query (optional).
", - "type": "string" - } - }, - "required": [ - "collection", - "attribute", - "query", - "skip", - "limit", - "index" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_last": { - "properties": { - "collection": { - "description": " the name of the collection
", - "type": "string" - }, - "count": { - "description": "the number of documents to return at most. Specifying count is optional. If it is not specified, it defaults to 1.
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "collection", - "count" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_near": { - "properties": { - "collection": { - "description": "The name of the collection to query.
", - "type": "string" - }, - "distance": { - "description": "If given, the attribute key used to return the distance to the given coordinate. (optional). If specified, distances are returned in meters.
", - "type": "string" - }, - "geo": { - "description": "If given, the identifier of the geo-index to use. (optional)
", - "type": "string" - }, - "latitude": { - "description": "The latitude of the coordinate.
", - "type": "string" - }, - "limit": { - "description": "The maximal amount of documents to return. The skip is applied before the limit restriction. The default is 100. (optional)
", - "type": "string" - }, - "longitude": { - "description": "The longitude of the coordinate.
", - "type": "string" - }, - "skip": { - "description": "The number of documents to skip in the query. (optional)
", - "type": "string" - } - }, - "required": [ - "collection", - "latitude", - "longitude", - "distance", - "skip", - "limit", - "geo" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_range": { - "properties": { - "attribute": { - "description": "The attribute path to check.
", - "type": "string" - }, - "closed": { - "description": "If true, use interval including left and right, otherwise exclude right, but include left.
", - "format": "", - "type": "boolean" - }, - "collection": { - "description": "The name of the collection to query.
", - "type": "string" - }, - "left": { - "description": "The lower bound.
", - "type": "string" - }, - "limit": { - "description": "The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
", - "format": "int64", - "type": "integer" - }, - "right": { - "description": "The upper bound.
", - "type": "string" - }, - "skip": { - "description": "The number of documents to skip in the query (optional).
", - "type": "string" - } - }, - "required": [ - "collection", - "attribute", - "left", - "right", - "closed", - "skip" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_remove_by_example": { - "properties": { - "collection": { - "description": "The name of the collection to remove from.
", - "type": "string" - }, - "example": { - "description": "An example document that all collection documents are compared against.
", - "type": "string" - }, - "options": { - "$ref": "#/definitions/put_api_simple_remove_by_example_opts" - } - }, - "required": [ - "collection", - "example" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_replace_by_example": { - "properties": { - "collection": { - "description": "The name of the collection to replace within.
", - "type": "string" - }, - "example": { - "description": "An example document that all collection documents are compared against.
", - "type": "string" - }, - "newValue": { - "description": "The replacement document that will get inserted in place of the \"old\" documents.
", - "type": "string" - }, - "options": { - "$ref": "#/definitions/put_api_simple_replace_by_example_options" - } - }, - "required": [ - "collection", - "example", - "newValue" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_update_by_example": { - "properties": { - "collection": { - "description": "The name of the collection to update within.
", - "type": "string" - }, - "example": { - "description": "An example document that all collection documents are compared against.
", - "type": "string" - }, - "newValue": { - "additionalProperties": {}, - "description": "A document containing all the attributes to update in the found documents.
", - "type": "object" - }, - "options": { - "$ref": "#/definitions/put_api_simple_update_by_example_options" - } - }, - "required": [ - "collection", - "example", - "newValue" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_within": { - "properties": { - "collection": { - "description": "The name of the collection to query.
", - "type": "string" - }, - "distance": { - "description": "If given, the attribute key used to return the distance to the given coordinate. (optional). If specified, distances are returned in meters.
", - "type": "string" - }, - "geo": { - "description": "If given, the identifier of the geo-index to use. (optional)
", - "type": "string" - }, - "latitude": { - "description": "The latitude of the coordinate.
", - "type": "string" - }, - "limit": { - "description": "The maximal amount of documents to return. The skip is applied before the limit restriction. The default is 100. (optional)
", - "type": "string" - }, - "longitude": { - "description": "The longitude of the coordinate.
", - "type": "string" - }, - "radius": { - "description": "The maximal radius (in meters).
", - "type": "string" - }, - "skip": { - "description": "The number of documents to skip in the query. (optional)
", - "type": "string" - } - }, - "required": [ - "collection", - "latitude", - "longitude", - "radius", - "distance", - "skip", - "limit", - "geo" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSA_put_api_simple_within_rectangle": { - "properties": { - "collection": { - "description": "The name of the collection to query.
", - "type": "string" - }, - "geo": { - "description": "If given, the identifier of the geo-index to use. (optional)
", - "type": "string" - }, - "latitude1": { - "description": "The latitude of the first rectangle coordinate.
", - "type": "string" - }, - "latitude2": { - "description": "The latitude of the second rectangle coordinate.
", - "type": "string" - }, - "limit": { - "description": "The maximal amount of documents to return. The skip is applied before the limit restriction. The default is 100. (optional)
", - "type": "string" - }, - "longitude1": { - "description": "The longitude of the first rectangle coordinate.
", - "type": "string" - }, - "longitude2": { - "description": "The longitude of the second rectangle coordinate.
", - "type": "string" - }, - "skip": { - "description": "The number of documents to skip in the query. (optional)
", - "type": "string" - } - }, - "required": [ - "collection", - "latitude1", - "longitude1", - "latitude2", - "longitude2", - "skip", - "limit", - "geo" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "JSF_HTTP_API_TRAVERSAL": { - "properties": { - "direction": { - "description": "direction for traversal
  • if set, must be either \"outbound\", \"inbound\", or \"any\"
  • if not set, the expander attribute must be specified
", - "type": "string" - }, - "edgeCollection": { - "description": "name of the collection that contains the edges.
", - "type": "string" - }, - "expander": { - "description": "body (JavaScript) code of custom expander function must be set if direction attribute is not set function signature: (config, vertex, path) -> array expander must return an array of the connections for vertex each connection is an object with the attributes edge and vertex
", - "type": "string" - }, - "filter": { - "description": "default is to include all nodes: body (JavaScript code) of custom filter function function signature: (config, vertex, path) -> mixed can return four different string values:
  • \"exclude\" -> this vertex will not be visited.
  • \"prune\" -> the edges of this vertex will not be followed.
  • \"\" or undefined -> visit the vertex and follow it's edges.
  • Array -> containing any combination of the above. If there is at least one \"exclude\" or \"prune\" respectivly is contained, it's effect will occur.
", - "type": "string" - }, - "graphName": { - "description": "name of the graph that contains the edges. Either edgeCollection or graphName has to be given. In case both values are set the graphName is prefered.
", - "type": "string" - }, - "init": { - "description": "body (JavaScript) code of custom result initialization function function signature: (config, result) -> void initialize any values in result with what is required
", - "type": "string" - }, - "itemOrder": { - "description": "item iteration order can be \"forward\" or \"backward\"
", - "type": "string" - }, - "maxDepth": { - "description": "ANDed with any existing filters visits only nodes in at most the given depth
", - "type": "string" - }, - "maxIterations": { - "description": "Maximum number of iterations in each traversal. This number can be set to prevent endless loops in traversal of cyclic graphs. When a traversal performs as many iterations as the maxIterations value, the traversal will abort with an error. If maxIterations is not set, a server-defined value may be used.
", - "type": "string" - }, - "minDepth": { - "description": "ANDed with any existing filters): visits only nodes in at least the given depth
", - "type": "string" - }, - "order": { - "description": "traversal order can be \"preorder\", \"postorder\" or \"preorder-expander\"
", - "type": "string" - }, - "sort": { - "description": "body (JavaScript) code of a custom comparison function for the edges. The signature of this function is (l, r) -> integer (where l and r are edges) and must return -1 if l is smaller than, +1 if l is greater than, and 0 if l and r are equal. The reason for this is the following: The order of edges returned for a certain vertex is undefined. This is because there is no natural order of edges for a vertex with multiple connected edges. To explicitly define the order in which edges on the vertex are followed, you can specify an edge comparator function with this attribute. Note that the value here has to be a string to conform to the JSON standard, which in turn is parsed as function body on the server side. Furthermore note that this attribute is only used for the standard expanders. If you use your custom expander you have to do the sorting yourself within the expander code.
", - "type": "string" - }, - "startVertex": { - "description": "id of the startVertex, e.g. \"users/foo\".
", - "type": "string" - }, - "strategy": { - "description": "traversal strategy can be \"depthfirst\" or \"breadthfirst\"
", - "type": "string" - }, - "uniqueness": { - "description": "specifies uniqueness for vertices and edges visited if set, must be an object like this:
\"uniqueness\": {\"vertices\": \"none\"|\"global\"|\"path\", \"edges\": \"none\"|\"global\"|\"path\"}
", - "type": "string" - }, - "visitor": { - "description": "body (JavaScript) code of custom visitor function function signature: (config, result, vertex, path, connected) -> void The visitor function can do anything, but its return value is ignored. To populate a result, use the result variable by reference. Note that the connected argument is only populated when the order attribute is set to \"preorder-expander\".
", - "type": "string" - } - }, - "required": [ - "startVertex" - ], - "type": "object", - "x-filename": "Graph Traversal - js/actions/api-traversal.js" - }, - "JSF_cluster_dispatcher_POST": { - "properties": { - "action": { - "description": "can be one of the following: - \"launch\": the cluster is launched for the first time, all data directories and log files are cleaned and created - \"shutdown\": the cluster is shut down, the additional property runInfo (see below) must be bound as well - \"relaunch\": the cluster is launched again, all data directories and log files are untouched and need to be there already - \"cleanup\": use this after a shutdown to remove all data in the data directories and all log files, use with caution - \"isHealthy\": checks whether or not the processes involved in the cluster are running or not. The additional property runInfo (see above) must be bound as well - \"upgrade\": performs an upgrade of a cluster, to this end, the agency is started, and then every server is once started with the \"--upgrade\" option, and then normally. Finally, the script \"verion-check.js\" is run on one of the coordinators for the cluster.
", - "type": "string" - }, - "clusterPlan": { - "additionalProperties": {}, - "description": "is a cluster plan (see JSF_cluster_planner_POST),
", - "type": "object" - }, - "myname": { - "description": "is the ID of this dispatcher, this is used to decide which commands are executed locally and which are forwarded to other dispatchers
", - "type": "string" - }, - "runInfo": { - "additionalProperties": {}, - "description": "this is needed for the \"shutdown\" and \"isHealthy\" actions only and should be the structure that \"launch\", \"relaunch\" or \"upgrade\" returned. It contains runtime information like process IDs.
", - "type": "object" - } - }, - "required": [ - "clusterPlan", - "myname", - "action" - ], - "type": "object", - "x-filename": "Cluster - js/actions/api-cluster.js" - }, - "JSF_general_graph_create_http_examples": { - "properties": { - "edgeDefinitions": { - "description": "An array of definitions for the edge
", - "type": "string" - }, - "name": { - "description": "Name of the graph.
", - "type": "string" - }, - "orphanCollections": { - "description": "An array of additional vertex collections.
", - "type": "string" - } - }, - "required": [ - "name" - ], - "type": "object", - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "JSF_general_graph_edge_definition_add_http_examples": { - "properties": { - "collection": { - "description": "The name of the edge collection to be used.
", - "type": "string" - }, - "from": { - "description": "One or many vertex collections that can contain source vertices.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "to": { - "description": "One or many edge collections that can contain target vertices.
", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "collection", - "from", - "to" - ], - "type": "object", - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "JSF_general_graph_edge_definition_modify_http_examples": { - "properties": { - "collection": { - "description": "The name of the edge collection to be used.
", - "type": "string" - }, - "from": { - "description": "One or many vertex collections that can contain source vertices.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "to": { - "description": "One or many edge collections that can contain target vertices.
", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "collection", - "from", - "to" - ], - "type": "object", - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "JSF_get_api_database_new": { - "properties": { - "active": { - "description": "A Flag indicating whether the user account should be activated or not. The default value is true.
", - "format": "", - "type": "boolean" - }, - "extra": { - "additionalProperties": {}, - "description": "A JSON object with extra user information. The data contained in extra will be stored for the user but not be interpreted further by ArangoDB.
", - "type": "object" - }, - "name": { - "description": "Has to contain a valid database name.
", - "type": "string" - }, - "passwd": { - "description": "The user password as a string. If not specified, it will default to an empty string.
", - "type": "string" - }, - "username": { - "description": "The user name as a string. If users is not specified or does not contain any users, a default user root will be created with an empty string password. This ensures that the new database will be accessible after it is created.
", - "type": "string" - }, - "users": { - "description": "Has to be a list of user objects to initially create for the new database. Each user object can contain the following attributes:
", - "items": { - "$ref": "#/definitions/JSF_get_api_database_new_USERS" - }, - "type": "array" - } - }, - "required": [ - "name" - ], - "type": "object", - "x-filename": "Database - js/actions/api-database.js" - }, - "JSF_get_api_database_new_USERS": { - "description": "", - "properties": { - "active": { - "description": "if False the user won't be able to log into the database.
", - "type": "boolean" - }, - "passwd": { - "description": "Password for the user
", - "type": "string" - }, - "username": { - "description": "Loginname of the user to be created
", - "type": "string" - } - }, - "type": "object" - }, - "JSF_get_api_return_rc_200": { - "properties": { - "details": { - "additionalProperties": {}, - "description": "an optional JSON object with additional details. This is returned only if the details URL parameter is set to true in the request.
", - "type": "object" - }, - "server": { - "description": "will always contain arango
", - "type": "string" - }, - "version": { - "description": "the server version string. The string has the format \"major.*minor.*sub\". major and minor will be numeric, and sub may contain a number or a textual version.
", - "type": "string" - } - }, - "required": [ - "server", - "version" - ], - "type": "object", - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - }, - "JSF_post_api_aqlfunction": { - "properties": { - "code": { - "description": "a string representation of the function body.
", - "type": "string" - }, - "isDeterministic": { - "description": "an optional boolean value to indicate that the function results are fully deterministic (function return value solely depends on the input value and return value is the same for repeated calls with same input). The isDeterministic attribute is currently not used but may be used later for optimisations.
", - "format": "", - "type": "boolean" - }, - "name": { - "description": "the fully qualified name of the user functions.
", - "type": "string" - } - }, - "required": [ - "name", - "code" - ], - "type": "object", - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "JSF_post_api_collection": { - "properties": { - "doCompact": { - "description": "whether or not the collection will be compacted (default is true)
", - "format": "", - "type": "boolean" - }, - "indexBuckets": { - "description": "The: number of buckets into which indexes using a hash table are split. The default is 16 and this number has to be a power of 2 and less than or equal to 1024.
For very large collections one should increase this to avoid long pauses when the hash table has to be initially built or resized, since buckets are resized individually and can be initially built in parallel. For example, 64 might be a sensible value for a collection with 100 000 000 documents. Currently, only the edge index respects this value, but other index types might follow in future ArangoDB versions. Changes (see below) are applied when the collection is loaded the next time.
", - "format": "int64", - "type": "integer" - }, - "isSystem": { - "description": "If true, create a system collection. In this case collection-name should start with an underscore. End users should normally create non-system collections only. API implementors may be required to create system collections in very special occasions, but normally a regular collection will do. (The default is false)
", - "format": "", - "type": "boolean" - }, - "isVolatile": { - "description": "If true then the collection data is kept in-memory only and not made persistent. Unloading the collection will cause the collection data to be discarded. Stopping or re-starting the server will also cause full loss of data in the collection. Setting this option will make the resulting collection be slightly faster than regular collections because ArangoDB does not enforce any synchronization to disk and does not calculate any CRC checksums for datafiles (as there are no datafiles). This option should therefore be used for cache-type collections only, and not for data that cannot be re-created otherwise. (The default is false)
", - "format": "", - "type": "boolean" - }, - "journalSize": { - "description": "The maximal size of a journal or datafile in bytes. The value must be at least `1048576` (1 MiB). (The default is a configuration parameter)
", - "format": "int64", - "type": "integer" - }, - "keyOptions": { - "$ref": "#/definitions/JSF_post_api_collection_opts" - }, - "name": { - "description": "The name of the collection.
", - "type": "string" - }, - "numberOfShards": { - "description": "(The default is 1): in a cluster, this value determines the number of shards to create for the collection. In a single server setup, this option is meaningless.
", - "format": "int64", - "type": "integer" - }, - "shardKeys": { - "description": "(The default is [ \"_key\" ]): in a cluster, this attribute determines which document attributes are used to determine the target shard for documents. Documents are sent to shards based on the values of their shard key attributes. The values of all shard key attributes in a document are hashed, and the hash value is used to determine the target shard. Note: Values of shard key attributes cannot be changed once set. This option is meaningless in a single server setup.
", - "type": "string" - }, - "type": { - "description": "(The default is 2): the type of the collection to create. The following values for type are valid:
  • 2: document collection
  • 3: edges collection
", - "format": "int64", - "type": "integer" - }, - "waitForSync": { - "description": "If true then the data is synchronized to disk before returning from a document create, update, replace or removal operation. (default: false)
", - "format": "", - "type": "boolean" - } - }, - "required": [ - "name" - ], - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "JSF_post_api_collection_opts": { - "description": "additional options for key generation. If specified, then keyOptions should be a JSON array containing the following attributes:
", - "properties": { - "allowUserKeys": { - "description": "if set to true, then it is allowed to supply own key values in the _key attribute of a document. If set to false, then the key generator will solely be responsible for generating keys and supplying own key values in the _key attribute of documents is considered an error.
", - "type": "boolean" - }, - "increment": { - "description": "increment value for autoincrement key generator. Not used for other key generator types.
", - "format": "int64", - "type": "integer" - }, - "offset": { - "description": "Initial offset value for autoincrement key generator. Not used for other key generator types.
", - "format": "int64", - "type": "integer" - }, - "type": { - "description": "specifies the type of the key generator. The currently available generators are traditional and autoincrement.
", - "type": "string" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "JSF_post_api_cursor": { - "properties": { - "batchSize": { - "description": "maximum number of result documents to be transferred from the server to the client in one roundtrip. If this attribute is not set, a server-controlled default value will be used. A batchSize value of 0 is disallowed.
", - "format": "int64", - "type": "integer" - }, - "bindVars": { - "description": "list of bind parameter objects.
", - "items": { - "additionalProperties": {}, - "type": "object" - }, - "type": "array" - }, - "cache": { - "description": "flag to determine whether the AQL query cache shall be used. If set to false, then any query cache lookup will be skipped for the query. If set to true, it will lead to the query cache being checked for the query if the query cache mode is either on or demand.
", - "format": "", - "type": "boolean" - }, - "count": { - "description": "indicates whether the number of documents in the result set should be returned in the \"count\" attribute of the result. Calculating the \"count\" attribute might in the future have a performance impact for some queries so this option is turned off by default, and \"count\" is only returned when requested.
", - "format": "", - "type": "boolean" - }, - "options": { - "$ref": "#/definitions/JSF_post_api_cursor_opts" - }, - "query": { - "description": "contains the query string to be executed
", - "type": "string" - }, - "ttl": { - "description": "The time-to-live for the cursor (in seconds). The cursor will be removed on the server automatically after the specified amount of time. This is useful to ensure garbage collection of cursors that are not fully fetched by clients. If not set, a server-defined value will be used.
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "query" - ], - "type": "object", - "x-filename": "Cursors - arangod/RestHandler/RestCursorHandler.cpp" - }, - "JSF_post_api_cursor_opts": { - "description": "key/value object with extra options for the query.
", - "properties": { - "fullCount": { - "description": "if set to true and the query contains a LIMIT clause, then the result will contain an extra attribute extra with a sub-attribute fullCount. This sub-attribute will contain the number of documents in the result before the last LIMIT in the query was applied. It can be used to count the number of documents that match certain filter criteria, but only return a subset of them, in one go. It is thus similar to MySQL's SQL_CALC_FOUND_ROWS hint. Note that setting the option will disable a few LIMIT optimizations and may lead to more documents being processed, and thus make queries run longer. Note that the fullCount sub-attribute will only be present in the result if the query has a LIMIT clause and the LIMIT clause is actually used in the query.
", - "type": "boolean" - }, - "maxPlans": { - "description": "limits the maximum number of plans that are created by the AQL query optimizer.
", - "format": "int64", - "type": "integer" - }, - "optimizer.rules": { - "description": "a list of to-be-included or to-be-excluded optimizer rules can be put into this attribute, telling the optimizer to include or exclude specific rules. To disable a rule, prefix its name with a `-`, to enable a rule, prefix it with a `+`. There is also a pseudo-rule `all`, which will match all optimizer rules.
", - "format": "string", - "items": { - "type": "string" - }, - "type": "array" - }, - "profile": { - "description": "if set to true, then the additional query profiling information will be returned in the extra.stats return attribute if the query result is not served from the query cache.
", - "type": "boolean" - } - }, - "type": "object", - "x-filename": "Cursors - arangod/RestHandler/RestCursorHandler.cpp" - }, - "JSF_post_api_cursor_rc_201": { - "properties": { - "cached": { - "description": "a boolean flag indicating whether the query result was served from the query cache or not. If the query result is served from the query cache, the extra return attribute will not contain any stats sub-attribute and no profile sub-attribute.
", - "format": "", - "type": "boolean" - }, - "code": { - "description": "the HTTP status code
", - "format": "integer", - "type": "integer" - }, - "count": { - "description": "the total number of result documents available (only available if the query was executed with the count attribute set)
", - "format": "int64", - "type": "integer" - }, - "error": { - "description": "A flag to indicate that an error occurred (false in this case)
", - "format": "", - "type": "boolean" - }, - "extra": { - "additionalProperties": {}, - "description": "an optional JSON object with extra information about the query result contained in its stats sub-attribute. For data-modification queries, the extra.stats sub-attribute will contain the number of modified documents and the number of documents that could not be modified due to an error (if ignoreErrors query option is specified)
", - "type": "object" - }, - "hasMore": { - "description": "A boolean indicator whether there are more results available for the cursor on the server
", - "format": "", - "type": "boolean" - }, - "id": { - "description": "id of temporary cursor created on the server (optional, see above)
", - "type": "string" - }, - "result": { - "description": "an array of result documents (might be empty if query has no results)
", - "items": {}, - "type": "array" - } - }, - "required": [ - "error", - "code", - "hasMore", - "id", - "cached" - ], - "type": "object", - "x-filename": "Cursors - arangod/RestHandler/RestCursorHandler.cpp" - }, - "JSF_post_api_cursor_rc_400": { - "properties": { - "code": { - "description": "the HTTP status code
", - "format": "int64", - "type": "integer" - }, - "error": { - "description": "boolean flag to indicate that an error occurred (true in this case)
", - "format": "", - "type": "boolean" - }, - "errorMessage": { - "description": "a descriptive error message
If the query specification is complete, the server will process the query. If an error occurs during query processing, the server will respond with HTTP 400. Again, the body of the response will contain details about the error.
A list of query errors can be found (../ArangoErrors/README.md) here.

", - "type": "string" - }, - "errorNum": { - "description": "the server error number
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "error", - "code", - "errorNum", - "errorMessage" - ], - "type": "object", - "x-filename": "Cursors - arangod/RestHandler/RestCursorHandler.cpp" - }, - "JSF_post_api_explain": { - "properties": { - "bindVars": { - "description": "key/value pairs representing the bind values
", - "items": { - "additionalProperties": {}, - "type": "object" - }, - "type": "array" - }, - "options": { - "$ref": "#/definitions/explain_options" - }, - "query": { - "description": "the query which you want explained; If the query references any bind variables, these must also be passed in the attribute bindVars. Additional options for the query can be passed in the options attribute.
", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object", - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "JSF_post_api_export": { - "properties": { - "batchSize": { - "description": "maximum number of result documents to be transferred from the server to the client in one roundtrip (optional). If this attribute is not set, a server-controlled default value will be used.
", - "format": "int64", - "type": "integer" - }, - "count": { - "description": "boolean flag that indicates whether the number of documents in the result set should be returned in the \"count\" attribute of the result (optional). Calculating the \"count\" attribute might in the future have a performance impact so this option is turned off by default, and \"count\" is only returned when requested.
", - "format": "", - "type": "boolean" - }, - "flush": { - "description": "if set to true, a WAL flush operation will be executed prior to the export. The flush operation will start copying documents from the WAL to the collection's datafiles. There will be an additional wait time of up to flushWait seconds after the flush to allow the WAL collector to change the adjusted document meta-data to point into the datafiles, too. The default value is false (i.e. no flush) so most recently inserted or updated documents from the collection might be missing in the export.
", - "format": "", - "type": "boolean" - }, - "flushWait": { - "description": "maximum wait time in seconds after a flush operation. The default value is 10. This option only has an effect when flush is set to true.
", - "format": "int64", - "type": "integer" - }, - "limit": { - "description": "an optional limit value, determining the maximum number of documents to be included in the cursor. Omitting the limit attribute or setting it to 0 will lead to no limit being used. If a limit is used, it is undefined which documents from the collection will be included in the export and which will be excluded. This is because there is no natural order of documents in a collection.
", - "format": "int64", - "type": "integer" - }, - "restrict": { - "$ref": "#/definitions/JSF_post_api_export_restrictions" - }, - "ttl": { - "description": "an optional time-to-live for the cursor (in seconds). The cursor will be removed on the server automatically after the specified amount of time. This is useful to ensure garbage collection of cursors that are not fully fetched by clients. If not set, a server-defined value will be used.
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "flush", - "flushWait", - "count", - "batchSize", - "limit", - "ttl" - ], - "type": "object", - "x-filename": "Bulk - arangod/RestHandler/RestExportHandler.cpp, arangod/RestHandler/RestImportHandler.cpp, arangod/RestHandler/RestBatchHandler.cpp" - }, - "JSF_post_api_export_restrictions": { - "description": "an object containing an array of attribute names that will be included or excluded when returning result documents.
Not specifying restrict will by default return all attributes of each document.
", - "properties": { - "fields": { - "description": "Contains an array of attribute names to include or exclude. Matching of attribute names for inclusion or exclusion will be done on the top level only. Specifying names of nested attributes is not supported at the moment.

", - "format": "string", - "items": { - "type": "string" - }, - "type": "array" - }, - "type": { - "description": "has to be be set to either include or exclude depending on which you want to use
", - "type": "string" - } - }, - "type": "object", - "x-filename": "Bulk - arangod/RestHandler/RestExportHandler.cpp, arangod/RestHandler/RestImportHandler.cpp, arangod/RestHandler/RestBatchHandler.cpp" - }, - "JSF_post_api_index_cap": { - "properties": { - "byteSize": { - "description": "The maximal size of the active document data in the collection (in bytes). If specified, the value must be at least 16384.

", - "format": "int64", - "type": "integer" - }, - "size": { - "description": "The maximal number of documents for the collection. If specified, the value must be greater than zero.
", - "format": "int64", - "type": "integer" - }, - "type": { - "description": "must be equal to \"cap\".
", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object", - "x-filename": "Indexes - js/actions/api-index.js" - }, - "JSF_post_api_index_fulltext": { - "properties": { - "fields": { - "description": "an array of attribute names. Currently, the array is limited to exactly one attribute.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "minLength": { - "description": "Minimum character length of words to index. Will default to a server-defined value if unspecified. It is thus recommended to set this value explicitly when creating the index.
", - "format": "int64", - "type": "integer" - }, - "type": { - "description": "must be equal to \"fulltext\".
", - "type": "string" - } - }, - "required": [ - "type", - "fields", - "minLength" - ], - "type": "object", - "x-filename": "Indexes - js/actions/api-index.js" - }, - "JSF_post_api_index_geo": { - "properties": { - "fields": { - "description": "An array with one or two attribute paths.
If it is an array with one attribute path location, then a geo-spatial index on all documents is created using location as path to the coordinates. The value of the attribute must be an array with at least two double values. The array must contain the latitude (first value) and the longitude (second value). All documents, which do not have the attribute path or with value that are not suitable, are ignored.
If it is an array with two attribute paths latitude and longitude, then a geo-spatial index on all documents is created using latitude and longitude as paths the latitude and the longitude. The value of the attribute latitude and of the attribute longitude must a double. All documents, which do not have the attribute paths or which values are not suitable, are ignored.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "geoJson": { - "description": "If a geo-spatial index on a location is constructed and geoJson is true, then the order within the array is longitude followed by latitude. This corresponds to the format described in http://geojson.org/geojson-spec.html#positions
", - "type": "string" - }, - "type": { - "description": "must be equal to \"geo\".
", - "type": "string" - } - }, - "required": [ - "type", - "fields", - "geoJson" - ], - "type": "object", - "x-filename": "Indexes - js/actions/api-index.js" - }, - "JSF_post_api_index_hash": { - "properties": { - "fields": { - "description": "an array of attribute paths.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "sparse": { - "description": "if true, then create a sparse index.
", - "format": "", - "type": "boolean" - }, - "type": { - "description": "must be equal to \"hash\".
", - "type": "string" - }, - "unique": { - "description": "if true, then create a unique index.
", - "format": "", - "type": "boolean" - } - }, - "required": [ - "type", - "fields", - "unique", - "sparse" - ], - "type": "object", - "x-filename": "Indexes - js/actions/api-index.js" - }, - "JSF_post_api_index_skiplist": { - "properties": { - "fields": { - "description": "an array of attribute paths.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "sparse": { - "description": "if true, then create a sparse index.
", - "format": "", - "type": "boolean" - }, - "type": { - "description": "must be equal to \"skiplist\".
", - "type": "string" - }, - "unique": { - "description": "if true, then create a unique index.
", - "format": "", - "type": "boolean" - } - }, - "required": [ - "type", - "fields", - "unique", - "sparse" - ], - "type": "object", - "x-filename": "Indexes - js/actions/api-index.js" - }, - "JSF_post_api_new_tasks": { - "properties": { - "command": { - "description": "The JavaScript code to be executed
", - "type": "string" - }, - "name": { - "description": "The name of the task
", - "type": "string" - }, - "offset": { - "description": "Number of seconds initial delay
", - "format": "int64", - "type": "integer" - }, - "params": { - "description": "The parameters to be passed into command
", - "type": "string" - }, - "period": { - "description": "number of seconds between the executions
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "name", - "command", - "params" - ], - "type": "object", - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - }, - "JSF_post_api_transaction": { - "properties": { - "action": { - "description": "the actual transaction operations to be executed, in the form of stringified JavaScript code. The code will be executed on server side, with late binding. It is thus critical that the code specified in action properly sets up all the variables it needs. If the code specified in action ends with a return statement, the value returned will also be returned by the REST API in the result attribute if the transaction committed successfully.
", - "type": "string" - }, - "collections": { - "description": "contains the array of collections to be used in the transaction (mandatory). collections must be a JSON object that can have the optional sub-attributes read and write. read and write must each be either arrays of collections names or strings with a single collection name.
", - "type": "string" - }, - "lockTimeout": { - "description": "an optional numeric value that can be used to set a timeout for waiting on collection locks. If not specified, a default value will be used. Setting lockTimeout to 0 will make ArangoDB not time out waiting for a lock.
", - "format": "int64", - "type": "integer" - }, - "params": { - "description": "optional arguments passed to action.
", - "type": "string" - }, - "waitForSync": { - "description": "an optional boolean flag that, if set, will force the transaction to write all data to disk before returning.
", - "format": "boolean", - "type": "boolean" - } - }, - "required": [ - "collections", - "action" - ], - "type": "object", - "x-filename": "Transactions - js/actions/api-transaction.js" - }, - "JSF_post_batch_replication": { - "properties": { - "ttl": { - "description": "the time-to-live for the new batch (in seconds)
A JSON object with the batch configuration.
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "ttl" - ], - "type": "object", - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - }, - "JSF_put_api_new_tasks": { - "properties": { - "command": { - "description": "The JavaScript code to be executed
", - "type": "string" - }, - "name": { - "description": "The name of the task
", - "type": "string" - }, - "offset": { - "description": "Number of seconds initial delay
", - "format": "int64", - "type": "integer" - }, - "params": { - "description": "The parameters to be passed into command
", - "type": "string" - }, - "period": { - "description": "number of seconds between the executions
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "name", - "command", - "params" - ], - "type": "object", - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - }, - "JSF_put_api_replication_applier_adjust": { - "properties": { - "adaptivePolling": { - "description": "if set to true, the replication applier will fall to sleep for an increasingly long period in case the logger server at the endpoint does not have any more replication events to apply. Using adaptive polling is thus useful to reduce the amount of work for both the applier and the logger server for cases when there are only infrequent changes. The downside is that when using adaptive polling, it might take longer for the replication applier to detect that there are new replication events on the logger server.
Setting adaptivePolling to false will make the replication applier contact the logger server in a constant interval, regardless of whether the logger server provides updates frequently or seldom.
", - "format": "", - "type": "boolean" - }, - "autoStart": { - "description": "whether or not to auto-start the replication applier on (next and following) server starts
", - "format": "", - "type": "boolean" - }, - "chunkSize": { - "description": "the requested maximum size for log transfer packets that is used when the endpoint is contacted.
", - "format": "int64", - "type": "integer" - }, - "connectTimeout": { - "description": "the timeout (in seconds) when attempting to connect to the endpoint. This value is used for each connection attempt.
", - "format": "int64", - "type": "integer" - }, - "database": { - "description": "the name of the database on the endpoint. If not specified, defaults to the current local database name.
", - "type": "string" - }, - "endpoint": { - "description": "the logger server to connect to (e.g. \"tcp://192.168.173.13:8529\"). The endpoint must be specified.
", - "type": "string" - }, - "includeSystem": { - "description": "whether or not system collection operations will be applied
", - "format": "", - "type": "boolean" - }, - "maxConnectRetries": { - "description": "the maximum number of connection attempts the applier will make in a row. If the applier cannot establish a connection to the endpoint in this number of attempts, it will stop itself.
", - "format": "int64", - "type": "integer" - }, - "password": { - "description": "the password to use when connecting to the endpoint.
", - "type": "string" - }, - "requestTimeout": { - "description": "the timeout (in seconds) for individual requests to the endpoint.
", - "format": "int64", - "type": "integer" - }, - "requireFromPresent": { - "description": "if set to true, then the replication applier will check at start whether the start tick from which it starts or resumes replication is still present on the master. If not, then there would be data loss. If requireFromPresent is true, the replication applier will abort with an appropriate error message. If set to false, then the replication applier will still start, and ignore the data loss.
", - "format": "", - "type": "boolean" - }, - "restrictCollections": { - "description": "the array of collections to include or exclude, based on the setting of restrictType
", - "items": { - "type": "string" - }, - "type": "array" - }, - "restrictType": { - "description": "the configuration for restrictCollections; Has to be either include or exclude
", - "type": "string" - }, - "username": { - "description": "an optional ArangoDB username to use when connecting to the endpoint.
", - "type": "string" - }, - "verbose": { - "description": "if set to true, then a log line will be emitted for all operations performed by the replication applier. This should be used for debugging replication problems only.
", - "format": "", - "type": "boolean" - } - }, - "required": [ - "endpoint", - "database", - "password", - "maxConnectRetries", - "connectTimeout", - "requestTimeout", - "chunkSize", - "autoStart", - "adaptivePolling", - "includeSystem", - "requireFromPresent", - "verbose", - "restrictType" - ], - "type": "object", - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - }, - "JSF_put_api_replication_makeSlave": { - "properties": { - "adaptivePolling": { - "description": "whether or not the replication applier will use adaptive polling.
", - "format": "", - "type": "boolean" - }, - "chunkSize": { - "description": "the requested maximum size for log transfer packets that is used when the endpoint is contacted.
", - "format": "int64", - "type": "integer" - }, - "connectTimeout": { - "description": "the timeout (in seconds) when attempting to connect to the endpoint. This value is used for each connection attempt.
", - "format": "int64", - "type": "integer" - }, - "database": { - "description": "the database name on the master (if not specified, defaults to the name of the local current database).
", - "type": "string" - }, - "endpoint": { - "description": "the master endpoint to connect to (e.g. \"tcp://192.168.173.13:8529\").
", - "type": "string" - }, - "includeSystem": { - "description": "whether or not system collection operations will be applied
", - "format": "", - "type": "boolean" - }, - "maxConnectRetries": { - "description": "the maximum number of connection attempts the applier will make in a row. If the applier cannot establish a connection to the endpoint in this number of attempts, it will stop itself.
", - "format": "int64", - "type": "integer" - }, - "password": { - "description": "the password to use when connecting to the master.
", - "type": "string" - }, - "requestTimeout": { - "description": "the timeout (in seconds) for individual requests to the endpoint.
", - "format": "int64", - "type": "integer" - }, - "requireFromPresent": { - "description": "if set to true, then the replication applier will check at start of its continuous replication if the start tick from the dump phase is still present on the master. If not, then there would be data loss. If requireFromPresent is true, the replication applier will abort with an appropriate error message. If set to false, then the replication applier will still start, and ignore the data loss.
", - "format": "", - "type": "boolean" - }, - "restrictCollections": { - "description": "an optional array of collections for use with restrictType. If restrictType is include, only the specified collections will be sychronised. If restrictType is exclude, all but the specified collections will be synchronized.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "restrictType": { - "description": "an optional string value for collection filtering. When specified, the allowed values are include or exclude.
", - "type": "string" - }, - "username": { - "description": "an optional ArangoDB username to use when connecting to the master.
", - "type": "string" - }, - "verbose": { - "description": "if set to true, then a log line will be emitted for all operations performed by the replication applier. This should be used for debugging replication problems only.
", - "format": "", - "type": "boolean" - } - }, - "required": [ - "endpoint", - "database", - "password", - "includeSystem", - "maxConnectRetries", - "connectTimeout", - "requestTimeout", - "chunkSize", - "adaptivePolling", - "requireFromPresent" - ], - "type": "object", - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - }, - "JSF_put_api_replication_synchronize": { - "properties": { - "database": { - "description": "the database name on the master (if not specified, defaults to the name of the local current database).
", - "type": "string" - }, - "endpoint": { - "description": "the master endpoint to connect to (e.g. \"tcp://192.168.173.13:8529\").
", - "type": "string" - }, - "includeSystem": { - "description": "whether or not system collection operations will be applied
", - "format": "", - "type": "boolean" - }, - "incremental": { - "description": "if set to true, then an incremental synchronization method will be used for synchronizing data in collections. This method is useful when collections already exist locally, and only the remaining differences need to be transferred from the remote endpoint. In this case, the incremental synchronization can be faster than a full synchronization. The default value is false, meaning that the complete data from the remote collection will be transferred.
", - "format": "", - "type": "boolean" - }, - "password": { - "description": "the password to use when connecting to the endpoint.
", - "type": "string" - }, - "restrictCollections": { - "description": "an optional array of collections for use with restrictType. If restrictType is include, only the specified collections will be sychronised. If restrictType is exclude, all but the specified collections will be synchronized.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "restrictType": { - "description": "an optional string value for collection filtering. When specified, the allowed values are include or exclude.
", - "type": "string" - }, - "username": { - "description": "an optional ArangoDB username to use when connecting to the endpoint.
", - "type": "string" - } - }, - "required": [ - "endpoint", - "password" - ], - "type": "object", - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - }, - "JSF_put_batch_replication": { - "properties": { - "ttl": { - "description": "the time-to-live for the new batch (in seconds)
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "ttl" - ], - "type": "object", - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - }, - "PostApiQueryProperties": { - "properties": { - "query": { - "description": "To validate a query string without executing it, the query string can be passed to the server via an HTTP POST request.
", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object", - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "PutApiQueryCacheProperties": { - "properties": { - "maxResults": { - "description": "the maximum number of query results that will be stored per database-specific cache.

", - "format": "int64", - "type": "integer" - }, - "mode": { - "description": " the mode the AQL query cache should operate in. Possible values are off, on or demand.
", - "type": "string" - } - }, - "required": [ - "mode", - "maxResults" - ], - "type": "object", - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "PutApiQueryProperties": { - "properties": { - "enabled": { - "description": "If set to true, then queries will be tracked. If set to false, neither queries nor slow queries will be tracked.
", - "format": "", - "type": "boolean" - }, - "maxQueryStringLength": { - "description": "The maximum query string length to keep in the list of queries. Query strings can have arbitrary lengths, and this property can be used to save memory in case very long query strings are used. The value is specified in bytes.
", - "format": "int64", - "type": "integer" - }, - "maxSlowQueries": { - "description": "The maximum number of slow queries to keep in the list of slow queries. If the list of slow queries is full, the oldest entry in it will be discarded when additional slow queries occur.
", - "format": "int64", - "type": "integer" - }, - "slowQueryThreshold": { - "description": "The threshold value for treating a query as slow. A query with a runtime greater or equal to this threshold value will be put into the list of slow queries when slow query tracking is enabled. The value for slowQueryThreshold is specified in seconds.
", - "format": "int64", - "type": "integer" - }, - "trackSlowQueries": { - "description": "If set to true, then slow queries will be tracked in the list of slow queries if their runtime exceeds the value set in slowQueryThreshold. In order for slow queries to be tracked, the enabled property must also be set to true.
", - "format": "", - "type": "boolean" - } - }, - "required": [ - "enabled", - "trackSlowQueries", - "maxSlowQueries", - "slowQueryThreshold", - "maxQueryStringLength" - ], - "type": "object", - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "RestLookupByKeys": { - "properties": { - "collection": { - "description": "The name of the collection to look in for the documents
", - "type": "string" - }, - "keys": { - "description": "array with the _keys of documents to remove.
", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "collection", - "keys" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "RestRemoveByKeys": { - "properties": { - "collection": { - "description": "The name of the collection to look in for the documents to remove
", - "type": "string" - }, - "keys": { - "description": "array with the _keys of documents to remove.
", - "items": { - "type": "string" - }, - "type": "array" - }, - "options": { - "$ref": "#/definitions/put_api_simple_remove_by_keys_opts" - } - }, - "required": [ - "collection", - "keys" - ], - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "collection_figures": { - "description": "metrics of the collection
", - "properties": { - "alive": { - "$ref": "#/definitions/collection_figures_alive" - }, - "attributes": { - "$ref": "#/definitions/collection_figures_attributes" - }, - "compactors": { - "$ref": "#/definitions/collection_figures_compactors" - }, - "datafiles": { - "$ref": "#/definitions/collection_figures_datafiles" - }, - "dead": { - "$ref": "#/definitions/collection_figures_dead" - }, - "indexes": { - "$ref": "#/definitions/collection_figures_indexes" - }, - "journals": { - "$ref": "#/definitions/collection_figures_journals" - }, - "maxTick": { - "description": "The tick of the last marker that was stored in a journal of the collection. This might be 0 if the collection does not yet have a journal.
", - "format": "int64", - "type": "integer" - }, - "shapefiles": { - "$ref": "#/definitions/collection_figures_shapefiles" - }, - "shapes": { - "$ref": "#/definitions/collection_figures_shapes" - }, - "uncollectedLogfileEntries": { - "description": "The number of markers in the write-ahead log for this collection that have not been transferred to journals or datafiles.
", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "figures", - "alive", - "dead", - "datafiles", - "journals", - "compactors", - "shapefiles", - "shapes", - "attributes", - "indexes" - ], - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_alive": { - "description": "the currently active figures
", - "properties": { - "count": { - "description": "The number of currently active documents in all datafiles and journals of the collection. Documents that are contained in the write-ahead log only are not reported in this figure.
", - "format": "int64", - "type": "integer" - }, - "size": { - "description": "The total size in bytes used by all active documents of the collection. Documents that are contained in the write-ahead log only are not reported in this figure.
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_attributes": { - "description": "", - "properties": { - "count": { - "description": "The total number of attributes used in the collection. Note: the value includes data of attributes that are not in use anymore. Attributes that are contained in the write-ahead log only are not reported in this figure.
", - "format": "int64", - "type": "integer" - }, - "size": { - "description": "The total size of the attribute data (in bytes). Note: the value includes data of attributes that are not in use anymore. Attributes that are contained in the write-ahead log only are not reported in this figure.
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_compactors": { - "description": "
", - "properties": { - "count": { - "description": "The number of compactor files.
", - "format": "int64", - "type": "integer" - }, - "fileSize": { - "description": "The total filesize of all compactor files (in bytes).
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_datafiles": { - "description": "Metrics regarding the datafiles
", - "properties": { - "count": { - "description": "The number of datafiles.
", - "format": "int64", - "type": "integer" - }, - "fileSize": { - "description": "The total filesize of datafiles (in bytes).
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_dead": { - "description": "the items waiting to be swept away by the cleaner
", - "properties": { - "count": { - "description": "The number of dead documents. This includes document versions that have been deleted or replaced by a newer version. Documents deleted or replaced that are contained the write-ahead log only are not reported in this figure.
", - "format": "int64", - "type": "integer" - }, - "deletion": { - "description": "The total number of deletion markers. Deletion markers only contained in the write-ahead log are not reporting in this figure.
", - "format": "int64", - "type": "integer" - }, - "size": { - "description": "The total size in bytes used by all dead documents.
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_indexes": { - "description": "", - "properties": { - "count": { - "description": "The total number of indexes defined for the collection, including the pre-defined indexes (e.g. primary index).
", - "format": "int64", - "type": "integer" - }, - "size": { - "description": "The total memory allocated for indexes in bytes.
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_journals": { - "description": "Metrics regarding the journal files
", - "properties": { - "count": { - "description": "The number of journal files.
", - "format": "int64", - "type": "integer" - }, - "fileSize": { - "description": "The total filesize of all journal files (in bytes).
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_shapefiles": { - "description": "deprecated
", - "properties": { - "count": { - "description": "The number of shape files. This value is deprecated and kept for compatibility reasons only. The value will always be 0 since ArangoDB 2.0 and higher.
", - "format": "int64", - "type": "integer" - }, - "fileSize": { - "description": "The total filesize of the shape files. This value is deprecated and kept for compatibility reasons only. The value will always be 0 in ArangoDB 2.0 and higher.
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "collection_figures_shapes": { - "description": "", - "properties": { - "count": { - "description": "The total number of shapes used in the collection. This includes shapes that are not in use anymore. Shapes that are contained in the write-ahead log only are not reported in this figure.
", - "format": "int64", - "type": "integer" - }, - "size": { - "description": "The total size of all shapes (in bytes). This includes shapes that are not in use anymore. Shapes that are contained in the write-ahead log only are not reported in this figure.
", - "format": "int64", - "type": "integer" - } - }, - "type": "object", - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "explain_options": { - "description": "Options for the query
", - "properties": { - "allPlans": { - "description": "if set to true, all possible execution plans will be returned. The default is false, meaning only the optimal plan will be returned.
", - "type": "boolean" - }, - "maxNumberOfPlans": { - "description": "an optional maximum number of plans that the optimizer is allowed to generate. Setting this attribute to a low value allows to put a cap on the amount of work the optimizer does.
", - "format": "int64", - "type": "integer" - }, - "optimizer.rules": { - "description": "an array of to-be-included or to-be-excluded optimizer rules can be put into this attribute, telling the optimizer to include or exclude specific rules. To disable a rule, prefix its name with a `-`, to enable a rule, prefix it with a `+`. There is also a pseudo-rule `all`, which will match all optimizer rules.
", - "format": "string", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object", - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "put_api_simple_remove_by_example_opts": { - "description": "a json object which can contains following attributes:
", - "properties": { - "limit": { - "description": "an optional value that determines how many documents to delete at most. If limit is specified but is less than the number of documents in the collection, it is undefined which of the documents will be deleted.
", - "type": "string" - }, - "waitForSync": { - "description": "if set to true, then all removal operations will instantly be synchronized to disk. If this is not specified, then the collection's default sync behavior will be applied.
", - "type": "string" - } - }, - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "put_api_simple_remove_by_keys_opts": { - "description": "a json object which can contains following attributes:
", - "properties": { - "waitForSync": { - "description": "if set to true, then all removal operations will instantly be synchronized to disk. If this is not specified, then the collection's default sync behavior will be applied.
", - "type": "string" - } - }, - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "put_api_simple_replace_by_example_options": { - "description": "a json object which can contain following attributes
", - "properties": { - "limit": { - "description": "an optional value that determines how many documents to replace at most. If limit is specified but is less than the number of documents in the collection, it is undefined which of the documents will be replaced.

", - "type": "string" - }, - "waitForSync": { - "description": "if set to true, then all removal operations will instantly be synchronized to disk. If this is not specified, then the collection's default sync behavior will be applied.
", - "type": "boolean" - } - }, - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - }, - "put_api_simple_update_by_example_options": { - "description": "a json object which can contains following attributes:
", - "properties": { - "keepNull": { - "description": "This parameter can be used to modify the behavior when handling null values. Normally, null values are stored in the database. By setting the keepNull parameter to false, this behavior can be changed so that all attributes in data with null values will be removed from the updated document.
", - "type": "string" - }, - "limit": { - "description": "an optional value that determines how many documents to update at most. If limit is specified but is less than the number of documents in the collection, it is undefined which of the documents will be updated.
", - "format": "int64", - "type": "integer" - }, - "waitForSync": { - "description": "if set to true, then all removal operations will instantly be synchronized to disk. If this is not specified, then the collection's default sync behavior will be applied.
", - "type": "boolean" - } - }, - "type": "object", - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "info": { - "description": "ArangoDB REST API Interface", - "license": { - "name": "Apache License, Version 2.0" - }, - "title": "ArangoDB", - "version": "1.0" - }, - "paths": { - "/_admin/cluster-test": { - "delete": { - "description": "\n\nSee GET method.
", - "parameters": [], - "summary": " Delete cluster roundtrip", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - }, - "get": { - "description": "\n\n
Executes a cluster roundtrip from a coordinator to a DB server and back. This call only works in a coordinator node in a cluster. One can and should append an arbitrary path to the URL and the part after /_admin/cluster-test is used as the path of the HTTP request which is sent from the coordinator to a DB node. Likewise, any form data appended to the URL is forwarded in the request to the DB node. This handler takes care of all request types (see below) and uses the same request type in its request to the DB node.
The following HTTP headers are interpreted in a special way:
- X-Shard-ID: This specifies the ID of the shard to which the cluster request is sent and thus tells the system to which DB server to send the cluster request. Note that the mapping from the shard ID to the responsible server has to be defined in the agency under Current/ShardLocation/. One has to give this header, otherwise the system does not know where to send the request. - X-Client-Transaction-ID: the value of this header is taken as the client transaction ID for the request - X-Timeout: specifies a timeout in seconds for the cluster operation. If the answer does not arrive within the specified timeout, an corresponding error is returned and any subsequent real answer is ignored. The default if not given is 24 hours. - X-Synchronous-Mode: If set to true the test function uses synchronous mode, otherwise the default asynchronous operation mode is used. This is mainly for debugging purposes. - Host: This header is ignored and not forwarded to the DB server. - User-Agent: This header is ignored and not forwarded to the DB server.
All other HTTP headers and the body of the request (if present, see other HTTP methods below) are forwarded as given in the original request.
In asynchronous mode the DB server answers with an HTTP request of its own, in synchronous mode it sends a HTTP response. In both cases the headers and the body are used to produce the HTTP response of this API call.
", - "parameters": [], - "responses": { - "200": { - "description": "is returned when everything went well, or if a timeout occurred. In the latter case a body of type application/json indicating the timeout is returned.
" - }, - "403": { - "description": "is returned if ArangoDB is not running in cluster mode.
" - }, - "404": { - "description": "is returned if ArangoDB was not compiled for cluster operation.
" - } - }, - "summary": " Execute cluster roundtrip", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - }, - "head": { - "description": "\n\nSee GET method.
", - "parameters": [], - "summary": " Execute cluster roundtrip", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - }, - "patch": { - "description": "free style json body\n\nSee GET method. The body can be any type and is simply forwarded.
", - "parameters": [ - { - "description": "
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "summary": " Update cluster roundtrip", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - }, - "post": { - "description": "free style json body\n\nSee GET method.
", - "parameters": [ - { - "description": "The body can be any type and is simply forwarded.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "summary": " Execute cluster roundtrip", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - }, - "put": { - "description": "free style json body\n\nSee GET method. The body can be any type and is simply forwarded.
", - "parameters": [ - { - "description": "
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "summary": " Execute cluster roundtrip", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - } - }, - "/_admin/clusterCheckPort": { - "get": { - "description": "\n\n
", - "parameters": [ - { - "description": "
", - "in": "query", - "name": "port", - "required": true, - "type": "integer" - } - ], - "responses": { - "200": { - "description": "
" - }, - "400": { - "description": "
" - } - }, - "summary": " Check port", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - } - }, - "/_admin/clusterDispatch": { - "post": { - "description": "**A json post document with these Properties is required:**
  • clusterPlan: is a cluster plan (see JSF_cluster_planner_POST),
  • action: can be one of the following: - \"launch\": the cluster is launched for the first time, all data directories and log files are cleaned and created - \"shutdown\": the cluster is shut down, the additional property runInfo (see below) must be bound as well - \"relaunch\": the cluster is launched again, all data directories and log files are untouched and need to be there already - \"cleanup\": use this after a shutdown to remove all data in the data directories and all log files, use with caution - \"isHealthy\": checks whether or not the processes involved in the cluster are running or not. The additional property runInfo (see above) must be bound as well - \"upgrade\": performs an upgrade of a cluster, to this end, the agency is started, and then every server is once started with the \"--upgrade\" option, and then normally. Finally, the script \"verion-check.js\" is run on one of the coordinators for the cluster.
  • runInfo: this is needed for the \"shutdown\" and \"isHealthy\" actions only and should be the structure that \"launch\", \"relaunch\" or \"upgrade\" returned. It contains runtime information like process IDs.
  • myname: is the ID of this dispatcher, this is used to decide which commands are executed locally and which are forwarded to other dispatchers
\n\nThe body must be an object with the following properties:
This call executes the plan by either doing the work personally or by delegating to other dispatchers.
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_cluster_dispatcher_POST" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "
" - }, - "400": { - "description": "went wrong with the startup.
" - } - }, - "summary": "execute startup commands", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - } - }, - "/_admin/clusterPlanner": { - "post": { - "description": "free style json body\n\nof a cluster and returns a JSON description of a plan to start up this cluster.
", - "parameters": [ - { - "description": "A cluster plan object
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "responses": { - "200": { - "description": "
" - }, - "400": { - "description": "
" - } - }, - "summary": " Produce cluster startup plan", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - } - }, - "/_admin/clusterStatistics": { - "get": { - "description": "\n\n
", - "parameters": [ - { - "description": "
", - "in": "query", - "name": "DBserver", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "
" - }, - "400": { - "description": "ID of a DBserver
" - }, - "403": { - "description": "
" - } - }, - "summary": " Queries statistics of DBserver", - "tags": [ - "Cluster" - ], - "x-examples": [], - "x-filename": "Cluster - js/actions/api-cluster.js" - } - }, - "/_admin/database/target-version": { - "get": { - "description": "\n\n
Returns the database-version that this server requires. The version is returned in the version attribute of the result.
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned in all cases.
" - } - }, - "summary": " Return the required version of the database", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/echo": { - "get": { - "description": "\n\n
The call returns an object with the following attributes:
  • headers: object with HTTP headers received
  • requestType: the HTTP request method (e.g. GET)
  • parameters: object with URL parameters received
", - "parameters": [], - "responses": { - "200": { - "description": "Echo was returned successfully.
" - } - }, - "summary": " Return current request", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/execute": { - "post": { - "description": "free style json body\n\n
Executes the javascript code in the body on the server as the body of a function with no arguments. If you have a return statement then the return value you produce will be returned as content type application/json. If the parameter returnAsJSON is set to true, the result will be a JSON object describing the return value directly, otherwise a string produced by JSON.stringify will be returned.
", - "parameters": [ - { - "description": "The body to be executed.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "summary": " Execute program", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/log": { - "get": { - "description": "\n\nReturns fatal, error, warning or info log messages from the server's global log. The result is a JSON object with the following attributes:
  • lid: a list of log entry identifiers. Each log message is uniquely identified by its lid and the identifiers are in ascending order.
  • level: a list of the log-levels for all log entries.
  • timestamp: a list of the timestamps as seconds since 1970-01-01 for all log entries.
  • text a list of the texts of all log entries
  • totalAmount: the total amount of log entries before pagination.
", - "parameters": [ - { - "description": "Returns all log entries up to log level upto. Note that upto must be:
  • fatal or 0
  • error or 1
  • warning or 2
  • info or 3
  • debug or 4 The default value is info.
", - "in": "query", - "name": "upto", - "required": false, - "type": "string" - }, - { - "description": "Returns all log entries of log level level. Note that the URL parameters upto and level are mutually exclusive.
", - "in": "query", - "name": "level", - "required": false, - "type": "string" - }, - { - "description": "Returns all log entries such that their log entry identifier (lid value) is greater or equal to start.
", - "in": "query", - "name": "start", - "required": false, - "type": "number" - }, - { - "description": "Restricts the result to at most size log entries.
", - "in": "query", - "name": "size", - "required": false, - "type": "number" - }, - { - "description": "Starts to return log entries skipping the first offset log entries. offset and size can be used for pagination.
", - "in": "query", - "name": "offset", - "required": false, - "type": "number" - }, - { - "description": "Only return the log entries containing the text specified in search.
", - "in": "query", - "name": "search", - "required": false, - "type": "string" - }, - { - "description": "Sort the log entries either ascending (if sort is asc) or descending (if sort is desc) according to their lid values. Note that the lid imposes a chronological order. The default value is asc.
", - "in": "query", - "name": "sort", - "required": false, - "type": "string" - } - ], - "responses": { - "400": { - "description": "is returned if invalid values are specified for upto or level.
" - }, - "403": { - "description": "is returned if the log is requested for any database other than _system.
" - }, - "500": { - "description": "is returned if the server cannot generate the result due to an out-of-memory error.
" - } - }, - "summary": " Read global log from the server", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/long_echo": { - "get": { - "description": "\n\n
The call returns an object with the following attributes:
  • headers: object with HTTP headers received
  • requestType: the HTTP request method (e.g. GET)
  • parameters: object with URL parameters received
", - "parameters": [], - "responses": { - "200": { - "description": "Echo was returned successfully.
" - } - }, - "summary": " Return current request and continues", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/routing/reload": { - "post": { - "description": "\n\n
Reloads the routing information from the collection routing.
", - "parameters": [], - "responses": { - "200": { - "description": "Routing information was reloaded successfully.
" - } - }, - "summary": " Reloads the routing information", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/server/role": { - "get": { - "description": "\n\n
Returns the role of a server in a cluster. The role is returned in the role attribute of the result. Possible return values for role are:
  • COORDINATOR: the server is a coordinator in a cluster
  • PRIMARY: the server is a primary database server in a cluster
  • SECONDARY: the server is a secondary database server in a cluster
  • UNDEFINED: in a cluster, UNDEFINED is returned if the server role cannot be determined. On a single server, UNDEFINED is the only possible return value.
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned in all cases.
" - } - }, - "summary": " Return role of a server in a cluster", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/shutdown": { - "get": { - "description": "\n\nThis call initiates a clean shutdown sequence.
", - "parameters": [], - "responses": { - "200": { - "description": "is returned in all cases.
" - } - }, - "summary": " Initiate shutdown sequence", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/sleep": { - "get": { - "description": "\n\n
The call returns an object with the attribute duration. This takes as many seconds as the duration argument says.
", - "parameters": [ - { - "description": "wait `duration` seconds until the reply is sent.
", - "format": "integer", - "in": "path", - "name": "duration", - "required": true, - "type": "integer" - } - ], - "responses": { - "200": { - "description": "Sleep was conducted successfully.
" - } - }, - "summary": " Sleep for a specified amount of seconds", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/statistics": { - "get": { - "description": "\n\n
Returns the statistics information. The returned object contains the statistics figures grouped together according to the description returned by _admin/statistics-description. For instance, to access a figure userTime from the group system, you first select the sub-object describing the group stored in system and in that sub-object the value for userTime is stored in the attribute of the same name.
In case of a distribution, the returned object contains the total count in count and the distribution list in counts. The sum (or total) of the individual values is returned in sum.

Example:

shell> curl --dump - http://localhost:8529/_admin/statistics\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"time\" : 1443627584.140516, \n  \"system\" : { \n    \"minorPageFaults\" : 137584, \n    \"majorPageFaults\" : 5, \n    \"userTime\" : 36.03, \n    \"systemTime\" : 1.34, \n    \"numberOfThreads\" : 23, \n    \"residentSize\" : 192217088, \n    \"residentSizePercent\" : 0.022905696552235805, \n    \"virtualSize\" : 3688673280 \n  }, \n  \"client\" : { \n    \"httpConnections\" : 1, \n    \"connectionTime\" : { \n      \"sum\" : 0.00033211708068847656, \n      \"count\" : 1, \n      \"counts\" : [ \n        1, \n        0, \n        0, \n        0 \n      ] \n    }, \n    \"totalTime\" : { \n      \"sum\" : 26.437366724014282, \n      \"count\" : 3555, \n      \"counts\" : [ \n        3204, \n        267, \n        60, \n        16, \n        3, \n        1, \n        4 \n      ] \n    }, \n    \"requestTime\" : { \n      \"sum\" : 14.136068344116211, \n      \"count\" : 3555, \n      \"counts\" : [ \n        3297, \n        219, \n        26, \n        8, \n        3, \n        2, \n        0 \n      ] \n    }, \n    \"queueTime\" : { \n      \"sum\" : 0.09597921371459961, \n      \"count\" : 3526, \n      \"counts\" : [ \n        3526, \n        0, \n        0, \n        0, \n        0, \n        0, \n        0 \n      ] \n    }, \n    \"ioTime\" : { \n      \"sum\" : 12.205319166183472, \n      \"count\" : 3555, \n      \"counts\" : [ \n        3438, \n        98, \n        12, \n        4, \n        0, \n        0, \n        3 \n      ] \n    }, \n    \"bytesSent\" : { \n      \"sum\" : 1578763, \n      \"count\" : 3555, \n      \"counts\" : [ \n        389, \n        2939, \n        15, \n        212, \n        0, \n        0 \n      ] \n    }, \n    \"bytesReceived\" : { \n      \"sum\" : 796270, \n      \"count\" : 3555, \n      \"counts\" : [ \n        3344, \n        211, \n        0, \n        0, \n        0, \n        0 \n      ] \n    } \n  }, \n  \"http\" : { \n    \"requestsTotal\" : 3567, \n    \"requestsAsync\" : 0, \n    \"requestsGet\" : 597, \n    \"requestsHead\" : 65, \n    \"requestsPost\" : 2652, \n    \"requestsPut\" : 110, \n    \"requestsPatch\" : 3, \n    \"requestsDelete\" : 139, \n    \"requestsOptions\" : 0, \n    \"requestsOther\" : 1 \n  }, \n  \"server\" : { \n    \"uptime\" : 47.32217192649841, \n    \"physicalMemory\" : 8391671808 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Statistics were returned successfully.
" - } - }, - "summary": " Read the statistics", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/statistics-description": { - "get": { - "description": "\n\n
Returns a description of the statistics returned by /_admin/statistics. The returned objects contains an array of statistics groups in the attribute groups and an array of statistics figures in the attribute figures.
A statistics group is described by
  • group: The identifier of the group.
  • name: The name of the group.
  • description: A description of the group.
A statistics figure is described by
  • group: The identifier of the group to which this figure belongs.
  • identifier: The identifier of the figure. It is unique within the group.
  • name: The name of the figure.
  • description: A description of the figure.
  • type: Either current, accumulated, or distribution.
  • cuts: The distribution vector.
  • units: Units in which the figure is measured.

Example:

shell> curl --dump - http://localhost:8529/_admin/statistics-description\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"groups\" : [ \n    { \n      \"group\" : \"system\", \n      \"name\" : \"Process Statistics\", \n      \"description\" : \"Statistics about the ArangoDB process\" \n    }, \n    { \n      \"group\" : \"client\", \n      \"name\" : \"Client Connection Statistics\", \n      \"description\" : \"Statistics about the connections.\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"name\" : \"HTTP Request Statistics\", \n      \"description\" : \"Statistics about the HTTP requests.\" \n    }, \n    { \n      \"group\" : \"server\", \n      \"name\" : \"Server Statistics\", \n      \"description\" : \"Statistics about the ArangoDB server\" \n    } \n  ], \n  \"figures\" : [ \n    { \n      \"group\" : \"system\", \n      \"identifier\" : \"userTime\", \n      \"name\" : \"User Time\", \n      \"description\" : \"Amount of time that this process has been scheduled in user mode, measured in seconds.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"seconds\" \n    }, \n    { \n      \"group\" : \"system\", \n      \"identifier\" : \"systemTime\", \n      \"name\" : \"System Time\", \n      \"description\" : \"Amount of time that this process has been scheduled in kernel mode, measured in seconds.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"seconds\" \n    }, \n    { \n      \"group\" : \"system\", \n      \"identifier\" : \"numberOfThreads\", \n      \"name\" : \"Number of Threads\", \n      \"description\" : \"Number of threads in the arangod process.\", \n      \"type\" : \"current\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"system\", \n      \"identifier\" : \"residentSize\", \n      \"name\" : \"Resident Set Size\", \n      \"description\" : \"The total size of the number of pages the process has in real memory. This is just the pages which count toward text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out. The resident set size is reported in bytes.\", \n      \"type\" : \"current\", \n      \"units\" : \"bytes\" \n    }, \n    { \n      \"group\" : \"system\", \n      \"identifier\" : \"residentSizePercent\", \n      \"name\" : \"Resident Set Size\", \n      \"description\" : \"The percentage of physical memory used by the process as resident set size.\", \n      \"type\" : \"current\", \n      \"units\" : \"percent\" \n    }, \n    { \n      \"group\" : \"system\", \n      \"identifier\" : \"virtualSize\", \n      \"name\" : \"Virtual Memory Size\", \n      \"description\" : \"On Windows, this figure contains the total amount of memory that the memory manager has committed for the arangod process. On other systems, this figure contains The size of the virtual memory the process is using.\", \n      \"type\" : \"current\", \n      \"units\" : \"bytes\" \n    }, \n    { \n      \"group\" : \"system\", \n      \"identifier\" : \"minorPageFaults\", \n      \"name\" : \"Minor Page Faults\", \n      \"description\" : \"The number of minor faults the process has made which have not required loading a memory page from disk. This figure is not reported on Windows.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"system\", \n      \"identifier\" : \"majorPageFaults\", \n      \"name\" : \"Major Page Faults\", \n      \"description\" : \"On Windows, this figure contains the total number of page faults. On other system, this figure contains the number of major faults the process has made which have required loading a memory page from disk.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"client\", \n      \"identifier\" : \"httpConnections\", \n      \"name\" : \"Client Connections\", \n      \"description\" : \"The number of connections that are currently open.\", \n      \"type\" : \"current\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"client\", \n      \"identifier\" : \"totalTime\", \n      \"name\" : \"Total Time\", \n      \"description\" : \"Total time needed to answer a request.\", \n      \"type\" : \"distribution\", \n      \"cuts\" : [ \n        0.01, \n        0.05, \n        0.1, \n        0.2, \n        0.5, \n        1 \n      ], \n      \"units\" : \"seconds\" \n    }, \n    { \n      \"group\" : \"client\", \n      \"identifier\" : \"requestTime\", \n      \"name\" : \"Request Time\", \n      \"description\" : \"Request time needed to answer a request.\", \n      \"type\" : \"distribution\", \n      \"cuts\" : [ \n        0.01, \n        0.05, \n        0.1, \n        0.2, \n        0.5, \n        1 \n      ], \n      \"units\" : \"seconds\" \n    }, \n    { \n      \"group\" : \"client\", \n      \"identifier\" : \"queueTime\", \n      \"name\" : \"Queue Time\", \n      \"description\" : \"Queue time needed to answer a request.\", \n      \"type\" : \"distribution\", \n      \"cuts\" : [ \n        0.01, \n        0.05, \n        0.1, \n        0.2, \n        0.5, \n        1 \n      ], \n      \"units\" : \"seconds\" \n    }, \n    { \n      \"group\" : \"client\", \n      \"identifier\" : \"bytesSent\", \n      \"name\" : \"Bytes Sent\", \n      \"description\" : \"Bytes sents for a request.\", \n      \"type\" : \"distribution\", \n      \"cuts\" : [ \n        250, \n        1000, \n        2000, \n        5000, \n        10000 \n      ], \n      \"units\" : \"bytes\" \n    }, \n    { \n      \"group\" : \"client\", \n      \"identifier\" : \"bytesReceived\", \n      \"name\" : \"Bytes Received\", \n      \"description\" : \"Bytes receiveds for a request.\", \n      \"type\" : \"distribution\", \n      \"cuts\" : [ \n        250, \n        1000, \n        2000, \n        5000, \n        10000 \n      ], \n      \"units\" : \"bytes\" \n    }, \n    { \n      \"group\" : \"client\", \n      \"identifier\" : \"connectionTime\", \n      \"name\" : \"Connection Time\", \n      \"description\" : \"Total connection time of a client.\", \n      \"type\" : \"distribution\", \n      \"cuts\" : [ \n        0.1, \n        1, \n        60 \n      ], \n      \"units\" : \"seconds\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsTotal\", \n      \"name\" : \"Total requests\", \n      \"description\" : \"Total number of HTTP requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsAsync\", \n      \"name\" : \"Async requests\", \n      \"description\" : \"Number of asynchronously executed HTTP requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsGet\", \n      \"name\" : \"HTTP GET requests\", \n      \"description\" : \"Number of HTTP GET requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsHead\", \n      \"name\" : \"HTTP HEAD requests\", \n      \"description\" : \"Number of HTTP HEAD requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsPost\", \n      \"name\" : \"HTTP POST requests\", \n      \"description\" : \"Number of HTTP POST requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsPut\", \n      \"name\" : \"HTTP PUT requests\", \n      \"description\" : \"Number of HTTP PUT requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsPatch\", \n      \"name\" : \"HTTP PATCH requests\", \n      \"description\" : \"Number of HTTP PATCH requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsDelete\", \n      \"name\" : \"HTTP DELETE requests\", \n      \"description\" : \"Number of HTTP DELETE requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsOptions\", \n      \"name\" : \"HTTP OPTIONS requests\", \n      \"description\" : \"Number of HTTP OPTIONS requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"http\", \n      \"identifier\" : \"requestsOther\", \n      \"name\" : \"other HTTP requests\", \n      \"description\" : \"Number of other HTTP requests.\", \n      \"type\" : \"accumulated\", \n      \"units\" : \"number\" \n    }, \n    { \n      \"group\" : \"server\", \n      \"identifier\" : \"uptime\", \n      \"name\" : \"Server Uptime\", \n      \"description\" : \"Number of seconds elapsed since server start.\", \n      \"type\" : \"current\", \n      \"units\" : \"seconds\" \n    }, \n    { \n      \"group\" : \"server\", \n      \"identifier\" : \"physicalMemory\", \n      \"name\" : \"Physical Memory\", \n      \"description\" : \"Physical memory in bytes.\", \n      \"type\" : \"current\", \n      \"units\" : \"bytes\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Description was returned successfully.
" - } - }, - "summary": " Statistics description", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/test": { - "post": { - "description": "free style json body\n\n
Executes the specified tests on the server and returns an object with the test results. The object has an attribute \"error\" which states whether any error occurred. The object also has an attribute \"passed\" which indicates which tests passed and which did not.
", - "parameters": [ - { - "description": "A JSON object containing an attribute tests which lists the files containing the test suites.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "summary": " Runs tests on server", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/time": { - "get": { - "description": "\n\n
The call returns an object with the attribute time. This contains the current system time as a Unix timestamp with microsecond precision.
", - "parameters": [], - "responses": { - "200": { - "description": "Time was returned successfully.
" - } - }, - "summary": " Return system time", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_admin/wal/flush": { - "put": { - "description": "\n\n
Flushes the write-ahead log. By flushing the currently active write-ahead logfile, the data in it can be transferred to collection journals and datafiles. This is useful to ensure that all data for a collection is present in the collection journals and datafiles, for example, when dumping the data of a collection.
", - "parameters": [ - { - "description": "Whether or not the operation should block until the not-yet synchronized data in the write-ahead log was synchronized to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "Whether or not the operation should block until the data in the flushed log has been collected by the write-ahead log garbage collector. Note that setting this option to true might block for a long time if there are long-running transactions and the write-ahead log garbage collector cannot finish garbage collection.
", - "in": "query", - "name": "waitForCollector", - "required": false, - "type": "boolean" - } - ], - "responses": { - "200": { - "description": "Is returned if the operation succeeds.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - } - }, - "summary": " Flushes the write-ahead log", - "tags": [ - "wal" - ], - "x-examples": [], - "x-filename": "wal - js/actions/_admin/wal/app.js" - } - }, - "/_admin/wal/properties": { - "get": { - "description": "\n\n
Retrieves the configuration of the write-ahead log. The result is a JSON object with the following attributes:
  • allowOversizeEntries: whether or not operations that are bigger than a single logfile can be executed and stored
  • logfileSize: the size of each write-ahead logfile
  • historicLogfiles: the maximum number of historic logfiles to keep
  • reserveLogfiles: the maximum number of reserve logfiles that ArangoDB allocates in the background
  • syncInterval: the interval for automatic synchronization of not-yet synchronized write-ahead log data (in milliseconds)
  • throttleWait: the maximum wait time that operations will wait before they get aborted if case of write-throttling (in milliseconds)
  • throttleWhenPending: the number of unprocessed garbage-collection operations that, when reached, will activate write-throttling. A value of 0 means that write-throttling will not be triggered.

Example:

shell> curl --dump - http://localhost:8529/_admin/wal/properties\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"allowOversizeEntries\" : true, \n  \"logfileSize\" : 33554432, \n  \"historicLogfiles\" : 10, \n  \"reserveLogfiles\" : 1, \n  \"syncInterval\" : 100, \n  \"throttleWait\" : 15000, \n  \"throttleWhenPending\" : 0, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned if the operation succeeds.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.

" - } - }, - "summary": " Retrieves the configuration of the write-ahead log", - "tags": [ - "wal" - ], - "x-examples": [], - "x-filename": "wal - js/actions/_admin/wal/app.js" - }, - "put": { - "description": "\n\n
Configures the behavior of the write-ahead log. The body of the request must be a JSON object with the following attributes:
  • allowOversizeEntries: whether or not operations that are bigger than a single logfile can be executed and stored
  • logfileSize: the size of each write-ahead logfile
  • historicLogfiles: the maximum number of historic logfiles to keep
  • reserveLogfiles: the maximum number of reserve logfiles that ArangoDB allocates in the background
  • throttleWait: the maximum wait time that operations will wait before they get aborted if case of write-throttling (in milliseconds)
  • throttleWhenPending: the number of unprocessed garbage-collection operations that, when reached, will activate write-throttling. A value of 0 means that write-throttling will not be triggered.
Specifying any of the above attributes is optional. Not specified attributes will be ignored and the configuration for them will not be modified.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_admin/wal/properties <<EOF\n{ \n  \"logfileSize\" : 33554432, \n  \"allowOversizeEntries\" : true \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"allowOversizeEntries\" : true, \n  \"logfileSize\" : 33554432, \n  \"historicLogfiles\" : 10, \n  \"reserveLogfiles\" : 1, \n  \"syncInterval\" : 100, \n  \"throttleWait\" : 15000, \n  \"throttleWhenPending\" : 0, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned if the operation succeeds.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.

" - } - }, - "summary": " Configures the write-ahead log", - "tags": [ - "wal" - ], - "x-examples": [], - "x-filename": "wal - js/actions/_admin/wal/app.js" - } - }, - "/_admin/wal/transactions": { - "get": { - "description": "\n\n
Returns information about the currently running transactions. The result is a JSON object with the following attributes:
  • runningTransactions: number of currently running transactions
  • minLastCollected: minimum id of the last collected logfile (at the start of each running transaction). This is null if no transaction is running.
  • minLastSealed: minimum id of the last sealed logfile (at the start of each running transaction). This is null if no transaction is running.

Example:

shell> curl --dump - http://localhost:8529/_admin/wal/transactions\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"runningTransactions\" : 0, \n  \"minLastCollected\" : null, \n  \"minLastSealed\" : null, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned if the operation succeeds.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.

" - } - }, - "summary": " Returns information about the currently running transactions", - "tags": [ - "wal" - ], - "x-examples": [], - "x-filename": "wal - js/actions/_admin/wal/app.js" - } - }, - "/_api/aqlfunction": { - "get": { - "description": "\n\nReturns all registered AQL user functions.
The call will return a JSON array with all user functions found. Each user function will at least have the following attributes:
  • name: The fully qualified name of the user function
  • code: A string representation of the function body

Example:

shell> curl --dump - http://localhost:8529/_api/aqlfunction\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  { \n    \"name\" : \"myfunctions::temperature::celsiustofahrenheit\", \n    \"code\" : \"function (celsius) { return celsius * 1.8 + 32; }\" \n  } \n]\n

\n
", - "parameters": [ - { - "description": "Returns all registered AQL user functions from namespace namespace.
", - "in": "query", - "name": "namespace", - "required": false, - "type": "string" - } - ], - "responses": { - "200": { - "description": "if success HTTP 200 is returned.
" - } - }, - "summary": " Return registered AQL user functions", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "post": { - "description": "**A json post document with these Properties is required:**
  • isDeterministic: an optional boolean value to indicate that the function results are fully deterministic (function return value solely depends on the input value and return value is the same for repeated calls with same input). The isDeterministic attribute is currently not used but may be used later for optimisations.
  • code: a string representation of the function body.
  • name: the fully qualified name of the user functions.
\n\n
In case of success, the returned JSON object has the following properties:
  • error: boolean flag to indicate that an error occurred (false in this case)
  • code: the HTTP status code
The body of the response will contain a JSON object with additional error details. The object has the following attributes:
  • error: boolean flag to indicate that an error occurred (true in this case)
  • code: the HTTP status code
  • errorNum: the server error number
  • errorMessage: a descriptive error message

Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/aqlfunction <<EOF\n{ \n  \"name\" : \"myfunctions::temperature::celsiustofahrenheit\", \n  \"code\" : \"function (celsius) { return celsius * 1.8 + 32; }\" \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_aqlfunction" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the function already existed and was replaced by the call, the server will respond with HTTP 200.
" - }, - "201": { - "description": "If the function can be registered by the server, the server will respond with HTTP 201.
" - }, - "400": { - "description": "If the JSON representation is malformed or mandatory data is missing from the request, the server will respond with HTTP 400.
" - } - }, - "summary": " Create AQL user function", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/aqlfunction/{name}": { - "delete": { - "description": "\n\n
Removes an existing AQL user function, identified by name.
In case of success, the returned JSON object has the following properties:
  • error: boolean flag to indicate that an error occurred (false in this case)
  • code: the HTTP status code
The body of the response will contain a JSON object with additional error details. The object has the following attributes:
  • error: boolean flag to indicate that an error occurred (true in this case)
  • code: the HTTP status code
  • errorNum: the server error number
  • errorMessage: a descriptive error message

Example: deletes a function:

shell> curl -X DELETE --dump - http://localhost:8529/_api/aqlfunction/square::x::y\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: function not found:

shell> curl -X DELETE --dump - http://localhost:8529/_api/aqlfunction/myfunction::x::y\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1582, \n  \"errorMessage\" : \"user function '%s()' not found\" \n}\n

\n
", - "parameters": [ - { - "description": "the name of the AQL user function.
", - "format": "string", - "in": "path", - "name": "name", - "required": true, - "type": "string" - }, - { - "description": "If set to true, then the function name provided in name is treated as a namespace prefix, and all functions in the specified namespace will be deleted. If set to false, the function name provided in name must be fully qualified, including any namespaces.
", - "in": "query", - "name": "group", - "required": false, - "type": "string" - } - ], - "responses": { - "200": { - "description": "If the function can be removed by the server, the server will respond with HTTP 200.
" - }, - "400": { - "description": "If the user function name is malformed, the server will respond with HTTP 400.
" - }, - "404": { - "description": "If the specified user user function does not exist, the server will respond with HTTP 404.
" - } - }, - "summary": " Remove existing AQL user function", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/batch": { - "post": { - "description": "free style json body\n\nExecutes a batch request. A batch request can contain any number of other requests that can be sent to ArangoDB in isolation. The benefit of using batch requests is that batching requests requires less client/server roundtrips than when sending isolated requests.
All parts of a batch request are executed serially on the server. The server will return the results of all parts in a single response when all parts are finished.
Technically, a batch request is a multipart HTTP request, with content-type `multipart/form-data`. A batch request consists of an envelope and the individual batch part actions. Batch part actions are \"regular\" HTTP requests, including full header and an optional body. Multiple batch parts are separated by a boundary identifier. The boundary identifier is declared in the batch envelope. The MIME content-type for each individual batch part must be `application/x-arango-batchpart`.
Please note that when constructing the individual batch parts, you must use CRLF (`\\r\\n`) as the line terminator as in regular HTTP messages.
The response sent by the server will be an `HTTP 200` response, with an optional error summary header `x-arango-errors`. This header contains the number of batch part operations that failed with an HTTP error code of at least 400. This header is only present in the response if the number of errors is greater than zero.
The response sent by the server is a multipart response, too. It contains the individual HTTP responses for all batch parts, including the full HTTP result header (with status code and other potential headers) and an optional result body. The individual batch parts in the result are seperated using the same boundary value as specified in the request.
The order of batch parts in the response will be the same as in the original client request. Client can additionally use the `Content-Id` MIME header in a batch part to define an individual id for each batch part. The server will return this id is the batch part responses, too.

Example: Sending a batch request with five batch parts:
  • GET /_api/version
  • DELETE /_api/collection/products
  • POST /_api/collection/products
  • GET /_api/collection/products/figures
  • DELETE /_api/collection/products
The boundary (`SomeBoundaryValue`) is passed to the server in the HTTP `Content-Type` HTTP header. Please note the reply is not displayed all accurate.


shell> curl -X POST --header 'Content-Type: multipart/form-data; boundary=SomeBoundaryValue' --data-binary @- --dump - http://localhost:8529/_api/batch <<EOF\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: myId1\r\n\r\nGET /_api/version HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: myId2\r\n\r\nDELETE /_api/collection/products HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: someId\r\n\r\nPOST /_api/collection/products HTTP/1.1\r\n\r\n{ \"name\": \"products\" }\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: nextId\r\n\r\nGET /_api/collection/products/figures HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: otherId\r\n\r\nDELETE /_api/collection/products HTTP/1.1\r\n--SomeBoundaryValue--\r\n\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: multipart/form-data; boundary=SomeBoundaryValue\nx-arango-errors: 1\n\n\"--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: myId1\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 43\\r\\n\\r\\n{\\\"server\\\":\\\"arango\\\",\\\"version\\\":\\\"2.7.0-devel\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: myId2\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 88\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'products'\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: someId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nLocation: /_db/_system/_api/collection/products\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 137\\r\\n\\r\\n{\\\"id\\\":\\\"619502023\\\",\\\"name\\\":\\\"products\\\",\\\"waitForSync\\\":false,\\\"isVolatile\\\":false,\\\"isSystem\\\":false,\\\"status\\\":3,\\\"type\\\":2,\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: nextId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nLocation: /_db/_system/_api/collection/products/figures\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 635\\r\\n\\r\\n{\\\"id\\\":\\\"619502023\\\",\\\"name\\\":\\\"products\\\",\\\"isSystem\\\":false,\\\"doCompact\\\":true,\\\"isVolatile\\\":false,\\\"journalSize\\\":1048576,\\\"keyOptions\\\":{\\\"type\\\":\\\"traditional\\\",\\\"allowUserKeys\\\":true},\\\"waitForSync\\\":false,\\\"indexBuckets\\\":8,\\\"count\\\":0,\\\"figures\\\":{\\\"alive\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"dead\\\":{\\\"count\\\":0,\\\"size\\\":0,\\\"deletion\\\":0},\\\"datafiles\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"journals\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"compactors\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"shapefiles\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"shapes\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"attributes\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"indexes\\\":{\\\"count\\\":1,\\\"size\\\":16064},\\\"lastTick\\\":\\\"0\\\",\\\"uncollectedLogfileEntries\\\":0},\\\"status\\\":3,\\\"type\\\":2,\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: otherId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 43\\r\\n\\r\\n{\\\"id\\\":\\\"619502023\\\",\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue--\"\n

\n
Example: Sending a batch request, setting the boundary implicitly (the server will in this case try to find the boundary at the beginning of the request body).

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/batch <<EOF\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\n\r\nDELETE /_api/collection/notexisting1 HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\n\r\nDELETE /_api/collection/notexisting2 HTTP/1.1\r\n--SomeBoundaryValue--\r\n\nEOF\n\nHTTP/1.1 200 OK\nx-arango-errors: 2\n\n\"--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 92\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'notexisting1'\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 92\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'notexisting2'\\\"}\\r\\n--SomeBoundaryValue--\"\n

\n
", - "parameters": [ - { - "description": "The multipart batch request, consisting of the envelope and the individual batch parts.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "responses": { - "200": { - "description": "is returned if the batch was received successfully. HTTP 200 is returned even if one or multiple batch part actions failed.
" - }, - "400": { - "description": "is returned if the batch envelope is malformed or incorrectly formatted. This code will also be returned if the content-type of the overall batch request or the individual MIME parts is not as expected.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - } - }, - "summary": "executes a batch request", - "tags": [ - "Bulk" - ], - "x-examples": [], - "x-filename": "Bulk - arangod/RestHandler/RestExportHandler.cpp, arangod/RestHandler/RestImportHandler.cpp, arangod/RestHandler/RestBatchHandler.cpp" - } - }, - "/_api/collection": { - "get": { - "description": "\n\nReturns an object with an attribute collections containing an array of all collection descriptions. The same information is also available in the names as an object with the collection names as keys.
By providing the optional URL parameter excludeSystem with a value of true, all system collections will be excluded from the response.

Example: Return information about all collections:

shell> curl --dump - http://localhost:8529/_api/collection\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"id\" : \"6216135\", \n      \"name\" : \"_queues\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"5757383\", \n      \"name\" : \"_configuration\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"22206919\", \n      \"name\" : \"animals\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"14145991\", \n      \"name\" : \"_sessions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"2087367\", \n      \"name\" : \"_graphs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"2480583\", \n      \"name\" : \"_cluster_kickstarter_plans\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"252359\", \n      \"name\" : \"_users\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"14866887\", \n      \"name\" : \"_system_users_users\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"4577735\", \n      \"name\" : \"_statisticsRaw\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"2349511\", \n      \"name\" : \"_routing\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"6347207\", \n      \"name\" : \"_jobs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"7199175\", \n      \"name\" : \"_apps\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"4970951\", \n      \"name\" : \"_statistics\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"5364167\", \n      \"name\" : \"_statistics15\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"21354951\", \n      \"name\" : \"demo\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"4446663\", \n      \"name\" : \"_aqlfunctions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"2218439\", \n      \"name\" : \"_modules\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    } \n  ], \n  \"names\" : { \n    \"_queues\" : { \n      \"id\" : \"6216135\", \n      \"name\" : \"_queues\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_configuration\" : { \n      \"id\" : \"5757383\", \n      \"name\" : \"_configuration\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"animals\" : { \n      \"id\" : \"22206919\", \n      \"name\" : \"animals\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_sessions\" : { \n      \"id\" : \"14145991\", \n      \"name\" : \"_sessions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_graphs\" : { \n      \"id\" : \"2087367\", \n      \"name\" : \"_graphs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_cluster_kickstarter_plans\" : { \n      \"id\" : \"2480583\", \n      \"name\" : \"_cluster_kickstarter_plans\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_users\" : { \n      \"id\" : \"252359\", \n      \"name\" : \"_users\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_system_users_users\" : { \n      \"id\" : \"14866887\", \n      \"name\" : \"_system_users_users\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_statisticsRaw\" : { \n      \"id\" : \"4577735\", \n      \"name\" : \"_statisticsRaw\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_routing\" : { \n      \"id\" : \"2349511\", \n      \"name\" : \"_routing\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_jobs\" : { \n      \"id\" : \"6347207\", \n      \"name\" : \"_jobs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_apps\" : { \n      \"id\" : \"7199175\", \n      \"name\" : \"_apps\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_statistics\" : { \n      \"id\" : \"4970951\", \n      \"name\" : \"_statistics\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_statistics15\" : { \n      \"id\" : \"5364167\", \n      \"name\" : \"_statistics15\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"demo\" : { \n      \"id\" : \"21354951\", \n      \"name\" : \"demo\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_aqlfunctions\" : { \n      \"id\" : \"4446663\", \n      \"name\" : \"_aqlfunctions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_modules\" : { \n      \"id\" : \"2218439\", \n      \"name\" : \"_modules\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "Whether or not system collections should be excluded from the result.
", - "in": "query", - "name": "excludeSystem", - "required": false, - "type": "boolean" - } - ], - "responses": { - "200": { - "description": "The list of collections
" - } - }, - "summary": "reads all collections", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "post": { - "description": "**A json post document with these Properties is required:**
  • journalSize: The maximal size of a journal or datafile in bytes. The value must be at least `1048576` (1 MiB). (The default is a configuration parameter)
  • keyOptions: additional options for key generation. If specified, then keyOptions should be a JSON array containing the following attributes:
    • allowUserKeys: if set to true, then it is allowed to supply own key values in the _key attribute of a document. If set to false, then the key generator will solely be responsible for generating keys and supplying own key values in the _key attribute of documents is considered an error.
    • type: specifies the type of the key generator. The currently available generators are traditional and autoincrement.
    • increment: increment value for autoincrement key generator. Not used for other key generator types.
    • offset: Initial offset value for autoincrement key generator. Not used for other key generator types.
  • name: The name of the collection.
  • waitForSync: If true then the data is synchronized to disk before returning from a document create, update, replace or removal operation. (default: false)
  • doCompact: whether or not the collection will be compacted (default is true)
  • isVolatile: If true then the collection data is kept in-memory only and not made persistent. Unloading the collection will cause the collection data to be discarded. Stopping or re-starting the server will also cause full loss of data in the collection. Setting this option will make the resulting collection be slightly faster than regular collections because ArangoDB does not enforce any synchronization to disk and does not calculate any CRC checksums for datafiles (as there are no datafiles). This option should therefore be used for cache-type collections only, and not for data that cannot be re-created otherwise. (The default is false)
  • shardKeys: (The default is [ \"_key\" ]): in a cluster, this attribute determines which document attributes are used to determine the target shard for documents. Documents are sent to shards based on the values of their shard key attributes. The values of all shard key attributes in a document are hashed, and the hash value is used to determine the target shard. Note: Values of shard key attributes cannot be changed once set. This option is meaningless in a single server setup.
  • numberOfShards: (The default is 1): in a cluster, this value determines the number of shards to create for the collection. In a single server setup, this option is meaningless.
  • isSystem: If true, create a system collection. In this case collection-name should start with an underscore. End users should normally create non-system collections only. API implementors may be required to create system collections in very special occasions, but normally a regular collection will do. (The default is false)
  • type: (The default is 2): the type of the collection to create. The following values for type are valid:
    • 2: document collection
    • 3: edges collection
  • indexBuckets: The: number of buckets into which indexes using a hash table are split. The default is 16 and this number has to be a power of 2 and less than or equal to 1024.
    For very large collections one should increase this to avoid long pauses when the hash table has to be initially built or resized, since buckets are resized individually and can be initially built in parallel. For example, 64 might be a sensible value for a collection with 100 000 000 documents. Currently, only the edge index respects this value, but other index types might follow in future ArangoDB versions. Changes (see below) are applied when the collection is loaded the next time.
\n\nCreates an new collection with a given name. The request must contain an object with the following attributes.


Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection <<EOF\n{ \n  \"name\" : \"testCollectionBasics\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionBasics\n\n{ \n  \"id\" : \"619895239\", \n  \"name\" : \"testCollectionBasics\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\nshell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection <<EOF\n{ \n  \"name\" : \"testCollectionEdges\", \n  \"type\" : 3 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionEdges\n\n{ \n  \"id\" : \"620026311\", \n  \"name\" : \"testCollectionEdges\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 3, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection <<EOF\n{ \n  \"name\" : \"testCollectionUsers\", \n  \"keyOptions\" : { \n    \"type\" : \"autoincrement\", \n    \"increment\" : 5, \n    \"allowUserKeys\" : true \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionUsers\n\n{ \n  \"id\" : \"620288455\", \n  \"name\" : \"testCollectionUsers\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_collection" - }, - "x-description-offset": 59 - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.

" - } - }, - "summary": " Create collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}": { - "delete": { - "description": "\n\nDrops the collection identified by collection-name.
If the collection was successfully dropped, an object is returned with the following attributes:
  • error: false
  • id: The identifier of the dropped collection.

Example: Using an identifier:

shell> curl -X DELETE --dump - http://localhost:8529/_api/collection/620485063\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"620485063\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using a name:

shell> curl -X DELETE --dump - http://localhost:8529/_api/collection/products1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"620681671\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection to drop.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Drops collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "get": { - "description": "\n\nThe result is an object describing the collection with the following attributes:
  • id: The identifier of the collection.
  • name: The name of the collection.
  • status: The status of the collection as number. - 1: new born collection - 2: unloaded - 3: loaded - 4: in the process of being unloaded - 5: deleted - 6: loading
Every other status indicates a corrupted collection.
  • type: The type of the collection as number. - 2: document collection (normal case) - 3: edges collection
  • isSystem: If true then the collection is a system collection.
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Return information about a collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/checksum": { - "get": { - "description": "\n\nWill calculate a checksum of the meta-data (keys and optionally revision ids) and optionally the document data in the collection.
The checksum can be used to compare if two collections on different ArangoDB instances contain the same contents. The current revision of the collection is returned too so one can make sure the checksums are calculated for the same state of data.
By default, the checksum will only be calculated on the _key system attribute of the documents contained in the collection. For edge collections, the system attributes _from and _to will also be included in the calculation.
By setting the optional URL parameter withRevisions to true, then revision ids (_rev system attributes) are included in the checksumming.
By providing the optional URL parameter withData with a value of true, the user-defined document attributes will be included in the calculation too. Note: Including user-defined attributes will make the checksumming slower.
The response is a JSON object with the following attributes:
  • checksum: The calculated checksum as a number.
  • revision: The collection revision id as a string.
Note: this method is not available in a cluster.

Example: Retrieving the checksum of a collection:

shell> curl --dump - http://localhost:8529/_api/collection/products/checksum\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"620878279\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"checksum\" : 2335626498, \n  \"revision\" : \"621205959\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Retrieving the checksum of a collection including the collection data, but not the revisions:

shell> curl --dump - http://localhost:8529/_api/collection/products/checksum?withRevisions=false&withData=true\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"621468103\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"checksum\" : 1042110547, \n  \"revision\" : \"621795783\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - }, - { - "description": "Whether or not to include document revision ids in the checksum calculation.
", - "in": "query", - "name": "withRevisions", - "required": false, - "type": "boolean" - }, - { - "description": "Whether or not to include document body data in the checksum calculation.
", - "in": "query", - "name": "withData", - "required": false, - "type": "boolean" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Return checksum for the collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/count": { - "get": { - "description": "\n\nIn addition to the above, the result also contains the number of documents. Note that this will always load the collection into memory.
  • count: The number of documents inside the collection.

Example: Requesting the number of documents:

shell> curl --dump - http://localhost:8529/_api/collection/products/count\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/count\n\n{ \n  \"id\" : \"622057927\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"indexBuckets\" : 8, \n  \"count\" : 100, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Return number of documents in a collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/figures": { - "get": { - "description": "\n\nIn addition to the above, the result also contains the number of documents and additional statistical information about the collection. Note : This will always load the collection into memory.
Note: collection data that are stored in the write-ahead log only are not reported in the results. When the write-ahead log is collected, documents might be added to journals and datafiles of the collection, which may modify the figures of the collection.
Additionally, the filesizes of collection and index parameter JSON files are not reported. These files should normally have a size of a few bytes each. Please also note that the fileSize values are reported in bytes and reflect the logical file sizes. Some filesystems may use optimisations (e.g. sparse files) so that the actual physical file size is somewhat different. Directories and sub-directories may also require space in the file system, but this space is not reported in the fileSize results.
That means that the figures reported do not reflect the actual disk usage of the collection with 100% accuracy. The actual disk usage of a collection is normally slightly higher than the sum of the reported fileSize values. Still the sum of the fileSize values can still be used as a lower bound approximation of the disk usage.
**A json document with these Properties is returned:**
  • count: The number of documents currently present in the collection.
  • journalSize: The maximal size of a journal or datafile in bytes.
  • figures: metrics of the collection
    • datafiles: Metrics regarding the datafiles
      • count: The number of datafiles.
      • fileSize: The total filesize of datafiles (in bytes).
    • uncollectedLogfileEntries: The number of markers in the write-ahead log for this collection that have not been transferred to journals or datafiles.
    • compactors:
      • count: The number of compactor files.
      • fileSize: The total filesize of all compactor files (in bytes).
    • dead: the items waiting to be swept away by the cleaner
      • count: The number of dead documents. This includes document versions that have been deleted or replaced by a newer version. Documents deleted or replaced that are contained the write-ahead log only are not reported in this figure.
      • deletion: The total number of deletion markers. Deletion markers only contained in the write-ahead log are not reporting in this figure.
      • size: The total size in bytes used by all dead documents.
    • indexes:
      • count: The total number of indexes defined for the collection, including the pre-defined indexes (e.g. primary index).
      • size: The total memory allocated for indexes in bytes.
    • shapes:
      • count: The total number of shapes used in the collection. This includes shapes that are not in use anymore. Shapes that are contained in the write-ahead log only are not reported in this figure.
      • size: The total size of all shapes (in bytes). This includes shapes that are not in use anymore. Shapes that are contained in the write-ahead log only are not reported in this figure.
    • alive: the currently active figures
      • count: The number of currently active documents in all datafiles and journals of the collection. Documents that are contained in the write-ahead log only are not reported in this figure.
      • size: The total size in bytes used by all active documents of the collection. Documents that are contained in the write-ahead log only are not reported in this figure.
    • attributes:
      • count: The total number of attributes used in the collection. Note: the value includes data of attributes that are not in use anymore. Attributes that are contained in the write-ahead log only are not reported in this figure.
      • size: The total size of the attribute data (in bytes). Note: the value includes data of attributes that are not in use anymore. Attributes that are contained in the write-ahead log only are not reported in this figure.
    • shapefiles: deprecated
      • count: The number of shape files. This value is deprecated and kept for compatibility reasons only. The value will always be 0 since ArangoDB 2.0 and higher.
      • fileSize: The total filesize of the shape files. This value is deprecated and kept for compatibility reasons only. The value will always be 0 in ArangoDB 2.0 and higher.
    • journals: Metrics regarding the journal files
      • count: The number of journal files.
      • fileSize: The total filesize of all journal files (in bytes).
    • maxTick: The tick of the last marker that was stored in a journal of the collection. This might be 0 if the collection does not yet have a journal.

Example: Using an identifier and requesting the figures of the collection:

shell> curl --dump - http://localhost:8529/_api/collection/products/figures\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/figures\n\n{ \n  \"id\" : \"642111943\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : false, \n  \"indexBuckets\" : 8, \n  \"count\" : 1, \n  \"figures\" : { \n    \"alive\" : { \n      \"count\" : 0, \n      \"size\" : 0 \n    }, \n    \"dead\" : { \n      \"count\" : 0, \n      \"size\" : 0, \n      \"deletion\" : 0 \n    }, \n    \"datafiles\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"journals\" : { \n      \"count\" : 1, \n      \"fileSize\" : 1048576 \n    }, \n    \"compactors\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"shapefiles\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"shapes\" : { \n      \"count\" : 0, \n      \"size\" : 0 \n    }, \n    \"attributes\" : { \n      \"count\" : 0, \n      \"size\" : 0 \n    }, \n    \"indexes\" : { \n      \"count\" : 1, \n      \"size\" : 16120 \n    }, \n    \"lastTick\" : \"642505159\", \n    \"uncollectedLogfileEntries\" : 1 \n  }, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "Returns information about the collection:
", - "schema": { - "$ref": "#/definitions/JSA_get_api_collection_figures_rc_200" - }, - "x-description-offset": 1458 - }, - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Return statistics for a collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/load": { - "put": { - "description": "\n\nLoads a collection into memory. Returns the collection on success.
The request body object might optionally contain the following attribute:
  • count: If set, this controls whether the return value should include the number of documents in the collection. Setting count to false may speed up loading a collection. The default value for count is true.
On success an object with the following attributes is returned:
  • id: The identifier of the collection.
  • name: The name of the collection.
  • count: The number of documents inside the collection. This is only returned if the count input parameters is set to true or has not been specified.
  • status: The status of the collection as number.
  • type: The collection type. Valid types are: - 2: document collection - 3: edges collection
  • isSystem: If true then the collection is a system collection.

Example:

shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/load\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"644078023\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"count\" : 0, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Load collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/properties": { - "get": { - "description": "\n\nIn addition to the above, the result will always contain the waitForSync, doCompact, journalSize, and isVolatile attributes. This is achieved by forcing a load of the underlying collection.
  • waitForSync: If true then creating, changing or removing documents will wait until the data has been synchronized to disk.
  • doCompact: Whether or not the collection will be compacted.
  • journalSize: The maximal size setting for journals / datafiles in bytes.
  • keyOptions: JSON object which contains key generation options: - type: specifies the type of the key generator. The currently available generators are traditional and autoincrement. - allowUserKeys: if set to true, then it is allowed to supply own key values in the _key attribute of a document. If set to false, then the key generator is solely responsible for generating keys and supplying own key values in the _key attribute of documents is considered an error.
  • isVolatile: If true then the collection data will be kept in memory only and ArangoDB will not write or sync the data to disk.
In a cluster setup, the result will also contain the following attributes:
  • numberOfShards: the number of shards of the collection.
  • shardKeys: contains the names of document attributes that are used to determine the target shard for documents.

Example: Using an identifier:

shell> curl --dump - http://localhost:8529/_api/collection/643422663/properties\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/properties\n\n{ \n  \"id\" : \"643422663\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"indexBuckets\" : 8, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using a name:

shell> curl --dump - http://localhost:8529/_api/collection/products/properties\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/properties\n\n{ \n  \"id\" : \"643619271\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"indexBuckets\" : 8, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Read properties of a collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - }, - "put": { - "description": "\n\nChanges the properties of a collection. Expects an object with the attribute(s)
  • waitForSync: If true then creating or changing a document will wait until the data has been synchronized to disk.
  • journalSize: The maximal size of a journal or datafile in bytes. The value must be at least `1048576` (1 MB). Note that when changing the journalSize value, it will only have an effect for additional journals or datafiles that are created. Already existing journals or datafiles will not be affected.
On success an object with the following attributes is returned:
  • id: The identifier of the collection.
  • name: The name of the collection.
  • waitForSync: The new value.
  • journalSize: The new value.
  • status: The status of the collection as number.
  • type: The collection type. Valid types are: - 2: document collection - 3: edges collection
  • isSystem: If true then the collection is a system collection.
  • isVolatile: If true then the collection data will be kept in memory only and ArangoDB will not write or sync the data to disk.
  • doCompact: Whether or not the collection will be compacted.
  • keyOptions: JSON object which contains key generation options: - type: specifies the type of the key generator. The currently available generators are traditional and autoincrement. - allowUserKeys: if set to true, then it is allowed to supply own key values in the _key attribute of a document. If set to false, then the key generator is solely responsible for generating keys and supplying own key values in the _key attribute of documents is considered an error.
Note: some other collection properties, such as type, isVolatile, numberOfShards or shardKeys cannot be changed once a collection is created.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/collection/products/properties <<EOF\n{ \n  \"waitForSync\" : true \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"644340167\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"indexBuckets\" : 8, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Change properties of a collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/rename": { - "put": { - "description": "\n\nRenames a collection. Expects an object with the attribute(s)
  • name: The new name.
If returns an object with the attributes
  • id: The identifier of the collection.
  • name: The new name of the collection.
  • status: The status of the collection as number.
  • type: The collection type. Valid types are: - 2: document collection - 3: edges collection
  • isSystem: If true then the collection is a system collection.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/collection/products1/rename <<EOF\n{ \n  \"name\" : \"newname\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"644602311\", \n  \"name\" : \"newname\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection to rename.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned." - } - }, - "summary": " Rename collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/revision": { - "get": { - "description": "\n\nIn addition to the above, the result will also contain the collection's revision id. The revision id is a server-generated string that clients can use to check whether data in a collection has changed since the last revision check.
  • revision: The collection revision id as a string.

Example: Retrieving the revision of a collection

shell> curl --dump - http://localhost:8529/_api/collection/products/revision\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"643815879\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"revision\" : \"0\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Return collection revision id", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/rotate": { - "put": { - "description": "\n\nRotates the journal of a collection. The current journal of the collection will be closed and made a read-only datafile. The purpose of the rotate method is to make the data in the file available for compaction (compaction is only performed for read-only datafiles, and not for journals).
Saving new data in the collection subsequently will create a new journal file automatically if there is no current journal.
If returns an object with the attributes
  • result: will be true if rotation succeeded
Note: This method is not available in a cluster.

Example: Rotating the journal:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/collection/products/rotate <<EOF\n{ \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Rotating if no journal exists:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/collection/products/rotate <<EOF\n{ \n}\nEOF\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1105, \n  \"errorMessage\" : \"could not rotate journal: no journal\" \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection currently has no journal, HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Rotate journal of a collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/truncate": { - "put": { - "description": "\n\nRemoves all documents from the collection, but leaves the indexes intact.

Example:

shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/truncate\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"644864455\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Truncate collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/collection/{collection-name}/unload": { - "put": { - "description": "\n\nRemoves a collection from memory. This call does not delete any documents. You can use the collection afterwards; in which case it will be loaded into memory, again. On success an object with the following attributes is returned:
  • id: The identifier of the collection.
  • name: The name of the collection.
  • status: The status of the collection as number.
  • type: The collection type. Valid types are: - 2: document collection - 3: edges collection
  • isSystem: If true then the collection is a system collection.

Example:

shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/unload\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"645126599\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 2, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "
", - "format": "string", - "in": "path", - "name": "collection-name", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "If the collection-name is missing, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Unload collection", - "tags": [ - "Collections" - ], - "x-examples": [], - "x-filename": "Collections - js/actions/_api/collection/app.js" - } - }, - "/_api/cursor": { - "post": { - "description": "**A json post document with these Properties is required:**
  • count: indicates whether the number of documents in the result set should be returned in the \"count\" attribute of the result. Calculating the \"count\" attribute might in the future have a performance impact for some queries so this option is turned off by default, and \"count\" is only returned when requested.
  • ttl: The time-to-live for the cursor (in seconds). The cursor will be removed on the server automatically after the specified amount of time. This is useful to ensure garbage collection of cursors that are not fully fetched by clients. If not set, a server-defined value will be used.
  • batchSize: maximum number of result documents to be transferred from the server to the client in one roundtrip. If this attribute is not set, a server-controlled default value will be used. A batchSize value of 0 is disallowed.
  • cache: flag to determine whether the AQL query cache shall be used. If set to false, then any query cache lookup will be skipped for the query. If set to true, it will lead to the query cache being checked for the query if the query cache mode is either on or demand.
  • bindVars: list of bind parameter objects. of type object
  • query: contains the query string to be executed
  • options: key/value object with extra options for the query.
    • profile: if set to true, then the additional query profiling information will be returned in the extra.stats return attribute if the query result is not served from the query cache.
    • optimizer.rules: a list of to-be-included or to-be-excluded optimizer rules can be put into this attribute, telling the optimizer to include or exclude specific rules. To disable a rule, prefix its name with a `-`, to enable a rule, prefix it with a `+`. There is also a pseudo-rule `all`, which will match all optimizer rules. of type string
    • fullCount: if set to true and the query contains a LIMIT clause, then the result will contain an extra attribute extra with a sub-attribute fullCount. This sub-attribute will contain the number of documents in the result before the last LIMIT in the query was applied. It can be used to count the number of documents that match certain filter criteria, but only return a subset of them, in one go. It is thus similar to MySQL's SQL_CALC_FOUND_ROWS hint. Note that setting the option will disable a few LIMIT optimizations and may lead to more documents being processed, and thus make queries run longer. Note that the fullCount sub-attribute will only be present in the result if the query has a LIMIT clause and the LIMIT clause is actually used in the query.
    • maxPlans: limits the maximum number of plans that are created by the AQL query optimizer.
\n\nThe query details include the query string plus optional query options and bind parameters. These values need to be passed in a JSON representation in the body of the POST request.
**A json document with these Properties is returned:**
  • count: the total number of result documents available (only available if the query was executed with the count attribute set)
  • code: the HTTP status code
  • extra: an optional JSON object with extra information about the query result contained in its stats sub-attribute. For data-modification queries, the extra.stats sub-attribute will contain the number of modified documents and the number of documents that could not be modified due to an error (if ignoreErrors query option is specified)
  • cached: a boolean flag indicating whether the query result was served from the query cache or not. If the query result is served from the query cache, the extra return attribute will not contain any stats sub-attribute and no profile sub-attribute.
  • hasMore: A boolean indicator whether there are more results available for the cursor on the server
  • result: an array of result documents (might be empty if query has no results) anonymous json object
  • error: A flag to indicate that an error occurred (false in this case)
  • id: id of temporary cursor created on the server (optional, see above)
  • errorMessage: a descriptive error message
    If the query specification is complete, the server will process the query. If an error occurs during query processing, the server will respond with HTTP 400. Again, the body of the response will contain details about the error.
    A list of query errors can be found (../ArangoErrors/README.md) here.

  • errorNum: the server error number
  • code: the HTTP status code
  • error: boolean flag to indicate that an error occurred (true in this case)

Example: Execute a query and extract the result in a single go

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR p IN products LIMIT 2 RETURN p\", \n  \"count\" : true, \n  \"batchSize\" : 2 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"hello2\" : \"world1\", \n      \"_id\" : \"products/648862151\", \n      \"_rev\" : \"648862151\", \n      \"_key\" : \"648862151\" \n    }, \n    { \n      \"hello1\" : \"world1\", \n      \"_id\" : \"products/648534471\", \n      \"_rev\" : \"648534471\", \n      \"_key\" : \"648534471\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"cached\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 2, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Execute a query and extract a part of the result

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR p IN products LIMIT 5 RETURN p\", \n  \"count\" : true, \n  \"batchSize\" : 2 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"hello3\" : \"world1\", \n      \"_id\" : \"products/647223751\", \n      \"_rev\" : \"647223751\", \n      \"_key\" : \"647223751\" \n    }, \n    { \n      \"hello5\" : \"world1\", \n      \"_id\" : \"products/647879111\", \n      \"_rev\" : \"647879111\", \n      \"_key\" : \"647879111\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"648075719\", \n  \"count\" : 5, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"cached\" : false, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Using the query option \"fullCount\"

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR i IN 1..1000 FILTER i > 500 LIMIT 10 RETURN i\", \n  \"count\" : true, \n  \"options\" : { \n    \"fullCount\" : true \n  } \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    501, \n    502, \n    503, \n    504, \n    505, \n    506, \n    507, \n    508, \n    509, \n    510 \n  ], \n  \"hasMore\" : false, \n  \"count\" : 10, \n  \"cached\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 500, \n      \"fullCount\" : 500 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Enabling and disabling optimizer rules

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR i IN 1..10 LET a = 1 LET b = 2 FILTER a + b == 3 RETURN i\", \n  \"count\" : true, \n  \"options\" : { \n    \"maxPlans\" : 1, \n    \"optimizer\" : { \n      \"rules\" : [ \n        \"-all\", \n        \"+remove-unnecessary-filters\" \n      ] \n    } \n  } \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    1, \n    2, \n    3, \n    4, \n    5, \n    6, \n    7, \n    8, \n    9, \n    10 \n  ], \n  \"hasMore\" : false, \n  \"count\" : 10, \n  \"cached\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Execute a data-modification query and retrieve the number of modified documents

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR p IN products REMOVE p IN products\" \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ ], \n  \"hasMore\" : false, \n  \"cached\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 2, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 2, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Execute a data-modification query with option ignoreErrors

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"REMOVE 'bar' IN products OPTIONS { ignoreErrors: true }\" \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ ], \n  \"hasMore\" : false, \n  \"cached\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 1, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Bad query - Missing body

shell> curl -X POST --dump - http://localhost:8529/_api/cursor\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"expecting atom, got end-of-file\", \n  \"code\" : 400, \n  \"errorNum\" : 600 \n}\n

\n
Example: Bad query - Unknown collection

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR u IN unknowncoll LIMIT 2 RETURN u\", \n  \"count\" : true, \n  \"batchSize\" : 2 \n}\nEOF\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection not found (unknowncoll)\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n

\n
Example: Bad query - Execute a data-modification query that attempts to remove a non-existing document

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"REMOVE 'foo' IN products\" \n}\nEOF\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document not found (while executing)\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n

\n

", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_cursor" - }, - "x-description-offset": 59 - } - ], - "produces": [ - "application/json" - ], - "responses": { - "201": { - "description": "is returned if the result set can be created by the server.
", - "schema": { - "$ref": "#/definitions/JSF_post_api_cursor_rc_201" - }, - "x-description-offset": 300 - }, - "400": { - "description": "is returned if the JSON representation is malformed or the query specification is missing from the request.
If the JSON representation is malformed or the query specification is missing from the request, the server will respond with HTTP 400.
The body of the response will contain a JSON object with additional error details. The object has the following attributes:
", - "schema": { - "$ref": "#/definitions/JSF_post_api_cursor_rc_400" - }, - "x-description-offset": 354 - }, - "404": { - "description": "The server will respond with HTTP 404 in case a non-existing collection is accessed in the query.
" - }, - "405": { - "description": "The server will respond with HTTP 405 if an unsupported HTTP method is used.
" - } - }, - "summary": " Create cursor", - "tags": [ - "Cursors" - ], - "x-examples": [], - "x-filename": "Cursors - arangod/RestHandler/RestCursorHandler.cpp" - } - }, - "/_api/cursor/{cursor-identifier}": { - "delete": { - "description": "\n\nDeletes the cursor and frees the resources associated with it.
The cursor will automatically be destroyed on the server when the client has retrieved all documents from it. The client can also explicitly destroy the cursor at any earlier time using an HTTP DELETE request. The cursor id must be included as part of the URL.
Note: the server will also destroy abandoned cursors automatically after a certain server-controlled timeout to avoid resource leakage.

Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR p IN products LIMIT 5 RETURN p\", \n  \"count\" : true, \n  \"batchSize\" : 2 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"hello3\" : \"world1\", \n      \"_id\" : \"products/650172871\", \n      \"_rev\" : \"650172871\", \n      \"_key\" : \"650172871\" \n    }, \n    { \n      \"hello1\" : \"world1\", \n      \"_id\" : \"products/649517511\", \n      \"_rev\" : \"649517511\", \n      \"_key\" : \"649517511\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"651024839\", \n  \"count\" : 5, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"cached\" : false, \n  \"error\" : false, \n  \"code\" : 201 \n}\nshell> curl -X DELETE --dump - http://localhost:8529/_api/cursor/651024839\n\n

\n
", - "parameters": [ - { - "description": "The id of the cursor
", - "format": "string", - "in": "path", - "name": "cursor-identifier", - "required": true, - "type": "string" - } - ], - "responses": { - "202": { - "description": "is returned if the server is aware of the cursor.
" - }, - "404": { - "description": "is returned if the server is not aware of the cursor. It is also returned if a cursor is used after it has been destroyed.
" - } - }, - "summary": " Delete cursor", - "tags": [ - "Cursors" - ], - "x-examples": [], - "x-filename": "Cursors - arangod/RestHandler/RestCursorHandler.cpp" - }, - "put": { - "description": "\n\n
If the cursor is still alive, returns an object with the following attributes:
  • id: the cursor-identifier
  • result: a list of documents for the current batch
  • hasMore: false if this was the last batch
  • count: if present the total number of elements
Note that even if hasMore returns true, the next call might still return no documents. If, however, hasMore is false, then the cursor is exhausted. Once the hasMore attribute has a value of false, the client can stop.

Example: Valid request for next batch

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR p IN products LIMIT 5 RETURN p\", \n  \"count\" : true, \n  \"batchSize\" : 2 \n}\nEOF\n\nshell> curl -X PUT --dump - http://localhost:8529/_api/cursor/655481287\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"hello1\" : \"world1\", \n      \"_id\" : \"products/653973959\", \n      \"_rev\" : \"653973959\", \n      \"_key\" : \"653973959\" \n    }, \n    { \n      \"hello3\" : \"world1\", \n      \"_id\" : \"products/654629319\", \n      \"_rev\" : \"654629319\", \n      \"_key\" : \"654629319\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"655481287\", \n  \"count\" : 5, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"cached\" : false, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Missing identifier

shell> curl -X PUT --dump - http://localhost:8529/_api/cursor\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"expecting PUT /_api/cursor/<cursor-id>\", \n  \"code\" : 400, \n  \"errorNum\" : 400 \n}\n

\n
Example: Unknown identifier

shell> curl -X PUT --dump - http://localhost:8529/_api/cursor/123123\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"cursor not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1600 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the cursor
", - "format": "string", - "in": "path", - "name": "cursor-identifier", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "The server will respond with HTTP 200 in case of success.
" - }, - "400": { - "description": "If the cursor identifier is omitted, the server will respond with HTTP 404.
" - }, - "404": { - "description": "If no cursor with the specified identifier can be found, the server will respond with HTTP 404.
" - } - }, - "summary": " Read next batch from cursor", - "tags": [ - "Cursors" - ], - "x-examples": [], - "x-filename": "Cursors - arangod/RestHandler/RestCursorHandler.cpp" - } - }, - "/_api/database": { - "get": { - "description": "\n\nRetrieves the list of all existing databases
Note: retrieving the list of databases is only possible from within the _system database.

Example:

shell> curl --dump - http://localhost:8529/_api/database\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    \"_system\" \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the list of database was compiled successfully.
" - }, - "400": { - "description": "is returned if the request is invalid.
" - }, - "403": { - "description": "is returned if the request was not executed in the _system database.
" - } - }, - "summary": " List of databases", - "tags": [ - "Database" - ], - "x-examples": [], - "x-filename": "Database - js/actions/api-database.js" - }, - "post": { - "description": "**A json post document with these Properties is required:**
  • username: The user name as a string. If users is not specified or does not contain any users, a default user root will be created with an empty string password. This ensures that the new database will be accessible after it is created.
  • users: Has to be a list of user objects to initially create for the new database. Each user object can contain the following attributes: \n
    • username: Loginname of the user to be created
    • passwd: Password for the user
    • active: if False the user won't be able to log into the database.
  • extra: A JSON object with extra user information. The data contained in extra will be stored for the user but not be interpreted further by ArangoDB.
  • passwd: The user password as a string. If not specified, it will default to an empty string.
  • active: A Flag indicating whether the user account should be activated or not. The default value is true.
  • name: Has to contain a valid database name.
\n\nCreates a new database
The response is a JSON object with the attribute result set to true.
Note: creating a new database is only possible from within the _system database.

Example: Creating a database named example.

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/database <<EOF\n{ \n  \"name\" : \"example\" \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Creating a database named mydb with two users.

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/database <<EOF\n{ \n  \"name\" : \"mydb\", \n  \"users\" : [ \n    { \n      \"username\" : \"admin\", \n      \"passwd\" : \"secret\", \n      \"active\" : true \n    }, \n    { \n      \"username\" : \"tester\", \n      \"passwd\" : \"test001\", \n      \"active\" : false \n    } \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_get_api_database_new" - }, - "x-description-offset": 59 - } - ], - "responses": { - "201": { - "description": "is returned if the database was created successfully.
" - }, - "400": { - "description": "is returned if the request parameters are invalid or if a database with the specified name already exists.
" - }, - "403": { - "description": "is returned if the request was not executed in the _system database.
" - }, - "409": { - "description": "is returned if a database with the specified name already exists.
" - } - }, - "summary": " Create database", - "tags": [ - "Database" - ], - "x-examples": [], - "x-filename": "Database - js/actions/api-database.js" - } - }, - "/_api/database/current": { - "get": { - "description": "\n\nRetrieves information about the current database
The response is a JSON object with the following attributes:
  • name: the name of the current database
  • id: the id of the current database
  • path: the filesystem path of the current database
  • isSystem: whether or not the current database is the _system database

Example:

shell> curl --dump - http://localhost:8529/_api/database/current\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"name\" : \"_system\", \n    \"id\" : \"121287\", \n    \"path\" : \"/tmp/vocdir.2239/databases/database-121287\", \n    \"isSystem\" : true \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the information was retrieved successfully.
" - }, - "400": { - "description": "is returned if the request is invalid.
" - }, - "404": { - "description": "is returned if the database could not be found.
" - } - }, - "summary": " Information of the database", - "tags": [ - "Database" - ], - "x-examples": [], - "x-filename": "Database - js/actions/api-database.js" - } - }, - "/_api/database/user": { - "get": { - "description": "\n\nRetrieves the list of all databases the current user can access without specifying a different username or password.

Example:

shell> curl --dump - http://localhost:8529/_api/database/user\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    \"_system\" \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the list of database was compiled successfully.
" - }, - "400": { - "description": "is returned if the request is invalid.
" - } - }, - "summary": " List of accessible databases ", - "tags": [ - "Database" - ], - "x-examples": [], - "x-filename": "Database - js/actions/api-database.js" - } - }, - "/_api/database/{database-name}": { - "delete": { - "description": "\n\nDrops the database along with all data stored in it.
Note: dropping a database is only possible from within the _system database. The _system database itself cannot be dropped.

Example:

shell> curl -X DELETE --dump - http://localhost:8529/_api/database/example\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the database
", - "format": "string", - "in": "path", - "name": "database-name", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the database was dropped successfully.
" - }, - "400": { - "description": "is returned if the request is malformed.
" - }, - "403": { - "description": "is returned if the request was not executed in the _system database.
" - }, - "404": { - "description": "is returned if the database could not be found.
" - } - }, - "summary": " Drop database", - "tags": [ - "Database" - ], - "x-examples": [], - "x-filename": "Database - js/actions/api-database.js" - } - }, - "/_api/document": { - "get": { - "description": "\n\nReturns an array of all keys, ids, or URI paths for all documents in the collection identified by collection. The type of the result array is determined by the type attribute.
Note that the results have no defined order and thus the order should not be relied on.

Example: Return all document paths

shell> curl --dump - http://localhost:8529/_api/document/?collection=products\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"documents\" : [ \n    \"/_db/_system/_api/document/products/711580103\", \n    \"/_db/_system/_api/document/products/712235463\", \n    \"/_db/_system/_api/document/products/711907783\" \n  ] \n}\n

\n
Example: Return all document keys

shell> curl --dump - http://localhost:8529/_api/document/?collection=products&type=key\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"documents\" : [ \n    \"710662599\", \n    \"710334919\", \n    \"710990279\" \n  ] \n}\n

\n
Example: Collection does not exist

shell> curl --dump - http://localhost:8529/_api/document/?collection=doesnotexist\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'doesnotexist' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n

\n
", - "parameters": [ - { - "description": "The name of the collection.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "description": "The type of the result. The following values are allowed:
  • id: returns an array of document ids (_id attributes)
  • key: returns an array of document keys (_key attributes)
  • path: returns an array of document URI paths. This is the default.
", - "in": "query", - "name": "type", - "required": false, - "type": "string" - } - ], - "responses": { - "200": { - "description": "All went good.
" - }, - "404": { - "description": "The collection does not exist.
" - } - }, - "summary": "Read all documents", - "tags": [ - "Documents" - ], - "x-examples": [], - "x-filename": "Documents - arangod/RestHandler/RestDocumentHandler.cpp" - }, - "post": { - "description": "free style json body\n\nCreates a new document in the collection named collection. A JSON representation of the document must be passed as the body of the POST request.
If the document was created successfully, then the \"Location\" header contains the path to the newly created document. The \"ETag\" header field contains the revision of the document.
The body of the response contains a JSON object with the following attributes:
  • _id contains the document handle of the newly created document
  • _key contains the document key
  • _rev contains the document revision
If the collection parameter waitForSync is false, then the call returns as soon as the document has been accepted. It will not wait until the document has been synced to disk.
Optionally, the URL parameter waitForSync can be used to force synchronization of the document creation operation to disk even in case that the waitForSync flag had been disabled for the entire collection. Thus, the waitForSync URL parameter can be used to force synchronization of just this specific operations. To use this, set the waitForSync parameter to true. If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronization for collections that have a default waitForSync value of true.

Example: Create a document in a collection named products. Note that the revision identifier might or might not by equal to the auto-generated key.

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products <<EOF\n{ \"Hello\": \"World\" }\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\netag: \"708172231\"\nlocation: /_db/_system/_api/document/products/708172231\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/708172231\", \n  \"_rev\" : \"708172231\", \n  \"_key\" : \"708172231\" \n}\n

\n
Example: Create a document in a collection named products with a collection-level waitForSync value of false.

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products <<EOF\n{ \"Hello\": \"World\" }\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"707647943\"\nlocation: /_db/_system/_api/document/products/707647943\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/707647943\", \n  \"_rev\" : \"707647943\", \n  \"_key\" : \"707647943\" \n}\n

\n
Example: Create a document in a collection with a collection-level waitForSync value of false, but using the waitForSync URL parameter.

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products&waitForSync=true <<EOF\n{ \"Hello\": \"World\" }\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\netag: \"709220807\"\nlocation: /_db/_system/_api/document/products/709220807\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/709220807\", \n  \"_rev\" : \"709220807\", \n  \"_key\" : \"709220807\" \n}\n

\n
Example: Create a document in a new, named collection

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products&createCollection=true <<EOF\n{ \"Hello\": \"World\" }\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"708696519\"\nlocation: /_db/_system/_api/document/products/708696519\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/708696519\", \n  \"_rev\" : \"708696519\", \n  \"_key\" : \"708696519\" \n}\n

\n
Example: Unknown collection name

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products <<EOF\n{ \"Hello\": \"World\" }\nEOF\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'products' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n

\n
Example: Illegal document

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products <<EOF\n{ 1: \"World\" }\nEOF\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"expecting attribute name\", \n  \"code\" : 400, \n  \"errorNum\" : 600 \n}\n

\n
", - "parameters": [ - { - "description": "A JSON representation of the document.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - }, - { - "description": "The collection name.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "description": "If this parameter has a value of true or yes, then the collection is created if it does not yet exist. Other values will be ignored so the collection must be present for the operation to succeed.
Note: this flag is not supported in a cluster. Using it will result in an error.
", - "in": "query", - "name": "createCollection", - "required": false, - "type": "boolean" - }, - { - "description": "Wait until document has been synced to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - } - ], - "responses": { - "201": { - "description": "is returned if the document was created successfully and waitForSync was true.
" - }, - "202": { - "description": "is returned if the document was created successfully and waitForSync was false.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a document. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": "Create document", - "tags": [ - "Documents" - ], - "x-examples": [], - "x-filename": "Documents - arangod/RestHandler/RestDocumentHandler.cpp" - } - }, - "/_api/document/{document-handle}": { - "delete": { - "description": "\n\nThe body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the removed document, _key contains the key which uniquely identifies a document in a given collection, and the attribute _rev contains the new document revision.
If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronization for collections that have a default waitForSync value of true.

Example: Using document handle:

shell> curl -X DELETE --dump - http://localhost:8529/_api/document/products/700832199\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/700832199\", \n  \"_rev\" : \"700832199\", \n  \"_key\" : \"700832199\" \n}\n

\n
Example: Unknown document handle:

shell> curl -X DELETE --dump - http://localhost:8529/_api/document/products/702994887\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n

\n
Example: Revision conflict:

shell> curl -X DELETE --header 'If-Match: \"702339527\"' --dump - http://localhost:8529/_api/document/products/702011847\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"702011847\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/702011847\", \n  \"_rev\" : \"702011847\", \n  \"_key\" : \"702011847\" \n}\n

\n
", - "parameters": [ - { - "description": "Removes the document identified by document-handle.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "You can conditionally remove a document based on a target revision id by using the rev URL parameter.
", - "in": "query", - "name": "rev", - "required": false, - "type": "string" - }, - { - "description": "To control the update behavior in case there is a revision mismatch, you can use the policy parameter. This is the same as when replacing documents (see replacing documents for more details).
", - "in": "query", - "name": "policy", - "required": false, - "type": "string" - }, - { - "description": "Wait until deletion operation has been synced to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "You can conditionally remove a document based on a target revision id by using the if-match HTTP header.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the document was removed successfully and waitForSync was true.
" - }, - "202": { - "description": "is returned if the document was removed successfully and waitForSync was false.
" - }, - "404": { - "description": "is returned if the collection or the document was not found. The response body contains an error document in this case.
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the _rev attribute. Additionally, the attributes _id and _key will be returned.
" - } - }, - "summary": " Removes a document", - "tags": [ - "Documents" - ], - "x-examples": [], - "x-filename": "Documents - arangod/RestHandler/RestDocumentHandler.cpp" - }, - "get": { - "description": "\n\nReturns the document identified by document-handle. The returned document contains three special attributes: _id containing the document handle, _key containing key which uniquely identifies a document in a given collection and _rev containing the revision.

Example: Use a document handle:

shell> curl --dump - http://localhost:8529/_api/document/products/709745095\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"709745095\"\n\n{ \n  \"hello\" : \"world\", \n  \"_id\" : \"products/709745095\", \n  \"_rev\" : \"709745095\", \n  \"_key\" : \"709745095\" \n}\n

\n
Example: Use a document handle and an etag:

shell> curl --header 'If-None-Match: \"713415111\"' --dump - http://localhost:8529/_api/document/products/713415111\n\n

\n
Example: Unknown document handle:

shell> curl --dump - http://localhost:8529/_api/document/products/unknownhandle\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'products' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n

\n
", - "parameters": [ - { - "description": "The handle of the document.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "If the \"If-None-Match\" header is given, then it must contain exactly one etag. The document is returned, if it has a different revision than the given etag. Otherwise an HTTP 304 is returned.
", - "in": "header", - "name": "If-None-Match", - "type": "string" - }, - { - "description": "If the \"If-Match\" header is given, then it must contain exactly one etag. The document is returned, if it has the same revision as the given etag. Otherwise a HTTP 412 is returned. As an alternative you can supply the etag in an attribute rev in the URL.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the document was found
" - }, - "304": { - "description": "is returned if the \"If-None-Match\" header is given and the document has the same version
" - }, - "404": { - "description": "is returned if the document or collection was not found
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the _rev attribute. Additionally, the attributes _id and _key will be returned.
" - } - }, - "summary": "Read document", - "tags": [ - "Documents" - ], - "x-examples": [], - "x-filename": "Documents - arangod/RestHandler/RestDocumentHandler.cpp" - }, - "head": { - "description": "\n\nLike GET, but only returns the header fields and not the body. You can use this call to get the current revision of a document or check if the document was deleted.

Example:

shell> curl -X HEAD --dump - http://localhost:8529/_api/document/products/712825287\n\n

\n

", - "parameters": [ - { - "description": "The handle of the document.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "You can conditionally fetch a document based on a target revision id by using the rev URL parameter.
", - "in": "query", - "name": "rev", - "required": false, - "type": "string" - }, - { - "description": "If the \"If-None-Match\" header is given, then it must contain exactly one etag. If the current document revision is different to the specified etag, an HTTP 200 response is returned. If the current document revision is identical to the specified etag, then an HTTP 304 is returned.
", - "in": "header", - "name": "If-None-Match", - "type": "string" - }, - { - "description": "You can conditionally fetch a document based on a target revision id by using the if-match HTTP header.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the document was found
" - }, - "304": { - "description": "is returned if the \"If-None-Match\" header is given and the document has same version
" - }, - "404": { - "description": "is returned if the document or collection was not found
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the etag header.
" - } - }, - "summary": "Read document header", - "tags": [ - "Documents" - ], - "x-examples": [], - "x-filename": "Documents - arangod/RestHandler/RestDocumentHandler.cpp" - }, - "patch": { - "description": "free style json body\n\nPartially updates the document identified by document-handle. The body of the request must contain a JSON document with the attributes to patch (the patch document). All attributes from the patch document will be added to the existing document if they do not yet exist, and overwritten in the existing document if they do exist there.
Setting an attribute value to null in the patch document will cause a value of null be saved for the attribute by default.
Optionally, the URL parameter waitForSync can be used to force synchronization of the document update operation to disk even in case that the waitForSync flag had been disabled for the entire collection. Thus, the waitForSync URL parameter can be used to force synchronization of just specific operations. To use this, set the waitForSync parameter to true. If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronization for collections that have a default waitForSync value of true.
The body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the updated document, _key contains the key which uniquely identifies a document in a given collection, and the attribute _rev contains the new document revision.
If the document does not exist, then a HTTP 404 is returned and the body of the response contains an error document.
You can conditionally update a document based on a target revision id by using either the rev URL parameter or the if-match HTTP header. To control the update behavior in case there is a revision mismatch, you can use the policy parameter. This is the same as when replacing documents (see replacing documents for details).

Example: patches an existing document with new content.

shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/703846855 <<EOF\n{ \n  \"hello\" : \"world\" \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"704174535\"\nlocation: /_db/_system/_api/document/products/703846855\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/703846855\", \n  \"_rev\" : \"704174535\", \n  \"_key\" : \"703846855\" \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/703846855 <<EOF\n{ \n  \"numbers\" : { \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3, \n    \"empty\" : null \n  } \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"704764359\"\nlocation: /_db/_system/_api/document/products/703846855\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/703846855\", \n  \"_rev\" : \"704764359\", \n  \"_key\" : \"703846855\" \n}\nshell> curl --dump - http://localhost:8529/_api/document/products/703846855\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"704764359\"\n\n{ \n  \"one\" : \"world\", \n  \"hello\" : \"world\", \n  \"numbers\" : { \n    \"empty\" : null, \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3 \n  }, \n  \"_id\" : \"products/703846855\", \n  \"_rev\" : \"704764359\", \n  \"_key\" : \"703846855\" \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/703846855?keepNull=false <<EOF\n{ \n  \"hello\" : null, \n  \"numbers\" : { \n    \"four\" : 4 \n  } \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"705223111\"\nlocation: /_db/_system/_api/document/products/703846855\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/703846855\", \n  \"_rev\" : \"705223111\", \n  \"_key\" : \"703846855\" \n}\nshell> curl --dump - http://localhost:8529/_api/document/products/703846855\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"705223111\"\n\n{ \n  \"one\" : \"world\", \n  \"numbers\" : { \n    \"empty\" : null, \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3, \n    \"four\" : 4 \n  }, \n  \"_id\" : \"products/703846855\", \n  \"_rev\" : \"705223111\", \n  \"_key\" : \"703846855\" \n}\n

\n
Example: Merging attributes of an object using `mergeObjects`:

shell> curl --dump - http://localhost:8529/_api/document/products/706075079\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"706075079\"\n\n{ \n  \"inhabitants\" : { \n    \"china\" : 1366980000, \n    \"india\" : 1263590000, \n    \"usa\" : 319220000 \n  }, \n  \"_id\" : \"products/706075079\", \n  \"_rev\" : \"706075079\", \n  \"_key\" : \"706075079\" \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/706075079?mergeObjects=true <<EOF\n{ \n  \"inhabitants\" : { \n    \"indonesia\" : 252164800, \n    \"brazil\" : 203553000 \n  } \n}\nEOF\n\nshell> curl --dump - http://localhost:8529/_api/document/products/706075079\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"706599367\"\n\n{ \n  \"inhabitants\" : { \n    \"china\" : 1366980000, \n    \"india\" : 1263590000, \n    \"usa\" : 319220000, \n    \"indonesia\" : 252164800, \n    \"brazil\" : 203553000 \n  }, \n  \"_id\" : \"products/706075079\", \n  \"_rev\" : \"706599367\", \n  \"_key\" : \"706075079\" \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/706075079?mergeObjects=false <<EOF\n{ \n  \"inhabitants\" : { \n    \"pakistan\" : 188346000 \n  } \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"707058119\"\nlocation: /_db/_system/_api/document/products/706075079\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/706075079\", \n  \"_rev\" : \"707058119\", \n  \"_key\" : \"706075079\" \n}\nshell> curl --dump - http://localhost:8529/_api/document/products/706075079\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"707058119\"\n\n{ \n  \"inhabitants\" : { \n    \"pakistan\" : 188346000 \n  }, \n  \"_id\" : \"products/706075079\", \n  \"_rev\" : \"707058119\", \n  \"_key\" : \"706075079\" \n}\n

\n
", - "parameters": [ - { - "description": "A JSON representation of the document update.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - }, - { - "description": "The handle of the document.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "If the intention is to delete existing attributes with the patch command, the URL query parameter keepNull can be used with a value of false. This will modify the behavior of the patch command to remove any attributes from the existing document that are contained in the patch document with an attribute value of null.
", - "in": "query", - "name": "keepNull", - "required": false, - "type": "boolean" - }, - { - "description": "Controls whether objects (not arrays) will be merged if present in both the existing and the patch document. If set to false, the value in the patch document will overwrite the existing document's value. If set to true, objects will be merged. The default is true.
", - "in": "query", - "name": "mergeObjects", - "required": false, - "type": "boolean" - }, - { - "description": "Wait until document has been synced to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "You can conditionally patch a document based on a target revision id by using the rev URL parameter.
", - "in": "query", - "name": "rev", - "required": false, - "type": "string" - }, - { - "description": "To control the update behavior in case there is a revision mismatch, you can use the policy parameter.
", - "in": "query", - "name": "policy", - "required": false, - "type": "string" - }, - { - "description": "You can conditionally patch a document based on a target revision id by using the if-match HTTP header.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "201": { - "description": "is returned if the document was created successfully and waitForSync was true.
" - }, - "202": { - "description": "is returned if the document was created successfully and waitForSync was false.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a document. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection or the document was not found
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the _rev attribute. Additionally, the attributes _id and _key will be returned.
" - } - }, - "summary": " Patch document", - "tags": [ - "Documents" - ], - "x-examples": [], - "x-filename": "Documents - arangod/RestHandler/RestDocumentHandler.cpp" - }, - "put": { - "description": "free style json body\n\nCompletely updates (i.e. replaces) the document identified by document-handle. If the document exists and can be updated, then a HTTP 201 is returned and the \"ETag\" header field contains the new revision of the document.
If the new document passed in the body of the request contains the document-handle in the attribute _id and the revision in _rev, these attributes will be ignored. Only the URI and the \"ETag\" header are relevant in order to avoid confusion when using proxies.

Optionally, the URL parameter waitForSync can be used to force synchronization of the document replacement operation to disk even in case that the waitForSync flag had been disabled for the entire collection. Thus, the waitForSync URL parameter can be used to force synchronization of just specific operations. To use this, set the waitForSync parameter to true. If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronization for collections that have a default waitForSync value of true.

The body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the updated document, _key contains the key which uniquely identifies a document in a given collection, and the attribute _rev contains the new document revision.
If the document does not exist, then a HTTP 404 is returned and the body of the response contains an error document.
There are two ways for specifying the targeted document revision id for conditional replacements (i.e. replacements that will only be executed if the revision id found in the database matches the document revision id specified in the request):
  • specifying the target revision in the rev URL query parameter
  • specifying the target revision in the if-match HTTP header
    Specifying a target revision is optional, however, if done, only one of the described mechanisms must be used (either the rev URL parameter or the if-match HTTP header). Regardless which mechanism is used, the parameter needs to contain the target document revision id as returned in the _rev attribute of a document or by an HTTP etag header.
For example, to conditionally replace a document based on a specific revision id, you can use the following request:

`PUT /_api/document/document-handle?rev=etag`

If a target revision id is provided in the request (e.g. via the etag value in the rev URL query parameter above), ArangoDB will check that the revision id of the document found in the database is equal to the target revision id provided in the request. If there is a mismatch between the revision id, then by default a HTTP 412 conflict is returned and no replacement is performed.

The conditional update behavior can be overridden with the policy URL query parameter:

`PUT /_api/document/document-handle?policy=policy`

If policy is set to error, then the behavior is as before: replacements will fail if the revision id found in the database does not match the target revision id specified in the request.
If policy is set to last, then the replacement will succeed, even if the revision id found in the database does not match the target revision id specified in the request. You can use the last *policy* to force replacements.

Example: Using a document handle

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/714004935 <<EOF\n{\"Hello\": \"you\"}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"714332615\"\nlocation: /_db/_system/_api/document/products/714004935\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/714004935\", \n  \"_rev\" : \"714332615\", \n  \"_key\" : \"714004935\" \n}\n

\n
Example: Unknown document handle

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/718199239 <<EOF\n{}\nEOF\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n

\n
Example: Produce a revision conflict

shell> curl -X PUT --header 'If-Match: \"715184583\"' --data-binary @- --dump - http://localhost:8529/_api/document/products/714856903 <<EOF\n{\"other\":\"content\"}\nEOF\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"714856903\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/714856903\", \n  \"_rev\" : \"714856903\", \n  \"_key\" : \"714856903\" \n}\n

\n
Example: Last write wins

shell> curl -X PUT --header 'If-Match: \"716298695\"' --data-binary @- --dump - http://localhost:8529/_api/document/products/715971015?policy=last <<EOF\n{}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"716560839\"\nlocation: /_db/_system/_api/document/products/715971015\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/715971015\", \n  \"_rev\" : \"716560839\", \n  \"_key\" : \"715971015\" \n}\n

\n
Example: Alternative to header fields

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/717085127?rev=717412807 <<EOF\n{\"other\":\"content\"}\nEOF\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"717085127\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/717085127\", \n  \"_rev\" : \"717085127\", \n  \"_key\" : \"717085127\" \n}\n

\n
", - "parameters": [ - { - "description": "A JSON representation of the new document.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - }, - { - "description": "The handle of the document.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "Wait until document has been synced to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "You can conditionally replace a document based on a target revision id by using the rev URL parameter.
", - "in": "query", - "name": "rev", - "required": false, - "type": "string" - }, - { - "description": "To control the update behavior in case there is a revision mismatch, you can use the policy parameter (see below).
", - "in": "query", - "name": "policy", - "required": false, - "type": "string" - }, - { - "description": "You can conditionally replace a document based on a target revision id by using the if-match HTTP header.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "201": { - "description": "is returned if the document was replaced successfully and waitForSync was true.
" - }, - "202": { - "description": "is returned if the document was replaced successfully and waitForSync was false.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a document. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection or the document was not found
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the _rev attribute. Additionally, the attributes _id and _key will be returned.
" - } - }, - "summary": "Replace document", - "tags": [ - "Documents" - ], - "x-examples": [], - "x-filename": "Documents - arangod/RestHandler/RestDocumentHandler.cpp" - } - }, - "/_api/edge": { - "get": { - "description": "\n\nReturns an array of all URIs for all edges from the collection identified by collection.
", - "parameters": [ - { - "description": "The name of the collection.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "All went good.
" - }, - "404": { - "description": "The collection does not exist.
" - } - }, - "summary": " Read all edges from collection", - "tags": [ - "Graph edges" - ], - "x-examples": [], - "x-filename": "Graph edges - arangod/RestHandler/RestEdgeHandler.cpp, js/actions/api-edges.js" - }, - "post": { - "description": "free style json body\n\nCreates a new edge document in the collection named collection. A JSON representation of the document must be passed as the body of the POST request.
The from and to handles are immutable once the edge has been created.
In all other respects the method works like POST /document.

Example: Create an edge and read it back:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/edge/?collection=edges&from=vertices/1&to=vertices/2 <<EOF\n{ \n  \"name\" : \"Emil\" \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"721082823\"\nlocation: /_db/_system/_api/edge/edges/721082823\n\n{ \n  \"error\" : false, \n  \"_id\" : \"edges/721082823\", \n  \"_rev\" : \"721082823\", \n  \"_key\" : \"721082823\" \n}\nshell> curl --dump - http://localhost:8529/_api/edge/edges/721082823\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"721082823\"\n\n{ \n  \"name\" : \"Emil\", \n  \"_id\" : \"edges/721082823\", \n  \"_rev\" : \"721082823\", \n  \"_key\" : \"721082823\", \n  \"_from\" : \"vertices/1\", \n  \"_to\" : \"vertices/2\" \n}\n

\n
", - "parameters": [ - { - "description": "A JSON representation of the edge document must be passed as the body of the POST request. This JSON object may contain the edge's document key in the _key attribute if needed.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - }, - { - "description": "Creates a new edge in the collection identified by collection name.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "description": "If this parameter has a value of true or yes, then the collection is created if it does not yet exist. Other values will be ignored so the collection must be present for the operation to succeed.
Note: This flag is not supported in a cluster. Using it will result in an error.
", - "in": "query", - "name": "createCollection", - "required": false, - "type": "boolean" - }, - { - "description": "Wait until the edge document has been synced to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "The document handle of the start point must be passed in from handle.
", - "in": "query", - "name": "from", - "required": true, - "type": "string" - }, - { - "description": "The document handle of the end point must be passed in to handle.
", - "in": "query", - "name": "to", - "required": true, - "type": "string" - } - ], - "responses": { - "201": { - "description": "is returned if the edge was created successfully and waitForSync was true.
" - }, - "202": { - "description": "is returned if the edge was created successfully and waitForSync was false.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of an edge, or if the collection specified is not an edge collection. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": "Create edge", - "tags": [ - "Graph edges" - ], - "x-examples": [], - "x-filename": "Graph edges - arangod/RestHandler/RestEdgeHandler.cpp, js/actions/api-edges.js" - } - }, - "/_api/edge/{document-handle}": { - "delete": { - "description": "\n\nThe body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the deleted edge document, _key contains the key which uniquely identifies a document in a given collection, and the attribute _rev contains the new document revision.
If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronization for collections that have a default waitForSync value of true.
", - "parameters": [ - { - "description": "Deletes the edge document identified by document-handle.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "You can conditionally delete an edge document based on a target revision id by using the rev URL parameter.
", - "in": "query", - "name": "rev", - "required": false, - "type": "string" - }, - { - "description": "To control the update behavior in case there is a revision mismatch, you can use the policy parameter. This is the same as when replacing edge documents (see replacing edge documents for more details).
", - "in": "query", - "name": "policy", - "required": false, - "type": "string" - }, - { - "description": "Wait until edge document has been synced to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "You can conditionally delete an edge document based on a target revision id by using the if-match HTTP header.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the edge document was deleted successfully and waitForSync was true.
" - }, - "202": { - "description": "is returned if the edge document was deleted successfully and waitForSync was false.
" - }, - "404": { - "description": "is returned if the collection or the edge document was not found. The response body contains an error document in this case.
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the _rev attribute. Additionally, the attributes _id and _key will be returned.
" - } - }, - "summary": " Deletes edge", - "tags": [ - "Graph edges" - ], - "x-examples": [], - "x-filename": "Graph edges - arangod/RestHandler/RestEdgeHandler.cpp, js/actions/api-edges.js" - }, - "get": { - "description": "\n\nReturns the edge identified by document-handle. The returned edge contains a few special attributes:
  • _id contains the document handle
  • _rev contains the revision
  • _from and to contain the document handles of the connected vertex documents
", - "parameters": [ - { - "description": "The handle of the edge document.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "If the \"If-None-Match\" header is given, then it must contain exactly one etag. The edge is returned if it has a different revision than the given etag. Otherwise an HTTP 304 is returned.
", - "in": "header", - "name": "If-None-Match", - "type": "string" - }, - { - "description": "If the \"If-Match\" header is given, then it must contain exactly one etag. The edge is returned if it has the same revision ad the given etag. Otherwise a HTTP 412 is returned. As an alternative you can supply the etag in an attribute rev in the URL.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the edge was found
" - }, - "304": { - "description": "is returned if the \"If-None-Match\" header is given and the edge has the same version
" - }, - "404": { - "description": "is returned if the edge or collection was not found
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the _rev attribute. Additionally, the attributes _id and _key will be returned.
" - } - }, - "summary": " Read edge", - "tags": [ - "Graph edges" - ], - "x-examples": [], - "x-filename": "Graph edges - arangod/RestHandler/RestEdgeHandler.cpp, js/actions/api-edges.js" - }, - "head": { - "description": "\n\nLike GET, but only returns the header fields and not the body. You can use this call to get the current revision of an edge document or check if it was deleted.
", - "parameters": [ - { - "description": "The handle of the edge document.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "You can conditionally fetch an edge document based on a target revision id by using the rev URL parameter.
", - "in": "query", - "name": "rev", - "required": false, - "type": "string" - }, - { - "description": "If the \"If-None-Match\" header is given, then it must contain exactly one etag. If the current document revision is different to the specified etag, an HTTP 200 response is returned. If the current document revision is identical to the specified etag, then an HTTP 304 is returned.
", - "in": "header", - "name": "If-None-Match", - "type": "string" - }, - { - "description": "You can conditionally fetch an edge document based on a target revision id by using the if-match HTTP header.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the edge document was found
" - }, - "304": { - "description": "is returned if the \"If-None-Match\" header is given and the edge document has same version
" - }, - "404": { - "description": "is returned if the edge document or collection was not found
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the etag header.
" - } - }, - "summary": " Read edge header", - "tags": [ - "Graph edges" - ], - "x-examples": [], - "x-filename": "Graph edges - arangod/RestHandler/RestEdgeHandler.cpp, js/actions/api-edges.js" - }, - "patch": { - "description": "free style json body\n\nPartially updates the edge document identified by document-handle. The body of the request must contain a JSON document with the attributes to patch (the patch document). All attributes from the patch document will be added to the existing edge document if they do not yet exist, and overwritten in the existing edge document if they do exist there.
Setting an attribute value to null in the patch document will cause a value of null be saved for the attribute by default.
Note: Internal attributes such as _key, _from and _to are immutable once set and cannot be updated.
Optionally, the URL parameter waitForSync can be used to force synchronization of the edge document update operation to disk even in case that the waitForSync flag had been disabled for the entire collection. Thus, the waitForSync URL parameter can be used to force synchronization of just specific operations. To use this, set the waitForSync parameter to true. If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronization for collections that have a default waitForSync value of true.
The body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the updated edge document, _key contains the key which uniquely identifies a document in a given collection, and the attribute _rev contains the new document revision.
If the edge document does not exist, then a HTTP 404 is returned and the body of the response contains an error document.
You can conditionally update an edge document based on a target revision id by using either the rev URL parameter or the if-match HTTP header. To control the update behavior in case there is a revision mismatch, you can use the policy parameter. This is the same as when replacing edge documents (see replacing documents for details).
", - "parameters": [ - { - "description": "A JSON representation of the edge update.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - }, - { - "description": "The handle of the edge document.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "If the intention is to delete existing attributes with the patch command, the URL query parameter keepNull can be used with a value of false. This will modify the behavior of the patch command to remove any attributes from the existing edge document that are contained in the patch document with an attribute value of null.
", - "in": "query", - "name": "keepNull", - "required": false, - "type": "boolean" - }, - { - "description": "Controls whether objects (not arrays) will be merged if present in both the existing and the patch edge. If set to false, the value in the patch edge will overwrite the existing edge's value. If set to true, objects will be merged. The default is true.
", - "in": "query", - "name": "mergeObjects", - "required": false, - "type": "boolean" - }, - { - "description": "Wait until edge document has been synced to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "You can conditionally patch an edge document based on a target revision id by using the rev URL parameter.
", - "in": "query", - "name": "rev", - "required": false, - "type": "string" - }, - { - "description": "To control the update behavior in case there is a revision mismatch, you can use the policy parameter.
", - "in": "query", - "name": "policy", - "required": false, - "type": "string" - }, - { - "description": "You can conditionally patch an edge document based on a target revision id by using the if-match HTTP header.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "201": { - "description": "is returned if the document was patched successfully and waitForSync was true.
" - }, - "202": { - "description": "is returned if the document was patched successfully and waitForSync was false.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation or when applied on an non-edge collection. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection or the edge document was not found
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the _rev attribute. Additionally, the attributes _id and _key will be returned.
" - } - }, - "summary": " Patches edge", - "tags": [ - "Graph edges" - ], - "x-examples": [], - "x-filename": "Graph edges - arangod/RestHandler/RestEdgeHandler.cpp, js/actions/api-edges.js" - }, - "put": { - "description": "free style json body\n\nCompletely updates (i.e. replaces) the edge document identified by document-handle. If the edge document exists and can be updated, then a HTTP 201 is returned and the \"ETag\" header field contains the new revision of the edge document.
If the new edge document passed in the body of the request contains the document-handle in the attribute _id and the revision in _rev, these attributes will be ignored. Only the URI and the \"ETag\" header are relevant in order to avoid confusion when using proxies. Note: The attributes _from and _to of an edge are immutable and cannot be updated either.
Optionally, the URL parameter waitForSync can be used to force synchronization of the edge document replacement operation to disk even in case that the waitForSync flag had been disabled for the entire collection. Thus, the waitForSync URL parameter can be used to force synchronization of just specific operations. To use this, set the waitForSync parameter to true. If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronization for collections that have a default waitForSync value of true.
The body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the updated edge document, _key contains the key which uniquely identifies a document in a given collection, and the attribute _rev contains the new document revision.
If the edge document does not exist, then a HTTP 404 is returned and the body of the response contains an error document.
There are two ways for specifying the targeted revision id for conditional replacements (i.e. replacements that will only be executed if the revision id found in the database matches the revision id specified in the request):
  • specifying the target revision in the rev URL query parameter
  • specifying the target revision in the if-match HTTP header
Specifying a target revision is optional, however, if done, only one of the described mechanisms must be used (either the rev URL parameter or the if-match HTTP header). Regardless which mechanism is used, the parameter needs to contain the target revision id as returned in the _rev attribute of an edge document or by an HTTP etag header.
For example, to conditionally replace an edge document based on a specific revision id, you can use the following request:
  • PUT /_api/document/document-handle?rev=etag
If a target revision id is provided in the request (e.g. via the etag value in the rev URL query parameter above), ArangoDB will check that the revision id of the edge document found in the database is equal to the target revision id provided in the request. If there is a mismatch between the revision id, then by default a HTTP 412 conflict is returned and no replacement is performed.
The conditional update behavior can be overridden with the policy URL query parameter:
  • PUT /_api/document/document-handle?policy=policy
If policy is set to error, then the behavior is as before: replacements will fail if the revision id found in the database does not match the target revision id specified in the request.
If policy is set to last, then the replacement will succeed, even if the revision id found in the database does not match the target revision id specified in the request. You can use the last *policy* to force replacements.
", - "parameters": [ - { - "description": "A JSON representation of the new edge data.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - }, - { - "description": "The handle of the edge document.
", - "format": "string", - "in": "path", - "name": "document-handle", - "required": true, - "type": "string" - }, - { - "description": "Wait until edge document has been synced to disk.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "You can conditionally replace an edge document based on a target revision id by using the rev URL parameter.
", - "in": "query", - "name": "rev", - "required": false, - "type": "string" - }, - { - "description": "To control the update behavior in case there is a revision mismatch, you can use the policy parameter (see below).
", - "in": "query", - "name": "policy", - "required": false, - "type": "string" - }, - { - "description": "You can conditionally replace an edge document based on a target revision id by using the if-match HTTP header.
", - "in": "header", - "name": "If-Match", - "type": "string" - } - ], - "responses": { - "201": { - "description": "is returned if the edge document was replaced successfully and waitForSync was true.
" - }, - "202": { - "description": "is returned if the edge document was replaced successfully and waitForSync was false.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of an edge document or if applied to a non-edge collection. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection or the edge document was not found
" - }, - "412": { - "description": "is returned if a \"If-Match\" header or rev is given and the found document has a different version. The response will also contain the found document's current revision in the _rev attribute. Additionally, the attributes _id and _key will be returned.
" - } - }, - "summary": "replaces an edge", - "tags": [ - "Graph edges" - ], - "x-examples": [], - "x-filename": "Graph edges - arangod/RestHandler/RestEdgeHandler.cpp, js/actions/api-edges.js" - } - }, - "/_api/edges/{collection-id}": { - "get": { - "description": "\n\nReturns an array of edges starting or ending in the vertex identified by vertex-handle.

Example: Any direction

shell> curl --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/6\", \n      \"_key\" : \"6\", \n      \"_rev\" : \"725211591\", \n      \"_from\" : \"vertices/2\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v2 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/7\", \n      \"_key\" : \"7\", \n      \"_rev\" : \"725735879\", \n      \"_from\" : \"vertices/4\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v4 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/5\", \n      \"_key\" : \"5\", \n      \"_rev\" : \"724687303\", \n      \"_from\" : \"vertices/1\", \n      \"_to\" : \"vertices/3\", \n      \"$label\" : \"v1 -> v3\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: In edges

shell> curl --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1&direction=in\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/6\", \n      \"_key\" : \"6\", \n      \"_rev\" : \"729930183\", \n      \"_from\" : \"vertices/2\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v2 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/7\", \n      \"_key\" : \"7\", \n      \"_rev\" : \"730454471\", \n      \"_from\" : \"vertices/4\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v4 -> v1\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Out edges

shell> curl --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1&direction=out\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/5\", \n      \"_key\" : \"5\", \n      \"_rev\" : \"734124487\", \n      \"_from\" : \"vertices/1\", \n      \"_to\" : \"vertices/3\", \n      \"$label\" : \"v1 -> v3\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The id of the collection.
", - "format": "string", - "in": "path", - "name": "collection-id", - "required": true, - "type": "string" - }, - { - "description": "The id of the start vertex.
", - "in": "query", - "name": "vertex", - "required": true, - "type": "string" - }, - { - "description": "Selects in or out direction for edges. If not set, any edges are returned.
", - "in": "query", - "name": "direction", - "required": false, - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the edge collection was found and edges were retrieved.
" - }, - "400": { - "description": "is returned if the request contains invalid parameters.
" - }, - "404": { - "description": "is returned if the edge collection was not found.
" - } - }, - "summary": " Read in- or outbound edges", - "tags": [ - "Graph edges" - ], - "x-examples": [], - "x-filename": "Graph edges - arangod/RestHandler/RestEdgeHandler.cpp, js/actions/api-edges.js" - } - }, - "/_api/endpoint": { - "get": { - "description": "\n\nReturns an array of all configured endpoints the server is listening on. For each endpoint, the array of allowed databases is returned too if set.
The result is a JSON object which has the endpoints as keys, and an array of mapped database names as values for each endpoint.
If an array of mapped databases is empty, it means that all databases can be accessed via the endpoint. If an array of mapped databases contains more than one database name, this means that any of the databases might be accessed via the endpoint, and the first database in the arry will be treated as the default database for the endpoint. The default database will be used when an incoming request does not specify a database name in the request explicitly.
Note: retrieving the array of all endpoints is allowed in the system database only. Calling this action in any other database will make the server return an error.

Example:

shell> curl --dump - http://localhost:8529/_api/endpoint\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  { \n    \"endpoint\" : \"tcp://127.0.0.1:32239\", \n    \"databases\" : [ ] \n  } \n]\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned when the array of endpoints can be determined successfully.
" - }, - "400": { - "description": "is returned if the action is not carried out in the system database.
" - }, - "405": { - "description": "The server will respond with HTTP 405 if an unsupported HTTP method is used.
" - } - }, - "summary": " Return list of all endpoints", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_api/explain": { - "post": { - "description": "**A json post document with these Properties is required:**
  • query: the query which you want explained; If the query references any bind variables, these must also be passed in the attribute bindVars. Additional options for the query can be passed in the options attribute.
  • options: Options for the query
    • optimizer.rules: an array of to-be-included or to-be-excluded optimizer rules can be put into this attribute, telling the optimizer to include or exclude specific rules. To disable a rule, prefix its name with a `-`, to enable a rule, prefix it with a `+`. There is also a pseudo-rule `all`, which will match all optimizer rules. of type string
    • maxNumberOfPlans: an optional maximum number of plans that the optimizer is allowed to generate. Setting this attribute to a low value allows to put a cap on the amount of work the optimizer does.
    • allPlans: if set to true, all possible execution plans will be returned. The default is false, meaning only the optimal plan will be returned.
  • bindVars: key/value pairs representing the bind values of type object
\n\n
To explain how an AQL query would be executed on the server, the query string can be sent to the server via an HTTP POST request. The server will then validate the query and create an execution plan for it. The execution plan will be returned, but the query will not be executed.
The execution plan that is returned by the server can be used to estimate the probable performance of the query. Though the actual performance will depend on many different factors, the execution plan normally can provide some rough estimates on the amount of work the server needs to do in order to actually run the query.
By default, the explain operation will return the optimal plan as chosen by the query optimizer The optimal plan is the plan with the lowest total estimated cost. The plan will be returned in the attribute plan of the response object. If the option allPlans is specified in the request, the result will contain all plans created by the optimizer. The plans will then be returned in the attribute plans.
The result will also contain an attribute warnings, which is an array of warnings that occurred during optimization or execution plan creation. Additionally, a stats attribute is contained in the result with some optimizer statistics.
Each plan in the result is a JSON object with the following attributes:
  • nodes: the array of execution nodes of the plan. The array of available node types can be found [here](../Aql/Optimizer.html)
  • estimatedCost: the total estimated cost for the plan. If there are multiple plans, the optimizer will choose the plan with the lowest total cost.
  • collections: an array of collections used in the query
  • rules: an array of rules the optimizer applied. An overview of the available rules can be found [here](../Aql/Optimizer.html)
  • variables: array of variables used in the query (note: this may contain internal variables created by the optimizer)

Example: Valid query

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain <<EOF\n{ \n  \"query\" : \"FOR p IN products RETURN p\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"nodes\" : [ \n      { \n        \"type\" : \"SingletonNode\", \n        \"dependencies\" : [ ], \n        \"id\" : 1, \n        \"estimatedCost\" : 1, \n        \"estimatedNrItems\" : 1 \n      }, \n      { \n        \"type\" : \"EnumerateCollectionNode\", \n        \"dependencies\" : [ \n          1 \n        ], \n        \"id\" : 2, \n        \"estimatedCost\" : 11, \n        \"estimatedNrItems\" : 10, \n        \"database\" : \"_system\", \n        \"collection\" : \"products\", \n        \"outVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        }, \n        \"random\" : false \n      }, \n      { \n        \"type\" : \"ReturnNode\", \n        \"dependencies\" : [ \n          2 \n        ], \n        \"id\" : 3, \n        \"estimatedCost\" : 21, \n        \"estimatedNrItems\" : 10, \n        \"inVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      } \n    ], \n    \"rules\" : [ ], \n    \"collections\" : [ \n      { \n        \"name\" : \"products\", \n        \"type\" : \"read\" \n      } \n    ], \n    \"variables\" : [ \n      { \n        \"id\" : 0, \n        \"name\" : \"p\" \n      } \n    ], \n    \"estimatedCost\" : 21, \n    \"estimatedNrItems\" : 10 \n  }, \n  \"warnings\" : [ ], \n  \"stats\" : { \n    \"rulesExecuted\" : 23, \n    \"rulesSkipped\" : 0, \n    \"plansCreated\" : 1 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: A plan with some optimizer rules applied

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain <<EOF\n{ \n  \"query\" : \"FOR p IN products LET a = p.id FILTER a == 4 LET name = p.name SORT p.id LIMIT 1 RETURN name\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"nodes\" : [ \n      { \n        \"type\" : \"SingletonNode\", \n        \"dependencies\" : [ ], \n        \"id\" : 1, \n        \"estimatedCost\" : 1, \n        \"estimatedNrItems\" : 1 \n      }, \n      { \n        \"type\" : \"IndexRangeNode\", \n        \"dependencies\" : [ \n          1 \n        ], \n        \"id\" : 11, \n        \"estimatedCost\" : 11, \n        \"estimatedNrItems\" : 10, \n        \"database\" : \"_system\", \n        \"collection\" : \"products\", \n        \"outVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        }, \n        \"ranges\" : [ \n          [ ] \n        ], \n        \"index\" : { \n          \"type\" : \"skiplist\", \n          \"id\" : \"737008071\", \n          \"unique\" : false, \n          \"sparse\" : false, \n          \"fields\" : [ \n            \"id\" \n          ] \n        }, \n        \"reverse\" : false \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          11 \n        ], \n        \"id\" : 3, \n        \"estimatedCost\" : 21, \n        \"estimatedNrItems\" : 10, \n        \"expression\" : { \n          \"type\" : \"attribute access\", \n          \"name\" : \"id\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"reference\", \n              \"name\" : \"p\", \n              \"id\" : 0 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 1, \n          \"name\" : \"a\" \n        }, \n        \"canThrow\" : false, \n        \"expressionType\" : \"attribute\" \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          3 \n        ], \n        \"id\" : 4, \n        \"estimatedCost\" : 31, \n        \"estimatedNrItems\" : 10, \n        \"expression\" : { \n          \"type\" : \"compare ==\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"reference\", \n              \"name\" : \"a\", \n              \"id\" : 1 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 4 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 4, \n          \"name\" : \"3\" \n        }, \n        \"canThrow\" : false, \n        \"expressionType\" : \"simple\" \n      }, \n      { \n        \"type\" : \"FilterNode\", \n        \"dependencies\" : [ \n          4 \n        ], \n        \"id\" : 5, \n        \"estimatedCost\" : 41, \n        \"estimatedNrItems\" : 10, \n        \"inVariable\" : { \n          \"id\" : 4, \n          \"name\" : \"3\" \n        } \n      }, \n      { \n        \"type\" : \"LimitNode\", \n        \"dependencies\" : [ \n          5 \n        ], \n        \"id\" : 9, \n        \"estimatedCost\" : 42, \n        \"estimatedNrItems\" : 1, \n        \"offset\" : 0, \n        \"limit\" : 1, \n        \"fullCount\" : false \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          9 \n        ], \n        \"id\" : 6, \n        \"estimatedCost\" : 43, \n        \"estimatedNrItems\" : 1, \n        \"expression\" : { \n          \"type\" : \"attribute access\", \n          \"name\" : \"name\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"reference\", \n              \"name\" : \"p\", \n              \"id\" : 0 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"name\" \n        }, \n        \"canThrow\" : false, \n        \"expressionType\" : \"attribute\" \n      }, \n      { \n        \"type\" : \"ReturnNode\", \n        \"dependencies\" : [ \n          6 \n        ], \n        \"id\" : 10, \n        \"estimatedCost\" : 44, \n        \"estimatedNrItems\" : 1, \n        \"inVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"name\" \n        } \n      } \n    ], \n    \"rules\" : [ \n      \"move-calculations-up\", \n      \"remove-redundant-calculations\", \n      \"move-calculations-up-2\", \n      \"use-index-for-sort\", \n      \"remove-unnecessary-calculations-2\", \n      \"move-calculations-down\" \n    ], \n    \"collections\" : [ \n      { \n        \"name\" : \"products\", \n        \"type\" : \"read\" \n      } \n    ], \n    \"variables\" : [ \n      { \n        \"id\" : 6, \n        \"name\" : \"5\" \n      }, \n      { \n        \"id\" : 4, \n        \"name\" : \"3\" \n      }, \n      { \n        \"id\" : 2, \n        \"name\" : \"name\" \n      }, \n      { \n        \"id\" : 1, \n        \"name\" : \"a\" \n      }, \n      { \n        \"id\" : 0, \n        \"name\" : \"p\" \n      } \n    ], \n    \"estimatedCost\" : 44, \n    \"estimatedNrItems\" : 1 \n  }, \n  \"warnings\" : [ ], \n  \"stats\" : { \n    \"rulesExecuted\" : 35, \n    \"rulesSkipped\" : 0, \n    \"plansCreated\" : 1 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using some options

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain <<EOF\n{ \n  \"query\" : \"FOR p IN products LET a = p.id FILTER a == 4 LET name = p.name SORT p.id LIMIT 1 RETURN name\", \n  \"options\" : { \n    \"maxNumberOfPlans\" : 2, \n    \"allPlans\" : true, \n    \"optimizer\" : { \n      \"rules\" : [ \n        \"-all\", \n        \"+use-index-for-sort\", \n        \"+use-index-range\" \n      ] \n    } \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plans\" : [ \n    { \n      \"nodes\" : [ \n        { \n          \"type\" : \"SingletonNode\", \n          \"dependencies\" : [ ], \n          \"id\" : 1, \n          \"estimatedCost\" : 1, \n          \"estimatedNrItems\" : 1 \n        }, \n        { \n          \"type\" : \"IndexRangeNode\", \n          \"dependencies\" : [ \n            1 \n          ], \n          \"id\" : 11, \n          \"estimatedCost\" : 11, \n          \"estimatedNrItems\" : 10, \n          \"database\" : \"_system\", \n          \"collection\" : \"products\", \n          \"outVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          }, \n          \"ranges\" : [ \n            [ ] \n          ], \n          \"index\" : { \n            \"type\" : \"skiplist\", \n            \"id\" : \"739563975\", \n            \"unique\" : false, \n            \"sparse\" : false, \n            \"fields\" : [ \n              \"id\" \n            ] \n          }, \n          \"reverse\" : false \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            11 \n          ], \n          \"id\" : 3, \n          \"estimatedCost\" : 21, \n          \"estimatedNrItems\" : 10, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"id\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"a\" \n          }, \n          \"canThrow\" : false, \n          \"expressionType\" : \"attribute\" \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            3 \n          ], \n          \"id\" : 4, \n          \"estimatedCost\" : 31, \n          \"estimatedNrItems\" : 10, \n          \"expression\" : { \n            \"type\" : \"compare ==\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"a\", \n                \"id\" : 1 \n              }, \n              { \n                \"type\" : \"value\", \n                \"value\" : 4 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 4, \n            \"name\" : \"3\" \n          }, \n          \"canThrow\" : false, \n          \"expressionType\" : \"simple\" \n        }, \n        { \n          \"type\" : \"FilterNode\", \n          \"dependencies\" : [ \n            4 \n          ], \n          \"id\" : 5, \n          \"estimatedCost\" : 41, \n          \"estimatedNrItems\" : 10, \n          \"inVariable\" : { \n            \"id\" : 4, \n            \"name\" : \"3\" \n          } \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            5 \n          ], \n          \"id\" : 6, \n          \"estimatedCost\" : 51, \n          \"estimatedNrItems\" : 10, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"name\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 2, \n            \"name\" : \"name\" \n          }, \n          \"canThrow\" : false, \n          \"expressionType\" : \"attribute\" \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            6 \n          ], \n          \"id\" : 7, \n          \"estimatedCost\" : 61, \n          \"estimatedNrItems\" : 10, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"id\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 6, \n            \"name\" : \"5\" \n          }, \n          \"canThrow\" : false, \n          \"expressionType\" : \"attribute\" \n        }, \n        { \n          \"type\" : \"LimitNode\", \n          \"dependencies\" : [ \n            7 \n          ], \n          \"id\" : 9, \n          \"estimatedCost\" : 62, \n          \"estimatedNrItems\" : 1, \n          \"offset\" : 0, \n          \"limit\" : 1, \n          \"fullCount\" : false \n        }, \n        { \n          \"type\" : \"ReturnNode\", \n          \"dependencies\" : [ \n            9 \n          ], \n          \"id\" : 10, \n          \"estimatedCost\" : 63, \n          \"estimatedNrItems\" : 1, \n          \"inVariable\" : { \n            \"id\" : 2, \n            \"name\" : \"name\" \n          } \n        } \n      ], \n      \"rules\" : [ \n        \"use-index-for-sort\" \n      ], \n      \"collections\" : [ \n        { \n          \"name\" : \"products\", \n          \"type\" : \"read\" \n        } \n      ], \n      \"variables\" : [ \n        { \n          \"id\" : 6, \n          \"name\" : \"5\" \n        }, \n        { \n          \"id\" : 4, \n          \"name\" : \"3\" \n        }, \n        { \n          \"id\" : 2, \n          \"name\" : \"name\" \n        }, \n        { \n          \"id\" : 1, \n          \"name\" : \"a\" \n        }, \n        { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      ], \n      \"estimatedCost\" : 63, \n      \"estimatedNrItems\" : 1 \n    } \n  ], \n  \"warnings\" : [ ], \n  \"stats\" : { \n    \"rulesExecuted\" : 4, \n    \"rulesSkipped\" : 31, \n    \"plansCreated\" : 1 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Returning all plans

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain <<EOF\n{ \n  \"query\" : \"FOR p IN products FILTER p.id == 25 RETURN p\", \n  \"options\" : { \n    \"allPlans\" : true \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plans\" : [ \n    { \n      \"nodes\" : [ \n        { \n          \"type\" : \"SingletonNode\", \n          \"dependencies\" : [ ], \n          \"id\" : 1, \n          \"estimatedCost\" : 1, \n          \"estimatedNrItems\" : 1 \n        }, \n        { \n          \"type\" : \"IndexRangeNode\", \n          \"dependencies\" : [ \n            1 \n          ], \n          \"id\" : 6, \n          \"estimatedCost\" : 1.9899995050000001, \n          \"estimatedNrItems\" : 1, \n          \"database\" : \"_system\", \n          \"collection\" : \"products\", \n          \"outVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          }, \n          \"ranges\" : [ \n            [ \n              { \n                \"variable\" : \"p\", \n                \"attr\" : \"id\", \n                \"lowConst\" : { \n                  \"bound\" : 25, \n                  \"include\" : true, \n                  \"isConstant\" : true \n                }, \n                \"highConst\" : { \n                  \"bound\" : 25, \n                  \"include\" : true, \n                  \"isConstant\" : true \n                }, \n                \"lows\" : [ ], \n                \"highs\" : [ ], \n                \"valid\" : true, \n                \"equality\" : true \n              } \n            ] \n          ], \n          \"index\" : { \n            \"type\" : \"hash\", \n            \"id\" : \"736025031\", \n            \"unique\" : false, \n            \"sparse\" : false, \n            \"selectivityEstimate\" : 1, \n            \"fields\" : [ \n              \"id\" \n            ] \n          }, \n          \"reverse\" : false \n        }, \n        { \n          \"type\" : \"ReturnNode\", \n          \"dependencies\" : [ \n            6 \n          ], \n          \"id\" : 5, \n          \"estimatedCost\" : 2.989999505, \n          \"estimatedNrItems\" : 1, \n          \"inVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          } \n        } \n      ], \n      \"rules\" : [ \n        \"use-index-range\", \n        \"remove-filter-covered-by-index\" \n      ], \n      \"collections\" : [ \n        { \n          \"name\" : \"products\", \n          \"type\" : \"read\" \n        } \n      ], \n      \"variables\" : [ \n        { \n          \"id\" : 2, \n          \"name\" : \"1\" \n        }, \n        { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      ], \n      \"estimatedCost\" : 2.989999505, \n      \"estimatedNrItems\" : 1 \n    } \n  ], \n  \"warnings\" : [ ], \n  \"stats\" : { \n    \"rulesExecuted\" : 23, \n    \"rulesSkipped\" : 0, \n    \"plansCreated\" : 1 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: A query that produces a warning

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain <<EOF\n{ \n  \"query\" : \"FOR i IN 1..10 RETURN 1 / 0\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"nodes\" : [ \n      { \n        \"type\" : \"SingletonNode\", \n        \"dependencies\" : [ ], \n        \"id\" : 1, \n        \"estimatedCost\" : 1, \n        \"estimatedNrItems\" : 1 \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          1 \n        ], \n        \"id\" : 2, \n        \"estimatedCost\" : 2, \n        \"estimatedNrItems\" : 1, \n        \"expression\" : { \n          \"type\" : \"range\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"value\", \n              \"value\" : 1 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 10 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"1\" \n        }, \n        \"canThrow\" : false, \n        \"expressionType\" : \"simple\" \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          2 \n        ], \n        \"id\" : 4, \n        \"estimatedCost\" : 3, \n        \"estimatedNrItems\" : 1, \n        \"expression\" : { \n          \"type\" : \"value\", \n          \"value\" : null \n        }, \n        \"outVariable\" : { \n          \"id\" : 4, \n          \"name\" : \"3\" \n        }, \n        \"canThrow\" : false, \n        \"expressionType\" : \"json\" \n      }, \n      { \n        \"type\" : \"EnumerateListNode\", \n        \"dependencies\" : [ \n          4 \n        ], \n        \"id\" : 3, \n        \"estimatedCost\" : 13, \n        \"estimatedNrItems\" : 10, \n        \"inVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"1\" \n        }, \n        \"outVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"i\" \n        } \n      }, \n      { \n        \"type\" : \"ReturnNode\", \n        \"dependencies\" : [ \n          3 \n        ], \n        \"id\" : 5, \n        \"estimatedCost\" : 23, \n        \"estimatedNrItems\" : 10, \n        \"inVariable\" : { \n          \"id\" : 4, \n          \"name\" : \"3\" \n        } \n      } \n    ], \n    \"rules\" : [ \n      \"move-calculations-up\", \n      \"move-calculations-up-2\" \n    ], \n    \"collections\" : [ ], \n    \"variables\" : [ \n      { \n        \"id\" : 4, \n        \"name\" : \"3\" \n      }, \n      { \n        \"id\" : 2, \n        \"name\" : \"1\" \n      }, \n      { \n        \"id\" : 0, \n        \"name\" : \"i\" \n      } \n    ], \n    \"estimatedCost\" : 23, \n    \"estimatedNrItems\" : 10 \n  }, \n  \"warnings\" : [ \n    { \n      \"code\" : 1562, \n      \"message\" : \"division by zero\" \n    } \n  ], \n  \"stats\" : { \n    \"rulesExecuted\" : 23, \n    \"rulesSkipped\" : 0, \n    \"plansCreated\" : 1 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Invalid query (missing bind parameter)

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain <<EOF\n{ \n  \"query\" : \"FOR p IN products FILTER p.id == @id LIMIT 2 RETURN p.n\" \n}\nEOF\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1551, \n  \"errorMessage\" : \"no value specified for declared bind parameter 'id' (while parsing)\" \n}\n

\n
Example: The data returned in the plan attribute of the result contains one element per AQL top-level statement (i.e. FOR, RETURN, FILTER etc.). If the query optimizer removed some unnecessary statements, the result might also contain less elements than there were top-level statements in the AQL query. The following example shows a query with a non-sensible filter condition that the optimizer has removed so that there are less top-level statements.

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain <<EOF\n{ \"query\" : \"FOR i IN [ 1, 2, 3 ] FILTER 1 == 2 RETURN i\" }\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"nodes\" : [ \n      { \n        \"type\" : \"SingletonNode\", \n        \"dependencies\" : [ ], \n        \"id\" : 1, \n        \"estimatedCost\" : 1, \n        \"estimatedNrItems\" : 1 \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          1 \n        ], \n        \"id\" : 2, \n        \"estimatedCost\" : 2, \n        \"estimatedNrItems\" : 1, \n        \"expression\" : { \n          \"type\" : \"array\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"value\", \n              \"value\" : 1 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 2 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 3 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"1\" \n        }, \n        \"canThrow\" : false, \n        \"expressionType\" : \"json\" \n      }, \n      { \n        \"type\" : \"NoResultsNode\", \n        \"dependencies\" : [ \n          2 \n        ], \n        \"id\" : 7, \n        \"estimatedCost\" : 0.5, \n        \"estimatedNrItems\" : 0 \n      }, \n      { \n        \"type\" : \"EnumerateListNode\", \n        \"dependencies\" : [ \n          7 \n        ], \n        \"id\" : 3, \n        \"estimatedCost\" : 0.5, \n        \"estimatedNrItems\" : 0, \n        \"inVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"1\" \n        }, \n        \"outVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"i\" \n        } \n      }, \n      { \n        \"type\" : \"ReturnNode\", \n        \"dependencies\" : [ \n          3 \n        ], \n        \"id\" : 6, \n        \"estimatedCost\" : 0.5, \n        \"estimatedNrItems\" : 0, \n        \"inVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"i\" \n        } \n      } \n    ], \n    \"rules\" : [ \n      \"move-calculations-up\", \n      \"move-filters-up\", \n      \"remove-unnecessary-filters\", \n      \"remove-unnecessary-calculations\" \n    ], \n    \"collections\" : [ ], \n    \"variables\" : [ \n      { \n        \"id\" : 4, \n        \"name\" : \"3\" \n      }, \n      { \n        \"id\" : 2, \n        \"name\" : \"1\" \n      }, \n      { \n        \"id\" : 0, \n        \"name\" : \"i\" \n      } \n    ], \n    \"estimatedCost\" : 0.5, \n    \"estimatedNrItems\" : 0 \n  }, \n  \"warnings\" : [ ], \n  \"stats\" : { \n    \"rulesExecuted\" : 23, \n    \"rulesSkipped\" : 0, \n    \"plansCreated\" : 1 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_explain" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the query is valid, the server will respond with HTTP 200 and return the optimal execution plan in the plan attribute of the response. If option allPlans was set in the request, an array of plans will be returned in the allPlans attribute instead.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request, or if the query contains a parse error. The body of the response will contain the error details embedded in a JSON object. Omitting bind variables if the query references any will also result in an HTTP 400 error.
" - }, - "404": { - "description": "The server will respond with HTTP 404 in case a non-existing collection is accessed in the query.
" - } - }, - "summary": " Explain an AQL query", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/export": { - "post": { - "description": "**A json post document with these Properties is required:**
  • count: boolean flag that indicates whether the number of documents in the result set should be returned in the \"count\" attribute of the result (optional). Calculating the \"count\" attribute might in the future have a performance impact so this option is turned off by default, and \"count\" is only returned when requested.
  • restrict: an object containing an array of attribute names that will be included or excluded when returning result documents.
    Not specifying restrict will by default return all attributes of each document.
    • fields: Contains an array of attribute names to include or exclude. Matching of attribute names for inclusion or exclusion will be done on the top level only. Specifying names of nested attributes is not supported at the moment.
      of type string
    • type: has to be be set to either include or exclude depending on which you want to use
  • batchSize: maximum number of result documents to be transferred from the server to the client in one roundtrip (optional). If this attribute is not set, a server-controlled default value will be used.
  • flush: if set to true, a WAL flush operation will be executed prior to the export. The flush operation will start copying documents from the WAL to the collection's datafiles. There will be an additional wait time of up to flushWait seconds after the flush to allow the WAL collector to change the adjusted document meta-data to point into the datafiles, too. The default value is false (i.e. no flush) so most recently inserted or updated documents from the collection might be missing in the export.
  • flushWait: maximum wait time in seconds after a flush operation. The default value is 10. This option only has an effect when flush is set to true.
  • limit: an optional limit value, determining the maximum number of documents to be included in the cursor. Omitting the limit attribute or setting it to 0 will lead to no limit being used. If a limit is used, it is undefined which documents from the collection will be included in the export and which will be excluded. This is because there is no natural order of documents in a collection.
  • ttl: an optional time-to-live for the cursor (in seconds). The cursor will be removed on the server automatically after the specified amount of time. This is useful to ensure garbage collection of cursors that are not fully fetched by clients. If not set, a server-defined value will be used.
\n\nA call to this method creates a cursor containing all documents in the specified collection. In contrast to other data-producing APIs, the internal data structures produced by the export API are more lightweight, so it is the preferred way to retrieve all documents from a collection.
Documents are returned in a similar manner as in the `/_api/cursor` REST API. If all documents of the collection fit into the first batch, then no cursor will be created, and the result object's hasMore attribute will be set to false. If not all documents fit into the first batch, then the result object's hasMore attribute will be set to true, and the id attribute of the result will contain a cursor id.
The order in which the documents are returned is not specified.
By default, only those documents from the collection will be returned that are stored in the collection's datafiles. Documents that are present in the write-ahead log (WAL) at the time the export is run will not be exported.
To export these documents as well, the caller can issue a WAL flush request before calling the export API or set the flush attribute. Setting the flush option will trigger a WAL flush before the export so documents get copied from the WAL to the collection datafiles.
If the result set can be created by the server, the server will respond with HTTP 201. The body of the response will contain a JSON object with the result set.
The returned JSON object has the following properties:
  • error: boolean flag to indicate that an error occurred (false in this case)
  • code: the HTTP status code
  • result: an array of result documents (might be empty if the collection was empty)
  • hasMore: a boolean indicator whether there are more results available for the cursor on the server
  • count: the total number of result documents available (only available if the query was executed with the count attribute set)
  • id: id of temporary cursor created on the server (optional, see above)
If the JSON representation is malformed or the query specification is missing from the request, the server will respond with HTTP 400.
The body of the response will contain a JSON object with additional error details. The object has the following attributes:
  • error: boolean flag to indicate that an error occurred (true in this case)
  • code: the HTTP status code
  • errorNum: the server error number
  • errorMessage: a descriptive error message
Clients should always delete an export cursor result as early as possible because a lingering export cursor will prevent the underlying collection from being compacted or unloaded. By default, unused cursors will be deleted automatically after a server-defined idle time, and clients can adjust this idle time by setting the ttl value.
Note: this API is currently not supported on cluster coordinators.
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_export" - }, - "x-description-offset": 59 - }, - { - "description": "The name of the collection to export.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - } - ], - "responses": { - "201": { - "description": "is returned if the result set can be created by the server.
" - }, - "400": { - "description": "is returned if the JSON representation is malformed or the query specification is missing from the request.
" - }, - "404": { - "description": "The server will respond with HTTP 404 in case a non-existing collection is accessed in the query.
" - }, - "405": { - "description": "The server will respond with HTTP 405 if an unsupported HTTP method is used.
" - }, - "501": { - "description": "The server will respond with HTTP 501 if this API is called on a cluster coordinator.

" - } - }, - "summary": " Create export cursor", - "tags": [ - "Bulk" - ], - "x-examples": [], - "x-filename": "Bulk - arangod/RestHandler/RestExportHandler.cpp, arangod/RestHandler/RestImportHandler.cpp, arangod/RestHandler/RestBatchHandler.cpp" - } - }, - "/_api/gharial": { - "get": { - "description": "\n\nLists all graph names stored in this database.

Example:

shell> curl --dump - http://localhost:8529/_api/gharial\n\nHTTP/1.1 200 OK\ncontent-type: application/json\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"graphs\" : [ \n    { \n      \"_id\" : \"_graphs/social\", \n      \"_key\" : \"social\", \n      \"_rev\" : \"557308359\", \n      \"edgeDefinitions\" : [ \n        { \n          \"collection\" : \"relation\", \n          \"from\" : [ \n            \"female\", \n            \"male\" \n          ], \n          \"to\" : [ \n            \"female\", \n            \"male\" \n          ] \n        } \n      ], \n      \"orphanCollections\" : [ ] \n    }, \n    { \n      \"_id\" : \"_graphs/routeplanner\", \n      \"_key\" : \"routeplanner\", \n      \"_rev\" : \"560650695\", \n      \"orphanCollections\" : [ ], \n      \"edgeDefinitions\" : [ \n        { \n          \"collection\" : \"germanHighway\", \n          \"from\" : [ \n            \"germanCity\" \n          ], \n          \"to\" : [ \n            \"germanCity\" \n          ] \n        }, \n        { \n          \"collection\" : \"frenchHighway\", \n          \"from\" : [ \n            \"frenchCity\" \n          ], \n          \"to\" : [ \n            \"frenchCity\" \n          ] \n        }, \n        { \n          \"collection\" : \"internationalHighway\", \n          \"from\" : [ \n            \"frenchCity\", \n            \"germanCity\" \n          ], \n          \"to\" : [ \n            \"frenchCity\", \n            \"germanCity\" \n          ] \n        } \n      ] \n    } \n  ] \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned if the module is available and the graphs could be listed.
" - } - }, - "summary": " List all graphs", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "post": { - "description": "\n\nThe creation of a graph requires the name of the graph and a definition of its edges. [See also edge definitions](../GeneralGraphs/Management.md#edge-definitions).
**A json post document with these Properties is required:**
  • orphanCollections: An array of additional vertex collections.
  • edgeDefinitions: An array of definitions for the edge
  • name: Name of the graph.

Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/gharial <<EOF\n{ \n  \"name\" : \"myGraph\", \n  \"edgeDefinitions\" : [ \n    { \n      \"collection\" : \"edges\", \n      \"from\" : [ \n        \"startVertices\" \n      ], \n      \"to\" : [ \n        \"endVertices\" \n      ] \n    } \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json\netag: 527817159\n\n{ \n  \"error\" : false, \n  \"code\" : 201, \n  \"graph\" : { \n    \"name\" : \"myGraph\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"edges\", \n        \"from\" : [ \n          \"startVertices\" \n        ], \n        \"to\" : [ \n          \"endVertices\" \n        ] \n      } \n    ], \n    \"orphanCollections\" : [ ], \n    \"_id\" : \"_graphs/myGraph\", \n    \"_rev\" : \"527817159\" \n  } \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_general_graph_create_http_examples" - }, - "x-description-offset": 229 - } - ], - "responses": { - "201": { - "description": "Is returned if the graph could be created. The body contains the graph configuration that has been stored.
" - }, - "409": { - "description": "Returned if there is a conflict storing the graph. This can occur either if a graph with this name is already stored, or if there is one edge definition with a the same [edge collection](../Glossary/index.html#edge_collection) but a different signature used in any other graph.
" - } - }, - "summary": " Create a graph", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/gharial/{graph-name}": { - "delete": { - "description": "\n\nRemoves a graph from the collection \\_graphs.

Example:

shell> curl -X DELETE --dump - http://localhost:8529/_api/gharial/social\n\nHTTP/1.1 200 OK\ncontent-type: application/json\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"removed\" : true \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Returned if the graph could be dropped.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " Drop a graph", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "get": { - "description": "\n\nGets a graph from the collection \\_graphs. Returns the definition content of this graph.

Example:

shell> curl --dump - http://localhost:8529/_api/gharial/myGraph\n\nHTTP/1.1 200 OK\ncontent-type: application/json\netag: 552131015\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"graph\" : { \n    \"name\" : \"myGraph\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"edges\", \n        \"from\" : [ \n          \"startVertices\" \n        ], \n        \"to\" : [ \n          \"endVertices\" \n        ] \n      } \n    ], \n    \"orphanCollections\" : [ ], \n    \"_id\" : \"_graphs/myGraph\", \n    \"_rev\" : \"552131015\" \n  } \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Returned if the graph could be found.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " Get a graph", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/gharial/{graph-name}/edge": { - "get": { - "description": "\n\nLists all edge collections within this graph.

Example:

shell> curl --dump - http://localhost:8529/_api/gharial/social/edge\n\nHTTP/1.1 200 OK\ncontent-type: application/json\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"collections\" : [ \n    \"relation\" \n  ] \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned if the edge definitions could be listed.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " List edge definitions", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "post": { - "description": "\n\nAdds an additional edge definition to the graph. This edge definition has to contain a collection and an array of each from and to vertex collections. An edge definition can only be added if this definition is either not used in any other graph, or it is used with exactly the same definition. It is not possible to store a definition \"e\" from \"v1\" to \"v2\" in the one graph, and \"e\" from \"v2\" to \"v1\" in the other graph.
**A json post document with these Properties is required:**
  • to: One or many edge collections that can contain target vertices. of type string
  • from: One or many vertex collections that can contain source vertices. of type string
  • collection: The name of the edge collection to be used.

Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/gharial/social/edge <<EOF\n{ \n  \"collection\" : \"lives_in\", \n  \"from\" : [ \n    \"female\", \n    \"male\" \n  ], \n  \"to\" : [ \n    \"city\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json\netag: 514972103\n\n{ \n  \"error\" : false, \n  \"code\" : 201, \n  \"graph\" : { \n    \"name\" : \"social\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"relation\", \n        \"from\" : [ \n          \"female\", \n          \"male\" \n        ], \n        \"to\" : [ \n          \"female\", \n          \"male\" \n        ] \n      }, \n      { \n        \"collection\" : \"lives_in\", \n        \"from\" : [ \n          \"female\", \n          \"male\" \n        ], \n        \"to\" : [ \n          \"city\" \n        ] \n      } \n    ], \n    \"orphanCollections\" : [ ], \n    \"_id\" : \"_graphs/social\", \n    \"_rev\" : \"514972103\" \n  } \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_general_graph_edge_definition_add_http_examples" - }, - "x-description-offset": 537 - } - ], - "responses": { - "200": { - "description": "Returned if the definition could be added successfully.
" - }, - "400": { - "description": "Returned if the defininition could not be added, the edge collection is used in an other graph with a different signature.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " Add edge definition", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/gharial/{graph-name}/edge/{collection-name}": { - "post": { - "description": "\n\nCreates a new edge in the collection. Within the body the has to contain a \\_from and \\_to value referencing to valid vertices in the graph. Furthermore the edge has to be valid in the definition of this [edge collection](../Glossary/index.html#edge_collection).
free style json body
Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/gharial/social/edge/relation <<EOF\n{ \n  \"type\" : \"friend\", \n  \"_from\" : \"female/alice\", \n  \"_to\" : \"female/diana\" \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json\netag: 513464775\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"edge\" : { \n    \"_id\" : \"relation/513464775\", \n    \"_rev\" : \"513464775\", \n    \"_key\" : \"513464775\" \n  } \n}\n

\n
", - "parameters": [ - { - "description": "The body has to be the JSON object to be stored.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 303 - } - ], - "responses": { - "201": { - "description": "Returned if the edge could be created.
" - }, - "202": { - "description": "Returned if the request was successful but waitForSync is false.
" - }, - "404": { - "description": "Returned if no graph with this name, no edge collection or no edge with this id could be found.
" - } - }, - "summary": " Create an edge", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/gharial/{graph-name}/edge/{collection-name}/{edge-key}": { - "delete": { - "description": "\n\nRemoves an edge from the collection.

Example:

shell> curl -X DELETE --dump - http://localhost:8529/_api/gharial/social/edge/relation/aliceAndBob\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"removed\" : true \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Returned if the edge could be removed.
" - }, - "202": { - "description": "Returned if the request was successful but waitForSync is false.
" - }, - "404": { - "description": "Returned if no graph with this name, no edge collection or no edge with this id could be found.
" - }, - "412": { - "description": "Returned if if-match header is given, but the documents revision is different.
" - } - }, - "summary": " Remove an edge", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "get": { - "description": "\n\nGets an edge from the given collection.

Example:

shell> curl --dump - http://localhost:8529/_api/gharial/social/edge/relation/aliceAndBob\n\nHTTP/1.1 200 OK\ncontent-type: application/json\netag: 549837255\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"edge\" : { \n    \"_id\" : \"relation/aliceAndBob\", \n    \"_key\" : \"aliceAndBob\", \n    \"_rev\" : \"549837255\", \n    \"_from\" : \"female/alice\", \n    \"_to\" : \"male/bob\", \n    \"type\" : \"married\" \n  } \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Returned if the edge could be found.
" - }, - "404": { - "description": "Returned if no graph with this name, no edge collection or no edge with this id could be found.
" - }, - "412": { - "description": "Returned if if-match header is given, but the documents revision is different.
" - } - }, - "summary": " Get an edge", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "patch": { - "description": "\n\nUpdates the data of the specific edge in the collection.
free style json body
Example:

shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/gharial/social/edge/relation/aliceAndBob <<EOF\n{ \n  \"since\" : \"01.01.2001\" \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json\netag: 580639175\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"edge\" : { \n    \"_id\" : \"relation/aliceAndBob\", \n    \"_rev\" : \"580639175\", \n    \"_oldRev\" : \"579525063\", \n    \"_key\" : \"aliceAndBob\" \n  } \n}\n

\n
", - "parameters": [ - { - "description": "The body has to be a JSON object containing the attributes to be updated.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 63 - } - ], - "responses": { - "200": { - "description": "Returned if the edge could be updated.
" - }, - "202": { - "description": "Returned if the request was successful but waitForSync is false.
" - }, - "404": { - "description": "Returned if no graph with this name, no edge collection or no edge with this id could be found.
" - } - }, - "summary": " Modify an edge", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "put": { - "description": "\n\nReplaces the data of an edge in the collection.
free style json body
Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/gharial/social/edge/relation/aliceAndBob <<EOF\n{ \n  \"type\" : \"divorced\" \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json\netag: 584505799\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"edge\" : { \n    \"_id\" : \"relation/aliceAndBob\", \n    \"_rev\" : \"584505799\", \n    \"_oldRev\" : \"583522759\", \n    \"_key\" : \"aliceAndBob\" \n  } \n}\n

\n
", - "parameters": [ - { - "description": "The body has to be the JSON object to be stored.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 54 - } - ], - "responses": { - "200": { - "description": "Returned if the edge could be replaced.
" - }, - "202": { - "description": "Returned if the request was successful but waitForSync is false.
" - }, - "404": { - "description": "Returned if no graph with this name, no edge collection or no edge with this id could be found.
" - }, - "412": { - "description": "Returned if if-match header is given, but the documents revision is different.
" - } - }, - "summary": " Replace an edge", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/gharial/{graph-name}/edge/{definition-name}": { - "delete": { - "description": "\n\nRemove one edge definition from the graph. This will only remove the edge collection, the vertex collections remain untouched and can still be used in your queries.

Example:

shell> curl -X DELETE --dump - http://localhost:8529/_api/gharial/social/edge/relation\n\nHTTP/1.1 200 OK\ncontent-type: application/json\netag: 544659911\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"graph\" : { \n    \"name\" : \"social\", \n    \"edgeDefinitions\" : [ ], \n    \"orphanCollections\" : [ \n      \"female\", \n      \"male\" \n    ], \n    \"_id\" : \"_graphs/social\", \n    \"_rev\" : \"544659911\" \n  } \n}\n

\n

", - "parameters": [], - "responses": { - "200": { - "description": "Returned if the edge definition could be removed from the graph.
" - }, - "400": { - "description": "Returned if no edge definition with this name is found in the graph.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " Remove an edge definition from the graph", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "post": { - "description": "\n\nChange one specific edge definition. This will modify all occurrences of this definition in all graphs known to your database.
**A json post document with these Properties is required:**
  • to: One or many edge collections that can contain target vertices. of type string
  • from: One or many vertex collections that can contain source vertices. of type string
  • collection: The name of the edge collection to be used.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/gharial/social/edge/relation <<EOF\n{ \n  \"collection\" : \"relation\", \n  \"from\" : [ \n    \"female\", \n    \"male\", \n    \"animal\" \n  ], \n  \"to\" : [ \n    \"female\", \n    \"male\", \n    \"animal\" \n  ] \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json\netag: 593746375\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"graph\" : { \n    \"name\" : \"social\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"relation\", \n        \"from\" : [ \n          \"animal\", \n          \"female\", \n          \"male\" \n        ], \n        \"to\" : [ \n          \"animal\", \n          \"female\", \n          \"male\" \n        ] \n      } \n    ], \n    \"orphanCollections\" : [ ], \n    \"_id\" : \"_graphs/social\", \n    \"_rev\" : \"593746375\" \n  } \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_general_graph_edge_definition_modify_http_examples" - }, - "x-description-offset": 192 - } - ], - "responses": { - "200": { - "description": "Returned if the edge definition could be replaced.
" - }, - "400": { - "description": "Returned if no edge definition with this name is found in the graph.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " Replace an edge definition", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/gharial/{graph-name}/vertex": { - "get": { - "description": "\n\nLists all vertex collections within this graph.

Example:

shell> curl --dump - http://localhost:8529/_api/gharial/social/vertex\n\nHTTP/1.1 200 OK\ncontent-type: application/json\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"collections\" : [ \n    \"female\", \n    \"male\" \n  ] \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned if the collections could be listed.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " List vertex collections", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "post": { - "description": "\n\nAdds a vertex collection to the set of collections of the graph. If the collection does not exist, it will be created.

Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/gharial/social/vertex <<EOF\n{ \n  \"collection\" : \"otherVertices\" \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json\netag: 523426247\n\n{ \n  \"error\" : false, \n  \"code\" : 201, \n  \"graph\" : { \n    \"name\" : \"social\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"relation\", \n        \"from\" : [ \n          \"female\", \n          \"male\" \n        ], \n        \"to\" : [ \n          \"female\", \n          \"male\" \n        ] \n      } \n    ], \n    \"orphanCollections\" : [ \n      \"otherVertices\" \n    ], \n    \"_id\" : \"_graphs/social\", \n    \"_rev\" : \"523426247\" \n  } \n}\n

\n
", - "parameters": [], - "responses": { - "201": { - "description": "Returned if the edge collection could be added successfully.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " Add vertex collection", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/gharial/{graph-name}/vertex/{collection-name}": { - "delete": { - "description": "\n\nRemoves a vertex collection from the graph and optionally deletes the collection, if it is not used in any other graph.

Example: /// You can remove vertex collections that are not used in any edge collection:

shell> curl -X DELETE --dump - http://localhost:8529/_api/gharial/social/vertex/otherVertices\n\nHTTP/1.1 200 OK\ncontent-type: application/json\netag: 588372423\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"graph\" : { \n    \"name\" : \"social\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"relation\", \n        \"from\" : [ \n          \"female\", \n          \"male\" \n        ], \n        \"to\" : [ \n          \"female\", \n          \"male\" \n        ] \n      } \n    ], \n    \"orphanCollections\" : [ ], \n    \"_id\" : \"_graphs/social\", \n    \"_rev\" : \"588372423\" \n  } \n}\n

\n
Example: You cannot remove vertex collections that are used in edge collections:

shell> curl -X DELETE --dump - http://localhost:8529/_api/gharial/social/vertex/male\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1928, \n  \"errorMessage\" : \"not in orphan collection\" \n}\n

\n

", - "parameters": [], - "responses": { - "200": { - "description": "Returned if the vertex collection was removed from the graph successfully.
" - }, - "400": { - "description": "Returned if the vertex collection is still used in an edge definition. In this case it cannot be removed from the graph yet, it has to be removed from the edge definition first.
" - }, - "404": { - "description": "Returned if no graph with this name could be found.
" - } - }, - "summary": " Remove vertex collection", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "post": { - "description": "\n\nAdds a vertex to the given collection.
free style json body
Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/gharial/social/vertex/male <<EOF\n{ \n  \"name\" : \"Francis\" \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json\netag: 521918919\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"vertex\" : { \n    \"_id\" : \"male/521918919\", \n    \"_rev\" : \"521918919\", \n    \"_key\" : \"521918919\" \n  } \n}\n

\n
", - "parameters": [ - { - "description": "The body has to be the JSON object to be stored.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 45 - } - ], - "responses": { - "201": { - "description": "Returned if the vertex could be added and waitForSync is true.
" - }, - "202": { - "description": "Returned if the request was successful but waitForSync is false.
" - }, - "404": { - "description": "Returned if no graph or no vertex collection with this name could be found.
" - } - }, - "summary": " Create a vertex", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/gharial/{graph-name}/vertex/{collection-name}/{vertex-key}": { - "delete": { - "description": "\n\nRemoves a vertex from the collection.

Example:

shell> curl -X DELETE --dump - http://localhost:8529/_api/gharial/social/vertex/female/alice\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"removed\" : true \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Returned if the vertex could be removed.
" - }, - "202": { - "description": "Returned if the request was successful but waitForSync is false.
" - }, - "404": { - "description": "Returned if no graph with this name, no vertex collection or no vertex with this id could be found.
" - }, - "412": { - "description": "Returned if if-match header is given, but the documents revision is different.
" - } - }, - "summary": " Remove a vertex", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "get": { - "description": "\n\nGets a vertex from the given collection.

Example:

shell> curl --dump - http://localhost:8529/_api/gharial/social/vertex/female/alice\n\nHTTP/1.1 200 OK\ncontent-type: application/json\netag: 553966023\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"vertex\" : { \n    \"_id\" : \"female/alice\", \n    \"_key\" : \"alice\", \n    \"_rev\" : \"553966023\", \n    \"name\" : \"Alice\" \n  } \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "Returned if the vertex could be found.
" - }, - "404": { - "description": "Returned if no graph with this name, no vertex collection or no vertex with this id could be found.
" - }, - "412": { - "description": "Returned if if-match header is given, but the documents revision is different.
" - } - }, - "summary": " Get a vertex", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "patch": { - "description": "\n\nUpdates the data of the specific vertex in the collection.
free style json body
Example:

shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/gharial/social/vertex/female/alice <<EOF\n{ \n  \"age\" : 26 \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json\netag: 576641479\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"vertex\" : { \n    \"_id\" : \"female/alice\", \n    \"_rev\" : \"576641479\", \n    \"_oldRev\" : \"574478791\", \n    \"_key\" : \"alice\" \n  } \n}\n

\n
", - "parameters": [ - { - "description": "The body has to contain a JSON object containing exactly the attributes that should be replaced.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 65 - } - ], - "responses": { - "200": { - "description": "Returned if the vertex could be updated.
" - }, - "202": { - "description": "Returned if the request was successful but waitForSync is false.
" - }, - "404": { - "description": "Returned if no graph with this name, no vertex collection or no vertex with this id could be found.
" - }, - "412": { - "description": "Returned if if-match header is given, but the documents revision is different.
" - } - }, - "summary": " Modify a vertex", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - }, - "put": { - "description": "\n\nReplaces the data of a vertex in the collection.
free style json body
Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/gharial/social/vertex/female/alice <<EOF\n{ \n  \"name\" : \"Alice Cooper\", \n  \"age\" : 26 \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json\netag: 600496583\n\n{ \n  \"error\" : false, \n  \"code\" : 202, \n  \"vertex\" : { \n    \"_id\" : \"female/alice\", \n    \"_rev\" : \"600496583\", \n    \"_oldRev\" : \"598333895\", \n    \"_key\" : \"alice\" \n  } \n}\n

\n
", - "parameters": [ - { - "description": "The body has to be the JSON object to be stored.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 55 - } - ], - "responses": { - "200": { - "description": "Returned if the vertex could be replaced.
" - }, - "202": { - "description": "Returned if the request was successful but waitForSync is false.
" - }, - "404": { - "description": "Returned if no graph with this name, no vertex collection or no vertex with this id could be found.
" - }, - "412": { - "description": "Returned if if-match header is given, but the documents revision is different.
" - } - }, - "summary": " Replace a vertex", - "tags": [ - "Graph" - ], - "x-examples": [], - "x-filename": "Graph - js/apps/system/_api/gharial/APP/gharial.js" - } - }, - "/_api/import#document": { - "post": { - "description": "free style json body\n\nNOTE Swagger examples won't work due to the anchor.

Creates documents in the collection identified by `collection-name`. The first line of the request body must contain a JSON-encoded array of attribute names. All following lines in the request body must contain JSON-encoded arrays of attribute values. Each line is interpreted as a separate document, and the values specified will be mapped to the array of attribute names specified in the first header line.
The response is a JSON object with the following attributes:
  • `created`: number of documents imported.
  • `errors`: number of documents that were not imported due to an error.
  • `empty`: number of empty lines found in the input (will only contain a value greater zero for types `documents` or `auto`).
  • `updated`: number of updated/replaced documents (in case `onDuplicate` was set to either `update` or `replace`).
  • `ignored`: number of failed but ignored insert operations (in case `onDuplicate` was set to `ignore`).
  • `details`: if URL parameter `details` is set to true, the result will contain a `details` attribute which is an array with more detailed information about which documents could not be inserted.
Note: this API is currently not supported on cluster coordinators.

Example: Importing two documents, with attributes `_key`, `value1` and `value2` each. One line in the import data is empty

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products <<EOF\n[ \"_key\", \"value1\", \"value2\" ]\n[ \"abc\", 25, \"test\" ]\n\n[ \"foo\", \"bar\", \"baz\" ]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 2, \n  \"errors\" : 0, \n  \"empty\" : 1, \n  \"updated\" : 0, \n  \"ignored\" : 0 \n}\n

\n
Example: Importing two documents into a new collection

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&createCollection=true <<EOF\n[ \"value1\", \"value2\" ]\n[ 1234, null ]\n[ \"foo\", \"bar\" ]\n[ 534.55, true ]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 3, \n  \"errors\" : 0, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0 \n}\n

\n
Example: Importing into an edge collection, with attributes `_from`, `_to` and `name`

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=links <<EOF\n[ \"_from\", \"_to\", \"name\" ]\n[ \"products/123\", \"products/234\", \"some name\" ]\n[ \"products/332\", \"products/abc\", \"other name\" ]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 2, \n  \"errors\" : 0, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0 \n}\n

\n
Example: Importing into an edge collection, omitting `_from` or `_to`

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=links&details=true <<EOF\n[ \"name\" ]\n[ \"some name\" ]\n[ \"other name\" ]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 0, \n  \"errors\" : 2, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0, \n  \"details\" : [ \n    \"at position 1: missing '_from' or '_to' attribute, offending document: {\\\"name\\\":\\\"some name\\\"}\", \n    \"at position 2: missing '_from' or '_to' attribute, offending document: {\\\"name\\\":\\\"other name\\\"}\" \n  ] \n}\n

\n
Example: Violating a unique constraint, but allow partial imports

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&details=true <<EOF\n[ \"_key\", \"value1\", \"value2\" ]\n[ \"abc\", 25, \"test\" ]\n[ \"abc\", \"bar\", \"baz\" ]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 1, \n  \"errors\" : 1, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0, \n  \"details\" : [ \n    \"at position 2: creating document failed with error 'unique constraint violated', offending document: {\\\"_key\\\":\\\"abc\\\",\\\"value1\\\":\\\"bar\\\",\\\"value2\\\":\\\"baz\\\"}\" \n  ] \n}\n

\n
Example: Violating a unique constraint, not allowing partial imports

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&complete=true <<EOF\n[ \"_key\", \"value1\", \"value2\" ]\n[ \"abc\", 25, \"test\" ]\n[ \"abc\", \"bar\", \"baz\" ]\nEOF\n\nHTTP/1.1 409 Conflict\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"cannot create document, unique constraint violated\", \n  \"code\" : 409, \n  \"errorNum\" : 1210 \n}\n

\n
Example: Using a non-existing collection

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products <<EOF\n[ \"_key\", \"value1\", \"value2\" ]\n[ \"abc\", 25, \"test\" ]\n[ \"foo\", \"bar\", \"baz\" ]\nEOF\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'products' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n

\n
Example: Using a malformed body

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products <<EOF\n{ \"_key\": \"foo\", \"value1\": \"bar\" }\nEOF\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"no JSON array found in second line\", \n  \"code\" : 400, \n  \"errorNum\" : 400 \n}\n

\n
", - "parameters": [ - { - "description": "The body must consist of JSON-encoded arrays of attribute values, with one line per document. The first row of the request must be a JSON-encoded array of attribute names. These attribute names are used for the data in the subsequent lines.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - }, - { - "description": "The collection name.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "description": "If this parameter has a value of `true` or `yes`, then the collection is created if it does not yet exist. Other values will be ignored so the collection must be present for the operation to succeed.
", - "in": "query", - "name": "createCollection", - "required": false, - "type": "boolean" - }, - { - "description": "If this parameter has a value of `true` or `yes`, then all data in the collection will be removed prior to the import. Note that any existing index definitions will be preseved.
", - "in": "query", - "name": "overwrite", - "required": false, - "type": "boolean" - }, - { - "description": "Wait until documents have been synced to disk before returning.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "Controls what action is carried out in case of a unique key constraint violation. Possible values are:
  • error: this will not import the current document because of the unique key constraint violation. This is the default setting.
  • update: this will update an existing document in the database with the data specified in the request. Attributes of the existing document that are not present in the request will be preseved.
  • replace: this will replace an existing document in the database with the data specified in the request.
  • ignore: this will not update an existing document and simply ignore the error caused by the unique key constraint violation.
Note that update, replace and ignore will only work when the import document in the request contains the _key attribute. update and replace may also fail because of secondary unique key constraint violations.
", - "in": "query", - "name": "onDuplicate", - "required": false, - "type": "string" - }, - { - "description": "If set to `true` or `yes`, it will make the whole import fail if any error occurs. Otherwise the import will continue even if some documents cannot be imported.
", - "in": "query", - "name": "complete", - "required": false, - "type": "boolean" - }, - { - "description": "If set to `true` or `yes`, the result will include an attribute `details` with details about documents that could not be imported.
", - "in": "query", - "name": "details", - "required": false, - "type": "boolean" - } - ], - "responses": { - "201": { - "description": "is returned if all documents could be imported successfully.
" - }, - "400": { - "description": "is returned if `type` contains an invalid value, no `collection` is specified, the documents are incorrectly encoded, or the request is malformed.
" - }, - "404": { - "description": "is returned if `collection` or the `_from` or `_to` attributes of an imported edge refer to an unknown collection.
" - }, - "409": { - "description": "is returned if the import would trigger a unique key violation and `complete` is set to `true`.
" - }, - "500": { - "description": "is returned if the server cannot auto-generate a document key (out of keys error) for a document with no user-defined key.
" - }, - "501": { - "description": "The server will respond with HTTP 501 if this API is called on a cluster coordinator.
" - } - }, - "summary": "imports document values", - "tags": [ - "Bulk" - ], - "x-examples": [], - "x-filename": "Bulk - arangod/RestHandler/RestExportHandler.cpp, arangod/RestHandler/RestImportHandler.cpp, arangod/RestHandler/RestBatchHandler.cpp" - } - }, - "/_api/import#json": { - "post": { - "description": "free style json body\n\nNOTE Swagger examples won't work due to the anchor.

Creates documents in the collection identified by `collection-name`. The JSON representations of the documents must be passed as the body of the POST request. The request body can either consist of multiple lines, with each line being a single stand-alone JSON object, or a singe JSON array with sub-objects.
The response is a JSON object with the following attributes:
  • `created`: number of documents imported.
  • `errors`: number of documents that were not imported due to an error.
  • `empty`: number of empty lines found in the input (will only contain a value greater zero for types `documents` or `auto`).
  • `updated`: number of updated/replaced documents (in case `onDuplicate` was set to either `update` or `replace`).
  • `ignored`: number of failed but ignored insert operations (in case `onDuplicate` was set to `ignore`).
  • `details`: if URL parameter `details` is set to true, the result will contain a `details` attribute which is an array with more detailed information about which documents could not be inserted.
Note: this API is currently not supported on cluster coordinators.

Example: Importing documents with heterogenous attributes from a JSON array

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&type=list <<EOF\n[ \n  { \n    \"_key\" : \"abc\", \n    \"value1\" : 25, \n    \"value2\" : \"test\", \n    \"allowed\" : true \n  }, \n  { \n    \"_key\" : \"foo\", \n    \"name\" : \"baz\" \n  }, \n  { \n    \"name\" : { \n      \"detailed\" : \"detailed name\", \n      \"short\" : \"short name\" \n    } \n  } \n]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 3, \n  \"errors\" : 0, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0 \n}\n

\n
Example: Importing documents from individual JSON lines

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&type=documents <<EOF\n{ \"_key\": \"abc\", \"value1\": 25, \"value2\": \"test\", \"allowed\": true }\n{ \"_key\": \"foo\", \"name\": \"baz\" }\n\n{ \"name\": { \"detailed\": \"detailed name\", \"short\": \"short name\" } }\n\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 3, \n  \"errors\" : 0, \n  \"empty\" : 1, \n  \"updated\" : 0, \n  \"ignored\" : 0 \n}\n

\n
Example: Using the auto type detection

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&type=auto <<EOF\n[ \n  { \n    \"_key\" : \"abc\", \n    \"value1\" : 25, \n    \"value2\" : \"test\", \n    \"allowed\" : true \n  }, \n  { \n    \"_key\" : \"foo\", \n    \"name\" : \"baz\" \n  }, \n  { \n    \"name\" : { \n      \"detailed\" : \"detailed name\", \n      \"short\" : \"short name\" \n    } \n  } \n]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 3, \n  \"errors\" : 0, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0 \n}\n

\n
Example: Importing documents into a new collection from a JSON array

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&createCollection=true&type=list <<EOF\n[ \n  { \n    \"id\" : \"12553\", \n    \"active\" : true \n  }, \n  { \n    \"id\" : \"4433\", \n    \"active\" : false \n  }, \n  { \n    \"id\" : \"55932\", \n    \"count\" : 4334 \n  } \n]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 3, \n  \"errors\" : 0, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0 \n}\n

\n
Example: Importing into an edge collection, with attributes `_from`, `_to` and `name`

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=links&type=documents <<EOF\n{ \"_from\": \"products/123\", \"_to\": \"products/234\" }\n{ \"_from\": \"products/332\", \"_to\": \"products/abc\", \"name\": \"other name\" }\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 2, \n  \"errors\" : 0, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0 \n}\n

\n
Example: Importing into an edge collection, omitting `_from` or `_to`

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=links&type=list&details=true <<EOF\n[ \n  { \n    \"name\" : \"some name\" \n  } \n]\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 0, \n  \"errors\" : 1, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0, \n  \"details\" : [ \n    \"at position 1: missing '_from' or '_to' attribute, offending document: {\\\"name\\\":\\\"some name\\\"}\" \n  ] \n}\n

\n
Example: Violating a unique constraint, but allow partial imports

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&type=documents&details=true <<EOF\n{ \"_key\": \"abc\", \"value1\": 25, \"value2\": \"test\" }\n{ \"_key\": \"abc\", \"value1\": \"bar\", \"value2\": \"baz\" }\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"created\" : 1, \n  \"errors\" : 1, \n  \"empty\" : 0, \n  \"updated\" : 0, \n  \"ignored\" : 0, \n  \"details\" : [ \n    \"at position 2: creating document failed with error 'unique constraint violated', offending document: {\\\"_key\\\":\\\"abc\\\",\\\"value1\\\":\\\"bar\\\",\\\"value2\\\":\\\"baz\\\"}\" \n  ] \n}\n

\n
Example: Violating a unique constraint, not allowing partial imports

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&type=documents&complete=true <<EOF\n{ \"_key\": \"abc\", \"value1\": 25, \"value2\": \"test\" }\n{ \"_key\": \"abc\", \"value1\": \"bar\", \"value2\": \"baz\" }\nEOF\n\nHTTP/1.1 409 Conflict\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"cannot create document, unique constraint violated\", \n  \"code\" : 409, \n  \"errorNum\" : 1210 \n}\n

\n
Example: Using a non-existing collection

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&type=documents <<EOF\n{ \"name\": \"test\" }\nEOF\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'products' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n

\n
Example: Using a malformed body

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/import?collection=products&type=list <<EOF\n{ }\nEOF\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"expecting a JSON array in the request\", \n  \"code\" : 400, \n  \"errorNum\" : 400 \n}\n

\n
", - "parameters": [ - { - "description": "The body must either be a JSON-encoded array of objects or a string with multiple JSON objects separated by newlines.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - }, - { - "description": "Determines how the body of the request will be interpreted. `type` can have the following values:
  • `documents`: when this type is used, each line in the request body is expected to be an individual JSON-encoded document. Multiple JSON objects in the request body need to be separated by newlines.
  • `list`: when this type is used, the request body must contain a single JSON-encoded array of individual objects to import.
  • `auto`: if set, this will automatically determine the body type (either `documents` or `list`).
", - "in": "query", - "name": "type", - "required": true, - "type": "string" - }, - { - "description": "The collection name.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "description": "If this parameter has a value of `true` or `yes`, then the collection is created if it does not yet exist. Other values will be ignored so the collection must be present for the operation to succeed.
", - "in": "query", - "name": "createCollection", - "required": false, - "type": "boolean" - }, - { - "description": "If this parameter has a value of `true` or `yes`, then all data in the collection will be removed prior to the import. Note that any existing index definitions will be preseved.
", - "in": "query", - "name": "overwrite", - "required": false, - "type": "boolean" - }, - { - "description": "Wait until documents have been synced to disk before returning.
", - "in": "query", - "name": "waitForSync", - "required": false, - "type": "boolean" - }, - { - "description": "Controls what action is carried out in case of a unique key constraint violation. Possible values are:
  • error: this will not import the current document because of the unique key constraint violation. This is the default setting.
  • update: this will update an existing document in the database with the data specified in the request. Attributes of the existing document that are not present in the request will be preseved.
  • replace: this will replace an existing document in the database with the data specified in the request.
  • ignore: this will not update an existing document and simply ignore the error caused by a unique key constraint violation.
Note that that update, replace and ignore will only work when the import document in the request contains the _key attribute. update and replace may also fail because of secondary unique key constraint violations.
", - "in": "query", - "name": "onDuplicate", - "required": false, - "type": "string" - }, - { - "description": "If set to `true` or `yes`, it will make the whole import fail if any error occurs. Otherwise the import will continue even if some documents cannot be imported.
", - "in": "query", - "name": "complete", - "required": false, - "type": "boolean" - }, - { - "description": "If set to `true` or `yes`, the result will include an attribute `details` with details about documents that could not be imported.
", - "in": "query", - "name": "details", - "required": false, - "type": "boolean" - } - ], - "responses": { - "201": { - "description": "is returned if all documents could be imported successfully.
" - }, - "400": { - "description": "is returned if `type` contains an invalid value, no `collection` is specified, the documents are incorrectly encoded, or the request is malformed.
" - }, - "404": { - "description": "is returned if `collection` or the `_from` or `_to` attributes of an imported edge refer to an unknown collection.
" - }, - "409": { - "description": "is returned if the import would trigger a unique key violation and `complete` is set to `true`.
" - }, - "500": { - "description": "is returned if the server cannot auto-generate a document key (out of keys error) for a document with no user-defined key.
" - }, - "501": { - "description": "The server will respond with HTTP 501 if this API is called on a cluster coordinator.
" - } - }, - "summary": "imports documents from JSON", - "tags": [ - "Bulk" - ], - "x-examples": [], - "x-filename": "Bulk - arangod/RestHandler/RestExportHandler.cpp, arangod/RestHandler/RestImportHandler.cpp, arangod/RestHandler/RestBatchHandler.cpp" - } - }, - "/_api/index": { - "get": { - "description": "\n\n
Returns an object with an attribute indexes containing an array of all index descriptions for the given collection. The same information is also available in the identifiers as an object with the index handles as keys.

Example: Return information about all indexes

shell> curl --dump - http://localhost:8529/_api/index?collection=products\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"indexes\" : [ \n    { \n      \"id\" : \"products/0\", \n      \"type\" : \"primary\", \n      \"fields\" : [ \n        \"_key\" \n      ], \n      \"selectivityEstimate\" : 1, \n      \"unique\" : true, \n      \"sparse\" : false \n    }, \n    { \n      \"id\" : \"products/758438343\", \n      \"type\" : \"hash\", \n      \"fields\" : [ \n        \"name\" \n      ], \n      \"selectivityEstimate\" : 1, \n      \"unique\" : false, \n      \"sparse\" : false \n    }, \n    { \n      \"id\" : \"products/758700487\", \n      \"type\" : \"skiplist\", \n      \"fields\" : [ \n        \"price\" \n      ], \n      \"unique\" : false, \n      \"sparse\" : true \n    } \n  ], \n  \"identifiers\" : { \n    \"products/0\" : { \n      \"id\" : \"products/0\", \n      \"type\" : \"primary\", \n      \"fields\" : [ \n        \"_key\" \n      ], \n      \"selectivityEstimate\" : 1, \n      \"unique\" : true, \n      \"sparse\" : false \n    }, \n    \"products/758438343\" : { \n      \"id\" : \"products/758438343\", \n      \"type\" : \"hash\", \n      \"fields\" : [ \n        \"name\" \n      ], \n      \"selectivityEstimate\" : 1, \n      \"unique\" : false, \n      \"sparse\" : false \n    }, \n    \"products/758700487\" : { \n      \"id\" : \"products/758700487\", \n      \"type\" : \"skiplist\", \n      \"fields\" : [ \n        \"price\" \n      ], \n      \"unique\" : false, \n      \"sparse\" : true \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The collection name.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "returns a json object containing a list of indexes on that collection.
" - } - }, - "summary": " Read all indexes of a collection", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - }, - "post": { - "description": "**A json post document with these Properties is required:**
  • fields: an array of attribute paths. of type string
  • unique: if true, then create a unique index.
  • type: must be equal to \"skiplist\".
  • sparse: if true, then create a sparse index.
\n\n
Creates a skip-list index for the collection collection-name, if it does not already exist. The call expects an object containing the index details.
In a sparse index all documents will be excluded from the index that do not contain at least one of the specified index attributes (i.e. fields) or that have a value of null in any of the specified index attributes. Such documents will not be indexed, and not be taken into account for uniqueness checks if the unique flag is set.
In a non-sparse index, these documents will be indexed (for non-present indexed attributes, a value of null will be used) and will be taken into account for uniqueness checks if the unique flag is set.
Note: unique indexes on non-shard keys are not supported in a cluster.

Example: Creating a skiplist index

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"skiplist\", \n  \"unique\" : false, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/761715143\", \n  \"type\" : \"skiplist\", \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"unique\" : false, \n  \"sparse\" : false, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Creating a sparse skiplist index

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"skiplist\", \n  \"unique\" : false, \n  \"sparse\" : true, \n  \"fields\" : [ \n    \"a\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/763222471\", \n  \"type\" : \"skiplist\", \n  \"fields\" : [ \n    \"a\" \n  ], \n  \"unique\" : false, \n  \"sparse\" : true, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "description": "The collection name.

", - "in": "query", - "name": "collection-name", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_index_skiplist" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the index already exists, then a HTTP 200 is returned.
" - }, - "201": { - "description": "If the index does not already exist and could be created, then a HTTP 201 is returned.
" - }, - "400": { - "description": "If the collection already contains documents and you try to create a unique skip-list index in such a way that there are documents violating the uniqueness, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Create skip list", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - } - }, - "/_api/index#CapConstraints": { - "post": { - "description": "**A json post document with these Properties is required:**
  • byteSize: The maximal size of the active document data in the collection (in bytes). If specified, the value must be at least 16384.

  • type: must be equal to \"cap\".
  • size: The maximal number of documents for the collection. If specified, the value must be greater than zero.
\n\nNOTE Swagger examples won't work due to the anchor.


Creates a cap constraint for the collection collection-name, if it does not already exist. Expects an object containing the index details.
Note: The cap constraint does not index particular attributes of the documents in a collection, but limits the number of documents in the collection to a maximum value. The cap constraint thus does not support attribute names specified in the fields attribute nor uniqueness of any kind via the unique attribute.
It is allowed to specify either size or byteSize, or both at the same time. If both are specified, then the automatic document removal will be triggered by the first non-met constraint.

Example: Creating a cap constraint

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"cap\", \n  \"size\" : 10 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/760142279\", \n  \"type\" : \"cap\", \n  \"size\" : 10, \n  \"byteSize\" : 0, \n  \"unique\" : false, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "description": "The collection name.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_index_cap" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the index already exists, then an HTTP 200 is returned.
" - }, - "201": { - "description": "If the index does not already exist and could be created, then an HTTP 201 is returned.
" - }, - "400": { - "description": "If either size or byteSize contain invalid values, then an HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Create cap constraint", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - } - }, - "/_api/index#fulltext": { - "post": { - "description": "**A json post document with these Properties is required:**
  • fields: an array of attribute names. Currently, the array is limited to exactly one attribute. of type string
  • type: must be equal to \"fulltext\".
  • minLength: Minimum character length of words to index. Will default to a server-defined value if unspecified. It is thus recommended to set this value explicitly when creating the index.
\n\nNOTE Swagger examples won't work due to the anchor.

Creates a fulltext index for the collection collection-name, if it does not already exist. The call expects an object containing the index details.

Example: Creating a fulltext index

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"fulltext\", \n  \"fields\" : [ \n    \"text\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/760601031\", \n  \"type\" : \"fulltext\", \n  \"fields\" : [ \n    \"text\" \n  ], \n  \"unique\" : false, \n  \"sparse\" : true, \n  \"minLength\" : 2, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "description": "The collection name.
", - "in": "query", - "name": "collection-name", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_index_fulltext" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the index already exists, then a HTTP 200 is returned.
" - }, - "201": { - "description": "If the index does not already exist and could be created, then a HTTP 201 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Create fulltext index", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - } - }, - "/_api/index#general": { - "post": { - "description": "free style json body\n\nNOTE Swagger examples won't work due to the anchor.

Creates a new index in the collection collection. Expects an object containing the index details.
The type of the index to be created must specified in the type attribute of the index details. Depending on the index type, additional other attributes may need to specified in the request in order to create the index.
Most indexes (a notable exception being the cap constraint) require the array of attributes to be indexed in the fields attribute of the index details. Depending on the index type, a single attribute or multiple attributes can be indexed.
Indexing system attributes such as _id, _key, _from, and _to is not supported for user-defined indexes. Manually creating an index using any of these attributes will fail with an error.
Some indexes can be created as unique or non-unique variants. Uniqueness can be controlled for most indexes by specifying the unique flag in the index details. Setting it to true will create a unique index. Setting it to false or omitting the unique attribute will create a non-unique index.
Note: The following index types do not support uniqueness, and using the unique attribute with these types may lead to an error:
  • cap constraints
  • fulltext indexes
Note: Unique indexes on non-shard keys are not supported in a cluster.
Hash and skiplist indexes can optionally be created in a sparse variant. A sparse index will be created if the sparse attribute in the index details is set to true. Sparse indexes do not index documents for which any of the index attributes is either not set or is null.
", - "parameters": [ - { - "description": "The collection name.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "description": "
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "responses": { - "200": { - "description": "If the index already exists, then an HTTP 200 is returned.
" - }, - "201": { - "description": "If the index does not already exist and could be created, then an HTTP 201 is returned.
" - }, - "400": { - "description": "If an invalid index description is posted or attributes are used that the target index will not support, then an HTTP 400 is returned.
" - }, - "404": { - "description": "If collection is unknown, then an HTTP 404 is returned.
" - } - }, - "summary": " Create index", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - } - }, - "/_api/index#geo": { - "post": { - "description": "**A json post document with these Properties is required:**
  • fields: An array with one or two attribute paths.
    If it is an array with one attribute path location, then a geo-spatial index on all documents is created using location as path to the coordinates. The value of the attribute must be an array with at least two double values. The array must contain the latitude (first value) and the longitude (second value). All documents, which do not have the attribute path or with value that are not suitable, are ignored.
    If it is an array with two attribute paths latitude and longitude, then a geo-spatial index on all documents is created using latitude and longitude as paths the latitude and the longitude. The value of the attribute latitude and of the attribute longitude must a double. All documents, which do not have the attribute paths or which values are not suitable, are ignored. of type string
  • type: must be equal to \"geo\".
  • geoJson: If a geo-spatial index on a location is constructed and geoJson is true, then the order within the array is longitude followed by latitude. This corresponds to the format described in http://geojson.org/geojson-spec.html#positions
\n\nNOTE Swagger examples won't work due to the anchor.

Creates a geo-spatial index in the collection collection-name, if it does not already exist. Expects an object containing the index details.
Geo indexes are always sparse, meaning that documents that do not contain the index attributes or have non-numeric values in the index attributes will not be indexed.

Example: Creating a geo index with a location attribute

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"geo\", \n  \"fields\" : [ \n    \"b\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/759749063\", \n  \"type\" : \"geo1\", \n  \"fields\" : [ \n    \"b\" \n  ], \n  \"geoJson\" : false, \n  \"constraint\" : false, \n  \"unique\" : false, \n  \"ignoreNull\" : true, \n  \"sparse\" : true, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Creating a geo index with latitude and longitude attributes

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"geo\", \n  \"fields\" : [ \n    \"e\", \n    \"f\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/759290311\", \n  \"type\" : \"geo2\", \n  \"fields\" : [ \n    \"e\", \n    \"f\" \n  ], \n  \"constraint\" : false, \n  \"unique\" : false, \n  \"ignoreNull\" : true, \n  \"sparse\" : true, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "description": "The collection name.

", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_index_geo" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the index already exists, then a HTTP 200 is returned.
" - }, - "201": { - "description": "If the index does not already exist and could be created, then a HTTP 201 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Create geo-spatial index", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - } - }, - "/_api/index#hash": { - "post": { - "description": "**A json post document with these Properties is required:**
  • fields: an array of attribute paths. of type string
  • unique: if true, then create a unique index.
  • type: must be equal to \"hash\".
  • sparse: if true, then create a sparse index.
\n\nNOTE Swagger examples won't work due to the anchor.

Creates a hash index for the collection collection-name if it does not already exist. The call expects an object containing the index details.
In a sparse index all documents will be excluded from the index that do not contain at least one of the specified index attributes (i.e. fields) or that have a value of null in any of the specified index attributes. Such documents will not be indexed, and not be taken into account for uniqueness checks if the unique flag is set.
In a non-sparse index, these documents will be indexed (for non-present indexed attributes, a value of null will be used) and will be taken into account for uniqueness checks if the unique flag is set.
Note: unique indexes on non-shard keys are not supported in a cluster.

Example: Creating an unique constraint

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"hash\", \n  \"unique\" : true, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/762239431\", \n  \"type\" : \"hash\", \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"selectivityEstimate\" : 1, \n  \"unique\" : true, \n  \"sparse\" : false, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Creating a non-unique hash index

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"hash\", \n  \"unique\" : false, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/761190855\", \n  \"type\" : \"hash\", \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"selectivityEstimate\" : 1, \n  \"unique\" : false, \n  \"sparse\" : false, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Creating a sparse index

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products <<EOF\n{ \n  \"type\" : \"hash\", \n  \"unique\" : false, \n  \"sparse\" : true, \n  \"fields\" : [ \n    \"a\" \n  ] \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/762698183\", \n  \"type\" : \"hash\", \n  \"fields\" : [ \n    \"a\" \n  ], \n  \"selectivityEstimate\" : 1, \n  \"unique\" : false, \n  \"sparse\" : true, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "description": "The collection name.
", - "in": "query", - "name": "collection-name", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_index_hash" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the index already exists, then a HTTP 200 is returned.
" - }, - "201": { - "description": "If the index does not already exist and could be created, then a HTTP 201 is returned.
" - }, - "400": { - "description": "If the collection already contains documents and you try to create a unique hash index in such a way that there are documents violating the uniqueness, then a HTTP 400 is returned.
" - }, - "404": { - "description": "If the collection-name is unknown, then a HTTP 404 is returned.
" - } - }, - "summary": " Create hash index", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - } - }, - "/_api/index/{index-handle}": { - "delete": { - "description": "\n\n
Deletes an index with index-handle.

Example:

shell> curl -X DELETE --dump - http://localhost:8529/_api/index/products/763746759\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/763746759\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The index handle.
", - "format": "string", - "in": "path", - "name": "index-handle", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "If the index could be deleted, then an HTTP 200 is returned.
" - }, - "404": { - "description": "If the index-handle is unknown, then an HTTP 404 is returned." - } - }, - "summary": " Delete index", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - }, - "get": { - "description": "\n\n
The result is an object describing the index. It has at least the following attributes:
  • id: the identifier of the index
  • type: the index type
All other attributes are type-dependent. For example, some indexes provide unique or sparse flags, whereas others don't. Some indexes also provide a selectivity estimate in the selectivityEstimate attribute of the result.

Example:

shell> curl --dump - http://localhost:8529/_api/index/products/0\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/0\", \n  \"type\" : \"primary\", \n  \"fields\" : [ \n    \"_key\" \n  ], \n  \"selectivityEstimate\" : 1, \n  \"unique\" : true, \n  \"sparse\" : false, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The index-handle.
", - "format": "string", - "in": "path", - "name": "index-handle", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "If the index exists, then a HTTP 200 is returned.
" - }, - "404": { - "description": "If the index does not exist, then a HTTP 404 is returned.
" - } - }, - "summary": "Read index", - "tags": [ - "Indexes" - ], - "x-examples": [], - "x-filename": "Indexes - js/actions/api-index.js" - } - }, - "/_api/job/{job-id}": { - "get": { - "description": "\n\nReturns the processing status of the specified job. The processing status can be determined by peeking into the HTTP response code of the response.

Example: Querying the status of a done job:

shell> curl -X PUT --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 603314631\n\nshell> curl -X PUT --dump - http://localhost:8529/_api/job/603314631\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nx-arango-async-id: 603314631\n\n{ \n  \"server\" : \"arango\", \n  \"version\" : \"2.7.0-devel\" \n}\n

\n
Example: Querying the status of a pending job: (we create a sleep job therefore...)

shell> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_admin/sleep?duration=30\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 603380167\n\nshell> curl --dump - http://localhost:8529/_api/job/603380167\n\nHTTP/1.1 204 No Content\ncontent-type: text/plain; charset=utf-8\n\n

\n
", - "parameters": [ - { - "description": "The async job id.
", - "format": "string", - "in": "path", - "name": "job-id", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the job requested via job-id has been executed and its result is ready to fetch.
" - }, - "204": { - "description": "is returned if the job requested via job-id is still in the queue of pending (or not yet finished) jobs.
" - }, - "404": { - "description": "is returned if the job was not found or already deleted or fetched from the job result list.
" - } - }, - "summary": " Returns async job", - "tags": [ - "job" - ], - "x-examples": [], - "x-filename": "job - arangod/HttpServer/AsyncJobManager.cpp, arangod/RestHandler/RestJobHandler.cpp" - }, - "put": { - "description": "\n\nReturns the result of an async job identified by job-id. If the async job result is present on the server, the result will be removed from the list of result. That means this method can be called for each job-id once. The method will return the original job result's headers and body, plus the additional HTTP header x-arango-async-job-id. If this header is present, then the job was found and the response contains the original job's result. If the header is not present, the job was not found and the response contains status information from the job manager.

Example: Not providing a job-id:

shell> curl -X PUT --dump - http://localhost:8529/_api/job\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"bad parameter\", \n  \"code\" : 400, \n  \"errorNum\" : 400 \n}\n

\n
Example: Providing a job-id for a non-existing job:

shell> curl -X PUT --dump - http://localhost:8529/_api/job/notthere\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"not found\", \n  \"code\" : 404, \n  \"errorNum\" : 404 \n}\n

\n
Example: Fetching the result of an HTTP GET job:

shell> curl -X PUT --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 602986951\n\nshell> curl -X PUT --dump - http://localhost:8529/_api/job/602986951\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nx-arango-async-id: 602986951\n\n{ \n  \"server\" : \"arango\", \n  \"version\" : \"2.7.0-devel\" \n}\n

\n
Example: Fetching the result of an HTTP POST job that failed:

shell> curl -X PUT --header 'x-arango-async: store' --data-binary @- --dump - http://localhost:8529/_api/collection <<EOF\n{ \n  \"name\" : \" this name is invalid \" \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 603052487\n\nshell> curl -X PUT --dump - http://localhost:8529/_api/job/603052487\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\nx-arango-async-id: 603052487\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 400, \n  \"errorMessage\" : \"expected PUT /_api/collection/<collection-name>/<action>\" \n}\n

\n
", - "parameters": [ - { - "description": "The async job id.
", - "format": "string", - "in": "path", - "name": "job-id", - "required": true, - "type": "string" - } - ], - "responses": { - "204": { - "description": "is returned if the job requested via job-id is still in the queue of pending (or not yet finished) jobs. In this case, no x-arango-async-id HTTP header will be returned.
" - }, - "400": { - "description": "is returned if no job-id was specified in the request. In this case, no x-arango-async-id HTTP header will be returned.
" - }, - "404": { - "description": "is returned if the job was not found or already deleted or fetched from the job result list. In this case, no x-arango-async-id HTTP header will be returned.
" - } - }, - "summary": " Return result of an async job", - "tags": [ - "job" - ], - "x-examples": [], - "x-filename": "job - arangod/HttpServer/AsyncJobManager.cpp, arangod/RestHandler/RestJobHandler.cpp" - } - }, - "/_api/job/{job-id}/cancel": { - "put": { - "description": "\n\nCancels the currently running job identified by job-id. Note that it still might take some time to actually cancel the running async job.

Example:

shell> curl -X POST --header 'x-arango-async: store' --data-binary @- --dump - http://localhost:8529/_api/cursor <<EOF\n{ \n  \"query\" : \"FOR i IN 1..10 FOR j IN 1..10 LET x = sleep(1.0) FILTER i == 5 && j == 5 RETURN 42\" \n}\nEOF\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 602659271\n\nshell> curl --dump - http://localhost:8529/_api/job/pending\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  \"602659271\" \n]\nshell> curl -X PUT --dump - http://localhost:8529/_api/job/602659271/cancel\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true \n}\nshell> curl --dump - http://localhost:8529/_api/job/pending\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ ]\n

\n
", - "parameters": [ - { - "description": "The async job id.
", - "format": "string", - "in": "path", - "name": "job-id", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "cancel has been initiated.
" - }, - "400": { - "description": "is returned if no job-id was specified in the request. In this case, no x-arango-async-id HTTP header will be returned.
" - }, - "404": { - "description": "is returned if the job was not found or already deleted or fetched from the job result list. In this case, no x-arango-async-id HTTP header will be returned.
" - } - }, - "summary": " Cancel async job", - "tags": [ - "job" - ], - "x-examples": [], - "x-filename": "job - arangod/HttpServer/AsyncJobManager.cpp, arangod/RestHandler/RestJobHandler.cpp" - } - }, - "/_api/job/{type}": { - "delete": { - "description": "\n\nDeletes either all job results, expired job results, or the result of a specific job. Clients can use this method to perform an eventual garbage collection of job results.

Example: Deleting all jobs:

shell> curl -X PUT --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 602790343\n\nshell> curl -X DELETE --dump - http://localhost:8529/_api/job/all\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true \n}\n

\n
Example: Deleting expired jobs:

shell> curl -X PUT --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 602855879\n\nshell> curl --dump - http://localhost:8529/_admin/time\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"time\" : 1443627576.40017, \n  \"error\" : false, \n  \"code\" : 200 \n}\nshell> curl -X DELETE --dump - http://localhost:8529/_api/job/expired?stamp=1443627576.40017\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true \n}\nshell> curl --dump - http://localhost:8529/_api/job/pending\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ ]\n

\n
Example: Deleting the result of a specific job:

shell> curl -X PUT --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 602921415\n\nshell> curl -X DELETE --dump - http://localhost:8529/_api/job/602921415\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true \n}\n

\n
Example: Deleting the result of a non-existing job:

shell> curl -X DELETE --dump - http://localhost:8529/_api/job/AreYouThere\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"not found\", \n  \"code\" : 404, \n  \"errorNum\" : 404 \n}\n

\n
", - "parameters": [ - { - "description": "The type of jobs to delete. type can be: *all: Deletes all jobs results. Currently executing or queued async jobs will not be stopped by this call. *expired: Deletes expired results. To determine the expiration status of a result, pass the stamp URL parameter. stamp needs to be a UNIX timestamp, and all async job results created at a lower timestamp will be deleted. *an actual job-id: In this case, the call will remove the result of the specified async job. If the job is currently executing or queued, it will not be aborted.
", - "format": "string", - "in": "path", - "name": "type", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the deletion operation was carried out successfully. This code will also be returned if no results were deleted.
" - }, - "400": { - "description": "is returned if type is not specified or has an invalid value.
" - }, - "404": { - "description": "is returned if type is a job-id but no async job with the specified id was found.
" - } - }, - "summary": " Deletes async job", - "tags": [ - "job" - ], - "x-examples": [], - "x-filename": "job - arangod/HttpServer/AsyncJobManager.cpp, arangod/RestHandler/RestJobHandler.cpp" - }, - "get": { - "description": "\n\nReturns the list of ids of async jobs with a specific status (either done or pending). The list can be used by the client to get an overview of the job system status and to retrieve completed job results later.

Example: Fetching the list of done jobs:

shell> curl -X PUT --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 603118023\n\nshell> curl --dump - http://localhost:8529/_api/job/done\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  \"603118023\" \n]\n

\n
Example: Fetching the list of pending jobs:

shell> curl -X PUT --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 603183559\n\nshell> curl --dump - http://localhost:8529/_api/job/pending\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ ]\n

\n
Example: Querying the status of a pending job: (we create a sleep job therefore...)

shell> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_admin/sleep?duration=30\n\nHTTP/1.1 202 Accepted\ncontent-type: text/plain; charset=utf-8\nx-arango-async-id: 603249095\n\nshell> curl --dump - http://localhost:8529/_api/job/pending\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  \"603249095\" \n]\nshell> curl -X DELETE --dump - http://localhost:8529/_api/job/603249095\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : true \n}\n

\n
", - "parameters": [ - { - "description": "The type of jobs to return. The type can be either done or pending. Setting the type to done will make the method return the ids of already completed async jobs for which results can be fetched. Setting the type to pending will return the ids of not yet finished async jobs.
", - "format": "string", - "in": "path", - "name": "type", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the list can be compiled successfully. Note: the list might be empty.
" - }, - "400": { - "description": "is returned if type is not specified or has an invalid value.
" - } - }, - "summary": " Returns list of async jobs", - "tags": [ - "job" - ], - "x-examples": [], - "x-filename": "job - arangod/HttpServer/AsyncJobManager.cpp, arangod/RestHandler/RestJobHandler.cpp" - } - }, - "/_api/query": { - "post": { - "description": "**A json post document with these Properties is required:**
  • query: To validate a query string without executing it, the query string can be passed to the server via an HTTP POST request.

Example: a Valid query

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/query <<EOF\n{ \"query\" : \"FOR p IN products FILTER p.name == @name LIMIT 2 RETURN p.n\" }\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"code\" : 200, \n  \"parsed\" : true, \n  \"collections\" : [ \n    \"products\" \n  ], \n  \"bindVars\" : [ \n    \"name\" \n  ], \n  \"ast\" : [ \n    { \n      \"type\" : \"root\", \n      \"subNodes\" : [ \n        { \n          \"type\" : \"for\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"variable\", \n              \"name\" : \"p\", \n              \"id\" : 0 \n            }, \n            { \n              \"type\" : \"collection\", \n              \"name\" : \"products\" \n            } \n          ] \n        }, \n        { \n          \"type\" : \"filter\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"compare ==\", \n              \"subNodes\" : [ \n                { \n                  \"type\" : \"attribute access\", \n                  \"name\" : \"name\", \n                  \"subNodes\" : [ \n                    { \n                      \"type\" : \"reference\", \n                      \"name\" : \"p\", \n                      \"id\" : 0 \n                    } \n                  ] \n                }, \n                { \n                  \"type\" : \"parameter\", \n                  \"name\" : \"name\" \n                } \n              ] \n            } \n          ] \n        }, \n        { \n          \"type\" : \"limit\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"value\", \n              \"value\" : 0 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 2 \n            } \n          ] \n        }, \n        { \n          \"type\" : \"return\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"attribute access\", \n              \"name\" : \"n\", \n              \"subNodes\" : [ \n                { \n                  \"type\" : \"reference\", \n                  \"name\" : \"p\", \n                  \"id\" : 0 \n                } \n              ] \n            } \n          ] \n        } \n      ] \n    } \n  ], \n  \"warnings\" : [ ] \n}\n

\n
Example: an Invalid query

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/query <<EOF\n{ \"query\" : \"FOR p IN products FILTER p.name = @name LIMIT 2 RETURN p.n\" }\nEOF\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"syntax error, unexpected assignment near '= @name LIMIT 2 RETURN p.n' at position 1:33\", \n  \"code\" : 400, \n  \"errorNum\" : 1501 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/PostApiQueryProperties" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the query is valid, the server will respond with HTTP 200 and return the names of the bind parameters it found in the query (if any) in the bindVars attribute of the response. It will also return an array of the collections used in the query in the collections attribute. If a query can be parsed successfully, the ast attribute of the returned JSON will contain the abstract syntax tree representation of the query. The format of the ast is subject to change in future versions of ArangoDB, but it can be used to inspect how ArangoDB interprets a given query. Note that the abstract syntax tree will be returned without any optimizations applied to it.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request, or if the query contains a parse error. The body of the response will contain the error details embedded in a JSON object.
" - } - }, - "summary": " Parse an AQL query", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/query-cache": { - "delete": { - "description": "\n\nclears the query cache", - "parameters": [], - "responses": { - "200": { - "description": "The server will respond with HTTP 200 when the cache was cleared successfully.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request.
" - } - }, - "summary": " Clears any results in the AQL query cache", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/query-cache/properties": { - "get": { - "description": "\n\nReturns the global AQL query cache configuration. The configuration is a JSON object with the following properties:
  • mode: the mode the AQL query cache operates in. The mode is one of the following values: off, on or demand.
  • maxResults: the maximum number of query results that will be stored per database-specific cache.
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned if the properties can be retrieved successfully.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request,

" - } - }, - "summary": " Returns the global properties for the AQL query cache", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "put": { - "description": "\n\nAfter the properties have been changed, the current set of properties will be returned in the HTTP response.
Note: changing the properties may invalidate all results in the cache. The global properties for AQL query cache. The properties need to be passed in the attribute properties in the body of the HTTP request. properties needs to be a JSON object with the following properties:
**A json post document with these Properties is required:**
  • mode: the mode the AQL query cache should operate in. Possible values are off, on or demand.
  • maxResults: the maximum number of query results that will be stored per database-specific cache.

", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/PutApiQueryCacheProperties" - }, - "x-description-offset": 489 - } - ], - "responses": { - "200": { - "description": "Is returned if the properties were changed successfully.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request,

" - } - }, - "summary": " Globally adjusts the AQL query result cache properties", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/query/current": { - "get": { - "description": "\n\nReturns an array containing the AQL queries currently running in the selected database. Each query is a JSON object with the following attributes:
  • id: the query's id
  • query: the query string (potentially truncated)
  • started: the date and time when the query was started
  • runTime: the query's run time up to the point the list of queries was queried
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned when the list of queries can be retrieved successfully.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request,

" - } - }, - "summary": " Returns the currently running AQL queries", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/query/properties": { - "get": { - "description": "\n\nReturns the current query tracking configuration. The configuration is a JSON object with the following properties:
  • enabled: if set to true, then queries will be tracked. If set to false, neither queries nor slow queries will be tracked.
  • trackSlowQueries: if set to true, then slow queries will be tracked in the list of slow queries if their runtime exceeds the value set in slowQueryThreshold. In order for slow queries to be tracked, the enabled property must also be set to true.
  • maxSlowQueries: the maximum number of slow queries to keep in the list of slow queries. If the list of slow queries is full, the oldest entry in it will be discarded when additional slow queries occur.
  • slowQueryThreshold: the threshold value for treating a query as slow. A query with a runtime greater or equal to this threshold value will be put into the list of slow queries when slow query tracking is enabled. The value for slowQueryThreshold is specified in seconds.
  • maxQueryStringLength: the maximum query string length to keep in the list of queries. Query strings can have arbitrary lengths, and this property can be used to save memory in case very long query strings are used. The value is specified in bytes.
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned if properties were retrieved successfully.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request,

" - } - }, - "summary": " Returns the properties for the AQL query tracking", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "put": { - "description": "**A json post document with these Properties is required:**
  • slowQueryThreshold: The threshold value for treating a query as slow. A query with a runtime greater or equal to this threshold value will be put into the list of slow queries when slow query tracking is enabled. The value for slowQueryThreshold is specified in seconds.
  • enabled: If set to true, then queries will be tracked. If set to false, neither queries nor slow queries will be tracked.
  • maxSlowQueries: The maximum number of slow queries to keep in the list of slow queries. If the list of slow queries is full, the oldest entry in it will be discarded when additional slow queries occur.
  • trackSlowQueries: If set to true, then slow queries will be tracked in the list of slow queries if their runtime exceeds the value set in slowQueryThreshold. In order for slow queries to be tracked, the enabled property must also be set to true.
  • maxQueryStringLength: The maximum query string length to keep in the list of queries. Query strings can have arbitrary lengths, and this property can be used to save memory in case very long query strings are used. The value is specified in bytes.
\n\nThe properties need to be passed in the attribute properties in the body of the HTTP request. properties needs to be a JSON object.
After the properties have been changed, the current set of properties will be returned in the HTTP response.
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/PutApiQueryProperties" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "Is returned if the properties were changed successfully.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request,

" - } - }, - "summary": " Changes the properties for the AQL query tracking", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/query/slow": { - "delete": { - "description": "\n\nClears the list of slow AQL queries
", - "parameters": [], - "responses": { - "200": { - "description": "The server will respond with HTTP 200 when the list of queries was cleared successfully.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request.
" - } - }, - "summary": " Clears the list of slow AQL queries", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - }, - "get": { - "description": "\n\nReturns an array containing the last AQL queries that exceeded the slow query threshold in the selected database. The maximum amount of queries in the list can be controlled by setting the query tracking property `maxSlowQueries`. The threshold for treating a query as slow can be adjusted by setting the query tracking property `slowQueryThreshold`.
Each query is a JSON object with the following attributes:
  • id: the query's id
  • query: the query string (potentially truncated)
  • started: the date and time when the query was started
  • runTime: the query's run time up to the point the list of queries was queried
", - "parameters": [], - "responses": { - "200": { - "description": "Is returned when the list of queries can be retrieved successfully.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request,

" - } - }, - "summary": " Returns the list of slow AQL queries", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/query/{query-id}": { - "delete": { - "description": "\n\nKills a running query. The query will be terminated at the next cancelation point.
", - "parameters": [ - { - "description": "The id of the query.
", - "format": "string", - "in": "path", - "name": "query-id", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "The server will respond with HTTP 200 when the query was still running when the kill request was executed and the query's kill flag was set.
" - }, - "400": { - "description": "The server will respond with HTTP 400 in case of a malformed request.
" - }, - "404": { - "description": "The server will respond with HTTP 404 when no query with the specified id was found.
" - } - }, - "summary": " Kills a running AQL query", - "tags": [ - "AQL" - ], - "x-examples": [], - "x-filename": "AQL - arangod/RestHandler/RestQueryHandler.cpp, js/actions/api-aqlfunction.js, js/actions/api-explain.js, arangod/RestHandler/RestQueryCacheHandler.cpp" - } - }, - "/_api/replication/applier-config": { - "get": { - "description": "\n\nReturns the configuration of the replication applier.
The body of the response is a JSON object with the configuration. The following attributes may be present in the configuration:
  • endpoint: the logger server to connect to (e.g. \"tcp://192.168.173.13:8529\").
  • database: the name of the database to connect to (e.g. \"_system\").
  • username: an optional ArangoDB username to use when connecting to the endpoint.
  • password: the password to use when connecting to the endpoint.
  • maxConnectRetries: the maximum number of connection attempts the applier will make in a row. If the applier cannot establish a connection to the endpoint in this number of attempts, it will stop itself.
  • connectTimeout: the timeout (in seconds) when attempting to connect to the endpoint. This value is used for each connection attempt.
  • requestTimeout: the timeout (in seconds) for individual requests to the endpoint.
  • chunkSize: the requested maximum size for log transfer packets that is used when the endpoint is contacted.
  • autoStart: whether or not to auto-start the replication applier on (next and following) server starts
  • adaptivePolling: whether or not the replication applier will use adaptive polling.
  • includeSystem: whether or not system collection operations will be applied
  • requireFromPresent: if set to true, then the replication applier will check at start whether the start tick from which it starts or resumes replication is still present on the master. If not, then there would be data loss. If requireFromPresent is true, the replication applier will abort with an appropriate error message. If set to false, then the replication applier will still start, and ignore the data loss.
  • verbose: if set to true, then a log line will be emitted for all operations performed by the replication applier. This should be used for debugging replication problems only.
  • restrictType: the configuration for restrictCollections
  • restrictCollections: the optional array of collections to include or exclude, based on the setting of restrictType

Example:

shell> curl --dump - http://localhost:8529/_api/replication/applier-config\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"requestTimeout\" : 300, \n  \"connectTimeout\" : 10, \n  \"ignoreErrors\" : 0, \n  \"maxConnectRetries\" : 100, \n  \"sslProtocol\" : 0, \n  \"chunkSize\" : 0, \n  \"autoStart\" : false, \n  \"adaptivePolling\" : true, \n  \"includeSystem\" : true, \n  \"requireFromPresent\" : false, \n  \"verbose\" : false, \n  \"restrictType\" : \"\", \n  \"restrictCollections\" : [ ] \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " Return configuration of replication applier", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - }, - "put": { - "description": "**A json post document with these Properties is required:**
  • username: an optional ArangoDB username to use when connecting to the endpoint.
  • includeSystem: whether or not system collection operations will be applied
  • endpoint: the logger server to connect to (e.g. \"tcp://192.168.173.13:8529\"). The endpoint must be specified.
  • verbose: if set to true, then a log line will be emitted for all operations performed by the replication applier. This should be used for debugging replication problems only.
  • connectTimeout: the timeout (in seconds) when attempting to connect to the endpoint. This value is used for each connection attempt.
  • database: the name of the database on the endpoint. If not specified, defaults to the current local database name.
  • restrictType: the configuration for restrictCollections; Has to be either include or exclude
  • requestTimeout: the timeout (in seconds) for individual requests to the endpoint.
  • requireFromPresent: if set to true, then the replication applier will check at start whether the start tick from which it starts or resumes replication is still present on the master. If not, then there would be data loss. If requireFromPresent is true, the replication applier will abort with an appropriate error message. If set to false, then the replication applier will still start, and ignore the data loss.
  • maxConnectRetries: the maximum number of connection attempts the applier will make in a row. If the applier cannot establish a connection to the endpoint in this number of attempts, it will stop itself.
  • autoStart: whether or not to auto-start the replication applier on (next and following) server starts
  • adaptivePolling: if set to true, the replication applier will fall to sleep for an increasingly long period in case the logger server at the endpoint does not have any more replication events to apply. Using adaptive polling is thus useful to reduce the amount of work for both the applier and the logger server for cases when there are only infrequent changes. The downside is that when using adaptive polling, it might take longer for the replication applier to detect that there are new replication events on the logger server.
    Setting adaptivePolling to false will make the replication applier contact the logger server in a constant interval, regardless of whether the logger server provides updates frequently or seldom.
  • password: the password to use when connecting to the endpoint.
  • restrictCollections: the array of collections to include or exclude, based on the setting of restrictType of type string
  • chunkSize: the requested maximum size for log transfer packets that is used when the endpoint is contacted.
\n\nSets the configuration of the replication applier. The configuration can only be changed while the applier is not running. The updated configuration will be saved immediately but only become active with the next start of the applier.
In case of success, the body of the response is a JSON object with the updated configuration.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/replication/applier-config <<EOF\n{ \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"username\" : \"replicationApplier\", \n  \"password\" : \"applier1234@foxx\", \n  \"chunkSize\" : 4194304, \n  \"autoStart\" : false, \n  \"adaptivePolling\" : true \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\", \n  \"username\" : \"replicationApplier\", \n  \"requestTimeout\" : 300, \n  \"connectTimeout\" : 10, \n  \"ignoreErrors\" : 0, \n  \"maxConnectRetries\" : 100, \n  \"sslProtocol\" : 0, \n  \"chunkSize\" : 4194304, \n  \"autoStart\" : false, \n  \"adaptivePolling\" : true, \n  \"includeSystem\" : true, \n  \"requireFromPresent\" : false, \n  \"verbose\" : false, \n  \"restrictType\" : \"\", \n  \"restrictCollections\" : [ ] \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_put_api_replication_applier_adjust" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "400": { - "description": "is returned if the configuration is incomplete or malformed, or if the replication applier is currently running.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " Adjust configuration of replication applier", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/applier-start": { - "put": { - "description": "\n\nStarts the replication applier. This will return immediately if the replication applier is already running.
If the replication applier is not already running, the applier configuration will be checked, and if it is complete, the applier will be started in a background thread. This means that even if the applier will encounter any errors while running, they will not be reported in the response to this method.
To detect replication applier errors after the applier was started, use the /_api/replication/applier-state API instead.

Example:

shell> curl -X PUT --dump - http://localhost:8529/_api/replication/applier-start\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"safeResumeTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2015-09-30T15:38:57Z\", \n      \"message\" : \"applier created\", \n      \"failedConnects\" : 0 \n    }, \n    \"totalRequests\" : 0, \n    \"totalFailedConnects\" : 0, \n    \"totalEvents\" : 0, \n    \"totalOperationsExcluded\" : 0, \n    \"lastError\" : { \n      \"errorNum\" : 0 \n    }, \n    \"time\" : \"2015-09-30T15:40:09Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.7.0-devel\", \n    \"serverId\" : \"4865533481307\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n

\n
", - "parameters": [ - { - "description": "The remote lastLogTick value from which to start applying. If not specified, the last saved tick from the previous applier run is used. If there is no previous applier state saved, the applier will start at the beginning of the logger server's log.
", - "in": "query", - "name": "from", - "required": false, - "type": "string" - } - ], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "400": { - "description": "is returned if the replication applier is not fully configured or the configuration is invalid.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " Start replication applier", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/applier-state": { - "get": { - "description": "\n\nReturns the state of the replication applier, regardless of whether the applier is currently running or not.
The response is a JSON object with the following attributes:
  • state: a JSON object with the following sub-attributes:
    - running: whether or not the applier is active and running
    - lastAppliedContinuousTick: the last tick value from the continuous replication log the applier has applied.
    - lastProcessedContinuousTick: the last tick value from the continuous replication log the applier has processed.
    Regularly, the last applied and last processed tick values should be identical. For transactional operations, the replication applier will first process incoming log events before applying them, so the processed tick value might be higher than the applied tick value. This will be the case until the applier encounters the transaction commit log event for the transaction.
    - lastAvailableContinuousTick: the last tick value the logger server can provide.
    - time: the time on the applier server.
    - totalRequests: the total number of requests the applier has made to the endpoint.
    - totalFailedConnects: the total number of failed connection attempts the applier has made.
    - totalEvents: the total number of log events the applier has processed.
    - totalOperationsExcluded: the total number of log events excluded because of restrictCollections.
    - progress: a JSON object with details about the replication applier progress. It contains the following sub-attributes if there is progress to report:
    - message: a textual description of the progress
    - time: the date and time the progress was logged
    - failedConnects: the current number of failed connection attempts
    - lastError: a JSON object with details about the last error that happened on the applier. It contains the following sub-attributes if there was an error:
    - errorNum: a numerical error code
    - errorMessage: a textual error description
    - time: the date and time the error occurred
    In case no error has occurred, lastError will be empty.
  • server: a JSON object with the following sub-attributes:
    - version: the applier server's version
    - serverId: the applier server's id
  • endpoint: the endpoint the applier is connected to (if applier is active) or will connect to (if applier is currently inactive)
  • database: the name of the database the applier is connected to (if applier is active) or will connect to (if applier is currently inactive)

Example: Fetching the state of an inactive applier:

shell> curl --dump - http://localhost:8529/_api/replication/applier-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : false, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"safeResumeTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2015-09-30T15:40:09Z\", \n      \"message\" : \"applier shut down\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 1, \n    \"totalFailedConnects\" : 1, \n    \"totalEvents\" : 0, \n    \"totalOperationsExcluded\" : 0, \n    \"lastError\" : { \n      \"time\" : \"2015-09-30T15:40:10Z\", \n      \"errorMessage\" : \"could not connect to master at tcp://127.0.0.1:8529: Could not connect to 'tcp://127.0.0.1:8529' 'connect() failed with #111 - Connection refused'\", \n      \"errorNum\" : 1412 \n    }, \n    \"time\" : \"2015-09-30T15:40:10Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.7.0-devel\", \n    \"serverId\" : \"4865533481307\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n

\n
Example: Fetching the state of an active applier:

shell> curl --dump - http://localhost:8529/_api/replication/applier-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"safeResumeTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2015-09-30T15:40:10Z\", \n      \"message\" : \"fetching master state information\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 2, \n    \"totalFailedConnects\" : 2, \n    \"totalEvents\" : 0, \n    \"totalOperationsExcluded\" : 0, \n    \"lastError\" : { \n      \"errorNum\" : 0 \n    }, \n    \"time\" : \"2015-09-30T15:40:10Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.7.0-devel\", \n    \"serverId\" : \"4865533481307\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " State of the replication applier", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/applier-stop": { - "put": { - "description": "\n\nStops the replication applier. This will return immediately if the replication applier is not running.

Example:

shell> curl -X PUT --dump - http://localhost:8529/_api/replication/applier-stop\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : false, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"safeResumeTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2015-09-30T15:40:10Z\", \n      \"message\" : \"applier shut down\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 3, \n    \"totalFailedConnects\" : 3, \n    \"totalEvents\" : 0, \n    \"totalOperationsExcluded\" : 0, \n    \"lastError\" : { \n      \"time\" : \"2015-09-30T15:40:11Z\", \n      \"errorMessage\" : \"could not connect to master at tcp://127.0.0.1:8529: Could not connect to 'tcp://127.0.0.1:8529' 'connect() failed with #111 - Connection refused'\", \n      \"errorNum\" : 1412 \n    }, \n    \"time\" : \"2015-09-30T15:40:11Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.7.0-devel\", \n    \"serverId\" : \"4865533481307\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " Stop replication applier", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/batch": { - "post": { - "description": "**A json post document with these Properties is required:**
  • ttl: the time-to-live for the new batch (in seconds)
    A JSON object with the batch configuration.
\n\nCreates a new dump batch and returns the batch's id.
The response is a JSON object with the following attributes:
  • id: the id of the batch
Note: on a coordinator, this request must have the URL parameter DBserver which must be an ID of a DBserver. The very same request is forwarded synchronously to that DBserver. It is an error if this attribute is not bound in the coordinator case.
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_batch_replication" - }, - "x-description-offset": 59 - } - ], - "responses": { - "204": { - "description": "is returned if the batch was created successfully.
" - }, - "400": { - "description": "is returned if the ttl value is invalid or if DBserver attribute is not specified or illegal on a coordinator.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - } - }, - "summary": " Create new dump batch", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/batch/{id}": { - "delete": { - "description": "\n\nDeletes the existing dump batch, allowing compaction and cleanup to resume.
Note: on a coordinator, this request must have the URL parameter DBserver which must be an ID of a DBserver. The very same request is forwarded synchronously to that DBserver. It is an error if this attribute is not bound in the coordinator case.
", - "parameters": [ - { - "description": "The id of the batch.
", - "format": "string", - "in": "path", - "name": "id", - "required": true, - "type": "string" - } - ], - "responses": { - "204": { - "description": "is returned if the batch was deleted successfully.
" - }, - "400": { - "description": "is returned if the batch was not found.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - } - }, - "summary": " Deletes an existing dump batch", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - }, - "put": { - "description": "**A json post document with these Properties is required:**
  • ttl: the time-to-live for the new batch (in seconds)
\n\nExtends the ttl of an existing dump batch, using the batch's id and the provided ttl value.
If the batch's ttl can be extended successfully, the response is empty.
Note: on a coordinator, this request must have the URL parameter DBserver which must be an ID of a DBserver. The very same request is forwarded synchronously to that DBserver. It is an error if this attribute is not bound in the coordinator case.
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_put_batch_replication" - }, - "x-description-offset": 59 - }, - { - "description": "The id of the batch.
", - "format": "string", - "in": "path", - "name": "id", - "required": true, - "type": "string" - } - ], - "responses": { - "204": { - "description": "is returned if the batch's ttl was extended successfully.
" - }, - "400": { - "description": "is returned if the ttl value is invalid or the batch was not found.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - } - }, - "summary": " Prolong existing dump batch", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/clusterInventory": { - "get": { - "description": "\n\nReturns the array of collections and indexes available on the cluster.
The response will be an array of JSON objects, one for each collection. Each collection containscontains exactly two keys \"parameters\" and \"indexes\". This information comes from Plan/Collections/{DB-Name}/* in the agency, just that the indexes attribute there is relocated to adjust it to the data format of arangodump.
", - "parameters": [ - { - "description": "Include system collections in the result. The default value is true.
", - "in": "query", - "name": "includeSystem", - "required": false, - "type": "boolean" - } - ], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " Return cluster inventory of collections and indexes", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/dump": { - "get": { - "description": "\n\nReturns the data from the collection for the requested range.
When the from URL parameter is not used, collection events are returned from the beginning. When the from parameter is used, the result will only contain collection entries which have higher tick values than the specified from value (note: the log entry with a tick value equal to from will be excluded).
The to URL parameter can be used to optionally restrict the upper bound of the result to a certain tick value. If used, the result will only contain collection entries with tick values up to (including) to.
The chunkSize URL parameter can be used to control the size of the result. It must be specified in bytes. The chunkSize value will only be honored approximately. Otherwise a too low chunkSize value could cause the server to not be able to put just one entry into the result and return it. Therefore, the chunkSize value will only be consulted after an entry has been written into the result. If the result size is then bigger than chunkSize, the server will respond with as many entries as there are in the response already. If the result size is still smaller than chunkSize, the server will try to return more data if there's more data left to return.
If chunkSize is not specified, some server-side default value will be used.
The Content-Type of the result is application/x-arango-dump. This is an easy-to-process format, with all entries going onto separate lines in the response body.
Each line itself is a JSON object, with at least the following attributes:
  • tick: the operation's tick attribute
  • key: the key of the document/edge or the key used in the deletion operation
  • rev: the revision id of the document/edge or the deletion operation
  • data: the actual document/edge data for types 2300 and 2301. The full document/edge data will be returned even for updates.
  • type: the type of entry. Possible values for type are:
    - 2300: document insertion/update
    - 2301: edge insertion/update
    - 2302: document/edge deletion
Note: there will be no distinction between inserts and updates when calling this method.

Example: Empty collection:

shell> curl --dump - http://localhost:8529/_api/replication/dump?collection=testCollection\n\nHTTP/1.1 204 No Content\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 0\n\n

\n
Example: Non-empty collection:

shell> curl --dump - http://localhost:8529/_api/replication/dump?collection=testCollection\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 766695879\n\n\"{\\\"tick\\\":\\\"766040519\\\",\\\"type\\\":2300,\\\"key\\\":\\\"123456\\\",\\\"rev\\\":\\\"765974983\\\",\\\"data\\\":{\\\"_key\\\":\\\"123456\\\",\\\"_rev\\\":\\\"765974983\\\",\\\"c\\\":false,\\\"b\\\":1,\\\"d\\\":\\\"additional value\\\"}}\\n{\\\"tick\\\":\\\"766499271\\\",\\\"type\\\":2302,\\\"key\\\":\\\"foobar\\\",\\\"rev\\\":\\\"766433735\\\"}\\n{\\\"tick\\\":\\\"766695879\\\",\\\"type\\\":2302,\\\"key\\\":\\\"abcdef\\\",\\\"rev\\\":\\\"766630343\\\"}\\n\"\n

\n
", - "parameters": [ - { - "description": "The name or id of the collection to dump.
", - "in": "query", - "name": "collection", - "required": true, - "type": "string" - }, - { - "description": "Lower bound tick value for results.
", - "in": "query", - "name": "from", - "required": false, - "type": "number" - }, - { - "description": "Upper bound tick value for results.
", - "in": "query", - "name": "to", - "required": false, - "type": "number" - }, - { - "description": "Approximate maximum size of the returned result.
", - "in": "query", - "name": "chunkSize", - "required": false, - "type": "number" - }, - { - "description": "Include system collections in the result. The default value is true.
", - "in": "query", - "name": "includeSystem", - "required": false, - "type": "boolean" - }, - { - "description": "Whether or not to include tick values in the dump. The default value is true.
", - "in": "query", - "name": "ticks", - "required": false, - "type": "boolean" - }, - { - "description": "Whether or not to flush the WAL before dumping. The default value is true.
", - "in": "query", - "name": "flush", - "required": false, - "type": "boolean" - } - ], - "responses": { - "200": { - "description": "is returned if the request was executed successfully and data was returned. The header `x-arango-replication-lastincluded` is set to the tick of the last document returned.
" - }, - "204": { - "description": "is returned if the request was executed successfully, but there was no content available. The header `x-arango-replication-lastincluded` is `0` in this case.
" - }, - "400": { - "description": "is returned if either the from or to values are invalid.
" - }, - "404": { - "description": "is returned when the collection could not be found.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " Return data of a collection", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/inventory": { - "get": { - "description": "\n\nReturns the array of collections and indexes available on the server. This array can be used by replication clients to initiate an initial sync with the server.
The response will contain a JSON object with the collection and state and tick attributes.
collections is a array of collections with the following sub-attributes:
  • parameters: the collection properties
  • indexes: a array of the indexes of a the collection. Primary indexes and edges indexes are not included in this array.
The state attribute contains the current state of the replication logger. It contains the following sub-attributes:
  • running: whether or not the replication logger is currently active. Note: since ArangoDB 2.2, the value will always be true
  • lastLogTick: the value of the last tick the replication logger has written
  • time: the current time on the server
Replication clients should note the lastLogTick value returned. They can then fetch collections' data using the dump method up to the value of lastLogTick, and query the continuous replication log for log events after this tick value.
To create a full copy of the collections on the server, a replication client can execute these steps:
  • call the /inventory API method. This returns the lastLogTick value and the array of collections and indexes from the server.
  • for each collection returned by /inventory, create the collection locally and call /dump to stream the collection data to the client, up to the value of lastLogTick. After that, the client can create the indexes on the collections as they were reported by /inventory.
If the clients wants to continuously stream replication log events from the logger server, the following additional steps need to be carried out:
  • the client should call /logger-follow initially to fetch the first batch of replication events that were logged after the client's call to /inventory.
    The call to /logger-follow should use a from parameter with the value of the lastLogTick as reported by /inventory. The call to /logger-follow will return the x-arango-replication-lastincluded which will contain the last tick value included in the response.
  • the client can then continuously call /logger-follow to incrementally fetch new replication events that occurred after the last transfer.
    Calls should use a from parameter with the value of the x-arango-replication-lastincluded header of the previous response. If there are no more replication events, the response will be empty and clients can go to sleep for a while and try again later.
Note: on a coordinator, this request must have the URL parameter DBserver which must be an ID of a DBserver. The very same request is forwarded synchronously to that DBserver. It is an error if this attribute is not bound in the coordinator case.

Example:

shell> curl --dump - http://localhost:8529/_api/replication/inventory\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"7199175\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_apps\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"7461319\", \n          \"type\" : \"hash\", \n          \"fields\" : [ \n            \"mount\" \n          ], \n          \"selectivityEstimate\" : 1, \n          \"unique\" : true, \n          \"sparse\" : false \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"4446663\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 4194304, \n        \"name\" : \"_aqlfunctions\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"2087367\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_graphs\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"2218439\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_modules\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"2349511\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 33554432, \n        \"name\" : \"_routing\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"14145991\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_sessions\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"14866887\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_system_users_users\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"252359\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 4194304, \n        \"name\" : \"_users\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"580039\", \n          \"type\" : \"hash\", \n          \"fields\" : [ \n            \"user\" \n          ], \n          \"selectivityEstimate\" : 1, \n          \"unique\" : true, \n          \"sparse\" : true \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"22206919\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"animals\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"21354951\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"demo\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    } \n  ], \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"767351239\", \n    \"totalEvents\" : 4726, \n    \"time\" : \"2015-09-30T15:40:13Z\" \n  }, \n  \"tick\" : \"767351239\" \n}\n

\n
Example: With some additional indexes:

shell> curl --dump - http://localhost:8529/_api/replication/inventory\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"7199175\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_apps\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"7461319\", \n          \"type\" : \"hash\", \n          \"fields\" : [ \n            \"mount\" \n          ], \n          \"selectivityEstimate\" : 1, \n          \"unique\" : true, \n          \"sparse\" : false \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"4446663\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 4194304, \n        \"name\" : \"_aqlfunctions\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"2087367\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_graphs\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"2218439\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_modules\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"2349511\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 33554432, \n        \"name\" : \"_routing\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"14145991\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_sessions\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"14866887\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"_system_users_users\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"252359\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 4194304, \n        \"name\" : \"_users\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"580039\", \n          \"type\" : \"hash\", \n          \"fields\" : [ \n            \"user\" \n          ], \n          \"selectivityEstimate\" : 1, \n          \"unique\" : true, \n          \"sparse\" : true \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"22206919\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"animals\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"21354951\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"demo\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"767416775\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"IndexedCollection1\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"767678919\", \n          \"type\" : \"hash\", \n          \"fields\" : [ \n            \"name\" \n          ], \n          \"selectivityEstimate\" : 1, \n          \"unique\" : false, \n          \"sparse\" : false \n        }, \n        { \n          \"id\" : \"768006599\", \n          \"type\" : \"skiplist\", \n          \"fields\" : [ \n            \"a\", \n            \"b\" \n          ], \n          \"unique\" : true, \n          \"sparse\" : false \n        }, \n        { \n          \"id\" : \"768203207\", \n          \"type\" : \"cap\", \n          \"size\" : 500, \n          \"byteSize\" : 0, \n          \"unique\" : false \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"768399815\", \n        \"indexBuckets\" : 8, \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"IndexedCollection2\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"768596423\", \n          \"type\" : \"fulltext\", \n          \"fields\" : [ \n            \"text\" \n          ], \n          \"unique\" : false, \n          \"sparse\" : true, \n          \"minLength\" : 10 \n        }, \n        { \n          \"id\" : \"768924103\", \n          \"type\" : \"skiplist\", \n          \"fields\" : [ \n            \"a\" \n          ], \n          \"unique\" : false, \n          \"sparse\" : false \n        }, \n        { \n          \"id\" : \"769120711\", \n          \"type\" : \"cap\", \n          \"size\" : 0, \n          \"byteSize\" : 1048576, \n          \"unique\" : false \n        } \n      ] \n    } \n  ], \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"767351239\", \n    \"totalEvents\" : 4739, \n    \"time\" : \"2015-09-30T15:40:13Z\" \n  }, \n  \"tick\" : \"769251783\" \n}\n

\n
", - "parameters": [ - { - "description": "Include system collections in the result. The default value is true.
", - "in": "query", - "name": "includeSystem", - "required": false, - "type": "boolean" - } - ], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " Return inventory of collections and indexes", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/logger-first-tick": { - "get": { - "description": "\n\nReturns the first available tick value that can be served from the server's replication log. This method can be called by replication clients after to determine if certain data (identified by a tick value) is still available for replication.
The result is a JSON object containing the attribute firstTick. This attribute contains the minimum tick value available in the server's replication log.
Note: this method is not supported on a coordinator in a cluster.

Example: Returning the first available tick

shell> curl --dump - http://localhost:8529/_api/replication/logger-first-tick\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n\"{\\\"firstTick\\\":\\\"383431\\\"}\"\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - }, - "501": { - "description": "is returned when this operation is called on a coordinator in a cluster.
" - } - }, - "summary": " Returns the first available tick value", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/logger-follow": { - "get": { - "description": "\n\nReturns data from the server's replication log. This method can be called by replication clients after an initial synchronization of data. The method will return all \"recent\" log entries from the logger server, and the clients can replay and apply these entries locally so they get to the same data state as the logger server.
Clients can call this method repeatedly to incrementally fetch all changes from the logger server. In this case, they should provide the from value so they will only get returned the log events since their last fetch.
When the from URL parameter is not used, the logger server will return log entries starting at the beginning of its replication log. When the from parameter is used, the logger server will only return log entries which have higher tick values than the specified from value (note: the log entry with a tick value equal to from will be excluded). Use the from value when incrementally fetching log data.
The to URL parameter can be used to optionally restrict the upper bound of the result to a certain tick value. If used, the result will contain only log events with tick values up to (including) to. In incremental fetching, there is no need to use the to parameter. It only makes sense in special situations, when only parts of the change log are required.
The chunkSize URL parameter can be used to control the size of the result. It must be specified in bytes. The chunkSize value will only be honored approximately. Otherwise a too low chunkSize value could cause the server to not be able to put just one log entry into the result and return it. Therefore, the chunkSize value will only be consulted after a log entry has been written into the result. If the result size is then bigger than chunkSize, the server will respond with as many log entries as there are in the response already. If the result size is still smaller than chunkSize, the server will try to return more data if there's more data left to return.
If chunkSize is not specified, some server-side default value will be used.
The Content-Type of the result is application/x-arango-dump. This is an easy-to-process format, with all log events going onto separate lines in the response body. Each log event itself is a JSON object, with at least the following attributes:
  • tick: the log event tick value
  • type: the log event type
Individual log events will also have additional attributes, depending on the event type. A few common attributes which are used for multiple events types are:
  • cid: id of the collection the event was for
  • tid: id of the transaction the event was contained in
  • key: document key
  • rev: document revision id
  • data: the original document data
A more detailed description of the individual replication event types and their data structures can be found in the manual.
The response will also contain the following HTTP headers:
  • x-arango-replication-active: whether or not the logger is active. Clients can use this flag as an indication for their polling frequency. If the logger is not active and there are no more replication events available, it might be sensible for a client to abort, or to go to sleep for a long time and try again later to check whether the logger has been activated.
  • x-arango-replication-lastincluded: the tick value of the last included value in the result. In incremental log fetching, this value can be used as the from value for the following request. Note that if the result is empty, the value will be 0. This value should not be used as from value by clients in the next request (otherwise the server would return the log events from the start of the log again).
  • x-arango-replication-lasttick: the last tick value the logger server has logged (not necessarily included in the result). By comparing the the last tick and last included tick values, clients have an approximate indication of how many events there are still left to fetch.
  • x-arango-replication-checkmore: whether or not there already exists more log data which the client could fetch immediately. If there is more log data available, the client could call logger-follow again with an adjusted from value to fetch remaining log entries until there are no more.
    If there isn't any more log data to fetch, the client might decide to go to sleep for a while before calling the logger again.
Note: this method is not supported on a coordinator in a cluster.

Example: No log events available

shell> curl --dump - http://localhost:8529/_api/replication/logger-follow?from=770628039\n\nHTTP/1.1 204 No Content\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: false\nx-arango-replication-frompresent: true\nx-arango-replication-lastincluded: 0\nx-arango-replication-lasttick: 770628039\n\n

\n
Example: A few log events

shell> curl --dump - http://localhost:8529/_api/replication/logger-follow?from=770628039\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: false\nx-arango-replication-frompresent: true\nx-arango-replication-lastincluded: 771873223\nx-arango-replication-lasttick: 771873223\n\n\"{\\\"tick\\\":\\\"770759111\\\",\\\"type\\\":2000,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"770693575\\\",\\\"collection\\\":{\\\"version\\\":5,\\\"type\\\":2,\\\"cid\\\":\\\"770693575\\\",\\\"indexBuckets\\\":8,\\\"deleted\\\":false,\\\"doCompact\\\":true,\\\"maximalSize\\\":1048576,\\\"name\\\":\\\"products\\\",\\\"isVolatile\\\":false,\\\"waitForSync\\\":false}}\\n{\\\"tick\\\":\\\"771086791\\\",\\\"type\\\":2300,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"770693575\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"771021255\\\",\\\"data\\\":{\\\"_key\\\":\\\"p1\\\",\\\"_rev\\\":\\\"771021255\\\",\\\"name\\\":\\\"flux compensator\\\"}}\\n{\\\"tick\\\":\\\"771414471\\\",\\\"type\\\":2300,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"770693575\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p2\\\",\\\"rev\\\":\\\"771348935\\\",\\\"data\\\":{\\\"_key\\\":\\\"p2\\\",\\\"_rev\\\":\\\"771348935\\\",\\\"hp\\\":5100,\\\"name\\\":\\\"hybrid hovercraft\\\"}}\\n{\\\"tick\\\":\\\"771611079\\\",\\\"type\\\":2302,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"770693575\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"771545543\\\"}\\n{\\\"tick\\\":\\\"771807687\\\",\\\"type\\\":2300,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"770693575\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p2\\\",\\\"rev\\\":\\\"771742151\\\",\\\"data\\\":{\\\"_key\\\":\\\"p2\\\",\\\"_rev\\\":\\\"771742151\\\"}}\\n{\\\"tick\\\":\\\"771873223\\\",\\\"type\\\":2001,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"770693575\\\"}\\n\"\n

\n
Example: More events than would fit into the response

shell> curl --dump - http://localhost:8529/_api/replication/logger-follow?from=769317319&chunkSize=400\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: true\nx-arango-replication-frompresent: true\nx-arango-replication-lastincluded: 769841607\nx-arango-replication-lasttick: 770628039\n\n\"{\\\"tick\\\":\\\"769382855\\\",\\\"type\\\":2001,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"768399815\\\"}\\n{\\\"tick\\\":\\\"769513927\\\",\\\"type\\\":2000,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"769448391\\\",\\\"collection\\\":{\\\"version\\\":5,\\\"type\\\":2,\\\"cid\\\":\\\"769448391\\\",\\\"indexBuckets\\\":8,\\\"deleted\\\":false,\\\"doCompact\\\":true,\\\"maximalSize\\\":1048576,\\\"name\\\":\\\"products\\\",\\\"isVolatile\\\":false,\\\"waitForSync\\\":false}}\\n{\\\"tick\\\":\\\"769841607\\\",\\\"type\\\":2300,\\\"database\\\":\\\"121287\\\",\\\"cid\\\":\\\"769448391\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"769776071\\\",\\\"data\\\":{\\\"_key\\\":\\\"p1\\\",\\\"_rev\\\":\\\"769776071\\\",\\\"name\\\":\\\"flux compensator\\\"}}\\n\"\n

\n
", - "parameters": [ - { - "description": "Lower bound tick value for results.
", - "in": "query", - "name": "from", - "required": false, - "type": "number" - }, - { - "description": "Upper bound tick value for results.
", - "in": "query", - "name": "to", - "required": false, - "type": "number" - }, - { - "description": "Approximate maximum size of the returned result.
", - "in": "query", - "name": "chunkSize", - "required": false, - "type": "number" - }, - { - "description": "Include system collections in the result. The default value is true.
", - "in": "query", - "name": "includeSystem", - "required": false, - "type": "boolean" - } - ], - "responses": { - "200": { - "description": "is returned if the request was executed successfully, and there are log events available for the requested range. The response body will not be empty in this case.
" - }, - "204": { - "description": "is returned if the request was executed successfully, but there are no log events available for the requested range. The response body will be empty in this case.
" - }, - "400": { - "description": "is returned if either the from or to values are invalid.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - }, - "501": { - "description": "is returned when this operation is called on a coordinator in a cluster.
" - } - }, - "summary": " Returns log entries", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/logger-state": { - "get": { - "description": "\n\nReturns the current state of the server's replication logger. The state will include information about whether the logger is running and about the last logged tick value. This tick value is important for incremental fetching of data.
The body of the response contains a JSON object with the following attributes:
  • state: the current logger state as a JSON object with the following sub-attributes:
    - running: whether or not the logger is running
    - lastLogTick: the tick value of the latest tick the logger has logged. This value can be used for incremental fetching of log data.
    - totalEvents: total number of events logged since the server was started. The value is not reset between multiple stops and re-starts of the logger.
    - time: the current date and time on the logger server
  • server: a JSON object with the following sub-attributes:
    - version: the logger server's version
    - serverId: the logger server's id
  • clients: returns the last fetch status by replication clients connected to the logger. Each client is returned as a JSON object with the following attributes:
    - serverId: server id of client
    - lastServedTick: last tick value served to this client via the logger-follow API
    - time: date and time when this client last called the logger-follow API

Example: Returns the state of the replication logger.

shell> curl --dump - http://localhost:8529/_api/replication/logger-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"771873223\", \n    \"totalEvents\" : 4761, \n    \"time\" : \"2015-09-30T15:40:17Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.7.0-devel\", \n    \"serverId\" : \"4865533481307\" \n  }, \n  \"clients\" : [ ] \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the logger state could be determined successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if the logger state could not be determined.
" - } - }, - "summary": " Return replication logger state", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/logger-tick-ranges": { - "get": { - "description": "\n\nReturns the currently available ranges of tick values for all currently available WAL logfiles. The tick values can be used to determine if certain data (identified by tick value) are still available for replication.
The body of the response contains a JSON array. Each array member is an object that describes a single logfile. Each object has the following attributes:
*datafile: name of the logfile
*status: status of the datafile, in textual form (e.g. \"sealed\", \"open\")
*tickMin: minimum tick value contained in logfile
*tickMax: maximum tick value contained in logfile

Example: Returns the available tick ranges.

shell> curl --dump - http://localhost:8529/_api/replication/logger-tick-ranges\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  { \n    \"datafile\" : \"/tmp/vocdir.2239/journals/logfile-186823.db\", \n    \"status\" : \"collected\", \n    \"tickMin\" : \"383431\", \n    \"tickMax\" : \"642505159\" \n  }, \n  { \n    \"datafile\" : \"/tmp/vocdir.2239/journals/logfile-642636231.db\", \n    \"status\" : \"collected\", \n    \"tickMin\" : \"642963911\", \n    \"tickMax\" : \"645716423\" \n  }, \n  { \n    \"datafile\" : \"/tmp/vocdir.2239/journals/logfile-645847495.db\", \n    \"status\" : \"collected\", \n    \"tickMin\" : \"645978567\", \n    \"tickMax\" : \"766695879\" \n  }, \n  { \n    \"datafile\" : \"/tmp/vocdir.2239/journals/logfile-766826951.db\", \n    \"status\" : \"collected\", \n    \"tickMin\" : \"766958023\", \n    \"tickMax\" : \"767089095\" \n  }, \n  { \n    \"datafile\" : \"/tmp/vocdir.2239/journals/logfile-767220167.db\", \n    \"status\" : \"open\", \n    \"tickMin\" : \"767351239\", \n    \"tickMax\" : \"771873223\" \n  } \n]\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the tick ranges could be determined successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if the logger state could not be determined.
" - }, - "501": { - "description": "is returned when this operation is called on a coordinator in a cluster.
" - } - }, - "summary": " Return the tick ranges available in the WAL logfiles", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/make-slave": { - "put": { - "description": "**A json post document with these Properties is required:**
  • username: an optional ArangoDB username to use when connecting to the master.
  • includeSystem: whether or not system collection operations will be applied
  • endpoint: the master endpoint to connect to (e.g. \"tcp://192.168.173.13:8529\").
  • verbose: if set to true, then a log line will be emitted for all operations performed by the replication applier. This should be used for debugging replication problems only.
  • connectTimeout: the timeout (in seconds) when attempting to connect to the endpoint. This value is used for each connection attempt.
  • database: the database name on the master (if not specified, defaults to the name of the local current database).
  • requireFromPresent: if set to true, then the replication applier will check at start of its continuous replication if the start tick from the dump phase is still present on the master. If not, then there would be data loss. If requireFromPresent is true, the replication applier will abort with an appropriate error message. If set to false, then the replication applier will still start, and ignore the data loss.
  • requestTimeout: the timeout (in seconds) for individual requests to the endpoint.
  • restrictType: an optional string value for collection filtering. When specified, the allowed values are include or exclude.
  • restrictCollections: an optional array of collections for use with restrictType. If restrictType is include, only the specified collections will be sychronised. If restrictType is exclude, all but the specified collections will be synchronized. of type string
  • adaptivePolling: whether or not the replication applier will use adaptive polling.
  • maxConnectRetries: the maximum number of connection attempts the applier will make in a row. If the applier cannot establish a connection to the endpoint in this number of attempts, it will stop itself.
  • password: the password to use when connecting to the master.
  • chunkSize: the requested maximum size for log transfer packets that is used when the endpoint is contacted.
\n\nStarts a full data synchronization from a remote endpoint into the local ArangoDB database and afterwards starts the continuous replication. The operation works on a per-database level.
All local database data will be removed prior to the synchronization.
In case of success, the body of the response is a JSON object with the following attributes:
  • state: a JSON object with the following sub-attributes:
    - running: whether or not the applier is active and running
    - lastAppliedContinuousTick: the last tick value from the continuous replication log the applier has applied.
    - lastProcessedContinuousTick: the last tick value from the continuous replication log the applier has processed.
    Regularly, the last applied and last processed tick values should be identical. For transactional operations, the replication applier will first process incoming log events before applying them, so the processed tick value might be higher than the applied tick value. This will be the case until the applier encounters the transaction commit log event for the transaction.
    - lastAvailableContinuousTick: the last tick value the logger server can provide.
    - time: the time on the applier server.
    - totalRequests: the total number of requests the applier has made to the endpoint.
    - totalFailedConnects: the total number of failed connection attempts the applier has made.
    - totalEvents: the total number of log events the applier has processed.
    - totalOperationsExcluded: the total number of log events excluded because of restrictCollections.
    - progress: a JSON object with details about the replication applier progress. It contains the following sub-attributes if there is progress to report:
    - message: a textual description of the progress
    - time: the date and time the progress was logged
    - failedConnects: the current number of failed connection attempts
    - lastError: a JSON object with details about the last error that happened on the applier. It contains the following sub-attributes if there was an error:
    - errorNum: a numerical error code
    - errorMessage: a textual error description
    - time: the date and time the error occurred
    In case no error has occurred, lastError will be empty.
  • server: a JSON object with the following sub-attributes:
    - version: the applier server's version
    - serverId: the applier server's id
  • endpoint: the endpoint the applier is connected to (if applier is active) or will connect to (if applier is currently inactive)
  • database: the name of the database the applier is connected to (if applier is active) or will connect to (if applier is currently inactive)
WARNING: calling this method will sychronize data from the collections found on the remote master to the local ArangoDB database. All data in the local collections will be purged and replaced with data from the master.
Use with caution!
Please also keep in mind that this command may take a long time to complete and return. This is because it will first do a full data synchronization with the master, which will take time roughly proportional to the amount of data.
Note: this method is not supported on a coordinator in a cluster.
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_put_api_replication_makeSlave" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "400": { - "description": "is returned if the configuration is incomplete or malformed.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred during sychronization or when starting the continuous replication.
" - }, - "501": { - "description": "is returned when this operation is called on a coordinator in a cluster.
" - } - }, - "summary": " Turn the server into a slave of another", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/server-id": { - "get": { - "description": "\n\nReturns the servers id. The id is also returned by other replication API methods, and this method is an easy means of determining a server's id.
The body of the response is a JSON object with the attribute serverId. The server id is returned as a string.

Example:

shell> curl --dump - http://localhost:8529/_api/replication/server-id\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"serverId\" : \"4865533481307\" \n}\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred while assembling the response.
" - } - }, - "summary": " Return server id", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/replication/sync": { - "put": { - "description": "**A json post document with these Properties is required:**
  • username: an optional ArangoDB username to use when connecting to the endpoint.
  • includeSystem: whether or not system collection operations will be applied
  • endpoint: the master endpoint to connect to (e.g. \"tcp://192.168.173.13:8529\").
  • database: the database name on the master (if not specified, defaults to the name of the local current database).
  • restrictType: an optional string value for collection filtering. When specified, the allowed values are include or exclude.
  • incremental: if set to true, then an incremental synchronization method will be used for synchronizing data in collections. This method is useful when collections already exist locally, and only the remaining differences need to be transferred from the remote endpoint. In this case, the incremental synchronization can be faster than a full synchronization. The default value is false, meaning that the complete data from the remote collection will be transferred.
  • restrictCollections: an optional array of collections for use with restrictType. If restrictType is include, only the specified collections will be sychronised. If restrictType is exclude, all but the specified collections will be synchronized. of type string
  • password: the password to use when connecting to the endpoint.
\n\nStarts a full data synchronization from a remote endpoint into the local ArangoDB database.
The sync method can be used by replication clients to connect an ArangoDB database to a remote endpoint, fetch the remote list of collections and indexes, and collection data. It will thus create a local backup of the state of data at the remote ArangoDB database. sync works on a per-database level.
sync will first fetch the list of collections and indexes from the remote endpoint. It does so by calling the inventory API of the remote database. It will then purge data in the local ArangoDB database, and after start will transfer collection data from the remote database to the local ArangoDB database. It will extract data from the remote database by calling the remote database's dump API until all data are fetched.
In case of success, the body of the response is a JSON object with the following attributes:
  • collections: an array of collections that were transferred from the endpoint
  • lastLogTick: the last log tick on the endpoint at the time the transfer was started. Use this value as the from value when starting the continuous synchronization later.
WARNING: calling this method will sychronize data from the collections found on the remote endpoint to the local ArangoDB database. All data in the local collections will be purged and replaced with data from the endpoint.
Use with caution!
Note: this method is not supported on a coordinator in a cluster.
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_put_api_replication_synchronize" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned if the request was executed successfully.
" - }, - "400": { - "description": "is returned if the configuration is incomplete or malformed.
" - }, - "405": { - "description": "is returned when an invalid HTTP method is used.
" - }, - "500": { - "description": "is returned if an error occurred during sychronization.
" - }, - "501": { - "description": "is returned when this operation is called on a coordinator in a cluster.
" - } - }, - "summary": " Synchronize data from a remote endpoint", - "tags": [ - "Replication" - ], - "x-examples": [], - "x-filename": "Replication - arangod/RestHandler/RestReplicationHandler.cpp" - } - }, - "/_api/simple/all": { - "put": { - "description": "free style json body\n\n
Returns all documents of a collections. The call expects a JSON object as body with the following attributes:
  • collection: The name of the collection to query.
  • skip: The number of documents to skip in the query (optional).
  • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

Example: Limit the amount of documents using limit

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/all <<EOF\n{ \"collection\": \"products\", \"skip\": 2, \"limit\" : 2 }\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"Hello3\" : \"World3\", \n      \"_id\" : \"products/774887879\", \n      \"_rev\" : \"774887879\", \n      \"_key\" : \"774887879\" \n    }, \n    { \n      \"Hello4\" : \"World4\", \n      \"_id\" : \"products/775215559\", \n      \"_rev\" : \"775215559\", \n      \"_key\" : \"775215559\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"cached\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Using a batchSize value

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/all <<EOF\n{ \"collection\": \"products\", \"batchSize\" : 3 }\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"Hello2\" : \"World2\", \n      \"_id\" : \"products/772594119\", \n      \"_rev\" : \"772594119\", \n      \"_key\" : \"772594119\" \n    }, \n    { \n      \"Hello1\" : \"World1\", \n      \"_id\" : \"products/772266439\", \n      \"_rev\" : \"772266439\", \n      \"_key\" : \"772266439\" \n    }, \n    { \n      \"Hello5\" : \"World5\", \n      \"_id\" : \"products/773577159\", \n      \"_rev\" : \"773577159\", \n      \"_key\" : \"773577159\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"773773767\", \n  \"count\" : 5, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0, \n      \"filtered\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"cached\" : false, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "description": "Contains the query.
", - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "additionalProperties": {}, - "type": "object" - }, - "x-description-offset": 0 - } - ], - "responses": { - "201": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Return all documents", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/any": { - "put": { - "description": "\n\n
Returns a random document from a collection. The call expects a JSON object as body with the following attributes:
**A json post document with these Properties is required:**
  • collection: The identifier or name of the collection to query.
    Returns a JSON object with the document stored in the attribute document if the collection contains at least one document. If the collection is empty, the document attrbute contains null.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/any <<EOF\n{ \n  \"collection\" : \"products\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"document\" : { \n    \"_id\" : \"products/776460743\", \n    \"_key\" : \"776460743\", \n    \"_rev\" : \"776460743\", \n    \"Hello2\" : \"World2\" \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_any" - }, - "x-description-offset": 185 - } - ], - "responses": { - "200": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Return a random document", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/by-example": { - "put": { - "description": "**A json post document with these Properties is required:**
  • skip: The number of documents to skip in the query (optional).
  • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
  • example: The example document.
  • collection: The name of the collection to query.
\n\n
This will find all documents matching a given example.
Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

Example: Matching an attribute

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"i\" : 1 \n  } \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/779082183\", \n      \"_key\" : \"779082183\", \n      \"_rev\" : \"779082183\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 2, \n        \"j\" : 2 \n      } \n    }, \n    { \n      \"_id\" : \"products/778295751\", \n      \"_key\" : \"778295751\", \n      \"_rev\" : \"778295751\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/778885575\", \n      \"_key\" : \"778885575\", \n      \"_rev\" : \"778885575\", \n      \"i\" : 1 \n    }, \n    { \n      \"_id\" : \"products/778623431\", \n      \"_key\" : \"778623431\", \n      \"_rev\" : \"778623431\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 4, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Matching an attribute which is a sub-document

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a.j\" : 1 \n  } \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/780589511\", \n      \"_key\" : \"780589511\", \n      \"_rev\" : \"780589511\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/780261831\", \n      \"_key\" : \"780261831\", \n      \"_rev\" : \"780261831\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: Matching an attribute within a sub-document

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a\" : { \n      \"j\" : 1 \n    } \n  } \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/782555591\", \n      \"_key\" : \"782555591\", \n      \"_rev\" : \"782555591\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 1, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_by_example" - }, - "x-description-offset": 59 - } - ], - "responses": { - "201": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Simple query by-example", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/first": { - "put": { - "description": "**A json post document with these Properties is required:**
  • count: the number of documents to return at most. Specifying count is optional. If it is not specified, it defaults to 1.
  • collection: the name of the collection
\n\n
This will return the first document(s) from the collection, in the order of insertion/update time. When the count argument is supplied, the result will be an array of documents, with the \"oldest\" document being first in the result array. If the count argument is not supplied, the result is the \"oldest\" document of the collection, or null if the collection is empty.
Note: this method is not supported for sharded collections with more than one shard.

Example: Retrieving the first n documents

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first <<EOF\n{ \n  \"collection\" : \"products\", \n  \"count\" : 2 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/784193991\", \n      \"_key\" : \"784193991\", \n      \"_rev\" : \"784193991\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/784521671\", \n      \"_key\" : \"784521671\", \n      \"_rev\" : \"784521671\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Retrieving the first document

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first <<EOF\n{ \n  \"collection\" : \"products\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"_id\" : \"products/789633479\", \n    \"_key\" : \"789633479\", \n    \"_rev\" : \"789633479\", \n    \"i\" : 1, \n    \"a\" : { \n      \"k\" : 1, \n      \"j\" : 1 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_first" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned when the query was successfully executed.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " First document of a collection", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/first-example": { - "put": { - "description": "**A json post document with these Properties is required:**
  • example: The example document.
  • collection: The name of the collection to query.
\n\n
This will return the first document matching a given example.
Returns a result containing the document or HTTP 404 if no document matched the example.
If more than one document in the collection matches the specified example, only one of these documents will be returned, and it is undefined which of the matching documents is returned.

Example: If a matching document was found

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"i\" : 1 \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"document\" : { \n    \"_id\" : \"products/786618823\", \n    \"_key\" : \"786618823\", \n    \"_rev\" : \"786618823\", \n    \"i\" : 1, \n    \"a\" : { \n      \"k\" : 2, \n      \"j\" : 2 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: If no document was found

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"l\" : 1 \n  } \n}\nEOF\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 404, \n  \"errorMessage\" : \"no match\" \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_first_example" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned when the query was successfully executed.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Find documents matching an example", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/fulltext": { - "put": { - "description": "**A json post document with these Properties is required:**
  • index: The identifier of the fulltext-index to use.
  • attribute: The attribute that contains the texts.
  • collection: The name of the collection to query.
  • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
  • skip: The number of documents to skip in the query (optional).
  • query: The fulltext query. Please refer to [Fulltext queries](../SimpleQueries/FulltextQueries.html) for details.
\n\n
This will find all documents from the collection that match the fulltext query specified in query.
In order to use the fulltext operator, a fulltext index must be defined for the collection and the specified attribute.
Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.
Note: the fulltext simple query is deprecated as of ArangoDB 2.6. This API may be removed in future versions of ArangoDB. The preferred way for retrieving documents from a collection using the near operator is to issue an AQL query using the FULLTEXT [AQL function](../Aql/FulltextFunctions.md) as follows:

FOR doc IN FULLTEXT(@@collection, @attributeName, @queryString, @limit) RETURN doc

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/fulltext <<EOF\n{ \n  \"collection\" : \"products\", \n  \"attribute\" : \"text\", \n  \"query\" : \"word\" \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/791009735\", \n      \"_key\" : \"791009735\", \n      \"_rev\" : \"791009735\", \n      \"text\" : \"this text contains word\" \n    }, \n    { \n      \"_id\" : \"products/791206343\", \n      \"_key\" : \"791206343\", \n      \"_rev\" : \"791206343\", \n      \"text\" : \"this text also has a word\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_fulltext" - }, - "x-description-offset": 59 - } - ], - "responses": { - "201": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Fulltext index query", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/last": { - "put": { - "description": "**A json post document with these Properties is required:**
  • count: the number of documents to return at most. Specifying count is optional. If it is not specified, it defaults to 1.
  • collection: the name of the collection
\n\n
This will return the last documents from the collection, in the order of insertion/update time. When the count argument is supplied, the result will be an array of documents, with the \"latest\" document being first in the result array.
If the count argument is not supplied, the result is the \"latest\" document of the collection, or null if the collection is empty.
Note: this method is not supported for sharded collections with more than one shard.

Example: Retrieving the last n documents

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/last <<EOF\n{ \n  \"collection\" : \"products\", \n  \"count\" : 2 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/793369031\", \n      \"_key\" : \"793369031\", \n      \"_rev\" : \"793369031\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 2, \n        \"j\" : 2 \n      } \n    }, \n    { \n      \"_id\" : \"products/793172423\", \n      \"_key\" : \"793172423\", \n      \"_rev\" : \"793172423\", \n      \"i\" : 1 \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Retrieving the first document

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/last <<EOF\n{ \n  \"collection\" : \"products\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"_id\" : \"products/795007431\", \n    \"_key\" : \"795007431\", \n    \"_rev\" : \"795007431\", \n    \"i\" : 1, \n    \"a\" : { \n      \"k\" : 2, \n      \"j\" : 2 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_last" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned when the query was successfully executed.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Last document of a collection", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/lookup-by-keys": { - "put": { - "description": "**A json post document with these Properties is required:**
  • keys: array with the _keys of documents to remove. of type string
  • collection: The name of the collection to look in for the documents
\n\nLooks up the documents in the specified collection using the array of keys provided. All documents for which a matching key was specified in the keys array and that exist in the collection will be returned. Keys for which no document can be found in the underlying collection are ignored, and no exception will be thrown for them.
The body of the response contains a JSON object with a documents attribute. The documents attribute is an array containing the matching documents. The order in which matching documents are present in the result array is unspecified.

Example: Looking up existing documents

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/lookup-by-keys <<EOF\n{ \n  \"keys\" : [ \n    \"test0\", \n    \"test1\", \n    \"test2\", \n    \"test3\", \n    \"test4\", \n    \"test5\", \n    \"test6\", \n    \"test7\", \n    \"test8\", \n    \"test9\" \n  ], \n  \"collection\" : \"test\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"documents\" : [ \n    { \n      \"value\" : 0, \n      \"_id\" : \"test/test0\", \n      \"_rev\" : \"795597255\", \n      \"_key\" : \"test0\" \n    }, \n    { \n      \"value\" : 1, \n      \"_id\" : \"test/test1\", \n      \"_rev\" : \"795793863\", \n      \"_key\" : \"test1\" \n    }, \n    { \n      \"value\" : 2, \n      \"_id\" : \"test/test2\", \n      \"_rev\" : \"795990471\", \n      \"_key\" : \"test2\" \n    }, \n    { \n      \"value\" : 3, \n      \"_id\" : \"test/test3\", \n      \"_rev\" : \"796187079\", \n      \"_key\" : \"test3\" \n    }, \n    { \n      \"value\" : 4, \n      \"_id\" : \"test/test4\", \n      \"_rev\" : \"796383687\", \n      \"_key\" : \"test4\" \n    }, \n    { \n      \"value\" : 5, \n      \"_id\" : \"test/test5\", \n      \"_rev\" : \"796580295\", \n      \"_key\" : \"test5\" \n    }, \n    { \n      \"value\" : 6, \n      \"_id\" : \"test/test6\", \n      \"_rev\" : \"796776903\", \n      \"_key\" : \"test6\" \n    }, \n    { \n      \"value\" : 7, \n      \"_id\" : \"test/test7\", \n      \"_rev\" : \"796973511\", \n      \"_key\" : \"test7\" \n    }, \n    { \n      \"value\" : 8, \n      \"_id\" : \"test/test8\", \n      \"_rev\" : \"797170119\", \n      \"_key\" : \"test8\" \n    }, \n    { \n      \"value\" : 9, \n      \"_id\" : \"test/test9\", \n      \"_rev\" : \"797366727\", \n      \"_key\" : \"test9\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Looking up non-existing documents

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/lookup-by-keys <<EOF\n{ \n  \"keys\" : [ \n    \"foo\", \n    \"bar\", \n    \"baz\" \n  ], \n  \"collection\" : \"test\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"documents\" : [ ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n

", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/RestLookupByKeys" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned if the operation was carried out successfully.
" - }, - "404": { - "description": "is returned if the collection was not found. The response body contains an error document in this case.
" - }, - "405": { - "description": "is returned if the operation was called with a different HTTP METHOD than PUT.
" - } - }, - "summary": " Find documents by their keys", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/near": { - "put": { - "description": "**A json post document with these Properties is required:**
  • distance: If given, the attribute key used to return the distance to the given coordinate. (optional). If specified, distances are returned in meters.
  • skip: The number of documents to skip in the query. (optional)
  • longitude: The longitude of the coordinate.
  • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. The default is 100. (optional)
  • collection: The name of the collection to query.
  • latitude: The latitude of the coordinate.
  • geo: If given, the identifier of the geo-index to use. (optional)
\n\n
The default will find at most 100 documents near the given coordinate. The returned array is sorted according to the distance, with the nearest document being first in the return array. If there are near documents of equal distance, documents are chosen randomly from this set until the limit is reached.
In order to use the near operator, a geo index must be defined for the collection. This index also defines which attribute holds the coordinates for the document. If you have more than one geo-spatial index, you can use the geo field to select a particular index.

Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.
Note: the near simple query is deprecated as of ArangoDB 2.6. This API may be removed in future versions of ArangoDB. The preferred way for retrieving documents from a collection using the near operator is to issue an [AQL query](../Aql/GeoFunctions.md) using the NEAR function as follows:

FOR doc IN NEAR(@@collection, @latitude, @longitude, @limit) RETURN doc`

Example: Without distance

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near <<EOF\n{ \n  \"collection\" : \"products\", \n  \"latitude\" : 0, \n  \"longitude\" : 0, \n  \"skip\" : 1, \n  \"limit\" : 2 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/801823175\", \n      \"_key\" : \"801823175\", \n      \"_rev\" : \"801823175\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ] \n    }, \n    { \n      \"_id\" : \"products/801429959\", \n      \"_key\" : \"801429959\", \n      \"_rev\" : \"801429959\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ] \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: With distance

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near <<EOF\n{ \n  \"collection\" : \"products\", \n  \"latitude\" : 0, \n  \"longitude\" : 0, \n  \"skip\" : 1, \n  \"limit\" : 3, \n  \"distance\" : \"distance\" \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/804444615\", \n      \"_key\" : \"804444615\", \n      \"_rev\" : \"804444615\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/804837831\", \n      \"_key\" : \"804837831\", \n      \"_rev\" : \"804837831\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/804248007\", \n      \"_key\" : \"804248007\", \n      \"_rev\" : \"804248007\", \n      \"name\" : \"Name/-0.004/\", \n      \"loc\" : [ \n        -0.004, \n        0 \n      ], \n      \"distance\" : 444.779706578235 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 3, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_near" - }, - "x-description-offset": 59 - } - ], - "responses": { - "201": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Returns documents near a coordinate", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/range": { - "put": { - "description": "**A json post document with these Properties is required:**
  • right: The upper bound.
  • attribute: The attribute path to check.
  • collection: The name of the collection to query.
  • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
  • closed: If true, use interval including left and right, otherwise exclude right, but include left.
  • skip: The number of documents to skip in the query (optional).
  • left: The lower bound.
\n\n
This will find all documents within a given range. In order to execute a range query, a skip-list index on the queried attribute must be present.
Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.
Note: the range simple query is deprecated as of ArangoDB 2.6. The function may be removed in future versions of ArangoDB. The preferred way for retrieving documents from a collection within a specific range is to use an AQL query as follows:

FOR doc IN @@collection FILTER doc.value >= @left && doc.value < @right LIMIT @skip, @limit RETURN doc`

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/range <<EOF\n{ \n  \"collection\" : \"products\", \n  \"attribute\" : \"i\", \n  \"left\" : 2, \n  \"right\" : 4 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/806738375\", \n      \"_key\" : \"806738375\", \n      \"_rev\" : \"806738375\", \n      \"i\" : 2 \n    }, \n    { \n      \"_id\" : \"products/806934983\", \n      \"_key\" : \"806934983\", \n      \"_rev\" : \"806934983\", \n      \"i\" : 3 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_range" - }, - "x-description-offset": 59 - } - ], - "responses": { - "201": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown or no suitable index for the range query is present. The response body contains an error document in this case.
" - } - }, - "summary": " Simple range query", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/remove-by-example": { - "put": { - "description": "**A json post document with these Properties is required:**
  • example: An example document that all collection documents are compared against.
  • collection: The name of the collection to remove from.
  • options: a json object which can contains following attributes:
    • limit: an optional value that determines how many documents to delete at most. If limit is specified but is less than the number of documents in the collection, it is undefined which of the documents will be deleted.
    • waitForSync: if set to true, then all removal operations will instantly be synchronized to disk. If this is not specified, then the collection's default sync behavior will be applied.
\n\n
This will find all documents in the collection that match the specified example object.
Note: the limit attribute is not supported on sharded collections. Using it will result in an error.
Returns the number of documents that were deleted.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/remove-by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a\" : { \n      \"j\" : 1 \n    } \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"deleted\" : 1, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using Parameter: waitForSync and limit

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/remove-by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a\" : { \n      \"j\" : 1 \n    } \n  }, \n  \"waitForSync\" : true, \n  \"limit\" : 2 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"deleted\" : 1, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using Parameter: waitForSync and limit with new signature

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/remove-by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a\" : { \n      \"j\" : 1 \n    } \n  }, \n  \"options\" : { \n    \"waitForSync\" : true, \n    \"limit\" : 2 \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"deleted\" : 1, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_remove_by_example" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Remove documents by example", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/remove-by-keys": { - "put": { - "description": "**A json post document with these Properties is required:**
  • keys: array with the _keys of documents to remove. of type string
  • options: a json object which can contains following attributes:
    • waitForSync: if set to true, then all removal operations will instantly be synchronized to disk. If this is not specified, then the collection's default sync behavior will be applied.
  • collection: The name of the collection to look in for the documents to remove
\n\nLooks up the documents in the specified collection using the array of keys provided, and removes all documents from the collection whose keys are contained in the keys array. Keys for which no document can be found in the underlying collection are ignored, and no exception will be thrown for them.
The body of the response contains a JSON object with information how many documents were removed (and how many were not). The removed attribute will contain the number of actually removed documents. The ignored attribute will contain the number of keys in the request for which no matching document could be found.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/remove-by-keys <<EOF\n{ \n  \"keys\" : [ \n    \"test0\", \n    \"test1\", \n    \"test2\", \n    \"test3\", \n    \"test4\", \n    \"test5\", \n    \"test6\", \n    \"test7\", \n    \"test8\", \n    \"test9\" \n  ], \n  \"collection\" : \"test\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"removed\" : 10, \n  \"ignored\" : 0, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/remove-by-keys <<EOF\n{ \n  \"keys\" : [ \n    \"foo\", \n    \"bar\", \n    \"baz\" \n  ], \n  \"collection\" : \"test\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"removed\" : 0, \n  \"ignored\" : 3, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n

", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/RestRemoveByKeys" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned if the operation was carried out successfully. The number of removed documents may still be 0 in this case if none of the specified document keys were found in the collection.
" - }, - "404": { - "description": "is returned if the collection was not found. The response body contains an error document in this case.
" - }, - "405": { - "description": "is returned if the operation was called with a different HTTP METHOD than PUT.
" - } - }, - "summary": " Remove documents by their keys", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/replace-by-example": { - "put": { - "description": "**A json post document with these Properties is required:**
  • options: a json object which can contain following attributes
    • limit: an optional value that determines how many documents to replace at most. If limit is specified but is less than the number of documents in the collection, it is undefined which of the documents will be replaced.

    • waitForSync: if set to true, then all removal operations will instantly be synchronized to disk. If this is not specified, then the collection's default sync behavior will be applied.
  • example: An example document that all collection documents are compared against.
  • collection: The name of the collection to replace within.
  • newValue: The replacement document that will get inserted in place of the \"old\" documents.
\n\n
This will find all documents in the collection that match the specified example object, and replace the entire document body with the new value specified. Note that document meta-attributes such as _id, _key, _from, _to etc. cannot be replaced.
Note: the limit attribute is not supported on sharded collections. Using it will result in an error.
Returns the number of documents that were replaced.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/replace-by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a\" : { \n      \"j\" : 1 \n    } \n  }, \n  \"newValue\" : { \n    \"foo\" : \"bar\" \n  }, \n  \"limit\" : 3 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"replaced\" : 1, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using new Signature for attributes WaitForSync and limit

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/replace-by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a\" : { \n      \"j\" : 1 \n    } \n  }, \n  \"newValue\" : { \n    \"foo\" : \"bar\" \n  }, \n  \"options\" : { \n    \"limit\" : 3, \n    \"waitForSync\" : true \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"replaced\" : 1, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_replace_by_example" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Replace documents by example", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/update-by-example": { - "put": { - "description": "**A json post document with these Properties is required:**
  • options: a json object which can contains following attributes:
    • keepNull: This parameter can be used to modify the behavior when handling null values. Normally, null values are stored in the database. By setting the keepNull parameter to false, this behavior can be changed so that all attributes in data with null values will be removed from the updated document.
    • limit: an optional value that determines how many documents to update at most. If limit is specified but is less than the number of documents in the collection, it is undefined which of the documents will be updated.
    • waitForSync: if set to true, then all removal operations will instantly be synchronized to disk. If this is not specified, then the collection's default sync behavior will be applied.
  • example: An example document that all collection documents are compared against.
  • collection: The name of the collection to update within.
  • newValue: A document containing all the attributes to update in the found documents.
\n\n
This will find all documents in the collection that match the specified example object, and partially update the document body with the new value specified. Note that document meta-attributes such as _id, _key, _from, _to etc. cannot be replaced.
Note: the limit attribute is not supported on sharded collections. Using it will result in an error.
Returns the number of documents that were updated.


Example: using old syntax for options

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/update-by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a\" : { \n      \"j\" : 1 \n    } \n  }, \n  \"newValue\" : { \n    \"a\" : { \n      \"j\" : 22 \n    } \n  }, \n  \"limit\" : 3 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"updated\" : 1, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: using new signature for options

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/update-by-example <<EOF\n{ \n  \"collection\" : \"products\", \n  \"example\" : { \n    \"a\" : { \n      \"j\" : 1 \n    } \n  }, \n  \"newValue\" : { \n    \"a\" : { \n      \"j\" : 22 \n    } \n  }, \n  \"options\" : { \n    \"limit\" : 3, \n    \"waitForSync\" : true \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"updated\" : 1, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_update_by_example" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "is returned if the collection was updated successfully and waitForSync was true.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Update documents by example", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/within": { - "put": { - "description": "**A json post document with these Properties is required:**
  • distance: If given, the attribute key used to return the distance to the given coordinate. (optional). If specified, distances are returned in meters.
  • skip: The number of documents to skip in the query. (optional)
  • longitude: The longitude of the coordinate.
  • radius: The maximal radius (in meters).
  • collection: The name of the collection to query.
  • latitude: The latitude of the coordinate.
  • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. The default is 100. (optional)
  • geo: If given, the identifier of the geo-index to use. (optional)
\n\n
This will find all documents within a given radius around the coordinate (latitude, longitude). The returned list is sorted by distance.
In order to use the within operator, a geo index must be defined for the collection. This index also defines which attribute holds the coordinates for the document. If you have more than one geo-spatial index, you can use the geo field to select a particular index.

Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.
Note: the within simple query is deprecated as of ArangoDB 2.6. This API may be removed in future versions of ArangoDB. The preferred way for retrieving documents from a collection using the near operator is to issue an [AQL query](../Aql/GeoFunctions.md) using the WITHIN function as follows:

FOR doc IN WITHIN(@@collection, @latitude, @longitude, @radius, @distanceAttributeName) RETURN doc

Example: Without distance

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near <<EOF\n{ \n  \"collection\" : \"products\", \n  \"latitude\" : 0, \n  \"longitude\" : 0, \n  \"skip\" : 1, \n  \"limit\" : 2, \n  \"radius\" : 500 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/829610439\", \n      \"_key\" : \"829610439\", \n      \"_rev\" : \"829610439\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ] \n    }, \n    { \n      \"_id\" : \"products/829217223\", \n      \"_key\" : \"829217223\", \n      \"_rev\" : \"829217223\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ] \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
Example: With distance

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near <<EOF\n{ \n  \"collection\" : \"products\", \n  \"latitude\" : 0, \n  \"longitude\" : 0, \n  \"skip\" : 1, \n  \"limit\" : 3, \n  \"distance\" : \"distance\", \n  \"radius\" : 300 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/832231879\", \n      \"_key\" : \"832231879\", \n      \"_rev\" : \"832231879\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/832625095\", \n      \"_key\" : \"832625095\", \n      \"_rev\" : \"832625095\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/832035271\", \n      \"_key\" : \"832035271\", \n      \"_rev\" : \"832035271\", \n      \"name\" : \"Name/-0.004/\", \n      \"loc\" : [ \n        -0.004, \n        0 \n      ], \n      \"distance\" : 444.779706578235 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 3, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_within" - }, - "x-description-offset": 59 - } - ], - "responses": { - "201": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Find documents within a radius around a coordinate", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/simple/within-rectangle": { - "put": { - "description": "**A json post document with these Properties is required:**
  • latitude1: The latitude of the first rectangle coordinate.
  • skip: The number of documents to skip in the query. (optional)
  • latitude2: The latitude of the second rectangle coordinate.
  • longitude2: The longitude of the second rectangle coordinate.
  • longitude1: The longitude of the first rectangle coordinate.
  • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. The default is 100. (optional)
  • collection: The name of the collection to query.
  • geo: If given, the identifier of the geo-index to use. (optional)
\n\n
This will find all documents within the specified rectangle (determined by the given coordinates (latitude1, longitude1, latitude2, longitude2).
In order to use the within-rectangle query, a geo index must be defined for the collection. This index also defines which attribute holds the coordinates for the document. If you have more than one geo-spatial index, you can use the geo field to select a particular index.
Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/within-rectangle <<EOF\n{ \n  \"collection\" : \"products\", \n  \"latitude1\" : 0, \n  \"longitude1\" : 0, \n  \"latitude2\" : 0.2, \n  \"longitude2\" : 0.2, \n  \"skip\" : 1, \n  \"limit\" : 2 \n}\nEOF\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/836229575\", \n      \"_key\" : \"836229575\", \n      \"_rev\" : \"836229575\", \n      \"name\" : \"Name/0.008/\", \n      \"loc\" : [ \n        0.008, \n        0 \n      ] \n    }, \n    { \n      \"_id\" : \"products/836032967\", \n      \"_key\" : \"836032967\", \n      \"_rev\" : \"836032967\", \n      \"name\" : \"Name/0.006/\", \n      \"loc\" : [ \n        0.006, \n        0 \n      ] \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSA_put_api_simple_within_rectangle" - }, - "x-description-offset": 59 - } - ], - "responses": { - "201": { - "description": "is returned if the query was executed successfully.
" - }, - "400": { - "description": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.
" - }, - "404": { - "description": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case.
" - } - }, - "summary": " Within rectangle query", - "tags": [ - "Simple Queries" - ], - "x-examples": [], - "x-filename": "Simple Queries - js/actions/api-simple.js, arangod/RestHandler/RestSimpleHandler.cpp, arangod/RestHandler/RestSimpleQueryHandler.cpp" - } - }, - "/_api/tasks": { - "post": { - "description": "**A json post document with these Properties is required:**
  • params: The parameters to be passed into command
  • offset: Number of seconds initial delay
  • command: The JavaScript code to be executed
  • name: The name of the task
  • period: number of seconds between the executions
\n\ncreates a new task with a generated id

Example:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/tasks/ <<EOF\n{ \n  \"name\" : \"SampleTask\", \n  \"command\" : \"(function(params) { require('internal').print(params); })(params)\", \n  \"params\" : { \n    \"foo\" : \"bar\", \n    \"bar\" : \"foo\" \n  }, \n  \"period\" : 2 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"836884935\", \n  \"name\" : \"SampleTask\", \n  \"type\" : \"periodic\", \n  \"period\" : 2, \n  \"created\" : 1443627622.01888, \n  \"command\" : \"(function(params) { require('internal').print(params); })(params)\", \n  \"database\" : \"_system\", \n  \"error\" : false, \n  \"code\" : 200 \n}\nshell> curl -X DELETE --dump - http://localhost:8529/_api/tasks/836884935\n\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_new_tasks" - }, - "x-description-offset": 59 - } - ], - "responses": { - "400": { - "description": "If the post body is not accurate, a HTTP 400 is returned.
" - } - }, - "summary": " creates a task", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_api/tasks/": { - "get": { - "description": "\n\nfetches all existing tasks on the server

Example: Fetching all tasks

shell> curl --dump - http://localhost:8529/_api/tasks\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  { \n    \"id\" : \"16898503\", \n    \"name\" : \"user-defined task\", \n    \"type\" : \"periodic\", \n    \"period\" : 1, \n    \"created\" : 1443627553.436199, \n    \"command\" : \"(function () {\\n      require('org/arangodb/foxx/queues/manager').manage();\\n    })(params)\", \n    \"database\" : \"_system\" \n  }, \n  { \n    \"id\" : \"statistics-gc\", \n    \"name\" : \"statistics-gc\", \n    \"type\" : \"periodic\", \n    \"period\" : 450, \n    \"created\" : 1443627552.94918, \n    \"command\" : \"require('org/arangodb/statistics').garbageCollector();\", \n    \"database\" : \"_system\" \n  }, \n  { \n    \"id\" : \"statistics-average-collector\", \n    \"name\" : \"statistics-average-collector\", \n    \"type\" : \"periodic\", \n    \"period\" : 900, \n    \"created\" : 1443627552.946052, \n    \"command\" : \"require('org/arangodb/statistics').historianAverage();\", \n    \"database\" : \"_system\" \n  }, \n  { \n    \"id\" : \"statistics-collector\", \n    \"name\" : \"statistics-collector\", \n    \"type\" : \"periodic\", \n    \"period\" : 10, \n    \"created\" : 1443627552.945114, \n    \"command\" : \"require('org/arangodb/statistics').historian();\", \n    \"database\" : \"_system\" \n  } \n]\n

\n
", - "parameters": [], - "responses": { - "200": { - "description": "The list of tasks
" - } - }, - "summary": " Fetch all tasks or one task", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_api/tasks/{id}": { - "delete": { - "description": "\n\nDeletes the task identified by id on the server.

Example: trying to delete non existing task

shell> curl -X DELETE --dump - http://localhost:8529/_api/tasks/NoTaskWithThatName\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1852, \n  \"errorMessage\" : \"task not found\" \n}\n

\n
Example: Remove existing Task

shell> curl -X DELETE --dump - http://localhost:8529/_api/tasks/SampleTask\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The id of the task to delete.
", - "format": "string", - "in": "path", - "name": "id", - "required": true, - "type": "string" - } - ], - "responses": { - "404": { - "description": "If the task id is unknown, then an HTTP 404 is returned.
" - } - }, - "summary": " deletes the task with id", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - }, - "get": { - "description": "\n\nfetches one existing tasks on the server specified by id

Example: Fetching a single task by its id

shell> curl --dump - http://localhost:8529/_api/tasks/statistics-average-collector\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"statistics-average-collector\", \n  \"name\" : \"statistics-average-collector\", \n  \"type\" : \"periodic\", \n  \"period\" : 900, \n  \"created\" : 1443627552.946052, \n  \"command\" : \"require('org/arangodb/statistics').historianAverage();\", \n  \"database\" : \"_system\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: trying to fetch a non-existing task

shell> curl --dump - http://localhost:8529/_api/tasks/non-existing-task\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1852, \n  \"errorMessage\" : \"task not found\" \n}\n

\n
", - "parameters": [ - { - "description": "The id of the task to fetch.
", - "format": "string", - "in": "path", - "name": "id", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "The requested task
" - } - }, - "summary": " Fetch one task with id", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - }, - "put": { - "description": "**A json post document with these Properties is required:**
  • params: The parameters to be passed into command
  • offset: Number of seconds initial delay
  • command: The JavaScript code to be executed
  • name: The name of the task
  • period: number of seconds between the executions
\n\nregisters a new task with the specified id

Example:

shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/tasks/sampleTask <<EOF\n{ \n  \"id\" : \"SampleTask\", \n  \"name\" : \"SampleTask\", \n  \"command\" : \"(function(params) { require('internal').print(params); })(params)\", \n  \"params\" : { \n    \"foo\" : \"bar\", \n    \"bar\" : \"foo\" \n  }, \n  \"period\" : 2 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"sampleTask\", \n  \"name\" : \"SampleTask\", \n  \"type\" : \"periodic\", \n  \"period\" : 2, \n  \"created\" : 1443627622.623117, \n  \"command\" : \"(function(params) { require('internal').print(params); })(params)\", \n  \"database\" : \"_system\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
", - "parameters": [ - { - "description": "The id of the task to create
", - "format": "string", - "in": "path", - "name": "id", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_put_api_new_tasks" - }, - "x-description-offset": 59 - } - ], - "responses": { - "400": { - "description": "If the task id already exists or the rest body is not accurate, HTTP 400 is returned.
" - } - }, - "summary": " creates a task with id", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - }, - "/_api/transaction": { - "post": { - "description": "**A json post document with these Properties is required:**
  • action: the actual transaction operations to be executed, in the form of stringified JavaScript code. The code will be executed on server side, with late binding. It is thus critical that the code specified in action properly sets up all the variables it needs. If the code specified in action ends with a return statement, the value returned will also be returned by the REST API in the result attribute if the transaction committed successfully.
  • params: optional arguments passed to action.
  • collections: contains the array of collections to be used in the transaction (mandatory). collections must be a JSON object that can have the optional sub-attributes read and write. read and write must each be either arrays of collections names or strings with a single collection name.
  • lockTimeout: an optional numeric value that can be used to set a timeout for waiting on collection locks. If not specified, a default value will be used. Setting lockTimeout to 0 will make ArangoDB not time out waiting for a lock.
  • waitForSync: an optional boolean flag that, if set, will force the transaction to write all data to disk before returning.
\n\n
Contains the collections and action.
The transaction description must be passed in the body of the POST request.
If the transaction is fully executed and committed on the server, HTTP 200 will be returned. Additionally, the return value of the code defined in action will be returned in the result attribute.
For successfully committed transactions, the returned JSON object has the following properties:
  • error: boolean flag to indicate if an error occurred (false in this case)
  • code: the HTTP status code
  • result: the return value of the transaction
If the transaction specification is either missing or malformed, the server will respond with HTTP 400.
The body of the response will then contain a JSON object with additional error details. The object has the following attributes:
  • error: boolean flag to indicate that an error occurred (true in this case)
  • code: the HTTP status code
  • errorNum: the server error number
  • errorMessage: a descriptive error message
If a transaction fails to commit, either by an exception thrown in the action code, or by an internal error, the server will respond with an error. Any other errors will be returned with any of the return codes HTTP 400, HTTP 409, or HTTP 500.

Example: Executing a transaction on a single collection

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/transaction <<EOF\n{ \n  \"collections\" : { \n    \"write\" : \"products\" \n  }, \n  \"action\" : \"function () { var db = require('internal').db; db.products.save({});  return db.products.count(); }\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : 1, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Executing a transaction using multiple collections

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/transaction <<EOF\n{ \n  \"collections\" : { \n    \"write\" : [ \n      \"products\", \n      \"materials\" \n    ] \n  }, \n  \"action\" : \"function () {var db = require('internal').db;db.products.save({});db.materials.save({});return 'worked!';}\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : \"worked!\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Aborting a transaction due to an internal error

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/transaction <<EOF\n{ \n  \"collections\" : { \n    \"write\" : \"products\" \n  }, \n  \"action\" : \"function () {var db = require('internal').db;db.products.save({ _key: 'abc'});db.products.save({ _key: 'abc'});}\" \n}\nEOF\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"exception\" : \"[ArangoError 1210: unique constraint violated]\", \n  \"stacktrace\" : [ \n    \"[ArangoError 1210: unique constraint violated]\", \n    \"  at Error (native)\", \n    \"  at eval (<anonymous>:1:99)\", \n    \"  at eval (<anonymous>:1:122)\", \n    \"  at post_api_transaction (js/actions/api-transaction.js:268:16)\", \n    \"  at Function.actions.defineHttp.callback (js/actions/api-transaction.js:288:11)\" \n  ], \n  \"message\" : \"unique constraint violated\", \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1210, \n  \"errorMessage\" : \"unique constraint violated\" \n}\n

\n
Example: Aborting a transaction by explicitly throwing an exception

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/transaction <<EOF\n{ \n  \"collections\" : { \n    \"read\" : \"products\" \n  }, \n  \"action\" : \"function () { throw 'doh!'; }\" \n}\nEOF\n\nHTTP/1.1 500 Internal Server Error\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"exception\" : \"doh!\", \n  \"error\" : true, \n  \"code\" : 500, \n  \"errorNum\" : 500, \n  \"errorMessage\" : \"internal server error\" \n}\n

\n
Example: Referring to a non-existing collection

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/transaction <<EOF\n{ \n  \"collections\" : { \n    \"read\" : \"products\" \n  }, \n  \"action\" : \"function () { return true; }\" \n}\nEOF\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"exception\" : \"[ArangoError 1203: collection not found]\", \n  \"stacktrace\" : [ \n    \"[ArangoError 1203: collection not found]\", \n    \"  at Error (native)\", \n    \"  at post_api_transaction (js/actions/api-transaction.js:268:16)\", \n    \"  at Function.actions.defineHttp.callback (js/actions/api-transaction.js:288:11)\" \n  ], \n  \"message\" : \"collection not found\", \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1203, \n  \"errorMessage\" : \"collection not found\" \n}\n

\n
", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_post_api_transaction" - }, - "x-description-offset": 59 - } - ], - "responses": { - "200": { - "description": "If the transaction is fully executed and committed on the server, HTTP 200 will be returned.
" - }, - "400": { - "description": "If the transaction specification is either missing or malformed, the server will respond with HTTP 400.
" - }, - "404": { - "description": "If the transaction specification contains an unknown collection, the server will respond with HTTP 404.
" - }, - "500": { - "description": "Exceptions thrown by users will make the server respond with a return code of HTTP 500
" - } - }, - "summary": " Execute transaction", - "tags": [ - "Transactions" - ], - "x-examples": [], - "x-filename": "Transactions - js/actions/api-transaction.js" - } - }, - "/_api/traversal": { - "post": { - "description": "\n\nStarts a traversal starting from a given vertex and following. edges contained in a given edgeCollection. The request must contain the following attributes.
**A json post document with these Properties is required:**
  • sort: body (JavaScript) code of a custom comparison function for the edges. The signature of this function is (l, r) -> integer (where l and r are edges) and must return -1 if l is smaller than, +1 if l is greater than, and 0 if l and r are equal. The reason for this is the following: The order of edges returned for a certain vertex is undefined. This is because there is no natural order of edges for a vertex with multiple connected edges. To explicitly define the order in which edges on the vertex are followed, you can specify an edge comparator function with this attribute. Note that the value here has to be a string to conform to the JSON standard, which in turn is parsed as function body on the server side. Furthermore note that this attribute is only used for the standard expanders. If you use your custom expander you have to do the sorting yourself within the expander code.
  • direction: direction for traversal
    • if set, must be either \"outbound\", \"inbound\", or \"any\"
    • if not set, the expander attribute must be specified
  • minDepth: ANDed with any existing filters): visits only nodes in at least the given depth
  • startVertex: id of the startVertex, e.g. \"users/foo\".
  • visitor: body (JavaScript) code of custom visitor function function signature: (config, result, vertex, path, connected) -> void The visitor function can do anything, but its return value is ignored. To populate a result, use the result variable by reference. Note that the connected argument is only populated when the order attribute is set to \"preorder-expander\".
  • itemOrder: item iteration order can be \"forward\" or \"backward\"
  • strategy: traversal strategy can be \"depthfirst\" or \"breadthfirst\"
  • filter: default is to include all nodes: body (JavaScript code) of custom filter function function signature: (config, vertex, path) -> mixed can return four different string values:
    • \"exclude\" -> this vertex will not be visited.
    • \"prune\" -> the edges of this vertex will not be followed.
    • \"\" or undefined -> visit the vertex and follow it's edges.
    • Array -> containing any combination of the above. If there is at least one \"exclude\" or \"prune\" respectivly is contained, it's effect will occur.
  • init: body (JavaScript) code of custom result initialization function function signature: (config, result) -> void initialize any values in result with what is required
  • maxIterations: Maximum number of iterations in each traversal. This number can be set to prevent endless loops in traversal of cyclic graphs. When a traversal performs as many iterations as the maxIterations value, the traversal will abort with an error. If maxIterations is not set, a server-defined value may be used.
  • maxDepth: ANDed with any existing filters visits only nodes in at most the given depth
  • uniqueness: specifies uniqueness for vertices and edges visited if set, must be an object like this:
    \"uniqueness\": {\"vertices\": \"none\"|\"global\"|\"path\", \"edges\": \"none\"|\"global\"|\"path\"}
  • order: traversal order can be \"preorder\", \"postorder\" or \"preorder-expander\"
  • graphName: name of the graph that contains the edges. Either edgeCollection or graphName has to be given. In case both values are set the graphName is prefered.
  • expander: body (JavaScript) code of custom expander function must be set if direction attribute is not set function signature: (config, vertex, path) -> array expander must return an array of the connections for vertex each connection is an object with the attributes edge and vertex
  • edgeCollection: name of the collection that contains the edges.
\n\n
If the Traversal is successfully executed HTTP 200 will be returned. Additionally the result object will be returned by the traversal.
For successful traversals, the returned JSON object has the following properties:
  • error: boolean flag to indicate if an error occurred (false in this case)
  • code: the HTTP status code
  • result: the return value of the traversal
If the traversal specification is either missing or malformed, the server will respond with HTTP 400.
The body of the response will then contain a JSON object with additional error details. The object has the following attributes:
  • error: boolean flag to indicate that an error occurred (true in this case)
  • code: the HTTP status code
  • errorNum: the server error number
  • errorMessage: a descriptive error message

Example: In the following examples the underlying graph will contain five persons Alice, Bob, Charlie, Dave and Eve. We will have the following directed relations: - Alice knows Bob - Bob knows Charlie - Bob knows Dave - Eve knows Alice - Eve knows Bob
The starting vertex will always be Alice.
Follow only outbound edges


shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"outbound\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"890100167\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"890296775\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"890558919\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"890755527\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"890100167\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/891214279\", \n              \"_key\" : \"891214279\", \n              \"_rev\" : \"891214279\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"890100167\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"890296775\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/891214279\", \n              \"_key\" : \"891214279\", \n              \"_rev\" : \"891214279\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/891410887\", \n              \"_key\" : \"891410887\", \n              \"_rev\" : \"891410887\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"890100167\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"890296775\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"890558919\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/891214279\", \n              \"_key\" : \"891214279\", \n              \"_rev\" : \"891214279\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/891607495\", \n              \"_key\" : \"891607495\", \n              \"_rev\" : \"891607495\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"890100167\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"890296775\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"890755527\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Follow only inbound edges

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"inbound\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"871619015\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"872470983\", \n          \"name\" : \"Eve\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"871619015\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/873322951\", \n              \"_key\" : \"873322951\", \n              \"_rev\" : \"873322951\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"871619015\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"872470983\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Follow any direction of edges

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"any\", \n  \"uniqueness\" : { \n    \"vertices\" : \"none\", \n    \"edges\" : \"global\" \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"841537991\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"842389959\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"841734599\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"841537991\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"841996743\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"842193351\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"841537991\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/843241927\", \n              \"_key\" : \"843241927\", \n              \"_rev\" : \"843241927\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"841537991\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"842389959\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/843241927\", \n              \"_key\" : \"843241927\", \n              \"_rev\" : \"843241927\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/843438535\", \n              \"_key\" : \"843438535\", \n              \"_rev\" : \"843438535\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"841537991\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"842389959\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"841734599\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/843241927\", \n              \"_key\" : \"843241927\", \n              \"_rev\" : \"843241927\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/843438535\", \n              \"_key\" : \"843438535\", \n              \"_rev\" : \"843438535\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/842652103\", \n              \"_key\" : \"842652103\", \n              \"_rev\" : \"842652103\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"841537991\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"842389959\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"841734599\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"841537991\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/843241927\", \n              \"_key\" : \"843241927\", \n              \"_rev\" : \"843241927\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/843438535\", \n              \"_key\" : \"843438535\", \n              \"_rev\" : \"843438535\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/842848711\", \n              \"_key\" : \"842848711\", \n              \"_rev\" : \"842848711\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"841537991\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"842389959\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"841734599\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"841996743\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/843241927\", \n              \"_key\" : \"843241927\", \n              \"_rev\" : \"843241927\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/843438535\", \n              \"_key\" : \"843438535\", \n              \"_rev\" : \"843438535\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/843045319\", \n              \"_key\" : \"843045319\", \n              \"_rev\" : \"843045319\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"841537991\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"842389959\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"841734599\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"842193351\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Excluding Charlie and Bob

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"outbound\", \n  \"filter\" : \"if (vertex.name === \\\"Bob\\\" ||     vertex.name === \\\"Charlie\\\") {  return \\\"exclude\\\";}return;\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"863427015\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"864082375\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"863427015\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/864541127\", \n              \"_key\" : \"864541127\", \n              \"_rev\" : \"864541127\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/864934343\", \n              \"_key\" : \"864934343\", \n              \"_rev\" : \"864934343\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"863427015\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"863623623\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"864082375\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Do not follow edges from Bob

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"outbound\", \n  \"filter\" : \"if (vertex.name === \\\"Bob\\\") {return \\\"prune\\\";}return;\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"867686855\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"867883463\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"867686855\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/868800967\", \n              \"_key\" : \"868800967\", \n              \"_rev\" : \"868800967\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"867686855\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"867883463\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Visit only nodes in a depth of at least 2

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"outbound\", \n  \"minDepth\" : 2 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"886299079\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"886495687\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/886954439\", \n              \"_key\" : \"886954439\", \n              \"_rev\" : \"886954439\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/887151047\", \n              \"_key\" : \"887151047\", \n              \"_rev\" : \"887151047\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"885840327\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"886036935\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"886299079\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/886954439\", \n              \"_key\" : \"886954439\", \n              \"_rev\" : \"886954439\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/887347655\", \n              \"_key\" : \"887347655\", \n              \"_rev\" : \"887347655\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"885840327\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"886036935\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"886495687\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Visit only nodes in a depth of at most 1

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"outbound\", \n  \"maxDepth\" : 1 \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"875616711\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"875813319\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"875616711\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/876730823\", \n              \"_key\" : \"876730823\", \n              \"_rev\" : \"876730823\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"875616711\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"875813319\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using a visitor function to return vertex ids only

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"outbound\", \n  \"visitor\" : \"result.visited.vertices.push(vertex._id);\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        \"persons/alice\", \n        \"persons/bob\", \n        \"persons/charlie\", \n        \"persons/dave\" \n      ], \n      \"paths\" : [ ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Count all visited nodes and return a list of nodes only

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"outbound\", \n  \"init\" : \"result.visited = 0; result.myVertices = [ ];\", \n  \"visitor\" : \"result.visited++; result.myVertices.push(vertex);\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : 4, \n    \"myVertices\" : [ \n      { \n        \"_id\" : \"persons/alice\", \n        \"_key\" : \"alice\", \n        \"_rev\" : \"900323783\", \n        \"name\" : \"Alice\" \n      }, \n      { \n        \"_id\" : \"persons/bob\", \n        \"_key\" : \"bob\", \n        \"_rev\" : \"900520391\", \n        \"name\" : \"Bob\" \n      }, \n      { \n        \"_id\" : \"persons/charlie\", \n        \"_key\" : \"charlie\", \n        \"_rev\" : \"900782535\", \n        \"name\" : \"Charlie\" \n      }, \n      { \n        \"_id\" : \"persons/dave\", \n        \"_key\" : \"dave\", \n        \"_rev\" : \"900979143\", \n        \"name\" : \"Dave\" \n      } \n    ] \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Expand only inbound edges of Alice and outbound edges of Eve

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"expander\" : \"var connections = [ ];if (vertex.name === \\\"Alice\\\") {config.datasource.getInEdges(vertex).forEach(function (e) {connections.push({ vertex: require(\\\"internal\\\").db._document(e._from), edge: e});});}if (vertex.name === \\\"Eve\\\") {config.datasource.getOutEdges(vertex).forEach(function (e) {connections.push({vertex: require(\\\"internal\\\").db._document(e._to), edge: e});});}return connections;\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"904583623\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"905435591\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"904780231\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"904583623\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/906287559\", \n              \"_key\" : \"906287559\", \n              \"_rev\" : \"906287559\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"904583623\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"905435591\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/906287559\", \n              \"_key\" : \"906287559\", \n              \"_rev\" : \"906287559\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/906484167\", \n              \"_key\" : \"906484167\", \n              \"_rev\" : \"906484167\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"904583623\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"905435591\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"904780231\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Follow the depthfirst strategy

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"any\", \n  \"strategy\" : \"depthfirst\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"852482503\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"853334471\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"852679111\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"852482503\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"852941255\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"853137863\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"852679111\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"853334471\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"852482503\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"852941255\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"853137863\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/854186439\", \n              \"_key\" : \"854186439\", \n              \"_rev\" : \"854186439\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"853334471\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/854186439\", \n              \"_key\" : \"854186439\", \n              \"_rev\" : \"854186439\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/854383047\", \n              \"_key\" : \"854383047\", \n              \"_rev\" : \"854383047\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"853334471\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/854186439\", \n              \"_key\" : \"854186439\", \n              \"_rev\" : \"854186439\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/854383047\", \n              \"_key\" : \"854383047\", \n              \"_rev\" : \"854383047\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/853596615\", \n              \"_key\" : \"853596615\", \n              \"_rev\" : \"853596615\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"853334471\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/854186439\", \n              \"_key\" : \"854186439\", \n              \"_rev\" : \"854186439\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/854383047\", \n              \"_key\" : \"854383047\", \n              \"_rev\" : \"854383047\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/853793223\", \n              \"_key\" : \"853793223\", \n              \"_rev\" : \"853793223\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"853334471\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"852941255\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/854186439\", \n              \"_key\" : \"854186439\", \n              \"_rev\" : \"854186439\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/854383047\", \n              \"_key\" : \"854383047\", \n              \"_rev\" : \"854383047\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/853989831\", \n              \"_key\" : \"853989831\", \n              \"_rev\" : \"853989831\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"853334471\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"853137863\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/853596615\", \n              \"_key\" : \"853596615\", \n              \"_rev\" : \"853596615\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/853596615\", \n              \"_key\" : \"853596615\", \n              \"_rev\" : \"853596615\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/854383047\", \n              \"_key\" : \"854383047\", \n              \"_rev\" : \"854383047\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"853334471\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/853596615\", \n              \"_key\" : \"853596615\", \n              \"_rev\" : \"853596615\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/854383047\", \n              \"_key\" : \"854383047\", \n              \"_rev\" : \"854383047\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/854186439\", \n              \"_key\" : \"854186439\", \n              \"_rev\" : \"854186439\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"853334471\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/853596615\", \n              \"_key\" : \"853596615\", \n              \"_rev\" : \"853596615\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/853793223\", \n              \"_key\" : \"853793223\", \n              \"_rev\" : \"853793223\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"852941255\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/853596615\", \n              \"_key\" : \"853596615\", \n              \"_rev\" : \"853596615\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/853989831\", \n              \"_key\" : \"853989831\", \n              \"_rev\" : \"853989831\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"852482503\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"852679111\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"853137863\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using postorder ordering

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"any\", \n  \"order\" : \"postorder\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"894360007\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"894818759\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"895015367\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"894556615\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"895211975\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"894360007\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"895211975\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"894818759\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"895015367\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"894556615\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"894360007\", \n          \"name\" : \"Alice\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/896063943\", \n              \"_key\" : \"896063943\", \n              \"_rev\" : \"896063943\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/896260551\", \n              \"_key\" : \"896260551\", \n              \"_rev\" : \"896260551\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/895474119\", \n              \"_key\" : \"895474119\", \n              \"_rev\" : \"895474119\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"895211975\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/896063943\", \n              \"_key\" : \"896063943\", \n              \"_rev\" : \"896063943\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/896260551\", \n              \"_key\" : \"896260551\", \n              \"_rev\" : \"896260551\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/895670727\", \n              \"_key\" : \"895670727\", \n              \"_rev\" : \"895670727\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"895211975\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"894818759\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/896063943\", \n              \"_key\" : \"896063943\", \n              \"_rev\" : \"896063943\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/896260551\", \n              \"_key\" : \"896260551\", \n              \"_rev\" : \"896260551\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/895867335\", \n              \"_key\" : \"895867335\", \n              \"_rev\" : \"895867335\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"895211975\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"895015367\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/896063943\", \n              \"_key\" : \"896063943\", \n              \"_rev\" : \"896063943\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/896260551\", \n              \"_key\" : \"896260551\", \n              \"_rev\" : \"896260551\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"895211975\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/896063943\", \n              \"_key\" : \"896063943\", \n              \"_rev\" : \"896063943\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"895211975\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/895474119\", \n              \"_key\" : \"895474119\", \n              \"_rev\" : \"895474119\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/896260551\", \n              \"_key\" : \"896260551\", \n              \"_rev\" : \"896260551\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/896063943\", \n              \"_key\" : \"896063943\", \n              \"_rev\" : \"896063943\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"895211975\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/895474119\", \n              \"_key\" : \"895474119\", \n              \"_rev\" : \"895474119\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/896260551\", \n              \"_key\" : \"896260551\", \n              \"_rev\" : \"896260551\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"895211975\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/895474119\", \n              \"_key\" : \"895474119\", \n              \"_rev\" : \"895474119\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/895670727\", \n              \"_key\" : \"895670727\", \n              \"_rev\" : \"895670727\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"894818759\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/895474119\", \n              \"_key\" : \"895474119\", \n              \"_rev\" : \"895474119\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/895867335\", \n              \"_key\" : \"895867335\", \n              \"_rev\" : \"895867335\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"895015367\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/895474119\", \n              \"_key\" : \"895474119\", \n              \"_rev\" : \"895474119\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"894556615\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"894360007\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Using backward item-ordering:

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"any\", \n  \"itemOrder\" : \"backward\" \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"846518727\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"846715335\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"847174087\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"846977479\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"847370695\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"846518727\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"847370695\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"846715335\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"847174087\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"846977479\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"846518727\", \n          \"name\" : \"Alice\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/847632839\", \n              \"_key\" : \"847632839\", \n              \"_rev\" : \"847632839\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/847632839\", \n              \"_key\" : \"847632839\", \n              \"_rev\" : \"847632839\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/848026055\", \n              \"_key\" : \"848026055\", \n              \"_rev\" : \"848026055\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"847174087\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/847632839\", \n              \"_key\" : \"847632839\", \n              \"_rev\" : \"847632839\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/847829447\", \n              \"_key\" : \"847829447\", \n              \"_rev\" : \"847829447\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"846977479\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/847632839\", \n              \"_key\" : \"847632839\", \n              \"_rev\" : \"847632839\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/848419271\", \n              \"_key\" : \"848419271\", \n              \"_rev\" : \"848419271\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"847370695\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/847632839\", \n              \"_key\" : \"847632839\", \n              \"_rev\" : \"847632839\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/848419271\", \n              \"_key\" : \"848419271\", \n              \"_rev\" : \"848419271\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/848222663\", \n              \"_key\" : \"848222663\", \n              \"_rev\" : \"848222663\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"847370695\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/848222663\", \n              \"_key\" : \"848222663\", \n              \"_rev\" : \"848222663\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"847370695\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/848222663\", \n              \"_key\" : \"848222663\", \n              \"_rev\" : \"848222663\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/848419271\", \n              \"_key\" : \"848419271\", \n              \"_rev\" : \"848419271\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"847370695\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/848222663\", \n              \"_key\" : \"848222663\", \n              \"_rev\" : \"848222663\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/848419271\", \n              \"_key\" : \"848419271\", \n              \"_rev\" : \"848419271\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/848026055\", \n              \"_key\" : \"848026055\", \n              \"_rev\" : \"848026055\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"847370695\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"847174087\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/848222663\", \n              \"_key\" : \"848222663\", \n              \"_rev\" : \"848222663\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/848419271\", \n              \"_key\" : \"848419271\", \n              \"_rev\" : \"848419271\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/847829447\", \n              \"_key\" : \"847829447\", \n              \"_rev\" : \"847829447\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"847370695\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"846977479\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/848222663\", \n              \"_key\" : \"848222663\", \n              \"_rev\" : \"848222663\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/848419271\", \n              \"_key\" : \"848419271\", \n              \"_rev\" : \"848419271\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/847632839\", \n              \"_key\" : \"847632839\", \n              \"_rev\" : \"847632839\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"847370695\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"846715335\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"846518727\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: Edges should only be included once globally, but nodes are included every time they are visited

shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"any\", \n  \"uniqueness\" : { \n    \"vertices\" : \"none\", \n    \"edges\" : \"global\" \n  } \n}\nEOF\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"858446279\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"859298247\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"858642887\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"858446279\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"858905031\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"859101639\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"858446279\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/860150215\", \n              \"_key\" : \"860150215\", \n              \"_rev\" : \"860150215\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"858446279\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"859298247\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/860150215\", \n              \"_key\" : \"860150215\", \n              \"_rev\" : \"860150215\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/860346823\", \n              \"_key\" : \"860346823\", \n              \"_rev\" : \"860346823\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"858446279\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"859298247\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"858642887\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/860150215\", \n              \"_key\" : \"860150215\", \n              \"_rev\" : \"860150215\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/860346823\", \n              \"_key\" : \"860346823\", \n              \"_rev\" : \"860346823\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/859560391\", \n              \"_key\" : \"859560391\", \n              \"_rev\" : \"859560391\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"858446279\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"859298247\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"858642887\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"858446279\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/860150215\", \n              \"_key\" : \"860150215\", \n              \"_rev\" : \"860150215\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/860346823\", \n              \"_key\" : \"860346823\", \n              \"_rev\" : \"860346823\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/859756999\", \n              \"_key\" : \"859756999\", \n              \"_rev\" : \"859756999\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"858446279\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"859298247\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"858642887\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"858905031\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/860150215\", \n              \"_key\" : \"860150215\", \n              \"_rev\" : \"860150215\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/860346823\", \n              \"_key\" : \"860346823\", \n              \"_rev\" : \"860346823\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/859953607\", \n              \"_key\" : \"859953607\", \n              \"_rev\" : \"859953607\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"858446279\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"859298247\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"858642887\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"859101639\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

\n
Example: If the underlying graph is cyclic, maxIterations should be set
The underlying graph has two vertices Alice and Bob. With the directed edges:
  • Alice knows Bob _ Bob knows Alice


shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal <<EOF\n{ \n  \"startVertex\" : \"persons/alice\", \n  \"graphName\" : \"knows_graph\", \n  \"direction\" : \"any\", \n  \"uniqueness\" : { \n    \"vertices\" : \"none\", \n    \"edges\" : \"none\" \n  }, \n  \"maxIterations\" : 5 \n}\nEOF\n\nHTTP/1.1 500 Internal Server Error\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 500, \n  \"errorNum\" : 1909, \n  \"errorMessage\" : \"too many iterations - try increasing the value of 'maxIterations'\" \n}\n

\n

", - "parameters": [ - { - "in": "body", - "name": "Json Post Body", - "required": true, - "schema": { - "$ref": "#/definitions/JSF_HTTP_API_TRAVERSAL" - }, - "x-description-offset": 222 - } - ], - "responses": { - "200": { - "description": "If the traversal is fully executed HTTP 200 will be returned.
" - }, - "400": { - "description": "If the traversal specification is either missing or malformed, the server will respond with HTTP 400.
" - }, - "404": { - "description": "The server will responded with HTTP 404 if the specified edge collection does not exist, or the specified start vertex cannot be found.
" - }, - "500": { - "description": "The server will responded with HTTP 500 when an error occurs inside the traversal or if a traversal performs more than maxIterations iterations.
" - } - }, - "summary": "executes a traversal", - "tags": [ - "Graph Traversal" - ], - "x-examples": [], - "x-filename": "Graph Traversal - js/actions/api-traversal.js" - } - }, - "/_api/user": { - "post": { - "description": "\n\n
The following data need to be passed in a JSON representation in the body of the POST request:
  • user: The name of the user as a string. This is mandatory.
  • passwd: The user password as a string. If no password is specified, the empty string will be used. If you pass the special value ARANGODB_DEFAULT_ROOT_PASSWORD, the password will be set the value stored in the environment variable `ARANGODB_DEFAULT_ROOT_PASSWORD`. This can be used to pass an instance variable into ArangoDB. For example, the instance identifier from Amazon.
  • active: An optional flag that specifies whether the user is active. If not specified, this will default to true
  • extra: An optional JSON object with arbitrary extra data about the user
  • changePassword: An optional flag that specifies whethers the user must change the password or not. If not specified, this will default to false. If set to true, the only operations allowed are PUT /_api/user or PATCH /_api/user. All other operations executed by the user will result in an HTTP 403.
If the user can be added by the server, the server will respond with HTTP 201. In case of success, the returned JSON object has the following properties:
  • error: Boolean flag to indicate that an error occurred (false in this case)
  • code: The HTTP status code
In case of error, the body of the response will contain a JSON object with additional error details. The object has the following attributes:
  • error: Boolean flag to indicate that an error occurred (true in this case)
  • code: The HTTP status code
  • errorNum: The server error number
  • errorMessage: A descriptive error message
", - "parameters": [], - "responses": { - "201": { - "description": "Returned if the user can be added by the server
" - }, - "400": { - "description": "If the JSON representation is malformed or mandatory data is missing from the request.

" - } - }, - "summary": " Create User", - "tags": [ - "User handling" - ], - "x-examples": [], - "x-filename": "User handling - js/actions/_api/user/app.js" - } - }, - "/_api/user/": { - "get": { - "description": "\n\n
Fetches data about all users.
The call will return a JSON object with at least the following attributes on success:
  • user: The name of the user as a string.
  • active: An optional flag that specifies whether the user is active.
  • extra: An optional JSON object with arbitrary extra data about the user.
  • changePassword: An optional flag that specifies whether the user must change the password or not.
", - "parameters": [], - "responses": { - "200": { - "description": "The users that were found

" - } - }, - "summary": " List available Users", - "tags": [ - "User handling" - ], - "x-examples": [], - "x-filename": "User handling - js/actions/_api/user/app.js" - } - }, - "/_api/user/{user}": { - "delete": { - "description": "\n\n
Removes an existing user, identified by user.
If the user can be removed, the server will respond with HTTP 202. In case of success, the returned JSON object has the following properties:
  • error: Boolean flag to indicate that an error occurred (false in this case)
  • code: The HTTP status code
In case of error, the body of the response will contain a JSON object with additional error details. The object has the following attributes:
  • error: Boolean flag to indicate that an error occurred (true in this case)
  • code: The HTTP status code
  • errorNum: The server error number
  • errorMessage: A descriptive error message
", - "parameters": [ - { - "description": "The name of the user
", - "format": "string", - "in": "path", - "name": "user", - "required": true, - "type": "string" - } - ], - "responses": { - "202": { - "description": "Is returned if the user was removed by the server
" - }, - "404": { - "description": "The specified user does not exist

" - } - }, - "summary": " Remove User", - "tags": [ - "User handling" - ], - "x-examples": [], - "x-filename": "User handling - js/actions/_api/user/app.js" - }, - "get": { - "description": "\n\n
Fetches data about the specified user.
The call will return a JSON object with at least the following attributes on success:
  • user: The name of the user as a string.
  • active: An optional flag that specifies whether the user is active.
  • extra: An optional JSON object with arbitrary extra data about the user.
  • changePassword: An optional flag that specifies whether the user must change the password or not.
", - "parameters": [ - { - "description": "The name of the user
", - "format": "string", - "in": "path", - "name": "user", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "The user was found
" - }, - "404": { - "description": "The user with the specified name does not exist

" - } - }, - "summary": " Fetch User", - "tags": [ - "User handling" - ], - "x-examples": [], - "x-filename": "User handling - js/actions/_api/user/app.js" - }, - "patch": { - "description": "\n\n
Partially updates the data of an existing user. The name of an existing user must be specified in user.
The following data can be passed in a JSON representation in the body of the POST request:
  • passwd: The user password as a string. Specifying a password is optional. If not specified, the previously existing value will not be modified.
  • active: An optional flag that specifies whether the user is active. If not specified, the previously existing value will not be modified.
  • extra: An optional JSON object with arbitrary extra data about the user. If not specified, the previously existing value will not be modified.
  • changePassword: An optional flag that specifies whether the user must change the password or not. If not specified, the previously existing value will not be modified.
If the user can be updated by the server, the server will respond with HTTP 200.
In case of success, the returned JSON object has the following properties:
  • error: Boolean flag to indicate that an error occurred (false in this case)
  • code: The HTTP status code
In case of error, the body of the response will contain a JSON object with additional error details. The object has the following attributes:
  • error: Boolean flag to indicate that an error occurred (true in this case)
  • code: The HTTP status code
  • errorNum: The server error number
  • errorMessage: A descriptive error message
", - "parameters": [ - { - "description": "The name of the user
", - "format": "string", - "in": "path", - "name": "user", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "Is returned if the user data can be replaced by the server
" - }, - "400": { - "description": "The JSON representation is malformed or mandatory data is missing from the request
" - }, - "404": { - "description": "The specified user does not exist

" - } - }, - "summary": " Update User", - "tags": [ - "User handling" - ], - "x-examples": [], - "x-filename": "User handling - js/actions/_api/user/app.js" - }, - "put": { - "description": "\n\n
Replaces the data of an existing user. The name of an existing user must be specified in user.
The following data can to be passed in a JSON representation in the body of the POST request:
  • passwd: The user password as a string. Specifying a password is mandatory, but the empty string is allowed for passwords
  • active: An optional flag that specifies whether the user is active. If not specified, this will default to true
  • extra: An optional JSON object with arbitrary extra data about the user
  • changePassword: An optional flag that specifies whether the user must change the password or not. If not specified, this will default to false
If the user can be replaced by the server, the server will respond with HTTP 200.
In case of success, the returned JSON object has the following properties:
  • error: Boolean flag to indicate that an error occurred (false in this case)
  • code: The HTTP status code
In case of error, the body of the response will contain a JSON object with additional error details. The object has the following attributes:
  • error: Boolean flag to indicate that an error occurred (true in this case)
  • code: The HTTP status code
  • errorNum: The server error number
  • errorMessage: A descriptive error message
", - "parameters": [ - { - "description": "The name of the user
", - "format": "string", - "in": "path", - "name": "user", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "Is returned if the user data can be replaced by the server
" - }, - "400": { - "description": "The JSON representation is malformed or mandatory data is missing from the request
" - }, - "404": { - "description": "The specified user does not exist

" - } - }, - "summary": " Replace User", - "tags": [ - "User handling" - ], - "x-examples": [], - "x-filename": "User handling - js/actions/_api/user/app.js" - } - }, - "/_api/version": { - "get": { - "description": "\n\nReturns the server name and version number. The response is a JSON object with the following attributes:
**A json document with these Properties is returned:**
  • version: the server version string. The string has the format \"major.*minor.*sub\". major and minor will be numeric, and sub may contain a number or a textual version.
  • details: an optional JSON object with additional details. This is returned only if the details URL parameter is set to true in the request.
  • server: will always contain arango

Example: Return the version information

shell> curl --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"server\" : \"arango\", \n  \"version\" : \"2.7.0-devel\" \n}\n

\n
Example: Return the version information with details

shell> curl --dump - http://localhost:8529/_api/version?details=true\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"server\" : \"arango\", \n  \"version\" : \"2.7.0-devel\", \n  \"details\" : { \n    \"architecture\" : \"64bit\", \n    \"build-date\" : \"2015-09-25 11:17:39\", \n    \"configure\" : \"'./configure' '--enable-relative' '--enable-maintainer-mode' '--with-backtrace' '--enable-v8-debug' 'CXXFLAGS=-O0 -ggdb -DDEBUG_CLUSTER_COMM' 'CFLAGS=-O0 -ggdb  -DDEBUG_CLUSTER_COMM'\", \n    \"env\" : \"CFLAGS='-O0 -ggdb  -DDEBUG_CLUSTER_COMM' CXXFLAGS='-O0 -ggdb -DDEBUG_CLUSTER_COMM'\", \n    \"fd-client-event-handler\" : \"poll\", \n    \"fd-setsize\" : \"1024\", \n    \"icu-version\" : \"54.1\", \n    \"libev-version\" : \"4.11\", \n    \"maintainer-mode\" : \"true\", \n    \"openssl-version\" : \"OpenSSL 1.0.2 22 Jan 2015\", \n    \"readline-version\" : \"6.3\", \n    \"repository-version\" : \"heads/devel-0-g43dd92bb4716d73c7128478b4a7cdb36fd200421\", \n    \"server-version\" : \"2.7.0-devel\", \n    \"sizeof int\" : \"4\", \n    \"sizeof void*\" : \"8\", \n    \"tcmalloc\" : \"false\", \n    \"v8-version\" : \"4.3.61\", \n    \"mode\" : \"standalone\" \n  } \n}\n

\n
", - "parameters": [ - { - "description": "If set to true, the response will contain a details attribute with additional information about included components and their versions. The attribute names and internals of the details object may vary depending on platform and ArangoDB version.
", - "in": "query", - "name": "details", - "required": false, - "type": "boolean" - } - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "is returned in all cases.
", - "schema": { - "$ref": "#/definitions/JSF_get_api_return_rc_200" - }, - "x-description-offset": 165 - } - }, - "summary": " Return server version", - "tags": [ - "Administration" - ], - "x-examples": [], - "x-filename": "Administration - js/actions/_admin/app.js, js/actions/_admin/routing/app.js, js/actions/_admin/server/app.js, js/actions/_admin/database/app.js, arangod/RestHandler/RestShutdownHandler.cpp, arangod/RestHandler/RestAdminLogHandler.cpp, js/actions/api-tasks.js, js/actions/api-endpoint.js, arangod/RestHandler/RestVersionHandler.cpp, js/actions/api-system.js" - } - } - }, - "schemes": [ - "http" - ], - "swagger": "2.0" -} From 379932e063c7ae0ccea97c83ce8e1ad129fa1ad8 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Wed, 30 Nov 2022 14:30:15 +0100 Subject: [PATCH 2/2] updated test java versions --- .github/workflows/maven.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 46d9229..95f8783 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -20,7 +20,8 @@ jobs: java-version: - 8 - 11 - - 16 + - 17 + - 19 steps: - uses: actions/checkout@v2