Skip to content

Commit

Permalink
Procedure db.indexes list index provider
Browse files Browse the repository at this point in the history
And also list label and property as separate fields
  • Loading branch information
burqen committed Nov 2, 2017
1 parent 573a820 commit c67d012
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 15 deletions.
Expand Up @@ -40,6 +40,7 @@
import org.neo4j.kernel.api.exceptions.schema.IndexBrokenKernelException;
import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException;
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.proc.ProcedureSignature;
import org.neo4j.kernel.api.proc.QualifiedName;
import org.neo4j.kernel.api.proc.UserFunctionSignature;
Expand Down Expand Up @@ -237,6 +238,9 @@ IndexDescriptor indexGetForSchema( LabelSchemaDescriptor descriptor )
/** Retrieve the state of an index. */
InternalIndexState indexGetState( IndexDescriptor descriptor ) throws IndexNotFoundKernelException;

/** Retrieve provider descriptor for an index. */
SchemaIndexProvider.Descriptor indexGetProviderDescriptor( IndexDescriptor descriptor ) throws IndexNotFoundKernelException;

/** Retrieve the population progress of an index. */
PopulationProgress indexGetPopulationProgress( IndexDescriptor descriptor ) throws IndexNotFoundKernelException;

Expand Down
Expand Up @@ -40,6 +40,7 @@
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.graphdb.index.RelationshipIndex;
import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.kernel.api.ExplicitIndexHits;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.ReadOperations;
Expand All @@ -50,6 +51,7 @@
import org.neo4j.kernel.api.exceptions.Status;
import org.neo4j.kernel.api.exceptions.explicitindex.ExplicitIndexNotFoundKernelException;
import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.schema.index.IndexDescriptor;
import org.neo4j.kernel.impl.api.TokenAccess;
import org.neo4j.kernel.impl.api.index.IndexingService;
Expand Down Expand Up @@ -162,8 +164,11 @@ public Stream<IndexResult> listIndexes() throws ProcedureException
type = IndexType.NODE_LABEL_PROPERTY.typeName();
}

