Skip to content
Permalink
Browse files

Introduce jOOQ.

This commit introduces jOOQ to the build. By executing the flyway maven
plugin (also managed by Spring Boot) during build into a temporary, file
based H2 instance, we create the baseline for jOOQ.

jOOQ connects against the database and creates all necessary table
definitions.

The newly introduced StatisticsService now uses only jOOQ builder
methods to create SQL.

The only thing that had to be adapted was the fact that jOOQ doesn't
provide dateDiff with a date part atm.
  • Loading branch information...
michael-simons committed Nov 1, 2019
1 parent 9c670d7 commit 64600a910236f99d2bf56efccc945cf4cd6931e6
103 pom.xml
@@ -73,6 +73,9 @@

<!-- Same exclusions as pure JaCoCo -->
<sonar.coverage.exclusions>**/Application.java,**/JAXBContextFactory.java,src/main/java/ac/simons/biking2/config/*</sonar.coverage.exclusions>

<db.url>jdbc:h2:${project.build.directory}/flyway-code-gen</db.url>
<db.username>sa</db.username>
</properties>

<dependencies>
@@ -125,6 +128,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
@@ -301,10 +308,76 @@
<version>${checkstyle.version}</version>
</dependency>
</dependencies>
<configuration>
<configLocation>src/checkstyle/checkstyle.xml</configLocation>
<suppressionsLocation>src/checkstyle/checkstyle-suppressions.xml</suppressionsLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<linkXRef>false</linkXRef>
<excludes>${project.build.directory}/generated-sources/**/*</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>migrate</goal>
</goals>
</execution>
</executions>
<configuration>
<url>${db.url}</url>
<user>${db.username}</user>
</configuration>
</plugin>
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<jdbc>
<url>${db.url}</url>
<user>${db.username}</user>
</jdbc>
<generator>
<database>
<name>org.jooq.meta.h2.H2Database</name>
<schemaVersionProvider>SELECT :schema_name || '_' || MAX("version") FROM "flyway_schema_history"</schemaVersionProvider>
<includes>.*</includes>
<excludes>schema_version</excludes>
<schemata>
<schema>
<inputSchema>PUBLIC</inputSchema>
<outputSchemaToDefault>true</outputSchemaToDefault>
</schema>
</schemata>
</database>
<generate>
<deprecated>false</deprecated>
<javaTimeTypes>true</javaTimeTypes>
</generate>
<target>
<packageName>ac.simons.biking2.db</packageName>
<directory>target/generated-sources/jooq</directory>
</target>
</generator>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
@@ -397,7 +470,7 @@
<executions>
<execution>
<goals>
<goal>jar</goal>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
@@ -409,14 +482,6 @@
<execution>
<id>validate</id>
<phase>validate</phase>
<configuration>
<configLocation>src/checkstyle/checkstyle.xml</configLocation>
<suppressionsLocation>src/checkstyle/checkstyle-suppressions.xml</suppressionsLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<linkXRef>false</linkXRef>
</configuration>
<goals>
<goal>check</goal>
</goals>
@@ -435,6 +500,8 @@
<exclude>ac/simons/biking2/misc/JAXBContextFactory.class</exclude>
<!-- Configuration -->
<exclude>ac/simons/biking2/config/*</exclude>
<!-- jOOQ Code -->
<exclude>ac/simons/biking2/db/**/*</exclude>
</excludes>
</configuration>
<executions>
@@ -453,17 +520,15 @@
</goals>
<configuration>
<rules>
<!-- implmentation is needed only for Maven 2 -->
<rule implementation="org.jacoco.maven.RuleConfiguration">
<rule>
<element>BUNDLE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<limit>
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>0.95</minimum>
</limit>
<!-- implmentation is needed only for Maven 2 -->
<limit implementation="org.jacoco.report.check.Limit">
<limit>
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.85</minimum>
@@ -515,16 +580,6 @@

<reporting>
<plugins>
<!-- Included a second time to make NetBeans aware of it -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<configuration>
<configLocation>src/checkstyle/checkstyle.xml</configLocation>
<suppressionsLocation>src/checkstyle/checkstyle-suppressions.xml</suppressionsLocation>
</configuration>
</plugin>
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
@@ -21,3 +21,15 @@ WHERE p.fqn in ['ac.simons.biking2.shared', 'ac.simons.biking2.support']
SET p:Package:Support
return p
----

The `database` package contains generated code for accessing our database via jOOQ:

