/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.relational.cursors; import java.sql.ResultSet; import xxl.core.cursors.Cursor; import xxl.core.cursors.MetaDataCursor; import xxl.core.functions.Function; import xxl.core.predicates.ComparatorBasedEqual; import xxl.core.predicates.Not; import xxl.core.predicates.Predicate; import xxl.core.relational.metaData.ResultSetMetaDatas; import xxl.core.relational.tuples.Tuple; import xxl.core.relational.tuples.Tuples; import xxl.core.util.metaData.CompositeMetaData; /** * The sort-based grouper is an implementation of the group operator. It is * based on {@link xxl.core.cursors.groupers.SortBasedGrouper}. The input * relation has to be sorted so that all elements belonging to the same group * have to be in sequence. Then, a group is defined by a predicate that returns * false at the end of such a sequence. * * <p>A call to the <code>next</code> method returns a group (cursor) * containing all elements of a group.</p> * * <p>Usually, a * {@link xxl.core.relational.cursors.GroupAggregator group-aggregator} is * applied on the output of a grouper.</p> */ public class SortBasedGrouper extends xxl.core.cursors.groupers.SortBasedGrouper<Tuple> implements MetaDataCursor<Cursor<Tuple>, CompositeMetaData<Object, Object>> { /** * The metadata provided by the sort-based grouper. */ protected CompositeMetaData<Object, Object> globalMetaData; /** * Constructs an instance of the sort-based grouper. * * @param sortedCursor the sorted metadata cursor containing elements. * @param predicate the predicate that determines the borders of the groups. */ public SortBasedGrouper(MetaDataCursor<Tuple, CompositeMetaData<Object, Object>> sortedCursor, Predicate<? super Tuple> predicate) { super(sortedCursor, predicate); globalMetaData = new CompositeMetaData<Object, Object>(); globalMetaData.add(ResultSetMetaDatas.RESULTSET_METADATA_TYPE, ResultSetMetaDatas.getResultSetMetaData(sortedCursor)); } /** * Constructs an instance of the sort-based grouper. * * @param sortedCursor the sorted metadata cursor containing elements. * @param columns if the values in the passed column numbers differ, a new * group is created. The first column is 1, the second is 2, ... */ public SortBasedGrouper(MetaDataCursor<Tuple, CompositeMetaData<Object, Object>> sortedCursor, int[] columns) { this( sortedCursor, new Not<Tuple>( new ComparatorBasedEqual<Tuple>( Tuples.getTupleComparator(columns) ) ) ); } /** * Constructs an instance of the sort-based grouper. * * @param sortedResultSet the sorted result set containing elements. * @param createTuple a function that maps a (row of the) result set to a * tuple. The function gets a result set and maps the current row to * a tuple. If <code>null</code> is passed, the factory method of * array-tuple is used. It is forbidden to call the * <code>next</code>, <code>update</code> and similar methods of the * result set from inside the function! * @param predicate the predicate that determines the borders of the * groups. */ public SortBasedGrouper(ResultSet sortedResultSet, Function<? super ResultSet, ? extends Tuple> createTuple, Predicate<? super Tuple> predicate) { this( createTuple == null ? new ResultSetMetaDataCursor(sortedResultSet) : new ResultSetMetaDataCursor(sortedResultSet, createTuple), predicate ); } /** * Constructs an instance of the sort-based grouper. * * @param sortedResultSet the sorted result set containing elements. * @param createTuple a function that maps a (row of the) result set to a * tuple. The function gets a result set and maps the current row to * a tuple. If <code>null</code> is passed, the factory method of * array-tuple is used. It is forbidden to call the * <code>next</code>, <code>update</code> and similar methods of the * result set from inside the function! * @param columns if the values in the passed column numbers differ, a new * group is created. The first column is 1, the second is 2, ... */ public SortBasedGrouper(ResultSet sortedResultSet, Function<? super ResultSet, ? extends Tuple> createTuple, int[] columns) { this( sortedResultSet, createTuple, new Not<Tuple>( new ComparatorBasedEqual<Tuple>( Tuples.getTupleComparator(columns) ) ) ); } /** * Returns the metadata information for this metadata-cursor as a composite * metadata ({@link CompositeMetaData}). * * @return the metadata information for this metadata-cursor as a composite * metadata ({@link CompositeMetaData}). */ public CompositeMetaData<Object, Object> getMetaData() { return globalMetaData; } }