Skip to content

Commit

Permalink
Introduce IndexDefinition.getName and Schema.getIndexByName, and Inde…
Browse files Browse the repository at this point in the history
…xCreator.withName.

Also makes FTS procedures use standard Schema.awaitIndexOnline instead of a local copy of that method.
  • Loading branch information
chrisvest committed Oct 4, 2018
1 parent f2564a4 commit 43a271b
Show file tree
Hide file tree
Showing 14 changed files with 145 additions and 26 deletions.
Expand Up @@ -214,7 +214,7 @@ public void droppingAnUnexistingIndexShouldGiveHelpfulExceptionInSameTransaction
}
catch ( ConstraintViolationException e )
{
assertThat( e.getMessage(), containsString( "No index was found for :MY_LABEL(my_property_key)." ) );
assertThat( e.getMessage(), containsString( "No such INDEX ON :MY_LABEL(my_property_key)." ) );
}
tx.success();
}
Expand All @@ -238,7 +238,7 @@ public void droppingAnUnexistingIndexShouldGiveHelpfulExceptionInSeparateTransac
}
catch ( ConstraintViolationException e )
{
assertThat( e.getMessage(), containsString( "No index was found for :MY_LABEL(my_property_key)." ) );
assertThat( e.getMessage(), containsString( "No such INDEX ON :MY_LABEL(my_property_key)." ) );
}

// THEN
Expand Down
Expand Up @@ -33,12 +33,15 @@
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.graphdb.schema.Schema;
import org.neo4j.helpers.collection.Iterables;
import org.neo4j.internal.kernel.api.IndexReference;
import org.neo4j.test.TestGraphDatabaseFactory;
import org.neo4j.test.extension.EphemeralFileSystemExtension;
import org.neo4j.test.extension.Inject;
import org.neo4j.test.extension.TestDirectoryExtension;
import org.neo4j.test.rule.TestDirectory;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
Expand All @@ -47,6 +50,8 @@
@ExtendWith( {EphemeralFileSystemExtension.class, TestDirectoryExtension.class} )
public class SchemaImplTest
{
private static final Label USER_LABEL = Label.label( "User" );

@Inject
private EphemeralFileSystemAbstraction fs;
@Inject
Expand All @@ -69,7 +74,7 @@ void shutdownDb()
@Test
void testGetIndexPopulationProgress() throws Exception
{
assertFalse( indexExists( Label.label( "User" ) ) );
assertFalse( indexExists( USER_LABEL ) );

// Create some nodes
try ( Transaction tx = db.beginTx() )
Expand All @@ -90,9 +95,7 @@ void testGetIndexPopulationProgress() throws Exception
try ( Transaction tx = db.beginTx() )
{
Schema schema = db.schema();
indexDefinition = schema.indexFor( Label.label( "User" ) )
.on( "username" )
.create();
indexDefinition = schema.indexFor( USER_LABEL ).on( "username" ).create();
tx.success();
}

Expand All @@ -119,6 +122,35 @@ void testGetIndexPopulationProgress() throws Exception
}
}

@Test
void createdIndexDefinitionsMustBeUnnamed()
{
try ( Transaction tx = db.beginTx() )
{
IndexDefinition index = db.schema().indexFor( USER_LABEL ).on( "name" ).create();
assertThat( index.getName(), is( IndexReference.UNNAMED_INDEX ) );
tx.success();
}
}

@Test
void mustRememberNamesOfCreatedIndex()
{
String indexName = "Users index";
try ( Transaction tx = db.beginTx() )
{
IndexDefinition index = db.schema().indexFor( USER_LABEL ).on( "name" ).withName( indexName ).create();
assertThat( index.getName(), is( indexName ) );
tx.success();
}
try ( Transaction tx = db.beginTx() )
{
IndexDefinition index = db.schema().getIndexByName( indexName );
assertThat( index.getName(), is( indexName ) );
tx.success();
}
}

