further handicap impl

This commit is contained in:
2023-10-02 13:02:37 -04:00
parent b571db1f4e
commit 360165c64e
21 changed files with 1159 additions and 366 deletions

View File

@@ -30,7 +30,7 @@ public interface CourseApi {
description = "Retreives name, location, and other direct meta-data about the specified course."
)
public abstract Course get(@Parameter(description = "A unique identifier for a golf course")
@NotNull @Positive @PathParam("courseId") int courseId);
@NotNull @Positive @PathParam("courseId") int courseId);
@GET
@Path("/nine/byName/{name}")
@@ -40,8 +40,7 @@ public interface CourseApi {
description = "Retreives name, location, and other direct meta-data about the specified course."
)
public abstract CourseNine getNine(@Parameter(description = "A unique identifier for a golf course")
@NotNull @Positive @PathParam("courseId") int courseId,
@PathParam("name") String name);
@NotNull @Positive @PathParam("courseId") int courseId, @PathParam("name") String name);
@GET
@Path("/nine/{nineId:[0-9]+}")
@@ -51,7 +50,6 @@ public interface CourseApi {
description = "Retreives name, location, and other direct meta-data about the specified course."
)
public abstract CourseNine getNine(@Parameter(description = "A unique identifier for a golf course")
@NotNull @Positive @PathParam("courseId") int courseId,
@PathParam("nineId") long courseNineId);
@NotNull @Positive @PathParam("courseId") int courseId, @PathParam("nineId") long courseNineId);
}

View File

