/* 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 java.sql.ResultSetMetaData; import xxl.core.cursors.MetaDataCursor; import xxl.core.cursors.unions.Sequentializer; import xxl.core.functions.Function; import xxl.core.relational.metaData.ResultSetMetaDatas; import xxl.core.relational.tuples.Tuple; import xxl.core.util.metaData.CompositeMetaData; import xxl.core.util.metaData.MetaDataException; /** * Union is a straight forward implementation of the operator union. It is * based on {@link Sequentializer}. The elements of both input relations become * appended. The metadata of both inputs has to be compatible. * * <p>The example in the main method wraps two cursors containing tuples * representing the elements of enumerations (integers 0 to 9 and integers 10 * to 19) to metadata cursors using * {@link xxl.core.cursors.Cursors#wrapToMetaDataCursor(java.util.Iterator, Object)}. * Then, the union operator is applied.</p> */ public class Union extends Sequentializer<Tuple> implements MetaDataCursor<Tuple, CompositeMetaData<Object, Object>> { /** * The metadata provided by the selection. */ protected CompositeMetaData<Object, Object> globalMetaData; /** * Constructs an instance of the union operator. * * @param cursor1 the first metadata cursor containing the input elements. * @param cursor2 the second metadata cursor containing the input elements. */ public Union(MetaDataCursor<Tuple, CompositeMetaData<Object, Object>> cursor1, MetaDataCursor<Tuple, CompositeMetaData<Object, Object>> cursor2) { super(cursor1, cursor2); ResultSetMetaData metaData1 = ResultSetMetaDatas.getResultSetMetaData(cursor1); ResultSetMetaData metaData2 = ResultSetMetaDatas.getResultSetMetaData(cursor2); if (ResultSetMetaDatas.RESULTSET_METADATA_COMPARATOR.compare(metaData1, metaData2) != 0) throw new MetaDataException("the difference of the given cursors cannot be computed because they differ in their relational metadata"); globalMetaData = new CompositeMetaData<Object, Object>(); globalMetaData.add(ResultSetMetaDatas.RESULTSET_METADATA_TYPE, metaData1); } /** * Constructs an instance of the union operator. * * @param resultSet1 the first input result set delivering the elements. * The result set is wrapped internally to a metadata cursor using * {@link ResultSetMetaDataCursor}. * @param resultSet2 the second input result set delivering the elements. * The result set is wrapped internally to a metadata cursor using * {@link ResultSetMetaDataCursor}. * @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! */ public Union(ResultSet resultSet1, ResultSet resultSet2, Function<? super ResultSet, ? extends Tuple> createTuple ) { this(new ResultSetMetaDataCursor(resultSet1, createTuple), new ResultSetMetaDataCursor(resultSet2, createTuple)); } /** * 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; } }