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);
}
}
}