initial checkin

This commit is contained in:
Brian Long 2020-10-26 10:43:21 -04:00
commit cfdc7d2e36
19 changed files with 832 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Maven
target
# Eclipse
.project
.classpath
.settings

194
pom.xml Normal file
View File

@ -0,0 +1,194 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.poststats</groupId>
<artifactId>golf-api</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.debug>true</maven.compiler.debug>
<maven.compiler.debuglevel>lines,vars,source</maven.compiler.debuglevel>
<server.hostname>poststats.com</server.hostname>
<server.path.tomcat>/var/local/tomcat7-${env}</server.path.tomcat>
<server.path.configs>${server.path.tomcat}/shared/classes</server.path.configs>
<server.path.webapps>${server.path.tomcat}/webapps/golf.api.poststats.com</server.path.webapps>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.bundles</groupId>
<artifactId>jaxrs-ri</artifactId>
<version>2.26</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>com.poststats.golf</groupId>
<artifactId>db</artifactId>
<version>4.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.poststats</groupId>
<artifactId>db</artifactId>
<version>4.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.poststats</groupId>
<artifactId>commons-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.10</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.8.v20171121</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<webApp>
<contextPath>/</contextPath>
<resourceBases>
<resourceBase>${project.build.directory}/${project.artifactId}-${project.version}</resourceBase>
</resourceBases>
<extraClasspath>${basedir}/../../poststats-db/db/src/${env},${basedir}/../../golf-db/db/src/${env},${basedir}/src/${env}/resources</extraClasspath>
</webApp>
<contextXml>${basedir}/src/${env}/jetty.xml</contextXml>
<useTestScope>true</useTestScope>
</configuration>
</plugin>
<plugin>
<groupId>com.webcohesion.enunciate</groupId>
<artifactId>enunciate-maven-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<docsDir>${project.build.directory}/${project.build.finalName}</docsDir>
<configFile>${basedir}/enunciate.xml</configFile>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>docs</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>digitalocean-env</id>
<activation>
<property>
<name>env</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<serverId>digitalocean-poststats</serverId>
</configuration>
<executions>
<execution>
<id>upload-config-to-server</id>
<phase>install</phase>
<goals>
<goal>upload</goal>
</goals>
<configuration>
<fromDir>${basedir}/src/${env}/resources</fromDir>
<url>scp://${server.hostname}${server.path.configs}</url>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>digitalocean-deploy</id>
<activation>
<property>
<name>env</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<serverId>digitalocean-poststats</serverId>
</configuration>
<executions>
<execution>
<id>upload-war-to-server</id>
<phase>install</phase>
<goals>
<goal>upload-single</goal>
</goals>
<configuration>
<fromFile>${project.build.directory}/${project.build.finalName}.war</fromFile>
<url>scp://${server.hostname}/tmp</url>
</configuration>
</execution>
<execution>
<id>deploy-war-in-server</id>
<phase>install</phase>
<goals>
<goal>sshexec</goal>
</goals>
<configuration>
<url>scp://${server.hostname}</url>
<commands>
<command>mv /tmp/${project.build.finalName}.war ${server.path.webapps}/ROOT.war</command>
</commands>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

4
src/local/jetty.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<Configure id="golf-api" class="org.eclipse.jetty.webapp.WebAppContext">
</Configure>

View File

@ -0,0 +1,8 @@
package com.poststats.api.golf;
import javax.ws.rs.ApplicationPath;
@ApplicationPath("golf")
public class Application extends javax.ws.rs.core.Application {
}

View File

