/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jdbi.v3.sqlobject;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.jdbi.v3.core.Handle;
import org.jdbi.v3.core.rule.H2DatabaseRule;
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import com.google.common.collect.ImmutableMap;
public class TestFoldToObjectGraph
{
@Rule
public H2DatabaseRule dbRule = new H2DatabaseRule().withPlugin(new SqlObjectPlugin());
private Handle handle;
private Map<String, Team> expected;
@Before
public void setUp() throws Exception
{
handle = dbRule.getSharedHandle();
handle.execute("create table team ( name varchar(100), " +
" mascot varchar(100)," +
" primary key (name) )");
handle.execute("create table person( name varchar(100), " +
" role varchar(100), " +
" team varchar(100)," +
" primary key (name)," +
" foreign key (team) references team(name) )");
handle.prepareBatch("insert into team (name, mascot) values (?, ?)")
.add("A-Team", "The Van")
.add("Hogan's Heroes", "The Tunnel")
.execute();
handle.prepareBatch("insert into person (name, role, team) values (?, ?, ?)")
.add("Kinchloe", "comms", "Hogan's Heroes")
.add("Carter", "bombs", "Hogan's Heroes")
.add("Murdoch", "driver", "A-Team")
.add("Peck", "face", "A-Team")
.execute();
Team ateam = new Team("A-Team", "The Van");
ateam.getPeople().add(new Person("Murdoch", "driver"));
ateam.getPeople().add(new Person("Peck", "face"));
Team hogans = new Team("Hogan's Heroes", "The Tunnel");
hogans.getPeople().add(new Person("Kinchloe", "comms"));
hogans.getPeople().add(new Person("Carter", "bombs"));
this.expected = ImmutableMap.of("Hogan's Heroes", hogans,
"A-Team", ateam);
}
@Test
public void testSqlObjectApi() throws Exception
{
Dao dao = handle.attach(Dao.class);
assertThat(dao.findAllTeams()).isEqualTo(expected);
}
public interface Dao
{
@SqlQuery("select t.name as teamName, " +
" t.mascot as mascot, " +
" p.name as personName, " +
" p.role as role " +
"from team t inner join person p on (t.name = p.team)")
@RegisterBeanMapper(TeamPersonJoinRow.class)
Iterator<TeamPersonJoinRow> findAllTeamsAndPeople();
default Map<String, Team> findAllTeams()
{
Iterator<TeamPersonJoinRow> i = findAllTeamsAndPeople();
Map<String, Team> acc = new HashMap<>();
while (i.hasNext()) {
TeamPersonJoinRow row = i.next();
if (!acc.containsKey(row.getTeamName())) {
acc.put(row.getTeamName(), new Team(row.getTeamName(), row.getMascot()));
}
acc.get(row.getTeamName()).getPeople().add(new Person(row.getPersonName(), row.getRole()));
}
return acc;
}
}
public static class Team
{
private final String name;
private final String mascot;
private final Set<Person> people = new LinkedHashSet<>();
public Team(String name, String mascot)
{
this.name = name;
this.mascot = mascot;
}
public String getName()
{
return name;
}
public String getMascot()
{
return mascot;
}
public Set<Person> getPeople()
{
return this.people;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Team that = (Team) o;
return Objects.equals(this.mascot, that.mascot)
&& Objects.equals(this.name, that.name)
&& Objects.equals(this.people, that.people);
}
@Override
public int hashCode()
{
return Objects.hash(name, mascot, people);
}
}
public static class Person
{
private final String name;
private final String role;
public Person(String name, String role)
{
this.name = name;
this.role = role;
}
public String getName()
{
return name;
}
public String getRole()
{
return role;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return name.equals(person.name) && role.equals(person.role);
}
@Override
public int hashCode()
{
int result = name.hashCode();
result = 31 * result + role.hashCode();
return result;
}
}
public static class TeamPersonJoinRow
{
private String teamName;
private String mascot;
private String personName;
private String role;
public String getTeamName()
{
return teamName;
}
public String getMascot()
{
return mascot;
}
public String getPersonName()
{
return personName;
}
public String getRole()
{
return role;
}
public void setTeamName(String teamName)
{
this.teamName = teamName;
}
public void setMascot(String mascot)
{
this.mascot = mascot;
}
public void setPersonName(String personName)
{
this.personName = personName;
}
public void setRole(String role)
{
this.role = role;
}
}
}