Repository: tinkerpop Updated Branches: refs/heads/TINKERPOP-919 [created] ead131069
TINKERPOP-919 Added supportsIdenticalMultiProperties() That feature allows a graph to specify whether or not it supports multi-properties that allow the same value to be supplied on the same key. Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/ead13106 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/ead13106 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/ead13106 Branch: refs/heads/TINKERPOP-919 Commit: ead13106981bc019be25b66e0e432741c3646a2f Parents: 285ff35 Author: Stephen Mallette <sp...@genoprime.com> Authored: Tue Oct 25 13:50:48 2016 -0400 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Tue Oct 25 13:50:48 2016 -0400 ---------------------------------------------------------------------- CHANGELOG.asciidoc | 1 + .../upgrade/release-3.2.x-incubating.asciidoc | 13 ++++++++++ .../tinkerpop/gremlin/structure/Graph.java | 12 +++++++++ .../gremlin/structure/VertexProperty.java | 4 +++ .../gremlin/structure/FeatureSupportTest.java | 27 ++++++++++++++++++-- .../gremlin/structure/VertexPropertyTest.java | 26 ++++++++++++++++--- 6 files changed, 78 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ead13106/CHANGELOG.asciidoc ---------------------------------------------------------------------- diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index a281c38..1adee55 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima TinkerPop 3.2.4 (Release Date: NOT OFFICIALLY RELEASED YET) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* Added `VertexFeatures.supportsIdenticalMultiProperties()` for graphs that only support unique values in multi-properties. * Fixed a severe bug where `GraphComputer` strategies are not being loaded until the second use of the traversal source. [[release-3-2-3]] http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ead13106/docs/src/upgrade/release-3.2.x-incubating.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc index 3ed46b2..05dc3ad 100644 --- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc +++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc @@ -29,6 +29,19 @@ TinkerPop 3.2.4 Please see the link:https://github.com/apache/tinkerpop/blob/3.2.4/CHANGELOG.asciidoc#release-3-2-4[changelog] for a complete list of all the modifications that are part of this release. +Upgrading for Providers +~~~~~~~~~~~~~~~~~~~~~~~ + +Graph Database Providers +^^^^^^^^^^^^^^^^^^^^^^^^ + +Unique Multi-Properties ++++++++++++++++++++++++ + +Added `supportsIdenticalMultiProperties` to `VertexFeatures` so that graph provider who only support unique values as +multi-properties have more flexibility in describing their graph capabilities. + +See: https://issues.apache.org/jira/browse/TINKERPOP-919[TINKERPOP-919] TinkerPop 3.2.3 --------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ead13106/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java index 01379f4..617acc3 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java @@ -24,6 +24,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.engine.ComputerTraversalEngine; import org.apache.tinkerpop.gremlin.structure.io.Io; import org.apache.tinkerpop.gremlin.structure.io.IoRegistry; import org.apache.tinkerpop.gremlin.structure.util.FeatureDescriptor; @@ -512,6 +513,7 @@ public interface Graph extends AutoCloseable, Host { public interface VertexFeatures extends ElementFeatures { public static final String FEATURE_ADD_VERTICES = "AddVertices"; public static final String FEATURE_MULTI_PROPERTIES = "MultiProperties"; + public static final String FEATURE_IDENTICAL_MULTI_PROPERTIES = "IdenticalMultiProperties"; public static final String FEATURE_META_PROPERTIES = "MetaProperties"; public static final String FEATURE_REMOVE_VERTICES = "RemoveVertices"; @@ -550,6 +552,16 @@ public interface Graph extends AutoCloseable, Host { } /** + * Determines if a {@link Vertex} can support non-unique values on the same key. For this value to be + * {@code true}, then {@link #supportsMetaProperties()} must also return true. By default this method, + * just returns what {@link #supportsMultiProperties()} returns. + */ + @FeatureDescriptor(name = FEATURE_IDENTICAL_MULTI_PROPERTIES) + public default boolean supportsIdenticalMultiProperties() { + return supportsMultiProperties(); + } + + /** * Determines if a {@link Vertex} can support properties on vertex properties. It is assumed that a * graph will support all the same data types for meta-properties that are supported for regular * properties. http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ead13106/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexProperty.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexProperty.java index ecbefb3..c6b443c 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexProperty.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexProperty.java @@ -99,6 +99,10 @@ public interface VertexProperty<V> extends Property<V>, Element { return new UnsupportedOperationException("Multiple properties on a vertex is not supported"); } + public static UnsupportedOperationException identicalMultiPropertiesNotSupported() { + return new UnsupportedOperationException("Multiple properties on a vertex is supported, but a single key may not hold the same value more than once"); + } + public static UnsupportedOperationException metaPropertiesNotSupported() { return new UnsupportedOperationException("Properties on a vertex property is not supported"); } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ead13106/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java index 98406b4..d3e0986 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java @@ -697,7 +697,8 @@ public class FeatureSupportTest { "multiPropertiesNotSupported", "metaPropertiesNotSupported", "userSuppliedIdsNotSupported", - "userSuppliedIdsOfThisTypeNotSupported" + "userSuppliedIdsOfThisTypeNotSupported", + "identicalMultiPropertiesNotSupported" }) @ExceptionCoverage(exceptionClass = Element.Exceptions.class, methods = { "propertyRemovalNotSupported" @@ -877,6 +878,22 @@ public class FeatureSupportTest { @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES) @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY) + @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = VertexFeatures.FEATURE_MULTI_PROPERTIES) + @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = VertexFeatures.FEATURE_IDENTICAL_MULTI_PROPERTIES, supported = false) + public void shouldSupportIdenticalMultiPropertyIfTheSameKeyCanBeAssignedSameValueMoreThanOnce() throws Exception { + try { + final Vertex v = graph.addVertex("name", "stephen", "name", "stephen"); + if (2 == IteratorUtils.count(v.properties())) + fail(String.format(INVALID_FEATURE_SPECIFICATION, VertexFeatures.class.getSimpleName(), VertexFeatures.FEATURE_IDENTICAL_MULTI_PROPERTIES)); + } catch (Exception ex) { + validateException(VertexProperty.Exceptions.identicalMultiPropertiesNotSupported(), ex); + } + } + + @Test + @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES) + @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) + @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_PROPERTY) @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = VertexFeatures.FEATURE_MULTI_PROPERTIES, supported = false) public void shouldSupportMultiPropertyIfTheSameKeyCanBeAssignedMoreThanOnce() throws Exception { try { @@ -1023,7 +1040,13 @@ public class FeatureSupportTest { @Test public void shouldSupportRegularTransactionsIfThreadedTransactionsAreEnabled() { if (graphFeatures.supportsThreadedTransactions()) - assertTrue(graphFeatures.supportsThreadedTransactions()); + assertThat(graphFeatures.supportsThreadedTransactions(), is(true)); + } + + @Test + public void shouldSupportMultiPropertiesIfSupportingIdenticalMultiProperties() { + if (vertexFeatures.supportsIdenticalMultiProperties()) + assertThat(vertexFeatures.supportsMultiProperties(), is(true)); } } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ead13106/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexPropertyTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexPropertyTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexPropertyTest.java index 845be70..a265d4e 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexPropertyTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/VertexPropertyTest.java @@ -34,6 +34,7 @@ import java.util.Map; import java.util.UUID; import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThat; @@ -288,11 +289,8 @@ public class VertexPropertyTest extends AbstractGremlinTest { } } }); - - } - @Test @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_META_PROPERTIES) @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_MULTI_PROPERTIES) @@ -329,6 +327,28 @@ public class VertexPropertyTest extends AbstractGremlinTest { assertEquals(0, IteratorUtils.count(newMexico.properties(T.key.getAccessor()))); assertEquals(0, IteratorUtils.count(newMexico.properties(T.value.getAccessor()))); } + + @Test + @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY) + @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_MULTI_PROPERTIES) + @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_IDENTICAL_MULTI_PROPERTIES) + public void shouldAllowIdenticalValuedMultiProperties() { + final Vertex v = graph.addVertex(); + v.property(VertexProperty.Cardinality.list, "name", "stephen"); + v.property(VertexProperty.Cardinality.list, "name", "stephen"); + v.property(VertexProperty.Cardinality.list, "name", "steve"); + v.property(VertexProperty.Cardinality.list, "name", "stephen"); + v.property(VertexProperty.Cardinality.list, "color", "red"); + + tryCommit(graph, g -> { + final Vertex vertex = graph.vertices(v).next(); + assertEquals(4, IteratorUtils.count(vertex.properties("name"))); + assertEquals(1, IteratorUtils.count(vertex.properties("color"))); + assertEquals(5, IteratorUtils.count(vertex.properties())); + + assertThat(IteratorUtils.set(vertex.values("name")), contains("stephen", "steve")); + }); + } } public static class VertexPropertyRemoval extends AbstractGremlinTest {