@ -0,0 +1,103 @@
package com.poststats.api.golf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import com.brianlong.sql.DataSet;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.poststats.api.golf.service.EventFinanceService;
@Path("/event/{eventId}/finance")
public class EventFinanceApi {
private final ObjectMapper mapper = new ObjectMapper();
@PathParam("eventId")
private long eventId;
@GET
@Path("/balance/persons")
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("member")
public String getBalanceByPersonsAsJson(@Context SecurityContext securityContext) throws JsonProcessingException {
if (!securityContext.isUserInRole(this.eventId + "~finance"))
throw new SecurityException("Not permitted");
List<DataSet> personsBalances = this.getEventFinanceService().getPersonsBalances(this.eventId);
List<Map<String, Object>> personsBalancesJson = new ArrayList<>(personsBalances.size());
for (DataSet personBalance : personsBalances) {
Map<String, Object> personBalanceJson = new HashMap<>(5);
personBalanceJson.put("personId", personBalance.getLong("personID"));
personBalanceJson.put("expense", personBalance.getFloat("expense"));
personBalanceJson.put("paid", personBalance.getFloat("paid"));
personBalanceJson.put("balance", personBalance.getFloat("balance"));
personsBalancesJson.add(personBalanceJson);
}
return this.mapper.writeValueAsString(personsBalancesJson);
}
@GET
@Path("/balance/persons/csv")
@Produces("text/csv")
@RolesAllowed("member")
public String getBalanceByPersonsAsCsv(@Context SecurityContext securityContext) throws IOException {
if (!securityContext.isUserInRole(this.eventId + "~finance"))
throw new SecurityException("Not permitted");
List<DataSet> personsBalances = this.getEventFinanceService().getPersonsBalances(this.eventId);
StringBuilder personsBalancesCsvBuilder = new StringBuilder();
CSVPrinter personsBalancesCsvPrinter = new CSVPrinter(personsBalancesCsvBuilder, CSVFormat.DEFAULT);
try {
personsBalancesCsvPrinter.printRecord(
"personID",
"lname",
"fname",
"suffix",
"expense",
"paid",
"balance");
for (DataSet personBalance : personsBalances) {
personsBalancesCsvPrinter.printRecord(
personBalance.getLong("personID"),
personBalance.getString("lname"),
personBalance.getString("fname"),
personBalance.getString("suffix"),
personBalance.getFloat("expense"),
personBalance.getFloat("paid"),
personBalance.getFloat("balance"));
}
personsBalancesCsvPrinter.flush();
} finally {
personsBalancesCsvPrinter.close();
}
return personsBalancesCsvBuilder.toString();
}
private EventFinanceService getEventFinanceService() {
return ServiceLoader.load(EventFinanceService.class).iterator().next();
}
}

View File

