/** * Alipay.com Inc. * Copyright (c) 2004-2012 All Rights Reserved. */ package com.alipay.zdal.parser.result; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import com.alipay.zdal.common.lang.StringUtil; import com.alipay.zdal.common.sqljep.function.Comparative; import com.alipay.zdal.common.sqljep.function.ComparativeAND; import com.alipay.zdal.common.sqljep.function.ComparativeOR; import com.alipay.zdal.parser.GroupFunctionType; import com.alipay.zdal.parser.exceptions.SqlParserException; import com.alipay.zdal.parser.sql.parser.ParserException; import com.alipay.zdal.parser.sql.stat.TableStat; import com.alipay.zdal.parser.sql.stat.TableStat.Column; import com.alipay.zdal.parser.sql.stat.TableStat.Mode; import com.alipay.zdal.parser.sql.stat.TableStat.SELECTMODE; import com.alipay.zdal.parser.sqlobjecttree.ComparativeMapChoicer; import com.alipay.zdal.parser.visitor.BindVarCondition; import com.alipay.zdal.parser.visitor.OrderByEle; import com.alipay.zdal.parser.visitor.ZdalSchemaStatVisitor; /** * * @author xiaoqing.zhouxq * @version $Id: AbstractSqlParserResult.java, v 0.1 2012-5-21 ����03:11:27 xiaoqing.zhouxq Exp $ */ public abstract class DefaultSqlParserResult implements SqlParserResult, ComparativeMapChoicer { protected ZdalSchemaStatVisitor visitor; /** * ���û��skip��max�᷵�ش�ֵ */ public final static int DEFAULT_SKIP_MAX = -1000; protected String tableName = null; public DefaultSqlParserResult(ZdalSchemaStatVisitor visitor) { if (visitor == null) { throw new SqlParserException("ERROR the visitor is null "); } this.visitor = visitor; } public List<OrderByEle> getGroupByEles() { Set<Column> columns = visitor.getGroupByColumns(); List<OrderByEle> results = Collections.emptyList(); for (Column column : columns) { OrderByEle orderByEle = new OrderByEle(column.getTable(), column.getName()); orderByEle.setAttributes(column.getAttributes()); results.add(orderByEle); } return results; } public GroupFunctionType getGroupFuncType() { if (SELECTMODE.COUNT == visitor.getSelectMode()) { return GroupFunctionType.COUNT; } else if (SELECTMODE.MAX == visitor.getSelectMode()) { return GroupFunctionType.MAX; } else if (SELECTMODE.MIN == visitor.getSelectMode()) { return GroupFunctionType.MIN; } else if (SELECTMODE.SUM == visitor.getSelectMode()) { return GroupFunctionType.SUM; } return GroupFunctionType.NORMAL; } public boolean isDML() { return (visitor.getSqlMode() == Mode.Delete) || (visitor.getSqlMode() == Mode.Insert) || (visitor.getSqlMode() == Mode.Select) || (visitor.getSqlMode() == Mode.Update); } public List<OrderByEle> getOrderByEles() { List<Column> columns = visitor.getOrderByColumns(); List<OrderByEle> results = new ArrayList<OrderByEle>(); for (Column column : columns) { OrderByEle orderByEle = new OrderByEle(column.getTable(), column.getName()); orderByEle.setAttributes(column.getAttributes()); results.add(orderByEle); } return results; } /** * ��ȡ���� * @return * @see com.alipay.zdal.parser.result.SqlParserResult#getTableName() */ public String getTableName() { if (visitor.getTables() == null || visitor.getTables().isEmpty()) { throw new SqlParserException("ERROR ## the tableName is null"); } if (StringUtil.isBlank(tableName)) { for (Entry<TableStat.Name, TableStat> entry : visitor.getTables().entrySet()) { String temp = entry.getKey().getName(); if (tableName == null) { if (temp != null) { tableName = temp.toLowerCase(); } } else { if (temp != null && !tableName.equals(entry.getKey().getName().toLowerCase())) { throw new IllegalArgumentException("sql����еı�����ͬ���뱣֤����sql���ı���" + "�Լ����ǵ�schemaName��ͬ��������Ƕsql"); } } } } return tableName; } /** * ��ȡComparativeMap. * map��key ������ value�ǰ󶨱������{@link Comparative} * ����Ǹ����ɸ�ֵ�ı������򲻻᷵�ء� * ���ɸ�ֵָ���ǣ���Ȼ���Խ������������Ժ�Ľ�����ܽ��м��㡣 * ��where col = concat(str,str); * ����SQL��Ȼ���Խ���������Ϊ��Ӧ�Ĵ�����û����ɣ������Dz��ܸ�ֵ�ġ����������col * �Dz��ᱻ�ŵ����ص�map�еġ� * @param arguments ����ֵ�б�. * @param partnationSet ����ֶ��б�. * @return */ public Map<String, Comparative> getColumnsMap(List<Object> arguments, Set<String> partnationSet) { Map<String, Comparative> copiedMap = new LinkedHashMap<String, Comparative>(); for (String partnation : partnationSet) { Comparative comparative = getComparativeOf(partnation, arguments); if (comparative != null) { copiedMap.put(partnation, comparative); } } return copiedMap; } /** * ���ݲ���ֶδ�sql���ֶ��л�ȡ��Ӧ����������ֵ. * @param partinationKey * @param arguments * @return */ private Comparative getComparativeOf(String partinationKey, List<Object> arguments) { List<BindVarCondition> bindColumns = visitor.getBindVarConditions(); List<BindVarCondition> conditions = new ArrayList<BindVarCondition>(); for (BindVarCondition tmp : bindColumns) { if (tmp.getColumnName().equalsIgnoreCase(partinationKey)) { conditions.add(tmp); } } if (!conditions.isEmpty()) { //�ȴӰ󶨲����б��в���. Comparative comparative = null; int index = 1; for (BindVarCondition bindVarCondition : conditions) { String op = bindVarCondition.getOperator(); int function = Comparative.getComparisonByIdent(op); if (function == Comparative.NotSupport || op.trim().equalsIgnoreCase("in")) {//֧�ֲ���ֶ���in��ģʽ. Object arg = arguments.get(bindVarCondition.getIndex()); Comparable<?> value = null; if (arg instanceof Comparable<?>) { value = (Comparable<?>) arg; } else { throw new ParserException("ERROR ## can not use this type of partination"); } if (comparative == null) { comparative = new Comparative(Comparative.Equivalent, value); if (index == conditions.size()) { return comparative; } } else { Comparative next = new Comparative(Comparative.Equivalent, value); ComparativeOR comparativeOR = new ComparativeOR(); comparativeOR.addComparative(comparative); comparativeOR.addComparative(next); comparative = comparativeOR; if (index == conditions.size()) { return comparativeOR; } } index++; } } index = -1; for (BindVarCondition condition : conditions) { Object arg = arguments.get(condition.getIndex()); Comparable<?> value = null; if (arg instanceof Comparable<?>) { value = (Comparable<?>) arg; } else { throw new ParserException("ERROR ## can not use this type of partination"); } int function = Comparative.getComparisonByIdent(condition.getOperator()); if (comparative == null) { comparative = new Comparative(function, value); index = condition.getIndex(); } else { Comparative next = new Comparative(function, value); if (index == condition.getIndex()) {//���Ӳ�ѯ�У����ڲ���ֶε�index��ͬ������������ͬ�Ͳ���Ҫand/or ����ƥ����. return comparative; } if (condition.getOp() == 1) { ComparativeAND comparativeAND = new ComparativeAND(); comparativeAND.addComparative(comparative); comparativeAND.addComparative(next); return comparativeAND; } else if (condition.getOp() == -1) { ComparativeOR comparativeOR = new ComparativeOR(); comparativeOR.addComparative(comparative); comparativeOR.addComparative(next); return comparativeOR; } } } return comparative; } else { List<BindVarCondition> noBindConditions = visitor.getNoBindVarConditions(); if (noBindConditions.isEmpty()) { return null; } List<BindVarCondition> noBinditions = new ArrayList<BindVarCondition>(); for (BindVarCondition tmp : noBindConditions) { if (tmp.getColumnName().equalsIgnoreCase(partinationKey)) { int function = Comparative.getComparisonByIdent(tmp.getOperator()); if (function == Comparative.NotSupport) { if (tmp.getOperator().trim().equalsIgnoreCase("in")) { noBinditions.add(tmp); } else { continue; } } else { noBinditions.add(tmp); } } } Comparative comparative = null; for (BindVarCondition condition : noBinditions) { Comparable<?> value = condition.getValue(); if (value == null) { throw new SqlParserException( "ERROR ## parse from no-bind-column of this partination is error,the partination name = " + partinationKey); } if (!(value instanceof Comparable<?>)) { throw new ParserException("ERROR ## can not use this type of partination"); } if (condition.getOperator().trim().equalsIgnoreCase("in")) { if (comparative == null) { comparative = new Comparative(Comparative.Equivalent, value); } else { Comparative next = new Comparative(Comparative.Equivalent, value); ComparativeOR comparativeOR = new ComparativeOR(); comparativeOR.addComparative(comparative); comparativeOR.addComparative(next); comparative = comparativeOR; } } else { int function = Comparative.getComparisonByIdent(condition.getOperator()); if (comparative == null) { comparative = new Comparative(function, value); } else { Comparative next = new Comparative(function, value); if (condition.getOp() == 1) { ComparativeAND comparativeAND = new ComparativeAND(); comparativeAND.addComparative(comparative); comparativeAND.addComparative(next); return comparativeAND; } else if (condition.getOp() == -1) { ComparativeOR comparativeOR = new ComparativeOR(); comparativeOR.addComparative(comparative); comparativeOR.addComparative(next); return comparativeOR; } } } } return comparative; } } /** * @param tables * @param args * @param skip * �����䣬���Ŀ�ʼ * @param max * �����䣬���� * @return */ public void getSqlReadyToRun(Set<String> tables, List<Object> args, Number skip, Number max, Map<Integer, Object> modifiedMap) { if (tables == null) { throw new IllegalArgumentException("���滻����Ϊ��"); } //�����skip �� max �����ڣ������ǰ󶨱��������������в������滻 if (this.isSkipBind() < 0 && this.isRowCountBind() < 0) { throw new IllegalArgumentException("The limit skip or rowCount set error!"); } modifyParam(skip, isSkipBind(), modifiedMap); modifyParam(max, isRowCountBind(), modifiedMap); } protected void modifyParam(Number num, int index, Map<Integer, Object> changeParam) { Object obj = null; if (num instanceof Long) { obj = (Long) num; } else if (num instanceof Integer) { obj = (Integer) num; } else { throw new IllegalArgumentException("ֻ֧��int long�����"); } changeParam.put(index, obj); } protected String toColumns(Set<Column> columns) { StringBuilder result = new StringBuilder(); int i = 0; for (Column column : columns) { result.append(column); if (i != (columns.size() - 1)) { result.append(","); } } return result.toString(); } public ComparativeMapChoicer getComparativeMapChoicer() { return this; } }