From fda712c9caca1ec73045a74464a81a5e75d48ba1 Mon Sep 17 00:00:00 2001 From: Ravi Chodavarapu Date: Thu, 8 Sep 2016 00:03:30 +0100 Subject: [PATCH] Support adding order by to SQL queries --- .../datamill/db/ConjoinedOrderBuilder.java | 14 +++++++ .../stack/datamill/db/OrderBuilder.java | 9 +++++ .../stack/datamill/db/SelectLimitBuilder.java | 3 ++ .../stack/datamill/db/SelectWhereBuilder.java | 4 +- .../stack/datamill/db/WhereBuilder.java | 2 +- .../stack/datamill/db/impl/SqlSyntax.java | 3 ++ .../datamill/db/impl/WhereBuilderImpl.java | 39 ++++++++++++++++++- .../db/impl/QueryBuilderImplTest.java | 18 +++++++++ 8 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/foundation/stack/datamill/db/ConjoinedOrderBuilder.java create mode 100644 core/src/main/java/foundation/stack/datamill/db/OrderBuilder.java diff --git a/core/src/main/java/foundation/stack/datamill/db/ConjoinedOrderBuilder.java b/core/src/main/java/foundation/stack/datamill/db/ConjoinedOrderBuilder.java new file mode 100644 index 0000000..816cf6d --- /dev/null +++ b/core/src/main/java/foundation/stack/datamill/db/ConjoinedOrderBuilder.java @@ -0,0 +1,14 @@ +package foundation.stack.datamill.db; + +import foundation.stack.datamill.reflection.Member; + +/** + * @author Ravi Chodavarapu (rchodava@gmail.com) + */ +public interface ConjoinedOrderBuilder { + R all(); + R limit(int count); + R limit(int offset, int count); + OrderBuilder andOrderBy(String fragment); + OrderBuilder andOrderBy(Member member); +} diff --git a/core/src/main/java/foundation/stack/datamill/db/OrderBuilder.java b/core/src/main/java/foundation/stack/datamill/db/OrderBuilder.java new file mode 100644 index 0000000..58fc2aa --- /dev/null +++ b/core/src/main/java/foundation/stack/datamill/db/OrderBuilder.java @@ -0,0 +1,9 @@ +package foundation.stack.datamill.db; + +/** + * @author Ravi Chodavarapu (rchodava@gmail.com) + */ +public interface OrderBuilder { + ConjoinedOrderBuilder desc(); + ConjoinedOrderBuilder asc(); +} diff --git a/core/src/main/java/foundation/stack/datamill/db/SelectLimitBuilder.java b/core/src/main/java/foundation/stack/datamill/db/SelectLimitBuilder.java index a212dbe..811ca8a 100644 --- a/core/src/main/java/foundation/stack/datamill/db/SelectLimitBuilder.java +++ b/core/src/main/java/foundation/stack/datamill/db/SelectLimitBuilder.java @@ -1,10 +1,13 @@ package foundation.stack.datamill.db; import foundation.stack.datamill.LimitBuilder; +import foundation.stack.datamill.reflection.Member; /** * @author Ravi Chodavarapu (rchodava@gmail.com) */ public interface SelectLimitBuilder extends LimitBuilder { R limit(int offset, int count); + OrderBuilder orderBy(String fragment); + OrderBuilder orderBy(Member member); } diff --git a/core/src/main/java/foundation/stack/datamill/db/SelectWhereBuilder.java b/core/src/main/java/foundation/stack/datamill/db/SelectWhereBuilder.java index 16fc7a1..c274923 100644 --- a/core/src/main/java/foundation/stack/datamill/db/SelectWhereBuilder.java +++ b/core/src/main/java/foundation/stack/datamill/db/SelectWhereBuilder.java @@ -1,10 +1,12 @@ package foundation.stack.datamill.db; -import foundation.stack.datamill.reflection.Outline; +import foundation.stack.datamill.reflection.Member; /** * @author Ravi Chodavarapu (rchodava@gmail.com) */ public interface SelectWhereBuilder extends WhereBuilder> { R limit(int offset, int count); + OrderBuilder orderBy(String fragment); + OrderBuilder orderBy(Member member); } diff --git a/core/src/main/java/foundation/stack/datamill/db/WhereBuilder.java b/core/src/main/java/foundation/stack/datamill/db/WhereBuilder.java index c27ad1d..f633b4c 100644 --- a/core/src/main/java/foundation/stack/datamill/db/WhereBuilder.java +++ b/core/src/main/java/foundation/stack/datamill/db/WhereBuilder.java @@ -10,7 +10,7 @@ public interface WhereBuilder> { R all(); R limit(int count); - L where(Func1 conditionBuilder); JoinBuilder leftJoin(String table); JoinBuilder leftJoin(Outline outline); + L where(Func1 conditionBuilder); } diff --git a/core/src/main/java/foundation/stack/datamill/db/impl/SqlSyntax.java b/core/src/main/java/foundation/stack/datamill/db/impl/SqlSyntax.java index 72e3023..c362bbb 100644 --- a/core/src/main/java/foundation/stack/datamill/db/impl/SqlSyntax.java +++ b/core/src/main/java/foundation/stack/datamill/db/impl/SqlSyntax.java @@ -4,9 +4,11 @@ * @author Ravi Chodavarapu (rchodava@gmail.com) */ public interface SqlSyntax { + String SQL_ASC = " ASC"; String SQL_ASSIGNMENT = " = "; String SQL_DELETE_FROM = "DELETE FROM "; String SQL_DELETE = "DELETE "; + String SQL_DESC = " DESC"; String SQL_EQ = " = "; String SQL_FROM = " FROM "; String SQL_GREATER_THAN = " > "; @@ -26,6 +28,7 @@ public interface SqlSyntax { String SQL_AND = " AND "; String SQL_IN = " IN "; String SQL_OR = " OR "; + String SQL_ORDER_BY = " ORDER BY "; String OPEN_PARENTHESIS = "("; String CLOSE_PARENTHESIS = ")"; String COMMA = ","; diff --git a/core/src/main/java/foundation/stack/datamill/db/impl/WhereBuilderImpl.java b/core/src/main/java/foundation/stack/datamill/db/impl/WhereBuilderImpl.java index 2d0e5d4..4ccc279 100644 --- a/core/src/main/java/foundation/stack/datamill/db/impl/WhereBuilderImpl.java +++ b/core/src/main/java/foundation/stack/datamill/db/impl/WhereBuilderImpl.java @@ -14,7 +14,7 @@ * @author Ravi Chodavarapu (rchodava@gmail.com) */ abstract class WhereBuilderImpl implements SelectWhereBuilder, ConditionBuilder, ConjunctionBuilder, - JoinBuilder, SelectLimitBuilder { + JoinBuilder, SelectLimitBuilder, OrderBuilder, ConjoinedOrderBuilder { protected final StringBuilder query; protected final List parameters; @@ -87,6 +87,31 @@ public ConditionBuilder and() { return this; } + @Override + public OrderBuilder andOrderBy(String fragment) { + query.append(SqlSyntax.COMMA); + query.append(' '); + query.append(fragment); + return this; + } + + @Override + public OrderBuilder andOrderBy(Member member) { + return andOrderBy(SqlSyntax.qualifiedName(member.outline().pluralName(), member.name())); + } + + @Override + public ConjoinedOrderBuilder asc() { + query.append(SqlSyntax.SQL_ASC); + return this; + } + + @Override + public ConjoinedOrderBuilder desc() { + query.append(SqlSyntax.SQL_DESC); + return this; + } + @Override public TerminalCondition or( Func1 left, @@ -244,6 +269,18 @@ public SelectWhereBuilder onEq(String table1, String column1, Member member2) return onEq(table1, column1, member2.outline().pluralName(), member2.name()); } + @Override + public OrderBuilder orderBy(String fragment) { + query.append(SqlSyntax.SQL_ORDER_BY); + query.append(fragment); + return this; + } + + @Override + public OrderBuilder orderBy(Member member) { + return orderBy(SqlSyntax.qualifiedName(member.outline().pluralName(), member.name())); + } + @Override public SelectLimitBuilder where(Func1 conditionBuilder) { query.append(SqlSyntax.SQL_WHERE); diff --git a/core/src/test/java/foundation/stack/datamill/db/impl/QueryBuilderImplTest.java b/core/src/test/java/foundation/stack/datamill/db/impl/QueryBuilderImplTest.java index d80cd3b..9d30aec 100644 --- a/core/src/test/java/foundation/stack/datamill/db/impl/QueryBuilderImplTest.java +++ b/core/src/test/java/foundation/stack/datamill/db/impl/QueryBuilderImplTest.java @@ -118,6 +118,14 @@ public void selectQueries() { assertEquals("SELECT * FROM table_name LIMIT 10, 20", queryBuilder.getLastQuery()); assertFalse(queryBuilder.getLastWasUpdate()); + queryBuilder.selectAll().from("table_name").orderBy("column").asc().limit(1); + assertEquals("SELECT * FROM table_name ORDER BY column ASC LIMIT 1", queryBuilder.getLastQuery()); + assertFalse(queryBuilder.getLastWasUpdate()); + + queryBuilder.selectAll().from("table_name").orderBy("column").asc().andOrderBy("column2").desc().limit(1); + assertEquals("SELECT * FROM table_name ORDER BY column ASC, column2 DESC LIMIT 1", queryBuilder.getLastQuery()); + assertFalse(queryBuilder.getLastWasUpdate()); + queryBuilder.selectAll().from(outline).all(); assertEquals("SELECT * FROM query_test_beans", queryBuilder.getLastQuery()); assertFalse(queryBuilder.getLastWasUpdate()); @@ -127,6 +135,11 @@ public void selectQueries() { assertArrayEquals(new Object[] { 2 }, queryBuilder.getLastParameters()); assertFalse(queryBuilder.getLastWasUpdate()); + queryBuilder.selectAll().from("table_name").where(c -> c.eq("int_column", 2)).orderBy("int_column").asc().all(); + assertEquals("SELECT * FROM table_name WHERE int_column = ? ORDER BY int_column ASC", queryBuilder.getLastQuery()); + assertArrayEquals(new Object[] { 2 }, queryBuilder.getLastParameters()); + assertFalse(queryBuilder.getLastWasUpdate()); + queryBuilder.selectAll().from("table_name").where(c -> c.eq("int_column", 2)).limit(1); assertEquals("SELECT * FROM table_name WHERE int_column = ? LIMIT 1", queryBuilder.getLastQuery()); assertArrayEquals(new Object[] { 2 }, queryBuilder.getLastParameters()); @@ -137,6 +150,11 @@ public void selectQueries() { assertArrayEquals(new Object[] { 2 }, queryBuilder.getLastParameters()); assertFalse(queryBuilder.getLastWasUpdate()); + queryBuilder.selectAll().from("table_name").where(c -> c.eq("int_column", 2)).orderBy("int_column").desc().limit(10, 20); + assertEquals("SELECT * FROM table_name WHERE int_column = ? ORDER BY int_column DESC LIMIT 10, 20", queryBuilder.getLastQuery()); + assertArrayEquals(new Object[] { 2 }, queryBuilder.getLastParameters()); + assertFalse(queryBuilder.getLastWasUpdate()); + queryBuilder.selectAll().from("table_name").where(c -> c.eq(outline.member(m -> m.getId()), 2)).all(); assertEquals("SELECT * FROM table_name WHERE query_test_beans.id = ?", queryBuilder.getLastQuery()); assertArrayEquals(new Object[] { 2 }, queryBuilder.getLastParameters());