@ -0,0 +1,158 @@
package com.poststats.api.golf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import com.brianlong.sql.DataSet;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.poststats.api.golf.service.EventPersonService;
import com.poststats.api.golf.service.EventService;
import com.poststats.api.model.Person;
@Path("/event/{eventId}")
public class EventPersonApi {
private final ObjectMapper mapper = new ObjectMapper();
@PathParam("eventId")
private long eventId;
@GET
@Path("/people")
@Produces({MediaType.APPLICATION_JSON, "text/csv"})
@RolesAllowed("member")
public String get(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException {
if (!securityContext.isUserInRole(this.eventId + "~member"))
throw new SecurityException("Not permitted");
List<DataSet> persons = this.getEventPersonService().getPeople(this.eventId);
if ("csv".equals(format)) {
return this.toAddressBookAsCsv(persons);
} else {
return this.toAddressBookAsJson(persons);
}
}
@GET
@Path("/participants")
@Produces({MediaType.APPLICATION_JSON, "text/csv"})
@RolesAllowed("member")
public String getParticipants(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException {
if (!securityContext.isUserInRole(this.eventId + "~member"))
throw new SecurityException("Not permitted");
List<DataSet> persons = this.getEventPersonService().getParticipants(this.eventId);
if ("csv".equals(format)) {
return this.toAddressBookAsCsv(persons);
} else {
return this.toAddressBookAsJson(persons);
}
}
@GET
@Path("/participants")
@Produces({MediaType.APPLICATION_JSON, "text/csv"})
@RolesAllowed("member")
public String getSeriesParticipants(@Context SecurityContext securityContext, @QueryParam("format") String format) throws JsonProcessingException, IOException {
if (!securityContext.isUserInRole(this.eventId + "~member"))
throw new SecurityException("Not permitted");
int seriesId = this.getEventService().getSeriesId(this.eventId);
Person principal = (Person)securityContext.getUserPrincipal();
Set<Long> eventIds = this.getEventPersonService().getSeriesEventIdsAsParticipant(seriesId, principal.getId());
Set<Long> personIds = new HashSet<>();
List<DataSet> persons = new LinkedList<>();
for (long eventId : eventIds) {
List<DataSet> tmpPersons = this.getEventPersonService().getParticipants(eventId);
for (DataSet person : tmpPersons)
if (personIds.add(person.getLong("personID")))
persons.add(person);
}
if ("csv".equals(format)) {
return this.toAddressBookAsCsv(persons);
} else {
return this.toAddressBookAsJson(persons);
}
}
private String toAddressBookAsJson(List<DataSet> persons) throws JsonProcessingException {
List<Map<String, Object>> personsJson = new ArrayList<>(persons.size());
for (DataSet person : persons) {
Map<String, Object> personJson = new HashMap<>(5);
personJson.put("personId", person.getLong("personID"));
personJson.put("prefix", person.getString("prefix"));
personJson.put("lastName", person.getString("lname"));
personJson.put("firstName", person.getString("fname"));
personJson.put("suffix", person.getString("suffix"));
personJson.put("emailAddress", person.getString("email"));
personsJson.add(personJson);
}
return this.mapper.writeValueAsString(personsJson);
}
private String toAddressBookAsCsv(List<DataSet> persons) throws IOException {
StringBuilder personsCsvBuilder = new StringBuilder();
CSVPrinter personsCsvPrinter = new CSVPrinter(personsCsvBuilder, CSVFormat.DEFAULT);
try {
personsCsvPrinter.printRecord(
"ID",
"Prefix",
"Last Name",
"First Name",
"Suffix",
"Email Address");
for (DataSet person : persons) {
personsCsvPrinter.printRecord(
person.getLong("personID"),
person.getString("prefix"),
person.getString("lname"),
person.getString("fname"),
person.getString("suffix"),
person.getString("email"));
}
personsCsvPrinter.flush();
} finally {
personsCsvPrinter.close();
}
return personsCsvBuilder.toString();
}
private EventService getEventService() {
return ServiceLoader.load(EventService.class).iterator().next();
}
private EventPersonService getEventPersonService() {
return ServiceLoader.load(EventPersonService.class).iterator().next();
}
}

View File

@ -0,0 +1,31 @@
package com.poststats.api.golf;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.TextNode;
@Path("/version")
public class VersionApi {
private ObjectMapper mapper = new ObjectMapper();
@GET
@Produces(MediaType.APPLICATION_JSON)
public String get() throws JsonProcessingException {
// FIXME make dynamic
return this.mapper.writeValueAsString(new TextNode("1.0"));
}
@GET
@Path("/pattern")
@Produces(MediaType.APPLICATION_JSON)
public String getRegexPattern() throws JsonProcessingException {
return this.mapper.writeValueAsString(new TextNode("[0-9]+\\.[0-9]+"));
}
}

View File

@ -0,0 +1,11 @@
package com.poststats.api.golf.service;
import java.util.List;
import com.brianlong.sql.DataSet;
public interface EventFinanceService {
List<DataSet> getPersonsBalances(long eventId);
}

View File

@ -0,0 +1,16 @@
package com.poststats.api.golf.service;
import java.util.List;
import java.util.Set;
import com.brianlong.sql.DataSet;
public interface EventPersonService {
List<DataSet> getPeople(long eventId);
List<DataSet> getParticipants(long eventId);
Set<Long> getSeriesEventIdsAsParticipant(int seriesId, long personId);
}

View File

@ -0,0 +1,7 @@
package com.poststats.api.golf.service;
public interface EventService {
int getSeriesId(long eventId);
}

View File

@ -0,0 +1,13 @@
package com.poststats.api.golf.service;
import java.util.List;
import com.brianlong.sql.DataSet;
public interface SeriesPersonService {
List<DataSet> getSeriesPeople(int seriesId);
List<DataSet> getSeriesParticipants(int seriesId);
}

View File

@ -0,0 +1,81 @@
package com.poststats.api.golf.service.impl;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
import com.brianlong.sql.DataSet;
import com.brianlong.sql.FlexPreparedStatement;
import com.poststats.api.golf.service.EventFinanceService;
import com.poststats.golf.sql.GolfSQL;
import com.poststats.sql.PostStatsDataSource;
public class DatabaseEventFinanceService implements EventFinanceService {
@Override
public List<DataSet> getPersonsBalances(long eventId) {
Connection dbcon = PostStatsDataSource.getInstance().acquire(true);
try {
return this.queryPersonsBalances(dbcon, eventId);
} catch (SQLException se) {
throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR);
} finally {
PostStatsDataSource.getInstance().release(dbcon);
}
}
private List<DataSet> queryPersonsBalances(Connection dbcon, long eventId) throws SQLException {
FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_BALANCES);
try {
for (int i = 1; i <= 5; i++)
fps.setIntegerU(1, eventId);
return fps.executeQuery().getAllRows();
} finally {
fps.close();
}
}
private static final String SQL_SELECT_BALANCES = GolfSQL.changeSchema(new StringBuilder()
.append("SELECT P.personID, P.prefix, P.fname, P.lname, P.suffix, ")
.append("TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance ")
.append("FROM (")
.append("SELECT ALL EP.personID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid ")
.append("FROM ~g~.EventPerson EP ")
.append("LEFT JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) ")
.append("WHERE EP.eventID=? ")
.append("UNION ALL ")
.append("SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid ")
.append("FROM ~g~.EventPerson EP ")
.append("INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) ")
.append("INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) ")
.append("WHERE EP.eventID=? AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE ")
.append("UNION ALL ")
.append("SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid ")
.append("FROM ~g~.EventPerson EP ")
.append("INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) ")
.append("INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) ")
.append("WHERE EP.eventID=? AND EPO.itemID IS NOT NULL ")
.append("AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) ")
.append("AND EO.amount IS NOT NULL AND EO.waive IS FALSE ")
.append("UNION ALL ")
.append("SELECT ALL EP.personID, EP.epersonID, EOI.amount expenses, 0 paid ")
.append("FROM ~g~.EventPerson EP ")
.append("INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) ")
.append("INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) ")
.append("INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) ")
.append("WHERE EP.eventID=? AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL ")
.append("UNION ALL ")
.append("SELECT ALL EPP.personID, EP.epersonID, 0 expenses, EPP.amount paid ")
.append("FROM ~g~.EventPersonPayment EPP ")
.append("LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) ")
.append("WHERE EPP.eventID=?) TT ")
.append("INNER JOIN ~p~.Person P ")
.append("GROUP BY P.personID ")
.append("ORDER BY P.lname, P.fname, P.suffix").toString());
}

