@try io > and pay attention about prototyping, it's not easy to extend an object, unfortunatly it's much worst than you think:
oh I agree remember? I said its complicated and confusing. But the nut cases that developed prototyping for SELF thought that it would be an easier alternative to classes, they said so.
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;
}
}