提交 d60ab812 编写于 作者: F Frankie Wu

further implementation

上级 16ebe4b3
......@@ -35,6 +35,7 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
......
......@@ -3,8 +3,14 @@ package com.dianping.bee.engine.build;
import java.util.ArrayList;
import java.util.List;
import com.dianping.bee.engine.spi.Statement;
import com.dianping.bee.engine.spi.StatementManager;
import com.dianping.bee.engine.spi.TableProviderManager;
import com.dianping.bee.engine.spi.internal.DefaultStatement;
import com.dianping.bee.engine.spi.internal.DefaultStatementManager;
import com.dianping.bee.engine.spi.internal.DefaultTableProviderManager;
import com.dianping.bee.engine.spi.internal.SingleTableStatementVisitor;
import com.dianping.bee.engine.spi.internal.TableHelper;
import com.site.lookup.configuration.AbstractResourceConfigurator;
import com.site.lookup.configuration.Component;
......@@ -14,6 +20,14 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
List<Component> all = new ArrayList<Component>();
all.add(C(TableProviderManager.class, DefaultTableProviderManager.class));
all.add(C(StatementManager.class, DefaultStatementManager.class));
all.add(C(Statement.class, DefaultStatement.class).is(PER_LOOKUP));
all.add(C(TableHelper.class) //
.req(TableProviderManager.class));
all.add(C(SingleTableStatementVisitor.class).is(PER_LOOKUP) //
.req(TableHelper.class, Statement.class));
return all;
}
......
package com.dianping.bee.engine.spi;
public interface DatabaseProvider {
public String getName();
public TableProvider[] getTables();
}
\ No newline at end of file
package com.dianping.bee.engine.spi;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
public interface Index {
public int getLength();
public ColumnMeta getColumn(int index);
public boolean isAscend(int index);
}
......@@ -2,6 +2,10 @@ package com.dianping.bee.engine.spi;
import java.util.List;
import com.alibaba.cobar.parser.ast.expression.Expression;
public interface RowFilter {
public boolean filter(List<Object> values);
public void setExpression(Expression where);
}
......@@ -5,9 +5,15 @@ import java.util.List;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
public interface Statement {
public List<ColumnMeta> getSelectedColumns();
public List<ColumnMeta> getSelectColumns();
public Index getIndex();
public RowFilter getRowFilter();
public String getTableName();
public void setRowFilter(RowFilter rowFilter);
public void setSelectColumns(List<ColumnMeta> selectColumns);
}
package com.dianping.bee.engine.spi;
import java.sql.SQLSyntaxErrorException;
public interface StatementManager {
public Statement parse(String sql) throws SQLSyntaxErrorException;
}
package com.dianping.bee.engine.spi;
import java.util.List;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.dianping.bee.engine.spi.meta.TableMeta;
public interface TableProvider {
public TableMeta getMeta();
public String getName();
public List<ColumnMeta> getColumns();
public ColumnMeta[] getColumns();
public List<Index> getIndexes();
public Index[] getIndexes();
public RowSet query(List<ColumnMeta> selectedColumns, Index index, RowFilter filter);
public RowSet query(Statement stmt);
}
package com.dianping.bee.engine.spi.internal;
public class BadSQLSyntaxException extends RuntimeException {
private static final long serialVersionUID = 4674438101686847844L;
public BadSQLSyntaxException(String message) {
super(message);
}
public BadSQLSyntaxException(String pattern, Object... args) {
super(String.format(pattern, args));
}
}
package com.dianping.bee.engine.spi.internal;
import java.util.List;
import com.dianping.bee.engine.spi.Index;
import com.dianping.bee.engine.spi.RowFilter;
import com.dianping.bee.engine.spi.Statement;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
public class DefaultStatement implements Statement {
@Override
public List<ColumnMeta> getSelectColumns() {
// TODO Auto-generated method stub
return null;
}
@Override
public Index getIndex() {
// TODO Auto-generated method stub
return null;
}
@Override
public RowFilter getRowFilter() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getTableName() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setRowFilter(RowFilter rowFilter) {
// TODO Auto-generated method stub
}
}
package com.dianping.bee.engine.spi.internal;
import java.sql.SQLSyntaxErrorException;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.cobar.parser.ast.stmt.SQLStatement;
import com.alibaba.cobar.parser.recognizer.SQLParserDelegate;
import com.dianping.bee.engine.spi.Statement;
import com.dianping.bee.engine.spi.StatementManager;
import com.site.lookup.ContainerHolder;
public class DefaultStatementManager extends ContainerHolder implements StatementManager {
private Map<String, Statement> m_statements = new HashMap<String, Statement>();
@Override
public Statement parse(String sql) throws SQLSyntaxErrorException {
Statement statement = m_statements.get(sql);
if (statement == null) {
synchronized (m_statements) {
statement = m_statements.get(sql);
if (statement == null) {
statement = parseSQL(sql);
m_statements.put(sql, statement);
}
}
}
return statement;
}
private Statement parseSQL(String sql) throws SQLSyntaxErrorException {
SingleTableStatementVisitor visitor = lookup(SingleTableStatementVisitor.class);
SQLStatement statement = SQLParserDelegate.parse(sql);
statement.accept(visitor);
return visitor.getStatement();
}
}
package com.dianping.bee.engine.spi.internal;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.cobar.parser.ast.expression.Expression;
import com.alibaba.cobar.parser.ast.expression.primary.Identifier;
import com.alibaba.cobar.parser.ast.fragment.tableref.TableRefFactor;
import com.alibaba.cobar.parser.ast.fragment.tableref.TableReference;
import com.alibaba.cobar.parser.ast.stmt.dml.DMLSelectStatement;
import com.alibaba.cobar.parser.util.Pair;
import com.alibaba.cobar.parser.visitor.EmptySQLASTVisitor;
import com.dianping.bee.engine.spi.RowFilter;
import com.dianping.bee.engine.spi.Statement;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.site.lookup.annotation.Inject;
public class SingleTableStatementVisitor extends EmptySQLASTVisitor {
@Inject
private TableHelper m_helper;
@Inject
private Statement m_stmt;
@Inject
private RowFilter m_rowFilter;
private String m_alias;
private String m_tableName;
private Clause m_clause;
private List<ColumnMeta> m_selectColumns = new ArrayList<ColumnMeta>();
private List<ColumnMeta> m_whereColumns = new ArrayList<ColumnMeta>();
public Statement getStatement() {
return m_stmt;
}
@Override
public void visit(DMLSelectStatement node) {
TableReference tr = node.getTables();
m_clause = Clause.TABLE;
if (tr.isSingleTable()) {
tr.accept(this);
} else {
throw new RuntimeException("Not a single table query!");
}
List<Pair<Expression, String>> exprList = node.getSelectExprList();
m_clause = Clause.SELECT;
for (Pair<Expression, String> pair : exprList) {
String alias = pair.getValue();
if (alias != null && !alias.equals(m_alias)) {
throw new BadSQLSyntaxException("Invalid select alias(%s)!", alias);
}
pair.getKey().accept(this);
}
m_stmt.setSelectColumns(m_selectColumns);
m_clause = Clause.WHERE;
Expression where = node.getWhere();
if (where != null) {
// to get columns from where clause
where.accept(this);
// to evaluate where clause
m_rowFilter.setExpression(where);
m_stmt.setRowFilter(m_rowFilter);
}
}
@Override
public void visit(Identifier node) {
switch (m_clause) {
case SELECT:
String selectColumnName = node.getIdTextUpUnescape();
findOrCreateColumnFrom(m_selectColumns, selectColumnName);
break;
case WHERE:
String whereColumnName = node.getIdTextUpUnescape();
findOrCreateColumnFrom(m_whereColumns, whereColumnName);
break;
}
}
private ColumnMeta findOrCreateColumnFrom(List<ColumnMeta> columns, String columnName) {
for (ColumnMeta column : columns) {
if (column.getName().equals(columnName)) {
return column;
}
}
ColumnMeta column = m_helper.findColumn(m_tableName, columnName);
columns.add(column);
return column;
}
@Override
public void visit(TableRefFactor node) {
m_alias = node.getAlias();
m_tableName = node.getTable().getIdTextUpUnescape();
}
static enum Clause {
SELECT,
TABLE,
WHERE,
GROUP,
HAVING,
ORDER;
}
}
package com.dianping.bee.engine.spi.internal;
import com.dianping.bee.engine.spi.TableProviderManager;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.site.lookup.annotation.Inject;
public class TableHelper {
@Inject
private TableProviderManager m_manager;
public ColumnMeta findColumn(String table, String column) {
return null;
}
}
package com.dianping.bee.engine.spi.meta;
public interface TableMeta {
}
......@@ -337,6 +337,7 @@ public class DefaultVisitor implements SQLASTVisitor {
selectStep = SELECT_STEP.WHERE;
Expression where = node.getWhere();
visitChild(2, where);
this.whereExpression = where;
......
......@@ -4,5 +4,14 @@
<role>com.dianping.bee.engine.spi.TableProviderManager</role>
<implementation>com.dianping.bee.engine.spi.internal.DefaultTableProviderManager</implementation>
</component>
<component>
<role>com.dianping.bee.engine.spi.StatementManager</role>
<implementation>com.dianping.bee.engine.spi.internal.DefaultStatementManager</implementation>
</component>
<component>
<role>com.dianping.bee.engine.spi.Statement</role>
<implementation>com.dianping.bee.engine.spi.internal.DefaultStatement</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
</component>
</components>
</plexus>
package com.dianping.bee.db;
import com.dianping.bee.engine.spi.DatabaseProvider;
import com.dianping.bee.engine.spi.Index;
import com.dianping.bee.engine.spi.RowSet;
import com.dianping.bee.engine.spi.Statement;
import com.dianping.bee.engine.spi.TableProvider;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
public class CatDatabase implements DatabaseProvider {
@Override
public String getName() {
return "cat";
}
@Override
public CatTable[] getTables() {
return CatTable.values();
}
public static enum CatTable implements TableProvider {
Transaction("transaction") {
@Override
public TransactionColumn[] getColumns() {
return TransactionColumn.values();
}
@Override
public TransactionIndex[] getIndexes() {
return TransactionIndex.values();
}
},
Event("event"),
Heartbeat("heartbeat"),
Problem("problem");
private String m_name;
private CatTable(String name) {
m_name = name;
}
@Override
public ColumnMeta[] getColumns() {
// TODO Auto-generated method stub
return null;
}
@Override
public Index[] getIndexes() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getName() {
return m_name;
}
@Override
public RowSet query(Statement stmt) {
// TODO Auto-generated method stub
return null;
}
}
public static enum TransactionColumn implements ColumnMeta {
Type(String.class),
Name(String.class),
TotalCount(Integer.class),
Failures(Integer.class),
SampleLink(String.class),
MinDuration(Integer.class),
MaxDuration(Integer.class),
SumDuration(Long.class),
Sum2Duration(Long.class),
Line95(Integer.class);
private String m_name;
private Class<?> m_type;
private TransactionColumn(Class<?> type) {
m_type = type;
m_name = name().toLowerCase();
}
@Override
public Object getName() {
return m_name;
}
}
public static enum TransactionIndex implements Index {
IDX_TYPE_NAME {
@Override
public ColumnMeta getColumn(int index) {
switch (index) {
case 0:
return TransactionColumn.Type;
case 1:
return TransactionColumn.Name;
}
throw new RuntimeException("Internal error happened!");
}
@Override
public int getLength() {
return 2;
}
@Override
public boolean isAscend(int index) {
return true;
}
};
}
}
package com.dianping.bee.engine.spi;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
......@@ -11,19 +9,13 @@ import com.site.lookup.ComponentTestCase;
@RunWith(JUnit4.class)
public class SpiTest extends ComponentTestCase {
// select a, sum(a) from t1 where c=? and d=?
@Test
public void sample() throws Exception {
TableProviderManager manager = lookup(TableProviderManager.class);
TableProvider table = manager.getTableProvider("t1");
Statement stmt = null;
// stmt.accept(visitor);
List<ColumnMeta> cols = stmt.getSelectedColumns();
Index index = stmt.getIndex();
RowFilter filter = stmt.getRowFilter();
RowSet rowset = table.query(cols, index, filter);
TableProviderManager tableProviderManager = lookup(TableProviderManager.class);
StatementManager statementManager = lookup(StatementManager.class);
Statement stmt = statementManager.parse("select a, sum(a) from t1 where c=? and d=?");
TableProvider table = tableProviderManager.getTableProvider(stmt.getTableName());
RowSet rowset = table.query(stmt);
display(rowset);
}
......@@ -55,7 +47,7 @@ public class SpiTest extends ComponentTestCase {
}
sb.append(rows).append(" rows selected.");
System.out.println(sb);
}
}
......@@ -24,11 +24,11 @@
AND <FIELD name='tag-request'/> = ${tag-request}
</IF>
<IF type='EQ' field='direction' value='true'>
AND <FIELD name='message-id'/> \\> ${message-id}
AND <FIELD name='message-id'/> \> ${message-id}
ORDER BY <FIELD name='message-id'/> ASC
</IF>
<IF type='EQ' field='direction' value='false'>
AND <FIELD name='message-id'/> \\< ${message-id}
AND <FIELD name='message-id'/> \< ${message-id}
ORDER BY <FIELD name='message-id'/> DESC
</IF>
LIMIT 1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册