View File

@ -0,0 +1,89 @@
package com.poststats.api.golf.service.impl;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
import com.brianlong.sql.DataSet;
import com.brianlong.sql.FlexPreparedStatement;
import com.poststats.api.golf.service.EventPersonService;
import com.poststats.sql.PostStatsDataSource;
public class DatabaseEventPersonService implements EventPersonService {
@Override
public List<DataSet> getPeople(long eventId) {
Connection dbcon = PostStatsDataSource.getInstance().acquire(true);
try {
return this.queryPersons(dbcon, eventId);
} catch (SQLException se) {
throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR);
} finally {
PostStatsDataSource.getInstance().release(dbcon);
}
}
@Override
public List<DataSet> getParticipants(long eventId) {
Connection dbcon = PostStatsDataSource.getInstance().acquire(true);
try {
return this.queryParticipants(dbcon, eventId);
} catch (SQLException se) {
throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR);
} finally {
PostStatsDataSource.getInstance().release(dbcon);
}
}
@Override
public Set<Long> getSeriesEventIdsAsParticipant(int seriesId, long personId) {
Connection dbcon = PostStatsDataSource.getInstance().acquire(true);
try {
return this.querySeriesEventIdsAsParticipant(dbcon, seriesId, personId);
} catch (SQLException se) {
throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR);
} finally {
PostStatsDataSource.getInstance().release(dbcon);
}
}
private List<DataSet> queryPersons(Connection dbcon, long eventId) throws SQLException {
FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_PERSONS);
try {
fps.setIntegerU(1, eventId);
return fps.executeQuery().getAllRows();
} finally {
fps.close();
}
}
private List<DataSet> queryParticipants(Connection dbcon, long eventId) throws SQLException {
FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_PARTICIPANTS);
try {
fps.setIntegerU(1, eventId);
return fps.executeQuery().getAllRows();
} finally {
fps.close();
}
}
private Set<Long> querySeriesEventIdsAsParticipant(Connection dbcon, int seriesId, long personId) throws SQLException {
FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, SQL_SELECT_PARTICIPANTS);
try {
fps.setSmallintU(1, seriesId);
fps.setIntegerU(2, personId);
Set<Long> eventIds = new HashSet<>();
fps.executeQuery().getFirstColumn(Long.class, eventIds);
return eventIds;
} finally {
fps.close();
}
}
}

