From 85dede86f053a613dcf3ee8fe74ffaab977c523f Mon Sep 17 00:00:00 2001 From: wea_ondara Date: Thu, 14 Jul 2022 21:54:23 +0200 Subject: [PATCH] added limits --- src/main/java/jef/Queryable.java | 15 +++--- src/main/java/jef/expressions/Expression.java | 1 + .../java/jef/expressions/LimitExpression.java | 34 +++++++++++++ .../modifier/ExpressionModifier.java | 6 +++ .../visitors/DebugExpressionVisitor.java | 13 +++++ .../visitors/ExpressionVisitor.java | 6 +++ src/main/java/jef/operations/LimitOp.java | 49 +++++++++++++++++++ src/test/java/jef/operations/LimitOpTest.java | 34 +++++++++++++ 8 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 src/main/java/jef/expressions/LimitExpression.java create mode 100644 src/main/java/jef/operations/LimitOp.java create mode 100644 src/test/java/jef/operations/LimitOpTest.java diff --git a/src/main/java/jef/Queryable.java b/src/main/java/jef/Queryable.java index deac561..1e3df62 100644 --- a/src/main/java/jef/Queryable.java +++ b/src/main/java/jef/Queryable.java @@ -3,6 +3,7 @@ package jef; import jef.expressions.Expression; import jef.operations.CountOp; import jef.operations.FilterOp; +import jef.operations.LimitOp; import jef.serializable.SerializablePredicate; import java.io.Serializable; @@ -104,13 +105,13 @@ public interface Queryable { // return null; // } // -// default Queryable limit(long l) { -// return null; -// } -// -// default Queryable skip(long l) { -// return null; -// } + default Queryable limit(long l) { + return new LimitOp<>(this, null, l); + } + + default Queryable skip(long l) { + return new LimitOp<>(this, l, null); + } // // default void forEach(Consumer consumer) { diff --git a/src/main/java/jef/expressions/Expression.java b/src/main/java/jef/expressions/Expression.java index df071d6..2f11dd5 100644 --- a/src/main/java/jef/expressions/Expression.java +++ b/src/main/java/jef/expressions/Expression.java @@ -14,6 +14,7 @@ public interface Expression { CONSTANT, FIELD, INTERMEDIATE_FIELD, + LIMIT, NULL, OR, PARAMETER, diff --git a/src/main/java/jef/expressions/LimitExpression.java b/src/main/java/jef/expressions/LimitExpression.java new file mode 100644 index 0000000..0977ee3 --- /dev/null +++ b/src/main/java/jef/expressions/LimitExpression.java @@ -0,0 +1,34 @@ +package jef.expressions; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class LimitExpression implements Expression { + private final Expression expr; + private final Long start; + private final Long count; + + @Override + public Type getType() { + return Type.LIMIT; + } + + @Override + public Priority getPriority() { + return Priority.UNDEFINED; + } + + @Override + public String toString() { + var ret = expr.toString(); + if (count != null) { + ret += " LIMIT " + count; + } + if (start != null) { + ret += " OFFSET " + start; + } + return ret; + } +} diff --git a/src/main/java/jef/expressions/modifier/ExpressionModifier.java b/src/main/java/jef/expressions/modifier/ExpressionModifier.java index 1ed11b7..1a38749 100644 --- a/src/main/java/jef/expressions/modifier/ExpressionModifier.java +++ b/src/main/java/jef/expressions/modifier/ExpressionModifier.java @@ -6,6 +6,7 @@ import jef.expressions.ConstantExpression; import jef.expressions.Expression; import jef.expressions.FieldExpression; import jef.expressions.IntermediateFieldExpression; +import jef.expressions.LimitExpression; import jef.expressions.NullExpression; import jef.expressions.OrExpression; import jef.expressions.ParameterExpression; @@ -27,6 +28,7 @@ public abstract class ExpressionModifier { case CONSTANT -> modifyConstant((ConstantExpression) expr); case FIELD -> modifyField((FieldExpression) expr); case INTERMEDIATE_FIELD -> modifyIntermediateField((IntermediateFieldExpression) expr); + case LIMIT -> modifyLimit((LimitExpression) expr); case NULL -> modifyNull((NullExpression) expr); case OR -> modifyOr((OrExpression) expr); case PARAMETER -> modifyParameter((ParameterExpression) expr); @@ -63,6 +65,10 @@ public abstract class ExpressionModifier { return expr; } + public Expression modifyLimit(LimitExpression expr) { + return new LimitExpression(modify(expr.getExpr()), expr.getStart(), expr.getCount()); + } + public Expression modifyNull(NullExpression expr) { return expr; } diff --git a/src/main/java/jef/expressions/visitors/DebugExpressionVisitor.java b/src/main/java/jef/expressions/visitors/DebugExpressionVisitor.java index c911b24..2d340b0 100644 --- a/src/main/java/jef/expressions/visitors/DebugExpressionVisitor.java +++ b/src/main/java/jef/expressions/visitors/DebugExpressionVisitor.java @@ -5,6 +5,7 @@ import jef.expressions.BinaryExpression; import jef.expressions.ConstantExpression; import jef.expressions.FieldExpression; import jef.expressions.IntermediateFieldExpression; +import jef.expressions.LimitExpression; import jef.expressions.NullExpression; import jef.expressions.OrExpression; import jef.expressions.ParameterExpression; @@ -58,6 +59,18 @@ public class DebugExpressionVisitor extends ExpressionVisitor { System.out.println(i() + expr.toString()); } + public void visitLimit(LimitExpression expr) { + visit(expr.getExpr()); + var s = ""; + if (expr.getCount() != null) { + s += " LIMIT " + expr.getCount(); + } + if (expr.getStart() != null) { + s += " OFFSET " + expr.getStart(); + } + System.out.println(i() + s); + } + @Override public void visitNull(NullExpression expr) { System.out.println(i() + expr.toString()); diff --git a/src/main/java/jef/expressions/visitors/ExpressionVisitor.java b/src/main/java/jef/expressions/visitors/ExpressionVisitor.java index 25b41e1..db20fdf 100644 --- a/src/main/java/jef/expressions/visitors/ExpressionVisitor.java +++ b/src/main/java/jef/expressions/visitors/ExpressionVisitor.java @@ -6,6 +6,7 @@ import jef.expressions.ConstantExpression; import jef.expressions.Expression; import jef.expressions.FieldExpression; import jef.expressions.IntermediateFieldExpression; +import jef.expressions.LimitExpression; import jef.expressions.NullExpression; import jef.expressions.OrExpression; import jef.expressions.ParameterExpression; @@ -23,6 +24,7 @@ public abstract class ExpressionVisitor { case CONSTANT -> visitConstant((ConstantExpression) expr); case FIELD -> visitField((FieldExpression) expr); case INTERMEDIATE_FIELD -> visitIntermediateField((IntermediateFieldExpression) expr); + case LIMIT -> visitLimit((LimitExpression) expr); case NULL -> visitNull((NullExpression) expr); case OR -> visitOr((OrExpression) expr); case PARAMETER -> visitParameter((ParameterExpression) expr); @@ -55,6 +57,10 @@ public abstract class ExpressionVisitor { public void visitIntermediateField(IntermediateFieldExpression expr) { } + public void visitLimit(LimitExpression expr) { + visit(expr.getExpr()); + } + public void visitNull(NullExpression expr) { } diff --git a/src/main/java/jef/operations/LimitOp.java b/src/main/java/jef/operations/LimitOp.java new file mode 100644 index 0000000..680aadc --- /dev/null +++ b/src/main/java/jef/operations/LimitOp.java @@ -0,0 +1,49 @@ +package jef.operations; + +import jef.Queryable; +import jef.expressions.Expression; +import jef.expressions.LimitExpression; +import jef.expressions.SelectExpression; +import jef.expressions.selectable.DatabaseSelectAllExpression; + +import java.io.Serializable; +import java.util.List; + +public class LimitOp implements Queryable { + private final Queryable queryable; + private Long start; + private Long count; + + public LimitOp(Queryable queryable, Long start, Long count) { + this.queryable = queryable; + this.start = start; + this.count = count; + } + + @Override + public String getTableAlias() { + return String.valueOf((char) (queryable.getTableAlias().charAt(0) + (char) 1)); + } + + @Override + public Expression getExpression() { + return new LimitExpression(new SelectExpression(List.of(new DatabaseSelectAllExpression()), queryable.getExpression(), getTableAlias()), start, count); + } + + @Override + public String toString() { + return getExpression().toString(); + } + + @Override + public Queryable limit(long l) { + count = l; + return this; + } + + @Override + public Queryable skip(long l) { + start = l; + return this; + } +} diff --git a/src/test/java/jef/operations/LimitOpTest.java b/src/test/java/jef/operations/LimitOpTest.java new file mode 100644 index 0000000..83c8ea7 --- /dev/null +++ b/src/test/java/jef/operations/LimitOpTest.java @@ -0,0 +1,34 @@ +package jef.operations; + +import jef.DBSet; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class LimitOpTest { + @Test + public void test() { + String act; + act = new DBSet("table1") + .limit(10).skip(5) + .toString(); + Assertions.assertEquals("SELECT * FROM (SELECT * FROM `table1`) a LIMIT 10 OFFSET 5", act); + + + act = new DBSet("table1") + .skip(5).limit(10) + .toString(); + Assertions.assertEquals("SELECT * FROM (SELECT * FROM `table1`) a LIMIT 10 OFFSET 5", act); + + + act = new DBSet("table1") + .skip(5) + .toString(); + Assertions.assertEquals("SELECT * FROM (SELECT * FROM `table1`) a OFFSET 5", act); + + + act = new DBSet("table1") + .limit(10) + .toString(); + Assertions.assertEquals("SELECT * FROM (SELECT * FROM `table1`) a LIMIT 10", act); + } +} \ No newline at end of file