result.add( new IndexResult( "INDEX ON " + index.schema().userDescription( tokens ),
operations.indexGetState( index ).toString(), type ) );
String label = tokens.labelGetName( index.schema().getLabelId() );
List<String> propertyNames = propertyNames( tokens, index );
result.add( new IndexResult( "INDEX ON " + index.schema().userDescription( tokens ), label, propertyNames,
operations.indexGetState( index ).toString(), type,
indexProviderDescriptorMap( operations.indexGetProviderDescriptor( index ) ) ) );
}
catch ( IndexNotFoundKernelException e )
{
Expand Down Expand Up @@ -586,6 +591,24 @@ public Stream<BooleanResult> relationshipManualIndexRemove( @Name( "indexName" )
return Stream.of( new BooleanResult( true ) );
}

private Map<String,String> indexProviderDescriptorMap( SchemaIndexProvider.Descriptor providerDescriptor )
{
return MapUtil.stringMap(
"key", providerDescriptor.getKey(),
"version", providerDescriptor.getVersion() );
}

private List<String> propertyNames( TokenNameLookup tokens, IndexDescriptor index )
{
int[] propertyIds = index.schema().getPropertyIds();
List<String> propertyNames = new ArrayList<>();
for ( int i = 0; i < propertyIds.length; i++ )
{
propertyNames.add( tokens.propertyKeyGetName( propertyIds[i] ) );
}
return propertyNames;
}

private <T> Stream<T> toStream( PrimitiveLongResourceIterator iterator, Function<Long,T> mapper )
{
Iterator<T> it = new Iterator<T>()
Expand Down Expand Up @@ -699,14 +722,20 @@ public BooleanResult( Boolean success )
public class IndexResult
{
public final String description;
public final String label;
public final List<String> properties;
public final String state;
public final String type;
public final Map<String,String> provider;

private IndexResult( String description, String state, String type )
private IndexResult( String description, String label, List<String> properties, String state, String type, Map<String,String> provider )
{
this.description = description;
this.label = label;
this.properties = properties;
this.state = state;
this.type = type;
this.provider = provider;
}
}

Expand Down
Expand Up @@ -40,6 +40,7 @@
import org.neo4j.kernel.api.exceptions.schema.RepeatedPropertyInCompositeSchemaException;
import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException;
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.schema.LabelSchemaDescriptor;
import org.neo4j.kernel.api.schema.RelationTypeSchemaDescriptor;
import org.neo4j.kernel.api.schema.SchemaDescriptor;
Expand Down Expand Up @@ -192,6 +193,14 @@ public InternalIndexState indexGetState( KernelStatement state, IndexDescriptor
return schemaReadDelegate.indexGetState( state, descriptor );
}

@Override
public SchemaIndexProvider.Descriptor indexGetProviderDescriptor( KernelStatement state, IndexDescriptor descriptor ) throws IndexNotFoundKernelException
{
sharedLabelLock( state, descriptor.schema().getLabelId() );
state.assertOpen();
return schemaReadDelegate.indexGetProviderDescriptor( state, descriptor );
}

@Override
public PopulationProgress indexGetPopulationProgress( KernelStatement state, IndexDescriptor descriptor )
throws IndexNotFoundKernelException
Expand Down
Expand Up @@ -66,6 +66,7 @@
import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException;
import org.neo4j.kernel.api.exceptions.schema.TooManyLabelsException;
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.proc.BasicContext;
import org.neo4j.kernel.api.proc.CallableUserAggregationFunction;
import org.neo4j.kernel.api.proc.Context;
Expand Down Expand Up @@ -591,6 +592,13 @@ public InternalIndexState indexGetState( IndexDescriptor descriptor ) throws Ind
return schemaRead().indexGetState( statement, descriptor );
}

@Override
public SchemaIndexProvider.Descriptor indexGetProviderDescriptor( IndexDescriptor descriptor ) throws IndexNotFoundKernelException
{
statement.assertOpen();
return schemaRead().indexGetProviderDescriptor( statement, descriptor );
}

@Override
public PopulationProgress indexGetPopulationProgress( IndexDescriptor descriptor ) throws IndexNotFoundKernelException
{
Expand Down
Expand Up @@ -57,6 +57,7 @@
import org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException;
import org.neo4j.kernel.api.explicitindex.AutoIndexing;
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.properties.PropertyKeyIdIterator;
import org.neo4j.kernel.api.schema.IndexQuery;
import org.neo4j.kernel.api.schema.LabelSchemaDescriptor;
Expand Down Expand Up @@ -755,6 +756,20 @@ public InternalIndexState indexGetState( KernelStatement state, IndexDescriptor
return storeLayer.indexGetState( descriptor );
}

@Override
public SchemaIndexProvider.Descriptor indexGetProviderDescriptor( KernelStatement state, IndexDescriptor descriptor ) throws IndexNotFoundKernelException
{
if ( state.hasTxStateWithChanges() )
{
if ( checkIndexState( descriptor,
state.txState().indexDiffSetsByLabel( descriptor.schema().getLabelId() ) ) )
{
// todo if index is in our state
}
}
return storeLayer.indexGetProviderDescriptor( descriptor );
}

@Override
public PopulationProgress indexGetPopulationProgress( KernelStatement state, IndexDescriptor descriptor ) throws
IndexNotFoundKernelException
Expand Down
Expand Up @@ -25,6 +25,7 @@
import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException;
import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException;
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.schema.LabelSchemaDescriptor;
import org.neo4j.kernel.api.schema.SchemaDescriptor;
import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptor;
Expand Down Expand Up @@ -54,6 +55,11 @@ public interface SchemaReadOperations
*/
InternalIndexState indexGetState( KernelStatement state, IndexDescriptor descriptor ) throws IndexNotFoundKernelException;

/**
* Retrieve the index provider descriptor for an index.
*/
SchemaIndexProvider.Descriptor indexGetProviderDescriptor( KernelStatement state, IndexDescriptor descriptor ) throws IndexNotFoundKernelException;

/**
* Retrieve the population progress of an index.
*/
Expand Down
Expand Up @@ -40,6 +40,7 @@
import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException;
import org.neo4j.kernel.api.exceptions.schema.TooManyLabelsException;
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.properties.PropertyKeyIdIterator;
import org.neo4j.kernel.api.schema.LabelSchemaDescriptor;
import org.neo4j.kernel.api.schema.SchemaDescriptor;
Expand Down Expand Up @@ -233,6 +234,12 @@ public InternalIndexState indexGetState( IndexDescriptor descriptor ) throws Ind
return indexService.getIndexProxy( descriptor.schema() ).getState();
}

@Override
public SchemaIndexProvider.Descriptor indexGetProviderDescriptor( IndexDescriptor descriptor ) throws IndexNotFoundKernelException
{
return indexService.getIndexProxy( descriptor.schema() ).getProviderDescriptor();
}

@Override
public PopulationProgress indexGetPopulationProgress( LabelSchemaDescriptor descriptor )
throws IndexNotFoundKernelException
Expand Down
Expand Up @@ -36,6 +36,7 @@
import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException;
import org.neo4j.kernel.api.exceptions.schema.TooManyLabelsException;
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.schema.LabelSchemaDescriptor;
import org.neo4j.kernel.api.schema.SchemaDescriptor;
import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptor;
Expand Down Expand Up @@ -147,6 +148,15 @@ long indexGetCommittedId( IndexDescriptor index )
*/
InternalIndexState indexGetState( IndexDescriptor descriptor ) throws IndexNotFoundKernelException;

/**
* Return index provider descriptor of a stored index.
*
* @param descriptor {@link LabelSchemaDescriptor} to get provider descriptor for.
* @return {@link SchemaIndexProvider.Descriptor} for index.
* @throws IndexNotFoundKernelException if index not found.
*/
SchemaIndexProvider.Descriptor indexGetProviderDescriptor( IndexDescriptor descriptor ) throws IndexNotFoundKernelException;

/**
* @param descriptor {@link LabelSchemaDescriptor} to get population progress for.
* @return progress of index population, which is the initial state of an index when it's created.
Expand Down
Expand Up @@ -36,11 +36,13 @@
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.Relationship;
import org.neo4j.helpers.collection.Iterators;
import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.exceptions.ProcedureException;
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.api.proc.BasicContext;
import org.neo4j.kernel.api.proc.Key;
import org.neo4j.kernel.api.proc.ProcedureSignature;
Expand All @@ -49,6 +51,7 @@
import org.neo4j.kernel.api.schema.index.IndexDescriptor;
import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory;
import org.neo4j.kernel.api.security.SecurityContext;
import org.neo4j.kernel.impl.api.index.inmemory.InMemoryIndexProviderFactory;
import org.neo4j.kernel.impl.factory.Edition;
import org.neo4j.kernel.impl.proc.Procedures;
import org.neo4j.kernel.impl.proc.TypeMappers;
Expand Down Expand Up @@ -99,7 +102,13 @@ public void shouldListAllIndexes() throws Throwable

// When/Then
assertThat( call( "db.indexes" ),
contains( record( "INDEX ON :User(name)", "ONLINE", "node_label_property" ) ) );
contains( record( "INDEX ON :User(name)", "User", singletonList( "name" ), "ONLINE", "node_label_property",
getIndexProviderDescriptorMap( InMemoryIndexProviderFactory.PROVIDER_DESCRIPTOR ) ) ) );
}

private Map<String,String> getIndexProviderDescriptorMap( SchemaIndexProvider.Descriptor providerDescriptor )
{
return MapUtil.stringMap( "key", providerDescriptor.getKey(), "version", providerDescriptor.getVersion() );
}

@Test
Expand All @@ -110,7 +119,8 @@ public void shouldListAllUniqueIndexes() throws Throwable

// When/Then
assertThat( call( "db.indexes" ),
contains( record( "INDEX ON :User(name)", "ONLINE", "node_unique_property" ) ) );
contains( record( "INDEX ON :User(name)", "User", singletonList( "name" ), "ONLINE", "node_unique_property",
getIndexProviderDescriptorMap( InMemoryIndexProviderFactory.PROVIDER_DESCRIPTOR ) ) ) );
}

@Test
Expand Down Expand Up @@ -197,7 +207,8 @@ public void shouldListCorrectBuiltinProcedures() throws Throwable
"Wait for all indexes to come online (for example: CALL db.awaitIndexes(\"500\"))." ),
record( "db.constraints", "db.constraints() :: (description :: STRING?)",
"List all constraints in the database." ),
record( "db.indexes", "db.indexes() :: (description :: STRING?, state :: STRING?, type :: STRING?)",
record( "db.indexes", "db.indexes() :: (description :: STRING?, label :: STRING?, properties :: LIST? OF STRING?, " +
"state :: STRING?, type :: STRING?, provider :: MAP?)",
"List all indexes in the database." ),
record( "db.labels", "db.labels() :: (label :: STRING?)", "List all labels in the database." ),
record( "db.propertyKeys", "db.propertyKeys() :: (propertyKey :: STRING?)",
Expand Down Expand Up @@ -492,6 +503,8 @@ public void setup() throws Exception
when( read.countsForNode( anyInt() ) ).thenReturn( 1L );
when( read.countsForRelationship( anyInt(), anyInt(), anyInt() ) ).thenReturn( 1L );
when( read.indexGetState( any( IndexDescriptor.class ) ) ).thenReturn( InternalIndexState.ONLINE );
when( read.indexGetProviderDescriptor( any( IndexDescriptor.class ) ) )
.thenReturn( InMemoryIndexProviderFactory.PROVIDER_DESCRIPTOR );
}

private Answer<Iterator<Token>> asTokens( Map<Integer,String> tokens )
Expand Down
Expand Up @@ -31,9 +31,10 @@
public class InMemoryIndexProviderFactory extends KernelExtensionFactory<InMemoryIndexProviderFactory.Dependencies>
{
public static final String KEY = "in-memory-index";
public static final String VERSION = "1.0";

public static final SchemaIndexProvider.Descriptor PROVIDER_DESCRIPTOR =
new SchemaIndexProvider.Descriptor( KEY, "1.0" );
new SchemaIndexProvider.Descriptor( KEY, VERSION );

private final SchemaIndexProvider singleProvider;

Expand Down
Expand Up @@ -23,17 +23,20 @@
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.neo4j.collection.RawIterator;
import org.neo4j.graphdb.Transaction;
import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.TokenWriteOperations;
import org.neo4j.kernel.api.exceptions.ProcedureException;
import org.neo4j.kernel.api.schema.SchemaDescriptorFactory;
import org.neo4j.kernel.api.security.AnonymousContext;
import org.neo4j.kernel.api.security.SecurityContext;
import org.neo4j.kernel.impl.api.index.inmemory.InMemoryIndexProviderFactory;
import org.neo4j.kernel.internal.Version;

import static java.util.Collections.singletonList;
Expand Down Expand Up @@ -121,7 +124,8 @@ public void listProcedures() throws Throwable
equalTo( new Object[]{"db.constraints", "db.constraints() :: (description :: STRING?)",
"List all constraints in the database."} ),
equalTo( new Object[]{"db.indexes",
"db.indexes() :: (description :: STRING?, state :: STRING?, type :: STRING?)",
"db.indexes() :: (description :: STRING?, label :: STRING?, properties :: LIST? OF STRING?, state :: STRING?, " +
"type :: STRING?, provider :: MAP?)",
"List all indexes in the database."} ),
equalTo( new Object[]{"db.awaitIndex",
"db.awaitIndex(index :: STRING?, timeOutSeconds = 300 :: INTEGER?) :: VOID",
Expand Down Expand Up @@ -291,10 +295,12 @@ public void listAllIndexes() throws Throwable
Statement statement = statementInNewTransaction( SecurityContext.AUTH_DISABLED );
int labelId1 = statement.tokenWriteOperations().labelGetOrCreateForName( "Person" );
int labelId2 = statement.tokenWriteOperations().labelGetOrCreateForName( "Age" );
int propertyKeyId = statement.tokenWriteOperations().propertyKeyGetOrCreateForName( "foo" );
int propertyKeyId1 = statement.tokenWriteOperations().propertyKeyGetOrCreateForName( "foo" );
int propertyKeyId2 = statement.tokenWriteOperations().propertyKeyGetOrCreateForName( "bar" );
//TODO: Add test support for composite indexes
statement.schemaWriteOperations().indexCreate( SchemaDescriptorFactory.forLabel( labelId1, propertyKeyId ) );
statement.schemaWriteOperations().uniquePropertyConstraintCreate( forLabel( labelId2, propertyKeyId ) );
statement.schemaWriteOperations().indexCreate( forLabel( labelId1, propertyKeyId1 ) );
statement.schemaWriteOperations().uniquePropertyConstraintCreate( forLabel( labelId2, propertyKeyId1 ) );
statement.schemaWriteOperations().indexCreate( forLabel( labelId1, propertyKeyId1, propertyKeyId2 ) );
commit();

//let indexes come online
Expand All @@ -315,9 +321,13 @@ public void listAllIndexes() throws Throwable
}

// Then
Map<String,String> providerDescriptionMap = MapUtil.stringMap(
"key", InMemoryIndexProviderFactory.KEY,
"version", InMemoryIndexProviderFactory.VERSION );
assertThat( result, containsInAnyOrder(
new Object[]{"INDEX ON :Age(foo)", "ONLINE", "node_unique_property"},
new Object[]{"INDEX ON :Person(foo)", "ONLINE", "node_label_property"}
new Object[]{"INDEX ON :Age(foo)", "Age", singletonList("foo" ), "ONLINE", "node_unique_property", providerDescriptionMap},
new Object[]{"INDEX ON :Person(foo)", "Person", singletonList( "foo" ), "ONLINE", "node_label_property", providerDescriptionMap},
new Object[]{"INDEX ON :Person(foo, bar)", "Person", Arrays.asList( "foo", "bar" ), "ONLINE", "node_label_property", providerDescriptionMap}
) );
commit();
}
Expand Down

0 comments on commit c67d012

Please sign in to comment.