View File

@ -0,0 +1,38 @@
package com.poststats.api.golf.service.impl;
import java.sql.Connection;
import java.sql.SQLException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
import com.brianlong.sql.FlexPreparedStatement;
import com.poststats.api.golf.service.EventService;
import com.poststats.golf.sql.GolfSQL;
import com.poststats.sql.PostStatsDataSource;
public class DatabaseEventService implements EventService {
@Override
public int getSeriesId(long eventId) {
Connection dbcon = PostStatsDataSource.getInstance().acquire(true);
try {
return this.querySeriesId(dbcon, eventId);
} catch (SQLException se) {
throw new WebApplicationException("Database call failure", se, Status.INTERNAL_SERVER_ERROR);
} finally {
PostStatsDataSource.getInstance().release(dbcon);
}
}
private int querySeriesId(Connection dbcon, long eventId) throws SQLException {
FlexPreparedStatement fps = new FlexPreparedStatement(dbcon, GolfSQL.changeSchema("SELECT seriesId FROM ~g~.Event WHERE eventID=?"));
try {
fps.setIntegerU(1, eventId);
return fps.executeQuery().getOne(Integer.class);
} finally {
fps.close();
}
}
}

View File

@ -0,0 +1 @@
com.poststats.api.golf.service.impl.DatabaseEventFinanceService

View File

@ -0,0 +1 @@
com.poststats.api.golf.service.impl.DatabaseEventPersonService

View File

@ -0,0 +1 @@
com.poststats.api.golf.service.impl.DatabaseEventService

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>PostStats Golf API</display-name>
<context-param>
<param-name>envConfig</param-name>
<param-value>/env-config.golf-api.properties</param-value>
</context-param>
<!--
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>default</realm-name>
</login-config>
-->
<session-config>
<session-timeout>300</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

View File

@ -0,0 +1,44 @@
package com.poststats.api.golf;
import java.io.IOException;
import java.util.regex.Pattern;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import com.poststats.api.golf.VersionApi;
public class VersionApiUnitTest {
private static VersionApi api;
@BeforeClass
public static void init() {
api = new VersionApi();
}
@Test
public void get() throws IOException {
String current = api.get();
Assert.assertNotNull(current);
Assert.assertTrue(current.length() > 0);
}
@Test
public void getPattern() throws IOException {
String pattern = api.getRegexPattern();
Assert.assertNotNull(pattern);
Assert.assertTrue(pattern.length() > 0);
Pattern.compile(pattern);
}
@Test
public void isValidFormat() throws IOException {
String pattern = api.getRegexPattern();
String current = api.get();
Assert.assertTrue(Pattern.compile(pattern).matcher(current).matches());
}
}