-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Loader implement java.util.stream.Collector
#14
Changes from all commits
98f6ee2
dd12846
c75c77a
570d02d
1c732bc
b17e0e6
b1499a7
135335c
06ef703
666d9b5
4838b8d
b5acf12
6379c16
b26d359
79c72a7
815c37b
8d86a22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Changelog | ||
|
||
## v0.0.3 | ||
|
||
### Release date: | ||
|
||
2021/11/14 | ||
|
||
### Changes: | ||
|
||
This release introduces a backwards-incompatible makeover of the public API by simplifying the main `Loader` API, | ||
requiring JDK v11+ and Jooq v3.15+ and dropping multiple public methods: | ||
|
||
- Require JDK v11+ and Jooq v3.15+. | ||
- Implement `Collector<Record, ObjectGraph, List<T>>` for `Loader<T>` to be used | ||
with `org.jooq.ResultQuery#collect(Collector<? super R, A, X> collector)`. See the [README.md] for updated usage | ||
advice. | ||
- Make `Entity`, `Relation` and `Loader` effectively immutable. | ||
- Remove or hide `Entity#get(long id)`, `Entity#getEntities()`, `Entity#getEntityMap()`. `Entity#copy()` | ||
, `Entity#load(Record record)` | ||
- Remove `Loader#next(Record record)`, `Loader#get()`, `Loader#stream()`, `Loader#getSet()`, `Loader#getList()` | ||
, `Loader#getOne()`, `Loader#getOptional()`, `Loader#collect(Collector<? super T, A, R> collector)`. | ||
- Custom relation loaders have to implement `Function<Record, Set<IdPair>`. | ||
|
||
## v0.0.2 | ||
|
||
### Release date: | ||
|
||
2020/03/01 | ||
|
||
### Changes: | ||
|
||
- Introduce `Loader#collect(Collector<? super T, A, R> collector)` | ||
|
||
## v0.0.1 | ||
|
||
### Release date: | ||
|
||
2019/08/13 | ||
|
||
### Changes: | ||
|
||
Initial release |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,8 +8,7 @@ | |
[![SonarCloud Maintainability][sonarcloud-badge-maintainability]][sonarcloud-measure-maintainability] | ||
[![BCH compliance][bettercodehub-badge]][bettercodehub-results] | ||
|
||
Short for _jOOQ Loader_. A utility library to add basic object-relation mapping | ||
to your [jOOQ][jooq] code. | ||
Short for _jOOQ Loader_. A utility library to add basic object-relation mapping to your [jOOQ][jooq] code. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason we are switching to unwrapped text? MarkDown is a lot easier to read in plaintext viewers if it's wrapped. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The text is still wrapped but IntelliJ defaults to a 120 character limit instead of 80. Let me check how other OSS projects handle that. |
||
|
||
![Picnic-jolo][jolo-image] | ||
|
||
|
@@ -21,42 +20,38 @@ Artifacts are hosted on [Maven's Central Repository][maven-central-browse]: | |
|
||
```groovy | ||
dependencies { | ||
compile 'tech.picnic.jolo:jolo:0.0.1' | ||
compile 'tech.picnic.jolo:jolo:0.0.3' | ||
} | ||
``` | ||
|
||
### Maven | ||
|
||
```xml | ||
|
||
<dependency> | ||
<groupId>tech.picnic.jolo</groupId> | ||
<artifactId>jolo</artifactId> | ||
<version>0.0.1</version> | ||
<groupId>tech.picnic.jolo</groupId> | ||
<artifactId>jolo</artifactId> | ||
<version>0.0.3</version> | ||
</dependency> | ||
``` | ||
|
||
## Features | ||
|
||
- Easy specification of relations between entities using a chaining API. | ||
- Object instantiation using jOOQ's native "into" method; the loader can | ||
additionally call setters to instantiate relationships between entities. | ||
- Performs foreign key checks to see whether the defined relationships make | ||
sense. | ||
- Extra checks on field names of returned records to prevent loading fields | ||
from one table as fields of another (no implicit conversion of `FOO.FIELD` to | ||
`BAR.FIELD`). | ||
- Implements `java.util.stream.Collector` allowing object instantiation using jOOQ's native "collect" method; the loader | ||
can additionally call setters to instantiate relationships between entities. | ||
- Performs foreign key checks to see whether the defined relationships make sense. | ||
- Extra checks on field names of returned records to prevent loading fields from one table as fields of another (no | ||
implicit conversion of `FOO.FIELD` to `BAR.FIELD`). | ||
- Supports circular references. | ||
- Supports adding extra (non-table) fields to entities. | ||
|
||
## Limitations | ||
|
||
- Only primary / foreign keys of (Java) type `long` are supported. We have no | ||
intention to support composite foreign keys for the time being. For keys of | ||
different types (e.g. `String`) we would accept pull requests, but only if | ||
this does not further complicate the interface of the library (no long type | ||
parameter lists). | ||
- Relation mapping does not work yet for entities that are not based on a table | ||
in the DB schema. | ||
- Only primary / foreign keys of (Java) type `long` are supported. We have no intention to support composite foreign | ||
keys for the time being. For keys of different types (e.g. `String`) we would accept pull requests, but only if this | ||
does not further complicate the interface of the library (no long type parameter lists). | ||
- Relation mapping does not work yet for entities that are not based on a table in the DB schema. | ||
|
||
## Example usage | ||
|
||
|
@@ -76,8 +71,7 @@ CREATE TABLE Flea ( | |
) | ||
``` | ||
|
||
And in Java you have modelled your dogs and fleas using POJOs that are serialisable using | ||
standard jOOQ functionality: | ||
And in Java you have modelled your dogs and fleas using POJOs that are serialisable using standard jOOQ functionality: | ||
|
||
```java | ||
class Dog { | ||
|
@@ -110,22 +104,20 @@ Using this library, you can specify how to instantiate the relationship between | |
(i.e., how to fill the `fleas` property of `Dog`): | ||
|
||
```java | ||
LoaderFactory<Dog> createLoaderFactory() { | ||
var dog = new Entity<>(Tables.DOG, Dog.class); | ||
var flea = new Entity<>(Tables.FLEA, Flea.class); | ||
return LoaderFactory.create(dog) | ||
.oneToMany(dog, flea) | ||
.setManyLeft(Dog::setFleas) | ||
.build(); | ||
class LoaderUtil { | ||
static Loader<Dog> createLoader() { | ||
var dog = new Entity<>(Tables.DOG, Dog.class); | ||
var flea = new Entity<>(Tables.FLEA, Flea.class); | ||
return Loader.of(dog).oneToMany(dog, flea).setManyLeft(Dog::setFleas).build(); | ||
} | ||
} | ||
``` | ||
|
||
Then in the code that executes the query, you can use the loader to instantiate | ||
and link POJO classes: | ||
Then in the code that executes the query, you can use the loader to instantiate and link POJO classes: | ||
|
||
```java | ||
class Repository { | ||
private static final LoaderFactory<Dog> LOADER_FACTORY = createLoaderFactory(); | ||
private static final Loader<Dog> LOADER = createLoader(); | ||
|
||
private final DSLContext context; | ||
|
||
|
@@ -134,8 +126,7 @@ class Repository { | |
.from(DOG) | ||
.leftJoin(FLEA) | ||
.on(FLEA.DOG_ID.eq(DOG.ID)) | ||
.fetchInto(LOADER_FACTORY.newLoader()) | ||
.get(); | ||
.collect(toLinkedObjectsWith(LOADER)); | ||
|
||
for (Dog dog : dogs) { | ||
int fleaWeight = dog.getFleas().stream().mapToInt(Flea::getWeight).sum(); | ||
|
@@ -152,11 +143,9 @@ class Repository { | |
Contributions are welcome! Feel free to file an [issue][new-issue] or open a | ||
[pull request][new-pr]. | ||
|
||
When submitting changes, please make every effort to follow existing | ||
conventions and style in order to keep the code as readable as possible. New | ||
code must be covered by tests. As a rule of thumb, overall test coverage should | ||
not decrease. (There are exceptions to this rule, e.g. when more code is | ||
deleted than added.) | ||
When submitting changes, please make every effort to follow existing conventions and style in order to keep the code as | ||
readable as possible. New code must be covered by tests. As a rule of thumb, overall test coverage should not | ||
decrease. (There are exceptions to this rule, e.g. when more code is deleted than added.) | ||
|
||
[bettercodehub-badge]: https://bettercodehub.com/edge/badge/PicnicSupermarket/jolo?branch=master | ||
[bettercodehub-results]: https://bettercodehub.com/results/PicnicSupermarket/jolo | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>tech.picnic</groupId> | ||
<artifactId>oss-parent</artifactId> | ||
<version>0.0.2</version> | ||
<version>0.0.3</version> | ||
</parent> | ||
|
||
<groupId>tech.picnic.jolo</groupId> | ||
|
@@ -24,6 +25,11 @@ | |
<organization>Picnic Technologies BV</organization> | ||
<timezone>Europe/Amsterdam</timezone> | ||
</developer> | ||
<developer> | ||
<name>Ferdinand Swoboda</name> | ||
<email>[email protected]</email> | ||
<timezone>Europe/Amsterdam</timezone> | ||
</developer> | ||
<developer> | ||
<name>Ivan Babiankou</name> | ||
<email>[email protected]</email> | ||
|
@@ -71,7 +77,15 @@ | |
</ciManagement> | ||
|
||
<properties> | ||
<version.immutables>2.8.3</version.immutables> | ||
<version.immutables>2.8.8</version.immutables> | ||
<version.jdk>11</version.jdk> | ||
<version.jooq>3.15.3</version.jooq> | ||
<version.maven>3.8.1</version.maven> | ||
<version.error-prone>2.9.0</version.error-prone> | ||
<version.error-prone-javac>10+23</version.error-prone-javac> | ||
<version.guava-beta-checker>1.0</version.guava-beta-checker> | ||
<version.nullaway>0.9.2</version.nullaway> | ||
<version.jmh>1.33</version.jmh> | ||
</properties> | ||
|
||
<dependencyManagement> | ||
|
@@ -81,6 +95,11 @@ | |
<artifactId>javax.annotation-api</artifactId> | ||
<version>1.3.2</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
<version>31.0.1-jre</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.immutables</groupId> | ||
<artifactId>value-annotations</artifactId> | ||
|
@@ -125,6 +144,17 @@ | |
<artifactId>junit-jupiter-engine</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.openjdk.jmh</groupId> | ||
<artifactId>jmh-core</artifactId> | ||
<version>${version.jmh}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.openjdk.jmh</groupId> | ||
<artifactId>jmh-generator-annprocess</artifactId> | ||
<version>${version.jmh}</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
|
@@ -149,6 +179,7 @@ | |
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>${version.maven}</version> | ||
<configuration> | ||
<annotationProcessorPaths> | ||
<path> | ||
|
@@ -159,7 +190,12 @@ | |
<path> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
<version>28.2-jre</version> | ||
<version>31.0.1-jre</version> | ||
</path> | ||
<path> | ||
<groupId>org.openjdk.jmh</groupId> | ||
<artifactId>jmh-generator-annprocess</artifactId> | ||
<version>${version.jmh}</version> | ||
</path> | ||
</annotationProcessorPaths> | ||
</configuration> | ||
|
@@ -192,7 +228,9 @@ | |
code, so we must take care to exclude it during the | ||
Javadoc generation process. Flag this issue with jOOQ | ||
to get it resolved. --> | ||
<sourcepath>${project.basedir}/src/main/java:${project.build.directory}/generated-sources/annotations</sourcepath> | ||
<sourcepath> | ||
${project.basedir}/src/main/java:${project.build.directory}/generated-sources/annotations | ||
</sourcepath> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
|
@@ -263,8 +301,10 @@ | |
<forcedTypes> | ||
<forcedType> | ||
<userType>Long[]</userType> | ||
<expression>.*\.RELATEDFOOIDS</expression> | ||
<converter>org.jooq.Converter.ofNullable(Object[].class, Long[].class, i -> (Long[])i, i -> i)</converter> | ||
<includeExpression>.*\.RELATEDFOOIDS</includeExpression> | ||
<converter>org.jooq.Converter.ofNullable(Object[].class, Long[].class, i -> | ||
(Long[])i, i -> i) | ||
</converter> | ||
</forcedType> | ||
</forcedTypes> | ||
</database> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Obviously wishful thinking