-
-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
237 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
core/datacap-parser/src/main/java/io/edurt/datacap/sql/formatter/ExpressionFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package io.edurt.datacap.sql.formatter; | ||
|
||
import io.edurt.datacap.sql.node.Expression; | ||
|
||
import static io.edurt.datacap.sql.formatter.SQLFormatter.INDENT; | ||
|
||
public class ExpressionFormatter | ||
{ | ||
public ExpressionFormatter() | ||
{} | ||
|
||
public static String formatExpression(Expression expr, int depth) | ||
{ | ||
if (expr == null) { | ||
return "null"; | ||
} | ||
|
||
StringBuilder sb = new StringBuilder(); | ||
String currentIndent = INDENT.repeat(depth); | ||
|
||
// Start expression with current depth indentation | ||
sb.append(currentIndent).append("Expression {\n"); | ||
|
||
// Content should be indented one more level | ||
String contentIndent = INDENT.repeat(depth + 1); | ||
sb.append(contentIndent).append("type: ").append(expr.getType()).append(",\n"); | ||
sb.append(contentIndent).append("value: \"").append(expr.getValue()).append("\""); | ||
|
||
if (expr.getChildren() != null && !expr.getChildren().isEmpty()) { | ||
sb.append(",\n"); | ||
sb.append(contentIndent).append("children: [\n"); | ||
|
||
for (int i = 0; i < expr.getChildren().size(); i++) { | ||
Expression child = expr.getChildren().get(i); | ||
// Children should be indented one more level than the children array | ||
sb.append(formatExpression(child, depth + 2)); | ||
|
||
if (i < expr.getChildren().size() - 1) { | ||
sb.append(","); | ||
} | ||
sb.append("\n"); | ||
} | ||
|
||
sb.append(contentIndent).append("]"); | ||
} | ||
|
||
sb.append("\n").append(currentIndent).append("}"); | ||
return sb.toString(); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
core/datacap-parser/src/main/java/io/edurt/datacap/sql/formatter/SQLFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package io.edurt.datacap.sql.formatter; | ||
|
||
import io.edurt.datacap.sql.statement.SQLStatement; | ||
import io.edurt.datacap.sql.statement.SelectStatement; | ||
|
||
public abstract class SQLFormatter | ||
{ | ||
protected static final String INDENT = " "; | ||
|
||
public String format(SQLStatement statement) | ||
{ | ||
if (statement instanceof SelectStatement) { | ||
return new SelectFormatter().format(statement); | ||
} | ||
else { | ||
throw new UnsupportedOperationException("Unsupported statement: " + statement); | ||
} | ||
} | ||
} |
124 changes: 124 additions & 0 deletions
124
core/datacap-parser/src/main/java/io/edurt/datacap/sql/formatter/SelectFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package io.edurt.datacap.sql.formatter; | ||
|
||
import io.edurt.datacap.sql.node.Expression; | ||
import io.edurt.datacap.sql.node.clause.LimitClause; | ||
import io.edurt.datacap.sql.node.element.OrderByElement; | ||
import io.edurt.datacap.sql.node.element.SelectElement; | ||
import io.edurt.datacap.sql.node.element.TableElement; | ||
import io.edurt.datacap.sql.statement.SQLStatement; | ||
import io.edurt.datacap.sql.statement.SelectStatement; | ||
|
||
import static io.edurt.datacap.sql.formatter.ExpressionFormatter.formatExpression; | ||
|
||
public class SelectFormatter | ||
extends SQLFormatter | ||
{ | ||
@Override | ||
public String format(SQLStatement statement) | ||
{ | ||
if (statement == null) { | ||
return "null"; | ||
} | ||
|
||
SelectStatement selectStatement = (SelectStatement) statement; | ||
|
||
StringBuilder sb = new StringBuilder(); | ||
String indent = INDENT; | ||
|
||
sb.append("SelectStatement {\n"); | ||
|
||
// Format SELECT elements | ||
if (selectStatement.getSelectElements() != null && !selectStatement.getSelectElements().isEmpty()) { | ||
sb.append(indent).append("selectElements: [\n"); | ||
for (SelectElement element : selectStatement.getSelectElements()) { | ||
sb.append(indent).append(INDENT).append("SelectElement {\n"); | ||
if (element.getColumn() != null) { | ||
sb.append(indent).append(INDENT).append(INDENT).append("column: \"").append(element.getColumn()).append("\",\n"); | ||
} | ||
if (element.getAlias() != null) { | ||
sb.append(indent).append(INDENT).append(INDENT).append("alias: \"").append(element.getAlias()).append("\",\n"); | ||
} | ||
if (element.getExpression() != null) { | ||
sb.append(indent).append(INDENT).append(INDENT).append("expression: "); | ||
// 移除前面的换行,并调整缩进级别 | ||
String expressionStr = formatExpression(element.getExpression(), 4); | ||
sb.append(expressionStr.trim()).append(",\n"); | ||
} | ||
sb.append(indent).append(INDENT).append("},\n"); | ||
} | ||
sb.append(indent).append("],\n"); | ||
} | ||
|
||
// Format FROM sources | ||
if (selectStatement.getFromSources() != null && !selectStatement.getFromSources().isEmpty()) { | ||
sb.append(indent).append("fromSources: [\n"); | ||
for (TableElement table : selectStatement.getFromSources()) { | ||
sb.append(indent).append(INDENT).append("TableElement {\n"); | ||
if (table.getTableName() != null) { | ||
sb.append(indent).append(INDENT).append(INDENT).append("tableName: \"").append(table.getTableName()).append("\",\n"); | ||
} | ||
if (table.getAlias() != null) { | ||
sb.append(indent).append(INDENT).append(INDENT).append("alias: \"").append(table.getAlias()).append("\",\n"); | ||
} | ||
if (table.getSubquery() != null) { | ||
sb.append(indent).append(INDENT).append(INDENT).append("subquery: {...},\n"); | ||
} | ||
sb.append(indent).append(INDENT).append("},\n"); | ||
} | ||
sb.append(indent).append("],\n"); | ||
} | ||
|
||
// Format WHERE clause | ||
if (selectStatement.getWhereClause() != null) { | ||
sb.append(indent).append("whereClause: "); | ||
String expressionStr = formatExpression(selectStatement.getWhereClause(), 1); | ||
sb.append(expressionStr.trim()).append(",\n"); | ||
} | ||
|
||
// Format GROUP BY elements | ||
if (selectStatement.getGroupByElements() != null && !selectStatement.getGroupByElements().isEmpty()) { | ||
sb.append(indent).append("groupByElements: [\n"); | ||
for (Expression expr : selectStatement.getGroupByElements()) { | ||
sb.append(indent).append(INDENT); | ||
String expressionStr = formatExpression(expr, 2); | ||
sb.append(expressionStr.trim()).append(",\n"); | ||
} | ||
sb.append(indent).append("],\n"); | ||
} | ||
|
||
// Format HAVING clause | ||
if (selectStatement.getHavingClause() != null) { | ||
sb.append(indent).append("havingClause: "); | ||
String expressionStr = formatExpression(selectStatement.getHavingClause(), 1); | ||
sb.append(expressionStr.trim()).append(",\n"); | ||
} | ||
|
||
// Format ORDER BY elements | ||
if (selectStatement.getOrderByElements() != null && !selectStatement.getOrderByElements().isEmpty()) { | ||
sb.append(indent).append("orderByElements: [\n"); | ||
for (OrderByElement element : selectStatement.getOrderByElements()) { | ||
sb.append(indent).append(INDENT).append("OrderByElement {\n"); | ||
if (element.getExpression() != null) { | ||
sb.append(indent).append(INDENT).append(INDENT).append("expression: "); | ||
String expressionStr = formatExpression(element.getExpression(), 4); | ||
sb.append(expressionStr.trim()).append(",\n"); | ||
} | ||
sb.append(indent).append(INDENT).append(INDENT).append("ascending: ").append(element.isAscending()).append("\n"); | ||
sb.append(indent).append(INDENT).append("},\n"); | ||
} | ||
sb.append(indent).append("],\n"); | ||
} | ||
|
||
// Format LIMIT clause | ||
if (selectStatement.getLimitClause() != null) { | ||
LimitClause limit = selectStatement.getLimitClause(); | ||
sb.append(indent).append("limitClause: {\n"); | ||
sb.append(indent).append(INDENT).append("limit: ").append(limit.getLimit()).append(",\n"); | ||
sb.append(indent).append(INDENT).append("offset: ").append(limit.getOffset()).append("\n"); | ||
sb.append(indent).append("}\n"); | ||
} | ||
|
||
sb.append("}"); | ||
return sb.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
...atacap-test-parser/src/test/java/io/edurt/datacap/test/formatter/SelectStatementTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package io.edurt.datacap.test.formatter; | ||
|
||
import io.edurt.datacap.sql.SQLParser; | ||
import io.edurt.datacap.sql.formatter.SelectFormatter; | ||
import io.edurt.datacap.sql.statement.SQLStatement; | ||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.assertNotNull; | ||
|
||
public class SelectStatementTest | ||
{ | ||
@Test | ||
public void test() | ||
{ | ||
String sql = "SELECT id, name, COUNT(1) as count FROM users WHERE age > 18 and name = 12 GROUP BY id, name HAVING count > 1 ORDER BY id DESC LIMIT 10"; | ||
SQLStatement statement = SQLParser.parse(sql); | ||
SelectFormatter formatter = new SelectFormatter(); | ||
assertNotNull(formatter.format(statement)); | ||
} | ||
} |