git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1321 f203690c-595d-4dc9-a70b-905162fa7fd2tags/jackcess-3.5.0
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
import com.healthmarketscience.jackcess.util.ColumnMatcher; | import com.healthmarketscience.jackcess.util.ColumnMatcher; | ||||
import com.healthmarketscience.jackcess.util.ErrorHandler; | import com.healthmarketscience.jackcess.util.ErrorHandler; | ||||
@Override | @Override | ||||
public Iterator<Row> iterator(); | public Iterator<Row> iterator(); | ||||
/** | |||||
* @return a Stream using the default Iterator. | |||||
*/ | |||||
default public Stream<Row> stream() { | |||||
return StreamSupport.stream(spliterator(), false); | |||||
} | |||||
/** | /** | ||||
* Convenience method for constructing a new IterableBuilder for this | * Convenience method for constructing a new IterableBuilder for this | ||||
* cursor. An IterableBuilder provides a variety of options for more | * cursor. An IterableBuilder provides a variety of options for more | ||||
* @throws IllegalStateException if the current row is not valid (at | * @throws IllegalStateException if the current row is not valid (at | ||||
* beginning or end of table), or deleted. | * beginning or end of table), or deleted. | ||||
*/ | */ | ||||
public <M extends Map<String,Object>> M updateCurrentRowFromMap(M row) | |||||
public <M extends Map<String,Object>> M updateCurrentRowFromMap(M row) | |||||
throws IOException; | throws IOException; | ||||
/** | /** | ||||
* @return The next row in this table (Column name -> Column value), or | * @return The next row in this table (Column name -> Column value), or | ||||
* {@code null} if no next row is found | * {@code null} if no next row is found | ||||
*/ | */ | ||||
public Row getNextRow(Collection<String> columnNames) | |||||
public Row getNextRow(Collection<String> columnNames) | |||||
throws IOException; | throws IOException; | ||||
/** | /** | ||||
* @return The previous row in this table (Column name -> Column value), or | * @return The previous row in this table (Column name -> Column value), or | ||||
* {@code null} if no previous row is found | * {@code null} if no previous row is found | ||||
*/ | */ | ||||
public Row getPreviousRow(Collection<String> columnNames) | |||||
public Row getPreviousRow(Collection<String> columnNames) | |||||
throws IOException; | throws IOException; | ||||
/** | /** | ||||
* otherwise | * otherwise | ||||
*/ | */ | ||||
public boolean moveToPreviousRow() throws IOException; | public boolean moveToPreviousRow() throws IOException; | ||||
/** | /** | ||||
* Moves to the row with the given rowId. If the row is not found (or an | * Moves to the row with the given rowId. If the row is not found (or an | ||||
* exception is thrown), the cursor is restored to its previous state. | * exception is thrown), the cursor is restored to its previous state. | ||||
* | |||||
* | |||||
* @return {@code true} if a valid row was found with the given id, | * @return {@code true} if a valid row was found with the given id, | ||||
* {@code false} if no row was found | * {@code false} if no row was found | ||||
*/ | */ | ||||
* Savepoint. | * Savepoint. | ||||
*/ | */ | ||||
public interface Id | public interface Id | ||||
{ | |||||
{ | |||||
} | } | ||||
/** | /** | ||||
* Value object which maintains the current position of the cursor. | * Value object which maintains the current position of the cursor. | ||||
*/ | */ | ||||
public interface Position | public interface Position | ||||
{ | |||||
{ | |||||
/** | /** | ||||
* Returns the unique RowId of the position of the cursor. | * Returns the unique RowId of the position of the cursor. | ||||
*/ | */ |
import java.util.Map; | import java.util.Map; | ||||
import java.util.Set; | import java.util.Set; | ||||
import java.util.TimeZone; | import java.util.TimeZone; | ||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
import com.healthmarketscience.jackcess.expr.EvalConfig; | import com.healthmarketscience.jackcess.expr.EvalConfig; | ||||
import com.healthmarketscience.jackcess.impl.DatabaseImpl; | import com.healthmarketscience.jackcess.impl.DatabaseImpl; | ||||
@Override | @Override | ||||
public Iterator<Table> iterator(); | public Iterator<Table> iterator(); | ||||
/** | |||||
* @return a Stream using the default Iterator. | |||||
*/ | |||||
default public Stream<Table> stream() { | |||||
return StreamSupport.stream(spliterator(), false); | |||||
} | |||||
/** | /** | ||||
* Convenience method for constructing a new TableIterableBuilder for this | * Convenience method for constructing a new TableIterableBuilder for this | ||||
* cursor. A TableIterableBuilder provides a variety of options for more | * cursor. A TableIterableBuilder provides a variety of options for more | ||||
*/ | */ | ||||
public Iterable<TableMetaData> newTableMetaDataIterable(); | public Iterable<TableMetaData> newTableMetaDataIterable(); | ||||
/** | |||||
* @return a Stream using the {@link #newTableMetaDataIterable} | |||||
*/ | |||||
default public Stream<TableMetaData> newTableMetaDataStream() { | |||||
return StreamSupport.stream( | |||||
newTableMetaDataIterable().spliterator(), false); | |||||
} | |||||
/** | /** | ||||
* @param name User table name (case-insensitive) | * @param name User table name (case-insensitive) | ||||
* @return The Table, or null if it doesn't exist (or is a system table) | * @return The Table, or null if it doesn't exist (or is a system table) |
package com.healthmarketscience.jackcess; | package com.healthmarketscience.jackcess; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
/** | /** | ||||
* Map of properties for a database object. | * Map of properties for a database object. | ||||
*/ | */ | ||||
public void save() throws IOException; | public void save() throws IOException; | ||||
/** | |||||
* @return a Stream using the default Iterator. | |||||
*/ | |||||
default public Stream<PropertyMap.Property> stream() { | |||||
return StreamSupport.stream(spliterator(), false); | |||||
} | |||||
/** | /** | ||||
* Info about a property defined in a PropertyMap. | * Info about a property defined in a PropertyMap. | ||||
*/ | */ |
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
import com.healthmarketscience.jackcess.util.ErrorHandler; | import com.healthmarketscience.jackcess.util.ErrorHandler; | ||||
public enum ColumnOrder { | public enum ColumnOrder { | ||||
/** columns are ordered based on the order of the data in the table (this | /** columns are ordered based on the order of the data in the table (this | ||||
order does not change as columns are added to the table). */ | order does not change as columns are added to the table). */ | ||||
DATA, | |||||
DATA, | |||||
/** columns are ordered based on the "display" order (this order can be | /** columns are ordered based on the "display" order (this order can be | ||||
changed arbitrarily) */ | changed arbitrarily) */ | ||||
DISPLAY; | DISPLAY; | ||||
* @return the given row map, which will contain any autonumbers generated | * @return the given row map, which will contain any autonumbers generated | ||||
* @usage _general_method_ | * @usage _general_method_ | ||||
*/ | */ | ||||
public <M extends Map<String,Object>> M addRowFromMap(M row) | |||||
public <M extends Map<String,Object>> M addRowFromMap(M row) | |||||
throws IOException; | throws IOException; | ||||
/** | /** | ||||
* partially successful write. | * partially successful write. | ||||
* | * | ||||
* @see #addRow(Object...) for more details on row arrays | * @see #addRow(Object...) for more details on row arrays | ||||
* | |||||
* | |||||
* @param rows List of Object[] row values. the rows will be modified if | * @param rows List of Object[] row values. the rows will be modified if | ||||
* this table contains an auto-number column, otherwise they | * this table contains an auto-number column, otherwise they | ||||
* will not be modified. | * will not be modified. | ||||
* generated | * generated | ||||
* @usage _general_method_ | * @usage _general_method_ | ||||
*/ | */ | ||||
public List<? extends Object[]> addRows(List<? extends Object[]> rows) | |||||
public List<? extends Object[]> addRows(List<? extends Object[]> rows) | |||||
throws IOException; | throws IOException; | ||||
/** | /** | ||||
* Most exceptions thrown from this method will be wrapped with a {@link | * Most exceptions thrown from this method will be wrapped with a {@link | ||||
* BatchUpdateException} which gives useful information in the case of a | * BatchUpdateException} which gives useful information in the case of a | ||||
* partially successful write. | * partially successful write. | ||||
* | |||||
* | |||||
* @return the given row map list, where the row maps will contain any | * @return the given row map list, where the row maps will contain any | ||||
* autonumbers generated | * autonumbers generated | ||||
* @usage _general_method_ | * @usage _general_method_ | ||||
*/ | */ | ||||
public <M extends Map<String,Object>> List<M> addRowsFromMaps(List<M> rows) | |||||
public <M extends Map<String,Object>> List<M> addRowsFromMaps(List<M> rows) | |||||
throws IOException; | throws IOException; | ||||
/** | /** | ||||
@Override | @Override | ||||
public Iterator<Row> iterator(); | public Iterator<Row> iterator(); | ||||
/** | |||||
* @return a Stream using the default Iterator. | |||||
*/ | |||||
default public Stream<Row> stream() { | |||||
return StreamSupport.stream(spliterator(), false); | |||||
} | |||||
/** | /** | ||||
* After calling this method, {@link #getNextRow} will return the first row | * After calling this method, {@link #getNextRow} will return the first row | ||||
* in the table, see {@link Cursor#reset} (uses the {@link #getDefaultCursor | * in the table, see {@link Cursor#reset} (uses the {@link #getDefaultCursor |
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.HashSet; | import java.util.HashSet; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
import com.healthmarketscience.jackcess.Column; | import com.healthmarketscience.jackcess.Column; | ||||
import com.healthmarketscience.jackcess.IndexCursor; | import com.healthmarketscience.jackcess.IndexCursor; | ||||
@Override | @Override | ||||
public Iterator<Row> iterator() { | public Iterator<Row> iterator() { | ||||
return ((IndexCursorImpl)_cursor).entryIterator(this); | return ((IndexCursorImpl)_cursor).entryIterator(this); | ||||
} | |||||
} | |||||
/** | |||||
* @return a Stream using the default Iterator. | |||||
*/ | |||||
public Stream<Row> stream() { | |||||
return StreamSupport.stream(spliterator(), false); | |||||
} | |||||
} | } |
import java.util.HashSet; | import java.util.HashSet; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
import com.healthmarketscience.jackcess.Column; | import com.healthmarketscience.jackcess.Column; | ||||
import com.healthmarketscience.jackcess.Cursor; | import com.healthmarketscience.jackcess.Cursor; | ||||
_columnNames.add(columnName); | _columnNames.add(columnName); | ||||
} | } | ||||
public IterableBuilder setMatchPattern(Column columnPattern, | |||||
public IterableBuilder setMatchPattern(Column columnPattern, | |||||
Object valuePattern) { | Object valuePattern) { | ||||
_type = Type.COLUMN_MATCH; | _type = Type.COLUMN_MATCH; | ||||
_matchPattern = new AbstractMap.SimpleImmutableEntry<Column,Object>( | _matchPattern = new AbstractMap.SimpleImmutableEntry<Column,Object>( | ||||
return this; | return this; | ||||
} | } | ||||
public IterableBuilder setMatchPattern(String columnNamePattern, | |||||
public IterableBuilder setMatchPattern(String columnNamePattern, | |||||
Object valuePattern) { | Object valuePattern) { | ||||
return setMatchPattern(_cursor.getTable().getColumn(columnNamePattern), | return setMatchPattern(_cursor.getTable().getColumn(columnNamePattern), | ||||
valuePattern); | valuePattern); | ||||
return this; | return this; | ||||
} | } | ||||
public IterableBuilder addMatchPattern(String columnNamePattern, | |||||
public IterableBuilder addMatchPattern(String columnNamePattern, | |||||
Object valuePattern) | Object valuePattern) | ||||
{ | { | ||||
_type = Type.ROW_MATCH; | _type = Type.ROW_MATCH; | ||||
} | } | ||||
matchPattern.put(columnNamePattern, valuePattern); | matchPattern.put(columnNamePattern, valuePattern); | ||||
return this; | return this; | ||||
} | |||||
} | |||||
public IterableBuilder setColumnMatcher(ColumnMatcher columnMatcher) { | public IterableBuilder setColumnMatcher(ColumnMatcher columnMatcher) { | ||||
_columnMatcher = columnMatcher; | _columnMatcher = columnMatcher; | ||||
public Iterator<Row> iterator() { | public Iterator<Row> iterator() { | ||||
return ((CursorImpl)_cursor).iterator(this); | return ((CursorImpl)_cursor).iterator(this); | ||||
} | } | ||||
/** | |||||
* @return a Stream using the default Iterator. | |||||
*/ | |||||
public Stream<Row> stream() { | |||||
return StreamSupport.stream(spliterator(), false); | |||||
} | |||||
} | } |
import java.io.InputStream; | import java.io.InputStream; | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.sql.Blob; | import java.sql.Blob; | ||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
import com.healthmarketscience.jackcess.impl.OleUtil; | import com.healthmarketscience.jackcess.impl.OleUtil; | ||||
* } | * } | ||||
* } finally { | * } finally { | ||||
* if(oleBlob != null) { oleBlob.close(); } | * if(oleBlob != null) { oleBlob.close(); } | ||||
* } | |||||
* } | |||||
* </pre> | * </pre> | ||||
* <p> | * <p> | ||||
* <b>Example for creating new, embedded ole data:</b> | * <b>Example for creating new, embedded ole data:</b> | ||||
* db.addRow(1, oleBlob); | * db.addRow(1, oleBlob); | ||||
* } finally { | * } finally { | ||||
* if(oleBlob != null) { oleBlob.close(); } | * if(oleBlob != null) { oleBlob.close(); } | ||||
* } | |||||
* } | |||||
* </pre> | * </pre> | ||||
* <p> | * <p> | ||||
* <b>Example for creating new, linked ole data:</b> | * <b>Example for creating new, linked ole data:</b> | ||||
* db.addRow(1, oleBlob); | * db.addRow(1, oleBlob); | ||||
* } finally { | * } finally { | ||||
* if(oleBlob != null) { oleBlob.close(); } | * if(oleBlob != null) { oleBlob.close(); } | ||||
* } | |||||
* } | |||||
* </pre> | * </pre> | ||||
* | * | ||||
* @author James Ahlborn | * @author James Ahlborn | ||||
public enum ContentType { | public enum ContentType { | ||||
/** the blob contents are a link (file path) to some external content. | /** the blob contents are a link (file path) to some external content. | ||||
Content will be an instance of LinkContent */ | Content will be an instance of LinkContent */ | ||||
LINK, | |||||
LINK, | |||||
/** the blob contents are a simple wrapper around some embedded content | /** the blob contents are a simple wrapper around some embedded content | ||||
and related file names/paths. Content will be an instance | and related file names/paths. Content will be an instance | ||||
SimplePackageContent */ | SimplePackageContent */ | ||||
SIMPLE_PACKAGE, | |||||
SIMPLE_PACKAGE, | |||||
/** the blob contents are a complex embedded data known as compound | /** the blob contents are a complex embedded data known as compound | ||||
storage (aka OLE2). Working with compound storage requires the | storage (aka OLE2). Working with compound storage requires the | ||||
optional POI library. Content will be an instance of CompoundContent. | optional POI library. Content will be an instance of CompoundContent. | ||||
OTHER, | OTHER, | ||||
/** the top-level blob wrapper is not understood (this may not be a valid | /** the top-level blob wrapper is not understood (this may not be a valid | ||||
ole instance). Content will simply be an instance of Content (the | ole instance). Content will simply be an instance of Content (the | ||||
data can be accessed from the main blob instance) */ | |||||
data can be accessed from the main blob instance) */ | |||||
UNKNOWN; | UNKNOWN; | ||||
} | } | ||||
public Content getContent() throws IOException; | public Content getContent() throws IOException; | ||||
public interface Content | |||||
{ | |||||
public interface Content | |||||
{ | |||||
/** | /** | ||||
* Returns the type of this content. | * Returns the type of this content. | ||||
*/ | */ | ||||
* Intermediate sub-interface for Content which has a nested package. | * Intermediate sub-interface for Content which has a nested package. | ||||
*/ | */ | ||||
public interface PackageContent extends Content | public interface PackageContent extends Content | ||||
{ | |||||
{ | |||||
public String getPrettyName() throws IOException; | public String getPrettyName() throws IOException; | ||||
public String getClassName() throws IOException; | public String getClassName() throws IOException; | ||||
public InputStream getStream() throws IOException; | public InputStream getStream() throws IOException; | ||||
public void writeTo(OutputStream out) throws IOException; | |||||
public void writeTo(OutputStream out) throws IOException; | |||||
} | } | ||||
/** | /** | ||||
* the access database (but the original file source path can also be found | * the access database (but the original file source path can also be found | ||||
* at {@link #getFilePath}). | * at {@link #getFilePath}). | ||||
*/ | */ | ||||
public interface SimplePackageContent | |||||
public interface SimplePackageContent | |||||
extends PackageContent, EmbeddedContent | extends PackageContent, EmbeddedContent | ||||
{ | { | ||||
public String getFileName(); | public String getFileName(); | ||||
public Entry getContentsEntry() throws IOException; | public Entry getContentsEntry() throws IOException; | ||||
/** | |||||
* @return a Stream using the default Iterator. | |||||
*/ | |||||
default public Stream<CompoundContent.Entry> stream() { | |||||
return StreamSupport.stream(spliterator(), false); | |||||
} | |||||
/** | /** | ||||
* A document entry in the compound storage. | * A document entry in the compound storage. | ||||
*/ | */ | ||||
*/ | */ | ||||
public CompoundContent getParent(); | public CompoundContent getParent(); | ||||
} | } | ||||
} | |||||
} | |||||
/** | /** | ||||
* Sub-interface for Content which has the {@link ContentType#OTHER} type. | * Sub-interface for Content which has the {@link ContentType#OTHER} type. | ||||
private String _prettyName; | private String _prettyName; | ||||
private String _className; | private String _className; | ||||
private String _typeName; | private String _typeName; | ||||
public ContentType getType() { | public ContentType getType() { | ||||
return _type; | return _type; | ||||
} | } | ||||
public String getClassName() { | public String getClassName() { | ||||
return _className; | return _className; | ||||
} | } | ||||
public String getTypeName() { | public String getTypeName() { | ||||
return _typeName; | return _typeName; | ||||
} | } | ||||
public Builder setSimplePackageBytes(byte[] bytes) { | public Builder setSimplePackageBytes(byte[] bytes) { | ||||
_bytes = bytes; | _bytes = bytes; | ||||
_contentLen = bytes.length; | _contentLen = bytes.length; |
import java.util.Map; | import java.util.Map; | ||||
import java.util.NoSuchElementException; | import java.util.NoSuchElementException; | ||||
import java.util.Objects; | import java.util.Objects; | ||||
import java.util.function.Predicate; | |||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
import com.healthmarketscience.jackcess.Column; | import com.healthmarketscience.jackcess.Column; | ||||
import com.healthmarketscience.jackcess.Row; | import com.healthmarketscience.jackcess.Row; | ||||
* @author Patricia Donaldson, Xerox Corporation | * @author Patricia Donaldson, Xerox Corporation | ||||
* @usage _general_class_ | * @usage _general_class_ | ||||
*/ | */ | ||||
public abstract class RowFilter | |||||
public abstract class RowFilter implements Predicate<Row> | |||||
{ | { | ||||
/** | /** | ||||
*/ | */ | ||||
public abstract boolean matches(Row row); | public abstract boolean matches(Row row); | ||||
/** | |||||
* Adaptation of this class for {@link Predicate} support. Uses the | |||||
* {@link #matches} method. | |||||
*/ | |||||
@Override | |||||
public boolean test(Row row) { | |||||
return matches(row); | |||||
} | |||||
/** | /** | ||||
* Returns an iterable which filters the given iterable based on this | * Returns an iterable which filters the given iterable based on this | ||||
* filter. | * filter. | ||||
return new FilterIterable(iterable); | return new FilterIterable(iterable); | ||||
} | } | ||||
/** | |||||
* Convenience method to apply this filter to the given iterable and return | |||||
* it as a Stream. | |||||
*/ | |||||
public Stream<Row> filter(Iterable<? extends Row> iterable) { | |||||
return StreamSupport.stream( | |||||
new FilterIterable(iterable).spliterator(), false) | |||||
.filter(this); | |||||
} | |||||
/** | /** | ||||
* Creates a filter based on a row pattern. | * Creates a filter based on a row pattern. |
package com.healthmarketscience.jackcess.util; | package com.healthmarketscience.jackcess.util; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.stream.Stream; | |||||
import java.util.stream.StreamSupport; | |||||
import com.healthmarketscience.jackcess.Database; | import com.healthmarketscience.jackcess.Database; | ||||
import com.healthmarketscience.jackcess.Table; | import com.healthmarketscience.jackcess.Table; | ||||
private boolean _includeNormalTables = true; | private boolean _includeNormalTables = true; | ||||
private boolean _includeSystemTables; | private boolean _includeSystemTables; | ||||
private boolean _includeLinkedTables = true; | private boolean _includeLinkedTables = true; | ||||
public TableIterableBuilder(Database db) { | public TableIterableBuilder(Database db) { | ||||
_db = db; | _db = db; | ||||
} | } | ||||
public boolean isIncludeNormalTables() { | public boolean isIncludeNormalTables() { | ||||
return _includeNormalTables; | return _includeNormalTables; | ||||
} | } | ||||
public boolean isIncludeSystemTables() { | public boolean isIncludeSystemTables() { | ||||
return _includeSystemTables; | return _includeSystemTables; | ||||
} | } | ||||
public boolean isIncludeLinkedTables() { | public boolean isIncludeLinkedTables() { | ||||
return _includeLinkedTables; | return _includeLinkedTables; | ||||
} | } | ||||
public TableIterableBuilder setIncludeNormalTables(boolean includeNormalTables) { | public TableIterableBuilder setIncludeNormalTables(boolean includeNormalTables) { | ||||
_includeNormalTables = includeNormalTables; | _includeNormalTables = includeNormalTables; | ||||
return this; | return this; | ||||
} | } | ||||
public TableIterableBuilder setIncludeSystemTables(boolean includeSystemTables) { | public TableIterableBuilder setIncludeSystemTables(boolean includeSystemTables) { | ||||
_includeSystemTables = includeSystemTables; | _includeSystemTables = includeSystemTables; | ||||
return this; | return this; | ||||
setIncludeSystemTables(false); | setIncludeSystemTables(false); | ||||
return setIncludeLinkedTables(false); | return setIncludeLinkedTables(false); | ||||
} | } | ||||
/** | /** | ||||
* Convenience method to set the flags to include only system tables. | * Convenience method to set the flags to include only system tables. | ||||
*/ | */ | ||||
setIncludeSystemTables(true); | setIncludeSystemTables(true); | ||||
return setIncludeLinkedTables(false); | return setIncludeLinkedTables(false); | ||||
} | } | ||||
@Override | @Override | ||||
public Iterator<Table> iterator() { | public Iterator<Table> iterator() { | ||||
return ((DatabaseImpl)_db).iterator(this); | return ((DatabaseImpl)_db).iterator(this); | ||||
} | } | ||||
/** | |||||
* @return a Stream using the default Iterator. | |||||
*/ | |||||
public Stream<Table> stream() { | |||||
return StreamSupport.stream(spliterator(), false); | |||||
} | |||||
} | } |
import java.util.Map; | import java.util.Map; | ||||
import java.util.NoSuchElementException; | import java.util.NoSuchElementException; | ||||
import java.util.TreeSet; | import java.util.TreeSet; | ||||
import java.util.stream.Collectors; | |||||
import static com.healthmarketscience.jackcess.Database.*; | import static com.healthmarketscience.jackcess.Database.*; | ||||
import com.healthmarketscience.jackcess.impl.ColumnImpl; | import com.healthmarketscience.jackcess.impl.ColumnImpl; | ||||
Index idx = t1.getIndex("Table2Table1"); | Index idx = t1.getIndex("Table2Table1"); | ||||
IndexCursor cursor = CursorBuilder.createCursor(idx); | IndexCursor cursor = CursorBuilder.createCursor(idx); | ||||
List<String> expectedData = new ArrayList<String>(); | |||||
for(Row row : cursor.newEntryIterable(1) | |||||
.addColumnNames("data")) { | |||||
expectedData.add(row.getString("data")); | |||||
} | |||||
List<String> expectedData = cursor.newEntryIterable(1) | |||||
.addColumnNames("data") | |||||
.stream().map(r -> r.getString("data")) | |||||
.collect(Collectors.toList()); | |||||
assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData); | assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData); | ||||
Table t1 = db.getTable("Table1"); | Table t1 = db.getTable("Table1"); | ||||
Cursor cursor = CursorBuilder.createCursor(t1); | Cursor cursor = CursorBuilder.createCursor(t1); | ||||
List<String> expectedData = new ArrayList<String>(); | |||||
for(Row row : cursor.newIterable().setColumnNames( | |||||
Arrays.asList("otherfk1", "data"))) { | |||||
if(row.get("otherfk1").equals(1)) { | |||||
expectedData.add(row.getString("data")); | |||||
} | |||||
} | |||||
List<String> expectedData = cursor.newIterable().setColumnNames( | |||||
Arrays.asList("otherfk1", "data")).stream() | |||||
.filter(r -> r.get("otherfk1").equals(1)) | |||||
.map(r -> r.getString("data")) | |||||
.collect(Collectors.toList()); | |||||
assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData); | assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData); | ||||
import java.util.TimeZone; | import java.util.TimeZone; | ||||
import java.util.TreeSet; | import java.util.TreeSet; | ||||
import java.util.UUID; | import java.util.UUID; | ||||
import java.util.stream.Collectors; | |||||
import static com.healthmarketscience.jackcess.Database.*; | import static com.healthmarketscience.jackcess.Database.*; | ||||
import com.healthmarketscience.jackcess.impl.ColumnImpl; | import com.healthmarketscience.jackcess.impl.ColumnImpl; | ||||
((DatabaseImpl)db).getPageChannel().finishWrite(); | ((DatabaseImpl)db).getPageChannel().finishWrite(); | ||||
} | } | ||||
Set<Integer> ids = new HashSet<Integer>(); | |||||
for(Row row : t) { | |||||
ids.add(row.getInt("ID")); | |||||
} | |||||
Set<Integer> ids = t.stream() | |||||
.map(r -> r.getInt("ID")) | |||||
.collect(Collectors.toSet()); | |||||
assertEquals(1000, ids.size()); | assertEquals(1000, ids.size()); | ||||
assertTrue(((TableImpl)t).getOwnedPagesCursor().getUsageMap().toString() | assertTrue(((TableImpl)t).getOwnedPagesCursor().getUsageMap().toString() | ||||
((DatabaseImpl)db).getPageChannel().finishWrite(); | ((DatabaseImpl)db).getPageChannel().finishWrite(); | ||||
} | } | ||||
List<Date> foundDates = new ArrayList<Date>(); | |||||
for(Row row : table) { | |||||
foundDates.add(row.getDate("date")); | |||||
} | |||||
List<Date> foundDates = table.stream() | |||||
.map(r -> r.getDate("date")) | |||||
.collect(Collectors.toList()); | |||||
assertEquals(dates.size(), foundDates.size()); | assertEquals(dates.size(), foundDates.size()); | ||||
for(int i = 0; i < dates.size(); ++i) { | for(int i = 0; i < dates.size(); ++i) { | ||||
table.addRow("row " + dateStr, d); | table.addRow("row " + dateStr, d); | ||||
} | } | ||||
List<String> foundDates = new ArrayList<String>(); | |||||
for(Row row : table) { | |||||
foundDates.add(sdf.format(row.getDate("date"))); | |||||
} | |||||
List<String> foundDates = table.stream() | |||||
.map(r -> sdf.format(r.getDate("date"))) | |||||
.collect(Collectors.toList()); | |||||
assertEquals(dates, foundDates); | assertEquals(dates, foundDates); | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Set; | import java.util.Set; | ||||
import java.util.stream.Collectors; | |||||
import com.healthmarketscience.jackcess.Database; | import com.healthmarketscience.jackcess.Database; | ||||
import com.healthmarketscience.jackcess.Index; | import com.healthmarketscience.jackcess.Index; | ||||
assertSame(t2t1, t2t1Join.getFromIndex()); | assertSame(t2t1, t2t1Join.getFromIndex()); | ||||
assertSame(t1, t2t1Join.getToTable()); | assertSame(t1, t2t1Join.getToTable()); | ||||
assertSame(t1t2, t2t1Join.getToIndex()); | assertSame(t1t2, t2t1Join.getToIndex()); | ||||
doTestJoiner(t2t1Join, createT2T1Data()); | doTestJoiner(t2t1Join, createT2T1Data()); | ||||
Index t3t1 = t1t3.getReferencedIndex(); | Index t3t1 = t1t3.getReferencedIndex(); | ||||
assertSame(t3, t3t1.getTable()); | assertSame(t3, t3t1.getTable()); | ||||
Joiner t3t1Join = Joiner.create(t3t1); | Joiner t3t1Join = Joiner.create(t3t1); | ||||
assertSame(t3t1, t3t1Join.getFromIndex()); | assertSame(t3t1, t3t1Join.getFromIndex()); | ||||
assertSame(t1, t3t1Join.getToTable()); | assertSame(t1, t3t1Join.getToTable()); | ||||
assertSame(t1t3, t3t1Join.getToIndex()); | assertSame(t1t3, t3t1Join.getToIndex()); | ||||
doTestJoiner(t3t1Join, createT3T1Data()); | |||||
doTestJoiner(t3t1Join, createT3T1Data()); | |||||
doTestJoinerDelete(t2t1Join); | doTestJoinerDelete(t2t1Join); | ||||
} | |||||
} | |||||
} | } | ||||
private static void doTestJoiner( | private static void doTestJoiner( | ||||
for(Row row : join.getFromTable()) { | for(Row row : join.getFromTable()) { | ||||
Integer id = row.getInt("id"); | Integer id = row.getInt("id"); | ||||
List<Row> joinedRows = | |||||
new ArrayList<Row>(); | |||||
for(Row t1Row : join.findRows(row)) { | |||||
joinedRows.add(t1Row); | |||||
} | |||||
List<Row> joinedRows = join.findRows(row).stream() | |||||
.collect(Collectors.toList()); | |||||
List<Row> expectedRows = expectedData.get(id); | List<Row> expectedRows = expectedData.get(id); | ||||
assertEquals(expectedData.get(id), joinedRows); | assertEquals(expectedData.get(id), joinedRows); | ||||
assertFalse(join.hasRows(row)); | assertFalse(join.hasRows(row)); | ||||
assertNull(join.findFirstRow(row)); | assertNull(join.findFirstRow(row)); | ||||
} | } | ||||
List<Row> expectedRows2 = new ArrayList<Row>(); | List<Row> expectedRows2 = new ArrayList<Row>(); | ||||
for(Row tmpRow : expectedRows) { | for(Row tmpRow : expectedRows) { | ||||
Row tmpRow2 = new RowImpl(tmpRow); | Row tmpRow2 = new RowImpl(tmpRow); | ||||
tmpRow2.keySet().retainAll(colNames); | tmpRow2.keySet().retainAll(colNames); | ||||
expectedRows2.add(tmpRow2); | expectedRows2.add(tmpRow2); | ||||
} | } | ||||
joinedRows = new ArrayList<Row>(); | |||||
for(Row t1Row : join.findRows(row).setColumnNames(colNames)) { | |||||
joinedRows.add(t1Row); | |||||
} | |||||
joinedRows = join.findRows(row).setColumnNames(colNames) | |||||
.stream().collect(Collectors.toList()); | |||||
assertEquals(expectedRows2, joinedRows); | assertEquals(expectedRows2, joinedRows); | ||||
assertEquals(expectedRows2.get(0), join.findFirstRow(row, colNames)); | assertEquals(expectedRows2.get(0), join.findFirstRow(row, colNames)); | ||||
} else { | } else { | ||||
assertNull(join.findFirstRow(row, colNames)); | assertNull(join.findFirstRow(row, colNames)); | ||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
return data; | return data; | ||||
} | } | ||||
private static Map<Integer,List<Row>> createT3T1Data() | private static Map<Integer,List<Row>> createT3T1Data() | ||||
{ | { | ||||
Map<Integer,List<Row>> data = new HashMap<Integer,List<Row>>(); | Map<Integer,List<Row>> data = new HashMap<Integer,List<Row>>(); | ||||
return data; | return data; | ||||
} | } | ||||
} | } |