diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..03220c5
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..7c65633
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..be0fb2c
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/scala_compiler.xml b/.idea/scala_compiler.xml
new file mode 100644
index 0000000..d84cc6a
--- /dev/null
+++ b/.idea/scala_compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index aca358d..8416304 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,18 @@
1.8.1
+
+ org.apache.commons
+ commons-dbcp2
+ 2.5.0
+
+
+
+ mysql
+ mysql-connector-java
+ 5.1.6
+
+
diff --git a/src/main/java/streams/StocksPrice.java b/src/main/java/streams/StocksPrice.java
new file mode 100644
index 0000000..1af2209
--- /dev/null
+++ b/src/main/java/streams/StocksPrice.java
@@ -0,0 +1,49 @@
+package streams;
+
+import java.util.Date;
+
+public class StocksPrice {
+
+ private String stockSymbol;
+ private Date tradeDate;
+ private double openPrice;
+ private double highPrice;
+
+ public Date getTradeDate() {
+ return tradeDate;
+ }
+
+ public double getHighPrice() {
+ return highPrice;
+ }
+
+ public double getOpenPrice() {
+ return openPrice;
+ }
+
+ public void setStockSymbol(String stockSymbol) {
+ this.stockSymbol = stockSymbol;
+ }
+
+ public String getStockSymbol() {
+ return stockSymbol;
+ }
+
+ public void setHighPrice(double highPrice) {
+ this.highPrice = highPrice;
+ }
+
+ public void setOpenPrice(double openPrice) {
+ this.openPrice = openPrice;
+ }
+
+ public void setTradeDate(Date tradeDate) {
+ this.tradeDate = tradeDate;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Symbol=%s;Date=%s;open price=%s ; HighPrice=%s", stockSymbol, tradeDate, openPrice, highPrice);
+ }
+
+}
diff --git a/src/main/java/streams/TableStreamApplication.java b/src/main/java/streams/TableStreamApplication.java
new file mode 100644
index 0000000..0990ce8
--- /dev/null
+++ b/src/main/java/streams/TableStreamApplication.java
@@ -0,0 +1,51 @@
+package streams;
+
+import org.apache.commons.dbcp2.BasicDataSource;
+import streams.database.TableStreamBuilder;
+import streams.database.Where;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class TableStreamApplication {
+
+ public static void main(String... args) {
+
+ BasicDataSource ds = createDataSource();
+
+ TableStreamBuilder stocksTable = TableStreamBuilder
+ .with(ds)
+ .build(StocksPrice.class, "stocks_price", () -> new StocksPrice());
+
+ Stream rows = stocksTable.stream();
+
+ long count = rows
+ .filter(Where.GT("volume", 1467200))
+ .filter(Where.GT("open_price", 1108d))
+ .count();
+
+ System.out.println(count);
+
+
+ List o = (List) stocksTable.stream()
+ .filter(Where.GT("volume", 1467200))
+ .filter(Where.GT("open_price", 1108d))
+ .limit(2)
+ .collect(Collectors.toList());
+
+ System.out.println(o);
+
+
+ }
+
+ private static BasicDataSource createDataSource() {
+ BasicDataSource ds = new BasicDataSource();
+ ds.setDriverClassName("com.mysql.jdbc.Driver");
+ ds.setUrl("jdbc:mysql://localhost:3306/playground");
+ ds.setUsername("root");
+ ds.setPassword("changeme");
+ return ds;
+ }
+
+}
diff --git a/src/main/java/streams/database/NoOpStream.java b/src/main/java/streams/database/NoOpStream.java
new file mode 100644
index 0000000..3286c22
--- /dev/null
+++ b/src/main/java/streams/database/NoOpStream.java
@@ -0,0 +1,211 @@
+package streams.database;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.Spliterator;
+import java.util.function.*;
+import java.util.stream.*;
+
+public class NoOpStream implements Stream {
+
+ @Override
+ public Stream filter(Predicate super T> predicate) {
+ return null;
+ }
+
+ @Override
+ public Stream map(Function super T, ? extends R> mapper) {
+ return null;
+ }
+
+ @Override
+ public IntStream mapToInt(ToIntFunction super T> mapper) {
+ return null;
+ }
+
+ @Override
+ public LongStream mapToLong(ToLongFunction super T> mapper) {
+ return null;
+ }
+
+ @Override
+ public DoubleStream mapToDouble(ToDoubleFunction super T> mapper) {
+ return null;
+ }
+
+ @Override
+ public Stream flatMap(Function super T, ? extends Stream extends R>> mapper) {
+ return null;
+ }
+
+ @Override
+ public IntStream flatMapToInt(Function super T, ? extends IntStream> mapper) {
+ return null;
+ }
+
+ @Override
+ public LongStream flatMapToLong(Function super T, ? extends LongStream> mapper) {
+ return null;
+ }
+
+ @Override
+ public DoubleStream flatMapToDouble(Function super T, ? extends DoubleStream> mapper) {
+ return null;
+ }
+
+ @Override
+ public Stream distinct() {
+ return null;
+ }
+
+ @Override
+ public Stream sorted() {
+ return null;
+ }
+
+ @Override
+ public Stream sorted(Comparator super T> comparator) {
+ return null;
+ }
+
+ @Override
+ public Stream peek(Consumer super T> action) {
+ return null;
+ }
+
+ @Override
+ public Stream limit(long maxSize) {
+ return null;
+ }
+
+ @Override
+ public Stream skip(long n) {
+ return null;
+ }
+
+ @Override
+ public void forEach(Consumer super T> action) {
+
+ }
+
+ @Override
+ public void forEachOrdered(Consumer super T> action) {
+
+ }
+
+ @Override
+ public Object[] toArray() {
+ return new Object[0];
+ }
+
+ @Override
+ public A[] toArray(IntFunction generator) {
+ return null;
+ }
+
+ @Override
+ public T reduce(T identity, BinaryOperator accumulator) {
+ return null;
+ }
+
+ @Override
+ public Optional reduce(BinaryOperator accumulator) {
+ return Optional.empty();
+ }
+
+ @Override
+ public U reduce(U identity, BiFunction accumulator, BinaryOperator combiner) {
+ return null;
+ }
+
+ @Override
+ public R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) {
+ return null;
+ }
+
+ @Override
+ public R collect(Collector super T, A, R> collector) {
+ return null;
+ }
+
+ @Override
+ public Optional min(Comparator super T> comparator) {
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional max(Comparator super T> comparator) {
+ return Optional.empty();
+ }
+
+ @Override
+ public long count() {
+ return 0;
+ }
+
+ @Override
+ public boolean anyMatch(Predicate super T> predicate) {
+ return false;
+ }
+
+ @Override
+ public boolean allMatch(Predicate super T> predicate) {
+ return false;
+ }
+
+ @Override
+ public boolean noneMatch(Predicate super T> predicate) {
+ return false;
+ }
+
+ @Override
+ public Optional findFirst() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional findAny() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Iterator iterator() {
+ return null;
+ }
+
+ @Override
+ public Spliterator spliterator() {
+ return null;
+ }
+
+ @Override
+ public boolean isParallel() {
+ return false;
+ }
+
+ @Override
+ public Stream sequential() {
+ return null;
+ }
+
+ @Override
+ public Stream parallel() {
+ return null;
+ }
+
+ @Override
+ public Stream unordered() {
+ return null;
+ }
+
+ @Override
+ public Stream onClose(Runnable closeHandler) {
+ return null;
+ }
+
+ @Override
+ public void close() {
+
+ }
+}
diff --git a/src/main/java/streams/database/TableStreamBuilder.java b/src/main/java/streams/database/TableStreamBuilder.java
new file mode 100644
index 0000000..3705d55
--- /dev/null
+++ b/src/main/java/streams/database/TableStreamBuilder.java
@@ -0,0 +1,217 @@
+package streams.database;
+
+import javax.sql.DataSource;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class TableStreamBuilder {
+
+ static Pattern columnNamePattern = Pattern.compile("set([A-Z].*)([A-Z].*)");
+
+ private final DataSource ds;
+ private Class tableClass;
+ private String tableName;
+ private Supplier rowSupplier;
+ private List columnNames;
+
+ public TableStreamBuilder(DataSource ds) {
+ this.ds = ds;
+ }
+
+ public Stream stream() {
+
+ List