chore(project): 添加项目配置文件和忽略规则
- 添加 Babel 配置文件支持 ES6+ 语法转换 - 添加 ESLint 忽略规则和配置文件 - 添加 Git 忽略规则文件 - 添加 Travis CI 配置文件 - 添加 1.4.2 版本变更日志文件 - 添加 Helm 图表辅助模板文件 - 添加 Helm 忽略规则文件
This commit is contained in:
51
sqlparser/seata-sqlparser-antlr/pom.xml
Normal file
51
sqlparser/seata-sqlparser-antlr/pom.xml
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-sqlparser</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>seata-sqlparser-antlr</artifactId>
|
||||
<name>seata-sqlparser-antlr ${project.version}</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-sqlparser-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr;
|
||||
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.sqlparser.SQLParsingException;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.SQLRecognizerFactory;
|
||||
import io.seata.sqlparser.SqlParserType;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zhihou
|
||||
*/
|
||||
@LoadLevel(name = SqlParserType.SQL_PARSER_TYPE_ANTLR)
|
||||
public class AntlrDelegatingSQLRecognizerFactory implements SQLRecognizerFactory {
|
||||
|
||||
private volatile SQLRecognizerFactory recognizerFactoryImpl;
|
||||
|
||||
public AntlrDelegatingSQLRecognizerFactory() {
|
||||
setClassLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only for unit test
|
||||
*
|
||||
*/
|
||||
void setClassLoader() {
|
||||
try {
|
||||
Class<?> recognizerFactoryImplClass = ClassLoader.getSystemClassLoader().loadClass("io.seata.sqlparser.antlr.mysql.AntlrMySQLRecognizerFactory");
|
||||
Constructor<?> implConstructor = recognizerFactoryImplClass.getDeclaredConstructor();
|
||||
implConstructor.setAccessible(true);
|
||||
try {
|
||||
recognizerFactoryImpl = (SQLRecognizerFactory) implConstructor.newInstance();
|
||||
} finally {
|
||||
implConstructor.setAccessible(false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new SQLParsingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SQLRecognizer> create(String sql, String dbType) {
|
||||
return recognizerFactoryImpl.create(sql, dbType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr;
|
||||
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
|
||||
/**
|
||||
* The interface SQLOperateRecognizerHolder
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public interface SQLOperateRecognizerHolder {
|
||||
|
||||
/**
|
||||
* Get delete recognizer
|
||||
*
|
||||
* @param sql the sql
|
||||
* @return the delete recognizer
|
||||
*/
|
||||
SQLRecognizer getDeleteRecognizer(String sql);
|
||||
|
||||
/**
|
||||
* Get insert recognizer
|
||||
*
|
||||
* @param sql the sql
|
||||
* @return the insert recognizer
|
||||
*/
|
||||
SQLRecognizer getInsertRecognizer(String sql);
|
||||
|
||||
/**
|
||||
* Get update recognizer
|
||||
*
|
||||
* @param sql the sql
|
||||
* @return the update recognizer
|
||||
*/
|
||||
SQLRecognizer getUpdateRecognizer(String sql);
|
||||
|
||||
/**
|
||||
* Get SelectForUpdate recognizer
|
||||
*
|
||||
* @param sql the sql
|
||||
* @return the SelectForUpdate recognizer
|
||||
*/
|
||||
SQLRecognizer getSelectForUpdateRecognizer(String sql);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* The SQLOperateRecognizerHolderFactory
|
||||
*
|
||||
* @author: zhi hou
|
||||
*/
|
||||
public class SQLOperateRecognizerHolderFactory {
|
||||
|
||||
private static final Map<String, SQLOperateRecognizerHolder> RECOGNIZER_HOLDER_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* get SQLOperateRecognizer by db type
|
||||
*
|
||||
* @param dbType the db type
|
||||
* @return the SQLOperateRecognizer
|
||||
*/
|
||||
public static SQLOperateRecognizerHolder getSQLRecognizerHolder(String dbType) {
|
||||
return CollectionUtils.computeIfAbsent(RECOGNIZER_HOLDER_MAP, dbType, key -> EnhancedServiceLoader.load(SQLOperateRecognizerHolder.class, dbType, SQLOperateRecognizerHolderFactory.class.getClassLoader()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql;
|
||||
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLDeleteRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.antlr.mysql.listener.DeleteSpecificationSqlListener;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AntlrMySQLDeleteRecognizer
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class AntlrMySQLDeleteRecognizer implements SQLDeleteRecognizer {
|
||||
|
||||
private MySqlContext sqlContext;
|
||||
|
||||
public AntlrMySQLDeleteRecognizer(String sql) {
|
||||
MySqlLexer mySqlLexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
CommonTokenStream commonTokenStream = new CommonTokenStream(mySqlLexer);
|
||||
MySqlParser parser2 = new MySqlParser(commonTokenStream);
|
||||
MySqlParser.RootContext root = parser2.root();
|
||||
ParseTreeWalker walker2 = new ParseTreeWalker();
|
||||
sqlContext = new MySqlContext();
|
||||
sqlContext.setOriginalSQL(sql);
|
||||
walker2.walk(new DeleteSpecificationSqlListener(sqlContext), root);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) {
|
||||
return sqlContext.getWhereCondition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
return sqlContext.getWhereCondition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return sqlContext.tableAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return sqlContext.tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalSQL() {
|
||||
|
||||
return sqlContext.getOriginalSQL();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql;
|
||||
|
||||
import io.seata.sqlparser.SQLInsertRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.InsertStatementSqlVisitor;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* AntlrMySQLInsertRecognizer
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class AntlrMySQLInsertRecognizer implements SQLInsertRecognizer {
|
||||
|
||||
private MySqlContext sqlContext;
|
||||
|
||||
public AntlrMySQLInsertRecognizer(String sql) {
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
sqlContext = new MySqlContext();
|
||||
sqlContext.setOriginalSQL(sql);
|
||||
InsertStatementSqlVisitor visitor = new InsertStatementSqlVisitor(sqlContext);
|
||||
visitor.visit(rootContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.INSERT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return sqlContext.tableAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return sqlContext.tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalSQL() {
|
||||
return sqlContext.getOriginalSQL();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insertColumnsIsEmpty() {
|
||||
|
||||
List<MySqlContext.SQL> insertColumnNames = sqlContext.getInsertColumnNames();
|
||||
|
||||
if (insertColumnNames.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getInsertColumns() {
|
||||
|
||||
List<MySqlContext.SQL> insertColumnNames = sqlContext.getInsertColumnNames();
|
||||
|
||||
if (insertColumnNames.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return insertColumnNames.stream().map(insertColumns -> insertColumns.getColumnName()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<Object>> getInsertRows(Collection<Integer> primaryKeyIndex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql;
|
||||
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.SQLRecognizerFactory;
|
||||
import io.seata.sqlparser.antlr.SQLOperateRecognizerHolder;
|
||||
import io.seata.sqlparser.antlr.SQLOperateRecognizerHolderFactory;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.StatementSqlVisitor;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AntlrMySQLRecognizerFactory
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
class AntlrMySQLRecognizerFactory implements SQLRecognizerFactory {
|
||||
|
||||
@Override
|
||||
public List<SQLRecognizer> create(String sqlData, String dbType) {
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sqlData));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.SqlStatementsContext sqlStatementsContext = parser.sqlStatements();
|
||||
|
||||
List<MySqlParser.SqlStatementContext> sqlStatementContexts = sqlStatementsContext.sqlStatement();
|
||||
|
||||
List<SQLRecognizer> recognizers = null;
|
||||
SQLRecognizer recognizer = null;
|
||||
|
||||
for (MySqlParser.SqlStatementContext sql : sqlStatementContexts) {
|
||||
|
||||
StatementSqlVisitor visitor = new StatementSqlVisitor();
|
||||
|
||||
String originalSQL = visitor.visit(sql).toString();
|
||||
|
||||
SQLOperateRecognizerHolder recognizerHolder =
|
||||
SQLOperateRecognizerHolderFactory.getSQLRecognizerHolder(dbType.toLowerCase());
|
||||
if (sql.dmlStatement().updateStatement() != null) {
|
||||
recognizer = recognizerHolder.getUpdateRecognizer(originalSQL);
|
||||
} else if (sql.dmlStatement().insertStatement() != null) {
|
||||
recognizer = recognizerHolder.getInsertRecognizer(originalSQL);
|
||||
} else if (sql.dmlStatement().deleteStatement() != null) {
|
||||
recognizer = recognizerHolder.getDeleteRecognizer(originalSQL);
|
||||
} else if (sql.dmlStatement().selectStatement() != null) {
|
||||
recognizer = recognizerHolder.getSelectForUpdateRecognizer(originalSQL);
|
||||
}
|
||||
|
||||
if (recognizer != null) {
|
||||
if (recognizers == null) {
|
||||
recognizers = new ArrayList<>();
|
||||
}
|
||||
recognizers.add(recognizer);
|
||||
}
|
||||
}
|
||||
return recognizers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql;
|
||||
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLSelectRecognizer;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.antlr.mysql.listener.SelectSpecificationSqlListener;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AntlrMySQLSelectRecognizer
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class AntlrMySQLSelectRecognizer implements SQLSelectRecognizer {
|
||||
|
||||
private MySqlContext sqlContext;
|
||||
|
||||
public AntlrMySQLSelectRecognizer(String sql) {
|
||||
MySqlLexer mySqlLexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
CommonTokenStream commonTokenStream = new CommonTokenStream(mySqlLexer);
|
||||
MySqlParser parser = new MySqlParser(commonTokenStream);
|
||||
MySqlParser.RootContext root = parser.root();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
sqlContext = new MySqlContext();
|
||||
sqlContext.setOriginalSQL(sql);
|
||||
walker.walk(new SelectSpecificationSqlListener(sqlContext), root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) {
|
||||
return sqlContext.getWhereCondition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
return sqlContext.getWhereCondition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.SELECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return sqlContext.tableAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return sqlContext.tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalSQL() {
|
||||
return sqlContext.getOriginalSQL();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql;
|
||||
|
||||
import io.seata.sqlparser.ParametersHolder;
|
||||
import io.seata.sqlparser.SQLType;
|
||||
import io.seata.sqlparser.SQLUpdateRecognizer;
|
||||
import io.seata.sqlparser.antlr.mysql.listener.UpdateSpecificationSqlListener;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* AntlrMySQLUpdateRecognizer
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class AntlrMySQLUpdateRecognizer implements SQLUpdateRecognizer {
|
||||
|
||||
private MySqlContext sqlContext;
|
||||
|
||||
public AntlrMySQLUpdateRecognizer(String sql) {
|
||||
MySqlLexer mySqlLexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
CommonTokenStream commonTokenStream = new CommonTokenStream(mySqlLexer);
|
||||
MySqlParser parser2 = new MySqlParser(commonTokenStream);
|
||||
MySqlParser.RootContext root = parser2.root();
|
||||
ParseTreeWalker walker2 = new ParseTreeWalker();
|
||||
sqlContext = new MySqlContext();
|
||||
sqlContext.setOriginalSQL(sql);
|
||||
walker2.walk(new UpdateSpecificationSqlListener(sqlContext), root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUpdateColumns() {
|
||||
|
||||
List<MySqlContext.SQL> updateFoColumnNames = sqlContext.getUpdateFoColumnNames();
|
||||
List<String> sqlList = new ArrayList<>();
|
||||
for (MySqlContext.SQL sql : updateFoColumnNames) {
|
||||
sqlList.add(sql.getUpdateColumn());
|
||||
}
|
||||
return sqlList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getUpdateValues() {
|
||||
|
||||
List<MySqlContext.SQL> updateForValues = sqlContext.getUpdateForValues();
|
||||
|
||||
if (updateForValues.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return updateForValues.stream().map(updateValues -> updateValues.getUpdateValue()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) {
|
||||
return sqlContext.getWhereCondition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWhereCondition() {
|
||||
return sqlContext.getWhereCondition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLType getSQLType() {
|
||||
return SQLType.UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableAlias() {
|
||||
return sqlContext.tableAlias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return sqlContext.tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalSQL() {
|
||||
return sqlContext.getOriginalSQL();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql;
|
||||
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.antlr.SQLOperateRecognizerHolder;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
|
||||
/**
|
||||
* The class MySqlOperateRecognizerHolder
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
@LoadLevel(name = JdbcConstants.MYSQL)
|
||||
public class MySQLOperateRecognizerHolder implements SQLOperateRecognizerHolder {
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getDeleteRecognizer(String sql) {
|
||||
return new AntlrMySQLDeleteRecognizer(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getInsertRecognizer(String sql) {
|
||||
return new AntlrMySQLInsertRecognizer(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getUpdateRecognizer(String sql) {
|
||||
return new AntlrMySQLUpdateRecognizer(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLRecognizer getSelectForUpdateRecognizer(String sql) {
|
||||
return new AntlrMySQLSelectRecognizer(sql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MySqlContext
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class MySqlContext {
|
||||
|
||||
/**
|
||||
* Table Name
|
||||
*/
|
||||
public String tableName;
|
||||
|
||||
/**
|
||||
* Table Alias
|
||||
*/
|
||||
public String tableAlias;
|
||||
|
||||
/**
|
||||
* Number of inserts
|
||||
*/
|
||||
public Integer insertRows;
|
||||
|
||||
/**
|
||||
* Where condition
|
||||
*/
|
||||
private String whereCondition;
|
||||
|
||||
/**
|
||||
* Query column name collection
|
||||
*/
|
||||
public List<SQL> queryColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Conditional query column name collection
|
||||
*/
|
||||
public List<SQL> queryWhereColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Conditional query column name corresponding value collection
|
||||
*/
|
||||
public List<SQL> queryWhereValColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Query column name collection
|
||||
*/
|
||||
public List<SQL> insertColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Insert the value set corresponding to the column name
|
||||
*/
|
||||
public List<List<String>> insertForValColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Delete condition column name set
|
||||
*/
|
||||
public List<SQL> deleteForWhereColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Conditional delete column name object value collection
|
||||
*/
|
||||
public List<SQL> deleteForWhereValColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Conditional update condition column name object collection
|
||||
*/
|
||||
public List<SQL> updateForWhereColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Conditional update column name object value collection
|
||||
*/
|
||||
public List<SQL> updateForWhereValColumnNames = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Update column name object value collection
|
||||
*/
|
||||
public List<SQL> updateFoColumnNames = new ArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
* Update object value collection
|
||||
*/
|
||||
public List<SQL> updateForValues = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* sql object information collection
|
||||
*/
|
||||
public List<SQL> sqlInfos = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* originalSQL
|
||||
*/
|
||||
private String originalSQL;
|
||||
|
||||
public void addSqlInfo(SQL sql) {
|
||||
sqlInfos.add(sql);
|
||||
}
|
||||
|
||||
public void addForInsertColumnName(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setInsertColumnName(columnName);
|
||||
insertColumnNames.add(sql);
|
||||
}
|
||||
|
||||
public void addForInsertValColumnName(List<String> columnName) {
|
||||
insertForValColumnNames.add(columnName);
|
||||
}
|
||||
|
||||
public void addQueryColumnNames(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setColumnName(columnName);
|
||||
queryColumnNames.add(sql);
|
||||
}
|
||||
|
||||
public void addQueryWhereColumnNames(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setQueryWhereColumnName(columnName);
|
||||
queryWhereColumnNames.add(sql);
|
||||
}
|
||||
|
||||
public void addQueryWhereValColumnNames(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setQueryWhereValColumnName(columnName);
|
||||
queryWhereValColumnNames.add(sql);
|
||||
}
|
||||
|
||||
public void addDeleteWhereColumnNames(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setDeleteWhereColumnName(columnName);
|
||||
deleteForWhereColumnNames.add(sql);
|
||||
}
|
||||
|
||||
public void addDeleteWhereValColumnNames(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setDeleteWhereValColumnName(columnName);
|
||||
deleteForWhereValColumnNames.add(sql);
|
||||
}
|
||||
|
||||
|
||||
public void addUpdateWhereValColumnNames(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setUpdateWhereValColumnName(columnName);
|
||||
updateForWhereValColumnNames.add(sql);
|
||||
}
|
||||
|
||||
|
||||
public void addUpdateWhereColumnNames(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setUpdateWhereColumnName(columnName);
|
||||
updateForWhereColumnNames.add(sql);
|
||||
}
|
||||
|
||||
public void addUpdateColumnNames(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setUpdateColumn(columnName);
|
||||
updateFoColumnNames.add(sql);
|
||||
}
|
||||
|
||||
public void addUpdateValues(String columnName) {
|
||||
SQL sql = new SQL();
|
||||
sql.setUpdateValue(columnName);
|
||||
updateForValues.add(sql);
|
||||
}
|
||||
|
||||
public static class SQL {
|
||||
private String columnName;
|
||||
private String tableName;
|
||||
private String queryWhereValColumnName;
|
||||
private String queryWhereColumnName;
|
||||
private String insertColumnName;
|
||||
private String deleteWhereValColumnName;
|
||||
private String deleteWhereColumnName;
|
||||
private String updateWhereValColumnName;
|
||||
private String updateWhereColumnName;
|
||||
private String updateColumn;
|
||||
private String updateValue;
|
||||
private Integer sqlType;
|
||||
private String sql;
|
||||
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
public void setColumnName(String columnName) {
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getQueryWhereValColumnName() {
|
||||
return queryWhereValColumnName;
|
||||
}
|
||||
|
||||
public void setQueryWhereValColumnName(String queryWhereValColumnName) {
|
||||
this.queryWhereValColumnName = queryWhereValColumnName;
|
||||
}
|
||||
|
||||
public String getQueryWhereColumnName() {
|
||||
return queryWhereColumnName;
|
||||
}
|
||||
|
||||
public void setQueryWhereColumnName(String queryWhereColumnName) {
|
||||
this.queryWhereColumnName = queryWhereColumnName;
|
||||
}
|
||||
|
||||
public String getInsertColumnName() {
|
||||
return insertColumnName;
|
||||
}
|
||||
|
||||
public void setInsertColumnName(String insertColumnName) {
|
||||
this.insertColumnName = insertColumnName;
|
||||
}
|
||||
|
||||
public String getDeleteWhereValColumnName() {
|
||||
return deleteWhereValColumnName;
|
||||
}
|
||||
|
||||
public void setDeleteWhereValColumnName(String deleteWhereValColumnName) {
|
||||
this.deleteWhereValColumnName = deleteWhereValColumnName;
|
||||
}
|
||||
|
||||
public String getDeleteWhereColumnName() {
|
||||
return deleteWhereColumnName;
|
||||
}
|
||||
|
||||
public void setDeleteWhereColumnName(String deleteWhereColumnName) {
|
||||
this.deleteWhereColumnName = deleteWhereColumnName;
|
||||
}
|
||||
|
||||
public String getUpdateWhereValColumnName() {
|
||||
return updateWhereValColumnName;
|
||||
}
|
||||
|
||||
public void setUpdateWhereValColumnName(String updateWhereValColumnName) {
|
||||
this.updateWhereValColumnName = updateWhereValColumnName;
|
||||
}
|
||||
|
||||
public String getUpdateWhereColumnName() {
|
||||
return updateWhereColumnName;
|
||||
}
|
||||
|
||||
public void setUpdateWhereColumnName(String updateWhereColumnName) {
|
||||
this.updateWhereColumnName = updateWhereColumnName;
|
||||
}
|
||||
|
||||
public String getUpdateColumn() {
|
||||
return updateColumn;
|
||||
}
|
||||
|
||||
public void setUpdateColumn(String updateColumn) {
|
||||
this.updateColumn = updateColumn;
|
||||
}
|
||||
|
||||
public String getUpdateValue() {
|
||||
return updateValue;
|
||||
}
|
||||
|
||||
public void setUpdateValue(String updateValue) {
|
||||
this.updateValue = updateValue;
|
||||
}
|
||||
|
||||
public Integer getSqlType() {
|
||||
return sqlType;
|
||||
}
|
||||
|
||||
public void setSqlType(Integer sqlType) {
|
||||
this.sqlType = sqlType;
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public void setSql(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
}
|
||||
|
||||
public List<SQL> getQueryColumnNames() {
|
||||
return queryColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getQueryWhereColumnNames() {
|
||||
return queryWhereColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getQueryWhereValColumnNames() {
|
||||
return queryWhereValColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getInsertColumnNames() {
|
||||
return insertColumnNames;
|
||||
}
|
||||
|
||||
public List<List<String>> getInsertForValColumnNames() {
|
||||
return insertForValColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getDeleteForWhereColumnNames() {
|
||||
return deleteForWhereColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getDeleteForWhereValColumnNames() {
|
||||
return deleteForWhereValColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getUpdateForWhereColumnNames() {
|
||||
return updateForWhereColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getUpdateForWhereValColumnNames() {
|
||||
return updateForWhereValColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getUpdateFoColumnNames() {
|
||||
return updateFoColumnNames;
|
||||
}
|
||||
|
||||
public List<SQL> getUpdateForValues() {
|
||||
return updateForValues;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public Integer getInsertRows() {
|
||||
return insertRows;
|
||||
}
|
||||
|
||||
public void setInsertRows(Integer insertRows) {
|
||||
this.insertRows = insertRows;
|
||||
}
|
||||
|
||||
public String getWhereCondition() {
|
||||
return whereCondition;
|
||||
}
|
||||
|
||||
public void setWhereCondition(String whereCondition) {
|
||||
this.whereCondition = whereCondition;
|
||||
}
|
||||
|
||||
public List<SQL> getSqlInfos() {
|
||||
return sqlInfos;
|
||||
}
|
||||
|
||||
public String getOriginalSQL() {
|
||||
return originalSQL;
|
||||
}
|
||||
|
||||
public void setOriginalSQL(String originalSQL) {
|
||||
this.originalSQL = originalSQL;
|
||||
}
|
||||
|
||||
public void setTableAlias(String tableAlias) {
|
||||
this.tableAlias = tableAlias;
|
||||
}
|
||||
|
||||
public String getTableAlias() {
|
||||
return tableAlias;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql.listener;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParserBaseListener;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.StatementSqlVisitor;
|
||||
|
||||
/**
|
||||
* @author houzhi
|
||||
*/
|
||||
public class DeleteSpecificationSqlListener extends MySqlParserBaseListener {
|
||||
|
||||
private MySqlContext sqlQueryContext;
|
||||
|
||||
public DeleteSpecificationSqlListener(MySqlContext sqlQueryContext) {
|
||||
this.sqlQueryContext = sqlQueryContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterAtomTableItem(MySqlParser.AtomTableItemContext ctx) {
|
||||
MySqlParser.TableNameContext tableNameContext = ctx.tableName();
|
||||
sqlQueryContext.setTableName(tableNameContext.getText());
|
||||
MySqlParser.UidContext uid = ctx.uid();
|
||||
sqlQueryContext.setTableAlias(uid.getText());
|
||||
super.enterAtomTableItem(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterConstantExpressionAtom(MySqlParser.ConstantExpressionAtomContext ctx) {
|
||||
sqlQueryContext.addDeleteWhereValColumnNames(ctx.getText());
|
||||
super.enterConstantExpressionAtom(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFullColumnNameExpressionAtom(MySqlParser.FullColumnNameExpressionAtomContext ctx) {
|
||||
sqlQueryContext.addDeleteWhereColumnNames(ctx.getText());
|
||||
super.enterFullColumnNameExpressionAtom(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSingleDeleteStatement(MySqlParser.SingleDeleteStatementContext ctx) {
|
||||
MySqlParser.TableNameContext tableNameContext = ctx.tableName();
|
||||
sqlQueryContext.setTableName(tableNameContext.getText());
|
||||
MySqlParser.ExpressionContext expression = ctx.expression();
|
||||
StatementSqlVisitor statementSqlVisitor = new StatementSqlVisitor();
|
||||
String text = statementSqlVisitor.visit(expression).toString();
|
||||
sqlQueryContext.setWhereCondition(text);
|
||||
super.enterSingleDeleteStatement(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterMultipleDeleteStatement(MySqlParser.MultipleDeleteStatementContext ctx) {
|
||||
MySqlParser.ExpressionContext expression = ctx.expression();
|
||||
StatementSqlVisitor statementSqlVisitor = new StatementSqlVisitor();
|
||||
String text = statementSqlVisitor.visit(expression).toString();
|
||||
sqlQueryContext.setWhereCondition(text);
|
||||
super.enterMultipleDeleteStatement(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterInPredicate(MySqlParser.InPredicateContext ctx) {
|
||||
StatementSqlVisitor statementSqlVisitor = new StatementSqlVisitor();
|
||||
String text = statementSqlVisitor.visit(ctx).toString();
|
||||
sqlQueryContext.setWhereCondition(text);
|
||||
super.enterInPredicate(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql.listener;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParserBaseListener;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.StatementSqlVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author houzhi
|
||||
*/
|
||||
public class SelectSpecificationSqlListener extends MySqlParserBaseListener {
|
||||
|
||||
private MySqlContext sqlQueryContext;
|
||||
|
||||
public SelectSpecificationSqlListener(MySqlContext sqlQueryContext) {
|
||||
this.sqlQueryContext = sqlQueryContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterTableName(MySqlParser.TableNameContext ctx) {
|
||||
|
||||
sqlQueryContext.setTableName(ctx.getText());
|
||||
super.enterTableName(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterAtomTableItem(MySqlParser.AtomTableItemContext ctx) {
|
||||
|
||||
MySqlParser.UidContext uid = ctx.uid();
|
||||
if (uid != null) {
|
||||
String text = uid.getText();
|
||||
if (!text.isEmpty()) {
|
||||
sqlQueryContext.setTableAlias(text);
|
||||
}
|
||||
}
|
||||
super.enterAtomTableItem(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFromClause(MySqlParser.FromClauseContext ctx) {
|
||||
|
||||
MySqlParser.ExpressionContext whereExpr = ctx.whereExpr;
|
||||
StatementSqlVisitor statementSqlVisitor = new StatementSqlVisitor();
|
||||
String text = statementSqlVisitor.visit(whereExpr).toString();
|
||||
sqlQueryContext.setWhereCondition(text);
|
||||
super.enterFromClause(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFullColumnNameExpressionAtom(MySqlParser.FullColumnNameExpressionAtomContext ctx) {
|
||||
|
||||
sqlQueryContext.addQueryWhereColumnNames(ctx.getText());
|
||||
super.enterFullColumnNameExpressionAtom(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterConstantExpressionAtom(MySqlParser.ConstantExpressionAtomContext ctx) {
|
||||
|
||||
sqlQueryContext.addQueryWhereValColumnNames(ctx.getText());
|
||||
super.enterConstantExpressionAtom(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSelectElements(MySqlParser.SelectElementsContext ctx) {
|
||||
|
||||
List<MySqlParser.SelectElementContext> selectElementContexts = ctx.selectElement();
|
||||
for (MySqlParser.SelectElementContext selectElementContext : selectElementContexts) {
|
||||
sqlQueryContext.addQueryColumnNames(selectElementContext.getText());
|
||||
}
|
||||
super.enterSelectElements(ctx);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql.listener;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParserBaseListener;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.StatementSqlVisitor;
|
||||
|
||||
/**
|
||||
* @author houzhi
|
||||
*/
|
||||
public class UpdateSpecificationSqlListener extends MySqlParserBaseListener {
|
||||
|
||||
|
||||
private MySqlContext sqlQueryContext;
|
||||
|
||||
public UpdateSpecificationSqlListener(MySqlContext sqlQueryContext) {
|
||||
this.sqlQueryContext = sqlQueryContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterTableName(MySqlParser.TableNameContext ctx) {
|
||||
|
||||
sqlQueryContext.setTableName(ctx.getText());
|
||||
super.enterTableName(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterConstantExpressionAtomForUpdate(MySqlParser.ConstantExpressionAtomForUpdateContext ctx) {
|
||||
|
||||
sqlQueryContext.addUpdateWhereValColumnNames(ctx.getText());
|
||||
super.enterConstantExpressionAtomForUpdate(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFullColumnNameExpressionAtomForUpdate(MySqlParser.FullColumnNameExpressionAtomForUpdateContext ctx) {
|
||||
|
||||
sqlQueryContext.addUpdateWhereColumnNames(ctx.getText());
|
||||
super.enterFullColumnNameExpressionAtomForUpdate(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSingleUpdateStatement(MySqlParser.SingleUpdateStatementContext ctx) {
|
||||
|
||||
MySqlParser.ExpressionForUpdateContext expressionForUpdateContext = ctx.expressionForUpdate();
|
||||
StatementSqlVisitor statementSqlVisitor = new StatementSqlVisitor();
|
||||
String text = statementSqlVisitor.visit(expressionForUpdateContext).toString();
|
||||
sqlQueryContext.setWhereCondition(text);
|
||||
|
||||
MySqlParser.UidContext uid = ctx.uid();
|
||||
|
||||
if (uid != null) {
|
||||
String alias = uid.getText();
|
||||
if (!text.isEmpty()) {
|
||||
sqlQueryContext.setTableAlias(alias);
|
||||
}
|
||||
}
|
||||
super.enterSingleUpdateStatement(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterUpdatedElement(MySqlParser.UpdatedElementContext ctx) {
|
||||
|
||||
MySqlParser.ExpressionContext expression = ctx.expression();
|
||||
sqlQueryContext.addUpdateValues(expression.getText());
|
||||
|
||||
MySqlParser.FullColumnNameContext fullColumnNameContext = ctx.fullColumnName();
|
||||
sqlQueryContext.addUpdateColumnNames(fullColumnNameContext.getText());
|
||||
|
||||
super.enterUpdatedElement(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql.stream;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
import org.antlr.v4.runtime.IntStream;
|
||||
|
||||
/**
|
||||
* ANTLRNoCaseStringStream
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class ANTLRNoCaseStringStream extends ANTLRInputStream {
|
||||
|
||||
public ANTLRNoCaseStringStream(String input) {
|
||||
super(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int LA(int i) {
|
||||
int la = super.LA(i);
|
||||
if (la == 0 || la == IntStream.EOF) {
|
||||
return la;
|
||||
} else {
|
||||
return Character.toUpperCase(la);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql.visit;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParserBaseVisitor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* InsertSpecificationSqlVisitor
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class InsertSpecificationSqlVisitor extends MySqlParserBaseVisitor<MySqlContext> {
|
||||
|
||||
private MySqlContext mySqlContext;
|
||||
|
||||
public InsertSpecificationSqlVisitor(MySqlContext mySqlContext) {
|
||||
this.mySqlContext = mySqlContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MySqlContext visitInsertStatement(MySqlParser.InsertStatementContext ctx) {
|
||||
|
||||
MySqlParser.TableNameContext tableNameContext = ctx.tableName();
|
||||
|
||||
mySqlContext.setTableName(tableNameContext.getText());
|
||||
|
||||
MySqlParser.UidListContext columns = ctx.columns;
|
||||
|
||||
List<String> strings = Arrays.asList(columns.getText().split(","));
|
||||
|
||||
for (String insertColumnName : strings) {
|
||||
mySqlContext.addForInsertColumnName(insertColumnName);
|
||||
}
|
||||
|
||||
MySqlParser.InsertStatementValueContext insertStatementValueContext = ctx.insertStatementValue();
|
||||
List<MySqlParser.ExpressionsWithDefaultsContext> expressionsWithDefaultsContexts = insertStatementValueContext.expressionsWithDefaults();
|
||||
|
||||
for (MySqlParser.ExpressionsWithDefaultsContext expressions : expressionsWithDefaultsContexts) {
|
||||
|
||||
String text = expressions.getText();
|
||||
String str = null;
|
||||
if (text.contains("'")) {
|
||||
str = text.replace("'", "");
|
||||
} else if (text.contains("\"")) {
|
||||
str = text.replace("\"", "");
|
||||
} else {
|
||||
str = text;
|
||||
}
|
||||
if (!str.isEmpty() && !str.contains("'") && !str.contains("\"")) {
|
||||
mySqlContext.addForInsertValColumnName(Arrays.asList(str.split(",")));
|
||||
}
|
||||
}
|
||||
mySqlContext.setInsertRows(expressionsWithDefaultsContexts.size());
|
||||
return this.mySqlContext;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql.visit;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParserBaseVisitor;
|
||||
|
||||
/**
|
||||
* InsertStatementSqlVisitor
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class InsertStatementSqlVisitor extends MySqlParserBaseVisitor<MySqlContext> {
|
||||
|
||||
private MySqlContext mySqlContext;
|
||||
|
||||
public InsertStatementSqlVisitor(MySqlContext mySqlContext) {
|
||||
this.mySqlContext = mySqlContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MySqlContext visitInsertStatement(MySqlParser.InsertStatementContext ctx) {
|
||||
return new InsertSpecificationSqlVisitor(this.mySqlContext).visitInsertStatement(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr.mysql.visit;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParserBaseVisitor;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
/**
|
||||
* StatementSqlVisitor
|
||||
*
|
||||
* @author zhihou
|
||||
*/
|
||||
public class StatementSqlVisitor extends MySqlParserBaseVisitor<StringBuilder> {
|
||||
|
||||
private StringBuilder sb = new StringBuilder();
|
||||
|
||||
@Override
|
||||
public StringBuilder visitTerminal(TerminalNode node) {
|
||||
String text = node.getText();
|
||||
if (text != null && !"".equals(text.trim())) {
|
||||
if (shouldAddSpace(text.trim())) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(text);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
private boolean shouldAddSpace(String text) {
|
||||
if (sb.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
char lastChar = sb.charAt(sb.length() - 1);
|
||||
switch (lastChar) {
|
||||
case '.':
|
||||
case ',':
|
||||
case '(':
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (text.charAt(0)) {
|
||||
case '.':
|
||||
case ',':
|
||||
case ')':
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
io.seata.sqlparser.antlr.AntlrDelegatingSQLRecognizerFactory
|
||||
@@ -0,0 +1 @@
|
||||
io.seata.sqlparser.antlr.mysql.MySQLOperateRecognizerHolder
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.sqlparser.SQLRecognizer;
|
||||
import io.seata.sqlparser.SQLRecognizerFactory;
|
||||
import io.seata.sqlparser.SqlParserType;
|
||||
import io.seata.sqlparser.util.JdbcConstants;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zhihou
|
||||
*/
|
||||
public class AntlrIsolationTest {
|
||||
|
||||
String TEST_SQL = "SELECT name,phone FROM t1 WHERE id = 1 and username = '11' and age = 'a' or hz = '1' or aa = 1 FOR UPDATE";
|
||||
|
||||
@Test
|
||||
public void testAntlrIsolation() {
|
||||
AntlrDelegatingSQLRecognizerFactory recognizerFactory = (AntlrDelegatingSQLRecognizerFactory) EnhancedServiceLoader.load(SQLRecognizerFactory.class, SqlParserType.SQL_PARSER_TYPE_ANTLR);
|
||||
List<SQLRecognizer> sqlRecognizer = recognizerFactory.create(TEST_SQL, JdbcConstants.MYSQL);
|
||||
Assertions.assertNotNull(sqlRecognizer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.listener.DeleteSpecificationSqlListener;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.StatementSqlVisitor;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author houzhi
|
||||
* @date 2020-7-10
|
||||
* @description
|
||||
*/
|
||||
public class MySQLDeleteRecognizerTest {
|
||||
|
||||
/**
|
||||
* base statementSql visitor test
|
||||
*/
|
||||
private String baseStatementSqlVisitor(String sql) {
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
MySqlParser.SqlStatementContext sqlStatementContext = parser.sqlStatement();
|
||||
StatementSqlVisitor sqlToStringVisitor = new StatementSqlVisitor();
|
||||
return sqlToStringVisitor.visit(sqlStatementContext).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete recognizer test 0.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_0() {
|
||||
|
||||
String sql = "DELETE t FROM t1 as t WHERE t.id = 'id1'";
|
||||
|
||||
String visitorText = baseStatementSqlVisitor(sql);
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(visitorText));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new DeleteSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("t.id = 'id1'", mySqlContext.getWhereCondition());
|
||||
Assertions.assertEquals("t", mySqlContext.getTableAlias());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_1() {
|
||||
|
||||
String sql = "DELETE FROM t1 WHERE id = 'id1'";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new DeleteSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("'id1'",
|
||||
mySqlContext.getDeleteForWhereValColumnNames().get(0).getDeleteWhereValColumnName());
|
||||
Assertions.assertEquals("id = 'id1'", mySqlContext.getWhereCondition());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_2() {
|
||||
|
||||
String sql = "DELETE FROM t1 WHERE id = ?";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new DeleteSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("?",
|
||||
mySqlContext.getDeleteForWhereValColumnNames().get(0).getDeleteWhereValColumnName());
|
||||
Assertions.assertEquals("id = ?", mySqlContext.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete recognizer test 2.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_3() {
|
||||
|
||||
String sql = "DELETE FROM t1 WHERE id IN (1, 2)";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new DeleteSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("2", mySqlContext.getDeleteForWhereValColumnNames().get(1).getDeleteWhereValColumnName());
|
||||
Assertions.assertEquals("id IN (1,2)", mySqlContext.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete recognizer test 3.
|
||||
*/
|
||||
@Test
|
||||
public void deleteRecognizerTest_4() {
|
||||
|
||||
String sql = "DELETE FROM t1 WHERE id between 1 AND 'id'";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new DeleteSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("'id'", mySqlContext.getDeleteForWhereValColumnNames().get(1).getDeleteWhereValColumnName());
|
||||
Assertions.assertEquals("id between 1 AND 'id'", mySqlContext.getWhereCondition());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.InsertStatementSqlVisitor;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author houzhi
|
||||
* @date 2020-7-10
|
||||
* @description
|
||||
*/
|
||||
public class MySQLInsertRecognizerTest {
|
||||
|
||||
/**
|
||||
* Insert recognizer test 0.
|
||||
*/
|
||||
@Test
|
||||
public void insertRecognizerTest_0() {
|
||||
|
||||
String sql = "INSERT INTO t1 (id) VALUES (1)";
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext visitorSqlContext = new MySqlContext();
|
||||
InsertStatementSqlVisitor visitor = new InsertStatementSqlVisitor(visitorSqlContext);
|
||||
visitor.visit(rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", visitorSqlContext.tableName);
|
||||
Assertions.assertEquals(Collections.singletonList("id"), Arrays.asList(visitorSqlContext.getInsertColumnNames().get(0).getInsertColumnName()));
|
||||
Assertions.assertEquals(1, visitorSqlContext.insertRows);
|
||||
Assertions.assertEquals(Arrays.asList("1"), visitorSqlContext.getInsertForValColumnNames().get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void insertRecognizerTest_1() {
|
||||
|
||||
String sql = "INSERT INTO t1 (name1, name2) VALUES ('name1', 12)";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext visitorSqlContext = new MySqlContext();
|
||||
InsertStatementSqlVisitor visitor = new InsertStatementSqlVisitor(visitorSqlContext);
|
||||
visitor.visit(rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", visitorSqlContext.tableName);
|
||||
Assertions.assertEquals(Arrays.asList("name1", "name2"), visitorSqlContext.getInsertColumnNames().stream().map(insert -> {
|
||||
return insert.getInsertColumnName();
|
||||
}).collect(Collectors.toList()));
|
||||
Assertions.assertEquals(1, visitorSqlContext.insertRows);
|
||||
Assertions.assertEquals(Arrays.asList("name1", "12"), visitorSqlContext.getInsertForValColumnNames().get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert recognizer test 3.
|
||||
*/
|
||||
@Test
|
||||
public void insertRecognizerTest_3() {
|
||||
|
||||
String sql = "INSERT INTO t1 (name1, name2) VALUES ('name1', 'name2'), ('name3', 'name4'), ('name5', 'name6')";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext visitorSqlContext = new MySqlContext();
|
||||
InsertStatementSqlVisitor visitor = new InsertStatementSqlVisitor(visitorSqlContext);
|
||||
visitor.visit(rootContext);
|
||||
|
||||
|
||||
Assertions.assertEquals("t1", visitorSqlContext.tableName);
|
||||
Assertions.assertEquals("name2", visitorSqlContext.getInsertColumnNames().get(1).getInsertColumnName());
|
||||
|
||||
Integer insertRows = visitorSqlContext.insertRows;
|
||||
Assertions.assertEquals(3, insertRows);
|
||||
|
||||
Assertions.assertEquals(Arrays.asList("name1", "name2"), visitorSqlContext.getInsertForValColumnNames().get(0));
|
||||
Assertions.assertEquals(Arrays.asList("name3", "name4"), visitorSqlContext.getInsertForValColumnNames().get(1));
|
||||
Assertions.assertEquals(Arrays.asList("name5", "name6"), visitorSqlContext.getInsertForValColumnNames().get(2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.listener.SelectSpecificationSqlListener;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.StatementSqlVisitor;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author houzhi
|
||||
* @date 2020-7-9
|
||||
* @description
|
||||
*/
|
||||
public class MySQLSelectForUpdateRecognizerForListenerTest {
|
||||
|
||||
/**
|
||||
* base statementSql visitor test
|
||||
*/
|
||||
private String baseStatementSqlVisitor(String sql) {
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
MySqlParser.SqlStatementContext sqlStatementContext = parser.sqlStatement();
|
||||
StatementSqlVisitor sqlToStringVisitor = new StatementSqlVisitor();
|
||||
return sqlToStringVisitor.visit(sqlStatementContext).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 0.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_0() {
|
||||
|
||||
String sql = "SELECT a FROM t1 b WHERE b.id = d FOR UPDATE";
|
||||
|
||||
String visitorText = baseStatementSqlVisitor(sql);
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(visitorText));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext listenerSqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new SelectSpecificationSqlListener(listenerSqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", listenerSqlContext.getTableName());
|
||||
Assertions.assertEquals("b.id = d", listenerSqlContext.getWhereCondition());
|
||||
Assertions.assertEquals("b", listenerSqlContext.getTableAlias());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_1() {
|
||||
|
||||
String sql = "SELECT name,age,phone FROM t1 WHERE id = 'id1' FOR UPDATE";
|
||||
|
||||
String visitorText = baseStatementSqlVisitor(sql);
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(visitorText));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext listenerSqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new SelectSpecificationSqlListener(listenerSqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", listenerSqlContext.getTableName());
|
||||
Assertions.assertEquals("phone", listenerSqlContext.getQueryColumnNames().get(2).getColumnName());
|
||||
Assertions.assertEquals("id = 'id1'", listenerSqlContext.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_2() {
|
||||
|
||||
String sql = "SELECT name,age,phone FROM t2 WHERE id = 'id'FOR UPDATE";
|
||||
|
||||
String visitorText = baseStatementSqlVisitor(sql);
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(visitorText));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new SelectSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t2", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("phone", mySqlContext.getQueryColumnNames().get(2).getColumnName());
|
||||
Assertions.assertEquals("id = 'id'", mySqlContext.getWhereCondition());
|
||||
Assertions.assertEquals("id", mySqlContext.getQueryWhereColumnNames().get(0).getQueryWhereColumnName());
|
||||
Assertions.assertEquals("'id'", mySqlContext.getQueryWhereValColumnNames().get(0).getQueryWhereValColumnName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_3() {
|
||||
|
||||
String sql = "SELECT name,phone FROM t1 WHERE id = 1 and username = '11' and age = 'a' or hz = '1' or aa = 1 FOR UPDATE";
|
||||
|
||||
String visitorText = baseStatementSqlVisitor(sql);
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(visitorText));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new SelectSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("name", mySqlContext.getQueryColumnNames().get(0).getColumnName());
|
||||
Assertions.assertEquals("username", mySqlContext.getQueryWhereColumnNames().get(1).getQueryWhereColumnName());
|
||||
Assertions.assertEquals("'a'", mySqlContext.getQueryWhereValColumnNames().get(2).getQueryWhereValColumnName());
|
||||
Assertions.assertEquals("id = 1 and username = '11' and age = 'a' or hz = '1' or aa = 1", mySqlContext.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 4.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_4() {
|
||||
|
||||
String sql = "SELECT name1, name2 FROM t1 WHERE id IN (100,101) FOR UPDATE";
|
||||
|
||||
String visitorText = baseStatementSqlVisitor(sql);
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(visitorText));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new SelectSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("name1", mySqlContext.getQueryColumnNames().get(0).getColumnName());
|
||||
Assertions.assertEquals("id", mySqlContext.getQueryWhereColumnNames().get(0).getQueryWhereColumnName());
|
||||
Assertions.assertEquals("101", mySqlContext.getQueryWhereValColumnNames().get(1).getQueryWhereValColumnName());
|
||||
Assertions.assertEquals("id IN (100,101)", mySqlContext.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select for update recognizer test 5.
|
||||
*/
|
||||
@Test
|
||||
public void selectForUpdateRecognizerTest_5() {
|
||||
|
||||
String sql = "SELECT name1, name2 FROM t1 WHERE name = 1 and id between 2 and 3 or img = '11' FOR UPDATE";
|
||||
|
||||
String visitorText = baseStatementSqlVisitor(sql);
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(visitorText));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new SelectSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("name1", mySqlContext.getQueryColumnNames().get(0).getColumnName());
|
||||
Assertions.assertEquals("id", mySqlContext.getQueryWhereColumnNames().get(1).getQueryWhereColumnName());
|
||||
Assertions.assertEquals("3", mySqlContext.getQueryWhereValColumnNames().get(2).getQueryWhereValColumnName());
|
||||
Assertions.assertEquals("name = 1 and id between 2 and 3 or img = '11'", mySqlContext.getWhereCondition());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.sqlparser.antlr;
|
||||
|
||||
import io.seata.sqlparser.antlr.mysql.MySqlContext;
|
||||
import io.seata.sqlparser.antlr.mysql.listener.UpdateSpecificationSqlListener;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlLexer;
|
||||
import io.seata.sqlparser.antlr.mysql.parser.MySqlParser;
|
||||
import io.seata.sqlparser.antlr.mysql.stream.ANTLRNoCaseStringStream;
|
||||
import io.seata.sqlparser.antlr.mysql.visit.StatementSqlVisitor;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type My sql update recognizer test.
|
||||
*/
|
||||
public class MySQLUpdateRecognizerTest {
|
||||
|
||||
/**
|
||||
* base statementSql visitor test
|
||||
*/
|
||||
private String baseStatementSqlVisitor(String sql) {
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
MySqlParser.SqlStatementContext sqlStatementContext = parser.sqlStatement();
|
||||
StatementSqlVisitor sqlToStringVisitor = new StatementSqlVisitor();
|
||||
return sqlToStringVisitor.visit(sqlStatementContext).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 0.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_0() {
|
||||
|
||||
String sql = "UPDATE t1 a SET a.name = 'name1' WHERE a.id = 'id1'";
|
||||
|
||||
String visitorText = baseStatementSqlVisitor(sql);
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(visitorText));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new UpdateSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals(1, mySqlContext.getUpdateForValues().size());
|
||||
Assertions.assertEquals("a.id", mySqlContext.getUpdateForWhereColumnNames().get(0).getUpdateWhereColumnName());
|
||||
Assertions.assertEquals("a.name", mySqlContext.getUpdateFoColumnNames().get(0).getUpdateColumn());
|
||||
Assertions.assertEquals("a.id = 'id1'", mySqlContext.getWhereCondition());
|
||||
Assertions.assertEquals("a", mySqlContext.getTableAlias());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 1.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_1() {
|
||||
|
||||
String sql = "UPDATE t1 SET name1 = name1, name2 = name2 WHERE id = 'id1'";
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new UpdateSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("name1", mySqlContext.getUpdateFoColumnNames().get(0).getUpdateColumn());
|
||||
Assertions.assertEquals("name1", mySqlContext.getUpdateForValues().get(0).getUpdateValue());
|
||||
Assertions.assertEquals("name2", mySqlContext.getUpdateFoColumnNames().get(1).getUpdateColumn());
|
||||
Assertions.assertEquals("name2", mySqlContext.getUpdateForValues().get(1).getUpdateValue());
|
||||
Assertions.assertEquals("id = 'id1'", mySqlContext.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 2.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_2() {
|
||||
|
||||
String sql = "UPDATE t1 SET name1 = 'name1', name2 = 'name2' WHERE id = ?";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new UpdateSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
List<MySqlContext.SQL> updateForWhereValColumnNames = mySqlContext.getUpdateForWhereValColumnNames();
|
||||
|
||||
System.out.println(updateForWhereValColumnNames);
|
||||
|
||||
Assertions.assertEquals("?", mySqlContext.getUpdateForWhereValColumnNames().get(0).getUpdateWhereValColumnName());
|
||||
Assertions.assertEquals("name1", mySqlContext.getUpdateFoColumnNames().get(0).getUpdateColumn());
|
||||
Assertions.assertEquals("name2", mySqlContext.getUpdateFoColumnNames().get(1).getUpdateColumn());
|
||||
Assertions.assertEquals("id = ?", mySqlContext.getWhereCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 3.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_3() {
|
||||
|
||||
String sql = "UPDATE t1 as t SET t.name1 = 'name1', t.name2 = 'name2' WHERE id in (1, 2)";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new UpdateSpecificationSqlListener(mySqlContext), rootContext);
|
||||
|
||||
Assertions.assertEquals("1", mySqlContext.getUpdateForWhereValColumnNames().get(0).getUpdateWhereValColumnName());
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("t.name1", mySqlContext.getUpdateFoColumnNames().get(0).getUpdateColumn());
|
||||
Assertions.assertEquals("'name1'", mySqlContext.getUpdateForValues().get(0).getUpdateValue());
|
||||
Assertions.assertEquals("t.name2", mySqlContext.getUpdateFoColumnNames().get(1).getUpdateColumn());
|
||||
Assertions.assertEquals("id in (1,2)", mySqlContext.getWhereCondition());
|
||||
Assertions.assertEquals("t", mySqlContext.getTableAlias());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recognizer test 5.
|
||||
*/
|
||||
@Test
|
||||
public void updateRecognizerTest_5() {
|
||||
|
||||
String sql = "UPDATE t1 SET name1 = 'name1', name2 = 'name2' WHERE id between 1 and 2";
|
||||
|
||||
MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseStringStream(sql));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
MySqlParser parser = new MySqlParser(tokenStream);
|
||||
|
||||
MySqlParser.RootContext rootContext = parser.root();
|
||||
|
||||
MySqlContext mySqlContext = new MySqlContext();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(new UpdateSpecificationSqlListener(mySqlContext), rootContext);
|
||||
Assertions.assertEquals("t1", mySqlContext.getTableName());
|
||||
Assertions.assertEquals("name1", mySqlContext.getUpdateFoColumnNames().get(0).getUpdateColumn());
|
||||
Assertions.assertEquals("'name1'", mySqlContext.getUpdateForValues().get(0).getUpdateValue());
|
||||
Assertions.assertEquals("name2", mySqlContext.getUpdateFoColumnNames().get(1).getUpdateColumn());
|
||||
Assertions.assertEquals("2", mySqlContext.getUpdateForWhereValColumnNames().get(1).getUpdateWhereValColumnName());
|
||||
Assertions.assertEquals("id between 1 and 2", mySqlContext.getWhereCondition());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user