@@ -33,7 +33,8 @@ public interface EventApi {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
Event get(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
Event get(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/detail")
@@ -46,7 +47,8 @@ public interface EventApi {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
Event getDetail(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
Event getDetail(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@POST
@Path("/document/{documentId}/send")
@@ -66,8 +68,11 @@ public interface EventApi {
description = "An event or document with the specified ID could not be found"
)
})
void sendDocument(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event document") @NotNull @Positive @PathParam("documentId") long documentId);
void sendDocument(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event document")
@NotNull @Positive @PathParam("documentId") long documentId);
@POST
@Path("/document/{documentId}/sendTest/{personId}")
@@ -87,8 +92,12 @@ public interface EventApi {
description = "An event, document, or person with the specified ID could not be found"
)
})
void sendTestDocument(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event document") @NotNull @Positive @PathParam("documentId") long documentId,
@Parameter(description = "A unique identifier for a person") @NotNull @Positive @PathParam("personId") long personId);
void sendTestDocument(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event document")
@NotNull @Positive @PathParam("documentId") long documentId,
@Parameter(description = "A unique identifier for a person")
@NotNull @Positive @PathParam("personId") long personId);
}

View File

@@ -38,8 +38,9 @@ public interface EventFinanceApi {
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
List<Map<String, Object>> getBalanceByPersonsAsJson(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId,
@QueryParam("minBalance") Float minBalance,
List<Map<String, Object>> getBalanceByPersonsAsJson(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId, @QueryParam("minBalance") Float minBalance,
@QueryParam("maxBalance") Float maxBalance);
@GET
@@ -57,7 +58,8 @@ public interface EventFinanceApi {
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
StreamingOutput getBalanceByPersonsAsCsv(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
StreamingOutput getBalanceByPersonsAsCsv(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/balance/person/{personId}")
@@ -77,8 +79,11 @@ public interface EventFinanceApi {
description = "An event or person with the specified IDs could not be found"
)
})
Map<String, Object> getBalanceByPersonsAsJson(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for a person") @NotNull @Positive @PathParam("personId") long personId);
Map<String, Object> getBalanceByPersonsAsJson(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for a person")
@NotNull @Positive @PathParam("personId") long personId);
@GET
@Path("/series/balance/persons")
@@ -95,6 +100,8 @@ public interface EventFinanceApi {
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
List<Map<String, Object>> getSeriesBalanceByPersonsAsJson(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
List<Map<String, Object>> getSeriesBalanceByPersonsAsJson(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
}

View File

@@ -23,7 +23,7 @@ import jakarta.ws.rs.core.StreamingOutput;
@Path("/golf/event/{eventId}")
@Tag(name = "Event Participant API")
public interface EventPersonApi {
@GET
@Path("/people")
@RolesAllowed(
@@ -39,7 +39,8 @@ public interface EventPersonApi {
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
List<? extends EventPerson> get(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
List<? extends EventPerson> get(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/people/detail")
@@ -56,7 +57,8 @@ public interface EventPersonApi {
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
List<? extends EventPerson> getDetail(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
List<? extends EventPerson> getDetail(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/people/csv")
@@ -73,7 +75,8 @@ public interface EventPersonApi {
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
StreamingOutput getAsCsv(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
StreamingOutput getAsCsv(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/participants")
@@ -83,7 +86,8 @@ public interface EventPersonApi {
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
List<? extends EventPerson> getParticipants(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
List<? extends EventPerson> getParticipants(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/participants/csv")
@@ -100,7 +104,8 @@ public interface EventPersonApi {
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
StreamingOutput getParticipantsAsCsv(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
StreamingOutput getParticipantsAsCsv(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/series/participants")
@@ -117,6 +122,7 @@ public interface EventPersonApi {
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
Set<Long> getSeriesParticipants(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
Set<Long> getSeriesParticipants(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
}

View File

@@ -43,7 +43,8 @@ public interface EventRoundApi {
description = "An event with the specified ID or upcoming event rounds could not be found"
)
})
List<EventRound> getNext(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
List<EventRound> getNext(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/round/{eroundId:[0-9]+}")
@@ -59,8 +60,11 @@ public interface EventRoundApi {
description = "An event or event round with the specified ID could not be found"
)
})
EventRound getOne(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event round") @NotNull @Positive @PathParam("eroundId") long eroundId);
EventRound getOne(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event round")
@NotNull @Positive @PathParam("eroundId") long eroundId);
@GET
@Path("/rounds")
@@ -76,7 +80,8 @@ public interface EventRoundApi {
description = "An event with the specified ID or any event rounds could not be found"
)
})
List<EventRound> getAll(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId);
List<EventRound> getAll(@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId);
@GET
@Path("/round/{eroundId:[0-9]+}/pairings")
@@ -89,8 +94,11 @@ public interface EventRoundApi {
description = "An event or its round with the specified ID could not be found"
)
})
List<EventRoundPairing> getPairings(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event round") @NotNull @Positive @PathParam("eroundId") long eroundId);
List<EventRoundPairing> getPairings(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event round")
@NotNull @Positive @PathParam("eroundId") long eroundId);
@GET
@Path("/round/{eroundId:[0-9]+}/pairings/csv")
@@ -103,8 +111,11 @@ public interface EventRoundApi {
description = "An event or its round with the specified ID could not be found"
)
})
StreamingOutput getPairingsAsCsv(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event round") @NotNull @Positive @PathParam("eroundId") long eroundId,
StreamingOutput getPairingsAsCsv(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event round")
@NotNull @Positive @PathParam("eroundId") long eroundId,
@QueryParam("orderBy") List<EventRoundPairingOrder> orderBys,
@QueryParam("lastNameFirst") boolean lastNameFirst);
@@ -119,8 +130,10 @@ public interface EventRoundApi {
description = "An event with the specified ID or upcoming event rounds could not be found"
)
})
EventRoundPairing getPairing(@Parameter(description = "A unique identifier for an event") @NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event round") @NotNull @Positive @PathParam("eroundId") long eroundId,
@PathParam("pairingID") BigInteger pairingId);
EventRoundPairing getPairing(
@Parameter(description = "A unique identifier for an event")
@NotNull @Positive @PathParam("eventId") long eventId,
@Parameter(description = "A unique identifier for an event round")
@NotNull @Positive @PathParam("eroundId") long eroundId, @PathParam("pairingID") BigInteger pairingId);
}

View File

@@ -62,8 +62,6 @@ public class EventApi implements com.poststats.golf.api.EventApi {
FlexMap row = this.eventService.get(eventId);
if (row == null)
throw new WebApplicationException("Event not found", Status.NOT_FOUND);
this.seriesService.inject("seriesID", row, "series");
return this.converter.convertValue(row, Event.class);
}

View File

@@ -86,8 +86,7 @@ public class EventFinanceApi implements com.poststats.golf.api.EventFinanceApi {
@Override
public List<Map<String, Object>> getSeriesBalanceByPersonsAsJson(long eventId) {
Map<Long, DataSet> personsBalances = this.eventFinanceService
.getSeriesPersonsPreviousBalances(eventId);
Map<Long, DataSet> personsBalances = this.eventFinanceService.getSeriesPersonsPreviousBalances(eventId);
List<Map<String, Object>> personsBalancesJson = new ArrayList<>(personsBalances.size());
for (DataSet personBalance : personsBalances.values()) {

View File

@@ -1,11 +1,33 @@
package com.poststats.golf.service;
import com.brianlong.util.FlexMap;
public interface CourseRatingService<R> {
public interface CourseRatingService {
/**
* This method computes a golf course eighteen/tee combination's difficulty
* rating as of today, inclusive.
*
* In some cases, there is no computation, but a simple fetch from an external
* resource. In other cases the ratings will need to be computed. In other
* cases, a rating cannot be determined.
*
* @param etratingId A unique identifier for a golf course eighteen/tee
* combination (gender) rating.
* @return A rating for the course; `null` if one cannot be determined.
*/
R computeEighteenTeeRatingIndex(long etratingId);
FlexMap getNineTeeRating(long ntratingId);
FlexMap getEighteenTeeRating(long etratingId);
/**
* This method computes a golf course nine/tee combination's difficulty rating
* as of today, inclusive.
*
* In some cases, there is no computation, but a simple fetch from an external
* resource. In other cases the ratings will need to be computed. In other
* cases, a rating cannot be determined.
*
* @param ntratingId A unique identifier for a golf course nine/tee combination
* (gender) rating.
* @return A rating for the course; `null` if one cannot be determined.
*/
R computeNineTeeRatingIndex(long ntratingId);
}

View File

@@ -2,7 +2,7 @@ package com.poststats.golf.service;
import java.time.LocalDate;
public interface HandicapIndexService<I, R> {
public interface HandicapIndexService<I> {
/**
* This method computes a golfer's handicap index as of today, inclusive.
@@ -32,32 +32,4 @@ public interface HandicapIndexService<I, R> {
*/
I computeGolferIndex(long personId, LocalDate beforeDay);
/**
* This method computes a golf course eighteen/tee combination's difficulty
* rating as of today, inclusive.
*
* In some cases, there is no computation, but a simple fetch from an external
* resource. In other cases the ratings will need to be computed. In other
* cases, a rating cannot be determined.
*
* @param etratingId A unique identifier for a golf course eighteen/tee
* combination (gender) rating.
* @return A rating for the course; `null` if one cannot be determined.
*/
R computeEighteenTeeRatingIndex(long etratingId);
/**
* This method computes a golf course nine/tee combination's difficulty rating
* as of today, inclusive.
*
* In some cases, there is no computation, but a simple fetch from an external
* resource. In other cases the ratings will need to be computed. In other
* cases, a rating cannot be determined.
*
* @param ntratingId A unique identifier for a golf course nine/tee combination
* (gender) rating.
* @return A rating for the course; `null` if one cannot be determined.
*/
R computeNineTeeRatingIndex(long ntratingId);
}

View File

@@ -0,0 +1,37 @@
package com.poststats.golf.service;
import java.math.BigInteger;
public interface HandicapScoreService<S> {
/**
* This method computes a non-event round's score.
*
* The score depends on the handicap system. For instance, the simple
* stroke (non-handicap) system, it will be strokes-minus-par. For the
* world handicap system (WHS), it will be your adjusted strokes-to-par,
* applying the course rating, your handicap, hole handicaps, and course
* condition adjustment. For point handicap systems, it will be your
* points, including the course adjustment.
*
* @param roundId A unique identifier for the non-event round.
* @return A score for the round.
*/
S computeRoundScore(BigInteger roundId);
/**
* This method computes a person's event round score.
*
* The score depends on the handicap system. For instance, the simple
* stroke (non-handicap) system, it will be strokes-minus-par. For the
* world handicap system (WHS), it will be your adjusted strokes-to-par,
* applying the course rating, your handicap, hole handicaps, and course
* condition adjustment. For point handicap systems, it will be your
* points, including the course adjustment.
*
* @param proundId A unique identifier for the event/person round.
* @return A score for the round.
*/
S computeEventRoundScore(BigInteger proundId);
}

View File

@@ -1,5 +1,6 @@
package com.poststats.golf.service;
import java.math.BigInteger;
import java.time.LocalDate;
import java.util.List;
@@ -11,6 +12,48 @@ public interface PersonRoundService {
public enum Filter { AttestedOnly, CourseRatedOnly }
/**
* This method retrieves meta-data about the specified non-event round.
*
* @param roundId A unique identifier for the non-event round.
* @param selection Include `ScoreToPar` or `StrokeHandicapIndex` values in the
* results.
* @param filter An array of filters.
* @return A non-event round and its meta-data.
*/
FlexMap fetchNonEvent(BigInteger roundId, Selection selection, Filter... filters);
/**
* This method retrieves meta-data about the specified golfer's event round.
*
* @param proundId A unique identifier for a golfer's event round.
* @param selection Include `ScoreToPar` or `StrokeHandicapIndex` values in the
* results.
* @param filter An array of filters.
* @return A golfer's event round and its meta-data.
*/
FlexMap fetchEvent(BigInteger proundId, Selection selection, Filter... filters);
/**
* This method retrieves scores for all holes played in the specified non-event round.
*
* @param roundId A unique identifier for the non-event round.
* @param selection Include `ScoreToPar` or `StrokeHandicapIndex` values in the
* results.
* @return A list of holes and associated scores.
*/
List<? extends FlexMap> fetchNonEventHoles(BigInteger roundId, Selection selection);
/**
* This method retrieves scores for all holes played in the specified golfer's event round.
*
* @param proundId A unique identifier for the golfer's event round.
* @param selection Include `ScoreToPar` or `StrokeHandicapIndex` values in the
* results.
* @return A list of holes and associated scores.
*/
List<? extends FlexMap> fetchEventHoles(BigInteger proundId, Selection selection);
/**
* This method retrieves recent round meta-data about the specified golfer.
*

View File

@@ -4,17 +4,19 @@ import java.time.LocalDate;
import java.util.List;
import com.brianlong.util.FlexMap;
import com.poststats.golf.service.CourseRatingService;
import com.poststats.golf.service.HandicapIndexService;
import com.poststats.golf.service.HandicapScoreService;
import com.poststats.golf.service.PersonRoundService;
import com.poststats.golf.service.PersonRoundService.Filter;
import com.poststats.golf.service.PersonRoundService.Selection;
import jakarta.inject.Inject;
public abstract class AbstractHandicapIndexService<I, R> implements HandicapIndexService<I, R> {
public abstract class AbstractHandicappingService<I, R, S> implements HandicapIndexService<I>, CourseRatingService<R>, HandicapScoreService<S> {
@Inject
private PersonRoundService personRoundService;
protected PersonRoundService personRoundService;
protected short getMinimumRounds() {
return 1;

View File

@@ -1,5 +1,6 @@
package com.poststats.golf.service.compute;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -16,7 +17,7 @@ import com.brianlong.util.MapUtil;
import com.poststats.golf.service.PersonRoundService.Selection;
import com.poststats.golf.service.model.PointHandicapIndex;
public abstract class AbstractPointHandicapIndexService extends AbstractHandicapIndexService<PointHandicapIndex, Byte> {
public abstract class AbstractPointHandicappingService extends AbstractHandicappingService<PointHandicapIndex, Byte, Short> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -128,6 +129,22 @@ public abstract class AbstractPointHandicapIndexService extends AbstractHandicap
// closest
}
}
@Override
public Short computeRoundScore(BigInteger roundId) {
// TODO Auto-generated method stub
return null;
}
@Override
public Short computeEventRoundScore(BigInteger proundId) {
// TODO Auto-generated method stub
return null;
}
private PointHandicapIndex generateIndexBy2MostCommon(byte mostCommonScoreToParIndex,
short mostCommonScoreToParCount, byte nextMostCommonScoreToParIndex, short nextMostCommonScoreToParCount,

View File

@@ -1,117 +0,0 @@
package com.poststats.golf.service.compute;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.brianlong.util.FlexMap;
import com.poststats.golf.service.PersonRoundService.Selection;
import com.poststats.golf.service.model.StrokeCourseRating;
public abstract class AbstractStrokeHandicapIndexService
extends AbstractHandicapIndexService<Float, StrokeCourseRating> {
private final Comparator<FlexMap> roundComparator;
public AbstractStrokeHandicapIndexService() {
this.roundComparator = new Comparator<FlexMap>() {
@Override
public int compare(FlexMap round1, FlexMap round2) {
Float sh1 = round1.getFloat(getStrokeHandicapColumn());
Float sh2 = round2.getFloat(getStrokeHandicapColumn());
return sh1.compareTo(sh2);
}
};
}
protected abstract String getStrokeHandicapColumn();
@Override
protected Selection getRoundSelection() {
return Selection.StrokeHandicapIndex;
}
protected short getRoundsToCount(short rounds) {
switch (rounds) {
case 0:
throw new IllegalArgumentException();
case 1:
case 2:
case 3:
case 4:
case 5:
return 1;
case 6:
case 7:
case 8:
return 2;
case 9:
case 10:
case 11:
return 3;
case 12:
case 13:
case 14:
return 4;
case 15:
case 16:
return 5;
case 17:
case 18:
return 6;
case 19:
return 7;
case 20:
return 8;
default:
throw new IllegalArgumentException();
}
}
@Override
public Float compute(List<? extends FlexMap> rounds) {
Collections.sort(rounds, this.roundComparator);
short roundsToCount = this.getRoundsToCount((short) rounds.size());
return this.compute(rounds.subList(0, roundsToCount), (short) rounds.size());
}
public Float compute(List<? extends FlexMap> rounds, short roundsConsidered) {
float sh = 0f;
for (FlexMap round : rounds)
sh += round.getFloat(this.getStrokeHandicapColumn());
sh /= rounds.size();
float adjustment = this.getHandicapAdjustment(roundsConsidered);
return sh + adjustment;
}
@Override
public StrokeCourseRating computeEighteenTeeRatingIndex(long etratingId) {
// TODO call WHS service for the information
return null;
}
@Override
public StrokeCourseRating computeNineTeeRatingIndex(long ntratingId) {
// TODO call WHS service for the information
return null;
}
protected float getHandicapAdjustment(short rounds) {
switch (rounds) {
case 0:
throw new IllegalArgumentException();
case 1:
return -3f;
case 2:
case 3:
return -2f;
case 4:
case 6:
return -1f;
default:
return 0f;
}
}
}

View File

@@ -0,0 +1,415 @@
package com.poststats.golf.service.compute;
import java.math.BigInteger;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import com.brianlong.sql.FlexPreparedStatement;
import com.brianlong.util.FlexMap;
import com.poststats.golf.provider.GolfProvider;
import com.poststats.golf.service.PersonRoundService.Selection;
import com.poststats.golf.service.PersonService;
import com.poststats.golf.service.model.StrokeCourseRating;
import com.poststats.provider.NonTransactionalProvider;
import com.poststats.provider.Statement;
import com.poststats.provider.StatementProvider;
import com.poststats.provider.TransactionalProvider;
import com.poststats.service.ServiceException;
import jakarta.inject.Inject;
public abstract class AbstractStrokeHandicappingService
extends AbstractHandicappingService<Float, StrokeCourseRating, Float> {
@Inject
private Logger logger;
@Inject
private PersonService personService;
private final Comparator<FlexMap> roundComparator;
public AbstractStrokeHandicappingService() {
this.roundComparator = new Comparator<FlexMap>() {
@Override
public int compare(FlexMap round1, FlexMap round2) {
Float sh1 = round1.getFloat(getStrokeHandicapColumn());
Float sh2 = round2.getFloat(getStrokeHandicapColumn());
return sh1.compareTo(sh2);
}
};
}
protected abstract String getStrokeHandicapColumn();
protected abstract String getHoleHandicapColumn();
@Override
protected Selection getRoundSelection() {
return Selection.StrokeHandicapIndex;
}
protected short getRoundsToCount(short rounds) {
switch (rounds) {
case 0:
throw new IllegalArgumentException();
case 1:
case 2:
case 3:
case 4:
case 5:
return 1;
case 6:
case 7:
case 8:
return 2;
case 9:
case 10:
case 11:
return 3;
case 12:
case 13:
case 14:
return 4;
case 15:
case 16:
return 5;
case 17:
case 18:
return 6;
case 19:
return 7;
case 20:
return 8;
default:
throw new IllegalArgumentException();
}
}
@Override
public Float compute(List<? extends FlexMap> rounds) {
Collections.sort(rounds, this.roundComparator);
short roundsToCount = this.getRoundsToCount((short) rounds.size());
return this.compute(rounds.subList(0, roundsToCount), (short) rounds.size());
}
public Float compute(List<? extends FlexMap> rounds, short roundsConsidered) {
float sh = 0f;
for (FlexMap round : rounds)
sh += round.getFloat(this.getStrokeHandicapColumn());
sh /= rounds.size();
float adjustment = this.getHandicapAdjustment(roundsConsidered);
return sh + adjustment;
}
protected float getHandicapAdjustment(short rounds) {
switch (rounds) {
case 0:
throw new IllegalArgumentException();
case 1:
return -3f;
case 2:
case 3:
return -2f;
case 4:
case 6:
return -1f;
default:
return 0f;
}
}
@Override
public StrokeCourseRating computeNineTeeRatingIndex(long ntratingId) {
FlexMap ntrating = this.getNineTeeRating(ntratingId);
if (ntrating == null)
return null;
LocalDateTime syncd = ntrating.getDateTime("syncd");
if (LocalDateTime.now().getYear() == syncd.getYear() && LocalDateTime.now().minusMonths(3).isBefore(syncd))
// assume it hasn't changed if sync'd within the last 3 months and still the same calendar year
return new StrokeCourseRating(ntrating.getShort("slopeRating"), ntrating.getFloat("courseRating"));
CourseMetadata courseMeta = this.fetchNineTeeRating(ntratingId);
if (courseMeta == null)
return null;
this.updateNineTeeRating(ntratingId, courseMeta);
throw new UnsupportedOperationException();
// FIXME return new StrokeCourseRating(courseMeta.getSlopeRating(), courseMeta.getCourseRating());
}
@Override
public StrokeCourseRating computeEighteenTeeRatingIndex(long etratingId) {
FlexMap etrating = this.getNineTeeRating(etratingId);
if (etrating == null)
return null;
LocalDateTime syncd = etrating.getDateTime("syncd");
if (LocalDateTime.now().getYear() == syncd.getYear() && LocalDateTime.now().minusMonths(3).isBefore(syncd))
// assume it hasn't changed if sync'd within the last 3 months and still the same calendar year
return new StrokeCourseRating(etrating.getShort("slopeRating"), etrating.getFloat("courseRating"));
CourseMetadata courseMeta = this.fetchEighteenTeeRating(etratingId);
if (courseMeta == null)
return null;
this.updateEighteenTeeRating(etratingId, courseMeta);
throw new UnsupportedOperationException();
// FIXME return new StrokeCourseRating(courseMeta.getSlopeRating(), courseMeta.getCourseRating());
}
public Float computeEighteenTeeRatingHandicap(long etratingId, long personId) {
FlexMap person = this.personService.get(personId);
Float strokeHandicap = person.getFloat(this.getStrokeHandicapColumn());
if (strokeHandicap == null)
return null;
CourseMetadata courseMeta = this.fetchEighteenTeeRating(etratingId);
float handicap = strokeHandicap.floatValue();
if (courseMeta.getSlopeRating() != null)
handicap = handicap * courseMeta.getSlopeRating() / 113f;
if (courseMeta.getCourseRating() != null)
handicap += courseMeta.getCourseRating() - courseMeta.getPar();
return handicap;
}
public Float computeNineTeeRatingHandicap(long ntratingId, long personId) {
FlexMap person = this.personService.get(personId);
Float strokeHandicap = person.getFloat(this.getStrokeHandicapColumn());
if (strokeHandicap == null)
return null;
CourseMetadata courseMeta = this.fetchNineTeeRating(ntratingId);
float handicap = strokeHandicap.floatValue() / 2f;
if (courseMeta.getSlopeRating() != null)
handicap = handicap * courseMeta.getSlopeRating() / 113f;
if (courseMeta.getCourseRating() != null)
handicap += courseMeta.getCourseRating() - courseMeta.getPar();
return handicap;
}
@Override
public Float computeRoundScore(BigInteger roundId) {
FlexMap round = this.personRoundService.fetchNonEvent(roundId, this.getRoundSelection(), this.getRoundFilter());
if (round == null) {
this.logger.debug("The round does not exist or does not meeting the requirements to be handicap scored: {}", roundId);
return null;
}
List<? extends FlexMap> holes = this.personRoundService.fetchNonEventHoles(roundId, this.getRoundSelection());
if (holes.size() != 18) {
this.logger.debug("The round does not have 18 scored holes; cannot compute handicap score: {}", roundId);
return null;
}
return this.computeRoundScore(round, holes, roundId, "round");
}
@Override
public Float computeEventRoundScore(BigInteger proundId) {
FlexMap pround = this.personRoundService.fetchEvent(proundId, this.getRoundSelection(), this.getRoundFilter());
if (pround == null) {
// the round either doesn't exist or it is not eligible for handicap computation
return null;
}
int totalHolesNeeded = pround.isNotEmpty("ntratingID") ? 9 : 18;
List<? extends FlexMap> holes = this.personRoundService.fetchEventHoles(proundId, this.getRoundSelection());
if (holes.size() != totalHolesNeeded) {
this.logger.debug("The pround does not have {} scored holes; cannot compute handicap score: {}", totalHolesNeeded, proundId);
return null;
}
return this.computeRoundScore(pround, holes, proundId, "pround");
}
private Float computeRoundScore(FlexMap round, List<? extends FlexMap> holes, Object roundId, String msgName) {
// prepare for equitable stroke control
Pair<Byte, Byte> esc = this.computeEquitableStrokeControl(round.getLong("personID"));
int escStrokes = 0;
for (FlexMap hole : holes) {
Byte strokeIndex = hole.getByte(this.getHoleHandicapColumn());
if (strokeIndex == null) {
this.logger.debug("The course for the {} does not have the appropriate hole handicaps to compute the handicap with equitable stroke control: {}", msgName, roundId);
return null;
}
int scoreToPar = hole.getByte("strokes") - hole.getByte("par");
if (strokeIndex.byteValue() <= esc.getRight().byteValue()) {
scoreToPar = Math.min(scoreToPar, esc.getLeft() + 1);
} else {
scoreToPar = Math.min(scoreToPar, esc.getLeft());
}
escStrokes += scoreToPar + hole.getByte("par");
}
float adjStrokes = (float) escStrokes;
if (round.getFloat("courseRating") != null) {
adjStrokes -= round.getFloat("courseRating").floatValue();
} else {
adjStrokes -= round.getByte("par").floatValue();
}
if (round.getShort("slopeRating") != null)
adjStrokes = adjStrokes * 113 / round.getShort("slopeRating").floatValue();
return adjStrokes;
}
private Pair<Byte, Byte> computeEquitableStrokeControl(long personId) {
byte netDoubleBogey = 5;
byte netDoubleBogeyRemainder = 0;
FlexMap person = this.personService.get(personId);
Float strokeHandicap = person.getFloat(this.getStrokeHandicapColumn());
if (strokeHandicap != null) {
byte baseHandicap = (byte) Math.round(strokeHandicap.floatValue());
netDoubleBogey = (byte) (baseHandicap / 18 + 2);
netDoubleBogeyRemainder = (byte) (baseHandicap % 18);
}
return Pair.of(netDoubleBogey, netDoubleBogeyRemainder);
}
private CourseMetadata fetchNineTeeRating(long ntratingId) {
// TODO call WHS service for the information
return null;
}
private CourseMetadata fetchEighteenTeeRating(long etratingId) {
// TODO call WHS service for the information
return null;
}
private FlexMap getNineTeeRating(long ntratingId) {
try {
FlexPreparedStatement fps = this.sqlSelectCourseNineTeeRating.buildPreparedStatement();
try {
fps.setIntegerU(1, ntratingId);
return fps.executeQuery().getNextRow();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = "SELECT CNTR.*, CNT.par, CNT.yards "
+ "FROM ~g~.CourseNineTeeRating CNTR "
+ " INNER JOIN ~g~.CourseNineTee CNT ON (CNTR.nineteeID=CNT.nineteeID) "
+ "WHERE CNTR.ntratingID=? "
)
private StatementProvider sqlSelectCourseNineTeeRating;
private FlexMap getEighteenTeeRating(long etratingId) {
try {
FlexPreparedStatement fps = this.sqlSelectCourseEighteenTeeRating.buildPreparedStatement();
try {
fps.setIntegerU(1, etratingId);
return fps.executeQuery().getNextRow();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = "SELECT CETR.*, CET.par, CET.yards "
+ "FROM ~g~.CourseEighteenTeeRating CETR "
+ " INNER JOIN ~g~.CourseEighteenTee CET ON (CETR.eighteenteeID=CET.eighteenteeID) "
+ "WHERE CETR.etratingID=? "
)
private StatementProvider sqlSelectCourseEighteenTeeRating;
private void updateNineTeeRating(long ntratingId, CourseMetadata courseMeta) {
try {
FlexPreparedStatement fps = this.sqlUpdateCourseNineTeeRating.buildPreparedStatement();
try {
//fps.setTinyintU(1, courseMeta.getSlopeRating());
//fps.setTinyintU(2, courseMeta.getCourseRating());
fps.setIntegerU(3, ntratingId);
fps.executeUpdate();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Inject
@TransactionalProvider
@GolfProvider
@Statement(
sql = "UPDATE ~g~.CourseNineTeeRating "
+ "SET slopeRating=?, courseRating=? "
+ "WHERE ntratingID=? "
)
private StatementProvider sqlUpdateCourseNineTeeRating;
private void updateEighteenTeeRating(long etratingId, CourseMetadata courseMeta) {
try {
FlexPreparedStatement fps = this.sqlUpdateCourseEighteenTeeRating.buildPreparedStatement();
try {
//fps.setTinyintU(1, courseMeta.getSlopeRating());
//fps.setTinyintU(2, courseMeta.getCourseRating());
fps.setIntegerU(3, etratingId);
fps.executeUpdate();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Inject
@TransactionalProvider
@GolfProvider
@Statement(
sql = "UPDATE ~g~.CourseEighteenTeeRating "
+ "SET slopeRating=?, courseRating=? "
+ "WHERE etratingID=? "
)
private StatementProvider sqlUpdateCourseEighteenTeeRating;
private interface CourseMetadata {
// TODO replace with WHS model
Short getSlopeRating();
Float getCourseRating();
byte getPar();
}
}

View File

@@ -1,16 +1,11 @@
package com.poststats.golf.service.compute;
import com.brianlong.util.FlexMap;
import com.poststats.golf.service.CourseRatingService;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
public class LegacyPostStatsPointHandicapIndexService extends AbstractPointHandicapIndexService {
@Inject
private CourseRatingService courseRatingService;
public class LegacyPostStatsPointHandicapIndexService extends AbstractPointHandicappingService {
@Override
protected float getAccelerant() {

View File

@@ -13,7 +13,7 @@ import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
public class PostStatsPointHandicapIndexService extends AbstractPointHandicapIndexService {
public class PostStatsPointHandicapIndexService extends AbstractPointHandicappingService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

View File

@@ -3,7 +3,7 @@ package com.poststats.golf.service.compute;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class PostStatsStrokeHandicapIndexService extends AbstractStrokeHandicapIndexService {
public class PostStatsStrokeHandicappingService extends AbstractStrokeHandicappingService {
@Override
protected short getMaximumRounds() {
@@ -15,4 +15,9 @@ public class PostStatsStrokeHandicapIndexService extends AbstractStrokeHandicapI
return "strokeHandicapIndex";
}
@Override
protected String getHoleHandicapColumn() {
return "handicap";
}
}

View File

@@ -5,7 +5,7 @@ import com.poststats.golf.service.PersonRoundService.Filter;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class WhsStrokeHandicapIndexService extends AbstractStrokeHandicapIndexService {
public class WhsStrokeHandicapIndexService extends AbstractStrokeHandicappingService {
@Override
protected short getMinimumRounds() {
@@ -22,6 +22,11 @@ public class WhsStrokeHandicapIndexService extends AbstractStrokeHandicapIndexSe
return "whsStrokeHandicapIndex";
}
@Override
protected String getHoleHandicapColumn() {
return "whsHandicap";
}
@Override
protected Filter[] getRoundFilter() {
return new Filter[] {

View File

@@ -14,7 +14,6 @@ import com.brianlong.util.SubList;
import com.poststats.golf.provider.GolfProvider;
import com.poststats.golf.service.CourseHoleService;
import com.poststats.golf.service.CourseNineService;
import com.poststats.golf.service.CourseRatingService;
import com.poststats.golf.service.CourseService;
import com.poststats.provider.NonTransactionalProvider;
import com.poststats.provider.Statement;
@@ -29,7 +28,7 @@ import jakarta.inject.Inject;
@ApplicationScoped
public class CourseServiceDAO extends CacheableServiceDAO<Integer>
implements CourseService, CourseNineService, CourseRatingService, CourseHoleService {
implements CourseService, CourseNineService, CourseHoleService {
private final int defaultCacheExpirationInSeconds = 600;
private final FlexManyToOneDef facilityManyToOneDef = new FlexManyToOneDef("facilityID", "facility");
@@ -263,58 +262,6 @@ public class CourseServiceDAO extends CacheableServiceDAO<Integer>
@Override
public FlexMap getNineTeeRating(long ntratingId) {
try {
FlexPreparedStatement fps = this.sqlSelectCourseNineTeeRating.buildPreparedStatement();
try {
fps.setIntegerU(1, ntratingId);
return fps.executeQuery().getNextRow();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = "SELECT CNTR.*, CNT.par, CNT.yards "
+ "FROM ~g~.CourseNineTeeRating CNTR "
+ " INNER JOIN ~g~.CourseNineTee CNT ON (CNTR.nineteeID=CNT.nineteeID) "
+ "WHERE CNTR.ntratingID=? "
)
private StatementProvider sqlSelectCourseNineTeeRating;
@Override
public FlexMap getEighteenTeeRating(long etratingId) {
try {
FlexPreparedStatement fps = this.sqlSelectCourseEighteenTeeRating.buildPreparedStatement();
try {
fps.setIntegerU(1, etratingId);
return fps.executeQuery().getNextRow();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = "SELECT CETR.*, CET.par, CET.yards "
+ "FROM ~g~.CourseEighteenTeeRating CETR "
+ " INNER JOIN ~g~.CourseEighteenTee CET ON (CETR.eighteenteeID=CET.eighteenteeID) "
+ "WHERE CETR.etratingID=? "
)
private StatementProvider sqlSelectCourseEighteenTeeRating;
@Override
public List<? extends FlexMap> getHolesByEighteenTee(long eighteenteeId) {
// TODO Auto-generated method stub

View File

@@ -1,5 +1,6 @@
package com.poststats.golf.service.db;
import java.math.BigInteger;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.HashSet;
@@ -21,10 +22,82 @@ import jakarta.inject.Inject;
@ApplicationScoped
public class PersonRoundServiceDAO implements PersonRoundService {
@Override
public FlexMap fetchNonEvent(BigInteger roundId, Selection selection, Filter... filters) {
StatementProvider stmt = this.getNonEventRoundStatementProvider(selection, filters);
try {
FlexPreparedStatement fps = stmt.buildPreparedStatement();
try {
for (int c = 1; c <= fps.getPreparedStatement().getParameterMetaData().getParameterCount(); c++)
fps.setBigintU(c, roundId);
return fps.executeQuery().getNextRow();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Override
public FlexMap fetchEvent(BigInteger proundId, Selection selection, Filter... filters) {
StatementProvider stmt = this.getEventRoundStatementProvider(selection, filters);
try {
FlexPreparedStatement fps = stmt.buildPreparedStatement();
try {
for (int c = 1; c <= fps.getPreparedStatement().getParameterMetaData().getParameterCount(); c++)
fps.setBigintU(c, proundId);
return fps.executeQuery().getNextRow();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Override
public List<? extends FlexMap> fetchNonEventHoles(BigInteger roundId, Selection selection) {
StatementProvider stmt = this.getNonEventRoundHolesStatementProvider(selection);
try {
FlexPreparedStatement fps = stmt.buildPreparedStatement();
try {
for (int c = 1; c <= fps.getPreparedStatement().getParameterMetaData().getParameterCount(); c++)
fps.setBigintU(c, roundId);
return fps.executeQuery().getAllRows();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Override
public List<? extends FlexMap> fetchEventHoles(BigInteger proundId, Selection selection) {
StatementProvider stmt = this.getEventRoundHolesStatementProvider(selection);
try {
FlexPreparedStatement fps = stmt.buildPreparedStatement();
try {
for (int c = 1; c <= fps.getPreparedStatement().getParameterMetaData().getParameterCount(); c++)
fps.setBigintU(c, proundId);
return fps.executeQuery().getAllRows();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Override
public List<? extends FlexMap> findBefore(long personId, LocalDate beforeDay, short roundCount, Selection selection,
Filter... filters) {
StatementProvider stmt = this.getRoundStatementProvider(selection, filters);
StatementProvider stmt = this.getRoundsStatementProvider(selection, filters);
try {
FlexPreparedStatement fps = stmt.buildPreparedStatement();
@@ -45,7 +118,107 @@ public class PersonRoundServiceDAO implements PersonRoundService {
}
}
private StatementProvider getRoundStatementProvider(Selection selection, Filter... filters) {
private StatementProvider getNonEventRoundStatementProvider(Selection selection, Filter... filters) {
Set<Filter> filterSet = new HashSet<>();
for (Filter filter : filters)
filterSet.add(filter);
switch (selection) {
case StrokeHandicapIndex:
if (filterSet.contains(Filter.AttestedOnly)) {
if (filterSet.contains(Filter.CourseRatedOnly)) {
return this.sqlSelectSignedRatedNonEventRoundWithStrokeHandicap;
} else {
return this.sqlSelectSignedNonEventRoundWithStrokeHandicap;
}
} else {
if (filterSet.contains(Filter.CourseRatedOnly)) {
return this.sqlSelectRatedNonEventRoundWithStrokeHandicap;
} else {
return this.sqlSelectNonEventRoundWithStrokeHandicap;
}
}
case ScoreToPar:
if (filterSet.contains(Filter.AttestedOnly)) {
if (filterSet.contains(Filter.CourseRatedOnly)) {
return this.sqlSelectSignedRatedNonEventRoundWithScoreToPar;
} else {
return this.sqlSelectSignedNonEventRoundWithScoreToPar;
}
} else {
if (filterSet.contains(Filter.CourseRatedOnly)) {
return this.sqlSelectRatedNonEventRoundWithScoreToPar;
} else {
return this.sqlSelectNonEventRoundWithScoreToPar;
}
}
default:
throw new IllegalArgumentException();
}
}
private StatementProvider getEventRoundStatementProvider(Selection selection, Filter... filters) {
Set<Filter> filterSet = new HashSet<>();
for (Filter filter : filters)
filterSet.add(filter);
switch (selection) {
case StrokeHandicapIndex:
if (filterSet.contains(Filter.AttestedOnly)) {
if (filterSet.contains(Filter.CourseRatedOnly)) {
return this.sqlSelectSignedRatedEventRoundWithStrokeHandicap;
} else {
return this.sqlSelectSignedEventRoundWithStrokeHandicap;
}
} else {
if (filterSet.contains(Filter.CourseRatedOnly)) {
return this.sqlSelectRatedEventRoundWithStrokeHandicap;
} else {
return this.sqlSelectEventRoundWithStrokeHandicap;
}
}
case ScoreToPar:
if (filterSet.contains(Filter.AttestedOnly)) {
if (filterSet.contains(Filter.CourseRatedOnly)) {
return this.sqlSelectSignedRatedEventRoundWithScoreToPar;
} else {
return this.sqlSelectSignedEventRoundWithScoreToPar;
}
} else {
if (filterSet.contains(Filter.CourseRatedOnly)) {
return this.sqlSelectRatedEventRoundWithScoreToPar;
} else {
return this.sqlSelectEventRoundWithScoreToPar;
}
}
default:
throw new IllegalArgumentException();
}
}
private StatementProvider getNonEventRoundHolesStatementProvider(Selection selection) {
switch (selection) {
case StrokeHandicapIndex:
return this.sqlSelectNonEventRoundHolesWithStrokeHandicap;
case ScoreToPar:
return this.sqlSelectNonEventRoundHolesWithScoreToPar;
default:
throw new IllegalArgumentException();
}
}
private StatementProvider getEventRoundHolesStatementProvider(Selection selection) {
switch (selection) {
case StrokeHandicapIndex:
return this.sqlSelectEventRoundHolesWithStrokeHandicap;
case ScoreToPar:
return this.sqlSelectEventRoundHolesWithScoreToPar;
default:
throw new IllegalArgumentException();
}
}
private StatementProvider getRoundsStatementProvider(Selection selection, Filter... filters) {
Set<Filter> filterSet = new HashSet<>();
for (Filter filter : filters)
filterSet.add(filter);
@@ -84,28 +257,27 @@ public class PersonRoundServiceDAO implements PersonRoundService {
}
}
private final static String nonEventRoundSqlSelectClause = "SELECT R.roundID, NULL proundID, NULL linkProundID, R.etratingID, R.courseID, R.teedate, R.teetime, R.strokes, ";
private final static String nonEventRoundSqlSelectClause = "SELECT R.roundID, NULL proundID, NULL linkProundID, R.personID, R.etratingID, R.courseID, R.teedate, R.teetime, R.strokes, ";
private final static String nonEventRoundSqlFromClause = "FROM ~g~.Round R "
+ " INNER JOIN ~p~.Person P ON (R.personID=P.personID) ";
private final static String nonEventRoundSqlWhereClause = "WHERE R.personID=? AND R.complete IS TRUE AND R.teedate<? "
private final static String nonEventRoundSqlWhereClause = "WHERE R.roundID=? ";
private final static String nonEventRoundsSqlWhereClause = "WHERE R.personID=? AND R.complete IS TRUE AND R.teedate<? "
+ " AND (P.healthSetback IS NULL OR R.teedate>P.healthSetback) ";
private final static String event18RoundSqlSelectClause = "SELECT NULL roundID, EPR.proundID, NULL linkProundID, EPR.etratingID, EPR.courseID, ER.date, ERP.teetime, EPR.strokes, ";
private final static String event18RoundSqlSelectClause = "SELECT NULL roundID, EPR.proundID, NULL linkProundID, EP.personID, EPR.etratingID, EPR.courseID, ER.date, ERP.teetime, EPR.strokes, ";
private final static String event18RoundSqlFromClause = "FROM ~g~.EventPersonRound EPR "
+ " INNER JOIN ~g~.EventRound ER ON (EPR.eroundID=ER.eroundID) "
+ " INNER JOIN ~g~.EventPerson EP ON (EPR.epersonID=EP.epersonID) "
+ " INNER JOIN ~p~.Person P ON (EP.personID=P.personID) "
+ " LEFT JOIN ~g~.EventRoundPairing ERP ON (EPR.pairingID=ERP.pairingID) ";
private final static String event18RoundSqlWhereClause = "WHERE EP.personID=? AND EPR.complete IS TRUE AND EPR.etratingID IS NOT NULL AND ER.date<? "
+ " AND (P.healthSetback IS NULL OR ER.date>P.healthSetback) ";
private final static String event18RoundSqlWhereClause = "WHERE EPR.proundID=? ";
private final static String event18RoundsSqlWhereClause = "WHERE EP.personID=? AND EPR.complete IS TRUE AND EPR.etratingID IS NOT NULL AND ER.date<? "
+ " AND (P.healthSetback IS NULL OR ER.date>P.healthSetback) ";
private final static String event9RoundSqlSelectClause = "SELECT NULL roundID, EPR.proundID, EPR.linkProundID, CETR.etratingID, EPR.courseID, ER.date, ERP.teetime, "
private final static String event9RoundSqlSelectClause = "SELECT NULL roundID, EPR.proundID, EPR.linkProundID, EP.personID, CETR.etratingID, EPR.courseID, ER.date, ERP.teetime, "
+ " (EPR.strokes+EPR2.strokes) strokes, ";
private final static String event9RoundSqlFromClause = "FROM ~g~.EventPersonRound EPR "
+ " INNER JOIN ~g~.EventPersonRound EPR2 ON (EPR.linkProundID=EPR2.proundID AND EPR.proundID>EPR2.proundID) " // don't
// include
// 9-hole
// twice
+ " INNER JOIN ~g~.EventPersonRound EPR2 ON (EPR.linkProundID=EPR2.proundID AND EPR.proundID>EPR2.proundID) "
+ " INNER JOIN ~g~.CourseNineTeeRating CNTR1 ON (EPR.ntratingID=CNTR1.ntratingID) "
+ " INNER JOIN ~g~.CourseNineTeeRating CNTR2 ON (EPR2.ntratingID=CNTR2.ntratingID) "
+ " INNER JOIN ~g~.CourseEighteenTee CET ON ((CNTR1.nineteeID=CET.nineteeID1 AND CNTR2.nineteeID=CET.nineteeID2) "
@@ -117,103 +289,208 @@ public class PersonRoundServiceDAO implements PersonRoundService {
+ " INNER JOIN ~g~.EventPerson EP ON (EPR.epersonID=EP.epersonID) "
+ " INNER JOIN ~p~.Person P ON (EP.personID=P.personID) "
+ " LEFT JOIN ~g~.EventRoundPairing ERP ON (EPR.pairingID=ERP.pairingID) ";
private final static String event9RoundSqlWhereClause = "WHERE EP.personID=? AND EPR.complete IS TRUE AND ER.date<? "
+ " AND (P.healthSetback IS NULL OR ER.date>P.healthSetback) ";
private final static String event9RoundSqlWhereClause = "WHERE EPR.proundID=? ";
private final static String event9RoundsSqlWhereClause = "WHERE EP.personID=? AND EPR.complete IS TRUE AND ER.date<? "
+ " AND (P.healthSetback IS NULL OR ER.date>P.healthSetback) ";
private final static String nonEventRoundSqlSelectStrokeHandicap = nonEventRoundSqlSelectClause
+ " R.strokeHandicapIndex, R.whsStrokeHandicapIndex "
+ nonEventRoundSqlFromClause
+ nonEventRoundSqlWhereClause;
private final static String nonEventRoundsSqlSelectStrokeHandicap = nonEventRoundSqlSelectClause
+ " R.strokeHandicapIndex, R.whsStrokeHandicapIndex "
+ nonEventRoundSqlFromClause
+ nonEventRoundsSqlWhereClause;
private final static String event18RoundSqlSelectStrokeHandicap = event18RoundSqlSelectClause
private final static String event18RoundSqlSelectStrokeHandicap = event18RoundSqlSelectClause
+ " EPR.strokeHandicapIndex, EPR.whsStrokeHandicapIndex "
+ event18RoundSqlFromClause
+ event18RoundSqlWhereClause;
private final static String event18RoundsSqlSelectStrokeHandicap = event18RoundSqlSelectClause
+ " EPR.strokeHandicapIndex, EPR.whsStrokeHandicapIndex "
+ event18RoundSqlFromClause
+ event18RoundSqlWhereClause;
+ event18RoundsSqlWhereClause;
private final static String event9RoundSqlSelectStrokeHandicap = event9RoundSqlSelectClause
private final static String event9RoundSqlSelectStrokeHandicap = event9RoundSqlSelectClause
+ " (EPR.strokeHandicapIndex+EPR2.strokeHandicapIndex) strokeHandicapIndex, "
+ " (EPR.whsStrokeHandicapIndex+EPR2.whsStrokeHandicapIndex) whsStrokeHandicapIndex "
+ event9RoundSqlFromClause
+ event9RoundSqlWhereClause;
private final static String event9RoundsSqlSelectStrokeHandicap = event9RoundSqlSelectClause
+ " (EPR.strokeHandicapIndex+EPR2.strokeHandicapIndex) strokeHandicapIndex, "
+ " (EPR.whsStrokeHandicapIndex+EPR2.whsStrokeHandicapIndex) whsStrokeHandicapIndex "
+ event9RoundSqlFromClause
+ event9RoundSqlWhereClause;
+ event9RoundsSqlWhereClause;
private final static String nonEventRoundSqlSelectScoreToPar = nonEventRoundSqlSelectClause
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 5 THEN 1 ELSE 0 END) bogey5, "
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 4 THEN 1 ELSE 0 END) bogey4, "
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 3 THEN 1 ELSE 0 END) bogey3, "
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 2 THEN 1 ELSE 0 END) bogey2, "
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 1 THEN 1 ELSE 0 END) bogey, "
+ " SUM(CASE WHEN RX.strokes = CNTH.par THEN 1 ELSE 0 END) par, "
+ " SUM(CASE WHEN (CNTH.par - RX.strokes) = 1 THEN 1 ELSE 0 END) birdie, "
+ " SUM(CASE WHEN (CNTH.par - RX.strokes) = 2 THEN 1 ELSE 0 END) eagle, "
+ " SUM(CASE WHEN (CNTH.par - RX.strokes) = 3 THEN 1 ELSE 0 END) alby, "
+ " CETR.pointAdj "
private final static String nonEventRoundSqlSelectPointsClause =
" SUM(CASE WHEN (RX.strokes - CNTH.par) = 5 THEN 1 ELSE 0 END) bogey5, "
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 4 THEN 1 ELSE 0 END) bogey4, "
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 3 THEN 1 ELSE 0 END) bogey3, "
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 2 THEN 1 ELSE 0 END) bogey2, "
+ " SUM(CASE WHEN (RX.strokes - CNTH.par) = 1 THEN 1 ELSE 0 END) bogey, "
+ " SUM(CASE WHEN RX.strokes = CNTH.par THEN 1 ELSE 0 END) par, "
+ " SUM(CASE WHEN (CNTH.par - RX.strokes) = 1 THEN 1 ELSE 0 END) birdie, "
+ " SUM(CASE WHEN (CNTH.par - RX.strokes) = 2 THEN 1 ELSE 0 END) eagle, "
+ " SUM(CASE WHEN (CNTH.par - RX.strokes) = 3 THEN 1 ELSE 0 END) alby, ";
private final static String nonEventRoundSqlFromPointsClause =
" INNER JOIN ~g~.RoundScore RX ON (R.roundID=RX.roundID) "
+ " INNER JOIN ~g~.CourseNineTeeHole CNTH ON (RX.holeID=CNTH.holeID) "
+ " INNER JOIN ~g~.CourseEighteenTeeRating CETR ON (R.etratingID=CETR.etratingID) ";
private final static String nonEventRoundSqlSelectScoreToPar = nonEventRoundSqlSelectClause
+ nonEventRoundSqlSelectPointsClause
+ " CETR.pointAdj "
+ nonEventRoundSqlFromClause
+ nonEventRoundSqlFromPointsClause
+ nonEventRoundSqlWhereClause
+ "GROUP BY R.roundID ";
private final static String nonEventRoundsSqlSelectScoreToPar = nonEventRoundSqlSelectClause
+ nonEventRoundSqlSelectPointsClause
+ " CETR.pointAdj "
+ nonEventRoundSqlFromClause
+ " INNER JOIN ~g~.RoundScore RX ON (R.roundID=RX.roundID) "
+ " INNER JOIN ~g~.CourseNineTeeHole CNTH ON (RX.holeID=CNTH.holeID) "
+ " INNER JOIN ~g~.CourseEighteenTeeRating CETR ON (R.etratingID=CETR.etratingID) "
+ nonEventRoundSqlWhereClause
+ nonEventRoundSqlFromPointsClause
+ nonEventRoundsSqlWhereClause
+ "GROUP BY R.roundID ";
private final static String event18RoundSqlSelectScoreToPar = event18RoundSqlSelectClause
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 5 THEN 1 ELSE 0 END) bogey5, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 4 THEN 1 ELSE 0 END) bogey4, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 3 THEN 1 ELSE 0 END) bogey3, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 2 THEN 1 ELSE 0 END) bogey2, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 1 THEN 1 ELSE 0 END) bogey, "
+ " SUM(CASE WHEN EPRS.strokes = CNTH.par THEN 1 ELSE 0 END) par, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 1 THEN 1 ELSE 0 END) birdie, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 2 THEN 1 ELSE 0 END) eagle, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 3 THEN 1 ELSE 0 END) alby,"
+ " CETR.pointAdj "
private final static String eventRoundSqlSelectPointsClause =
"SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 5 THEN 1 ELSE 0 END) bogey5, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 4 THEN 1 ELSE 0 END) bogey4, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 3 THEN 1 ELSE 0 END) bogey3, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 2 THEN 1 ELSE 0 END) bogey2, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 1 THEN 1 ELSE 0 END) bogey, "
+ " SUM(CASE WHEN EPRS.strokes = CNTH.par THEN 1 ELSE 0 END) par, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 1 THEN 1 ELSE 0 END) birdie, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 2 THEN 1 ELSE 0 END) eagle, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 3 THEN 1 ELSE 0 END) alby, ";
private final static String event18RoundSqlFromPointsClause =
" INNER JOIN ~g~.EventPersonRoundScore EPRS ON (EPR.proundID=EPRS.proundID) "
+ " INNER JOIN ~g~.CourseNineTeeHole CNTH ON (EPRS.holeID=CNTH.holeID) "
+ " INNER JOIN ~g~.CourseEighteenTeeRating CETR ON (EPR.etratingID=CETR.etratingID) ";
private final static String event9RoundSqlFromPointsClause =
" INNER JOIN ~g~.EventPersonRoundScore EPRS ON (EPR.proundID=EPRS.proundID OR EPR.linkProundID=EPRS.proundID) "
+ " INNER JOIN ~g~.CourseNineTeeHole CNTH ON (EPRS.holeID=CNTH.holeID) "
+ " INNER JOIN ~g~.CourseNineTeeRating CNTR ON (EPR.ntratingID=CNTR.ntratingID) ";
private final static String event18RoundSqlSelectScoreToPar = event18RoundSqlSelectClause
+ eventRoundSqlSelectPointsClause
+ " CETR.pointAdj "
+ event18RoundSqlFromClause
+ event18RoundSqlFromPointsClause
+ event18RoundSqlWhereClause
+ "GROUP BY EPR.proundID ";
private final static String event18RoundsSqlSelectScoreToPar = event18RoundSqlSelectClause
+ eventRoundSqlSelectPointsClause
+ " CETR.pointAdj "
+ event18RoundSqlFromClause
+ " INNER JOIN ~g~.EventPersonRoundScore EPRS ON (EPR.proundID=EPRS.proundID) "
+ " INNER JOIN ~g~.CourseNineTeeHole CNTH ON (EPRS.holeID=CNTH.holeID) "
+ " INNER JOIN ~g~.CourseEighteenTeeRating CETR ON (EPR.etratingID=CETR.etratingID) "
+ event18RoundSqlWhereClause
+ event18RoundSqlFromPointsClause
+ event18RoundsSqlWhereClause
+ "GROUP BY EPR.proundID ";
private final static String event9RoundSqlSelectScoreToPar = event9RoundSqlSelectClause
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 5 THEN 1 ELSE 0 END) bogey5, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 4 THEN 1 ELSE 0 END) bogey4, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 3 THEN 1 ELSE 0 END) bogey3, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 2 THEN 1 ELSE 0 END) bogey2, "
+ " SUM(CASE WHEN (EPRS.strokes - CNTH.par) = 1 THEN 1 ELSE 0 END) bogey, "
+ " SUM(CASE WHEN EPRS.strokes = CNTH.par THEN 1 ELSE 0 END) par, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 1 THEN 1 ELSE 0 END) birdie, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 2 THEN 1 ELSE 0 END) eagle, "
+ " SUM(CASE WHEN (CNTH.par - EPRS.strokes) = 3 THEN 1 ELSE 0 END) alby,"
+ " CETR.pointAdj "
+ eventRoundSqlSelectPointsClause
+ " CNTR.pointAdj "
+ event9RoundSqlFromClause
+ " INNER JOIN ~g~.EventPersonRoundScore EPRS ON (EPR.proundID=EPRS.proundID OR EPR.linkProundID=EPRS.proundID) "
+ " INNER JOIN ~g~.CourseNineTeeHole CNTH ON (EPRS.holeID=CNTH.holeID) "
+ event9RoundSqlFromPointsClause
+ event9RoundSqlWhereClause
+ "GROUP BY EPR.proundID ";
private final static String event9RoundsSqlSelectScoreToPar = event9RoundSqlSelectClause
+ eventRoundSqlSelectPointsClause
+ " CNTR.pointAdj "
+ event9RoundSqlFromClause
+ event9RoundSqlFromPointsClause
+ event9RoundsSqlWhereClause
+ "GROUP BY EPR.proundID ";
private final static String nonEventRoundHoleSqlSelectClause = "SELECT RX.holeID, RX.strokes, CNTH.par, ";
private final static String nonEventRoundHoleSqlFromClause =
"FROM ~g~.RoundScore RX "
+ " INNER JOIN ~g~.CourseNineTeeHole CNTH ON (RX.holeID=CNTH.holeID) ";
private final static String nonEventRoundHolesSqlSelectStrokeHandicap =
nonEventRoundHoleSqlSelectClause
+ " CNTH.handicap, CNTH.whsHandicap "
+ nonEventRoundHoleSqlFromClause
+ "WHERE RX.roundID=? ";
private final static String nonEventRoundHolesSqlSelectScoreToPar =
nonEventRoundHoleSqlSelectClause
+ nonEventRoundHoleSqlFromClause
+ "WHERE RX.roundID=? ";
private final static String eventRoundHoleSqlSelectClause = "SELECT EPRS.holeID, EPRS.strokes, CNTH.par, ";
private final static String eventRoundHoleSqlFromClause =
"FROM ~g~.EventPersonRoundScore EPRS "
+ " INNER JOIN ~g~.CourseNineTeeHole CNTH ON (EPRS.holeID=CNTH.holeID) "
+ " INNER JOIN ~g~.EventPersonRound EPR ON (EPRS.proundID=EPR.proundID) ";
private final static String eventRoundHolesSqlSelectStrokeHandicap =
eventRoundHoleSqlSelectClause
+ " CNTH.handicap, CNTH.whsHandicap "
+ eventRoundHoleSqlFromClause
+ "WHERE EPRS.proundID=? ";
private final static String eventRoundHolesSqlSelectScoreToPar =
eventRoundHoleSqlSelectClause
+ eventRoundHoleSqlFromClause
+ "WHERE EPRS.roundID=? ";
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(sql = nonEventRoundSqlSelectStrokeHandicap)
private StatementProvider sqlSelectNonEventRoundWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = event18RoundsSqlSelectStrokeHandicap
+ "UNION "
+ event9RoundsSqlSelectStrokeHandicap
)
private StatementProvider sqlSelectEventRoundWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectStrokeHandicap
sql = nonEventRoundsSqlSelectStrokeHandicap
+ "UNION "
+ event18RoundSqlSelectStrokeHandicap
+ event18RoundsSqlSelectStrokeHandicap
+ "UNION "
+ event9RoundSqlSelectStrokeHandicap
+ event9RoundsSqlSelectStrokeHandicap
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectRoundsWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundsSqlSelectStrokeHandicap
+ " AND R.whsStrokeHandicapIndex IS NOT NULL "
)
private StatementProvider sqlSelectRatedNonEventRoundWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = event18RoundsSqlSelectStrokeHandicap
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event9RoundsSqlSelectStrokeHandicap
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
)
private StatementProvider sqlSelectRatedEventRoundWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectStrokeHandicap
sql = nonEventRoundsSqlSelectStrokeHandicap
+ " AND R.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event18RoundSqlSelectStrokeHandicap
+ event18RoundsSqlSelectStrokeHandicap
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event9RoundSqlSelectStrokeHandicap
+ event9RoundsSqlSelectStrokeHandicap
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
@@ -226,95 +503,238 @@ public class PersonRoundServiceDAO implements PersonRoundService {
@Statement(
sql = nonEventRoundSqlSelectStrokeHandicap
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
+ "UNION "
+ event18RoundSqlSelectStrokeHandicap
+ "UNION "
+ event9RoundSqlSelectStrokeHandicap
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectSignedRoundsWithStrokeHandicap;
private StatementProvider sqlSelectSignedNonEventRoundWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = event18RoundSqlSelectStrokeHandicap
+ "UNION "
+ event9RoundSqlSelectStrokeHandicap
)
private StatementProvider sqlSelectSignedEventRoundWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundsSqlSelectStrokeHandicap
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
+ "UNION "
+ event18RoundsSqlSelectStrokeHandicap
+ "UNION "
+ event9RoundsSqlSelectStrokeHandicap
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectSignedRoundsWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectStrokeHandicap
+ " AND R.whsStrokeHandicapIndex IS NOT NULL "
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
)
private StatementProvider sqlSelectSignedRatedNonEventRoundWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = event18RoundSqlSelectStrokeHandicap
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event9RoundSqlSelectStrokeHandicap
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
)
private StatementProvider sqlSelectSignedRatedEventRoundWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectStrokeHandicap
sql = nonEventRoundsSqlSelectStrokeHandicap
+ " AND R.whsStrokeHandicapIndex IS NOT NULL "
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
+ "UNION "
+ event18RoundSqlSelectStrokeHandicap
+ event18RoundsSqlSelectStrokeHandicap
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event9RoundSqlSelectStrokeHandicap
+ event9RoundsSqlSelectStrokeHandicap
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectSignedRatedRoundsWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectScoreToPar
+ "UNION "
+ event18RoundSqlSelectScoreToPar
+ "UNION "
+ event9RoundSqlSelectScoreToPar
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectRoundsWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(sql = nonEventRoundSqlSelectScoreToPar)
private StatementProvider sqlSelectNonEventRoundWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = event18RoundSqlSelectScoreToPar
+ "UNION "
+ event9RoundSqlSelectScoreToPar
)
private StatementProvider sqlSelectEventRoundWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectScoreToPar
sql = nonEventRoundsSqlSelectScoreToPar
+ "UNION "
+ event18RoundsSqlSelectScoreToPar
+ "UNION "
+ event9RoundsSqlSelectScoreToPar
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectRoundsWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectScoreToPar
+ " AND R.whsStrokeHandicapIndex IS NOT NULL "
)
private StatementProvider sqlSelectRatedNonEventRoundWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = event18RoundSqlSelectScoreToPar
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event9RoundSqlSelectScoreToPar
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
)
private StatementProvider sqlSelectRatedEventRoundWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundsSqlSelectScoreToPar
+ " AND R.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event18RoundSqlSelectScoreToPar
+ event18RoundsSqlSelectScoreToPar
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event9RoundSqlSelectScoreToPar
+ event9RoundsSqlSelectScoreToPar
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectRatedRoundsWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectScoreToPar
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
+ "UNION "
+ event18RoundSqlSelectScoreToPar
+ "UNION "
+ event9RoundSqlSelectScoreToPar
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectSignedRoundsWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectScoreToPar
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
)
private StatementProvider sqlSelectSignedNonEventRoundWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = event18RoundSqlSelectScoreToPar
+ "UNION "
+ event9RoundSqlSelectScoreToPar
)
private StatementProvider sqlSelectSignedEventRoundWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectScoreToPar
sql = nonEventRoundsSqlSelectScoreToPar
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
+ "UNION "
+ event18RoundsSqlSelectScoreToPar
+ "UNION "
+ event9RoundsSqlSelectScoreToPar
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectSignedRoundsWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundSqlSelectScoreToPar
+ " AND R.whsStrokeHandicapIndex IS NOT NULL "
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
)
private StatementProvider sqlSelectSignedRatedNonEventRoundWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = event18RoundSqlSelectScoreToPar
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event9RoundSqlSelectScoreToPar
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
)
private StatementProvider sqlSelectSignedRatedEventRoundWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = nonEventRoundsSqlSelectScoreToPar
+ " AND R.whsStrokeHandicapIndex IS NOT NULL "
+ " AND EXISTS (SELECT RS.signerID FROM ~g~.RoundSigning RS WHERE RS.roundID=R.roundID) "
+ "UNION "
+ event18RoundSqlSelectScoreToPar
+ event18RoundsSqlSelectScoreToPar
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "UNION "
+ event9RoundSqlSelectScoreToPar
+ event9RoundsSqlSelectScoreToPar
+ " AND EPR.whsStrokeHandicapIndex IS NOT NULL "
+ "ORDER BY teedate DESC, teetime DESC "
+ "LIMIT ?"
)
private StatementProvider sqlSelectSignedRatedRoundsWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(sql = nonEventRoundHolesSqlSelectStrokeHandicap)
private StatementProvider sqlSelectNonEventRoundHolesWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(sql = eventRoundHolesSqlSelectStrokeHandicap)
private StatementProvider sqlSelectEventRoundHolesWithStrokeHandicap;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(sql = nonEventRoundHolesSqlSelectScoreToPar)
private StatementProvider sqlSelectNonEventRoundHolesWithScoreToPar;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(sql = eventRoundHolesSqlSelectScoreToPar)
private StatementProvider sqlSelectEventRoundHolesWithScoreToPar;
}