/** * Alipay.com Inc. * Copyright (c) 2004-2012 All Rights Reserved. */ package com.alipay.zdal.client.jdbc.resultset; import java.math.BigDecimal; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import com.alipay.zdal.client.jdbc.OrderByColumn; import com.alipay.zdal.client.jdbc.ZdalStatement; /** * bugfix by fanzeng. * ���������������ֵ��Ϊnull��ʱ����Ϊ������ȣ� * �������һ��Ϊnull����һ����Ϊnull������Ϊnull��С * ֻ�����߶���Ϊnull��ʱ�򣬻�������ݿ���ֶε�������ѡ��Ƚ��� * �������֮һΪnull����sortTypeΪnull��ѡ��null�Ƚ��������бȽ� * @author zhaofeng.wang * @version $Id: OrderByTResultSet.java,v 0.1 2010-12-16 ����03:27:10 zhaofeng.wang Exp $ */ public class OrderByTResultSet extends BaseTResultSet { public OrderByTResultSet(ZdalStatement statementProxy, List<ResultSet> resultSets) { super(statementProxy, resultSets); } private int needNext = -1; private boolean inited; private OrderByColumn[] orderByColumns; private int[] sortIndexes; private SortedSet<Integer> order; private Comparator<Integer> setComparator; private List<Comparator<ResultSet>> sortFieldComparators; /** * @see com.alipay.zdal.client.jdbc.resultset.BaseTResultSet#internNext() */ @Override protected boolean internNext() throws SQLException { if (!inited) { inited = true; reduce(); } try { if (needNext != -1) { if (actualResultSets.get(needNext).next()) { order.add(needNext); } } if (order.isEmpty()) { return false; } Integer first = order.first(); currentIndex = first; order.remove(first); needNext = first; limitTo--; } catch (RuntimeException exp) { Throwable cause = exp.getCause(); if (cause instanceof SQLException) { throw (SQLException) cause; } else if (cause instanceof CompareTypeUnsupported) { SQLException sqlException = new SQLException(cause.toString()); sqlException.setStackTrace(cause.getStackTrace()); throw sqlException; } else { throw exp; } } return true; } protected ResultSet reduce() throws SQLException { if (actualResultSets.size() == 0) { throw new RuntimeException("This should not happen!!"); } if (actualResultSets.size() == 1) { return actualResultSets.get(0); } initSort(); skipLimitFrom(); return null; } protected void initSort() throws SQLException { sortIndexes = new int[orderByColumns.length]; for (int i = 0; i < sortIndexes.length; i++) { sortIndexes[i] = -1; } sortFieldComparators = new ArrayList<Comparator<ResultSet>>(orderByColumns.length); for (int i = 0; i < orderByColumns.length; i++) { sortFieldComparators.add(null); } setComparator = new Comparator<Integer>() { public int compare(Integer left, Integer right) { if (left == right) { return 0; } ResultSet resultSet1, resultSet2; resultSet1 = actualResultSets.get(left); resultSet2 = actualResultSets.get(right); int ret; for (int indexOfOrderByColumn = 0; indexOfOrderByColumn < orderByColumns.length; indexOfOrderByColumn++) { try { if (sortIndexes[indexOfOrderByColumn] == -1) { sortIndexes[indexOfOrderByColumn] = actualResultSets.get(0).findColumn( orderByColumns[indexOfOrderByColumn].getColumnName()); } final int sortIndex = sortIndexes[indexOfOrderByColumn]; Comparator<ResultSet> sortFieldComparator = sortFieldComparators .get(indexOfOrderByColumn); if (sortFieldComparator == null) { Object o1 = resultSet1.getObject(sortIndex); Object o2 = resultSet2.getObject(sortIndex); Class<?> sortType = null; if (null != o1 && null != o2) { sortType = o1.getClass(); } if (sortType == Integer.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { int l = r1.getInt(sortIndex); int r = r2.getInt(sortIndex); return l == r ? 0 : (l < r ? -1 : 1); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == BigDecimal.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { return r1.getBigDecimal(sortIndex).compareTo( r2.getBigDecimal(sortIndex)); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == String.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { return r1.getString(sortIndex).compareTo( r2.getString(sortIndex)); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Timestamp.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { return r1.getTimestamp(sortIndex).compareTo( r2.getTimestamp(sortIndex)); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Short.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { short s1 = r1.getShort(sortIndex); short s2 = r2.getShort(sortIndex); return s1 == s2 ? 0 : (s1 < s2 ? -1 : 1); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Long.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { long l1 = r1.getLong(sortIndex); long l2 = r2.getLong(sortIndex); return l1 == l2 ? 0 : (l1 < l2 ? -1 : 1); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Float.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { float f1 = r1.getFloat(sortIndex); float f2 = r2.getFloat(sortIndex); return f1 == f2 ? 0 : (f1 < f2 ? -1 : 1); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Double.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { double d1 = r1.getDouble(sortIndex); double d2 = r2.getDouble(sortIndex); return d1 == d2 ? 0 : (d1 < d2 ? -1 : 1); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Byte.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { byte b1 = r1.getByte(sortIndex); byte b2 = r2.getByte(sortIndex); return b1 == b2 ? 0 : (b1 < b2 ? -1 : 1); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Boolean.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { boolean b1 = r1.getBoolean(sortIndex); boolean b2 = r2.getBoolean(sortIndex); return b1 == b2 ? 0 : (b1 ? 1 : -1); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Date.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { return r1.getDate(sortIndex).compareTo( r2.getDate(sortIndex)); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == Time.class) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { try { return r1.getTime(sortIndex).compareTo( r2.getTime(sortIndex)); } catch (SQLException e) { throw new RuntimeException(e); } } }; } else if (sortType == null) { sortFieldComparator = new Comparator<ResultSet>() { public int compare(ResultSet r1, ResultSet r2) { int ret = 0; try { if ((r1.getObject(sortIndex) == null) && (r2.getObject(sortIndex) == null)) { ret = 0; } else if ((r1.getObject(sortIndex) == null) && (r2.getObject(sortIndex) != null)) { ret = -1; } else if ((r1.getObject(sortIndex) != null) && (r2.getObject(sortIndex) == null)) { ret = 1; } } catch (SQLException e) { throw new RuntimeException(e); } return ret; } }; } else { throw new RuntimeException(new CompareTypeUnsupported()); } sortFieldComparators.set(indexOfOrderByColumn, sortFieldComparator); } ret = sortFieldComparator.compare(resultSet1, resultSet2); } catch (SQLException e) { throw new RuntimeException(e); } if (ret == 0 && resultSet1 != resultSet2) { continue; } if (orderByColumns[indexOfOrderByColumn].isAsc()) { return ret; } else { return -ret; } } /* * ����TreeSet�����������ͬ�Ķ�����������hashCode����ͬ�Ķ������ֿ� * �������hashCodeҲ��ͬ��2�����������ǵ�˳�����޹ؽ�Ҫ�� */ return System.identityHashCode(resultSet1) < System.identityHashCode(resultSet2) ? -1 : 1; } }; try { order = new TreeSet<Integer>(setComparator); for (int i = 0; i < actualResultSets.size(); i++) { if (actualResultSets.get(i).next()) { order.add(i); } } } catch (RuntimeException exp) { Throwable cause = exp.getCause(); if (cause instanceof SQLException) { throw (SQLException) cause; } else if (cause instanceof CompareTypeUnsupported) { SQLException sqlException = new SQLException(cause.toString()); sqlException.setStackTrace(cause.getStackTrace()); throw sqlException; } else { throw exp; } } } protected void skipLimitFrom() throws SQLException { for (int i = 0; i < limitFrom; i++) { next(); } } public void setOrderByColumns(OrderByColumn[] orderByColumns) { this.orderByColumns = orderByColumns; } }