diff --git a/src/main/java/com/widen/tabitha/RowReader.java b/src/main/java/com/widen/tabitha/RowReader.java index 0d3ebb8..4ff6a12 100644 --- a/src/main/java/com/widen/tabitha/RowReader.java +++ b/src/main/java/com/widen/tabitha/RowReader.java @@ -19,7 +19,7 @@ public interface RowReader extends Iterable, Closeable * * Closing has no effect on this row reader and is always re-usable. */ - RowReader EMPTY = Optional::empty; + RowReader VOID = Optional::empty; /** * Create a row reader from an array of rows. diff --git a/src/main/java/com/widen/tabitha/RowWriter.java b/src/main/java/com/widen/tabitha/RowWriter.java index 945d05e..d2cd847 100644 --- a/src/main/java/com/widen/tabitha/RowWriter.java +++ b/src/main/java/com/widen/tabitha/RowWriter.java @@ -14,7 +14,37 @@ public interface RowWriter extends Closeable * * Closing has no effect on this row writer and is always re-usable. */ - RowWriter NULL = row -> {}; + RowWriter VOID = row -> {}; + + /** + * Creates a new row writer that writes rows to multiple destinations. + * + * @param rowWriters The writers to write to. + * @return The new row writer. + */ + static RowWriter tee(RowWriter... rowWriters) + { + return new RowWriter() + { + @Override + public void write(Row row) throws IOException + { + for (RowWriter rowWriter : rowWriters) + { + rowWriter.write(row); + } + } + + @Override + public void close() throws IOException + { + for (RowWriter rowWriter : rowWriters) + { + rowWriter.close(); + } + } + }; + } /** * Writes a row to the output. diff --git a/src/test/groovy/com/widen/tabitha/DataFrameTest.groovy b/src/test/groovy/com/widen/tabitha/DataFrameTest.groovy index 0ffb1a1..b0c62ae 100644 --- a/src/test/groovy/com/widen/tabitha/DataFrameTest.groovy +++ b/src/test/groovy/com/widen/tabitha/DataFrameTest.groovy @@ -6,7 +6,7 @@ class DataFrameTest extends Specification { def "test is streaming"() { setup: def inMemory = new DataFrame() - def streaming = DataFrame.streaming(RowReader.EMPTY) + def streaming = DataFrame.streaming(RowReader.VOID) expect: !inMemory.isStreaming() diff --git a/src/test/groovy/com/widen/tabitha/RowReaderTest.groovy b/src/test/groovy/com/widen/tabitha/RowReaderTest.groovy index 92fba67..2a82a0e 100644 --- a/src/test/groovy/com/widen/tabitha/RowReaderTest.groovy +++ b/src/test/groovy/com/widen/tabitha/RowReaderTest.groovy @@ -5,7 +5,7 @@ import spock.lang.* class RowReaderTest extends Specification { def "empty reader"() { setup: - def reader = RowReader.EMPTY + def reader = RowReader.VOID expect: !reader.read().isPresent() diff --git a/src/test/groovy/com/widen/tabitha/RowWriterTest.groovy b/src/test/groovy/com/widen/tabitha/RowWriterTest.groovy index 54ee6e6..0e9cfff 100644 --- a/src/test/groovy/com/widen/tabitha/RowWriterTest.groovy +++ b/src/test/groovy/com/widen/tabitha/RowWriterTest.groovy @@ -3,10 +3,10 @@ package com.widen.tabitha import spock.lang.* class RowWriterTest extends Specification { - def "null is always writable"() { + def "void is always writable"() { setup: 100.times { - RowWriter.NULL.write(Mock(Row.class)) + RowWriter.VOID.write(Mock(Row.class)) } } }