@Procedure() @Description("apoc.bolt.load(url-or-key, kernelTransaction, params, config) - access to other databases via bolt for read") public Stream<RowResult> load(@Name("url") String url, @Name("kernelTransaction") String statement, @Name(value = "params", defaultValue = "{}") Map<String, Object> params, @Name(value = "config", defaultValue = "{}") Map<String, Object> config) throws URISyntaxException { if (params == null) params = Collections.emptyMap(); if (config == null) config = Collections.emptyMap(); boolean virtual = (boolean) config.getOrDefault("virtual", false); boolean addStatistics = (boolean) config.getOrDefault("statistics", false); boolean readOnly = (boolean) config.getOrDefault("readOnly", true); Config driverConfig = toDriverConfig(config.getOrDefault("driverConfig", map())); UriResolver uri = new UriResolver(url, "bolt"); uri.initialize(); try (Driver driver = GraphDatabase.driver(uri.getConfiguredUri(), uri.getToken(), driverConfig); Session session = driver.session()) { if (addStatistics) return Stream.of(new RowResult(toMap(runStatement(statement, session, params, readOnly).summary().counters()))); else return getRowResultStream(virtual, session, params, statement, readOnly); } catch (Exception e) { throw new RuntimeException("It's not possible to create a connection due to: " + e.getMessage()); } }
@Nonnull static Map<String, Value> info(@Nonnull ResultSummary summary) { Map<String, Value> result = new LinkedHashMap<>(); if (!summary.hasPlan()) return result; Plan plan = summary.plan(); result.put("Plan", Values.value(summary.hasProfile() ? "PROFILE" : "EXPLAIN")); result.put("Statement", Values.value(summary.statementType().name())); Map<String, Value> arguments = plan.arguments(); Value defaultValue = Values.value(""); for (String key : INFO) { Value value = arguments.getOrDefault(key, arguments.getOrDefault(key.toLowerCase(), defaultValue)); result.put(key, value); } result.put("Time", Values.value(summary.resultAvailableAfter(MILLISECONDS)+summary.resultConsumedAfter(MILLISECONDS))); if ( summary.hasProfile() ) result.put( "DbHits", Values.value( collectHits( summary.profile() ) ) ); if (summary.hasProfile()) result.put("Rows", Values.value( summary.profile().records() )); return result; }
@Nonnull public String formatFooter(@Nonnull BoltResult result) { int rows = result.getRecords().size(); ResultSummary summary = result.getSummary(); return String.format("%d row%s available after %d ms, " + "consumed after another %d ms", rows, rows != 1 ? "s" : "", summary.resultAvailableAfter(MILLISECONDS), summary.resultConsumedAfter(MILLISECONDS)); }
@Override public String getResultSummary() { ResultSummary summary = buffer.getResultSummary(); SummaryCounters counters = summary.counters(); sb.append(format("Query type: %s.\n", summary.statementType())); if (counters.containsUpdates()) { if (counters.nodesCreated() > 0) { if (summary.hasProfile()) { sb.append("Profile:\n"); profileToString(sb, summary.profile(), 1); } else if (summary.hasPlan()) { sb.append("Plan:\n"); planToString(sb, summary.plan(), 1); if (summary.notifications().size() > 0) { sb.append("Notifications:\n"); for (Notification notification : summary.notifications()) { sb.append(format("[%s] %s(%s) - %s", notification.severity(), notification.title(), notification.code(), notification.description()));
private Driver stubVersionInAnOpenSession(StatementResult versionMock, Session sessionMock, String value) { Driver driverMock = mock(Driver.class); ResultSummary resultSummary = mock(ResultSummary.class); ServerInfo serverInfo = mock(ServerInfo.class); when(resultSummary.server()).thenReturn(serverInfo); when(serverInfo.version()).thenReturn(value); when(versionMock.summary()).thenReturn(resultSummary); when(sessionMock.isOpen()).thenReturn(true); when(sessionMock.run("RETURN 1")).thenReturn(versionMock); when(driverMock.session(any(), anyString())).thenReturn(sessionMock); return driverMock; }
@Nonnull @Override public String formatInfo(@Nonnull ResultSummary summary) { if (!summary.hasPlan()) { return ""; } Map<String, Value> info = OutputFormatter.info(summary); return info.entrySet().stream() .map( e -> String.format("%s: %s",e.getKey(),e.getValue())).collect(Collectors.joining(NEWLINE)); } }
public Optional<GraphQueryPlan> getQueryPlan() { if (!hasPlan()) { return Optional.empty(); } Plan plan = resultSummary.plan(); return Optional.of(new Neo4jBoltQueryPlan(plan.operatorType(), getArguments(plan), plan.identifiers(), getPlanChildren(plan.children()))); }
@Test public void consume() { List<Map<String, Object>> results = asList( getRow(1), getRow(2) ); StatementResult statementResult = new GremlinServerStatementResult(serverInfo, statement, results.iterator(), converter); assertThat(statementResult.hasNext()).isTrue(); assertThat(statementResult.consume().server()).isEqualTo(serverInfo); assertThat(statementResult.hasNext()).isFalse(); }
@Test public void prettyPrintPlanInformation() throws Exception { // given ResultSummary resultSummary = mock(ResultSummary.class); ProfiledPlan plan = mock(ProfiledPlan.class); when(plan.dbHits()).thenReturn(1000L); when(plan.records()).thenReturn(20L); when(resultSummary.hasPlan()).thenReturn(true); when(resultSummary.hasProfile()).thenReturn(true); when(resultSummary.plan()).thenReturn(plan); when(resultSummary.profile()).thenReturn(plan); when(resultSummary.resultAvailableAfter(anyObject())).thenReturn(5L); when(resultSummary.resultConsumedAfter(anyObject())).thenReturn(7L); when(resultSummary.statementType()).thenReturn(StatementType.READ_ONLY); Map<String, Value> argumentMap = Values.parameters("Version", "3.1", "Planner", "COST", "Runtime", "INTERPRETED").asMap(v -> v); when(plan.arguments()).thenReturn(argumentMap); BoltResult result = mock(BoltResult.class); when(result.getRecords()).thenReturn(Collections.emptyList()); when(result.getSummary()).thenReturn(resultSummary); // when String actual = verbosePrinter.format(result); // then argumentMap.forEach((k, v) -> { assertThat(actual, CoreMatchers.containsString("| " + k)); assertThat(actual, CoreMatchers.containsString("| " + v.toString())); }); }
private int updatesCount(ResultSummary summary) { int updates = 0; if ( summary.counters().containsUpdates() ) { updates += summary.counters().constraintsAdded(); updates += summary.counters().constraintsRemoved(); updates += summary.counters().nodesCreated(); updates += summary.counters().nodesDeleted(); updates += summary.counters().relationshipsCreated(); updates += summary.counters().relationshipsDeleted(); updates += summary.counters().labelsAdded(); updates += summary.counters().labelsRemoved(); updates += summary.counters().indexesAdded(); updates += summary.counters().indexesRemoved(); updates += summary.counters().propertiesSet(); } return updates; }
public static ServerVersion version( Driver driver ) { try ( Session session = driver.session() ) { String versionString = session.readTransaction( tx -> tx.run( "RETURN 1" ).consume().server().version() ); return version( versionString ); } }
when(plan.records()).thenReturn(20L); when(resultSummary.hasPlan()).thenReturn(true); when(resultSummary.hasProfile()).thenReturn(true); when(resultSummary.plan()).thenReturn(plan); when(resultSummary.profile()).thenReturn(plan); when(resultSummary.resultAvailableAfter(anyObject())).thenReturn(5L); when(resultSummary.resultConsumedAfter(anyObject())).thenReturn(7L); when(resultSummary.statementType()).thenReturn(StatementType.READ_ONLY); Map<String, Value> argumentMap = Values.parameters("Version", "3.1", "Planner", "COST", "Runtime", "INTERPRETED").asMap(v -> v); when(plan.arguments()).thenReturn(argumentMap);
@Test public void returnStatisticsForDefaultFormatting() throws Exception { // given ResultSummary resultSummary = mock(ResultSummary.class); SummaryCounters summaryCounters = mock(SummaryCounters.class); when(resultSummary.counters()).thenReturn(summaryCounters); when(summaryCounters.labelsAdded()).thenReturn(1); when(summaryCounters.nodesCreated()).thenReturn(10); // when String actual = new StatisticsCollector(Format.VERBOSE).collect(resultSummary); // then assertThat(actual, is("Added 10 nodes, Added 1 labels")); }
private void reconnect() { String bookmark = null; if (session != null) { bookmark = session.lastBookmark(); session.close(); } session = driver.session(AccessMode.WRITE, bookmark); StatementResult run = session.run("RETURN 1"); this.version = run.summary().server().version(); run.consume(); }
@Test public void prettyPrintExplainInformation() throws Exception { // given ResultSummary resultSummary = mock(ResultSummary.class); ProfiledPlan plan = mock(ProfiledPlan.class); when(plan.dbHits()).thenReturn(1000L); when(plan.records()).thenReturn(20L); when(resultSummary.hasPlan()).thenReturn(true); when(resultSummary.hasProfile()).thenReturn(false); when(resultSummary.plan()).thenReturn(plan); when(resultSummary.resultAvailableAfter(anyObject())).thenReturn(5L); when(resultSummary.resultConsumedAfter(anyObject())).thenReturn(7L); when(resultSummary.statementType()).thenReturn(StatementType.READ_ONLY); Map<String, Value> argumentMap = Values.parameters("Version", "3.1", "Planner", "COST", "Runtime", "INTERPRETED").asMap(v -> v); when(plan.arguments()).thenReturn(argumentMap); BoltResult result = mock(BoltResult.class); when(result.getRecords()).thenReturn(Collections.emptyList()); when(result.getSummary()).thenReturn(resultSummary); // when String actual = plainPrinter.format(result); // then String expected = "Plan: \"EXPLAIN\"\n" + "Statement: \"READ_ONLY\"\n" + "Version: \"3.1\"\n" + "Planner: \"COST\"\n" + "Runtime: \"INTERPRETED\"\n" + "Time: 12"; Stream.of(expected.split("\n")).forEach(e -> assertThat(actual, containsString(e))); }
private String collectStatistics(@Nonnull ResultSummary summary) { List<String> statistics = new ArrayList<>(); SummaryCounters counters = summary.counters(); if (counters == null) return ""; if (counters.nodesCreated() != 0) {
@Test public void create() { List<Map<String, Object>> results = asList( getRow(1), getRow(2), getRow(3) ); StatementResult statementResult = new GremlinServerStatementResult(serverInfo, statement, results.iterator(), converter); assertThat(statementResult.keys()).containsExactly(KEY1, KEY2); assertThat(statementResult.peek().get(KEY1).asInt()).isEqualTo(1); assertThat(statementResult.hasNext()).isTrue(); assertThat(statementResult.next().get(KEY1).asInt()).isEqualTo(1); assertThat(statementResult.hasNext()).isTrue(); assertThat(statementResult.next().get(KEY1).asInt()).isEqualTo(2); assertThat(statementResult.hasNext()).isTrue(); //see org.neo4j.driver.internal.InternalStatementResult#list() assertThat(statementResult.list()).hasSize(1); assertThat(statementResult.hasNext()).isFalse(); assertThat(statementResult.summary().server()).isEqualTo(serverInfo); }
@Test public void returnStatisticsForEmptyRecords() throws Exception { // given ResultSummary resultSummary = mock(ResultSummary.class); SummaryCounters summaryCounters = mock(SummaryCounters.class); BoltResult result = mock(BoltResult.class); when(result.getRecords()).thenReturn(Collections.emptyList()); when(result.getSummary()).thenReturn(resultSummary); when(resultSummary.counters()).thenReturn(summaryCounters); when(summaryCounters.labelsAdded()).thenReturn(1); when(summaryCounters.nodesCreated()).thenReturn(10); // when String actual = verbosePrinter.format(result); // then assertThat(actual, containsString("Added 10 nodes, Added 1 labels")); }
@Override public QueryStatisticsModel adapt(StatementResult result) { QueryStatisticsModel queryStatisticsModel = new QueryStatisticsModel(); SummaryCounters stats = result.consume().counters(); queryStatisticsModel.setContains_updates(stats.containsUpdates()); queryStatisticsModel.setNodes_created(stats.nodesCreated()); queryStatisticsModel.setNodes_deleted(stats.nodesDeleted()); queryStatisticsModel.setProperties_set(stats.propertiesSet()); queryStatisticsModel.setRelationships_created(stats.relationshipsCreated()); queryStatisticsModel.setRelationship_deleted(stats.relationshipsDeleted()); queryStatisticsModel.setLabels_added(stats.labelsAdded()); queryStatisticsModel.setLabels_removed(stats.labelsRemoved()); queryStatisticsModel.setIndexes_added(stats.indexesAdded()); queryStatisticsModel.setIndexes_removed(stats.indexesRemoved()); queryStatisticsModel.setConstraints_added(stats.constraintsAdded()); queryStatisticsModel.setConstraints_removed(stats.constraintsRemoved()); return queryStatisticsModel; } }