This is an automated email from the ASF dual-hosted git repository. okram pushed a commit to branch tp4 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/tp4 by this push: new 7142dc1 Created a JDBCQueryStrategy that looks for 'join' semantics in the bytecode and folds it into a custom jdbs:sql instruction that does a SELECT call. 7142dc1 is described below commit 7142dc16d8fc81ad8bd4090096b42e5b9b1744f4 Author: Marko A. Rodriguez <okramma...@gmail.com> AuthorDate: Mon Apr 29 13:56:21 2019 -0600 Created a JDBCQueryStrategy that looks for 'join' semantics in the bytecode and folds it into a custom jdbs:sql instruction that does a SELECT call. --- .../tinkerpop/machine/bytecode/Bytecode.java | 5 + .../tinkerpop/machine/bytecode/BytecodeUtil.java | 12 +++ .../bytecode/compiler/BytecodeCompiler.java | 3 +- .../machine/bytecode/compiler/Compilation.java | 4 +- .../bytecode/compiler/SourceCompilation.java | 4 +- .../machine/function/barrier/OrderBarrier.java | 2 +- .../machine/function/branch/RepeatBranch.java | 4 +- .../machine/function/initial/FlatMapInitial.java | 9 +- .../processor/{ => util}/EmptyProcessor.java | 5 +- .../processor/{ => util}/FilterProcessor.java | 2 +- .../processor/{ => util}/LoopsProcessor.java | 2 +- .../processor/{ => util}/SimpleProcessor.java | 4 +- .../tinkerpop/machine/structure/TSymbol.java | 26 ----- .../machine/structure/graph/IdSymbol.java | 52 ---------- .../machine/structure/graph/LabelSymbol.java | 52 ---------- .../tinkerpop/machine/structure/graph/TGraph.java | 4 +- .../machine/structure/graph/TVertices.java | 27 ------ .../structure/{ => util}/EmptyStructure.java | 5 +- .../tinkerpop/machine/structure/util/JTuple.java | 5 + .../structure/{graph/G.java => util/TSymbol.java} | 22 +++-- .../machine/traverser/path/BasicPath.java | 1 + .../machine/structure/jdbc/JDBCDatabase.java | 6 +- .../machine/structure/jdbc/JDBCStructure.java | 11 ++- .../jdbc/bytecode/compiler/JDBCCompiler.java | 69 ++++++++++++++ .../jdbc/function/flatmap/SqlFlatMap.java | 105 +++++++++++++++++++++ .../structure/jdbc/strategy/JDBCQueryStrategy.java | 55 +++++++++++ .../structure/jdbc/strategy/JDBCStrategy.java | 7 ++ .../tinkerpop/machine/structure/jdbc/JDBCTest.java | 8 +- 28 files changed, 324 insertions(+), 187 deletions(-) diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/Bytecode.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/Bytecode.java index eeeeacc..7519652 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/Bytecode.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/Bytecode.java @@ -64,6 +64,11 @@ public final class Bytecode<C> implements Cloneable, Serializable { this.instructions.add(new Instruction<>(coefficient, op, args)); } + public void addInstruction(final int index, final Coefficient<C> coefficient, final String op, final Object... args) { + BytecodeUtil.linkBytecodeChildren(this, args); + this.instructions.add(index, new Instruction<>(coefficient, op, args)); + } + public List<Instruction<C>> getInstructions() { return this.instructions; } diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java index c4ea488..afb3072 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java @@ -187,4 +187,16 @@ public final class BytecodeUtil { } return Optional.of(COP_TraverserFactory.instance()); } + + public static <C> boolean startsWith(final Bytecode<C> bytecode, String... ops) { + int i = 0; + for (final Instruction<C> instruction : bytecode.getInstructions()) { + if (!instruction.op().equals(ops[i])) + return false; + i++; + if (i >= ops.length) + return true; + } + return false; + } } diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/BytecodeCompiler.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/BytecodeCompiler.java index 16cf912..07b49ed 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/BytecodeCompiler.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/BytecodeCompiler.java @@ -19,6 +19,7 @@ package org.apache.tinkerpop.machine.bytecode.compiler; import org.apache.tinkerpop.machine.bytecode.Bytecode; +import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; import org.apache.tinkerpop.machine.bytecode.Instruction; import org.apache.tinkerpop.machine.function.CFunction; import org.apache.tinkerpop.machine.function.initial.FlatMapInitial; @@ -37,7 +38,7 @@ public interface BytecodeCompiler { for (final Instruction<C> instruction : bytecode.getInstructions()) { final CFunction function = this.compile(instruction); functions.add(functions.isEmpty() && bytecode.getParent().isEmpty() && function instanceof Initializing ? - new FlatMapInitial<>(function.coefficient(), function.label(), (Initializing) function) : function); + new FlatMapInitial<>(function.coefficient(), function.label(), (Initializing) function, BytecodeUtil.getTraverserFactory(bytecode).get()) : function); } return functions; } diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Compilation.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Compilation.java index f7105d9..b7370ff 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Compilation.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Compilation.java @@ -21,10 +21,10 @@ package org.apache.tinkerpop.machine.bytecode.compiler; import org.apache.tinkerpop.machine.bytecode.Bytecode; import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; import org.apache.tinkerpop.machine.function.CFunction; -import org.apache.tinkerpop.machine.processor.EmptyProcessor; +import org.apache.tinkerpop.machine.processor.util.EmptyProcessor; import org.apache.tinkerpop.machine.processor.Processor; import org.apache.tinkerpop.machine.processor.ProcessorFactory; -import org.apache.tinkerpop.machine.structure.EmptyStructure; +import org.apache.tinkerpop.machine.structure.util.EmptyStructure; import org.apache.tinkerpop.machine.structure.StructureFactory; import org.apache.tinkerpop.machine.traverser.Traverser; import org.apache.tinkerpop.machine.traverser.TraverserFactory; diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java index 70a9603..9feeb59 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java @@ -20,10 +20,10 @@ package org.apache.tinkerpop.machine.bytecode.compiler; import org.apache.tinkerpop.machine.bytecode.Bytecode; import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; -import org.apache.tinkerpop.machine.processor.EmptyProcessor; +import org.apache.tinkerpop.machine.processor.util.EmptyProcessor; import org.apache.tinkerpop.machine.processor.ProcessorFactory; import org.apache.tinkerpop.machine.strategy.Strategy; -import org.apache.tinkerpop.machine.structure.EmptyStructure; +import org.apache.tinkerpop.machine.structure.util.EmptyStructure; import org.apache.tinkerpop.machine.structure.StructureFactory; import java.util.Set; diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/barrier/OrderBarrier.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/barrier/OrderBarrier.java index ed81393..05f02e2 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/barrier/OrderBarrier.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/barrier/OrderBarrier.java @@ -25,7 +25,7 @@ import org.apache.tinkerpop.machine.bytecode.compiler.Order; import org.apache.tinkerpop.machine.coefficient.Coefficient; import org.apache.tinkerpop.machine.function.AbstractFunction; import org.apache.tinkerpop.machine.function.BarrierFunction; -import org.apache.tinkerpop.machine.processor.FilterProcessor; +import org.apache.tinkerpop.machine.processor.util.FilterProcessor; import org.apache.tinkerpop.machine.traverser.Traverser; import org.apache.tinkerpop.machine.traverser.TraverserSet; import org.apache.tinkerpop.machine.traverser.species.ProjectedTraverser; diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/RepeatBranch.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/RepeatBranch.java index 378eb6d..8d73d5f 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/RepeatBranch.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/RepeatBranch.java @@ -23,8 +23,8 @@ import org.apache.tinkerpop.machine.bytecode.Instruction; import org.apache.tinkerpop.machine.bytecode.compiler.Compilation; import org.apache.tinkerpop.machine.coefficient.Coefficient; import org.apache.tinkerpop.machine.function.AbstractFunction; -import org.apache.tinkerpop.machine.processor.FilterProcessor; -import org.apache.tinkerpop.machine.processor.LoopsProcessor; +import org.apache.tinkerpop.machine.processor.util.FilterProcessor; +import org.apache.tinkerpop.machine.processor.util.LoopsProcessor; import org.apache.tinkerpop.machine.util.StringFactory; import java.util.ArrayList; diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/initial/FlatMapInitial.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/initial/FlatMapInitial.java index 2a2ca21..8b06567 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/initial/FlatMapInitial.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/initial/FlatMapInitial.java @@ -21,7 +21,7 @@ package org.apache.tinkerpop.machine.function.initial; import org.apache.tinkerpop.machine.coefficient.Coefficient; import org.apache.tinkerpop.machine.function.AbstractFunction; import org.apache.tinkerpop.machine.function.InitialFunction; -import org.apache.tinkerpop.machine.traverser.species.EmptyTraverser; +import org.apache.tinkerpop.machine.traverser.TraverserFactory; import java.util.Iterator; @@ -31,14 +31,17 @@ import java.util.Iterator; public final class FlatMapInitial<C, S> extends AbstractFunction<C> implements InitialFunction<C, S> { private final Initializing<C, ?, S> function; + private final TraverserFactory<C> traverserFactory; - public FlatMapInitial(final Coefficient<C> coefficient, final String label, final Initializing<C, ?, S> function) { + + public FlatMapInitial(final Coefficient<C> coefficient, final String label, final Initializing<C, ?, S> function, final TraverserFactory<C> traverserFactory) { super(coefficient, label); this.function = function; + this.traverserFactory = traverserFactory; } @Override public Iterator<S> get() { - return this.function.apply(EmptyTraverser.instance()); + return this.function.apply(traverserFactory.create(this, null)); } } diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessor.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/EmptyProcessor.java similarity index 91% rename from java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessor.java rename to java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/EmptyProcessor.java index d3da9cb..a56bb98 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessor.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/EmptyProcessor.java @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.processor; +package org.apache.tinkerpop.machine.processor.util; import org.apache.tinkerpop.machine.bytecode.compiler.Compilation; +import org.apache.tinkerpop.machine.processor.Processor; +import org.apache.tinkerpop.machine.processor.ProcessorFactory; import org.apache.tinkerpop.machine.traverser.Traverser; -import org.apache.tinkerpop.machine.util.FastNoSuchElementException; import java.util.Collections; import java.util.Iterator; diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/FilterProcessor.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/FilterProcessor.java similarity index 96% rename from java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/FilterProcessor.java rename to java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/FilterProcessor.java index a83e0d9..61294f7 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/FilterProcessor.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/FilterProcessor.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.processor; +package org.apache.tinkerpop.machine.processor.util; import org.apache.tinkerpop.machine.traverser.Traverser; diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/LoopsProcessor.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/LoopsProcessor.java similarity index 96% rename from java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/LoopsProcessor.java rename to java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/LoopsProcessor.java index 25a44e1..9d97f82 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/LoopsProcessor.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/LoopsProcessor.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.processor; +package org.apache.tinkerpop.machine.processor.util; import org.apache.tinkerpop.machine.traverser.Traverser; diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/SimpleProcessor.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/SimpleProcessor.java similarity index 93% rename from java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/SimpleProcessor.java rename to java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/SimpleProcessor.java index e2a0955..95b3edf 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/SimpleProcessor.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/util/SimpleProcessor.java @@ -16,9 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.processor; +package org.apache.tinkerpop.machine.processor.util; import org.apache.tinkerpop.machine.bytecode.compiler.Compilation; +import org.apache.tinkerpop.machine.processor.Processor; +import org.apache.tinkerpop.machine.processor.ProcessorFactory; import org.apache.tinkerpop.machine.traverser.Traverser; import org.apache.tinkerpop.machine.util.FastNoSuchElementException; diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/TSymbol.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/TSymbol.java deleted file mode 100644 index 67891ba..0000000 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/TSymbol.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tinkerpop.machine.structure; - -/** - * @author Marko A. Rodriguez (http://markorodriguez.com) - */ -public interface TSymbol { - -} diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/IdSymbol.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/IdSymbol.java deleted file mode 100644 index 43f6b8f..0000000 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/IdSymbol.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tinkerpop.machine.structure.graph; - -import org.apache.tinkerpop.machine.structure.TSymbol; - -/** - * @author Marko A. Rodriguez (http://markorodriguez.com) - */ -final class IdSymbol implements TSymbol { - - private static final IdSymbol INSTANCE = new IdSymbol(); - - private IdSymbol() { - // static instance - } - - @Override - public String toString() { - return "#id"; - } - - @Override - public int hashCode() { - return this.toString().hashCode(); - } - - @Override - public boolean equals(final Object other) { - return other instanceof IdSymbol; - } - - public static IdSymbol instance() { - return INSTANCE; - } -} diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/LabelSymbol.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/LabelSymbol.java deleted file mode 100644 index cbeb33b..0000000 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/LabelSymbol.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tinkerpop.machine.structure.graph; - -import org.apache.tinkerpop.machine.structure.TSymbol; - -/** - * @author Marko A. Rodriguez (http://markorodriguez.com) - */ -final class LabelSymbol implements TSymbol { - - private static final LabelSymbol INSTANCE = new LabelSymbol(); - - private LabelSymbol() { - // static instance - } - - @Override - public String toString() { - return "#label"; - } - - @Override - public int hashCode() { - return this.toString().hashCode(); - } - - @Override - public boolean equals(final Object other) { - return other instanceof LabelSymbol; - } - - public static LabelSymbol instance() { - return INSTANCE; - } -} \ No newline at end of file diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/TGraph.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/TGraph.java index f0fa9b4..6b8f122 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/TGraph.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/TGraph.java @@ -18,11 +18,11 @@ */ package org.apache.tinkerpop.machine.structure.graph; +import org.apache.tinkerpop.machine.structure.Structure; import org.apache.tinkerpop.machine.structure.TSequence; -import org.apache.tinkerpop.machine.structure.TTuple; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -public interface TGraph extends TSequence<TVertex> { +public interface TGraph extends TSequence<TVertex>, Structure { } diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/TVertices.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/TVertices.java deleted file mode 100644 index 90890b2..0000000 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/TVertices.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tinkerpop.machine.structure.graph; - -import org.apache.tinkerpop.machine.structure.TSequence; - -/** - * @author Marko A. Rodriguez (http://markorodriguez.com) - */ -public interface TVertices extends TSequence<TVertex> { -} diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/EmptyStructure.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/EmptyStructure.java similarity index 87% rename from java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/EmptyStructure.java rename to java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/EmptyStructure.java index a00abb7..a367dc1 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/EmptyStructure.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/EmptyStructure.java @@ -16,9 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.structure; +package org.apache.tinkerpop.machine.structure.util; -import java.util.Map; +import org.apache.tinkerpop.machine.structure.Structure; +import org.apache.tinkerpop.machine.structure.StructureFactory; /** * @author Marko A. Rodriguez (http://markorodriguez.com) diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/JTuple.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/JTuple.java index 5966aa2..46f5cf9 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/JTuple.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/JTuple.java @@ -79,4 +79,9 @@ public class JTuple<K, V> implements TTuple<K, V> { return IteratorUtils.map(this.map.entrySet().iterator(), e -> new J2Tuple<>(e.getKey(), e.getValue())); } + @Override + public String toString() { + return this.map.toString(); + } + } diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/G.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/TSymbol.java similarity index 63% rename from java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/G.java rename to java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/TSymbol.java index 5b0f6d0..a5ffd61 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/graph/G.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/structure/util/TSymbol.java @@ -16,19 +16,27 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.structure.graph; - -import org.apache.tinkerpop.machine.structure.TSymbol; +package org.apache.tinkerpop.machine.structure.util; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -public final class G { +public final class TSymbol { - private G() { + private TSymbol() { // static instance } - public static TSymbol id = IdSymbol.instance(); - public static TSymbol label = LabelSymbol.instance(); + public static final String id = "#id"; + public static final String label = "#label"; + public static final String key = "#key"; + public static final String value = "#value"; + + public static boolean isSymbol(final String string) { + return string.startsWith("#"); + } + + public static String asSymbol(final String string) { + return string.startsWith("#") ? string : "#" + string; + } } diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/traverser/path/BasicPath.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/traverser/path/BasicPath.java index 5b7f078..5b46c9e 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/traverser/path/BasicPath.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/traverser/path/BasicPath.java @@ -79,6 +79,7 @@ public final class BasicPath implements Path { @Override public Object get(final Pop pop, final String label) { + System.out.println(this.labels + ":::" + this.objects); if (Pop.last == pop) { for (int i = this.labels.size() - 1; i >= 0; i--) { if (label.equals(this.labels.get(i))) diff --git a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCDatabase.java b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCDatabase.java index b04e894..3e4e93f 100644 --- a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCDatabase.java +++ b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCDatabase.java @@ -33,7 +33,7 @@ import java.util.Iterator; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -final class JDBCDatabase implements TDatabase { +public final class JDBCDatabase implements TDatabase { private final Connection connection; @@ -45,6 +45,10 @@ final class JDBCDatabase implements TDatabase { } } + public Connection getConnection() { + return this.connection; + } + @Override public boolean has(final String key) { try { diff --git a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCStructure.java b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCStructure.java index 8c6a2ab..f951075 100644 --- a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCStructure.java +++ b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCStructure.java @@ -18,11 +18,15 @@ */ package org.apache.tinkerpop.machine.structure.jdbc; +import org.apache.tinkerpop.machine.bytecode.compiler.BytecodeCompiler; import org.apache.tinkerpop.machine.strategy.Strategy; import org.apache.tinkerpop.machine.structure.Structure; import org.apache.tinkerpop.machine.structure.StructureFactory; +import org.apache.tinkerpop.machine.structure.jdbc.bytecode.compiler.JDBCCompiler; +import org.apache.tinkerpop.machine.structure.jdbc.strategy.JDBCQueryStrategy; import org.apache.tinkerpop.machine.structure.jdbc.strategy.JDBCStrategy; +import java.util.List; import java.util.Map; import java.util.Set; @@ -41,11 +45,16 @@ public class JDBCStructure implements StructureFactory { @Override public Set<Strategy<?>> getStrategies() { - return Set.of(new JDBCStrategy()); + return Set.of(new JDBCStrategy(), new JDBCQueryStrategy()); } @Override public Structure mint() { return new JDBCDatabase((String) this.configuration.get(JDBC_CONNECTION)); } + + @Override + public List<BytecodeCompiler> getCompilers() { + return List.of(JDBCCompiler.instance()); + } } diff --git a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/bytecode/compiler/JDBCCompiler.java b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/bytecode/compiler/JDBCCompiler.java new file mode 100644 index 0000000..eb75b44 --- /dev/null +++ b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/bytecode/compiler/JDBCCompiler.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.machine.structure.jdbc.bytecode.compiler; + +import org.apache.tinkerpop.machine.bytecode.Instruction; +import org.apache.tinkerpop.machine.bytecode.compiler.BytecodeCompiler; +import org.apache.tinkerpop.machine.bytecode.compiler.FunctionType; +import org.apache.tinkerpop.machine.coefficient.Coefficient; +import org.apache.tinkerpop.machine.function.CFunction; +import org.apache.tinkerpop.machine.structure.jdbc.function.flatmap.SqlFlatMap; + +import java.sql.Connection; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class JDBCCompiler implements BytecodeCompiler { + + private static final JDBCCompiler INSTANCE = new JDBCCompiler(); + + private JDBCCompiler() { + // static instance + } + + public static JDBCCompiler instance() { + return INSTANCE; + } + + @Override + public <C> CFunction<C> compile(final Instruction<C> instruction) { + final String op = instruction.op(); + final Coefficient<C> coefficient = instruction.coefficient(); + final String label = instruction.label(); + if (op.equals(Symbols.JDBC_SQL)) + return new SqlFlatMap<>(coefficient, label, (Connection) instruction.args()[0], (String) instruction.args()[1], (String) instruction.args()[2], (String) instruction.args()[3]); + else + return null; + } + + @Override + public FunctionType getFunctionType(final String op) { + return op.equals(Symbols.JDBC_SQL) ? FunctionType.FLATMAP : null; + } + + public static class Symbols { + + private Symbols() { + // static instance + } + + public static final String JDBC_SQL = "jdbc:sql"; + } +} diff --git a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/function/flatmap/SqlFlatMap.java b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/function/flatmap/SqlFlatMap.java new file mode 100644 index 0000000..af5f2b0 --- /dev/null +++ b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/function/flatmap/SqlFlatMap.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.machine.structure.jdbc.function.flatmap; + +import org.apache.tinkerpop.machine.coefficient.Coefficient; +import org.apache.tinkerpop.machine.function.AbstractFunction; +import org.apache.tinkerpop.machine.function.initial.Initializing; +import org.apache.tinkerpop.machine.structure.TTuple; +import org.apache.tinkerpop.machine.structure.util.JTuple; +import org.apache.tinkerpop.machine.traverser.Traverser; +import org.apache.tinkerpop.machine.traverser.path.BasicPath; +import org.apache.tinkerpop.machine.traverser.path.Path; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class SqlFlatMap<C, S> extends AbstractFunction<C> implements Initializing<C, S, Path> { + + private final Connection connection; + private final String sqlQuery; + private final String as1; + private final String as2; + + public SqlFlatMap(final Coefficient<C> coefficient, final String label, final Connection connection, final String as1, final String as2, final String sqlQuery) { + super(coefficient, label); + this.connection = connection; + this.sqlQuery = sqlQuery; + this.as1 = as1; + this.as2 = as2; + } + + @Override + public Iterator<Path> apply(final Traverser<C, S> traverser) { + try { + final ResultSet resultSet = this.connection.createStatement().executeQuery(this.sqlQuery); + return new Iterator<>() { + boolean done = false; + + @Override + public boolean hasNext() { + return !this.done; + } + + @Override + public Path next() { + try { + resultSet.next(); + int size = resultSet.getMetaData().getColumnCount(); + final Path row = new BasicPath(); + final TTuple<String, Object> tuple1 = new JTuple<>(); + final TTuple<String, Object> tuple2 = new JTuple<>(); + Set<String> labels = new HashSet<>(); + boolean stay = true; + for (int i = 1; i <= size; i++) { + final String temp = resultSet.getMetaData().getColumnLabel(i); + stay = stay && labels.add(temp); + if (stay) { + tuple1.set(resultSet.getMetaData().getColumnName(i), resultSet.getObject(i)); + } else { + tuple2.set(resultSet.getMetaData().getColumnName(i), resultSet.getObject(i)); + } + } + row.add(as1, tuple1); + row.add(as2, tuple2); + this.done = resultSet.isLast(); + return row; + + } catch (final SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + }; + } catch (final SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + @Override + public SqlFlatMap<C, S> clone() { + return this; // TODO; + } +} diff --git a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/strategy/JDBCQueryStrategy.java b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/strategy/JDBCQueryStrategy.java new file mode 100644 index 0000000..3adb915 --- /dev/null +++ b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/strategy/JDBCQueryStrategy.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.machine.structure.jdbc.strategy; + +import org.apache.tinkerpop.machine.bytecode.Bytecode; +import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; +import org.apache.tinkerpop.machine.bytecode.Instruction; +import org.apache.tinkerpop.machine.bytecode.compiler.CoreCompiler.Symbols; +import org.apache.tinkerpop.machine.strategy.AbstractStrategy; +import org.apache.tinkerpop.machine.strategy.Strategy; +import org.apache.tinkerpop.machine.structure.jdbc.JDBCDatabase; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class JDBCQueryStrategy extends AbstractStrategy<Strategy.ProviderStrategy> implements Strategy.ProviderStrategy { + + @Override + public <C> void apply(final Bytecode<C> bytecode) { + if (bytecode.getParent().isEmpty() && BytecodeUtil.startsWith(bytecode, Symbols.DB, Symbols.VALUES, Symbols.DB, Symbols.VALUES, Symbols.HAS_KEY_VALUE, Symbols.PATH)) { + System.out.println(bytecode); + final JDBCDatabase db = (JDBCDatabase) bytecode.getInstructions().get(0).args()[0]; + bytecode.getInstructions().remove(0); // DB + final String table1 = (String) bytecode.getInstructions().get(0).args()[0]; + final String as1 = bytecode.getInstructions().get(0).label(); + bytecode.getInstructions().remove(0); // VALUES + bytecode.getInstructions().remove(0); // DB + final String table2 = (String) bytecode.getInstructions().get(0).args()[0]; + final String as2 = bytecode.getInstructions().get(0).label(); + bytecode.getInstructions().remove(0); // VALUES + final String join = as1 + "." + bytecode.getInstructions().get(0).args()[0] + "=" + as2 + "." + ((Bytecode<C>) ((Bytecode<C>) bytecode.getInstructions().get(0).args()[1]).getInstructions().get(0).args()[1]).getInstructions().get(0).args()[0]; + final String query = "SELECT " + as1 + ".*, " + as2 + ".* FROM " + table1 + " AS " + as1 + ", " + table2 + " AS " + as2 + " WHERE " + join; + final Instruction<C> inst = bytecode.getInstructions().remove(0); // HAS_KEY_VALUE + bytecode.getInstructions().remove(0); // PATH + bytecode.addInstruction(0, inst.coefficient(), "jdbc:sql", db.getConnection(), as1, as2, query); + System.out.println(bytecode); + } + } +} diff --git a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/strategy/JDBCStrategy.java b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/strategy/JDBCStrategy.java index fc3b154..60a3c28 100644 --- a/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/strategy/JDBCStrategy.java +++ b/java/machine/structure/jdbc/src/main/java/org/apache/tinkerpop/machine/structure/jdbc/strategy/JDBCStrategy.java @@ -26,7 +26,9 @@ import org.apache.tinkerpop.machine.strategy.AbstractStrategy; import org.apache.tinkerpop.machine.strategy.Strategy; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Set; /** * @author Marko A. Rodriguez (http://markorodriguez.com) @@ -49,4 +51,9 @@ public final class JDBCStrategy extends AbstractStrategy<Strategy.ProviderStrate BytecodeUtil.getStructureFactory(BytecodeUtil.getRootBytecode(bytecode)).get().mint())); } } + + @Override + public Set<Class<? extends ProviderStrategy>> applyPost() { + return Set.of(JDBCQueryStrategy.class); + } } diff --git a/java/machine/structure/jdbc/src/test/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCTest.java b/java/machine/structure/jdbc/src/test/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCTest.java index 6429f07..1fa6c6c 100644 --- a/java/machine/structure/jdbc/src/test/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCTest.java +++ b/java/machine/structure/jdbc/src/test/java/org/apache/tinkerpop/machine/structure/jdbc/JDBCTest.java @@ -41,8 +41,13 @@ public class JDBCTest { connection.createStatement().execute("CREATE TABLE IF NOT EXISTS people (\n" + " name VARCHAR(255) NOT NULL,\n" + " age TINYINT NOT NULL)"); + connection.createStatement().execute("CREATE TABLE IF NOT EXISTS addresses (\n" + + " name VARCHAR(255) NOT NULL,\n" + + " city VARCHAR(255) NOT NULL)"); //connection.createStatement().execute("INSERT INTO people(`name`,`age`) VALUES ('marko',29)"); //connection.createStatement().execute("INSERT INTO people(`name`,`age`) VALUES ('josh',32)"); + //connection.createStatement().execute("INSERT INTO addresses(`name`,`city`) VALUES ('josh','san jose')"); + //connection.createStatement().execute("INSERT INTO addresses(`name`,`city`) VALUES ('marko','santa fe')"); /* final TDatabase db = new JDBCDatabase("jdbc:h2:/tmp/test"); @@ -67,6 +72,7 @@ public class JDBCTest { System.out.println(jdbc.db().values("people").toList()); System.out.println(jdbc.db().values("people").value("name").toList()); System.out.println(jdbc.db().values("people").entries().toList()); - System.out.println(jdbc.db().values("people").as("x").db().values("people").has("name", __.path("x").by("name")).as("y").path("x", "y").toList()); + System.out.println(jdbc.db().values("people").as("x").db().values("addresses").as("y").has("name", __.path("x").by("name")).path("x", "y").toList()); + System.out.println(jdbc.db().values("people").as("x").db().values("addresses").as("y").has("name", __.path("x").by("name")).path("x", "y").explain().toList()); } }