如何解决尝试解析 CQL(Cassandra) 查询并使用 antlr
嘿,所以我正在尝试使用 CQL(cassandra) 解析器,我在其中使用 String CQL query
并尝试从中创建一个 QueryClass
对象
QueryClass.java
public QueryClass{
private List<String> select;
private Map<String,Object> insert;
private Map<String,Object> update;
private Map<String,Object> where;
private String keyspace;
private String tablename;
private Integer timeToLive;
//different constructors for different statements..
}
这是我们发送字符串查询并取回对象的方法。
public QueryClass cqlParser(String query) {
QueryClass queryObject;
ANTLRStringStream antlrStringStream= new ANTLRStringStream(query);
CqlLexer cqlLexer = new CqlLexer(antlrStringStream);
CommonTokenStream tokenStream = new CommonTokenStream(cqlLexer);
CqlParser cqlParser = new CqlParser(tokenStream);
ParsedStatement statement = cqlParser.query();
System.out.println(statement.getClass().getDeclaringClass());
if (statement.getClass().getDeclaringClass() == SelectStatement.class)
{
SelectStatement.RawStatement select= (SelectStatement.RawStatement) statement;
String tableName= select.columnFamily();
String keyspace= select.keyspace();
List<RawSelector> selectColumns= select.selectClause;
for (RawSelector rawSelector: selectColumns) {
System.out.println(rawSelector.selectable);
}
WhereClause whereClause= select.whereClause;
List<Relation> whereClauseConditions = whereClause.relations;
whereClauseConditions.forEach(System.out::println);
Term.Raw limit= select.limit;
queryObject = new QueryClass(tableName,keyspace,selectColumns,whereClause,limit);
}
else if(statement.getClass().getDeclaringClass() == UpdateStatement.class)
{
if(statement.getClass() == UpdateStatement.ParsedUpdate.class)
{
UpdateStatement.ParsedUpdate update= (UpdateStatement.ParsedUpdate) statement;
String tableName= update.columnFamily();
String keyspace= update.keyspace();
//need to get all the updates,whereclause and TimeToLive (TTL)
}
else if(statement.getClass() == UpdateStatement.ParsedInsert.class)
{
UpdateStatement.ParsedInsert insert = (UpdateStatement.ParsedInsert) statement;
String tableName= insert.columnFamily();
String keyspace=insert.keyspace();
//need to get all columns and their values,whereclause and TimeToLive
}
}
else if(statement.getClass().getDeclaringClass() == DeleteStatement.class)
{
DeleteStatement.Parsed delete = (DeleteStatement.Parsed) statement;
String tableName= delete.columnFamily();
String keyspace= delete.keyspace();
//need to get where clause
}
return queryObject;
}
这适用于选择语句。但不适用于 Insert、Update 和 delete 语句,因为字段、whereclause、条件、插入列名、列值、timeToLive 等都是私有字段,并且没有可用的 getter 和 setter。
那么我该如何获取它们呢?我能用这种方法得到他们吗?我应该换个角度看待这个问题吗?
顺便说一句,我在 pom.xml 中使用了这个依赖项-
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>cassandra-all</artifactId>
<version>3.11.4</version>
</dependency>
使用 Antlr v3.5.2。(Antlrv4 有什么对我有用的东西吗?)
感谢任何输入。谢谢。
解决方法
如果您今天想编写 CQL 解析器,那么 ANTLR4 绝对是更好的选择。
在 https://github.com/antlr/grammars-v4/tree/master/cql3 处甚至还有一个用于 ANTLR4 的 CQL3 语法
您似乎正在尝试使用已经是该包的一部分的 CQlParser。既然您还说您正在尝试编写自己的解析器,那有点令人困惑。
要编写自己的解析器,请先阅读一些 ANTLR4 教程以熟悉 ANTLR4,然后您应该了解如何利用上面引用的语法。
顺便说一句……私有变量等似乎都是 Cassandra 团队如何编写他们的类以与 ANTLR3 交互的产物(我在 V4 的日子里接触了 ANTLR,所以我不精通 ANTLR3,但是我认为这些限制与 ANTLR3 本身没有任何关系。)。也就是说,我不明白您为什么不使用 ANTLR4 语法并使用 ANTLR4。它非常好,比 ANTLR3 有很多改进。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。