package com.github.davidmoten.rx.jdbc; import static com.github.davidmoten.rx.jdbc.DatabaseCreator.connectionProvider; import static org.junit.Assert.assertEquals; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.junit.Test; import rx.Observable; import rx.functions.Action1; import rx.functions.Func1; import com.github.davidmoten.rx.jdbc.exceptions.SQLRuntimeException; public class DatabaseMasterDetailTest { @Test public void testIvanoExample1() { Connection con = connectionProvider().get(); createDatabase(con); Database db = Database.from(con); List<Master> masters = db.select("select id, name from master order by id") // map to class .autoMap(Master.class) // as list and get .toList().toBlocking().single(); assertEquals(2, masters.size()); assertEquals("FRED", masters.get(0).name()); assertEquals("JOHN", masters.get(1).name()); db.close(); } @Test public void testIvanoExample2() { Connection con = connectionProvider().get(); createDatabase(con); final Database db = Database.from(con); List<MasterAndDetails> list = db // get masters .select("select id, name from master order by id") // map to class .autoMap(Master.class) // combine master and details .flatMap(new Func1<Master, Observable<MasterAndDetails>>() { @Override public Observable<MasterAndDetails> call(final Master master) { return db .select("select id, desc from detail where master_id=? order by id") // set parameters .parameters(master.id()) // to Detail .autoMap(Detail.class) // to a list .toList() // now combine master and details in a // MasterAndDetails object .map(new Func1<List<Detail>, MasterAndDetails>() { @Override public MasterAndDetails call(List<Detail> details) { return new MasterAndDetails(master.id(), master.name(), details); } }); } }) // log .doOnNext(new Action1<MasterAndDetails>() { @Override public void call(MasterAndDetails md) { System.out.println(md); } }) // to list and get .toList().toBlocking().single(); assertEquals(2, list.size()); assertEquals("FRED", list.get(0).name()); assertEquals(2, list.get(0).details().size()); assertEquals(10, list.get(0).details().get(0).id()); assertEquals(11, list.get(0).details().get(1).id()); assertEquals("JOHN", list.get(1).name()); assertEquals(2, list.get(1).details().size()); assertEquals(20, list.get(1).details().get(0).id()); assertEquals(21, list.get(1).details().get(1).id()); } static class Master { private final Integer id; private final String name; Master(Integer id, String name) { this.id = id; this.name = name; } int id() { return id; } String name() { return name; } } static class Detail { private final Integer id; private final String description; public Detail(Integer id, String description) { this.id = id; this.description = description; } int id() { return id; } String description() { return description; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Detail [id="); builder.append(id); builder.append(", description="); builder.append(description); builder.append("]"); return builder.toString(); } } static class MasterAndDetails { private final Integer id; private final String name; private final List<Detail> details; MasterAndDetails(Integer id, String name, List<Detail> details) { this.id = id; this.name = name; this.details = new ArrayList<Detail>(details); } int id() { return id; } String name() { return name; } List<Detail> details() { // return defensive copy return new ArrayList<Detail>(details); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("MasterAndDetails [id="); builder.append(id); builder.append(", name="); builder.append(name); builder.append(", details="); builder.append(details); builder.append("]"); return builder.toString(); } } private static void createDatabase(Connection c) { try { c.setAutoCommit(true); c.prepareStatement("create table master (id int primary key, name varchar2(50))") .execute(); c.prepareStatement("insert into master(id,name) values(1,'FRED')").execute(); c.prepareStatement("insert into master(id,name) values(2,'JOHN')").execute(); c.prepareStatement("create table detail (id int, master_id int, desc varchar(50))") .execute(); c.prepareStatement( "insert into detail(id, master_id, desc) values(10, 1, 'a good fellow')") .execute(); c.prepareStatement( "insert into detail(id, master_id, desc) values(11, 1, 'rides his bike')") .execute(); c.prepareStatement( "insert into detail(id, master_id, desc) values(20, 2, 'a bit of a bore')") .execute(); c.prepareStatement( "insert into detail(id, master_id, desc) values(21, 2, 'is a good cook')") .execute(); } catch (SQLException e) { throw new SQLRuntimeException(e); } } }