public final class PgPersonByEmail implements People {
private final DataSource dataSource;
private final People source;
private final Email email;
public PgPersonByEmail(DataSource dataSource, Email email) {
this(
dataSource,
new PgPeople(dataSource),
email
);
}
public PgPersonByEmail(DataSource dataSource, People source, Email email) {
this.dataSource = dataSource;
this.source = source;
this.email = email;
}
public Person first() {
return iterate().iterator().next();
}
@Override
public Iterable<Person> iterate() {
try {
return new JdbcSession(this.dataSource)
.sql("SELECT id FROM person where email = ?")
.set(email.toString()).select(
new ListOutcome<>(
(ListOutcome.Mapping<Person>) rset -> new PgPerson(
dataSource,
rset.getInt(1)
)
)
);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public Person add(Email email) {
return this.source.add(email);
}
}
public final class PgPeople implements People {
private final DataSource dataSource;
public PgPeople(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Iterable<Person> iterate() {
try {
return new JdbcSession(this.dataSource)
.sql("SELECT id FROM person")
.select(
new ListOutcome<>(
(ListOutcome.Mapping<Person>) rset -> new PgPerson(
dataSource,
rset.getInt(1)
)
)
);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public Person add(Email email) {
try {
return new PgPerson(
this.dataSource,
new JdbcSession(dataSource)
.sql("INSERT INTO person (email) VALUES (?)")
.set(email.toString())
.update(new SingleOutcome<>(Long.class)).intValue()
);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
public final class PgOrganizations implements Organizations {
private final DataSource dataSource;
private final Filter filteredBy;
private final Object[] params;
public PgOrganizations(DataSource dataSource) {
this(
dataSource,
Filter.NONE
);
}
public PgOrganizations(DataSource dataSource, Filter filteredBy, Object... params) {
this.dataSource = dataSource;
this.filteredBy = filteredBy;
this.params = params;
}
@Override
public Iterable<Organization> iterate() {
try {
final JdbcSession session = new JdbcSession(this.dataSource);
session.sql(
String.format("SELECT id FROM organization %s", filteredBy.where)
);
for (Object param : params) {
session.set(param);
}
return session.select(
new ListOutcome<>(
(ListOutcome.Mapping<Organization>) rset -> new PgOrganization(
dataSource,
rset.getInt(1)
)
)
);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public Organization add(OrganizationUrl url) {
try {
return new PgOrganization(
this.dataSource,
new JdbcSession(dataSource)
.sql("INSERT INTO organization (email) VALUES (?)")
.set(url.toString())
.update(new SingleOutcome<>(Long.class)).intValue()
);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public enum Filter {
NONE(""),
BY_URL("where url = ?");
private final String where;
Filter(String where) {
this.where = where;
}
}
}
@EqualsAndHashCode(of = "id")
public final class PgPerson implements Person {
private static final Logger LOGGER = LoggerFactory.getLogger(PgPerson.class);
private final DataSource dataSource;
private final int id;
private final Account account;
public PgPerson(DataSource dataSource, int id) {
this(
dataSource,
id,
new PgAccount(
dataSource,
id
)
);
}
public PgPerson(DataSource dataSource, int id, Account account) {
this.dataSource = dataSource;
this.id = id;
this.account = account;
}
@Override
public int id() {
return this.id;
}
@Override
public void update(Name name) {
LOGGER.debug(
"name: {}",
name.toString());
try {
new JdbcSession(this.dataSource)
.sql("update person set first=?, middle=?, last=? where id = ?")
.set(name.first())
.set(name.middle())
.set(name.last())
.set(this.id)
.execute();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public Name name() {
try {
return new JdbcSession(this.dataSource)
.sql("select COALESCE(first,''), COALESCE(middle,''), COALESCE(last,'') from person where id = ?")
.set(this.id)
.select((Outcome<Name>) (rset, stmt) -> {
rset.next();
return new DefaultName(
rset.getString(1),
rset.getString(2),
rset.getString(3)
);
});
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public Account account() {
return this.account;
}
}