package com.github.davidmoten.rx.jdbc; import static org.junit.Assert.assertEquals; import java.sql.SQLException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.Ignore; import org.junit.Test; import com.github.davidmoten.rx.RxUtil; import com.github.davidmoten.rx.jdbc.annotations.Column; import rx.Observable; import rx.Subscriber; import rx.functions.Action1; import rx.functions.Func1; import rx.observers.TestSubscriber; public class DatabaseExampleTest { @Test public void testCreateAndUseAnInMemoryDatabase() throws SQLException { // create an h2 in-memory database that does not get dropped when all // connections closed Database db = Database.from("jdbc:h2:mem:demo1;DB_CLOSE_DELAY=-1"); db.update( "create table person (name varchar(50) primary key, score int not null,dob date, registered timestamp)") .count().toBlocking().single(); assertEquals(2, db.update("insert into person(name,score) values(?,?)") .parameters("FRED", 21, "JOE", 34).execute()); // use java 8 lambdas if you have them ! db.select("select name, score from person").autoMap(Person.class) .forEach(new Action1<Person>() { @Override public void call(Person person) { System.out.println(person.name() + " has score " + person.score()); } }); db.close(); } static interface Person { @Column String name(); @Column int score(); } @Test public void testParameterOperatorBackpressure() { // use composition to find the first person alphabetically with // a score less than the person with the last name alphabetically // whose name is not XAVIER. Two threads and connections will be used. Database db = DatabaseCreator.db(); TestSubscriber<String> ts = TestSubscriber.create(0); Observable.just("FRED", "FRED").repeat() .compose(db.select("select name from person where name = ?").parameterTransformer() .getAs(String.class)) .subscribe(ts); ts.requestMore(1); ts.assertValueCount(1); ts.unsubscribe(); } @Test public void testSelectParameterListOperatorWithError() { // use composition to find the first person alphabetically with // a score less than the person with the last name alphabetically // whose name is not XAVIER. Two threads and connections will be used. Database db = DatabaseCreator.db(); TestSubscriber<String> ts = TestSubscriber.create(); RuntimeException ex = new RuntimeException(); Observable.<Observable<Object>> error(ex) .compose(db.select("select name from person where name = ?") .parameterListTransformer().getAs(String.class)) .subscribe(ts); ts.assertError(ex); } @Test public void testUpdateParameterListOperatorWithError() { Database db = DatabaseCreator.db(); TestSubscriber<Integer> ts = TestSubscriber.create(); RuntimeException ex = new RuntimeException(); Observable.<Observable<Object>> error(ex) // update .compose(db.update("update person set name=?||'zz' where name = ?") .parameterListTransformer()) // flatten .compose(RxUtil.<Integer> flatten()).subscribe(ts); ts.assertError(ex); } @Test // ignore because infinite and doesn't test results yet apart from critical // failure @Ignore public void testBackpressureIssue38() { Database db = DatabaseCreator.db(); final Long start = System.currentTimeMillis(); final CountDownLatch latch = new CountDownLatch(1); Observable.interval(0, 1, TimeUnit.MILLISECONDS).onBackpressureLatest() // .doOnNext(t -> System.out.println("start " + t)) .compose(db.select("SELECT * FROM (VALUES (?)) AS v").parameterTransformer() .getAs(String.class)) // .doOnNext(t -> System.out.println("result " + t)) .concatMap(new Func1<String, Observable<String>>() { @Override public Observable<String> call(String t) { return Observable.<String> empty().delay(100, TimeUnit.MILLISECONDS) .startWith(t); } }).subscribe(new Subscriber<String>() { @Override public void onCompleted() { System.out.println("completed"); latch.countDown(); } @Override public void onError(Throwable e) { System.out.println("Something went wrong "); e.printStackTrace(); latch.countDown(); } @Override public void onNext(String t) { System.out.println("item " + t + " received at " + (System.currentTimeMillis() - start) + "ms"); } }); try { latch.await(); } catch (InterruptedException e) // ignore { throw new RuntimeException(e); } } }