All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.vertexium.cypher.executionPlan.UnwindClauseExecutionStep Maven / Gradle / Ivy

There is a newer version: 4.10.0
Show newest version
package org.vertexium.cypher.executionPlan;

import org.vertexium.cypher.CypherResultRow;
import org.vertexium.cypher.SingleRowVertexiumCypherResult;
import org.vertexium.cypher.VertexiumCypherQueryContext;
import org.vertexium.cypher.VertexiumCypherResult;
import org.vertexium.cypher.exceptions.VertexiumCypherNotImplemented;

import java.util.Arrays;
import java.util.stream.Stream;

import static org.vertexium.util.StreamUtils.stream;

public class UnwindClauseExecutionStep extends ExecutionStepWithChildren {
    private final String name;
    private final String expressionResultName;

    public UnwindClauseExecutionStep(String name, ExecutionStepWithResultName expression) {
        super(expression);
        this.name = name;
        this.expressionResultName = expression.getResultName();
    }

    @Override
    public VertexiumCypherResult execute(VertexiumCypherQueryContext ctx, VertexiumCypherResult source) {
        if (source == null) {
            source = new SingleRowVertexiumCypherResult();
        }
        source = super.execute(ctx, source);
        return source.flatMapCypherResult(this::executeOnRow);
    }

    @SuppressWarnings("unchecked")
    private Stream executeOnRow(CypherResultRow row) {
        Object expressionResult = row.get(expressionResultName);
        row.popScope();

        if (expressionResult instanceof Iterable) {
            return executeOnStream(row, stream((Iterable) expressionResult));
        }

        if (expressionResult instanceof Stream) {
            return executeOnStream(row, (Stream) expressionResult);
        }

        if (expressionResult.getClass().isArray()) {
            Object[] values = (Object[]) expressionResult;
            return executeOnStream(row, Arrays.stream(values));
        }

        throw new VertexiumCypherNotImplemented("Unhandled type: " + expressionResult.getClass().getName());
    }

    private Stream executeOnStream(CypherResultRow row, Stream expressionResult) {
        return expressionResult
            .map(item -> {
                CypherResultRow newRow = row.clone();
                newRow.set(name, item);
                return newRow;
            });
    }
}