private boolean indexExists( Label label )
{
try ( Transaction transaction = db.beginTx() )
Expand Down
Expand Up @@ -27,7 +27,7 @@
* A builder for entering details about an index to create. After all details have been entered
* {@link #create()} must be called for the index to actually be created. An index creator knows
* which {@link Label label} it is to be created for.
*
* <p>
* All methods except {@link #create()} will return an {@link IndexCreator} which should be
* used for further interaction.
*
Expand All @@ -38,14 +38,23 @@ public interface IndexCreator
/**
* Includes the given {@code propertyKey} in this index, such that {@link Node nodes} with
* the assigned {@link Label label} and this property key will have its values indexed.
*
* <p>
* NOTE: currently only a single property key per index is supported.
*
* @param propertyKey the property key to include in this index to be created.
* @return an {@link IndexCreator} instance to be used for further interaction.
*/
IndexCreator on( String propertyKey );

/**
* Assign a name to the index, which will then be returned from {@link IndexDefinition#getName()}, and can be used for finding the index with
* {@link Schema#getIndexByName(String)}.
*
* @param indexName the name to give the index.
* @return an {@link IndexCreator} instance to be used for further interaction.
*/
IndexCreator withName( String indexName );

/**
* Creates an index with the details specified by the other methods in this interface.
*
Expand Down
Expand Up @@ -19,6 +19,8 @@
*/
package org.neo4j.graphdb.schema;

import java.util.Optional;

import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.index.IndexManager;
Expand Down Expand Up @@ -133,4 +135,10 @@ public interface IndexDefinition
* @return {@code true} if this is a composite index.
*/
boolean isCompositeIndex();

/**
* Get the name given to this index when it was created, if any.
* If the index was not given any name, then the string {@code "Unnamed index"} is returned instead.
*/
String getName();
}
Expand Up @@ -162,4 +162,12 @@ enum IndexState
* FAILED state
*/
void awaitIndexesOnline( long duration, TimeUnit unit );

/**
* Get an {@link IndexDefinition} by the given name of the index.
* @param indexName The given name of the index.
* @return The index with that given name.
* @throws IllegalArgumentException if there is no index with that given name.
*/
IndexDefinition getIndexByName( String indexName );
}
Expand Up @@ -40,6 +40,15 @@ public interface SchemaWrite
*/
IndexReference indexCreate( SchemaDescriptor descriptor ) throws SchemaKernelException;

/**
* Create index from schema descriptor
*
* @param descriptor description of the index
* @param name name of the index
* @return the newly created index
*/
IndexReference indexCreate( SchemaDescriptor descriptor, Optional<String> name ) throws SchemaKernelException;

/**
* Create index from schema descriptor
*
Expand Down
Expand Up @@ -107,7 +107,7 @@ public String providerVersion()
@Override
public String name()
{
return userSuppliedName.orElse( "Unnamed index" );
return userSuppliedName.orElse( UNNAMED_INDEX );
}

public IndexProviderDescriptor providerDescriptor()
Expand Down
Expand Up @@ -38,18 +38,15 @@
import org.neo4j.kernel.api.KernelTransactionHandle;
import org.neo4j.kernel.api.exceptions.Status;
import org.neo4j.kernel.api.explicitindex.AutoIndexing;
import org.neo4j.kernel.api.txstate.ExplicitIndexTransactionState;
import org.neo4j.kernel.api.txstate.aux.AuxiliaryTransactionStateManager;
import org.neo4j.kernel.availability.AvailabilityGuard;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.api.index.IndexingProvidersService;
import org.neo4j.kernel.impl.api.state.ConstraintIndexCreator;
import org.neo4j.kernel.impl.api.state.ExplicitIndexTransactionStateImpl;
import org.neo4j.kernel.impl.constraints.ConstraintSemantics;
import org.neo4j.kernel.impl.core.TokenHolders;
import org.neo4j.kernel.impl.factory.AccessCapability;
import org.neo4j.kernel.impl.index.ExplicitIndexStore;
import org.neo4j.kernel.impl.index.IndexConfigStore;
import org.neo4j.kernel.impl.locking.StatementLocks;
import org.neo4j.kernel.impl.locking.StatementLocksFactory;
import org.neo4j.kernel.impl.proc.Procedures;
Expand Down
Expand Up @@ -21,6 +21,7 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;

import org.neo4j.graphdb.ConstraintViolationException;
import org.neo4j.graphdb.Label;
Expand All @@ -32,16 +33,18 @@ public class IndexCreatorImpl implements IndexCreator
private final Collection<String> propertyKeys;
private final Label label;
private final InternalSchemaActions actions;
private final Optional<String> indexName;

public IndexCreatorImpl( InternalSchemaActions actions, Label label )
{
this( actions, label, new ArrayList<>() );
this( actions, label, Optional.empty(), new ArrayList<>() );
}

private IndexCreatorImpl( InternalSchemaActions actions, Label label, Collection<String> propertyKeys )
private IndexCreatorImpl( InternalSchemaActions actions, Label label, Optional<String> indexName, Collection<String> propertyKeys )
{
this.actions = actions;
this.label = label;
this.indexName = indexName;
this.propertyKeys = propertyKeys;

assertInUnterminatedTransaction();
Expand All @@ -51,7 +54,14 @@ private IndexCreatorImpl( InternalSchemaActions actions, Label label, Collection
public IndexCreator on( String propertyKey )
{
assertInUnterminatedTransaction();
return new IndexCreatorImpl( actions, label, copyAndAdd( propertyKeys, propertyKey) );
return new IndexCreatorImpl( actions, label, indexName, copyAndAdd( propertyKeys, propertyKey) );
}

@Override
public IndexCreator withName( String indexName )
{
assertInUnterminatedTransaction();
return new IndexCreatorImpl( actions, label, Optional.ofNullable( indexName ), propertyKeys );
}

@Override
Expand All @@ -64,7 +74,7 @@ public IndexDefinition create() throws ConstraintViolationException
throw new ConstraintViolationException( "An index needs at least one property key to index" );
}

return actions.createIndexDefinition( label, propertyKeys.toArray( new String[0] ) );
return actions.createIndexDefinition( label, indexName, propertyKeys.toArray( new String[0] ) );
}

private void assertInUnterminatedTransaction()
Expand Down
Expand Up @@ -27,9 +27,14 @@
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.hashing.HashFunction;
import org.neo4j.internal.kernel.api.IndexReference;
import org.neo4j.internal.kernel.api.TokenRead;
import org.neo4j.internal.kernel.api.exceptions.KernelException;
import org.neo4j.internal.kernel.api.schema.SchemaDescriptor;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.joining;
import static org.neo4j.graphdb.Label.label;
import static org.neo4j.graphdb.RelationshipType.withName;
import static org.neo4j.helpers.collection.Iterables.stream;

public class IndexDefinitionImpl implements IndexDefinition
Expand Down Expand Up @@ -213,6 +218,12 @@ public boolean isCompositeIndex()
return propertyKeys.length > 1;
}

@Override
public String getName()
{
return indexReference == null ? IndexReference.UNNAMED_INDEX : indexReference.name();
}

@Override
public int hashCode()
{
Expand Down
Expand Up @@ -19,6 +19,8 @@
*/
package org.neo4j.kernel.impl.coreapi.schema;

import java.util.Optional;

import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.schema.ConstraintDefinition;
Expand All @@ -31,7 +33,7 @@
*/
public interface InternalSchemaActions
{
IndexDefinition createIndexDefinition( Label label, String... propertyKey );
IndexDefinition createIndexDefinition( Label label, Optional<String> indexName, String... propertyKey );

void dropIndexDefinitions( IndexDefinition indexDefinition );

Expand Down
Expand Up @@ -24,6 +24,8 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Supplier;
Expand Down Expand Up @@ -241,6 +243,32 @@ public void awaitIndexesOnline( long duration, TimeUnit unit )
}
}

