commit 9f2d00619a285d3f6dfde643bad8f4fb10735403 Author: Ruslan Penkrat Date: Fri Jul 26 23:15:47 2019 +0300 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2dd717a --- /dev/null +++ b/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + + com.github.russ-p + sqlbuilder + 0.0.1-SNAPSHOT + jar + + sqlbuilder + http://maven.apache.org + + + UTF-8 + 1.8 + + + + + junit + junit + 4.12 + test + + + com.h2database + h2 + 1.4.194 + test + + + diff --git a/src/main/java/com/github/russ_p/sqlbuilder/Sql.java b/src/main/java/com/github/russ_p/sqlbuilder/Sql.java new file mode 100644 index 0000000..3fc8ebf --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/Sql.java @@ -0,0 +1,11 @@ +package com.github.russ_p.sqlbuilder; + +import com.github.russ_p.sqlbuilder.select.SelectQueryBuilder; + +public class Sql { + + public static SelectQueryBuilder select() { + return new SelectQueryBuilder(); + } + +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/AbstractQueryBuilder.java b/src/main/java/com/github/russ_p/sqlbuilder/select/AbstractQueryBuilder.java new file mode 100644 index 0000000..e0c7e07 --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/AbstractQueryBuilder.java @@ -0,0 +1,16 @@ +package com.github.russ_p.sqlbuilder.select; + +abstract class AbstractQueryBuilder { + + protected final T query; + + public AbstractQueryBuilder(T query) { + this.query = query; + } + + @Override + public String toString() { + return query.toString(); + } + +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/FromBuilder.java b/src/main/java/com/github/russ_p/sqlbuilder/select/FromBuilder.java new file mode 100644 index 0000000..60e3884 --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/FromBuilder.java @@ -0,0 +1,37 @@ +package com.github.russ_p.sqlbuilder.select; + +public class FromBuilder extends AbstractQueryBuilder { + + FromBuilder(SelectQuery query, String table) { + super(query); + query.addTable(table); + } + + public WhereBuilder where() { + return new WhereBuilder(query); + } + + public WhereBuilder where(String condition) { + return new WhereBuilder(query, condition); + } + + public JoinBuilder join(String table) { + return innerJoin(table); + } + + public JoinBuilder innerJoin(String table) { + return new JoinBuilder(query, "inner", table); + } + + public JoinBuilder leftJoin(String table) { + return new JoinBuilder(query, "left", table); + } + + public JoinBuilder rightJoin(String table) { + return new JoinBuilder(query, "right", table); + } + + public JoinBuilder crossJoin(String table) { + return new JoinBuilder(query, "cross", table); + } +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/GroupByBuilder.java b/src/main/java/com/github/russ_p/sqlbuilder/select/GroupByBuilder.java new file mode 100644 index 0000000..13dce35 --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/GroupByBuilder.java @@ -0,0 +1,16 @@ +package com.github.russ_p.sqlbuilder.select; + +public class GroupByBuilder extends AbstractQueryBuilder { + + GroupByBuilder(SelectQuery query, String[] columns) { + super(query); + for (String column : columns) { + query.addGroup(column); + } + } + + public OrderByBuilder orderBy(String... columns) { + return new OrderByBuilder(query, columns); + } + +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/JoinBuilder.java b/src/main/java/com/github/russ_p/sqlbuilder/select/JoinBuilder.java new file mode 100644 index 0000000..5b707cc --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/JoinBuilder.java @@ -0,0 +1,14 @@ +package com.github.russ_p.sqlbuilder.select; + +public class JoinBuilder extends AbstractQueryBuilder { + + public JoinBuilder(SelectQuery query, String joinType, String table) { + super(query); + query.addJoin("\n " + joinType.toUpperCase() + " JOIN " + table); + } + + public JoinConditionBuilder on(String condition) { + return new JoinConditionBuilder(query, condition); + } + +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/JoinConditionBuilder.java b/src/main/java/com/github/russ_p/sqlbuilder/select/JoinConditionBuilder.java new file mode 100644 index 0000000..e4ea0f3 --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/JoinConditionBuilder.java @@ -0,0 +1,33 @@ +package com.github.russ_p.sqlbuilder.select; + +public class JoinConditionBuilder extends AbstractQueryBuilder { + + public JoinConditionBuilder(SelectQuery query, String condition) { + super(query); + query.addJoinCondition(condition); + } + + public WhereBuilder where(String condition) { + return new WhereBuilder(query, condition); + } + + public JoinBuilder join(String table) { + return innerJoin(table); + } + + public JoinBuilder innerJoin(String table) { + return new JoinBuilder(query, "inner", table); + } + + public JoinBuilder leftJoin(String table) { + return new JoinBuilder(query, "left", table); + } + + public JoinBuilder rightJoin(String table) { + return new JoinBuilder(query, "right", table); + } + + public JoinBuilder crossJoin(String table) { + return new JoinBuilder(query, "cross", table); + } +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/OrderByBuilder.java b/src/main/java/com/github/russ_p/sqlbuilder/select/OrderByBuilder.java new file mode 100644 index 0000000..799fd3e --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/OrderByBuilder.java @@ -0,0 +1,26 @@ +package com.github.russ_p.sqlbuilder.select; + +public class OrderByBuilder extends AbstractQueryBuilder { + + OrderByBuilder(SelectQuery query) { + super(query); + } + + public OrderByBuilder(SelectQuery query, String... columns) { + super(query); + for (String column : columns) { + query.addOrder(column); + } + } + + public OrderByBuilder by(String column) { + query.addOrder(column); + return this; + } + + public OrderByBuilder desc() { + query.setOrderDesc(); + return this; + } + +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/SelectQuery.java b/src/main/java/com/github/russ_p/sqlbuilder/select/SelectQuery.java new file mode 100644 index 0000000..79d016b --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/SelectQuery.java @@ -0,0 +1,101 @@ +package com.github.russ_p.sqlbuilder.select; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; +import java.util.stream.Collectors; + +class SelectQuery { + + private final Deque columns = new ArrayDeque<>(); + + private final List tables = new ArrayList<>(); + + private final List whereParts = new ArrayList<>(); + + private final Deque orderBy = new ArrayDeque<>(); + + private final List groupBy = new ArrayList<>(); + + private final List join = new ArrayList<>(); + + public void addColumn(String columnName) { + columns.add(columnName); + } + + public void addColumn(String columnName, String alias) { + columns.add(columnName + " AS " + alias); + } + + public void addColumnAlias(String alias) { + String col = columns.pollLast(); + if (col != null) { + addColumn(col, alias); + } + } + + public void addTable(String tableName) { + tables.add(tableName); + } + + public void addCondition(String condition) { + whereParts.add(condition); + } + + public void addAndCondition(String condition) { + whereParts.add(" AND\n " + condition); + } + + public void addOrder(String columnName) { + orderBy.add(columnName); + } + + public void setOrderDesc() { + String col = orderBy.pollLast(); + orderBy.add(col + " DESC"); + } + + public void addGroup(String columnName) { + groupBy.add(columnName); + } + + public void addJoin(String joinStr) { + join.add(joinStr); + } + + public void addJoinCondition(String condition) { + int lastIndex = join.size() - 1; + String s = join.get(lastIndex) + " ON " + condition; + join.set(lastIndex, s); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("SELECT\n "); + sb.append(columns.stream().collect(Collectors.joining(",\n "))); + + sb.append("\nFROM\n "); + sb.append(tables.stream().collect(Collectors.joining(", "))); + + if (!join.isEmpty()) { + sb.append(join.stream().collect(Collectors.joining("\n "))); + } + + sb.append("\nWHERE\n "); + sb.append(whereParts.stream().collect(Collectors.joining("\n "))); + + if (!groupBy.isEmpty()) { + sb.append("\nGROUP BY\n "); + sb.append(groupBy.stream().collect(Collectors.joining(", "))); + } + + if (!orderBy.isEmpty()) { + sb.append("\nORDER BY "); + sb.append(orderBy.stream().collect(Collectors.joining(", "))); + } + + return sb.toString(); + } + +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/SelectQueryBuilder.java b/src/main/java/com/github/russ_p/sqlbuilder/select/SelectQueryBuilder.java new file mode 100644 index 0000000..da332bd --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/SelectQueryBuilder.java @@ -0,0 +1,27 @@ +package com.github.russ_p.sqlbuilder.select; + +public class SelectQueryBuilder extends AbstractQueryBuilder { + + public SelectQueryBuilder() { + super(new SelectQuery()); + } + + public SelectQueryBuilder column(String columnName) { + query.addColumn(columnName); + return this; + } + + public SelectQueryBuilder as(String alias) { + query.addColumnAlias(alias); + return this; + } + + public FromBuilder from(String table) { + return new FromBuilder(query, table); + } + + @Override + public String toString() { + return query.toString(); + } +} diff --git a/src/main/java/com/github/russ_p/sqlbuilder/select/WhereBuilder.java b/src/main/java/com/github/russ_p/sqlbuilder/select/WhereBuilder.java new file mode 100644 index 0000000..daa7515 --- /dev/null +++ b/src/main/java/com/github/russ_p/sqlbuilder/select/WhereBuilder.java @@ -0,0 +1,27 @@ +package com.github.russ_p.sqlbuilder.select; + +public class WhereBuilder extends AbstractQueryBuilder { + + WhereBuilder(SelectQuery query) { + super(query); + } + + WhereBuilder(SelectQuery query, String condition) { + this(query); + query.addCondition(condition); + } + + public WhereBuilder and(String condition) { + query.addAndCondition(condition); + return this; + } + + public OrderByBuilder orderBy(String... columns) { + return new OrderByBuilder(query, columns); + } + + public GroupByBuilder groupBy(String... columns) { + return new GroupByBuilder(query, columns); + } + +} diff --git a/src/test/java/com/github/russ_p/sqlbuilder/SqlTest.java b/src/test/java/com/github/russ_p/sqlbuilder/SqlTest.java new file mode 100644 index 0000000..2555bf5 --- /dev/null +++ b/src/test/java/com/github/russ_p/sqlbuilder/SqlTest.java @@ -0,0 +1,74 @@ +package com.github.russ_p.sqlbuilder; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SqlTest { + + private static Connection conn; + + @Before + public void setUp() throws Exception { + } + + @BeforeClass + public static void start() throws SQLException { + conn = DriverManager.getConnection("jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1", "sa", ""); + + conn.createStatement().execute("CREATE TABLE `test_table` (\n" + + " `id` bigint(20) NOT NULL AUTO_INCREMENT,\n" + + " `code` varchar(255) DEFAULT NULL\n" + + ")"); + + conn.createStatement().execute("CREATE TABLE `another_table` (\n" + + " `id` bigint(20) NOT NULL AUTO_INCREMENT,\n" + + " `test_id` bigint(20),\n" + + " `code` varchar(255) DEFAULT NULL\n" + + ")"); + } + + @AfterClass + public static void finish() throws SQLException { + conn.close(); + } + + @Test + public void testSelect() throws Exception { + String sql = Sql.select() + .column("id").as("col_id") + .column("code").as("col_code") + .from("test_table") + .where("id = 1") + .groupBy("id") + .orderBy("id").by("code").desc() + .toString(); + + conn.createStatement().execute(sql); + + System.out.println(sql); + } + + @Test + public void testSelectWithJoin() throws Exception { + String sql = Sql.select() + .column("t1.id").as("col_id") + .column("t1.code").as("col_code") + .from("test_table t1") + .join("another_table t2").on("t2.test_id = t1.id") + .where("t1.id = 1").and("t2.id = 1") + .groupBy("t1.id") + .orderBy("t1.id").by("t1.code").desc() + .toString(); + + conn.createStatement().execute(sql); + + System.out.println(sql); + } + +}