package jeql.engine.query; import java.util.Collections; import java.util.List; import jeql.api.error.ExecutionException; import jeql.api.row.ArrayRowList; import jeql.api.row.RowList; import jeql.syntax.OrderItem; import jeql.syntax.SelectNode; public class OrderByEvaluator implements QueryOp { private RowList baseRowStr = null; private int[] orderIndex; public OrderByEvaluator(SelectNode select, RowList rowStr) { this.baseRowStr = rowStr; String[] resultColName = select.getSelectList().getResultColumnNames(); orderIndex = computeOrderIndices(resultColName, select.getOrderList()); } private int[] computeOrderIndices(String[] selColName, List orderList) { int[] index = new int[orderList.size()]; for (int i = 0; i < index.length; i++) { index[i] = computeOrderIndexDirection(selColName, (OrderItem) orderList.get(i)); } return index; } /** * * Order indices are 1-based (to conform to SQL convention, and to allow * sign to indicate direction). * * @param selColName * @param orderItem * @return the directed order index (< 0 if descending) */ private int computeOrderIndexDirection(String[] selColName, OrderItem orderItem) { String orderColName = orderItem.getColName(); // find index of order col int colNameIndex = colNameIndex(selColName, orderColName); if (colNameIndex < 0) throw new ExecutionException("Unknown ORDER BY select column name: " + orderColName); int indexDir = colNameIndex + 1; if (! orderItem.isAscending()) indexDir *= -1; return indexDir; } /** * Finds the index of a column name in an array * * @param colName the array of column names * @param name the name to look up * @return the index of the name (0-based) * @return -1 if the name is not in the list */ private int colNameIndex(String[] colName, String name) { // find index of order col for (int i = 0; i < colName.length; i++) { if (name.equals(colName[i])) { return i; } } return -1; } /* public OrderByEvaluator(RowList baseRowStr, int[] orderIndex) { this.baseRowStr = baseRowStr; this.orderIndex = orderIndex; } */ public RowList eval() { // memorize the rowlist in order to allow sorting ArrayRowList rowList = new ArrayRowList(baseRowStr.iterator()); // dismiss baseRowStr to allow GC baseRowStr = null; // sort according to ordering OrderComparator comp = new OrderComparator(orderIndex); Collections.sort(rowList.getRows(), comp); return rowList; } }