diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/record/ConstraintRule.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/record/ConstraintRule.java index f00d446054f94..60ff7af632bef 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/record/ConstraintRule.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/record/ConstraintRule.java @@ -39,8 +39,10 @@ public class ConstraintRule implements SchemaRule, ConstraintDescriptor.Supplier { + static final Long NO_OWNED_INDEX_RULE = null; + private final long id; - private final Optional ownedIndexRule; + private final Long ownedIndexRule; private final ConstraintDescriptor descriptor; @Override @@ -52,16 +54,16 @@ public final long getId() public static ConstraintRule constraintRule( long id, ConstraintDescriptor descriptor ) { - return new ConstraintRule( id, descriptor, Optional.empty() ); + return new ConstraintRule( id, descriptor, NO_OWNED_INDEX_RULE ); } public static ConstraintRule constraintRule( long id, ConstraintDescriptor descriptor, long ownedIndexRule ) { - return new ConstraintRule( id, descriptor, Optional.of( ownedIndexRule ) ); + return new ConstraintRule( id, descriptor, ownedIndexRule ); } - ConstraintRule( long id, ConstraintDescriptor descriptor, Optional ownedIndexRule ) + ConstraintRule( long id, ConstraintDescriptor descriptor, Long ownedIndexRule ) { this.id = id; this.descriptor = descriptor; @@ -86,9 +88,14 @@ public ConstraintDescriptor getConstraintDescriptor() return descriptor; } + @SuppressWarnings( "NumberEquality" ) public long getOwnedIndex() { - return ownedIndexRule.orElseThrow( IllegalStateException::new ); + if ( ownedIndexRule == NO_OWNED_INDEX_RULE ) + { + throw new IllegalStateException( "This constraint does not own an index." ); + } + return ownedIndexRule; } @Override @@ -153,6 +160,7 @@ public Integer computeSpecific( RelationTypeSchemaDescriptor schema ) } }; + @SuppressWarnings( "NumberEquality" ) class Serializer implements SchemaProcessor { private final ByteBuffer buffer; @@ -175,9 +183,9 @@ public void processSpecific( LabelSchemaDescriptor schema ) { buffer.putLong( propertyKeyId ); } - if ( ownedIndexRule.isPresent() ) + if ( ownedIndexRule != NO_OWNED_INDEX_RULE ) { - buffer.putLong( ownedIndexRule.get() ); + buffer.putLong( ownedIndexRule ); } break; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/record/SchemaRuleDeserializer2_0to3_1.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/record/SchemaRuleDeserializer2_0to3_1.java index 6839e23abf154..950a1f9e7b01b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/record/SchemaRuleDeserializer2_0to3_1.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/record/SchemaRuleDeserializer2_0to3_1.java @@ -135,14 +135,14 @@ public static ConstraintRule readNodePropertyExistenceConstraintRule( long id, i { return new ConstraintRule( id, ConstraintDescriptorFactory.existsForLabel( labelId, readPropertyKey( buffer ) ), - Optional.empty() ); + ConstraintRule.NO_OWNED_INDEX_RULE ); } public static ConstraintRule readRelPropertyExistenceConstraintRule( long id, int relTypeId, ByteBuffer buffer ) { return new ConstraintRule( id, ConstraintDescriptorFactory.existsForRelType( relTypeId, readPropertyKey( buffer ) ), - Optional.empty() ); + ConstraintRule.NO_OWNED_INDEX_RULE ); } private static int readPropertyKey( ByteBuffer buffer ) @@ -160,8 +160,8 @@ private static int[] readConstraintPropertyKeys( ByteBuffer buffer ) return keys; } - private static Optional readOwnedIndexRule( ByteBuffer buffer ) + private static Long readOwnedIndexRule( ByteBuffer buffer ) { - return Optional.of( buffer.getLong() ); + return buffer.getLong(); } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/ConstraintRuleTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/ConstraintRuleTest.java new file mode 100644 index 0000000000000..f8f6a28c1ae9a --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/ConstraintRuleTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.store.record; + +import org.junit.Test; + +import org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptor; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptorFactory.existsForLabel; +import static org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptorFactory.existsForRelType; +import static org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptorFactory.uniqueForLabel; +import static org.neo4j.kernel.api.schema_new.constaints.ConstraintDescriptorFactory.uniqueForRelType; +import static org.neo4j.test.assertion.Assert.assertException; + +public class ConstraintRuleTest extends SchemaRuleTestBase +{ + @Test + public void shouldCreateUniquenessConstraint() throws Exception + { + // GIVEN + ConstraintDescriptor descriptor = uniqueForLabel( LABEL_ID, PROPERTY_ID_1 ); + ConstraintRule constraintRule = ConstraintRule.constraintRule( RULE_ID, descriptor ); + + // THEN + assertThat( constraintRule.getId(), equalTo( RULE_ID ) ); + assertThat( constraintRule.getSchemaDescriptor(), equalTo( descriptor.schema() ) ); + assertThat( constraintRule.getConstraintDescriptor(), equalTo( descriptor ) ); + assertException( constraintRule::getOwnedIndex, IllegalStateException.class, "" ); + } + + @Test + public void shouldCreateUniquenessConstraintWithOwnedIndex() throws Exception + { + // GIVEN + ConstraintDescriptor descriptor = uniqueForLabel( LABEL_ID, PROPERTY_ID_1 ); + ConstraintRule constraintRule = ConstraintRule.constraintRule( RULE_ID, descriptor, RULE_ID_2 ); + + // THEN + assertThat( constraintRule.getConstraintDescriptor(), equalTo( descriptor ) ); + assertThat( constraintRule.getOwnedIndex(), equalTo( RULE_ID_2 ) ); + } + + @Test + public void shouldCreateExistenceConstraint() throws Exception + { + // GIVEN + ConstraintDescriptor descriptor = existsForLabel( LABEL_ID, PROPERTY_ID_1 ); + ConstraintRule constraintRule = ConstraintRule.constraintRule( RULE_ID, descriptor ); + + // THEN + assertThat( constraintRule.getId(), equalTo( RULE_ID ) ); + assertThat( constraintRule.getSchemaDescriptor(), equalTo( descriptor.schema() ) ); + assertThat( constraintRule.getConstraintDescriptor(), equalTo( descriptor ) ); + assertException( constraintRule::getOwnedIndex, IllegalStateException.class, "" ); + } + + @Test + public void indexRulesAreEqualBasedOnConstraintDescriptor() throws Exception + { + assertEqualityByDescriptor( existsForLabel( LABEL_ID, PROPERTY_ID_1 ) ); + assertEqualityByDescriptor( uniqueForLabel( LABEL_ID, PROPERTY_ID_1 ) ); + assertEqualityByDescriptor( existsForRelType( REL_TYPE_ID, PROPERTY_ID_1 ) ); + assertEqualityByDescriptor( uniqueForRelType( REL_TYPE_ID, PROPERTY_ID_1 ) ); + assertEqualityByDescriptor( existsForLabel( LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ) ); + assertEqualityByDescriptor( uniqueForLabel( LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ) ); + } + + private void assertEqualityByDescriptor( ConstraintDescriptor descriptor ) + { + ConstraintRule rule1 = ConstraintRule.constraintRule( RULE_ID, descriptor, RULE_ID_2 ); + ConstraintRule rule2 = ConstraintRule.constraintRule( RULE_ID_2, descriptor ); + + assertEquality( rule1, rule2 ); + } +} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/IndexRuleTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/IndexRuleTest.java new file mode 100644 index 0000000000000..5dd85b7049aa3 --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/IndexRuleTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.store.record; + +import org.junit.Test; + +import org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.neo4j.kernel.api.schema_new.index.NewIndexDescriptorFactory.forLabel; +import static org.neo4j.kernel.api.schema_new.index.NewIndexDescriptorFactory.uniqueForLabel; +import static org.neo4j.test.assertion.Assert.assertException; + +public class IndexRuleTest extends SchemaRuleTestBase +{ + @Test + public void shouldCreateGeneralIndex() throws Exception + { + // GIVEN + NewIndexDescriptor descriptor = forLabel( LABEL_ID, PROPERTY_ID_1 ); + IndexRule indexRule = IndexRule.indexRule( RULE_ID, descriptor, PROVIDER_DESCRIPTOR ); + + // THEN + assertThat( indexRule.getId(), equalTo( RULE_ID ) ); + assertFalse( indexRule.canSupportUniqueConstraint() ); + assertThat( indexRule.getSchemaDescriptor(), equalTo( descriptor.schema() ) ); + assertThat( indexRule.getIndexDescriptor(), equalTo( descriptor ) ); + assertThat( indexRule.getProviderDescriptor(), equalTo( PROVIDER_DESCRIPTOR ) ); + assertException( indexRule::getOwningConstraint, IllegalStateException.class, "" ); + assertException( () -> indexRule.withOwningConstraint( RULE_ID_2 ), IllegalStateException.class, "" ); + } + + @Test + public void shouldCreateUniqueIndex() throws Exception + { + // GIVEN + NewIndexDescriptor descriptor = uniqueForLabel( LABEL_ID, PROPERTY_ID_1 ); + IndexRule indexRule = IndexRule.indexRule( RULE_ID, descriptor, PROVIDER_DESCRIPTOR ); + + // THEN + assertThat( indexRule.getId(), equalTo( RULE_ID ) ); + assertTrue( indexRule.canSupportUniqueConstraint() ); + assertThat( indexRule.getSchemaDescriptor(), equalTo( descriptor.schema() ) ); + assertThat( indexRule.getIndexDescriptor(), equalTo( descriptor ) ); + assertThat( indexRule.getProviderDescriptor(), equalTo( PROVIDER_DESCRIPTOR ) ); + assertThat( indexRule.getOwningConstraint(), equalTo( null ) ); + + IndexRule withConstraint = indexRule.withOwningConstraint( RULE_ID_2 ); + assertThat( withConstraint.getOwningConstraint(), equalTo( RULE_ID_2 ) ); + assertThat( indexRule.getOwningConstraint(), equalTo( null ) ); // this is unchanged + } + + @Test + public void indexRulesAreEqualBasedOnIndexDescriptor() throws Exception + { + assertEqualityByDescriptor( forLabel( LABEL_ID, PROPERTY_ID_1 ) ); + assertEqualityByDescriptor( uniqueForLabel( LABEL_ID, PROPERTY_ID_1 ) ); + assertEqualityByDescriptor( forLabel( LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ) ); + assertEqualityByDescriptor( uniqueForLabel( LABEL_ID, PROPERTY_ID_1, PROPERTY_ID_2 ) ); + } + + private void assertEqualityByDescriptor( NewIndexDescriptor descriptor ) + { + IndexRule rule1 = IndexRule.indexRule( RULE_ID, descriptor, PROVIDER_DESCRIPTOR ); + IndexRule rule2 = IndexRule.indexRule( RULE_ID_2, descriptor, PROVIDER_DESCRIPTOR_2 ); + + assertEquality( rule1, rule2 ); + } +} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/SchemaRuleTestBase.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/SchemaRuleTestBase.java new file mode 100644 index 0000000000000..747ea0739b8d0 --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/record/SchemaRuleTestBase.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.store.record; + +import org.neo4j.kernel.api.index.SchemaIndexProvider; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +abstract class SchemaRuleTestBase +{ + protected static final long RULE_ID = 1; + protected static final long RULE_ID_2 = 1; + protected static final int LABEL_ID = 10; + protected static final int REL_TYPE_ID = 20; + protected static final int PROPERTY_ID_1 = 30; + protected static final int PROPERTY_ID_2 = 31; + + protected static final SchemaIndexProvider.Descriptor PROVIDER_DESCRIPTOR = + new SchemaIndexProvider.Descriptor( "index-provider", "1.0" ); + protected static final SchemaIndexProvider.Descriptor PROVIDER_DESCRIPTOR_2 = + new SchemaIndexProvider.Descriptor( "index-provider-2", "2.0" ); + + protected void assertEquality( Object o1, Object o2 ) + { + assertThat( o1, equalTo( o2 ) ); + assertThat( o2, equalTo( o1 ) ); + assertThat( o1.hashCode(), equalTo( o2.hashCode() ) ); + } +}