@Override
public IndexDefinition getIndexByName( String indexName )
{
Objects.requireNonNull( indexName );
Iterator<IndexDefinition> indexes = getIndexes().iterator();
IndexDefinition index = null;
while ( indexes.hasNext() )
{
IndexDefinition candidate = indexes.next();
if ( candidate.getName().equals( indexName ) )
{
if ( index != null )
{
throw new IllegalStateException( "Multiple indexes found by the name '" + indexName + "'. " +
"Try iterating Schema#getIndexes() and filter by name instead." );
}
index = candidate;
}
}
if ( index == null )
{
throw new IllegalArgumentException( "No index found with the name '" + indexName + "'." );
}
return index;
}

@Override
public IndexState getIndexState( final IndexDefinition index )
{
Expand Down Expand Up @@ -514,21 +542,20 @@ private static class GDBSchemaActions implements InternalSchemaActions
}

@Override
public IndexDefinition createIndexDefinition( Label label, String... propertyKeys )
public IndexDefinition createIndexDefinition( Label label, Optional<String> indexName, String... propertyKeys )
{
KernelTransaction transaction = safeAcquireTransaction( transactionSupplier );

try ( Statement ignore = transaction.acquireStatement() )
{
try
{
IndexDefinition indexDefinition = new IndexDefinitionImpl( this, null, new Label[]{label}, propertyKeys, false );
TokenWrite tokenWrite = transaction.tokenWrite();
int labelId = tokenWrite.labelGetOrCreateForName( label.name() );
int[] propertyKeyIds = getOrCreatePropertyKeyIds( tokenWrite, indexDefinition );
int[] propertyKeyIds = getOrCreatePropertyKeyIds( tokenWrite, propertyKeys );
LabelSchemaDescriptor descriptor = forLabel( labelId, propertyKeyIds );
transaction.schemaWrite().indexCreate( descriptor );
return indexDefinition;
IndexReference indexReference = transaction.schemaWrite().indexCreate( descriptor, indexName );
return new IndexDefinitionImpl( this, indexReference, new Label[]{label}, propertyKeys, false );
}

catch ( IllegalTokenNameException e )
Expand Down
Expand Up @@ -919,6 +919,12 @@ public IndexReference indexCreate( SchemaDescriptor descriptor ) throws SchemaKe
return indexCreate( descriptor, config.get( GraphDatabaseSettings.default_schema_provider ), Optional.empty() );
}

@Override
public IndexReference indexCreate( SchemaDescriptor descriptor, Optional<String> indexName ) throws SchemaKernelException
{
return indexCreate( descriptor, config.get( GraphDatabaseSettings.default_schema_provider ), indexName );
}

@Override
public IndexReference indexCreate( SchemaDescriptor descriptor,
String provider,
Expand Down

0 comments on commit 43a271b

Please sign in to comment.