aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2011-12-27 15:41:17 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2011-12-27 15:41:17 +0000
commitfc3bd9e65c915a20a5e2e7768b134fb84482efe0 (patch)
tree7f1d6fa17769d0f6c3f553191c5f7d9a1b0539ac /src/java
parent01ec74adba79020318c2dc7ef2cafab6c7a0858c (diff)
downloadjackcess-fc3bd9e65c915a20a5e2e7768b134fb84482efe0.tar.gz
jackcess-fc3bd9e65c915a20a5e2e7768b134fb84482efe0.zip
Rename and refactor the Cursor find methods to improve usability
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@606 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src/java')
-rw-r--r--src/java/com/healthmarketscience/jackcess/Column.java2
-rw-r--r--src/java/com/healthmarketscience/jackcess/Cursor.java313
-rw-r--r--src/java/com/healthmarketscience/jackcess/Database.java8
-rw-r--r--src/java/com/healthmarketscience/jackcess/Index.java2
-rw-r--r--src/java/com/healthmarketscience/jackcess/IndexCursor.java58
-rw-r--r--src/java/com/healthmarketscience/jackcess/IndexData.java4
-rw-r--r--src/java/com/healthmarketscience/jackcess/Joiner.java17
-rw-r--r--src/java/com/healthmarketscience/jackcess/Table.java6
-rw-r--r--src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java4
-rw-r--r--src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java3
-rw-r--r--src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java5
11 files changed, 355 insertions, 67 deletions
diff --git a/src/java/com/healthmarketscience/jackcess/Column.java b/src/java/com/healthmarketscience/jackcess/Column.java
index 32a67ce..ce6050d 100644
--- a/src/java/com/healthmarketscience/jackcess/Column.java
+++ b/src/java/com/healthmarketscience/jackcess/Column.java
@@ -787,7 +787,7 @@ public class Column implements Comparable<Column> {
return rowArray[_columnIndex];
}
- public Object getRowValue(Map<String,Object> rowMap) {
+ public Object getRowValue(Map<String,?> rowMap) {
return rowMap.get(_name);
}
diff --git a/src/java/com/healthmarketscience/jackcess/Cursor.java b/src/java/com/healthmarketscience/jackcess/Cursor.java
index 623bebd..042241a 100644
--- a/src/java/com/healthmarketscience/jackcess/Cursor.java
+++ b/src/java/com/healthmarketscience/jackcess/Cursor.java
@@ -178,19 +178,22 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
/**
* Convenience method for finding a specific row in a table which matches a
- * given row "pattern". See {@link #findRow(Map)} for details on the
+ * given row "pattern". See {@link #findFirstRow(Map)} for details on the
* rowPattern.
+ * <p>
+ * Warning, this method <i>always</i> starts searching from the beginning of
+ * the Table (you cannot use it to find successive matches).
*
* @param table the table to search
* @param rowPattern pattern to be used to find the row
* @return the matching row or {@code null} if a match could not be found.
*/
public static Map<String,Object> findRow(Table table,
- Map<String,Object> rowPattern)
+ Map<String,?> rowPattern)
throws IOException
{
Cursor cursor = createCursor(table);
- if(cursor.findRow(rowPattern)) {
+ if(cursor.findFirstRow(rowPattern)) {
return cursor.getCurrentRow();
}
return null;
@@ -198,8 +201,8 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
/**
* Convenience method for finding a specific row in a table which matches a
- * given row "pattern". See {@link #findRow(Column,Object)} for details on
- * the pattern.
+ * given row "pattern". See {@link #findFirstRow(Column,Object)} for
+ * details on the pattern.
* <p>
* Note, a {@code null} result value is ambiguous in that it could imply no
* match or a matching row with {@code null} for the desired value. If
@@ -218,7 +221,7 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
throws IOException
{
Cursor cursor = createCursor(table);
- if(cursor.findRow(columnPattern, valuePattern)) {
+ if(cursor.findFirstRow(columnPattern, valuePattern)) {
return cursor.getCurrentRowValue(column);
}
return null;
@@ -226,8 +229,11 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
/**
* Convenience method for finding a specific row in an indexed table which
- * matches a given row "pattern". See {@link #findRow(Map)} for details on
- * the rowPattern.
+ * matches a given row "pattern". See {@link #findFirstRow(Map)} for
+ * details on the rowPattern.
+ * <p>
+ * Warning, this method <i>always</i> starts searching from the beginning of
+ * the Table (you cannot use it to find successive matches).
*
* @param table the table to search
* @param index index to assist the search
@@ -235,11 +241,11 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
* @return the matching row or {@code null} if a match could not be found.
*/
public static Map<String,Object> findRow(Table table, Index index,
- Map<String,Object> rowPattern)
+ Map<String,?> rowPattern)
throws IOException
{
Cursor cursor = createIndexCursor(table, index);
- if(cursor.findRow(rowPattern)) {
+ if(cursor.findFirstRow(rowPattern)) {
return cursor.getCurrentRow();
}
return null;
@@ -247,8 +253,8 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
/**
* Convenience method for finding a specific row in a table which matches a
- * given row "pattern". See {@link #findRow(Column,Object)} for details on
- * the pattern.
+ * given row "pattern". See {@link #findFirstRow(Column,Object)} for
+ * details on the pattern.
* <p>
* Note, a {@code null} result value is ambiguous in that it could imply no
* match or a matching row with {@code null} for the desired value. If
@@ -268,7 +274,7 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
throws IOException
{
Cursor cursor = createIndexCursor(table, index);
- if(cursor.findRow(columnPattern, valuePattern)) {
+ if(cursor.findFirstRow(columnPattern, valuePattern)) {
return cursor.getCurrentRowValue(column);
}
return null;
@@ -519,6 +525,128 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
}
/**
+ * Returns an Iterable whose iterator() method returns the result of a call
+ * to {@link #columnMatchIterable(Column,Object)}
+ * @throws IllegalStateException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ */
+ public Iterable<Map<String, Object>> columnMatchIterable(
+ Column columnPattern, Object valuePattern)
+ {
+ return columnMatchIterable(null, columnPattern, valuePattern);
+ }
+
+ /**
+ * Calls <code>beforeFirst</code> on this cursor and returns a modifiable
+ * Iterator which will iterate through all the rows of this table which
+ * match the given column pattern. Use of the Iterator follows the same
+ * restrictions as a call to <code>getNextRow</code>. See
+ * {@link #findFirstRow(Column,Object)} for details on the columnPattern.
+ * @throws IllegalStateException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ */
+ public Iterator<Map<String, Object>> columnMatchIterator(
+ Column columnPattern, Object valuePattern)
+ {
+ return columnMatchIterator(null, columnPattern, valuePattern);
+ }
+
+ /**
+ * Returns an Iterable whose iterator() method returns the result of a call
+ * to {@link #columnMatchIterator(Collection,Column,Object)}
+ * @throws IllegalStateException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ */
+ public Iterable<Map<String, Object>> columnMatchIterable(
+ final Collection<String> columnNames,
+ final Column columnPattern, final Object valuePattern)
+ {
+ return new Iterable<Map<String, Object>>() {
+ public Iterator<Map<String, Object>> iterator() {
+ return Cursor.this.columnMatchIterator(
+ columnNames, columnPattern, valuePattern);
+ }
+ };
+ }
+
+ /**
+ * Calls <code>beforeFirst</code> on this table and returns a modifiable
+ * Iterator which will iterate through all the rows of this table which
+ * match the given column pattern, returning only the given columns. Use of
+ * the Iterator follows the same restrictions as a call to
+ * <code>getNextRow</code>. See {@link #findFirstRow(Column,Object)} for
+ * details on the columnPattern.
+ * @throws IllegalStateException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ */
+ public Iterator<Map<String, Object>> columnMatchIterator(
+ Collection<String> columnNames, Column columnPattern, Object valuePattern)
+ {
+ return new ColumnMatchIterator(columnNames, columnPattern, valuePattern);
+ }
+
+ /**
+ * Returns an Iterable whose iterator() method returns the result of a call
+ * to {@link #rowMatchIterator(Map)}
+ * @throws IllegalStateException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ */
+ public Iterable<Map<String, Object>> rowMatchIterable(
+ Map<String,?> rowPattern)
+ {
+ return rowMatchIterable(null, rowPattern);
+ }
+
+ /**
+ * Calls <code>beforeFirst</code> on this cursor and returns a modifiable
+ * Iterator which will iterate through all the rows of this table which
+ * match the given row pattern. Use of the Iterator follows the same
+ * restrictions as a call to <code>getNextRow</code>. See
+ * {@link #findFirstRow(Map)} for details on the rowPattern.
+ * @throws IllegalStateException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ */
+ public Iterator<Map<String, Object>> rowMatchIterator(
+ Map<String,?> rowPattern)
+ {
+ return rowMatchIterator(null, rowPattern);
+ }
+
+ /**
+ * Returns an Iterable whose iterator() method returns the result of a call
+ * to {@link #rowMatchIterator(Collection,Map)}
+ * @throws IllegalStateException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ */
+ public Iterable<Map<String, Object>> rowMatchIterable(
+ final Collection<String> columnNames,
+ final Map<String,?> rowPattern)
+ {
+ return new Iterable<Map<String, Object>>() {
+ public Iterator<Map<String, Object>> iterator() {
+ return Cursor.this.rowMatchIterator(
+ columnNames, rowPattern);
+ }
+ };
+ }
+
+ /**
+ * Calls <code>beforeFirst</code> on this table and returns a modifiable
+ * Iterator which will iterate through all the rows of this table which
+ * match the given row pattern, returning only the given columns. Use of
+ * the Iterator follows the same restrictions as a call to
+ * <code>getNextRow</code>. See {@link #findFirstRow(Map)} for details on
+ * the rowPattern.
+ * @throws IllegalStateException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ */
+ public Iterator<Map<String, Object>> rowMatchIterator(
+ Collection<String> columnNames, Map<String,?> rowPattern)
+ {
+ return new RowMatchIterator(columnNames, rowPattern);
+ }
+
+ /**
* Delete the current row.
* @throws IllegalStateException if the current row is not valid (at
* beginning or end of table), or already deleted.
@@ -703,10 +831,23 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
}
/**
+ * @deprecated renamed to {@link #findFirstRow(Column,Object)} to be more clear
+ */
+ @Deprecated
+ public boolean findRow(Column columnPattern, Object valuePattern)
+ throws IOException
+ {
+ return findFirstRow(columnPattern, valuePattern);
+ }
+
+ /**
* Moves to the first row (as defined by the cursor) where the given column
* has the given value. This may be more efficient on some cursors than
* others. If a match is not found (or an exception is thrown), the cursor
* is restored to its previous state.
+ * <p>
+ * Warning, this method <i>always</i> starts searching from the beginning of
+ * the Table (you cannot use it to find successive matches).
*
* @param columnPattern column from the table for this cursor which is being
* matched by the valuePattern
@@ -715,14 +856,15 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
* @return {@code true} if a valid row was found with the given value,
* {@code false} if no row was found
*/
- public boolean findRow(Column columnPattern, Object valuePattern)
+ public boolean findFirstRow(Column columnPattern, Object valuePattern)
throws IOException
{
Position curPos = _curPos;
Position prevPos = _prevPos;
boolean found = false;
try {
- found = findRowImpl(columnPattern, valuePattern);
+ beforeFirst();
+ found = findNextRowImpl(columnPattern, valuePattern);
return found;
} finally {
if(!found) {
@@ -736,24 +878,102 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
}
/**
+ * Moves to the next row (as defined by the cursor) where the given column
+ * has the given value. This may be more efficient on some cursors than
+ * others. If a match is not found (or an exception is thrown), the cursor
+ * is restored to its previous state.
+ *
+ * @param columnPattern column from the table for this cursor which is being
+ * matched by the valuePattern
+ * @param valuePattern value which is equal to the corresponding value in
+ * the matched row
+ * @return {@code true} if a valid row was found with the given value,
+ * {@code false} if no row was found
+ */
+ public boolean findNextRow(Column columnPattern, Object valuePattern)
+ throws IOException
+ {
+ Position curPos = _curPos;
+ Position prevPos = _prevPos;
+ boolean found = false;
+ try {
+ found = findNextRowImpl(columnPattern, valuePattern);
+ return found;
+ } finally {
+ if(!found) {
+ try {
+ restorePosition(curPos, prevPos);
+ } catch(IOException e) {
+ LOG.error("Failed restoring position", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * @deprecated renamed to {@link #findFirstRow(Map)} to be more clear
+ */
+ @Deprecated
+ public boolean findRow(Map<String,?> rowPattern)
+ throws IOException
+ {
+ return findFirstRow(rowPattern);
+ }
+
+ /**
* Moves to the first row (as defined by the cursor) where the given columns
* have the given values. This may be more efficient on some cursors than
* others. If a match is not found (or an exception is thrown), the cursor
* is restored to its previous state.
+ * <p>
+ * Warning, this method <i>always</i> starts searching from the beginning of
+ * the Table (you cannot use it to find successive matches).
*
* @param rowPattern column names and values which must be equal to the
* corresponding values in the matched row
* @return {@code true} if a valid row was found with the given values,
* {@code false} if no row was found
*/
- public boolean findRow(Map<String,Object> rowPattern)
+ public boolean findFirstRow(Map<String,?> rowPattern)
throws IOException
{
Position curPos = _curPos;
Position prevPos = _prevPos;
boolean found = false;
try {
- found = findRowImpl(rowPattern);
+ beforeFirst();
+ found = findNextRowImpl(rowPattern);
+ return found;
+ } finally {
+ if(!found) {
+ try {
+ restorePosition(curPos, prevPos);
+ } catch(IOException e) {
+ LOG.error("Failed restoring position", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Moves to the next row (as defined by the cursor) where the given columns
+ * have the given values. This may be more efficient on some cursors than
+ * others. If a match is not found (or an exception is thrown), the cursor
+ * is restored to its previous state.
+ *
+ * @param rowPattern column names and values which must be equal to the
+ * corresponding values in the matched row
+ * @return {@code true} if a valid row was found with the given values,
+ * {@code false} if no row was found
+ */
+ public boolean findNextRow(Map<String,?> rowPattern)
+ throws IOException
+ {
+ Position curPos = _curPos;
+ Position prevPos = _prevPos;
+ boolean found = false;
+ try {
+ found = findNextRowImpl(rowPattern);
return found;
} finally {
if(!found) {
@@ -786,7 +1006,7 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
* @param rowPattern column names and values which must be equal to the
* corresponding values in the current row
*/
- public boolean currentRowMatches(Map<String,Object> rowPattern)
+ public boolean currentRowMatches(Map<String,?> rowPattern)
throws IOException
{
Map<String,Object> row = getCurrentRow(rowPattern.keySet());
@@ -807,7 +1027,7 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
}
/**
- * Moves to the first row (as defined by the cursor) where the given column
+ * Moves to the next row (as defined by the cursor) where the given column
* has the given value. Caller manages save/restore on failure.
* <p>
* Default implementation scans the table from beginning to end.
@@ -819,10 +1039,9 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
* @return {@code true} if a valid row was found with the given value,
* {@code false} if no row was found
*/
- protected boolean findRowImpl(Column columnPattern, Object valuePattern)
+ protected boolean findNextRowImpl(Column columnPattern, Object valuePattern)
throws IOException
{
- beforeFirst();
while(moveToNextRow()) {
if(currentRowMatches(columnPattern, valuePattern)) {
return true;
@@ -832,7 +1051,7 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
}
/**
- * Moves to the first row (as defined by the cursor) where the given columns
+ * Moves to the next row (as defined by the cursor) where the given columns
* have the given values. Caller manages save/restore on failure.
* <p>
* Default implementation scans the table from beginning to end.
@@ -842,10 +1061,9 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
* @return {@code true} if a valid row was found with the given values,
* {@code false} if no row was found
*/
- protected boolean findRowImpl(Map<String,Object> rowPattern)
+ protected boolean findNextRowImpl(Map<String,?> rowPattern)
throws IOException
{
- beforeFirst();
while(moveToNextRow()) {
if(currentRowMatches(rowPattern)) {
return true;
@@ -1040,6 +1258,53 @@ public abstract class Cursor implements Iterable<Map<String, Object>>
}
}
+
+ /**
+ * Row iterator for this cursor, modifiable.
+ */
+ private final class ColumnMatchIterator extends BaseIterator
+ {
+ private final Column _columnPattern;
+ private final Object _valuePattern;
+
+ private ColumnMatchIterator(Collection<String> columnNames,
+ Column columnPattern, Object valuePattern)
+ {
+ super(columnNames);
+ _columnPattern = columnPattern;
+ _valuePattern = valuePattern;
+ beforeFirst();
+ }
+
+ @Override
+ protected boolean findNext() throws IOException {
+ return findNextRow(_columnPattern, _valuePattern);
+ }
+ }
+
+
+ /**
+ * Row iterator for this cursor, modifiable.
+ */
+ private final class RowMatchIterator extends BaseIterator
+ {
+ private final Map<String,?> _rowPattern;
+
+ private RowMatchIterator(Collection<String> columnNames,
+ Map<String,?> rowPattern)
+ {
+ super(columnNames);
+ _rowPattern = rowPattern;
+ beforeFirst();
+ }
+
+ @Override
+ protected boolean findNext() throws IOException {
+ return findNextRow(_rowPattern);
+ }
+ }
+
+
/**
* Handles moving the cursor in a given direction. Separates cursor
* logic from value storage.
diff --git a/src/java/com/healthmarketscience/jackcess/Database.java b/src/java/com/healthmarketscience/jackcess/Database.java
index 5b5e9d5..174f95f 100644
--- a/src/java/com/healthmarketscience/jackcess/Database.java
+++ b/src/java/com/healthmarketscience/jackcess/Database.java
@@ -2168,7 +2168,7 @@ public class Database
protected Cursor findRow(Integer parentId, String name)
throws IOException
{
- return (_systemCatalogCursor.findRowByEntry(parentId, name) ?
+ return (_systemCatalogCursor.findFirstRowByEntry(parentId, name) ?
_systemCatalogCursor : null);
}
@@ -2181,7 +2181,7 @@ public class Database
.toIndexCursor();
}
- return (_systemCatalogIdCursor.findRowByEntry(objectId) ?
+ return (_systemCatalogIdCursor.findFirstRowByEntry(objectId) ?
_systemCatalogIdCursor : null);
}
@@ -2234,7 +2234,7 @@ public class Database
Map<String,Object> rowPat = new HashMap<String,Object>();
rowPat.put(CAT_COL_PARENT_ID, parentId);
rowPat.put(CAT_COL_NAME, name);
- return (_systemCatalogCursor.findRow(rowPat) ?
+ return (_systemCatalogCursor.findFirstRow(rowPat) ?
_systemCatalogCursor : null);
}
@@ -2242,7 +2242,7 @@ public class Database
protected Cursor findRow(Integer objectId) throws IOException
{
Column idCol = _systemCatalog.getColumn(CAT_COL_ID);
- return (_systemCatalogCursor.findRow(idCol, objectId) ?
+ return (_systemCatalogCursor.findFirstRow(idCol, objectId) ?
_systemCatalogCursor : null);
}
diff --git a/src/java/com/healthmarketscience/jackcess/Index.java b/src/java/com/healthmarketscience/jackcess/Index.java
index 88b5237..9fc24c3 100644
--- a/src/java/com/healthmarketscience/jackcess/Index.java
+++ b/src/java/com/healthmarketscience/jackcess/Index.java
@@ -356,7 +356,7 @@ public class Index implements Comparable<Index> {
* @return the appropriate sparse array of data or {@code null} if not all
* columns for this index were provided
*/
- public Object[] constructIndexRow(Map<String,Object> row)
+ public Object[] constructIndexRow(Map<String,?> row)
{
return getIndexData().constructIndexRow(row);
}
diff --git a/src/java/com/healthmarketscience/jackcess/IndexCursor.java b/src/java/com/healthmarketscience/jackcess/IndexCursor.java
index 6d02fa2..aa77b65 100644
--- a/src/java/com/healthmarketscience/jackcess/IndexCursor.java
+++ b/src/java/com/healthmarketscience/jackcess/IndexCursor.java
@@ -48,7 +48,7 @@ public class IndexCursor extends Cursor
new ReverseIndexDirHandler();
/** logical index which this cursor is using */
private final Index _index;
- /** Cursor over the entries of the relvant index */
+ /** Cursor over the entries of the relevant index */
private final IndexData.EntryCursor _entryCursor;
/** column names for the index entry columns */
private Set<String> _indexEntryPattern;
@@ -157,22 +157,36 @@ public class IndexCursor extends Cursor
}
/**
+ * @deprecated renamed to {@link #findFirstRowByEntry(Object...)} to be more
+ * clear
+ */
+ @Deprecated
+ public boolean findRowByEntry(Object... entryValues)
+ throws IOException
+ {
+ return findFirstRowByEntry(entryValues);
+ }
+
+ /**
* Moves to the first row (as defined by the cursor) where the index entries
* match the given values. If a match is not found (or an exception is
* thrown), the cursor is restored to its previous state.
+ * <p>
+ * Warning, this method <i>always</i> starts searching from the beginning of
+ * the Table (you cannot use it to find successive matches).
*
* @param entryValues the column values for the index's columns.
* @return {@code true} if a valid row was found with the given values,
* {@code false} if no row was found
*/
- public boolean findRowByEntry(Object... entryValues)
+ public boolean findFirstRowByEntry(Object... entryValues)
throws IOException
{
Position curPos = _curPos;
Position prevPos = _prevPos;
boolean found = false;
try {
- found = findRowByEntryImpl(toRowValues(entryValues), true);
+ found = findFirstRowByEntryImpl(toRowValues(entryValues), true);
return found;
} finally {
if(!found) {
@@ -199,7 +213,7 @@ public class IndexCursor extends Cursor
Position prevPos = _prevPos;
boolean found = false;
try {
- findRowByEntryImpl(toRowValues(entryValues), false);
+ findFirstRowByEntryImpl(toRowValues(entryValues), false);
found = true;
} finally {
if(!found) {
@@ -305,15 +319,21 @@ public class IndexCursor extends Cursor
}
@Override
- protected boolean findRowImpl(Column columnPattern, Object valuePattern)
+ protected boolean findNextRowImpl(Column columnPattern, Object valuePattern)
throws IOException
{
+ if(!isBeforeFirst()) {
+ // use the default table scan for finding rows mid-cursor
+ return super.findNextRowImpl(columnPattern, valuePattern);
+ }
+
+ // searching for the first match
Object[] rowValues = _entryCursor.getIndexData().constructIndexRow(
columnPattern.getName(), valuePattern);
if(rowValues == null) {
// bummer, use the default table scan
- return super.findRowImpl(columnPattern, valuePattern);
+ return super.findNextRowImpl(columnPattern, valuePattern);
}
// sweet, we can use our index
@@ -335,8 +355,8 @@ public class IndexCursor extends Cursor
* @return {@code true} if a valid row was found with the given values,
* {@code false} if no row was found
*/
- protected boolean findRowByEntryImpl(Object[] rowValues,
- boolean requireMatch)
+ protected boolean findFirstRowByEntryImpl(Object[] rowValues,
+ boolean requireMatch)
throws IOException
{
if(!findPotentialRow(rowValues, requireMatch)) {
@@ -350,17 +370,23 @@ public class IndexCursor extends Cursor
}
@Override
- protected boolean findRowImpl(Map<String,Object> rowPattern)
+ protected boolean findNextRowImpl(Map<String,?> rowPattern)
throws IOException
{
+ if(!isBeforeFirst()) {
+ // use the default table scan for finding rows mid-cursor
+ return super.findNextRowImpl(rowPattern);
+ }
+
+ // searching for the first match
IndexData indexData = _entryCursor.getIndexData();
Object[] rowValues = indexData.constructIndexRow(rowPattern);
if(rowValues == null) {
// bummer, use the default table scan
- return super.findRowImpl(rowPattern);
+ return super.findNextRowImpl(rowPattern);
}
-
+
// sweet, we can use our index
if(!findPotentialRow(rowValues, true)) {
// at end of index, no potential matches
@@ -368,7 +394,7 @@ public class IndexCursor extends Cursor
}
// find actual matching row
- Map<String,Object> indexRowPattern = null;
+ Map<String,?> indexRowPattern = null;
if(rowPattern.size() == indexData.getColumns().size()) {
// the rowPattern matches our index columns exactly, so we can
// streamline our testing below
@@ -376,10 +402,10 @@ public class IndexCursor extends Cursor
} else {
// the rowPattern has more columns than just the index, so we need to
// do more work when testing below
- indexRowPattern = new LinkedHashMap<String,Object>();
+ Map<String,Object> tmpRowPattern = new LinkedHashMap<String,Object>();
+ indexRowPattern = tmpRowPattern;
for(IndexData.ColumnDescriptor idxCol : indexData.getColumns()) {
- indexRowPattern.put(idxCol.getName(),
- rowValues[idxCol.getColumnIndex()]);
+ tmpRowPattern.put(idxCol.getName(), rowValues[idxCol.getColumnIndex()]);
}
}
@@ -562,7 +588,7 @@ public class IndexCursor extends Cursor
super(columnNames);
_rowValues = rowValues;
try {
- _hasNext = findRowByEntryImpl(rowValues, true);
+ _hasNext = findFirstRowByEntryImpl(rowValues, true);
_validRow = _hasNext;
} catch(IOException e) {
throw new IllegalStateException(e);
diff --git a/src/java/com/healthmarketscience/jackcess/IndexData.java b/src/java/com/healthmarketscience/jackcess/IndexData.java
index 383bf24..637f763 100644
--- a/src/java/com/healthmarketscience/jackcess/IndexData.java
+++ b/src/java/com/healthmarketscience/jackcess/IndexData.java
@@ -817,14 +817,14 @@ public abstract class IndexData {
{
return constructIndexRow(Collections.singletonMap(colName, value));
}
-
+
/**
* Constructs an array of values appropriate for this index from the given
* column values.
* @return the appropriate sparse array of data or {@code null} if not all
* columns for this index were provided
*/
- public Object[] constructIndexRow(Map<String,Object> row)
+ public Object[] constructIndexRow(Map<String,?> row)
{
for(ColumnDescriptor col : _columns) {
if(!row.containsKey(col.getName())) {
diff --git a/src/java/com/healthmarketscience/jackcess/Joiner.java b/src/java/com/healthmarketscience/jackcess/Joiner.java
index 89da959..3b51854 100644
--- a/src/java/com/healthmarketscience/jackcess/Joiner.java
+++ b/src/java/com/healthmarketscience/jackcess/Joiner.java
@@ -121,7 +121,7 @@ public class Joiner
* @param fromRow row from the "from" table (which must include the relevant
* columns for this join relationship)
*/
- public Map<String,Object> findFirstRow(Map<String,Object> fromRow)
+ public Map<String,Object> findFirstRow(Map<String,?> fromRow)
throws IOException
{
return findFirstRow(fromRow, null);
@@ -136,12 +136,12 @@ public class Joiner
* columns for this join relationship)
* @param columnNames desired columns in the from table row
*/
- public Map<String,Object> findFirstRow(Map<String,Object> fromRow,
+ public Map<String,Object> findFirstRow(Map<String,?> fromRow,
Collection<String> columnNames)
throws IOException
{
toEntryValues(fromRow);
- return ((_toCursor.findRowByEntry(_entryValues) ?
+ return ((_toCursor.findFirstRowByEntry(_entryValues) ?
_toCursor.getCurrentRow(columnNames) : null));
}
@@ -152,7 +152,7 @@ public class Joiner
* @param fromRow row from the "from" table (which must include the relevant
* columns for this join relationship)
*/
- public Iterator<Map<String,Object>> findRows(Map<String,Object> fromRow)
+ public Iterator<Map<String,Object>> findRows(Map<String,?> fromRow)
{
return findRows(fromRow, null);
}
@@ -165,7 +165,7 @@ public class Joiner
* columns for this join relationship)
* @param columnNames desired columns in the from table row
*/
- public Iterator<Map<String,Object>> findRows(Map<String,Object> fromRow,
+ public Iterator<Map<String,Object>> findRows(Map<String,?> fromRow,
Collection<String> columnNames)
{
toEntryValues(fromRow);
@@ -181,8 +181,7 @@ public class Joiner
* @throws IllegalStateException if an IOException is thrown by one of the
* operations, the actual exception will be contained within
*/
- public Iterable<Map<String,Object>> findRowsIterable(
- Map<String,Object> fromRow)
+ public Iterable<Map<String,Object>> findRowsIterable(Map<String,?> fromRow)
{
return findRowsIterable(fromRow, null);
}
@@ -198,7 +197,7 @@ public class Joiner
* operations, the actual exception will be contained within
*/
public Iterable<Map<String,Object>> findRowsIterable(
- final Map<String,Object> fromRow, final Collection<String> columnNames)
+ final Map<String,?> fromRow, final Collection<String> columnNames)
{
return new Iterable<Map<String, Object>>() {
public Iterator<Map<String, Object>> iterator() {
@@ -211,7 +210,7 @@ public class Joiner
* Fills in the _entryValues with the relevant info from the given "from"
* table row.
*/
- private void toEntryValues(Map<String,Object> fromRow)
+ private void toEntryValues(Map<String,?> fromRow)
{
for(int i = 0; i < _entryValues.length; ++i) {
_entryValues[i] = fromRow.get(_fromCols.get(i).getName());
diff --git a/src/java/com/healthmarketscience/jackcess/Table.java b/src/java/com/healthmarketscience/jackcess/Table.java
index ba7b675..ae8b128 100644
--- a/src/java/com/healthmarketscience/jackcess/Table.java
+++ b/src/java/com/healthmarketscience/jackcess/Table.java
@@ -1339,7 +1339,7 @@ public class Table
* appropriate for a call to {@link #addRow(Object...)}.
* @usage _general_method_
*/
- public Object[] asRow(Map<String,Object> rowMap) {
+ public Object[] asRow(Map<String,?> rowMap) {
return asRow(rowMap, null);
}
@@ -1348,14 +1348,14 @@ public class Table
* appropriate for a call to {@link #updateCurrentRow(Object...)}.
* @usage _general_method_
*/
- public Object[] asUpdateRow(Map<String,Object> rowMap) {
+ public Object[] asUpdateRow(Map<String,?> rowMap) {
return asRow(rowMap, Column.KEEP_VALUE);
}
/**
* Converts a map of columnName -> columnValue to an array of row values.
*/
- private Object[] asRow(Map<String,Object> rowMap, Object defaultValue)
+ private Object[] asRow(Map<String,?> rowMap, Object defaultValue)
{
Object[] row = new Object[_columns.size()];
if(defaultValue != null) {
diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java
index f9de56d..0a4b255 100644
--- a/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java
+++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java
@@ -112,7 +112,7 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
Table complexColumns = db.getSystemComplexColumns();
IndexCursor cursor = IndexCursor.createCursor(
complexColumns, complexColumns.getPrimaryKeyIndex());
- if(!cursor.findRowByEntry(complexTypeId)) {
+ if(!cursor.findFirstRowByEntry(complexTypeId)) {
throw new IOException(
"Could not find complex column info for complex column with id " +
complexTypeId);
@@ -333,7 +333,7 @@ public abstract class ComplexColumnInfo<V extends ComplexValue>
.toIndexCursor();
}
- if(!_pkCursor.findRowByEntry(id)) {
+ if(!_pkCursor.findFirstRowByEntry(id)) {
throw new IllegalArgumentException("Row with id " + id +
" does not exist");
}
diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java
index ba31a3b..c8678a2 100644
--- a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java
+++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java
@@ -256,8 +256,7 @@ public class ComplexValueForeignKey extends Number
return value;
}
- public UnsupportedValue addUnsupportedValue(
- Map<String,? extends Object> values)
+ public UnsupportedValue addUnsupportedValue(Map<String,?> values)
throws IOException
{
reset();
diff --git a/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java
index 27ee434..03bd8b1 100644
--- a/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java
+++ b/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java
@@ -79,13 +79,12 @@ public class UnsupportedColumnInfo extends ComplexColumnInfo<UnsupportedValue>
return row;
}
- public static UnsupportedValue newValue(Map<String,? extends Object> values) {
+ public static UnsupportedValue newValue(Map<String,?> values) {
return newValue(INVALID_COMPLEX_VALUE_ID, values);
}
public static UnsupportedValue newValue(
- ComplexValueForeignKey complexValueFk,
- Map<String,? extends Object> values) {
+ ComplexValueForeignKey complexValueFk, Map<String,?> values) {
return new UnsupportedValueImpl(INVALID_ID, complexValueFk,
new LinkedHashMap<String,Object>(values));
}