RowNumSortExpression.java
package org.microspace.table.query.sql;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.microspace.table.Entry;
import org.microspace.table.column.Accessor;
import org.microspace.table.column.IndexedMap;
import org.microspace.table.query.SqlFormat;
/**
*
* @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
* @version 2017-07-06
* @param <T>
* The type of the Table.
*/
public class RowNumSortExpression<T> implements Serializable {
private static final long serialVersionUID = -5348440896112518581L;
final Class<T> tableClass;
Integer lowLimit = null;
Integer highLimit = null;
EntryComparator<T> comparator = null;
public RowNumSortExpression(Class<T> tableClass) {
this.tableClass = tableClass;
}
public Integer getLowLimit() {
if (lowLimit == null) {
return null;
}
if (lowLimit == Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return lowLimit + 1;
}
/**
* Set the lowLimit record number.
*
* @param lowLimit
* starting from zero.
*
*/
public void setLowLimit(Integer lowLimit) {
if (this.lowLimit != null) {
throw new IllegalArgumentException("Duplicate Low Limit");
}
this.lowLimit = lowLimit - 1;
}
public Integer getHighLimit() {
if (highLimit == null) {
return null;
}
if (highLimit == Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return highLimit +1;
}
/**
* Set the high limit record number.
*
* @param highLimit
* starting from zero.
*/
public void setHighLimit(Integer highLimit) {
if (this.highLimit != null) {
throw new IllegalArgumentException("Duplicate High Limit");
}
this.highLimit = highLimit - 1;
}
public EntryComparator<T> getComparator() {
return comparator;
}
public void setComparator(EntryComparator<T> comparator) {
if (this.comparator != null) {
throw new IllegalArgumentException("Duplicate Sort Comparator");
}
this.comparator = comparator;
}
public List<Entry<T>> sortApply(Accessor<T> accessor, IndexedMap<Object, Entry<T>> entries,
List<String> columnNames, boolean distinct) {
int min = lowLimit == null ? 0 : lowLimit;
int max = highLimit == null ? Integer.MAX_VALUE : highLimit;
if (min < 0)
min = 0;
ArrayList<Entry<T>> matches = new ArrayList<Entry<T>>(entries.size());
if (entries.size() == 0)
return matches;
if (columnNames.size() > 0) {
List<EntryComparator.Type> types = new LinkedList<>();
for (int i=0; i<columnNames.size(); i++) {
types.add(EntryComparator.Type.ASC);
}
// second columnNames is not used.
EntryComparator<T> distinctComp = new EntryComparator<>(tableClass,
EntryComparator.Type.SKIP,
columnNames, types, columnNames);
SortedSet<Entry<T>> uniqueMap = new TreeSet<>(distinctComp);
for (Entry<T> entry : entries.values()) {
uniqueMap.add(entry);
}
for (Entry<T> entry : uniqueMap) {
matches.add(entry);
}
} else {
for (Entry<T> entry : entries.values()) {
matches.add(entry);
}
}
if (comparator == null) {
Collections.sort(matches);
} else {
Collections.sort(matches, comparator);
}
ArrayList<Entry<T>> ret = new ArrayList<Entry<T>>(matches.size());
for (int index = min; index < max; index++) {
if (matches.size() <= index)
break;
Entry<T> entry = matches.get(index);
ret.add(entry);
}
return ret;
}
public boolean hasLimits() {
return lowLimit != null || highLimit != null;
}
public String formatRowNumString(SqlFormat format) {
StringBuffer ret = new StringBuffer();
if (format == SqlFormat.MICROSPACE) {
if (getLowLimit() != null) {
ret.append("ROWNUM >= ");
ret.append("" + getLowLimit());
}
if (getHighLimit() != null) {
if (ret.length() != 0)
ret.append(" AND ");
ret.append("ROWNUM < ");
ret.append("" + getHighLimit());
}
} else if (format == SqlFormat.GIGASPACES || format == SqlFormat.GIGASPACES_LITERAL) {
if (getLowLimit() != null && getHighLimit() != null) {
// GigaSpaces is inclusive.
int from = getLowLimit ();
int to = getHighLimit() -1;
ret.append("ROWNUM ( " + from + ", " + to + " )" );
} else {
if (lowLimit != null) {
ret.append("ROWNUM >= ");
ret.append("" + getLowLimit ());
}
if (highLimit != null) {
ret.append("ROWNUM < ");
ret.append("" + getHighLimit());
}
}
} else {
throw new IllegalArgumentException ("Format Not Supported: " + format);
}
return ret.toString();
}
public String formatCmpString(SqlFormat format) {
if (comparator != null) {
return comparator.constructSqlString(format);
}
return "";
}
}