added docs and annotation validation; fixed pagination
This commit is contained in:
@@ -7,7 +7,6 @@ import com.poststats.transformer.impl.DaoConverter;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.enterprise.context.RequestScoped;
|
import jakarta.enterprise.context.RequestScoped;
|
||||||
@@ -17,9 +16,7 @@ import jakarta.ws.rs.Path;
|
|||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
import jakarta.ws.rs.Produces;
|
import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.WebApplicationException;
|
import jakarta.ws.rs.WebApplicationException;
|
||||||
import jakarta.ws.rs.core.Context;
|
|
||||||
import jakarta.ws.rs.core.Response.Status;
|
import jakarta.ws.rs.core.Response.Status;
|
||||||
import jakarta.ws.rs.core.SecurityContext;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,14 +25,11 @@ import org.slf4j.Logger;
|
|||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/golf/course/{courseId}")
|
@Path("/golf/course/{courseId}")
|
||||||
@Tag(name = "Course API")
|
@Tag(name = "Course API")
|
||||||
@ApiResponses({
|
@ApiResponse(responseCode = "200", description = "Success")
|
||||||
@ApiResponse(responseCode = "200", description = "Success"),
|
@ApiResponse(responseCode = "404", description = "A golf course with the specified ID could not be found")
|
||||||
@ApiResponse(responseCode = "401", description = "You are not authorized"),
|
|
||||||
@ApiResponse(responseCode = "403", description = "You are not identified or authenticated")
|
|
||||||
})
|
|
||||||
public class CourseApi {
|
public class CourseApi {
|
||||||
|
|
||||||
@Parameter(name = "courseId", description = "A unique identifier for a golf course")
|
@Parameter(description = "A unique identifier for a golf course")
|
||||||
@PathParam("courseId")
|
@PathParam("courseId")
|
||||||
private int courseId;
|
private int courseId;
|
||||||
|
|
||||||
@@ -59,10 +53,7 @@ public class CourseApi {
|
|||||||
summary = "Retrieves limited meta-data about a course.",
|
summary = "Retrieves limited meta-data about a course.",
|
||||||
description = "Retreives name, location, and other direct meta-data about the specified course."
|
description = "Retreives name, location, and other direct meta-data about the specified course."
|
||||||
)
|
)
|
||||||
@ApiResponses({
|
public Course get() {
|
||||||
@ApiResponse(responseCode = "404", description = "A golf course with the specified ID could not be found")
|
|
||||||
})
|
|
||||||
public Course get(@Context SecurityContext scontext) {
|
|
||||||
FlexMap row = this.courseService.get(this.courseId);
|
FlexMap row = this.courseService.get(this.courseId);
|
||||||
if (row == null)
|
if (row == null)
|
||||||
throw new WebApplicationException("Course not found", Status.NOT_FOUND);
|
throw new WebApplicationException("Course not found", Status.NOT_FOUND);
|
||||||
|
@@ -16,6 +16,11 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.enterprise.context.RequestScoped;
|
import jakarta.enterprise.context.RequestScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.DecimalMax;
|
||||||
|
import jakarta.validation.constraints.DecimalMin;
|
||||||
|
import jakarta.validation.constraints.Max;
|
||||||
|
import jakarta.validation.constraints.Positive;
|
||||||
import jakarta.ws.rs.BeanParam;
|
import jakarta.ws.rs.BeanParam;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
@@ -25,7 +30,6 @@ import jakarta.ws.rs.QueryParam;
|
|||||||
import jakarta.ws.rs.WebApplicationException;
|
import jakarta.ws.rs.WebApplicationException;
|
||||||
import jakarta.ws.rs.core.Response.Status;
|
import jakarta.ws.rs.core.Response.Status;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.http.HttpStatus;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,6 +38,11 @@ import org.slf4j.Logger;
|
|||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/golf/courses")
|
@Path("/golf/courses")
|
||||||
@Tag(name = "Course API")
|
@Tag(name = "Course API")
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "Success"),
|
||||||
|
@ApiResponse(responseCode = "400", description = "A query parameter is not valid"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "No matching golf courses were found")
|
||||||
|
})
|
||||||
public class CoursesApi {
|
public class CoursesApi {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -57,22 +66,16 @@ public class CoursesApi {
|
|||||||
summary = "Searches for golf courses by their name.",
|
summary = "Searches for golf courses by their name.",
|
||||||
description = "Searches for golf courses by their name, excluding prefix (e.g. The) and suffix (e.g. Golf Club), returning limited meta-data about each matched golf course."
|
description = "Searches for golf courses by their name, excluding prefix (e.g. The) and suffix (e.g. Golf Club), returning limited meta-data about each matched golf course."
|
||||||
)
|
)
|
||||||
@ApiResponses({
|
|
||||||
@ApiResponse(responseCode = "200", description = "Success"),
|
|
||||||
@ApiResponse(responseCode = "404", description = "No matching golf courses were found"),
|
|
||||||
@ApiResponse(responseCode = "411", description = "The page number must be at least 1"),
|
|
||||||
@ApiResponse(responseCode = "413", description = "The page size is too large")
|
|
||||||
})
|
|
||||||
@Parameters({
|
@Parameters({
|
||||||
@Parameter(
|
@Parameter(
|
||||||
name = "name",
|
name = "name",
|
||||||
required = true,
|
required = true,
|
||||||
description = "A fragment or whole golf course name; the prefix and suffix are not included"
|
description = "A fragment or whole golf course name; the prefix and suffix are not included"
|
||||||
), @Parameter(name = "page", description = "A page number, starting at 1", example = "1"),
|
)
|
||||||
@Parameter(name = "perPage", description = "A page size", example = "10")
|
|
||||||
})
|
})
|
||||||
@Tag(name = "Search API")
|
@Tag(name = "Search API")
|
||||||
public PagedCollection<List<Course>> searchByName(@QueryParam("name") String name, @BeanParam Pagination paging) {
|
public PagedCollection<List<Course>> searchByName(@QueryParam("name") String name,
|
||||||
|
@BeanParam @Valid Pagination paging) {
|
||||||
SubList<? extends FlexMap> rows = this.courseService.findByName(name, paging.getPage(), paging.getPerPage());
|
SubList<? extends FlexMap> rows = this.courseService.findByName(name, paging.getPage(), paging.getPerPage());
|
||||||
if (rows.isEmpty())
|
if (rows.isEmpty())
|
||||||
throw new WebApplicationException("No matching courses found", Status.NOT_FOUND);
|
throw new WebApplicationException("No matching courses found", Status.NOT_FOUND);
|
||||||
@@ -90,27 +93,19 @@ public class CoursesApi {
|
|||||||
summary = "Searches for golf courses by their location.",
|
summary = "Searches for golf courses by their location.",
|
||||||
description = "Searches for golf courses by their major jurisdiction (e.g. US States), returning limited meta-data about each matched golf course."
|
description = "Searches for golf courses by their major jurisdiction (e.g. US States), returning limited meta-data about each matched golf course."
|
||||||
)
|
)
|
||||||
@ApiResponses({
|
|
||||||
@ApiResponse(responseCode = "200", description = "Success"),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "404",
|
|
||||||
description = "The country, state, or matching golf courses were not found"
|
|
||||||
), @ApiResponse(responseCode = "411", description = "The page number must be at least 1"),
|
|
||||||
@ApiResponse(responseCode = "413", description = "The page size is too large")
|
|
||||||
})
|
|
||||||
@Parameters({
|
@Parameters({
|
||||||
@Parameter(name = "country", required = true, description = "A country code", example = "US"),
|
@Parameter(name = "country", required = true, description = "A country code", example = "US"),
|
||||||
@Parameter(name = "state", description = "A State or high-level jurisdiction", example = "FL"),
|
@Parameter(name = "state", description = "A State or high-level jurisdiction", example = "FL")
|
||||||
@Parameter(name = "page", description = "A page number, starting at 1", example = "1"),
|
|
||||||
@Parameter(name = "perPage", description = "A page size", example = "10")
|
|
||||||
})
|
})
|
||||||
@Tag(name = "Search API")
|
@Tag(name = "Search API")
|
||||||
public PagedCollection<List<Course>> searchByJurisdiction(@PathParam("country") String country,
|
public PagedCollection<List<Course>> searchByJurisdiction(@PathParam("country") String country,
|
||||||
@PathParam("state") String state, @BeanParam Pagination paging) {
|
@PathParam("state") String state, @BeanParam @Valid Pagination paging) {
|
||||||
SubList<? extends FlexMap> rows = this.courseService.findByJurisdiction(country, state, paging.getPage(),
|
SubList<? extends FlexMap> rows = this.courseService.findByJurisdiction(country, state, paging.getPage(),
|
||||||
paging.getPerPage());
|
paging.getPerPage());
|
||||||
if (rows.isEmpty())
|
if (rows.isEmpty())
|
||||||
throw new WebApplicationException("No matching golf courses found", Status.NOT_FOUND);
|
throw new WebApplicationException("No matching golf courses found", Status.NOT_FOUND);
|
||||||
|
this.logger.trace("found: {} [{}-{}] of {}", rows.size(), rows.getStartIndex() + 1, rows.getEndIndex(),
|
||||||
|
rows.getTotal());
|
||||||
|
|
||||||
return this.converter.convertValue(rows, Course.class).withPage(paging.getPage())
|
return this.converter.convertValue(rows, Course.class).withPage(paging.getPage())
|
||||||
.withPerPage(paging.getPerPage());
|
.withPerPage(paging.getPerPage());
|
||||||
@@ -123,15 +118,6 @@ public class CoursesApi {
|
|||||||
summary = "Searches for golf courses by their location.",
|
summary = "Searches for golf courses by their location.",
|
||||||
description = "Searches for golf courses by their major jurisdiction (e.g. US States), returning limited meta-data about each matched golf course."
|
description = "Searches for golf courses by their major jurisdiction (e.g. US States), returning limited meta-data about each matched golf course."
|
||||||
)
|
)
|
||||||
@ApiResponses({
|
|
||||||
@ApiResponse(responseCode = "200", description = "Success"),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description = "A latitude/longitude/radius was outside its natural limits"
|
|
||||||
), @ApiResponse(responseCode = "404", description = "No golf courses were found"),
|
|
||||||
@ApiResponse(responseCode = "411", description = "The page number must be at least 1"),
|
|
||||||
@ApiResponse(responseCode = "413", description = "The page size is too large")
|
|
||||||
})
|
|
||||||
@Parameters({
|
@Parameters({
|
||||||
@Parameter(
|
@Parameter(
|
||||||
name = "latitude",
|
name = "latitude",
|
||||||
@@ -144,30 +130,19 @@ public class CoursesApi {
|
|||||||
required = true,
|
required = true,
|
||||||
description = "A longitude in decimal degrees",
|
description = "A longitude in decimal degrees",
|
||||||
example = "-81.34891"
|
example = "-81.34891"
|
||||||
), @Parameter(name = "radius", description = "A search radius in miles", example = "10"),
|
), @Parameter(name = "radius", description = "A search radius in miles", example = "10")
|
||||||
@Parameter(name = "page", description = "A page number, starting at 1", example = "1"),
|
|
||||||
@Parameter(name = "perPage", description = "A page size", example = "20")
|
|
||||||
})
|
})
|
||||||
@Tag(name = "Search API")
|
@Tag(name = "Search API")
|
||||||
public PagedCollection<List<Course>> searchByJurisdiction(@QueryParam("latitude") double latitude,
|
public PagedCollection<List<Course>> searchByJurisdiction(
|
||||||
@QueryParam("longitude") double longitude, @QueryParam("radius") Integer radiusInMiles,
|
@QueryParam("latitude") @DecimalMin("-90.0") @DecimalMax("90.0") double latitude,
|
||||||
@BeanParam Pagination paging) {
|
@QueryParam("longitude") @DecimalMin("-180.0") @DecimalMax("180.0") double longitude,
|
||||||
if (latitude < -90.0 || latitude > 90.0)
|
@QueryParam("radius") @Positive @Max(100) Integer radiusInMiles, @BeanParam @Valid Pagination paging) {
|
||||||
throw new WebApplicationException("A latitude of -90 to 90 is expected", HttpStatus.SC_BAD_REQUEST);
|
|
||||||
if (longitude < -180.0 || longitude > 180.0)
|
|
||||||
throw new WebApplicationException("A longitude of -180 to 180 is expected", HttpStatus.SC_BAD_REQUEST);
|
|
||||||
|
|
||||||
if (radiusInMiles == null)
|
|
||||||
radiusInMiles = 10;
|
|
||||||
if (radiusInMiles <= 0)
|
|
||||||
throw new WebApplicationException("A positive radius is expected", HttpStatus.SC_BAD_REQUEST);
|
|
||||||
if (radiusInMiles > 100)
|
|
||||||
throw new WebApplicationException("A radius under 100 miles is expected", HttpStatus.SC_BAD_REQUEST);
|
|
||||||
|
|
||||||
SubList<? extends FlexMap> rows = this.courseService.findByLocation(latitude, longitude, radiusInMiles,
|
SubList<? extends FlexMap> rows = this.courseService.findByLocation(latitude, longitude, radiusInMiles,
|
||||||
paging.getPage(), paging.getPerPage());
|
paging.getPage(), paging.getPerPage());
|
||||||
if (rows.isEmpty())
|
if (rows.isEmpty())
|
||||||
throw new WebApplicationException("No matching facilities found", Status.NOT_FOUND);
|
throw new WebApplicationException("No matching facilities found", Status.NOT_FOUND);
|
||||||
|
this.logger.trace("found: {} [{}-{}] of {}", rows.size(), rows.getStartIndex() + 1, rows.getEndIndex(),
|
||||||
|
rows.getTotal());
|
||||||
|
|
||||||
return this.converter.convertValue(rows, Course.class).withPage(paging.getPage())
|
return this.converter.convertValue(rows, Course.class).withPage(paging.getPage())
|
||||||
.withPerPage(paging.getPerPage());
|
.withPerPage(paging.getPerPage());
|
||||||
|
@@ -2,10 +2,11 @@ package com.poststats.golf.service;
|
|||||||
|
|
||||||
import com.brianlong.util.FlexMap;
|
import com.brianlong.util.FlexMap;
|
||||||
import com.brianlong.util.SubList;
|
import com.brianlong.util.SubList;
|
||||||
|
import com.poststats.service.CacheableService;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface CourseService {
|
public interface CourseService extends CacheableService<Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method retrieves meta-data about the specified course.
|
* This method retrieves meta-data about the specified course.
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
package com.poststats.golf.service;
|
package com.poststats.golf.service;
|
||||||
|
|
||||||
import com.brianlong.util.FlexMap;
|
import com.brianlong.util.FlexMap;
|
||||||
|
import com.poststats.service.CacheableService;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public interface EventService {
|
public interface EventService extends CacheableService<Long> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method retrieves meta-data about the specified event.
|
* This method retrieves meta-data about the specified event.
|
||||||
|
@@ -2,10 +2,11 @@ package com.poststats.golf.service;
|
|||||||
|
|
||||||
import com.brianlong.util.FlexMap;
|
import com.brianlong.util.FlexMap;
|
||||||
import com.poststats.golf.security.AuthenticatedPerson;
|
import com.poststats.golf.security.AuthenticatedPerson;
|
||||||
|
import com.poststats.service.CacheableService;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface PersonService {
|
public interface PersonService extends CacheableService<Long> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method builds a `UserPrincipal` object about the golfer.
|
* This method builds a `UserPrincipal` object about the golfer.
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
package com.poststats.golf.service;
|
package com.poststats.golf.service;
|
||||||
|
|
||||||
import com.brianlong.util.FlexMap;
|
import com.brianlong.util.FlexMap;
|
||||||
|
import com.poststats.service.CacheableService;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface SeriesService {
|
public interface SeriesService extends CacheableService<Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method retrieves meta-data about the specified series.
|
* This method retrieves meta-data about the specified series.
|
||||||
|
@@ -18,10 +18,7 @@ import jakarta.inject.Inject;
|
|||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements CourseService {
|
public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements CourseService {
|
||||||
@@ -41,8 +38,8 @@ public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements Co
|
|||||||
FlexMap row = super.get(Integer.valueOf(courseId));
|
FlexMap row = super.get(Integer.valueOf(courseId));
|
||||||
if (row == null)
|
if (row == null)
|
||||||
return null;
|
return null;
|
||||||
row.put("facility", this.facilityService.get(row.getInteger("facilityID")));
|
|
||||||
|
|
||||||
|
this.injectCache(row, this.facilityService, "facilityID", "facility");
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,19 +47,14 @@ public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements Co
|
|||||||
public Map<Integer, ? extends FlexMap> get(Collection<Integer> courseIds) {
|
public Map<Integer, ? extends FlexMap> get(Collection<Integer> courseIds) {
|
||||||
Map<Integer, ? extends FlexMap> rows = super.get(courseIds);
|
Map<Integer, ? extends FlexMap> rows = super.get(courseIds);
|
||||||
|
|
||||||
// bulk fetch series from cache/db
|
this.injectCache(rows.values(), this.facilityService, "facilityID", "facility");
|
||||||
Set<Integer> facilityIds = new HashSet<>();
|
|
||||||
for (Entry<Integer, ? extends FlexMap> row : rows.entrySet())
|
|
||||||
facilityIds.add(row.getValue().getInteger("facilityId"));
|
|
||||||
|
|
||||||
Map<Integer, ? extends FlexMap> facilities = this.facilityService.get(facilityIds);
|
|
||||||
for (Entry<Integer, ? extends FlexMap> row : rows.entrySet())
|
|
||||||
row.getValue().put("facility", facilities.get(row.getValue().getInteger("facilityId")));
|
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubList<? extends FlexMap> findByName(String name, int page, int perPage) {
|
public SubList<? extends FlexMap> findByName(String name, int page, int perPage) {
|
||||||
|
SubList<? extends FlexMap> rows;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FlexPreparedStatement fps = this.sqlSelectByName.buildPreparedStatement();
|
FlexPreparedStatement fps = this.sqlSelectByName.buildPreparedStatement();
|
||||||
try {
|
try {
|
||||||
@@ -70,31 +62,34 @@ public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements Co
|
|||||||
fps.setVarchar(2, "%" + name + "%");
|
fps.setVarchar(2, "%" + name + "%");
|
||||||
fps.setSmallintU(3, (page - 1) * perPage);
|
fps.setSmallintU(3, (page - 1) * perPage);
|
||||||
fps.setSmallintU(4, perPage);
|
fps.setSmallintU(4, perPage);
|
||||||
return (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
rows = (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
||||||
} finally {
|
} finally {
|
||||||
fps.close();
|
fps.close();
|
||||||
}
|
}
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
throw new ServiceException(se);
|
throw new ServiceException(se);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.injectCache(rows, this.facilityService, "facilityID", "facility");
|
||||||
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||||
@Statement(
|
@Statement(
|
||||||
feature = ResultSubSetFeature.class,
|
feature = ResultSubSetFeature.class,
|
||||||
sql = "SELECT FP.*, FS.*, F.*, CP.prefix coursePrefix, C.* "
|
sql = "SELECT CP.*, C.* "
|
||||||
+ "FROM ~g~.Course C "
|
+ "FROM ~g~.Course C "
|
||||||
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
||||||
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
||||||
+ " LEFT JOIN ~p~.FacilityPrefix FP ON (F.prefixID=FP.prefixID) "
|
|
||||||
+ " LEFT JOIN ~p~.FacilitySuffix FS ON (F.suffixID=FS.suffixID) "
|
|
||||||
+ "WHERE course LIKE ? OR facility LIKE ? "
|
+ "WHERE course LIKE ? OR facility LIKE ? "
|
||||||
)
|
)
|
||||||
private StatementProvider sqlSelectByName;
|
private StatementProvider sqlSelectByName;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubList<? extends FlexMap> findByJurisdiction(String country, String state, int page, int perPage) {
|
public SubList<? extends FlexMap> findByJurisdiction(String country, String state, int page, int perPage) {
|
||||||
|
SubList<? extends FlexMap> rows;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FlexPreparedStatement fps = this.sqlSelectByJurisdiction.buildPreparedStatement();
|
FlexPreparedStatement fps = this.sqlSelectByJurisdiction.buildPreparedStatement();
|
||||||
try {
|
try {
|
||||||
@@ -102,26 +97,28 @@ public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements Co
|
|||||||
fps.setVarchar(2, state);
|
fps.setVarchar(2, state);
|
||||||
fps.setSmallintU(3, (page - 1) * perPage);
|
fps.setSmallintU(3, (page - 1) * perPage);
|
||||||
fps.setSmallintU(4, perPage);
|
fps.setSmallintU(4, perPage);
|
||||||
return (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
rows = (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
||||||
} finally {
|
} finally {
|
||||||
fps.close();
|
fps.close();
|
||||||
}
|
}
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
throw new ServiceException(se);
|
throw new ServiceException(se);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.injectCache(rows, this.facilityService, "facilityID", "facility");
|
||||||
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||||
@Statement(
|
@Statement(
|
||||||
feature = ResultSubSetFeature.class,
|
feature = ResultSubSetFeature.class,
|
||||||
sql = "SELECT FP.*, FS.*, F.*, CP.prefix coursePrefix, C.* "
|
sql = "SELECT CP.*, C.* "
|
||||||
+ "FROM ~g~.Course C "
|
+ "FROM ~g~.Course C "
|
||||||
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
||||||
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
||||||
+ " LEFT JOIN ~p~.FacilityPrefix FP ON (F.prefixID=FP.prefixID) "
|
+ "WHERE F.addrcountry=? AND F.addrstate=? "
|
||||||
+ " LEFT JOIN ~p~.FacilitySuffix FS ON (F.suffixID=FS.suffixID) "
|
+ " AND C.deadline IS NULL "
|
||||||
+ "WHERE addrcountry=? AND addrstate=? AND C.deadline IS NULL AND F.deadline IS NULL "
|
|
||||||
)
|
)
|
||||||
private StatementProvider sqlSelectByJurisdiction;
|
private StatementProvider sqlSelectByJurisdiction;
|
||||||
|
|
||||||
@@ -129,6 +126,7 @@ public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements Co
|
|||||||
public SubList<? extends FlexMap> findByLocation(double latitude, double longitude, int radiusInMiles, int page,
|
public SubList<? extends FlexMap> findByLocation(double latitude, double longitude, int radiusInMiles, int page,
|
||||||
int perPage) {
|
int perPage) {
|
||||||
double degrees = PostStatsSQL.miles2degrees(radiusInMiles);
|
double degrees = PostStatsSQL.miles2degrees(radiusInMiles);
|
||||||
|
SubList<? extends FlexMap> rows;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FlexPreparedStatement fps = this.sqlSelectByGeolocation.buildPreparedStatement();
|
FlexPreparedStatement fps = this.sqlSelectByGeolocation.buildPreparedStatement();
|
||||||
@@ -139,27 +137,28 @@ public class CourseServiceDAO extends CacheableServiceDAO<Integer> implements Co
|
|||||||
fps.setDouble(4, longitude + degrees);
|
fps.setDouble(4, longitude + degrees);
|
||||||
fps.setSmallintU(5, (page - 1) * perPage);
|
fps.setSmallintU(5, (page - 1) * perPage);
|
||||||
fps.setSmallintU(6, perPage);
|
fps.setSmallintU(6, perPage);
|
||||||
return (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
rows = (SubList<? extends FlexMap>) fps.executeQuery().getAllRows();
|
||||||
} finally {
|
} finally {
|
||||||
fps.close();
|
fps.close();
|
||||||
}
|
}
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
throw new ServiceException(se);
|
throw new ServiceException(se);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.injectCache(rows, this.facilityService, "facilityID", "facility");
|
||||||
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
@Named(Constants.STATEMENT_PROVIDER_GOLF)
|
||||||
@Statement(
|
@Statement(
|
||||||
feature = ResultSubSetFeature.class,
|
feature = ResultSubSetFeature.class,
|
||||||
sql = "SELECT FP.*, FS.*, F.*, CP.prefix coursePrefix, C.* "
|
sql = "SELECT CP.*, C.* "
|
||||||
+ "FROM ~g~.Course C "
|
+ "FROM ~g~.Course C "
|
||||||
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
+ " LEFT JOIN ~g~.CoursePrefix CP ON (C.prefixID=CP.prefixID) "
|
||||||
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
+ " INNER JOIN ~p~.Facility F ON (C.facilityID=F.facilityID) "
|
||||||
+ " LEFT JOIN ~p~.FacilityPrefix FP ON (F.prefixID=FP.prefixID) "
|
|
||||||
+ " LEFT JOIN ~p~.FacilitySuffix FS ON (F.suffixID=FS.suffixID) "
|
|
||||||
+ "WHERE F.latitude>=? AND F.latitude<=? AND F.longitude>=? AND F.longitude<=? "
|
+ "WHERE F.latitude>=? AND F.latitude<=? AND F.longitude>=? AND F.longitude<=? "
|
||||||
+ " AND C.deadline IS NULL AND F.deadline IS NULL "
|
+ " AND C.deadline IS NULL "
|
||||||
)
|
)
|
||||||
private StatementProvider sqlSelectByGeolocation;
|
private StatementProvider sqlSelectByGeolocation;
|
||||||
|
|
||||||
|
@@ -35,8 +35,9 @@ public class EventRoundServiceDAO extends CacheableServiceDAO<Long> implements E
|
|||||||
FlexMap row = super.get(Long.valueOf(eventId));
|
FlexMap row = super.get(Long.valueOf(eventId));
|
||||||
if (row == null)
|
if (row == null)
|
||||||
return null;
|
return null;
|
||||||
row.put("course", this.courseService.get(row.getInteger("courseID")));
|
|
||||||
|
|
||||||
|
this.injectCache(row, this.courseService, "courseID", "course");
|
||||||
|
row.put("course", this.courseService.get(row.getInteger("courseID")));
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,7 +17,6 @@ import java.sql.SQLException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
@@ -38,8 +37,8 @@ public class EventServiceDAO extends CacheableServiceDAO<Long> implements EventS
|
|||||||
FlexMap row = super.get(Long.valueOf(eventId));
|
FlexMap row = super.get(Long.valueOf(eventId));
|
||||||
if (row == null)
|
if (row == null)
|
||||||
return null;
|
return null;
|
||||||
row.put("series", this.seriesService.get(row.getInteger("seriesID")));
|
|
||||||
|
|
||||||
|
this.injectCache(row, this.seriesService, "seriesID", "series");
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,14 +46,7 @@ public class EventServiceDAO extends CacheableServiceDAO<Long> implements EventS
|
|||||||
public Map<Long, ? extends FlexMap> get(Collection<Long> eventIds) {
|
public Map<Long, ? extends FlexMap> get(Collection<Long> eventIds) {
|
||||||
Map<Long, ? extends FlexMap> rows = super.get(eventIds);
|
Map<Long, ? extends FlexMap> rows = super.get(eventIds);
|
||||||
|
|
||||||
// bulk fetch series from cache/db
|
this.injectCache(rows.values(), this.seriesService, "seriesID", "series");
|
||||||
Set<Integer> seriesIds = new HashSet<>();
|
|
||||||
for (Entry<Long, ? extends FlexMap> row : rows.entrySet())
|
|
||||||
seriesIds.add(row.getValue().getInteger("seriesId"));
|
|
||||||
|
|
||||||
Map<Integer, ? extends FlexMap> serieses = this.seriesService.get(seriesIds);
|
|
||||||
for (Entry<Long, ? extends FlexMap> row : rows.entrySet())
|
|
||||||
row.getValue().put("series", serieses.get(row.getValue().getInteger("seriesID")));
|
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,7 +25,6 @@ import java.sql.SQLException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
@@ -74,16 +73,16 @@ public class PersonServiceDAO extends CacheableServiceDAO<Long> implements Perso
|
|||||||
FlexMap row = this.get(Long.valueOf(personId));
|
FlexMap row = this.get(Long.valueOf(personId));
|
||||||
if (row == null)
|
if (row == null)
|
||||||
return null;
|
return null;
|
||||||
row.put("person", this.poststatsPersonService.get(personId));
|
|
||||||
|
this.injectCache(row, this.poststatsPersonService, "personID", "person");
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Long, ? extends FlexMap> get(Collection<Long> ids) {
|
public Map<Long, ? extends FlexMap> get(Collection<Long> ids) {
|
||||||
Map<Long, ? extends FlexMap> rows = super.get(ids);
|
Map<Long, ? extends FlexMap> rows = super.get(ids);
|
||||||
Map<Long, ? extends FlexMap> persons = this.poststatsPersonService.get(ids);
|
|
||||||
for (Entry<Long, ? extends FlexMap> row : rows.entrySet())
|
this.injectCache(rows.values(), this.poststatsPersonService, "personID", "person");
|
||||||
row.getValue().put("person", persons.get(row.getKey()));
|
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user