All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onetwo.common.db.parser.JFishSqlParser Maven / Gradle / Ivy

package org.onetwo.common.db.parser;

import java.util.Map;

import org.onetwo.common.lexer.AbstractParser;
import org.onetwo.common.lexer.StringSourceReader;
import org.onetwo.common.utils.ArrayUtils;
import org.onetwo.common.utils.LangUtils;

public class JFishSqlParser extends AbstractParser implements SqlParser {

	private SqlTokenKey[] keywords;
	private SqlTokenKey[] operators;
	private boolean debug;
	private Map operatorParsers = LangUtils.newHashMap();
	
	public JFishSqlParser(String sql) {
		super(new SqlLexer(new StringSourceReader(sql)));
		keywords = getSqlLexer().getKeyWords().getKeyWordTokenAsArray();
		keywords = (SqlTokenKey[])ArrayUtils.add(keywords, SqlTokenKey.EOF);
		
		operators = getSqlLexer().getOperators().getKeyWordTokenAsArray();
		
		this.registerOperatorParser(new InOperatorParser());
		this.registerOperatorParser(new BetweenOperatorParser());
	}
	
	public SqlLexer getSqlLexer(){
		return (SqlLexer)lexer;
	}
	
	public boolean isDebug() {
		return debug;
	}
	
	public final JFishSqlParser registerOperatorParser(OperatorParser parser){
		this.operatorParsers.put(parser.getOperator(), parser);
		return this;
	}

	public void setDebug(boolean debug) {
		this.debug = debug;
		this.lexer.setDebug(true);
	}

	protected void addJTokenValuesToStatments(SqlStatment statment, JTokenValueCollection jtokens){
		if(!jtokens.isEmpty()){
			statment.addSqlObject(new SqlJTokenValuesObjectImpl(jtokens.clone()));
			jtokens.clear();
		}
	}
	
	public SqlStatment parse(){
		SqlStatment statment = new SqlStatment();
		lexer.nextToken();
		
//		boolean createCollection = true;
		SqlObject sqlObj = null;
//		int lastKeywordPos = -1;
//		int sqlObjectCount = 0;
		
		JTokenValueCollection jtokens = new JTokenValueCollection();
		SqlTokenKey token = null;
		boolean afterWhere = false;
		while(true){
			token = lexer.getToken();
			if(tokenIs(SqlTokenKey.EOF) || tokenIs(SqlTokenKey.SEMI)){
				this.addJTokenValuesToStatments(statment, jtokens);
				break;
			}

			/*if(tokenIs(SqlTokenKey.WHERE)){
				System.out.println("test");
			}*/
			if(ArrayUtils.contains(operators, token)){
				JTokenValue op = new JTokenValue(token, stringValue());
				this.throwIfNoNextToken();
				if(tokenIs(SqlTokenKey.LPARENT)){
					/*jtokens.addJTokenValue(op);
					jtokens.addJTokenValue(lexer.getToken(), stringValue());
					this.throwIfNoNextToken();*/

					JTokenValue lparent = new JTokenValue(lexer.getToken(), stringValue());
					
					this.throwIfNoNextToken();
					if(tokenIs(SqlTokenKey.SELECT)){//sub query
						this.addJTokenValuesToStatments(statment, jtokens);
						sqlObj = new SqlKeywordObject(op);
						statment.addSqlObject(sqlObj);
						jtokens.addJTokenValue(lparent);
					}else{
						JTokenValueCollection rightIds = nextAllTokensUntilKeywords();
						rightIds.addJTokenValue(0, lparent);
						sqlObj = createSqlInfixCondition(jtokens, token, rightIds);
						statment.addSqlObject(sqlObj);
						
					}
				}else{
					JTokenValueCollection rightIds = nextAllTokensUntilKeywords();
					
					//(m.login_code=:loginCode or m.mobile=:loginCode or m.email=:email)
					if(jtokens.startWith(SqlTokenKey.LPARENT) && !jtokens.contains(SqlTokenKey.RPARENT)){
						statment.addSqlObject(new SqlSymbolObject(jtokens.remove(0)));
						
						sqlObj = createSqlInfixCondition(jtokens, token, rightIds);
						statment.addSqlObject(sqlObj);
						
					}else if(rightIds.endWith(SqlTokenKey.RPARENT) && !rightIds.contains(SqlTokenKey.LPARENT)){
						JTokenValue rparentToken = rightIds.removeLast();
						sqlObj = createSqlInfixCondition(jtokens, token, rightIds);
						statment.addSqlObject(sqlObj);
						
						statment.addSqlObject(new SqlSymbolObject(rparentToken));
					}else{
						sqlObj = createSqlInfixCondition(jtokens, token, rightIds);
						statment.addSqlObject(sqlObj);
					}
				}
				continue;
			}else if(ArrayUtils.contains(keywords, token)){
				this.addJTokenValuesToStatments(statment, jtokens);
				
				sqlObj = new SqlKeywordObject(token, stringValue());
				if(tokenIs(SqlTokenKey.WHERE)){
					afterWhere = true;
				}
				
			}else if(!afterWhere && tokenIsSqlVarSymbol()){
				/*JTokenValue op = new JTokenValue(token, stringValue());
				throwIfNoNextToken();
				if(tokenIsOneOf(SqlTokenKey.COMMA, SqlTokenKey.RPARENT)){
					
				}*/
				this.addJTokenValuesToStatments(statment, jtokens);
				String var = stringValue();
				sqlObj = new SqlVarObjectImpl(var);
				
			}else{
				sqlObj = null;
			}
			
//			sqlObjectCount++;
			if(sqlObj!=null){
				statment.addSqlObject(sqlObj);
			}else{
				jtokens.addJTokenValue(token, stringValue());
			}
//			System.out.println("statment:"+statment.toSql());
			this.lexer.nextToken();
			
		}
//		System.out.println("statment:"+statment.toSql());
		return statment;
	}
	
