CAY-2466 New internal API to build SQL string
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/89439015 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/89439015 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/89439015 Branch: refs/heads/master Commit: 89439015fc7e3fd88e8a4846bea953b43f003717 Parents: 9889375 Author: Nikita Timofeev <stari...@gmail.com> Authored: Fri Jan 4 16:16:46 2019 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Fri Jan 4 17:20:44 2019 +0300 ---------------------------------------------------------------------- .../access/sqlbuilder/AliasedNodeBuilder.java | 46 ++++ .../access/sqlbuilder/ColumnNodeBuilder.java | 86 +++++++ .../access/sqlbuilder/ExistsNodeBuilder.java | 42 ++++ .../sqlbuilder/ExpressionNodeBuilder.java | 129 ++++++++++ .../access/sqlbuilder/ExpressionTrait.java | 62 +++++ .../access/sqlbuilder/FunctionNodeBuilder.java | 56 +++++ .../access/sqlbuilder/JoinNodeBuilder.java | 54 ++++ .../cayenne/access/sqlbuilder/JoinType.java | 39 +++ .../cayenne/access/sqlbuilder/NodeBuilder.java | 32 +++ .../access/sqlbuilder/NodeTreeVisitor.java | 47 ++++ .../access/sqlbuilder/OrderingNodeBuilder.java | 56 +++++ .../access/sqlbuilder/QuotingAppendable.java | 41 ++++ .../cayenne/access/sqlbuilder/SQLBuilder.java | 161 ++++++++++++ .../access/sqlbuilder/SQLGenerationContext.java | 35 +++ .../access/sqlbuilder/SQLGenerationVisitor.java | 63 +++++ .../access/sqlbuilder/SelectBuilder.java | 169 +++++++++++++ .../sqlbuilder/StringBuilderAppendable.java | 76 ++++++ .../access/sqlbuilder/TableNodeBuilder.java | 65 +++++ .../access/sqlbuilder/ValueNodeBuilder.java | 48 ++++ .../access/sqlbuilder/sqltree/BetweenNode.java | 52 ++++ .../sqlbuilder/sqltree/BitwiseNotNode.java | 38 +++ .../access/sqlbuilder/sqltree/ColumnNode.java | 76 ++++++ .../access/sqlbuilder/sqltree/DistinctNode.java | 43 ++++ .../access/sqlbuilder/sqltree/EmptyNode.java | 43 ++++ .../access/sqlbuilder/sqltree/EqualNode.java | 43 ++++ .../access/sqlbuilder/sqltree/ExistsNode.java | 38 +++ .../sqlbuilder/sqltree/ExpressionNode.java | 65 +++++ .../access/sqlbuilder/sqltree/FromNode.java | 43 ++++ .../access/sqlbuilder/sqltree/FunctionNode.java | 127 ++++++++++ .../access/sqlbuilder/sqltree/GroupByNode.java | 43 ++++ .../access/sqlbuilder/sqltree/HavingNode.java | 37 +++ .../access/sqlbuilder/sqltree/InNode.java | 65 +++++ .../access/sqlbuilder/sqltree/JoinNode.java | 51 ++++ .../access/sqlbuilder/sqltree/LikeNode.java | 89 +++++++ .../sqlbuilder/sqltree/LimitOffsetNode.java | 58 +++++ .../cayenne/access/sqlbuilder/sqltree/Node.java | 139 +++++++++++ .../access/sqlbuilder/sqltree/NodeType.java | 38 +++ .../access/sqlbuilder/sqltree/NotEqualNode.java | 42 ++++ .../access/sqlbuilder/sqltree/NotNode.java | 37 +++ .../sqlbuilder/sqltree/OffsetFetchNextNode.java | 53 ++++ .../access/sqlbuilder/sqltree/OffsetNode.java | 43 ++++ .../sqlbuilder/sqltree/OpExpressionNode.java | 44 ++++ .../access/sqlbuilder/sqltree/OrderByNode.java | 43 ++++ .../access/sqlbuilder/sqltree/SelectNode.java | 48 ++++ .../sqlbuilder/sqltree/SelectResultNode.java | 52 ++++ .../sqltree/SimpleNodeTreeVisitor.java | 46 ++++ .../access/sqlbuilder/sqltree/SubqueryNode.java | 45 ++++ .../access/sqlbuilder/sqltree/TableNode.java | 50 ++++ .../access/sqlbuilder/sqltree/TextNode.java | 44 ++++ .../access/sqlbuilder/sqltree/TopNode.java | 44 ++++ .../sqlbuilder/sqltree/TrimmingColumnNode.java | 134 ++++++++++ .../sqlbuilder/sqltree/UnescapedColumnNode.java | 52 ++++ .../access/sqlbuilder/sqltree/ValueNode.java | 246 +++++++++++++++++++ .../access/sqlbuilder/sqltree/WhereNode.java | 43 ++++ .../access/sqlbuilder/SelectBuilderTest.java | 131 ++++++++++ 55 files changed, 3592 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/AliasedNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/AliasedNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/AliasedNodeBuilder.java new file mode 100644 index 0000000..50f07bd --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/AliasedNodeBuilder.java @@ -0,0 +1,46 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.EmptyNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; +import org.apache.cayenne.access.sqlbuilder.sqltree.TextNode; + +/** + * @since 4.2 + */ +class AliasedNodeBuilder implements NodeBuilder { + + private final NodeBuilder nodeBuilder; + private final String alias; + + AliasedNodeBuilder(NodeBuilder nodeBuilder, String alias) { + this.nodeBuilder = nodeBuilder; + this.alias = alias; + } + + @Override + public Node build() { + Node root = new EmptyNode(); + root.addChild(nodeBuilder.build()); + root.addChild(new TextNode(" " + alias)); + return root; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ColumnNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ColumnNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ColumnNodeBuilder.java new file mode 100644 index 0000000..8236744 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ColumnNodeBuilder.java @@ -0,0 +1,86 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import java.util.Objects; + +import org.apache.cayenne.access.sqlbuilder.sqltree.ColumnNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; +import org.apache.cayenne.access.sqlbuilder.sqltree.UnescapedColumnNode; +import org.apache.cayenne.map.DbAttribute; + +/** + * @since 4.2 + */ +public class ColumnNodeBuilder implements ExpressionTrait { + + private final String table; + private final String column; + + private boolean unescaped; + private String alias; + private DbAttribute attribute; + + ColumnNodeBuilder(String table, String field) { + this.table = table; + this.column = Objects.requireNonNull(field); + } + + ColumnNodeBuilder(String table, DbAttribute attribute) { + this.table = table; + this.column = Objects.requireNonNull(attribute).getName(); + this.attribute = attribute; + } + + public ColumnNodeBuilder as(String alias) { + this.alias = alias; + return this; + } + + public ColumnNodeBuilder unescaped() { + this.unescaped = true; + return this; + } + + public ColumnNodeBuilder attribute(DbAttribute attribute) { + this.attribute = attribute; + return this; + } + + public OrderingNodeBuilder desc() { + return new OrderingNodeBuilder(this).desc(); + } + + public OrderingNodeBuilder asc() { + return new OrderingNodeBuilder(this).asc(); + } + + @Override + public Node build() { + ColumnNode columnNode; + if(unescaped) { + columnNode = new UnescapedColumnNode(table, column, alias, attribute); + } else { + columnNode = new ColumnNode(table, column, alias, attribute); + } + return columnNode; + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExistsNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExistsNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExistsNodeBuilder.java new file mode 100644 index 0000000..d71d38d --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExistsNodeBuilder.java @@ -0,0 +1,42 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.ExistsNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; + +/** + * @since 4.2 + */ +class ExistsNodeBuilder implements NodeBuilder { + + private final NodeBuilder builder; + + ExistsNodeBuilder(NodeBuilder builder) { + this.builder = builder; + } + + @Override + public Node build() { + Node node = new ExistsNode(); + node.addChild(builder.build()); + return node; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExpressionNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExpressionNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExpressionNodeBuilder.java new file mode 100644 index 0000000..2de4d7a --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExpressionNodeBuilder.java @@ -0,0 +1,129 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.EqualNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; +import org.apache.cayenne.access.sqlbuilder.sqltree.NotNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.OpExpressionNode; + +/** + * @since 4.2 + */ +public class ExpressionNodeBuilder implements ExpressionTrait { + + private final NodeBuilder left; + + ExpressionNodeBuilder(NodeBuilder left) { + this.left = left; + } + + public ExpressionNodeBuilder and(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "AND")); + } + + public ExpressionNodeBuilder or(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "OR")); + } + + @Override + public ExpressionNodeBuilder plus(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "+")); + } + + @Override + public ExpressionNodeBuilder minus(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "-")); + } + + @Override + public ExpressionNodeBuilder mul(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "*")); + } + + @Override + public ExpressionNodeBuilder div(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "/")); + } + + @Override + public ExpressionNodeBuilder eq(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "=")); + } + + @Override + public ExpressionNodeBuilder lt(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "<")); + } + + @Override + public ExpressionNodeBuilder gt(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, ">")); + } + + @Override + public ExpressionNodeBuilder lte(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, "<=")); + } + + @Override + public ExpressionNodeBuilder gte(NodeBuilder operand) { + return new ExpressionNodeBuilder(new ExpNodeBuilder(operand, ">=")); + } + + public ExpressionNodeBuilder not() { + return new ExpressionNodeBuilder(() -> { + Node and = new NotNode(); + and.addChild(left.build()); + return and; + }); + } + + @Override + public Node build() { + return left.build(); + } + + private class ExpNodeBuilder implements NodeBuilder { + + private final NodeBuilder operand; + + private final String operation; + + public ExpNodeBuilder(NodeBuilder operand, String operation) { + this.operand = operand; + this.operation = operation; + } + + @Override + public Node build() { + Node node; + if(operation.equals("=")) { + node = new EqualNode(); + } else { + node = new OpExpressionNode(operation); + } + + node.addChild(left.build()); + node.addChild(operand.build()); + return node; + } + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExpressionTrait.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExpressionTrait.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExpressionTrait.java new file mode 100644 index 0000000..91fd07c --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ExpressionTrait.java @@ -0,0 +1,62 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +/** + * @since 4.2 + */ +interface ExpressionTrait extends NodeBuilder { + + default ExpressionNodeBuilder lt(NodeBuilder operand) { + return new ExpressionNodeBuilder(this).lt(operand); + } + + default ExpressionNodeBuilder gt(NodeBuilder operand) { + return new ExpressionNodeBuilder(this).gt(operand); + } + + default ExpressionNodeBuilder lte(NodeBuilder operand) { + return new ExpressionNodeBuilder(this).lte(operand); + } + + default ExpressionNodeBuilder gte(NodeBuilder operand) { + return new ExpressionNodeBuilder(this).gte(operand); + } + + default ExpressionNodeBuilder eq(NodeBuilder nodeBuilder) { + return new ExpressionNodeBuilder(this).eq(nodeBuilder); + } + + default ExpressionNodeBuilder plus(NodeBuilder nodeBuilder) { + return new ExpressionNodeBuilder(this).plus(nodeBuilder); + } + + default ExpressionNodeBuilder minus(NodeBuilder nodeBuilder) { + return new ExpressionNodeBuilder(this).minus(nodeBuilder); + } + + default ExpressionNodeBuilder mul(NodeBuilder nodeBuilder) { + return new ExpressionNodeBuilder(this).mul(nodeBuilder); + } + + default ExpressionNodeBuilder div(NodeBuilder nodeBuilder) { + return new ExpressionNodeBuilder(this).div(nodeBuilder); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/FunctionNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/FunctionNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/FunctionNodeBuilder.java new file mode 100644 index 0000000..030477d --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/FunctionNodeBuilder.java @@ -0,0 +1,56 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.FunctionNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; + +/** + * @since 4.2 + */ +public class FunctionNodeBuilder implements ExpressionTrait { + + private final String functionName; + private final NodeBuilder[] args; + + private String alias; + + FunctionNodeBuilder(String functionName, NodeBuilder... args) { + this.functionName = functionName; + this.args = args; + } + + public FunctionNodeBuilder as(String alias) { + this.alias = alias; + return this; + } + + @Override + public Node build() { + Node functionNode = new FunctionNode(functionName, alias, true); + + for(NodeBuilder arg : args) { + functionNode.addChild(arg.build()); + } + + return functionNode; + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/JoinNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/JoinNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/JoinNodeBuilder.java new file mode 100644 index 0000000..4ed7909 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/JoinNodeBuilder.java @@ -0,0 +1,54 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import java.util.Objects; + +import org.apache.cayenne.access.sqlbuilder.sqltree.JoinNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; + +/** + * @since 4.2 + */ +public class JoinNodeBuilder implements NodeBuilder { + + private final JoinType joinType; + private final NodeBuilder table; + + private NodeBuilder joinExp; + + JoinNodeBuilder(JoinType joinType, NodeBuilder table) { + this.joinType = Objects.requireNonNull(joinType); + this.table = Objects.requireNonNull(table); + } + + public JoinNodeBuilder on(NodeBuilder joinExp) { + this.joinExp = Objects.requireNonNull(joinExp); + return this; + } + + @Override + public Node build() { + Node node = new JoinNode(joinType); + node.addChild(table.build()); + node.addChild(joinExp.build()); + return node; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/JoinType.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/JoinType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/JoinType.java new file mode 100644 index 0000000..b862849 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/JoinType.java @@ -0,0 +1,39 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +/** + * @since 4.2 + */ +public enum JoinType { + INNER(" "), + LEFT(" LEFT "), + RIGHT(" RIGHT "), + OUTER(" FULL OUTER "); + + private final String name; + + JoinType(String name) { + this.name = name; + } + + public String getName() { + return name; + }} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/NodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/NodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/NodeBuilder.java new file mode 100644 index 0000000..21d2034 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/NodeBuilder.java @@ -0,0 +1,32 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; + +/** + * @since 4.2 + */ +@FunctionalInterface +public interface NodeBuilder { + + Node build(); + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/NodeTreeVisitor.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/NodeTreeVisitor.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/NodeTreeVisitor.java new file mode 100644 index 0000000..e1c01d1 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/NodeTreeVisitor.java @@ -0,0 +1,47 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; + +/** + * @since 4.2 + */ +public interface NodeTreeVisitor { + + /** + * @param node to visit + * @return false if visitor should stop + */ + boolean onNodeStart(Node node); + + /** + * @param parent node + * @param child node + * @param index of this child in parent + * @param hasMore true if more children after this child + * @return false if visitor should stop + */ + boolean onChildNodeStart(Node parent, Node child, int index, boolean hasMore); + + void onChildNodeEnd(Node parent, Node child, int index, boolean hasMore); + + void onNodeEnd(Node node); +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/OrderingNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/OrderingNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/OrderingNodeBuilder.java new file mode 100644 index 0000000..cfc84e8 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/OrderingNodeBuilder.java @@ -0,0 +1,56 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.EmptyNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; +import org.apache.cayenne.access.sqlbuilder.sqltree.TextNode; + +/** + * @since 4.2 + */ +public class OrderingNodeBuilder implements NodeBuilder { + + private final NodeBuilder column; + + private String direction = ""; + + OrderingNodeBuilder(NodeBuilder column) { + this.column = column; + } + + public OrderingNodeBuilder desc() { + direction = " DESC"; + return this; + } + + public OrderingNodeBuilder asc() { + direction = ""; + return this; + } + + @Override + public Node build() { + Node node = new EmptyNode(); + node.addChild(column.build()); + node.addChild(new TextNode(direction)); + return node; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/QuotingAppendable.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/QuotingAppendable.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/QuotingAppendable.java new file mode 100644 index 0000000..297cb63 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/QuotingAppendable.java @@ -0,0 +1,41 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +/** + * @since 4.2 + */ +public interface QuotingAppendable extends Appendable { + + @Override + QuotingAppendable append(CharSequence csq); + + @Override + QuotingAppendable append(CharSequence csq, int start, int end); + + @Override + QuotingAppendable append(char c); + + QuotingAppendable append(int i); + + QuotingAppendable appendQuoted(CharSequence csq); + + SQLGenerationContext getContext(); +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLBuilder.java new file mode 100644 index 0000000..0dcdfc1 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLBuilder.java @@ -0,0 +1,161 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.ColumnNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.FunctionNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; +import org.apache.cayenne.access.sqlbuilder.sqltree.NodeType; +import org.apache.cayenne.access.sqlbuilder.sqltree.SimpleNodeTreeVisitor; +import org.apache.cayenne.access.sqlbuilder.sqltree.TextNode; + +/** + * @since 4.2 + */ +public final class SQLBuilder { + + public static SelectBuilder select(NodeBuilder... params) { + return new SelectBuilder(params); + } + + public static TableNodeBuilder table(String table) { + return new TableNodeBuilder(table); + } + + public static ColumnNodeBuilder column(String column) { + return new ColumnNodeBuilder(null, column); + } + + public static JoinNodeBuilder join(NodeBuilder table) { + return new JoinNodeBuilder(JoinType.INNER, table); + } + + public static JoinNodeBuilder leftJoin(NodeBuilder table) { + return new JoinNodeBuilder(JoinType.LEFT, table); + } + + public static JoinNodeBuilder rightJoin(NodeBuilder table) { + return new JoinNodeBuilder(JoinType.RIGHT, table); + } + + public static JoinNodeBuilder innerJoin(NodeBuilder table) { + return new JoinNodeBuilder(JoinType.INNER, table); + } + + public static JoinNodeBuilder outerJoin(NodeBuilder table) { + return new JoinNodeBuilder(JoinType.OUTER, table); + } + + public static ExpressionNodeBuilder exists(NodeBuilder builder) { + return new ExpressionNodeBuilder(new ExistsNodeBuilder(builder)); + } + + public static ValueNodeBuilder value(Object value) { + return new ValueNodeBuilder(value); + } + + public static ExpressionNodeBuilder exp(NodeBuilder builder) { + return new ExpressionNodeBuilder(builder); + } + + public static NodeBuilder node(Node node) { + return () -> node; + } + + public static NodeBuilder aliased(NodeBuilder nodeBuilder, String alias) { + return new AliasedNodeBuilder(nodeBuilder, alias); + } + + public static NodeBuilder aliased(Node node, String alias) { + if(suppressAlias(node)) { + return node(node); + } + return new AliasedNodeBuilder(node(node), alias); + } + + public static NodeBuilder text(String text) { + return () -> new TextNode(text); + } + + public static NodeBuilder all() { + return text(" *"); + } + + public static ExpressionNodeBuilder not(NodeBuilder value) { + return new ExpressionNodeBuilder(value).not(); + } + + public static FunctionNodeBuilder count(NodeBuilder value) { + return function("COUNT", value); + } + + public static FunctionNodeBuilder count() { + return function("COUNT", column("*")); + } + + public static FunctionNodeBuilder avg(NodeBuilder value) { + return function("AVG", value); + } + + public static FunctionNodeBuilder min(NodeBuilder value) { + return function("MIN", value); + } + + public static FunctionNodeBuilder max(NodeBuilder value) { + return function("MAX", value); + } + + public static FunctionNodeBuilder function(String function, NodeBuilder... values) { + return new FunctionNodeBuilder(function, values); + } + + public static OrderingNodeBuilder order(NodeBuilder expression) { + return new OrderingNodeBuilder(expression); + } + + private SQLBuilder() { + } + + private static boolean suppressAlias(Node node) { + return new SuppressAliasChecker().shouldSuppressForNode(node); + } + + private static class SuppressAliasChecker extends SimpleNodeTreeVisitor { + + private boolean suppressAlias; + + public boolean shouldSuppressForNode(Node node) { + node.visit(this); + return suppressAlias; + } + + @Override + public boolean onNodeStart(Node node) { + if(node.getType() == NodeType.COLUMN && ((ColumnNode) node).getAlias() != null) { + suppressAlias = true; + return false; + } else if(node.getType() == NodeType.FUNCTION && ((FunctionNode) node).getAlias() != null) { + suppressAlias = true; + return false; + } + return true; + } + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLGenerationContext.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLGenerationContext.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLGenerationContext.java new file mode 100644 index 0000000..485fbbd --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLGenerationContext.java @@ -0,0 +1,35 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import java.util.Collection; + +import org.apache.cayenne.access.translator.DbAttributeBinding; +import org.apache.cayenne.dba.DbAdapter; + +/** + * @since 4.2 + */ +public interface SQLGenerationContext { + + DbAdapter getAdapter(); + + Collection<DbAttributeBinding> getBindings(); +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLGenerationVisitor.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLGenerationVisitor.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLGenerationVisitor.java new file mode 100644 index 0000000..156909a --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SQLGenerationVisitor.java @@ -0,0 +1,63 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; + +/** + * @since 4.2 + */ +public class SQLGenerationVisitor implements NodeTreeVisitor { + + private final QuotingAppendable appendable; + + public SQLGenerationVisitor(QuotingAppendable appendable) { + this.appendable = appendable; + } + + @Override + public boolean onNodeStart(Node node) { + node.append(appendable); + node.appendChildrenStart(appendable); + return true; + } + + @Override + public boolean onChildNodeStart(Node parent, Node child, int index, boolean hasMore) { + return true; + } + + @Override + public void onChildNodeEnd(Node parent, Node child, int index, boolean hasMore) { + if(hasMore && parent != null) { + parent.appendChildrenSeparator(appendable, index); + } + } + + @Override + public void onNodeEnd(Node node) { + node.appendChildrenEnd(appendable); + } + + public String getSQLString() { + return appendable.toString(); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SelectBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SelectBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SelectBuilder.java new file mode 100644 index 0000000..5c2a821 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/SelectBuilder.java @@ -0,0 +1,169 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import java.util.function.Supplier; + +import org.apache.cayenne.access.sqlbuilder.sqltree.DistinctNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.FromNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.GroupByNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.HavingNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.LimitOffsetNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; +import org.apache.cayenne.access.sqlbuilder.sqltree.OrderByNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.SelectNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.SelectResultNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.TopNode; +import org.apache.cayenne.access.sqlbuilder.sqltree.WhereNode; + +/** + * @since 4.2 + */ +public class SelectBuilder implements NodeBuilder { + + private static final int SELECT_NODE = 0; + private static final int FROM_NODE = 1; + private static final int WHERE_NODE = 2; + private static final int GROUPBY_NODE = 3; + private static final int HAVING_NODE = 4; + private static final int UNION_NODE = 5; + private static final int ORDERBY_NODE = 6; + private static final int LIMIT_NODE = 7; + + /** + * Main root of this query + */ + private Node root; + + /* + * Following nodes are all children of root, + * but we keep them here for quick access. + */ + private Node[] nodes = new Node[LIMIT_NODE + 1]; + + SelectBuilder(NodeBuilder... selectExpressions) { + root = new SelectNode(); + for(NodeBuilder exp : selectExpressions) { + node(SELECT_NODE, SelectResultNode::new).addChild(exp.build()); + } + } + + public SelectBuilder distinct() { + root.addChild(new DistinctNode()); + return this; + } + + public SelectBuilder top(int count) { + root.addChild(new TopNode(count)); + return this; + } + + public SelectBuilder result(NodeBuilder selectExpression) { + node(SELECT_NODE, SelectResultNode::new).addChild(selectExpression.build()); + return this; + } + + public SelectBuilder from(NodeBuilder table) { + node(FROM_NODE, FromNode::new).addChild(table.build()); + return this; + } + + public SelectBuilder from(NodeBuilder... tables) { + for(NodeBuilder next : tables) { + node(FROM_NODE, FromNode::new).addChild(next.build()); + } + return this; + } + + public SelectBuilder where(NodeBuilder... params) { + for(NodeBuilder next : params) { + node(WHERE_NODE, WhereNode::new).addChild(next.build()); + } + return this; + } + + public SelectBuilder where(Node node) { + node(WHERE_NODE, WhereNode::new).addChild(node); + return this; + } + + public SelectBuilder orderBy(NodeBuilder... params) { + for(NodeBuilder next : params) { + node(ORDERBY_NODE, OrderByNode::new).addChild(next.build()); + } + return this; + } + + public SelectBuilder orderBy(NodeBuilder param) { + node(ORDERBY_NODE, OrderByNode::new).addChild(param.build()); + return this; + } + + public SelectBuilder groupBy(NodeBuilder... params) { + for(NodeBuilder next : params) { + node(GROUPBY_NODE, GroupByNode::new).addChild(next.build()); + } + return this; + } + + public SelectBuilder groupBy(Node node) { + node(GROUPBY_NODE, GroupByNode::new).addChild(node); + return this; + } + + public SelectBuilder having(NodeBuilder... params) { + for(NodeBuilder next : params) { + node(HAVING_NODE, HavingNode::new).addChild(next.build()); + } + return this; + } + + public SelectBuilder having(Node node) { + node(HAVING_NODE, HavingNode::new).addChild(node); + return this; + } + + public SelectBuilder limitOffset(int limit, int offset) { + nodes[LIMIT_NODE] = new LimitOffsetNode(limit, offset); + return this; + } + + @Override + public Node build() { + for (Node next : nodes) { + if (next != null) { + root.addChild(next); + } + } + return root; + } + + public Node getRoot() { + return root; + } + + private Node node(int idx, Supplier<Node> nodeSupplier) { + if(nodes[idx] == null) { + nodes[idx] = nodeSupplier.get(); + } + return nodes[idx]; + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/StringBuilderAppendable.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/StringBuilderAppendable.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/StringBuilderAppendable.java new file mode 100644 index 0000000..e0f24f7 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/StringBuilderAppendable.java @@ -0,0 +1,76 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +/** + * @since 4.2 + */ +public class StringBuilderAppendable implements QuotingAppendable { + + protected final StringBuilder builder; + + public StringBuilderAppendable() { + this.builder = new StringBuilder(); + } + + @Override + public QuotingAppendable append(CharSequence csq) { + builder.append(csq); + return this; + } + + @Override + public QuotingAppendable append(CharSequence csq, int start, int end) { + builder.append(csq, start, end); + return this; + } + + @Override + public QuotingAppendable append(char c) { + builder.append(c); + return this; + } + + @Override + public QuotingAppendable append(int c) { + builder.append(c); + return this; + } + + @Override + public QuotingAppendable appendQuoted(CharSequence csq) { + builder.append(csq); + return this; + } + + @Override + public SQLGenerationContext getContext() { + return null; + } + + @Override + public String toString() { + return builder.toString(); + } + + public StringBuilder unwrap() { + return builder; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/TableNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/TableNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/TableNodeBuilder.java new file mode 100644 index 0000000..681b209 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/TableNodeBuilder.java @@ -0,0 +1,65 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; +import org.apache.cayenne.access.sqlbuilder.sqltree.TableNode; +import org.apache.cayenne.map.DbAttribute; + +/** + * @since 4.2 + */ +public class TableNodeBuilder implements NodeBuilder { + + private final String tableName; + + private String alias; + + TableNodeBuilder(String tableName) { + this.tableName = tableName; + } + + public TableNodeBuilder as(String alias) { + this.alias = alias; + return this; + } + + public ColumnNodeBuilder column(String column) { + return new ColumnNodeBuilder(tableName, column); + } + + public ColumnNodeBuilder column(DbAttribute attribute) { + return new ColumnNodeBuilder(tableName, attribute); + } + + public String getAlias() { + return alias; + } + + public String getTableName() { + return tableName; + } + + @Override + public Node build() { + return new TableNode(tableName, alias); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ValueNodeBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ValueNodeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ValueNodeBuilder.java new file mode 100644 index 0000000..5e027c6 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/ValueNodeBuilder.java @@ -0,0 +1,48 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder; + +import org.apache.cayenne.access.sqlbuilder.sqltree.Node; +import org.apache.cayenne.access.sqlbuilder.sqltree.ValueNode; +import org.apache.cayenne.map.DbAttribute; + +/** + * @since 4.2 + */ +public class ValueNodeBuilder implements NodeBuilder, ExpressionTrait { + + private final Object value; + + private DbAttribute attribute; + + ValueNodeBuilder(Object value) { + this.value = value; + } + + public ValueNodeBuilder attribute(DbAttribute attribute) { + this.attribute = attribute; + return this; + } + + @Override + public Node build() { + return new ValueNode(value, attribute); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BetweenNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BetweenNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BetweenNode.java new file mode 100644 index 0000000..1102a8a --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BetweenNode.java @@ -0,0 +1,52 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class BetweenNode extends ExpressionNode { + + private final boolean not; + + public BetweenNode(boolean not) { + this.not = not; + } + + @Override + public void appendChildrenSeparator(QuotingAppendable buffer, int childIdx) { + if (childIdx == 0) { + if (not) { + buffer.append(" NOT"); + } + buffer.append(" BETWEEN"); + } else { + buffer.append(" AND"); + } + } + + @Override + public Node copy() { + return new BetweenNode(not); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BitwiseNotNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BitwiseNotNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BitwiseNotNode.java new file mode 100644 index 0000000..8d14308 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BitwiseNotNode.java @@ -0,0 +1,38 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class BitwiseNotNode extends ExpressionNode { + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + return buffer.append('!'); + } + + @Override + public Node copy() { + return new BitwiseNotNode(); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ColumnNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ColumnNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ColumnNode.java new file mode 100644 index 0000000..b610104 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ColumnNode.java @@ -0,0 +1,76 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; +import org.apache.cayenne.map.DbAttribute; + +/** + * @since 4.2 + */ +public class ColumnNode extends Node { + + protected final String table; + protected final String column; + protected final String alias; + protected final DbAttribute attribute; + + public ColumnNode(String table, String column, String alias, DbAttribute attribute) { + super(NodeType.COLUMN); + this.table = table; + this.column = column; + this.alias = alias; + this.attribute = attribute; + } + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + buffer.append(' '); + if (table != null) { + buffer.appendQuoted(table).append('.'); + } + buffer.appendQuoted(column); + if (alias != null) { + buffer.append(' ').appendQuoted(alias); + } + return buffer; + } + + public String getTable() { + return table; + } + + public String getColumn() { + return column; + } + + public String getAlias() { + return alias; + } + + public DbAttribute getAttribute() { + return attribute; + } + + @Override + public Node copy() { + return new ColumnNode(table, column, alias, attribute); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/DistinctNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/DistinctNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/DistinctNode.java new file mode 100644 index 0000000..bf08c76 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/DistinctNode.java @@ -0,0 +1,43 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class DistinctNode extends Node { + + public DistinctNode() { + super(NodeType.DISTINCT); + } + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + return buffer.append(" DISTINCT"); + } + + @Override + public Node copy() { + return new DistinctNode(); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/EmptyNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/EmptyNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/EmptyNode.java new file mode 100644 index 0000000..1a01209 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/EmptyNode.java @@ -0,0 +1,43 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class EmptyNode extends Node { + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + return buffer; + } + + @Override + public String toString() { + return "EmptyNode"; + } + + @Override + public Node copy() { + return new EmptyNode(); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/EqualNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/EqualNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/EqualNode.java new file mode 100644 index 0000000..b158c63 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/EqualNode.java @@ -0,0 +1,43 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class EqualNode extends ExpressionNode { + + public EqualNode() { + super(NodeType.EQUALITY); + } + + @Override + public void appendChildrenSeparator(QuotingAppendable buffer, int childIdx) { + Node child = getChild(1); + if (child.getType() == NodeType.VALUE && ((ValueNode) child).getValue() == null) { + buffer.append(" IS NULL"); + } else { + buffer.append(" ="); + } + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExistsNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExistsNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExistsNode.java new file mode 100644 index 0000000..8322e0b --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExistsNode.java @@ -0,0 +1,38 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class ExistsNode extends Node { + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + return buffer.append(" EXISTS"); + } + + @Override + public Node copy() { + return new ExistsNode(); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExpressionNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExpressionNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExpressionNode.java new file mode 100644 index 0000000..8344380 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExpressionNode.java @@ -0,0 +1,65 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class ExpressionNode extends Node { + + public ExpressionNode() { + } + + public ExpressionNode(NodeType nodeType) { + super(nodeType); + } + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + return buffer; + } + + @Override + public void appendChildrenStart(QuotingAppendable buffer) { + if(parent.type != NodeType.WHERE && parent.type != NodeType.JOIN) { + buffer.append(" ("); + } + } + + @Override + public void appendChildrenEnd(QuotingAppendable buffer) { + if(parent.type != NodeType.WHERE && parent.type != NodeType.JOIN) { + buffer.append(" )"); + } + } + + @Override + public String toString() { + return "{ExpressionNode}"; + } + + @Override + public Node copy() { + return new ExpressionNode(); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/FromNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/FromNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/FromNode.java new file mode 100644 index 0000000..84d93ad --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/FromNode.java @@ -0,0 +1,43 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class FromNode extends Node { + + public FromNode() { + super(NodeType.FROM); + } + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + return buffer.append(" FROM"); + } + + @Override + public Node copy() { + return new FromNode(); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/FunctionNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/FunctionNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/FunctionNode.java new file mode 100644 index 0000000..23b0fa7 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/FunctionNode.java @@ -0,0 +1,127 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.NodeTreeVisitor; +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class FunctionNode extends Node { + + private final String functionName; + private final String alias; + private final boolean needParentheses; + + public FunctionNode(String functionName, String alias) { + this(functionName, alias, true); + } + + public FunctionNode(String functionName, String alias, boolean needParentheses) { + super(NodeType.FUNCTION); + this.functionName = functionName; + this.alias = alias; + this.needParentheses = needParentheses; + } + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + if(skipContent()) { + buffer.append(' ').append(alias); + } else { + buffer.append(' ').append(functionName); + } + return buffer; + } + + @Override + public void visit(NodeTreeVisitor visitor) { + if(skipContent()) { + visitor.onNodeStart(this); + visitor.onNodeEnd(this); + return; + } + super.visit(visitor); + } + + @Override + public void appendChildrenStart(QuotingAppendable buffer) { + if(skipContent()){ + return; + } + if (needParentheses) { + buffer.append('('); + } + } + + @Override + public void appendChildrenEnd(QuotingAppendable buffer) { + if(skipContent()){ + return; + } + + if (needParentheses) { + buffer.append(" )"); + } + + if (alias != null) { + buffer.append(" AS ").appendQuoted(alias); + } + } + + @Override + public void appendChildrenSeparator(QuotingAppendable buffer, int childIdx) { + if(skipContent()) { + return; + } + buffer.append(','); + } + + public String getFunctionName() { + return functionName; + } + + public String getAlias() { + return alias; + } + + @Override + public Node copy() { + return new FunctionNode(functionName, alias, needParentheses); + } + + private boolean notInResultNode() { + // check if parent is of type RESULT + Node parent = getParent(); + while(parent != null) { + if(parent.getType() == NodeType.RESULT) { + return false; + } + parent = parent.getParent(); + } + return true; + } + + protected boolean skipContent() { + // has alias and not in result node + return alias != null && notInResultNode(); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/GroupByNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/GroupByNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/GroupByNode.java new file mode 100644 index 0000000..382b7b8 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/GroupByNode.java @@ -0,0 +1,43 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class GroupByNode extends Node { + + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + return buffer.append(" GROUP BY"); + } + + @Override + public void appendChildrenSeparator(QuotingAppendable buffer, int childIdx) { + buffer.append(','); + } + + @Override + public Node copy() { + return new GroupByNode(); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/89439015/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/HavingNode.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/HavingNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/HavingNode.java new file mode 100644 index 0000000..c705c2e --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/HavingNode.java @@ -0,0 +1,37 @@ +/***************************************************************** + * 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.cayenne.access.sqlbuilder.sqltree; + +import org.apache.cayenne.access.sqlbuilder.QuotingAppendable; + +/** + * @since 4.2 + */ +public class HavingNode extends Node { + @Override + public QuotingAppendable append(QuotingAppendable buffer) { + return buffer.append(" HAVING"); + } + + @Override + public Node copy() { + return new HavingNode(); + } +}