diff --git a/src/main/java/com/poststats/golf/api/SeriesApi.java b/src/main/java/com/poststats/golf/api/SeriesApi.java index e6ae05b..0322cc7 100644 --- a/src/main/java/com/poststats/golf/api/SeriesApi.java +++ b/src/main/java/com/poststats/golf/api/SeriesApi.java @@ -1,7 +1,6 @@ package com.poststats.golf.api; import com.brianlong.util.FlexMap; -import com.fasterxml.jackson.core.JsonProcessingException; import com.poststats.api.Constants; import com.poststats.golf.api.model.Event; import com.poststats.golf.api.model.Series; @@ -25,9 +24,9 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.core.Response.Status; +import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,7 +74,7 @@ public class SeriesApi { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found") }) - public Series get() throws JsonProcessingException { + public Series get() { FlexMap row = this.seriesService.get(this.seriesId); if (row == null) throw new WebApplicationException("Series not found", Status.NOT_FOUND); @@ -83,21 +82,6 @@ public class SeriesApi { return this.converter.convertValue(row, Series.class); } - @GET - @Path("/eventIds") - @Produces(Constants.V1_JSON) - @Operation(summary = "Retrieves event IDs under an event series.") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "Success"), - @ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found") - }) - public Set getEventIds() throws JsonProcessingException { - Set eventIds = this.eventService.getIdsBySeriesId(this.seriesId); - if (eventIds.isEmpty()) - throw new WebApplicationException("Series or events not found", Status.NOT_FOUND); - return eventIds; - } - @GET @Path("/events") @Produces(Constants.V1_JSON) @@ -109,13 +93,15 @@ public class SeriesApi { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "404", description = "An event series with the specified ID could not be found") }) - public List getEvents(@QueryParam("reverse") Boolean reverse) throws JsonProcessingException { - Map rows = this.eventService.getBySeriesId(this.seriesId, - !Boolean.TRUE.equals(reverse)); + public List getEvents(@QueryParam("reverse") Boolean reverse) { + Map rows = this.eventService.getBySeriesId(this.seriesId); if (rows.isEmpty()) throw new WebApplicationException("Series or events not found", Status.NOT_FOUND); - return this.converter.convertValue(rows.values(), Event.class); + List events = this.converter.convertValue(rows.values(), Event.class); + if (Boolean.TRUE.equals(reverse)) + Collections.reverse(events); + return events; } } diff --git a/src/main/java/com/poststats/golf/api/model/Event.java b/src/main/java/com/poststats/golf/api/model/Event.java index 3afdfc3..bc0955d 100644 --- a/src/main/java/com/poststats/golf/api/model/Event.java +++ b/src/main/java/com/poststats/golf/api/model/Event.java @@ -2,6 +2,12 @@ package com.poststats.golf.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.poststats.golf.api.Constants; +import com.poststats.service.impl.DefaultFormattingService; +import com.poststats.transformer.GeocodeSource; +import com.poststats.transformer.GeocodeTarget; +import com.poststats.transformer.GeocodeTarget.GeocodeField; +import com.poststats.transformer.MapCondition; import com.poststats.transformer.MapEntry; import jakarta.annotation.Generated; import java.time.LocalDate; @@ -24,10 +30,126 @@ public class Event extends TransientEvent { @MapEntry private LocalDate deadline; + @MapEntry + @GeocodeTarget(GeocodeField.City) + private String addrcity; + + @MapEntry + @GeocodeTarget(GeocodeField.State) + private String addrstate; + + @MapEntry + @GeocodeTarget(GeocodeField.Country) + private String addrcountry; + @JsonProperty @MapEntry private Series series; + @JsonProperty + @MapEntry + private Boolean financesEnabled; + + @JsonProperty + @MapEntry + private Boolean optionsEnabled; + + @JsonProperty + @MapEntry + private Boolean notebookEnabled; + + @JsonProperty + @MapEntry + private Boolean calendarEnabled; + + @JsonProperty + @MapEntry + private Boolean pairingsEnabled; + + @JsonProperty + @MapEntry + private Boolean teamsEnabled; + + @JsonProperty + @MapEntry + private Boolean lodgingEnabled; + + @JsonProperty + @MapEntry + private Boolean documentsEnabled; + + @JsonProperty + @MapEntry + private Boolean awardsEnabled; + + @JsonProperty + @MapEntry + private Boolean specialHolesEnabled; + + @JsonProperty + @MapEntry + private Boolean courseHandicapEnabled; + + @JsonProperty + @MapEntry + @MapCondition(rolesAllowed = { + Constants.EVENT_ROLE_PREFIX + "admin" + }) + private LocalDate registrationLiveline; + + @JsonProperty + @MapEntry + @MapCondition(rolesAllowed = { + Constants.EVENT_ROLE_PREFIX + "admin" + }) + private LocalDate registrationHideline; + + @JsonProperty + @MapEntry + private LocalDate registrationDeadline; + + @JsonProperty + @MapEntry + @MapCondition(rolesAllowed = { + Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "finance" + }) + private LocalDate financesLiveline; + + @JsonProperty + @MapEntry + @MapCondition(rolesAllowed = { + Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "pairing" + }) + private LocalDate pairingsLiveline; + + @JsonProperty + @MapEntry + @MapCondition(rolesAllowed = { + Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "pairing" + }) + private LocalDate teamsLiveline; + + @JsonProperty + @MapEntry + @MapCondition(rolesAllowed = { + Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "options" + }) + private LocalDate lodgingLiveline; + + @JsonProperty + @MapEntry + @MapCondition(rolesAllowed = { + Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "pairing" + }) + private LocalDate documentsLiveline; + + @JsonProperty + @MapEntry + @MapCondition(rolesAllowed = { + Constants.EVENT_ROLE_PREFIX + "admin", Constants.EVENT_ROLE_PREFIX + "pairing" + }) + private LocalDate specialHolesLiveline; + @Generated("Eclipse") public long getId() { return id; @@ -58,6 +180,20 @@ public class Event extends TransientEvent { this.deadline = deadline; } + @Override + @GeocodeSource + public String getFuzzyLocation() { + synchronized (this) { + if (super.getFuzzyLocation() == null) { + String address = new DefaultFormattingService().formatFuzzyPostalAddress(null, this.addrcity, + this.addrstate, this.addrcountry, null); + super.setFuzzyLocation(address); + } + } + + return super.getFuzzyLocation(); + } + public Series getSeries() { return series; } @@ -66,6 +202,166 @@ public class Event extends TransientEvent { this.series = series; } + public Boolean getAwardsEnabled() { + return awardsEnabled; + } + + public void setAwardsEnabled(Boolean awardsEnabled) { + this.awardsEnabled = awardsEnabled; + } + + public Boolean getCalendarEnabled() { + return calendarEnabled; + } + + public void setCalendarEnabled(Boolean calendarEnabled) { + this.calendarEnabled = calendarEnabled; + } + + public Boolean getCourseHandicapEnabled() { + return courseHandicapEnabled; + } + + public void setCourseHandicapEnabled(Boolean courseHandicapEnabled) { + this.courseHandicapEnabled = courseHandicapEnabled; + } + + public Boolean getDocumentsEnabled() { + return documentsEnabled; + } + + public void setDocumentsEnabled(Boolean documentsEnabled) { + this.documentsEnabled = documentsEnabled; + } + + public Boolean getFinancesEnabled() { + return financesEnabled; + } + + public void setFinancesEnabled(Boolean financesEnabled) { + this.financesEnabled = financesEnabled; + } + + public Boolean getLodgingEnabled() { + return lodgingEnabled; + } + + public void setLodgingEnabled(Boolean lodgingEnabled) { + this.lodgingEnabled = lodgingEnabled; + } + + public Boolean getNotebookEnabled() { + return notebookEnabled; + } + + public void setNotebookEnabled(Boolean notebookEnabled) { + this.notebookEnabled = notebookEnabled; + } + + public Boolean getOptionsEnabled() { + return optionsEnabled; + } + + public void setOptionsEnabled(Boolean optionsEnabled) { + this.optionsEnabled = optionsEnabled; + } + + public Boolean getPairingsEnabled() { + return pairingsEnabled; + } + + public void setPairingsEnabled(Boolean pairingsEnabled) { + this.pairingsEnabled = pairingsEnabled; + } + + public Boolean getSpecialHolesEnabled() { + return specialHolesEnabled; + } + + public void setSpecialHolesEnabled(Boolean specialHolesEnabled) { + this.specialHolesEnabled = specialHolesEnabled; + } + + public Boolean getTeamsEnabled() { + return teamsEnabled; + } + + public void setTeamsEnabled(Boolean teamsEnabled) { + this.teamsEnabled = teamsEnabled; + } + + public LocalDate getRegistrationLiveline() { + return registrationLiveline; + } + + public void setRegistrationLiveline(LocalDate registrationLiveline) { + this.registrationLiveline = registrationLiveline; + } + + public LocalDate getRegistrationHideline() { + return registrationHideline; + } + + public void setRegistrationHideline(LocalDate registrationHideline) { + this.registrationHideline = registrationHideline; + } + + public LocalDate getRegistrationDeadline() { + return registrationDeadline; + } + + public void setRegistrationDeadline(LocalDate registrationDeadline) { + this.registrationDeadline = registrationDeadline; + } + + public LocalDate getDocumentsLiveline() { + return documentsLiveline; + } + + public void setDocumentsLiveline(LocalDate documentsLiveline) { + this.documentsLiveline = documentsLiveline; + } + + public LocalDate getFinancesLiveline() { + return financesLiveline; + } + + public void setFinancesLiveline(LocalDate financesLiveline) { + this.financesLiveline = financesLiveline; + } + + public LocalDate getLodgingLiveline() { + return lodgingLiveline; + } + + public void setLodgingLiveline(LocalDate lodgingLiveline) { + this.lodgingLiveline = lodgingLiveline; + } + + public LocalDate getPairingsLiveline() { + return pairingsLiveline; + } + + public void setPairingsLiveline(LocalDate pairingsLiveline) { + this.pairingsLiveline = pairingsLiveline; + } + + public LocalDate getSpecialHolesLiveline() { + return specialHolesLiveline; + } + + public void setSpecialHolesLiveline(LocalDate specialHolesLiveline) { + this.specialHolesLiveline = specialHolesLiveline; + } + + public LocalDate getTeamsLiveline() { + return teamsLiveline; + } + + public void setTeamsLiveline(LocalDate teamsLiveline) { + this.teamsLiveline = teamsLiveline; + } + @Generated("Spark") public Event withId(long id) { this.id = id; @@ -89,4 +385,89 @@ public class Event extends TransientEvent { return this; } + public Event withDocumentsEnabled(Boolean documentsEnabled) { + this.documentsEnabled = documentsEnabled; + return this; + } + + public Event withFinancesEnabled(Boolean financesEnabled) { + this.financesEnabled = financesEnabled; + return this; + } + + public Event withLodgingEnabled(Boolean lodgingEnabled) { + this.lodgingEnabled = lodgingEnabled; + return this; + } + + public Event withNotebookEnabled(Boolean notebookEnabled) { + this.notebookEnabled = notebookEnabled; + return this; + } + + public Event withOptionsEnabled(Boolean optionsEnabled) { + this.optionsEnabled = optionsEnabled; + return this; + } + + public Event withPairingsEnabled(Boolean pairingsEnabled) { + this.pairingsEnabled = pairingsEnabled; + return this; + } + + public Event withSpecialHolesEnabled(Boolean specialHolesEnabled) { + this.specialHolesEnabled = specialHolesEnabled; + return this; + } + + public Event withTeamsEnabled(Boolean teamsEnabled) { + this.teamsEnabled = teamsEnabled; + return this; + } + + public Event withRegistrationLiveline(LocalDate registrationLiveline) { + this.registrationLiveline = registrationLiveline; + return this; + } + + public Event withRegistrationHideline(LocalDate registrationHideline) { + this.registrationHideline = registrationHideline; + return this; + } + + public Event withRegistrationDeadline(LocalDate registrationDeadline) { + this.registrationDeadline = registrationDeadline; + return this; + } + + public Event withDocumentsLiveline(LocalDate documentsLiveline) { + this.documentsLiveline = documentsLiveline; + return this; + } + + public Event withFinancesLiveline(LocalDate financesLiveline) { + this.financesLiveline = financesLiveline; + return this; + } + + public Event withLodgingLiveline(LocalDate lodgingLiveline) { + this.lodgingLiveline = lodgingLiveline; + return this; + } + + public Event withPairingsLiveline(LocalDate pairingsLiveline) { + this.pairingsLiveline = pairingsLiveline; + return this; + } + + public Event withSpecialHolesLiveline(LocalDate specialHolesLiveline) { + this.specialHolesLiveline = specialHolesLiveline; + return this; + } + + public Event withTeamsLiveline(LocalDate teamsLiveline) { + this.teamsLiveline = teamsLiveline; + return this; + } + } diff --git a/src/main/java/com/poststats/golf/api/model/Series.java b/src/main/java/com/poststats/golf/api/model/Series.java index ddc497c..28cedfc 100644 --- a/src/main/java/com/poststats/golf/api/model/Series.java +++ b/src/main/java/com/poststats/golf/api/model/Series.java @@ -10,16 +10,12 @@ import jakarta.annotation.Generated; * @author brian.long@poststats.com */ @JsonIgnoreProperties(ignoreUnknown = true) -public class Series { +public class Series extends TransientSeries { @JsonProperty(required = true, access = Access.READ_ONLY) @MapEntry("seriesID") private long id; - @JsonProperty(required = true) - @MapEntry("series") - private String name; - @Generated("Eclipse") public long getId() { return id; @@ -30,26 +26,10 @@ public class Series { this.id = id; } - @Generated("Eclipse") - public String getName() { - return name; - } - - @Generated("Eclipse") - public void setName(String name) { - this.name = name; - } - @Generated("Spark") public Series withId(long id) { this.id = id; return this; } - @Generated("Spark") - public Series withName(String name) { - this.name = name; - return this; - } - } diff --git a/src/main/java/com/poststats/golf/api/model/TransientEvent.java b/src/main/java/com/poststats/golf/api/model/TransientEvent.java index 0003c23..7795a09 100644 --- a/src/main/java/com/poststats/golf/api/model/TransientEvent.java +++ b/src/main/java/com/poststats/golf/api/model/TransientEvent.java @@ -3,6 +3,7 @@ package com.poststats.golf.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.poststats.transformer.MapEntry; + import jakarta.annotation.Generated; /** @@ -11,10 +12,32 @@ import jakarta.annotation.Generated; @JsonIgnoreProperties(ignoreUnknown = true) public class TransientEvent { + public enum EventType { + @JsonProperty("outing") + @MapEntry("outing") + Outing, @JsonProperty("tourney") + @MapEntry("tourney") + Tourney, @JsonProperty("trip") + @MapEntry("trip") + Trip, @JsonProperty("league") + @MapEntry("league") + League + } + @JsonProperty(required = true) @MapEntry("event") private String name; + @JsonProperty(required = true) + @MapEntry + private EventType type; + + @JsonProperty + private boolean showPublic; + + @JsonProperty + private String fuzzyLocation; + @Generated("Eclipse") public String getName() { return name; @@ -25,10 +48,48 @@ public class TransientEvent { this.name = name; } - @Generated("Spark") + public EventType getType() { + return type; + } + + public void setType(EventType type) { + this.type = type; + } + + public boolean isShowPublic() { + return showPublic; + } + + public void setShowPublic(boolean showPublic) { + this.showPublic = showPublic; + } + + public String getFuzzyLocation() { + return fuzzyLocation; + } + + public void setFuzzyLocation(String fuzzyLocation) { + this.fuzzyLocation = fuzzyLocation; + } + public TransientEvent withName(String name) { this.name = name; return this; } + public TransientEvent withType(EventType type) { + this.type = type; + return this; + } + + public TransientEvent withShowPublic(boolean showPublic) { + this.showPublic = showPublic; + return this; + } + + public TransientEvent withFuzzyLocation(String fuzzyLocation) { + this.fuzzyLocation = fuzzyLocation; + return this; + } + } diff --git a/src/main/java/com/poststats/golf/api/model/TransientSeries.java b/src/main/java/com/poststats/golf/api/model/TransientSeries.java new file mode 100644 index 0000000..1377e99 --- /dev/null +++ b/src/main/java/com/poststats/golf/api/model/TransientSeries.java @@ -0,0 +1,34 @@ +package com.poststats.golf.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.poststats.transformer.MapEntry; +import jakarta.annotation.Generated; + +/** + * @author brian.long@poststats.com + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class TransientSeries { + + @JsonProperty(required = true) + @MapEntry("series") + private String name; + + @Generated("Eclipse") + public String getName() { + return name; + } + + @Generated("Eclipse") + public void setName(String name) { + this.name = name; + } + + @Generated("Spark") + public TransientSeries withName(String name) { + this.name = name; + return this; + } + +} diff --git a/src/main/java/com/poststats/golf/service/EventService.java b/src/main/java/com/poststats/golf/service/EventService.java index 0b99cd1..e5fd6a6 100644 --- a/src/main/java/com/poststats/golf/service/EventService.java +++ b/src/main/java/com/poststats/golf/service/EventService.java @@ -25,7 +25,7 @@ public interface EventService { Set getIdsBySeriesId(int seriesId); - Map getBySeriesId(int seriesId, boolean chronological); + Map getBySeriesId(int seriesId); Integer getSeriesId(long eventId); diff --git a/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java index 0c26112..a8d1c68 100644 --- a/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventFinanceServiceDAO.java @@ -2,12 +2,14 @@ package com.poststats.golf.service.db; import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; +import com.poststats.golf.api.Constants; import com.poststats.golf.service.EventFinanceService; -import com.poststats.golf.sql.GolfSQL; +import com.poststats.provider.Statement; +import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; -import com.poststats.sql.PostStatsDataSource; import jakarta.enterprise.context.ApplicationScoped; -import java.sql.Connection; +import jakarta.inject.Inject; +import jakarta.inject.Named; import java.sql.SQLException; import java.util.List; @@ -16,65 +18,60 @@ public class EventFinanceServiceDAO implements EventFinanceService { @Override public List getPersonsBalances(long eventId) { - Connection dbcon = PostStatsDataSource.getInstance().acquire(true); try { - return this.queryPersonsBalances(dbcon, eventId); + FlexPreparedStatement fps = this.sqlSelectBalances.buildPreparedStatement(); + try { + for (int i = 1; i <= 5; i++) + fps.setIntegerU(i, eventId); + return fps.executeQuery().getAllRows(); + } finally { + fps.close(); + } } catch (SQLException se) { throw new ServiceException(se); - } finally { - PostStatsDataSource.getInstance().release(dbcon); } } - private List queryPersonsBalances(Connection dbcon, long eventId) throws SQLException { - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_BALANCES); - try { - for (int i = 1; i <= 5; i++) - fps.setIntegerU(i, eventId); - return fps.executeQuery().getAllRows(); - } finally { - fps.close(); - } - } - - - - private static final String SQL_SELECT_BALANCES = GolfSQL.changeSchema(new StringBuilder() - .append("SELECT P.personID, P.prefix, P.fname, P.lname, P.suffix, ") - .append("TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance ") - .append("FROM (") - .append("SELECT ALL EP.personID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid ") - .append("FROM ~g~.EventPerson EP ") - .append("LEFT JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) ") - .append("WHERE EP.eventID=? ") - .append("UNION ALL ") - .append("SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid ") - .append("FROM ~g~.EventPerson EP ") - .append("INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) ") - .append("INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) ") - .append("WHERE EP.eventID=? AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE ") - .append("UNION ALL ") - .append("SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid ") - .append("FROM ~g~.EventPerson EP ") - .append("INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) ") - .append("INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) ") - .append("WHERE EP.eventID=? AND EPO.itemID IS NOT NULL ") - .append("AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) ") - .append("AND EO.amount IS NOT NULL AND EO.waive IS FALSE ") - .append("UNION ALL ") - .append("SELECT ALL EP.personID, EP.epersonID, EOI.amount expenses, 0 paid ") - .append("FROM ~g~.EventPerson EP ") - .append("INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) ") - .append("INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) ") - .append("INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) ") - .append("WHERE EP.eventID=? AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL ") - .append("UNION ALL ") - .append("SELECT ALL EPP.personID, EP.epersonID, 0 expenses, EPP.amount paid ") - .append("FROM ~g~.EventPersonPayment EPP ") - .append("LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) ") - .append("WHERE EPP.eventID=?) TT ") - .append("INNER JOIN ~p~.Person P ") - .append("GROUP BY P.personID ") - .append("ORDER BY P.lname, P.fname, P.suffix").toString()); + @Inject + @Named(Constants.STATEMENT_PROVIDER_GOLF) + @Statement( + sql = "SELECT P.personID, P.prefix, P.fname, P.lname, P.suffix, " + + " TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance " + + "FROM (" + + " SELECT ALL EP.personID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid " + + " FROM ~g~.EventPerson EP " + + " LEFT JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) " + + " WHERE EP.eventID=? " + + " UNION ALL " + + " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid " + + " FROM ~g~.EventPerson EP " + + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + + " WHERE EP.eventID=? AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE " + + " UNION ALL " + + " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid " + + " FROM ~g~.EventPerson EP " + + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + + " WHERE EP.eventID=? AND EPO.itemID IS NOT NULL " + + " AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) " + + " AND EO.amount IS NOT NULL AND EO.waive IS FALSE " + + " UNION ALL " + + " SELECT ALL EP.personID, EP.epersonID, EOI.amount expenses, 0 paid " + + " FROM ~g~.EventPerson EP " + + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + + " INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) " + + " WHERE EP.eventID=? AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL " + + " UNION ALL " + + " SELECT ALL EPP.personID, EP.epersonID, 0 expenses, EPP.amount paid " + + " FROM ~g~.EventPersonPayment EPP " + + " LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) " + + " WHERE EPP.eventID=?) TT " + + " INNER JOIN ~p~.Person P " + + "GROUP BY P.personID " + + "ORDER BY P.lname, P.fname, P.suffix" + ) + private StatementProvider sqlSelectBalances; } diff --git a/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java index ed4b80c..d309221 100644 --- a/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventPersonServiceDAO.java @@ -1,15 +1,18 @@ package com.poststats.golf.service.db; import com.brianlong.cache.CacheRetrievalException; -import com.brianlong.sql.DataSet; import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; -import com.poststats.golf.cache.GolferCache; +import com.poststats.golf.api.Constants; import com.poststats.golf.service.EventPersonService; -import com.poststats.golf.sql.GolfSQL; +import com.poststats.golf.service.PersonService; +import com.poststats.provider.Statement; +import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; import com.poststats.sql.PostStatsDataSource; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.inject.Named; import java.math.BigInteger; import java.sql.Connection; import java.sql.SQLException; @@ -23,25 +26,37 @@ import java.util.Set; @ApplicationScoped public class EventPersonServiceDAO implements EventPersonService { + @Inject + private PersonService golferService; + @Override public List getPeople(long eventId, boolean includeDetails) { - Connection dbcon = PostStatsDataSource.getInstance().acquire(true); try { - return this.queryPersons(dbcon, eventId, includeDetails); + return this.query(this.sqlSelectPersonIds, eventId, 2, includeDetails); } catch (CacheRetrievalException cre) { throw new ServiceException(cre); } catch (SQLException se) { throw new ServiceException(se); - } finally { - PostStatsDataSource.getInstance().release(dbcon); } } + @Inject + @Named(Constants.STATEMENT_PROVIDER_GOLF) + @Statement( + sql = "SELECT epersonID, personID FROM ~g~.EventPerson WHERE eventID=? " + + "UNION " + + "SELECT DISTINCT NULL, personID " + + "FROM ~g~.EventPersonAccessControl EPAC " + + " LEFT JOIN ~g~.EventPerson EP ON (EPAC.eventID=EP.eventID AND EPAC.personID=EP.personID) " + + "WHERE eventID=? AND EP.personID IS NULL " + ) + private StatementProvider sqlSelectPersonIds; + @Override public List getParticipants(long eventId, boolean includeDetails) { Connection dbcon = PostStatsDataSource.getInstance().acquire(true); try { - return this.queryParticipants(dbcon, eventId, includeDetails); + return this.query(this.sqlSelectParticipantIds, eventId, 1, includeDetails); } catch (CacheRetrievalException cre) { throw new ServiceException(cre); } catch (SQLException se) { @@ -51,33 +66,43 @@ public class EventPersonServiceDAO implements EventPersonService { } } + @Inject + @Named(Constants.STATEMENT_PROVIDER_GOLF) + @Statement(sql = "SELECT epersonID, personID FROM ~g~.EventPerson WHERE eventID=?") + private StatementProvider sqlSelectParticipantIds; + @Override public Set getSeriesEventIdsAsParticipant(int seriesId, long personId) { - Connection dbcon = PostStatsDataSource.getInstance().acquire(true); try { - return this.querySeriesEventIdsAsParticipant(dbcon, seriesId, personId); + FlexPreparedStatement fps = this.sqlSelectFellowParticipants.buildPreparedStatement(); + try { + fps.setSmallintU(1, seriesId); + fps.setIntegerU(2, personId); + return fps.executeQuery().getFirstColumn(Long.class, new HashSet<>()); + } finally { + fps.close(); + } } catch (SQLException se) { throw new ServiceException(se); - } finally { - PostStatsDataSource.getInstance().release(dbcon); } } - private List queryPersons(Connection dbcon, long eventId, boolean includeDetails) - throws CacheRetrievalException, SQLException { - return this.query(dbcon, SQL_SELECT_PERSONS, eventId, 2, includeDetails); - } + @Inject + @Named(Constants.STATEMENT_PROVIDER_GOLF) + @Statement( + sql = "SELECT DISTINCT EP2.personID " + + "FROM ~g~.EventPerson EP1 " + + " INNER JOIN Event E ON (EP1.eventID=E.eventID) " + + " INNER JOIN EventPerson EP2 ON (E.eventID=EP2.eventID) " + + "WHERE EP1.personID=? AND E.seriesID=?" + ) + private StatementProvider sqlSelectFellowParticipants; - private List queryParticipants(Connection dbcon, long eventId, boolean includeDetails) - throws CacheRetrievalException, SQLException { - return this.query(dbcon, SQL_SELECT_PARTICIPANTS, eventId, 1, includeDetails); - } - - private List query(Connection dbcon, String sql, long eventId, int parameterCount, boolean includeDetails) + private List query(StatementProvider provider, long eventId, int parameterCount, boolean includeDetails) throws CacheRetrievalException, SQLException { Map epersonIdMap; - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, sql); + FlexPreparedStatement fps = provider.buildPreparedStatement(); try { for (int i = 1; i <= parameterCount; i++) fps.setIntegerU(i, eventId); @@ -86,7 +111,7 @@ public class EventPersonServiceDAO implements EventPersonService { fps.close(); } - Map personMap = GolferCache.getInstance().get(epersonIdMap.values()); + Map personMap = this.golferService.get(epersonIdMap.values()); List rows = new ArrayList<>(personMap.size()); for (Entry eperson : epersonIdMap.entrySet()) { @@ -98,39 +123,4 @@ public class EventPersonServiceDAO implements EventPersonService { return rows; } - private Set querySeriesEventIdsAsParticipant(Connection dbcon, int seriesId, long personId) - throws SQLException { - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_SERIES_PARTICIPANTS); - try { - fps.setSmallintU(1, seriesId); - fps.setIntegerU(2, personId); - - Set set = new HashSet<>(); - fps.executeQuery().getFirstColumn(Long.class, set); - return set; - } finally { - fps.close(); - } - } - - - - private static final String SQL_SELECT_PARTICIPANTS = GolfSQL.changeSchema( - "SELECT epersonID, personID FROM ~g~.EventPerson WHERE eventID=?"); - - private static final String SQL_SELECT_SERIES_PARTICIPANTS = GolfSQL.changeSchema( - "SELECT DISTINCT EP2.personID " - + "FROM ~g~.EventPerson EP1 " - + " INNER JOIN Event E ON (EP1.eventID=E.eventID) " - + " INNER JOIN EventPerson EP2 ON (E.eventID=EP2.eventID) " - + "WHERE EP1.personID=? AND E.seriesID=?"); - - private static final String SQL_SELECT_PERSONS = GolfSQL.changeSchema( - "SELECT epersonID, personID FROM ~g~.EventPerson WHERE eventID=? " - + "UNION " - + "SELECT DISTINCT NULL, personID " - + "FROM ~g~.EventPersonAccessControl EPAC " - + " LEFT JOIN ~g~.EventPerson EP ON (EPAC.eventID=EP.eventID AND EPAC.personID=EP.personID) " - + "WHERE eventID=? AND EP.personID IS NULL "); - } diff --git a/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java b/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java index 02d4f6f..c8a2d6f 100644 --- a/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/EventServiceDAO.java @@ -5,8 +5,6 @@ import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; import com.poststats.golf.api.Constants; import com.poststats.golf.service.EventService; -import com.poststats.golf.sql.GolfDataSource; -import com.poststats.golf.sql.GolfSQL; import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; @@ -14,12 +12,9 @@ import com.poststats.service.db.CacheableServiceDAO; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.inject.Named; -import java.sql.Connection; import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Set; @@ -34,53 +29,69 @@ public class EventServiceDAO extends CacheableServiceDAO implements EventS } @Override - public Map getBySeriesId(int seriesId, boolean chronological) { - List eventIds = new LinkedList<>(); - - Connection dbcon = GolfDataSource.getInstance().acquire(true); + public Set getIdsBySeriesId(int seriesId) { try { - this.queryEventIds(dbcon, seriesId, chronological, eventIds); + FlexPreparedStatement fps = this.sqlSelectIdsBySeriesId.buildPreparedStatement(); + try { + fps.setSmallintU(1, seriesId); + return fps.executeQuery().getFirstColumn(Long.class, new HashSet<>()); + } finally { + fps.close(); + } } catch (SQLException se) { throw new ServiceException(se); - } finally { - GolfDataSource.getInstance().release(dbcon); } - - return this.get(eventIds); } + @Inject + @Named(Constants.STATEMENT_PROVIDER_GOLF) + @Statement(sql = "SELECT eventId FROM ~g~.Event WHERE seriesID=? ") + private StatementProvider sqlSelectIdsBySeriesId; + @Override - public Set getIdsBySeriesId(int seriesId) { - Set eventIds = new HashSet<>(); - - Connection dbcon = GolfDataSource.getInstance().acquire(true); + public Map getBySeriesId(int seriesId) { try { - this.queryEventIds(dbcon, seriesId, null, eventIds); + FlexPreparedStatement fps = this.sqlSelectBySeriesId.buildPreparedStatement(); + try { + fps.setSmallintU(1, seriesId); + return fps.executeQuery().getAllRows("eventID", Long.class); + } finally { + fps.close(); + } } catch (SQLException se) { throw new ServiceException(se); - } finally { - GolfDataSource.getInstance().release(dbcon); } - - return eventIds; } + @Inject + @Named(Constants.STATEMENT_PROVIDER_GOLF) + @Statement(sql = "SELECT * FROM ~g~.Event WHERE seriesID=? ORDER BY E.liveline DESC ") + private StatementProvider sqlSelectBySeriesId; + @Override public Integer getSeriesId(long eventId) { FlexMap event = this.getIfHit(eventId); if (event != null) return event.getInteger("seriesID"); - Connection dbcon = GolfDataSource.getInstance().acquire(true); try { - return this.querySeriesId(dbcon, eventId); + FlexPreparedStatement fps = this.sqlSelectSeriesId.buildPreparedStatement(); + try { + fps.setSmallintU(1, eventId); + return fps.executeQuery().getOne(Integer.class); + } finally { + fps.close(); + } } catch (SQLException se) { throw new ServiceException(se); - } finally { - GolfDataSource.getInstance().release(dbcon); } } + @Inject + @Named(Constants.STATEMENT_PROVIDER_GOLF) + @Statement(sql = "SELECT seriesID FROM ~g~.Event WHERE eventID=? ") + private StatementProvider sqlSelectSeriesId; + @Override protected long getCacheExpirationInSeconds() { return this.defaultCacheExpirationInSeconds; @@ -103,7 +114,7 @@ public class EventServiceDAO extends CacheableServiceDAO implements EventS sql = "SELECT EF.*, E.* " + "FROM ~g~.Event E " + " INNER JOIN ~g~.EventFeature EF ON (E.eventID=EF.eventID) " - + "WHERE eventID=? " + + "WHERE E.eventID=? " ) private StatementProvider sqlSelectEvent; @@ -123,40 +134,8 @@ public class EventServiceDAO extends CacheableServiceDAO implements EventS sql = "SELECT EF.*, E.* " + "FROM ~g~.Event E " + " INNER JOIN ~g~.EventFeature EF ON (E.eventID=EF.eventID) " - + "WHERE eventID IN (??) " + + "WHERE E.eventID IN (??) " ) private StatementProvider sqlSelectEvents; - private void queryEventIds(Connection dbcon, int seriesId, Boolean chronological, Collection eventIds) - throws SQLException { - String sql = SQL_SELECT_EVENTS; - if (chronological != null) - sql += chronological ? SQL_ORDER_EVENTS_ASC : SQL_ORDER_EVENTS_DESC; - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, sql); - try { - fps.setSmallintU(1, seriesId); - fps.executeQuery().getFirstColumn(Long.class, eventIds); - } finally { - fps.close(); - } - } - - private static final String SQL_SELECT_EVENTS = GolfSQL.changeSchema( - "SELECT E.eventID FROM ~g~.Event E WHERE E.seriesID=? "); - private static final String SQL_ORDER_EVENTS_ASC = "ORDER BY E.liveline ASC"; - private static final String SQL_ORDER_EVENTS_DESC = "ORDER BY E.liveline DESC"; - - private Integer querySeriesId(Connection dbcon, long eventId) throws SQLException { - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_SERIES_REF); - try { - fps.setIntegerU(1, eventId); - return fps.executeQuery().getOne(Integer.class); - } finally { - fps.close(); - } - } - - private static final String SQL_SELECT_SERIES_REF = GolfSQL.changeSchema( - "SELECT seriesID FROM ~g~.Event WHERE eventID=?"); - } diff --git a/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java b/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java index 83bfbcb..142e9a9 100644 --- a/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java +++ b/src/main/java/com/poststats/golf/service/db/SeriesServiceDAO.java @@ -5,8 +5,6 @@ import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.util.FlexMap; import com.poststats.golf.api.Constants; import com.poststats.golf.service.SeriesService; -import com.poststats.golf.sql.GolfDataSource; -import com.poststats.golf.sql.GolfSQL; import com.poststats.provider.Statement; import com.poststats.provider.StatementProvider; import com.poststats.service.ServiceException; @@ -14,7 +12,6 @@ import com.poststats.service.db.CacheableServiceDAO; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.inject.Named; -import java.sql.Connection; import java.sql.SQLException; import java.util.Collection; import java.util.Map; @@ -31,16 +28,24 @@ public class SeriesServiceDAO extends CacheableServiceDAO implements Se @Override public DataSet getByEventId(long eventId) { - Connection dbcon = GolfDataSource.getInstance().acquire(true); try { - return this.querySeries(dbcon, eventId); + FlexPreparedStatement fps = this.sqlSelectByEventId.buildPreparedStatement(); + try { + fps.setIntegerU(1, eventId); + return fps.executeQuery().getNextRow(); + } finally { + fps.close(); + } } catch (SQLException se) { throw new ServiceException(se); - } finally { - GolfDataSource.getInstance().release(dbcon); } } + @Inject + @Named(Constants.STATEMENT_PROVIDER_GOLF) + @Statement(sql = "SELECT * FROM ~g~.Series WHERE eventID=? ") + private StatementProvider sqlSelectByEventId; + @Override protected long getCacheExpirationInSeconds() { return this.defaultCacheExpirationInSeconds; @@ -77,19 +82,4 @@ public class SeriesServiceDAO extends CacheableServiceDAO implements Se @Statement(sql = "SELECT S.* FROM ~g~.Series S WHERE seriesID IN (??) ") private StatementProvider sqlSelectSerieses; - private DataSet querySeries(Connection dbcon, long eventId) throws SQLException { - FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_SERIES_BY_EVENT_ID); - try { - fps.setIntegerU(1, eventId); - return fps.executeQuery().getNextRow(); - } finally { - fps.close(); - } - } - - private static final String SQL_SELECT = GolfSQL.changeSchema( - "SELECT * FROM ~g~.Series "); - private static final String SQL_SELECT_SERIES_BY_EVENT_ID = GolfSQL.changeSchema( - "SELECT * FROM ~g~.Series WHERE eventID=? "); - }