	private SqlObject createSqlInfixCondition(JTokenValueCollection jtokens, SqlTokenKey token, JTokenValueCollection rightIds){
		SqlObject sqlObj = null;
		
		if(operatorParsers.containsKey(token)){
			sqlObj = operatorParsers.get(token).parse(this, jtokens, rightIds);
		}else if(jtokens.contains(SqlTokenKey.VARNAME) || jtokens.contains(SqlTokenKey.QUESTION)){
			SqlInfixVarConditionExpr cond = new SqlInfixVarConditionExpr(jtokens.clone(), token, rightIds, false);
			sqlObj = cond;
		}else if(rightIds.contains(SqlTokenKey.VARNAME) || rightIds.contains(SqlTokenKey.QUESTION)){
			sqlObj = new SqlInfixVarConditionExpr(jtokens.clone(), token, rightIds, true);
		}
		
		if(sqlObj==null){
			sqlObj = new SqlInfixConditionExpr(jtokens.clone(), token, rightIds);
		}
		jtokens.clear();
		
		/*statment.addSqlObject(sqlObj);
		sqlObj = new SqlObjectImpl(stringValue());*/
		
		return sqlObj;
	}
	

	public JTokenValueCollection nextAllTokensUntilKeywords(){
		return nextAllTokensUntil(keywords);
	}
	
	private boolean tokenIsSqlVarSymbol(){
		return tokenIs(SqlTokenKey.VARNAME) || tokenIs(SqlTokenKey.QUESTION);
	}
	
	/*
	protected void buildWhere(WhereSqlObject where){
		SqlInfixConditionExpr cond = new SqlInfixConditionExpr();
		while(lexer.nextToken()){
			JTokenValueCollection  leftIds = nextAllTokensUntil(getSqlLexer().getOperators().getKeyWordTokenAsArray());
			cond.setLeft(leftIds);
			cond.setOperator(lexer.getToken());
			this.throwIfNoNextToken();
			JTokenValueCollection  rightIds = nextAllTokensUntil(getSqlLexer().getOperators().getKeyWordTokenAsArray());
			cond.setRight(rightIds);
			
			where.addCondition(cond);
			
			if(tokenIs(SqlTokenKey.AND)){
				cond = new SqlWordCollection();
			}else if(tokenIs(SqlTokenKey.OR)){
				cond = new SqlOrExpr();
			}else{
				break;
			}
		}
	}*/
	

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy