@Admin @Description( "List the currently active config of Neo4j." ) @Procedure( name = "dbms.listConfig", mode = DBMS ) public Stream<ConfigResult> listConfig( @Name( value = "searchString", defaultValue = "" ) String searchString ) { Config config = graph.getDependencyResolver().resolveDependency( Config.class ); String lowerCasedSearchString = searchString.toLowerCase(); return config.getConfigValues().values().stream() .filter( c -> !c.internal() ) .filter( c -> c.name().toLowerCase().contains( lowerCasedSearchString ) ) .map( ConfigResult::new ) .sorted( Comparator.comparing( c -> c.name ) ); }
@Override public Stream<CompilationMessage> visitExecutable( ExecutableElement method, Void ignored ) { Procedure procedure = method.getAnnotation( Procedure.class ); if ( procedure == null ) { return Stream.of( new PerformsWriteMisuseError( method, "@%s usage error: missing @%s annotation on method", PerformsWrites.class.getSimpleName(), Procedure.class.getSimpleName() ) ); } if ( procedure.mode() != Mode.DEFAULT ) { return Stream.of( new PerformsWriteMisuseError( method, "@%s usage error: cannot use mode other than Mode.DEFAULT", PerformsWrites.class.getSimpleName() ) ); } return Stream.empty(); }
@Procedure @Description("apoc.warmup.run(loadProperties=false,loadDynamicProperties=false,loadIndexes=false) - quickly loads all nodes and rels into memory by skipping one page at a time") public Stream<WarmupResult> run(@Name(value = "loadProperties", defaultValue = "false") boolean loadProperties, @Name(value = "loadDynamicProperties", defaultValue = "false") boolean loadDynamicProperties, @Name(value = "loadIndexes", defaultValue = "false") boolean loadIndexes) throws IOException { PageCache pageCache = db.getDependencyResolver().resolveDependency(PageCache.class); .filter(pF -> { String name = pF.file().getName(); if (isSchema(pF.file()) && !loadIndexes) return false; return true; }) .map((pagedFile -> { File file = pagedFile.file(); boolean index = isSchema(file); pageCache.reportEvents(); })).collect(Collectors.toMap(r -> r.file, r -> r));
.filter( m -> m.isAnnotationPresent( Procedure.class ) ) .collect( Collectors.toList() ); for ( Method method : procedureMethods ) String valueName = method.getAnnotation( Procedure.class ).value(); String definedName = method.getAnnotation( Procedure.class ).name(); QualifiedName procName = extractName( procDefinition, method, valueName, definedName );
@Description( "Query the given fulltext index. Returns the matching nodes and their lucene query score, ordered by score." ) @Procedure( name = "db.index.fulltext.queryNodes", mode = READ ) public Stream<NodeOutput> queryFulltextForNodes( @Name( "indexName" ) String name, @Name( "queryString" ) String query ) throws ParseException, IndexNotFoundKernelException, IOException { IndexReference indexReference = getValidIndexReference( name ); awaitOnline( indexReference ); EntityType entityType = indexReference.schema().entityType(); if ( entityType != EntityType.NODE ) { throw new IllegalArgumentException( "The '" + name + "' index (" + indexReference + ") is an index on " + entityType + ", so it cannot be queried for nodes." ); } ScoreEntityIterator resultIterator = accessor.query( tx, name, query ); return resultIterator.stream() .map( result -> NodeOutput.forExistingEntityOrNull( db, result ) ) .filter( Objects::nonNull ); }
@Procedure("apoc.schema.properties.distinctCount") @Description("apoc.schema.properties.distinctCount([label], [key]) YIELD label, key, value, count - quickly returns all distinct values and counts for a given key") public Stream<PropertyValueCount> distinctCount(@Name(value = "label", defaultValue = "") String labelName, @Name(value = "key", defaultValue = "") String keyName) throws SchemaRuleNotFoundException, IndexNotFoundKernelException, IOException { Iterable<IndexDefinition> labels = (labelName.isEmpty()) ? db.schema().getIndexes() : db.schema().getIndexes(Label.label(labelName)); return StreamSupport.stream(labels.spliterator(), false).filter(i -> keyName.isEmpty() || isKeyIndexed(i, keyName)).flatMap( index -> { Iterable<String> keys = keyName.isEmpty() ? index.getPropertyKeys() : Collections.singletonList(keyName); return StreamSupport.stream(keys.spliterator(), false).flatMap(key -> { String label = index.getLabel().name(); return distinctTermsCount(label, key). entrySet().stream().map(e -> new PropertyValueCount(label, key, e.getKey(), e.getValue())); }); } ); }
@Description( "List the available analyzers that the fulltext indexes can be configured with." ) @Procedure( name = "db.index.fulltext.listAvailableAnalyzers", mode = READ ) public Stream<AvailableAnalyzer> listAvailableAnalyzers() { Stream<AnalyzerProvider> stream = accessor.listAvailableAnalyzers(); return stream.flatMap( provider -> { String description = provider.description(); Spliterator<String> spliterator = provider.getKeys().spliterator(); return StreamSupport.stream( spliterator, false ).map( name -> new AvailableAnalyzer( name, description ) ); } ); }
@Description( "List all procedures in the DBMS." ) @Procedure( name = "dbms.procedures", mode = DBMS ) public Stream<ProcedureResult> listProcedures() { securityContext.assertCredentialsNotExpired(); return graph.getDependencyResolver().resolveDependency( Procedures.class ).getAllProcedures().stream() .sorted( Comparator.comparing( a -> a.name().toString() ) ) .map( ProcedureResult::new ); }
@Description( "List all constraints in the database." ) @Procedure( name = "db.constraints", mode = READ ) public Stream<ConstraintResult> listConstraints() { SchemaRead schemaRead = tx.schemaRead(); TokenNameLookup tokens = new SilentTokenNameLookup( tx.tokenRead() ); return asList( schemaRead.constraintsGetAll() ) .stream() .map( constraint -> constraint.prettyPrint( tokens ) ) .sorted() .map( ConstraintResult::new ); }
@Description( "List all native users." ) @Procedure( name = "dbms.security.listUsers", mode = DBMS ) public Stream<UserResult> listUsers() { securityContext.assertCredentialsNotExpired(); Set<String> usernames = userManager.getAllUsernames(); if ( usernames.isEmpty() ) { return showCurrentUser(); } else { return usernames.stream().map( this::userResultForName ); } }
@Description( "Provides attached transaction metadata." ) @Procedure( name = "dbms.getTXMetaData", mode = DBMS ) public Stream<MetadataResult> getTXMetaData() { securityContext.assertCredentialsNotExpired(); try ( Statement statement = getCurrentTx().acquireStatement() ) { return Stream.of( statement.queryRegistration().getMetaData() ).map( MetadataResult::new ); } }
@Deprecated @Description( "Check if a relationship explicit index exists" ) @Procedure( name = "db.index.explicit.existsForRelationships", mode = READ, deprecatedBy = EXPLICIT_INDEX_DEPRECATION ) public Stream<BooleanResult> relationshipManualIndexExists( @Name( "indexName" ) String explicitIndexName ) { return Stream.of( new BooleanResult( graphDatabaseAPI.index().existsForRelationships( explicitIndexName ) ) ); }
@Admin @Description( "Retrieve all available statistical data about the current database, in an anonymized form." ) @Procedure( name = "db.stats.retrieveAllAnonymized", mode = Mode.READ ) public Stream<RetrieveResult> retrieveAllAnonymized( @Name( value = "graphToken" ) String graphToken, @Name( value = "config", defaultValue = "" ) Map<String, Object> config ) throws IndexNotFoundKernelException, TransactionFailureException, InvalidArgumentsException { Map<String, Object> metaData = new HashMap<>(); metaData.put( "graphToken", graphToken ); metaData.put( "retrieveTime", ZonedDateTime.now() ); TokensSection.putTokenCounts( metaData, dataCollector.kernel ); Stream<RetrieveResult> meta = Stream.of( new RetrieveResult( "META", metaData ) ); return Stream.of( meta, GraphCountsSection.retrieve( dataCollector.kernel, Anonymizer.IDS ), QueriesSection.retrieve( dataCollector.queryCollector.doGetData(), new IdAnonymizer( transaction.tokenRead() ), RetrieveConfig.of( config ).maxInvocations ) ).flatMap( x -> x ); }
@Description( "Visualize the schema of the data. Replaces db.schema." ) @Procedure( name = "db.schema.visualization", mode = READ ) public Stream<SchemaProcedure.GraphResult> schemaVisualization() { return Stream.of( new SchemaProcedure( graphDatabaseAPI, tx ).buildSchemaGraph() ); }
@Admin @Description( "Clears all query caches." ) @Procedure( name = "dbms.clearQueryCaches", mode = DBMS ) public Stream<StringResult> clearAllQueryCaches() { QueryExecutionEngine queryExecutionEngine = graph.getDependencyResolver().resolveDependency( QueryExecutionEngine.class ); long numberOfClearedQueries = queryExecutionEngine.clearQueryCaches() - 1; // this query itself does not count String result = numberOfClearedQueries == 0 ? "Query cache already empty." : "Query caches successfully cleared of " + numberOfClearedQueries + " queries."; log.info( "Called dbms.clearQueryCaches(): " + result ); return Stream.of( new StringResult( result ) ); }
@Deprecated @Description( "Search nodes in explicit automatic index. Replaces `START n=node:node_auto_index('key:foo*')`" ) @Procedure( name = "db.index.explicit.auto.searchNodes", mode = READ, deprecatedBy = EXPLICIT_INDEX_DEPRECATION ) public Stream<WeightedNodeResult> nodeAutoIndexSearch( @Name( "query" ) Object query ) { try ( Statement ignore = tx.acquireStatement() ) { NodeExplicitIndexCursor cursor = tx.cursors().allocateNodeExplicitIndexCursor(); tx.indexRead().nodeExplicitIndexQuery( cursor, "node_auto_index", query ); return toWeightedNodeResultStream( cursor ); } catch ( KernelException e ) { // auto index will not exist if no nodes have been added that match the auto-index rules return Stream.empty(); } }
@Description( "Attaches a map of data to the transaction. The data will be printed when listing queries, and " + "inserted into the query log." ) @Procedure( name = "dbms.setTXMetaData", mode = DBMS ) public void setTXMetaData( @Name( value = "data" ) Map<String,Object> data ) { securityContext.assertCredentialsNotExpired(); int totalCharSize = data.entrySet().stream() .mapToInt( e -> e.getKey().length() + e.getValue().toString().length() ) .sum(); if ( totalCharSize >= HARD_CHAR_LIMIT ) { throw new IllegalArgumentException( format( "Invalid transaction meta-data, expected the total number of chars for " + "keys and values to be less than %d, got %d", HARD_CHAR_LIMIT, totalCharSize ) ); } try ( Statement statement = getCurrentTx().acquireStatement() ) { statement.queryRegistration().setMetaData( data ); } }
@Deprecated @Description( "Change the current user's password. Deprecated by dbms.security.changePassword." ) @Procedure( name = "dbms.changePassword", mode = DBMS, deprecatedBy = "dbms.security.changePassword" ) public void changePasswordDeprecated( @Name( "password" ) String password ) throws InvalidArgumentsException, IOException { // TODO: Deprecate this and create a new procedure that takes password as a byte[] changePassword( password ); }