[[structure:dbPackage]]
[source,cypher,role="concept",requiresConcepts="dependency:Package"]
.Returns the package containing generated jOOQ code
----
MATCH (p:Package)
WHERE p.fqn in ['ac.simons.biking2.db']
SET p:Package:Database
return p
----
@@ -8,10 +8,14 @@ Those packages should have no dependencies to other packages outside themselves
[source,cypher,role=constraint,requiresConcepts="structure:configPackages,structure:supportingPackages"]
.Top level packages should conform to the main building blocks.
----
MATCH (db:Package:Database)
WITH db
MATCH (a:Main:Artifact)
MATCH (a) -[:CONTAINS]-> (p1:Package) -[:DEPENDS_ON]-> (p2:Package) <-[:CONTAINS]- (a)
WHERE not p1:Config
and not (p1) -[:CONTAINS]-> (p2)
and not p2:Support
and p2 <> db
and not (db) - [:CONTAINS*] -> (p2)
RETURN p1, p2
----
@@ -30,17 +30,19 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import ac.simons.biking2.statistics.highcharts.HighchartsNgConfig;

/**
* @author Michael J. Simons, 2014-02-09
* @author Michael J. Simons
* @since 2014-02-09
*/
@RestController
@RequestMapping("/api")
@RequestMapping("/api/charts")
class ChartsController {

enum Messages {
@@ -72,7 +74,7 @@
this.i18n = new MessageSourceAccessor(messageSource, Locale.ENGLISH);
}

@RequestMapping("/charts/currentYear")
@GetMapping("/currentYear")
public HighchartsNgConfig getCurrentYear() {
// Start of current year
final LocalDate january1st = LocalDate.now().withMonth(1).withDayOfMonth(1);
@@ -158,7 +160,7 @@ public HighchartsNgConfig getCurrentYear() {
.build();
}

@RequestMapping("/charts/history")
@GetMapping("/history")
public HighchartsNgConfig getHistory(
@RequestParam(value = "start") final Optional<Integer> yearStart,
@RequestParam(value = "end") final Optional<Integer> yearEnd
@@ -169,7 +171,7 @@ public HighchartsNgConfig getHistory(
final HighchartsNgConfig.Builder builder = HighchartsNgConfig.define();

// Get statistics and create series in builder
final Map<Integer, YearlyStatistics> history = this.statisticService.computeHistory(yearStart, yearEnd);
final Map<Integer, HistoricYear> history = this.statisticService.computeHistory(yearStart, yearEnd);
history.forEach((k, v) -> builder.series().withName(Integer.toString(k)).withData(v.getValues()).build());

final StringBuilder title = new StringBuilder();
@@ -178,7 +180,7 @@ public HighchartsNgConfig getHistory(
} else {
// Compute summed years
final Map<Integer, Integer> summedYears = history.values().stream()
.collect(Collectors.toMap(YearlyStatistics::getYear, YearlyStatistics::getYearlyTotal));
.collect(Collectors.toMap(HistoricYear::getYear, HistoricYear::getYearlyTotal));

// Computed worst and best year from summed years
final Optional<Map.Entry<Integer, Integer>> worstYear = summedYears.entrySet().stream().min(Map.Entry.comparingByValue());
@@ -192,7 +194,7 @@ public HighchartsNgConfig getHistory(
// Preferred bikes...
userData.put("preferredBikes",
history.values().stream()
.collect(Collectors.toMap(YearlyStatistics::getYear, y -> Map.of("name", y.getPreferredBike())))
.collect(Collectors.toMap(HistoricYear::getYear, y -> Map.of("name", y.getPreferredBike())))

);

@@ -250,7 +252,7 @@ public HighchartsNgConfig getHistory(
.build();
}

@RequestMapping("/charts/monthlyAverage")
@GetMapping("/monthlyAverage")
public HighchartsNgConfig getMonthlyAverage() {

// Get statistics
@@ -25,7 +25,7 @@
* @author Michael J. Simons
* @since 2019-11-01
*/
final class YearlyStatistics {
final class HistoricYear {

private final int year;

@@ -36,7 +36,7 @@
private final String preferredBike;

@Builder
private YearlyStatistics(final int year, final int[] values, final String preferredBike) {
private HistoricYear(final int year, final int[] values, final String preferredBike) {
this.year = year;
this.values = values;
this.yearlyTotal = Arrays.stream(values).sum();

0 comments on commit 64600a9

Please sign in to comment.
You can’t perform that action at this time.