123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- /*
- Copyright (c) 2007 Health Market Science, Inc.
-
- 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 2.1 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, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- USA
-
- You can contact Health Market Science at info@healthmarketscience.com
- or at the following address:
-
- Health Market Science
- 2700 Horizon Drive
- Suite 200
- King of Prussia, PA 19406
- */
-
- package com.healthmarketscience.jackcess;
-
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.Iterator;
- import java.util.List;
-
-
- /**
- * Builder style class for constructing a Cursor. By default, a cursor is
- * created at the beginning of the table, and any start/end rows are
- * inclusive.
- *
- * @author James Ahlborn
- */
- public class CursorBuilder {
- /** the table which the cursor will traverse */
- private final Table _table;
- /** optional index to use in traversal */
- private Index _index;
- /** optional start row for an index cursor */
- private Object[] _startRow;
- /** whether or not start row for an index cursor is inclusive */
- private boolean _startRowInclusive = true;
- /** optional end row for an index cursor */
- private Object[] _endRow;
- /** whether or not end row for an index cursor is inclusive */
- private boolean _endRowInclusive = true;
- /** whether to start at beginning or end of cursor */
- private boolean _beforeFirst = true;
- /** optional save point to restore to the cursor */
- private Cursor.Savepoint _savepoint;
- /** ColumnMatcher to be used when matching column values */
- private ColumnMatcher _columnMatcher;
-
- public CursorBuilder(Table table) {
- _table = table;
- }
-
- /**
- * Sets the cursor so that it will start at the beginning (unless a
- * savepoint is given).
- */
- public CursorBuilder beforeFirst() {
- _beforeFirst = true;
- return this;
- }
-
- /**
- * Sets the cursor so that it will start at the end (unless a savepoint is
- * given).
- */
- public CursorBuilder afterLast() {
- _beforeFirst = false;
- return this;
- }
-
- /**
- * Sets a savepoint to restore for the initial position of the cursor.
- */
- public CursorBuilder restoreSavepoint(Cursor.Savepoint savepoint) {
- _savepoint = savepoint;
- return this;
- }
-
- /**
- * Sets an index to use for the cursor.
- */
- public CursorBuilder setIndex(Index index) {
- _index = index;
- return this;
- }
-
- /**
- * Sets an index to use for the cursor by searching the table for an index
- * with the given name.
- * @throws IllegalArgumentException if no index can be found on the table
- * with the given name
- */
- public CursorBuilder setIndexByName(String indexName) {
- return setIndex(_table.getIndex(indexName));
- }
-
- /**
- * Sets an index to use for the cursor by searching the table for an index
- * with exactly the given columns.
- * @throws IllegalArgumentException if no index can be found on the table
- * with the given columns
- */
- public CursorBuilder setIndexByColumnNames(String... columnNames) {
- return setIndexByColumns(Arrays.asList(columnNames));
- }
-
- /**
- * Sets an index to use for the cursor by searching the table for an index
- * with exactly the given columns.
- * @throws IllegalArgumentException if no index can be found on the table
- * with the given columns
- */
- public CursorBuilder setIndexByColumns(Column... columns) {
- List<String> colNames = new ArrayList<String>();
- for(Column col : columns) {
- colNames.add(col.getName());
- }
- return setIndexByColumns(colNames);
- }
-
- /**
- * Searches for an index with the given column names.
- */
- private CursorBuilder setIndexByColumns(List<String> searchColumns) {
- boolean found = false;
- for(Index index : _table.getIndexes()) {
-
- Collection<IndexData.ColumnDescriptor> indexColumns = index.getColumns();
- if(indexColumns.size() != searchColumns.size()) {
- continue;
- }
- Iterator<String> sIter = searchColumns.iterator();
- Iterator<IndexData.ColumnDescriptor> iIter = indexColumns.iterator();
- boolean matches = true;
- while(sIter.hasNext()) {
- String sColName = sIter.next();
- String iColName = iIter.next().getName();
- if((sColName != iColName) &&
- ((sColName == null) || !sColName.equalsIgnoreCase(iColName))) {
- matches = false;
- break;
- }
- }
-
- if(matches) {
- _index = index;
- found = true;
- break;
- }
- }
- if(!found) {
- throw new IllegalArgumentException("Index with columns " +
- searchColumns +
- " does not exist in table " + _table);
- }
- return this;
- }
-
- /**
- * Sets the starting and ending row for a range based index cursor.
- * <p>
- * A valid index must be specified before calling this method.
- */
- public CursorBuilder setSpecificRow(Object[] specificRow) {
- setStartRow(specificRow);
- setEndRow(specificRow);
- return this;
- }
-
- /**
- * Sets the starting and ending row for a range based index cursor to the
- * given entry (where the given values correspond to the index's columns).
- * <p>
- * A valid index must be specified before calling this method.
- */
- public CursorBuilder setSpecificEntry(Object... specificEntry) {
- if(specificEntry != null) {
- setSpecificRow(_index.constructIndexRowFromEntry(specificEntry));
- }
- return this;
- }
-
-
- /**
- * Sets the starting row for a range based index cursor.
- * <p>
- * A valid index must be specified before calling this method.
- */
- public CursorBuilder setStartRow(Object[] startRow) {
- _startRow = startRow;
- return this;
- }
-
- /**
- * Sets the starting row for a range based index cursor to the given entry
- * (where the given values correspond to the index's columns).
- * <p>
- * A valid index must be specified before calling this method.
- */
- public CursorBuilder setStartEntry(Object... startEntry) {
- if(startEntry != null) {
- setStartRow(_index.constructIndexRowFromEntry(startEntry));
- }
- return this;
- }
-
- /**
- * Sets whether the starting row for a range based index cursor is inclusive
- * or exclusive.
- */
- public CursorBuilder setStartRowInclusive(boolean inclusive) {
- _startRowInclusive = inclusive;
- return this;
- }
-
- /**
- * Sets the ending row for a range based index cursor.
- * <p>
- * A valid index must be specified before calling this method.
- */
- public CursorBuilder setEndRow(Object[] endRow) {
- _endRow = endRow;
- return this;
- }
-
- /**
- * Sets the ending row for a range based index cursor to the given entry
- * (where the given values correspond to the index's columns).
- * <p>
- * A valid index must be specified before calling this method.
- */
- public CursorBuilder setEndEntry(Object... endEntry) {
- if(endEntry != null) {
- setEndRow(_index.constructIndexRowFromEntry(endEntry));
- }
- return this;
- }
-
- /**
- * Sets whether the ending row for a range based index cursor is inclusive
- * or exclusive.
- */
- public CursorBuilder setEndRowInclusive(boolean inclusive) {
- _endRowInclusive = inclusive;
- return this;
- }
-
- /**
- * Sets the ColumnMatcher to use for matching row patterns.
- */
- public CursorBuilder setColumnMatcher(ColumnMatcher columnMatcher) {
- _columnMatcher = columnMatcher;
- return this;
- }
-
- /**
- * Returns a new cursor for the table, constructed to the given
- * specifications.
- */
- public Cursor toCursor()
- throws IOException
- {
- Cursor cursor = null;
- if(_index == null) {
- cursor = Cursor.createCursor(_table);
- } else {
- cursor = Cursor.createIndexCursor(_table, _index,
- _startRow, _startRowInclusive,
- _endRow, _endRowInclusive);
- }
- cursor.setColumnMatcher(_columnMatcher);
- if(_savepoint == null) {
- if(!_beforeFirst) {
- cursor.afterLast();
- }
- } else {
- cursor.restoreSavepoint(_savepoint);
- }
- return cursor;
- }
-
- /**
- * Returns a new index cursor for the table, constructed to the given
- * specifications.
- */
- public IndexCursor toIndexCursor()
- throws IOException
- {
- return (IndexCursor)toCursor();
- }
-
- }
|