Compare commits

...

38 Commits

Author SHA1 Message Date
9160b13c94
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-14 14:44:35 +03:00
6b99189f1d
[maven-release-plugin] prepare release v.1.4.0
All checks were successful
continuous-integration/drone/tag Build is passing
2024-10-14 14:44:35 +03:00
c30bcfa3bb
Удалил лишние методы 2024-10-14 14:43:31 +03:00
601608998e
Merge remote-tracking branch 'mkorotkiy/feature/add-multi-join-field' into update 2024-10-14 14:30:46 +03:00
mkorotkiy
2f51b899be Добавлена возможность указывать нескольких полей для join-а таблицы. 2024-10-11 11:04:47 +03:00
f11d7c9cad
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2024-06-24 15:51:40 +03:00
83a147537d
[maven-release-plugin] prepare release v.1.3.1
All checks were successful
continuous-integration/drone/tag Build is passing
2024-06-24 15:51:40 +03:00
4748a86037
update dependencies version
All checks were successful
continuous-integration/drone/push Build is passing
2024-06-24 15:50:11 +03:00
139db325a9
[maven-release-plugin] prepare for next development iteration
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-14 13:54:56 +03:00
ad20e9b882
[maven-release-plugin] prepare release v.1.3.0
Some checks failed
continuous-integration/drone/tag Build is failing
2024-06-14 13:54:56 +03:00
f283075ce9
Добавлен Jsonb
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-14 13:50:23 +03:00
519a581615
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2024-03-13 13:26:01 +03:00
01b14d0034
[maven-release-plugin] prepare release v.1.2.4 2024-03-13 13:26:01 +03:00
274fbad537
fix cicd 2024-03-13 13:25:40 +03:00
1d0d5349e5
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2024-03-13 13:23:05 +03:00
b06af5c4b5
[maven-release-plugin] prepare release v.1.2.3 2024-03-13 13:23:05 +03:00
675a0f2beb
fix cicd 2024-03-13 13:22:49 +03:00
6d3156a6ba
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2024-03-13 13:21:16 +03:00
0d5fba747f
[maven-release-plugin] prepare release v.1.2.2 2024-03-13 13:21:16 +03:00
4d0a9df13e
fix cicd 2024-03-13 13:21:02 +03:00
8a0b0f7906
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2024-03-13 13:18:18 +03:00
cce9d720df
[maven-release-plugin] prepare release v.1.2.1 2024-03-13 13:18:18 +03:00
ae596abd66
fix cicd
All checks were successful
continuous-integration/drone/push Build is passing
2024-03-13 13:17:47 +03:00
7152c683d4
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2024-03-13 13:11:58 +03:00
7be9508ffb
[maven-release-plugin] prepare release v.1.2.0 2024-03-13 13:11:58 +03:00
2e0039adcb
Add null order handling to SortContainer
A new enum NullOrderType was added and integrated into the SortContainer class to handle sorting nulls. The CriteriaJooqFilter's sorting methods were updated to use this new functionality as well, which enables the user to specify the nulls order (first or last) when sorting fields.
2024-03-13 13:10:24 +03:00
40302fb406
update cicd
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-03 09:55:09 +03:00
e774a9418a
update cicd
Some checks are pending
continuous-integration/drone/push Build is pending
2023-12-03 09:54:47 +03:00
9fb304e13c
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-17 23:08:25 +03:00
3aa37a27f2
[maven-release-plugin] prepare release v.1.1.0 2023-05-17 23:08:25 +03:00
2a5859d1c4
Переход на quarkus 3 2023-05-17 23:07:37 +03:00
6ffe36388f
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-11 12:52:42 +03:00
799db2897e
[maven-release-plugin] prepare release v.1.0.0 2023-05-11 12:52:41 +03:00
ffae50d28e
Настройка cicd 2023-05-11 12:48:51 +03:00
24df33a6b3
Добавил возможность использовать not операции 2023-05-11 10:43:13 +03:00
2b5d5ce9f6 Поправил seek пагинацию 2022-12-07 09:27:06 +03:00
3869a4f418 v.0.7.0 2022-11-30 21:07:16 +03:00
Struchkov Mark
1b89feade7 InitNextRelease 2022-04-02 11:19:44 +03:00
12 changed files with 553 additions and 150 deletions

109
.drone.yml Normal file
View File

@ -0,0 +1,109 @@
---
kind: pipeline
type: docker
name: snapshot-publish
trigger:
branch:
- develop
volumes:
- name: m2
host:
path: /drone/volume/m2
steps:
- name: publish
image: hub.docker.struchkov.dev/maven:3.9.5-eclipse-temurin-17-alpine
privileged: true
volumes:
- name: m2
path: /root/.m2/repository
environment:
MAVEN_SETTINGS:
from_secret: MAVEN_SETTINGS
commands:
- echo "$MAVEN_SETTINGS" >> maven-settings.xml
- mvn --settings maven-settings.xml -U -P snapshot clean deploy
image_pull_secrets:
- DOCKER_AUTH
---
kind: pipeline
type: docker
name: release-maven-central
trigger:
ref:
- refs/tags/v.*.*.*
volumes:
- name: m2
host:
path: /drone/volume/m2
steps:
- name: publish maven central
image: hub.docker.struchkov.dev/maven:3.9.5-eclipse-temurin-17-alpine
privileged: true
volumes:
- name: m2
path: /root/.m2/repository
environment:
GPG_PRIVATE_KEY:
from_secret: GPG_PRIVATE_KEY
MAVEN_SETTINGS:
from_secret: MAVEN_SETTINGS
GPG_PASSPHRASE:
from_secret: GPG_PASSPHRASE
commands:
- apk add --no-cache gnupg
- echo "$GPG_PRIVATE_KEY" >> gpg.key
- echo "$MAVEN_SETTINGS" >> maven-settings.xml
- gpg --pinentry-mode loopback --passphrase $GPG_PASSPHRASE --import gpg.key
- mvn --settings maven-settings.xml -U -P ossrh,release clean deploy
image_pull_secrets:
- DOCKER_AUTH
---
kind: pipeline
type: docker
name: release-struchkov-nexus
trigger:
ref:
- refs/tags/v.*.*.*
volumes:
- name: m2
host:
path: /drone/volume/m2
steps:
- name: publish struchkov nexus
image: hub.docker.struchkov.dev/maven:3.9.5-eclipse-temurin-17-alpine
privileged: true
volumes:
- name: m2
path: /root/.m2/repository
environment:
GPG_PRIVATE_KEY:
from_secret: GPG_PRIVATE_KEY
MAVEN_SETTINGS:
from_secret: MAVEN_SETTINGS
GPG_PASSPHRASE:
from_secret: GPG_PASSPHRASE
commands:
- apk add --no-cache gnupg
- echo "$GPG_PRIVATE_KEY" >> gpg.key
- echo "$MAVEN_SETTINGS" >> maven-settings.xml
- gpg --pinentry-mode loopback --passphrase $GPG_PASSPHRASE --import gpg.key
- mvn --settings maven-settings.xml -U -P ossrh,release-struchkov-nexus clean deploy
image_pull_secrets:
- DOCKER_AUTH
---
kind: signature
hmac: 2288dcbae543b712c60d1e1a5b7cc513a06515939d45bf77237e79642b406048
...

18
.gitignore vendored
View File

@ -20,21 +20,7 @@ dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
.idea/**/contentModel.xml
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
.idea/**/gradle.xml
.idea/**/libraries
.idea/
cmake-build-*/
.idea/**/mongoSettings.xml
*.iws
@ -46,8 +32,6 @@ com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
.idea/httpRequests
.idea/caches/build_file_checksums.ser
*~
.fuse_hidden*
.directory

View File

@ -1,17 +0,0 @@
image: maven:3.8.4-openjdk-11
variables:
MAVEN_OPTS: "-Dmaven.repo.local=./.m2/repository"
stages:
- deploy
deploy:
stage: deploy
only:
- /^v.*$/
except:
- branches
before_script:
- gpg --pinentry-mode loopback --passphrase $GPG_PASSPHRASE --import $GPG_PRIVATE_KEY
script:
- 'mvn --settings $MAVEN_SETTINGS -U -P ossrh,release clean deploy'

158
pom.xml
View File

@ -1,12 +1,10 @@
<?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 http://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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dev.struchkov.haiti.filter</groupId>
<artifactId>haiti-filter-jooq</artifactId>
<version>0.5.0</version>
<version>1.4.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Haiti Filter JOOQ</name>
@ -24,26 +22,37 @@
</issueManagement>
<properties>
<java.version>11</java.version>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<jooq.version>3.15.6</jooq.version>
<!-- https://mvnrepository.com/artifact/org.jooq/jooq -->
<jooq.version>3.18.4</jooq.version>
<plugin.nexus.staging.ver>1.6.8</plugin.nexus.staging.ver>
<plugin.maven.source.ver>3.2.1</plugin.maven.source.ver>
<plugin.maven.javadoc.ver>3.3.1</plugin.maven.javadoc.ver>
<plugin.maven.gpg.ver>3.0.1</plugin.maven.gpg.ver>
<haiti.version>3.0.3</haiti.version>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin -->
<plugin.maven.compiler.ver>3.13.0</plugin.maven.compiler.ver>
<!-- https://mvnrepository.com/artifact/org.sonatype.plugins/nexus-staging-maven-plugin -->
<plugin.nexus.staging.ver>1.7.0</plugin.nexus.staging.ver>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-source-plugin -->
<plugin.maven.source.ver>3.3.1</plugin.maven.source.ver>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-javadoc-plugin -->
<plugin.maven.javadoc.ver>3.7.0</plugin.maven.javadoc.ver>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-gpg-plugin -->
<plugin.maven.gpg.ver>3.2.4</plugin.maven.gpg.ver>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-release-plugin -->
<plugin.maven.release.ver>3.1.0</plugin.maven.release.ver>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.struchkov.haiti</groupId>
<artifactId>haiti-bom</artifactId>
<version>1.0.0</version>
<artifactId>haiti-dependencies</artifactId>
<version>${haiti.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -69,6 +78,28 @@
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${plugin.maven.compiler.ver}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>${plugin.maven.release.ver}</version>
<configuration>
<preparationGoals>clean install</preparationGoals>
<tagNameFormat>v.@{project.version}</tagNameFormat>
<autoVersionSubmodules>true</autoVersionSubmodules>
<pushChanges>false</pushChanges>
<localCheckout>true</localCheckout>
<signTag>true</signTag>
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
@ -133,10 +164,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@ -162,32 +189,117 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>release-struchkov-nexus</id>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<configuration>
<serverId>struchkov-nexus</serverId>
<nexusUrl>https://nexus.struchkov.dev/nexus/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
<skipStaging>true</skipStaging>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>snapshot</id>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<configuration>
<serverId>struchkov-nexus</serverId>
<nexusUrl>https://nexus.struchkov.dev/nexus/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories>
<repository>
<id>struchkov-nexus-release</id>
<url>https://nexus.struchkov.dev/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>struchkov-nexus-snapshot</id>
<url>https://nexus.struchkov.dev/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>struchkov-nexus-release</id>
<url>https://nexus.struchkov.dev/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>struchkov-nexus-snapshot</id>
<url>https://nexus.struchkov.dev/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<scm>
<connection>scm:git:https://github.com/haiti-projects/haiti-filter-jooq.git</connection>
<url>https://github.com/haiti-projects/haiti-filter-jooq</url>
<developerConnection>scm:git:https://github.com/haiti-projects/haiti-filter-jooq.git</developerConnection>
<tag>HEAD</tag>
</scm>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<developers>
<developer>
<id>uPagge</id>

View File

@ -5,9 +5,10 @@ import dev.struchkov.haiti.filter.jooq.join.JoinTable;
import dev.struchkov.haiti.filter.jooq.join.JoinTypeOperation;
import dev.struchkov.haiti.filter.jooq.page.PageableOffset;
import dev.struchkov.haiti.filter.jooq.page.PageableSeek;
import dev.struchkov.haiti.filter.jooq.sort.NullOrderType;
import dev.struchkov.haiti.filter.jooq.sort.SortContainer;
import dev.struchkov.haiti.filter.jooq.sort.SortType;
import dev.struchkov.haiti.utils.Assert;
import dev.struchkov.haiti.utils.Inspector;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Field;
@ -30,10 +31,12 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static dev.struchkov.haiti.filter.jooq.exception.FilterJooqHaitiException.filterJooqException;
import static java.util.stream.Collectors.toList;
import static org.jooq.impl.DSL.condition;
import static org.jooq.impl.DSL.field;
@ -41,7 +44,6 @@ public class CriteriaJooqFilter {
private final List<Condition> andConditions = new ArrayList<>();
private final List<Condition> orConditions = new ArrayList<>();
private final List<Condition> notConditions = new ArrayList<>();
private final List<JoinTable> joinTables = new ArrayList<>();
private final Table<Record> generalTable;
@ -85,27 +87,16 @@ public class CriteriaJooqFilter {
return this;
}
// FIXME: Добавить поддержку
// public CriteriaJooqFilter not(FilterQuery filterQuery) {
// throw new IllegalStateException("Операция отрицания пока не поддерживается");
// }
// FIXME: Добавить поддержку
// public CriteriaJooqFilter not(Consumer<FilterQuery> query) {
// throw new IllegalStateException("Операция отрицания пока не поддерживается");
// }
public CriteriaJooqFilter page(PageableOffset offset) {
Assert.isNotNull(offset);
Assert.isNull(seek, filterJooqException("Нельзя установить два типа пагинации одновременно"));
Inspector.isNotNull(offset);
Inspector.isNull(seek, filterJooqException("Нельзя установить два типа пагинации одновременно"));
this.offset = offset;
return this;
}
public CriteriaJooqFilter page(PageableSeek seek) {
Assert.isNotNull(seek);
Assert.isNull(offset, filterJooqException("Нельзя установить два типа пагинации одновременно"));
Inspector.isNotNull(seek);
Inspector.isNull(offset, filterJooqException("Нельзя установить два типа пагинации одновременно"));
this.seek = seek;
return this;
}
@ -124,6 +115,13 @@ public class CriteriaJooqFilter {
return this;
}
public CriteriaJooqFilter sort(String field, SortType sortType, NullOrderType nullsOrder) {
if (field != null) {
this.sorts.add(SortContainer.of(field, sortType, nullsOrder));
}
return this;
}
public CriteriaJooqFilter sort(String field) {
if (field != null) {
this.sorts.add(SortContainer.of(field));
@ -153,8 +151,8 @@ public class CriteriaJooqFilter {
}
public CriteriaJooqFilter join(JoinTable... joinTables) {
Assert.isNotNull(joinTables);
this.joinTables.addAll(Arrays.stream(joinTables).collect(Collectors.toList()));
Inspector.isNotNull(joinTables);
this.joinTables.addAll(Arrays.stream(joinTables).collect(toList()));
return this;
}
@ -167,7 +165,7 @@ public class CriteriaJooqFilter {
}
public Query generateQuery(String... fields) {
final List<Field<Object>> selectFields = Arrays.stream(fields).map(DSL::field).collect(Collectors.toList());
final List<Field<Object>> selectFields = Arrays.stream(fields).map(DSL::field).collect(toList());
final SelectSelectStep<Record> mainSelect = !selectFields.isEmpty() ? dsl.select(selectFields) : dsl.select();
final SelectLimitStep<? extends Record> selectSeekStepN = generate(mainSelect);
return setPaginationOffset(selectSeekStepN);
@ -189,7 +187,9 @@ public class CriteriaJooqFilter {
private SelectLimitStep<? extends Record> getOrderBy(SelectHavingStep<? extends Record> groupBy) {
if (!sorts.isEmpty()) {
return groupBy.orderBy(getOrderBy());
final SelectSeekStepN<? extends Record> sort = groupBy.orderBy(getOrderBy());
setPaginationSeek(sort);
return sort;
}
return groupBy;
}
@ -199,7 +199,7 @@ public class CriteriaJooqFilter {
return where.groupBy(
groupByFields.stream()
.map(DSL::field)
.collect(Collectors.toList())
.collect(toList())
);
}
return where;
@ -209,24 +209,34 @@ public class CriteriaJooqFilter {
if (!joinTables.isEmpty()) {
for (JoinTable joinTable : joinTables) {
final String tableName = joinTable.getTableName();
String fieldBase = joinTable.getFieldBase();
String fieldReference = joinTable.getFieldReference();
Table<Record> dlsJoinTableName = DSL.table(tableName);
if (joinTable.getAlias() != null) {
dlsJoinTableName = dlsJoinTableName.as(joinTable.getAlias());
fieldReference = joinTable.getAlias() + "." + fieldReference;
} else {
fieldReference = tableName + "." + fieldReference;
}
final Set<Condition> joinConditions = joinTable.getFieldReferences().stream()
.map(reference -> {
String fieldBase = reference.getBaseField();
String fieldReference = reference.getReferenceField();
if (joinTable.getAlias() != null) {
fieldReference = joinTable.getAlias() + "." + fieldReference;
} else {
fieldReference = tableName + "." + fieldReference;
}
final Field dslFieldBase = field(fieldBase);
final Field dslFieldReference = field(fieldReference);
return dslFieldBase.eq(dslFieldReference);
})
.collect(Collectors.toSet());
final JoinTypeOperation joinType = joinTable.getJoinTypeOperation();
final Field dslFieldBase = field(fieldBase);
final Field dslFieldReference = field(fieldReference);
final Condition on = dslFieldBase.eq(dslFieldReference);
final Condition on = DSL.and(joinConditions);
switch (joinType) {
case LEFT:
from = from.leftJoin(dlsJoinTableName).on(on);
@ -258,12 +268,14 @@ public class CriteriaJooqFilter {
if (!sorts.isEmpty()) {
final List<SortField<Object>> newSorts = new ArrayList<>();
for (SortContainer sort : sorts) {
final NullOrderType nullOrderType = sort.getNullOrderType();
final SortType sortType = sort.getType();
final String fieldName = sort.getFieldName();
if (SortType.ASC.equals(sortType)) {
newSorts.add(field(fieldName).asc());
final SortField<Object> sortField = SortType.ASC.equals(sortType) ? field(fieldName).asc() : field(fieldName).desc();
if (NullOrderType.LAST.equals(nullOrderType)) {
newSorts.add(sortField.nullsLast());
} else {
newSorts.add(field(fieldName).desc());
newSorts.add(sortField.nullsFirst());
}
}
return newSorts;
@ -273,18 +285,16 @@ public class CriteriaJooqFilter {
private void setPaginationSeek(SelectSeekStepN<? extends Record> sort) {
if (seek != null) {
Assert.isNotNull(sort, () -> new FilterJooqHaitiException("При использовании пагинации типа seek необходимо указать сортировку"));
Inspector.isNotNull(() -> new FilterJooqHaitiException("При использовании пагинации типа seek необходимо указать сортировку"), sort);
final Integer pageSize = seek.getPageSize();
final Object lastId = seek.getLastId();
if (pageSize != null) {
if (lastId != null) {
sort
.seek(lastId)
.limit(pageSize);
} else {
sort
.limit(pageSize);
}
final Object[] values = seek.getValues();
if (values != null) {
sort
.seek(values)
.limit(pageSize);
} else {
sort
.limit(pageSize);
}
}
}

View File

@ -1,6 +1,6 @@
package dev.struchkov.haiti.filter.jooq;
import dev.struchkov.haiti.utils.Assert;
import dev.struchkov.haiti.utils.Inspector;
import org.jooq.Condition;
import org.jooq.Field;
import org.jooq.impl.DSL;
@ -10,6 +10,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
import static org.jooq.impl.DSL.condition;
import static org.jooq.impl.DSL.field;
@ -26,7 +27,7 @@ public class CriteriaJooqQuery {
}
public <Y extends Comparable<? super Y>> CriteriaJooqQuery between(String field, Y from, Y to) {
Assert.isNotNull(field);
Inspector.isNotNull(field);
if (from != null && to != null) {
Condition condition = DSL.field(field).between(from, to);
conditions.add(condition);
@ -34,8 +35,17 @@ public class CriteriaJooqQuery {
return this;
}
public <Y extends Comparable<? super Y>> CriteriaJooqQuery notBetween(String field, Y from, Y to) {
Inspector.isNotNull(field);
if (from != null && to != null) {
Condition condition = DSL.field(field).notBetween(from, to);
conditions.add(condition);
}
return this;
}
public CriteriaJooqQuery matchPhrase(String field, Object value) {
Assert.isNotNull(field);
Inspector.isNotNull(field);
if (value != null) {
final Condition condition = condition(Map.of(field(field), value));
conditions.add(condition);
@ -43,8 +53,16 @@ public class CriteriaJooqQuery {
return this;
}
public CriteriaJooqQuery matchPhrase(String field, Object... values) {
Inspector.isNotNull(field);
if (checkNotEmpty(values)) {
conditions.add(DSL.field(field).in(values));
}
return this;
}
public <U> CriteriaJooqQuery matchPhrase(String field, Set<U> values) {
Assert.isNotNull(field);
Inspector.isNotNull(field);
if (values != null) {
if (values.isEmpty()) {
conditions.add(DSL.field(field).isNull());
@ -55,6 +73,35 @@ public class CriteriaJooqQuery {
return this;
}
public CriteriaJooqQuery notMatchPhrase(String field, Object value) {
Inspector.isNotNull(field);
if (value != null) {
final Condition condition = condition(Map.of(field(field), value)).not();
conditions.add(condition);
}
return this;
}
public <U> CriteriaJooqQuery notMatchPhrase(String field, Set<U> values) {
Inspector.isNotNull(field);
if (values != null) {
if (values.isEmpty()) {
conditions.add(DSL.field(field).isNull().not());
} else {
conditions.add(DSL.field(field).in(values).not());
}
}
return this;
}
public CriteriaJooqQuery notMatchPhrase(String field, Object... values) {
Inspector.isNotNull(field);
if (checkNotEmpty(values)) {
conditions.add(DSL.field(field).in(values).not());
}
return this;
}
public CriteriaJooqQuery exists(String field) {
if (field != null) {
conditions.add(DSL.field(field).isNotNull());
@ -62,6 +109,13 @@ public class CriteriaJooqQuery {
return this;
}
public CriteriaJooqQuery notExists(String field) {
if (field != null) {
conditions.add(DSL.field(field).isNull());
}
return this;
}
public CriteriaJooqQuery like(String field, String value) {
like(field, value, false);
return this;
@ -72,8 +126,18 @@ public class CriteriaJooqQuery {
return this;
}
public CriteriaJooqQuery notLike(String field, String value) {
notLike(field, value, false);
return this;
}
public CriteriaJooqQuery notLikeIgnoreCase(String field, String value) {
notLike(field, value, true);
return this;
}
public CriteriaJooqQuery like(String field, String value, boolean ignoreCase) {
Assert.isNotNull(field);
Inspector.isNotNull(field);
final Field<Object> query = field(field);
if (value != null) {
if (ignoreCase) {
@ -85,4 +149,17 @@ public class CriteriaJooqQuery {
return this;
}
public CriteriaJooqQuery notLike(String field, String value, boolean ignoreCase) {
Inspector.isNotNull(field);
final Field<Object> query = field(field);
if (value != null) {
if (ignoreCase) {
conditions.add(query.likeIgnoreCase(value).not());
} else {
conditions.add(query.like(value).not());
}
}
return this;
}
}

View File

@ -0,0 +1,31 @@
package dev.struchkov.haiti.filter.jooq.join;
import java.util.Set;
public class JoinFieldReference {
private final String baseField;
private final String referenceField;
public JoinFieldReference(String baseField, String referenceField) {
this.baseField = baseField;
this.referenceField = referenceField;
}
public String getBaseField() {
return baseField;
}
public String getReferenceField() {
return referenceField;
}
public static JoinFieldReference of(String baseField, String referenceField) {
return new JoinFieldReference(baseField, referenceField);
}
public static Set<JoinFieldReference> ofSingletonSet(String baseField, String referenceField) {
return Set.of(new JoinFieldReference(baseField, referenceField));
}
}

View File

@ -1,6 +1,10 @@
package dev.struchkov.haiti.filter.jooq.join;
import dev.struchkov.haiti.utils.Assert;
import dev.struchkov.haiti.utils.Inspector;
import java.util.Set;
import static dev.struchkov.haiti.filter.jooq.exception.FilterJooqHaitiException.filterJooqException;
/**
* Контейнер для соединения с таблицами.
@ -10,59 +14,87 @@ import dev.struchkov.haiti.utils.Assert;
public class JoinTable {
private final String tableName;
private final String fieldBase;
private final String fieldReference;
private final Set<JoinFieldReference> fieldReferences;
private final JoinTypeOperation joinTypeOperation;
private String alias;
private JoinTable(String tableName, String fieldBase, String fieldReference, JoinTypeOperation joinTypeOperation, String alias) {
private JoinTable(String tableName, JoinTypeOperation joinTypeOperation, Set<JoinFieldReference> fieldReferences, String alias) {
this.tableName = tableName;
this.fieldBase = fieldBase;
this.fieldReference = fieldReference;
this.joinTypeOperation = joinTypeOperation;
this.fieldReferences = fieldReferences;
this.alias = alias;
}
public static JoinTable ofLeft(String tableName, String fieldBase, String fieldReference) {
Assert.isNotNull(tableName, fieldBase, fieldReference);
return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.LEFT, null);
Inspector.isNotNull(tableName, fieldBase, fieldReference);
return new JoinTable(tableName, JoinTypeOperation.LEFT, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), null);
}
public static JoinTable ofLeft(String tableName, Set<JoinFieldReference> fieldReferences) {
Inspector.isNotNull(tableName, fieldReferences);
Inspector.isNotEmpty(fieldReferences, filterJooqException("fieldReferences is empty: {0}", fieldReferences));
return new JoinTable(tableName, JoinTypeOperation.LEFT, fieldReferences, null);
}
public static JoinTable ofLeft(String tableName, String fieldBase, String fieldReference, String alias) {
Assert.isNotNull(tableName, fieldBase, fieldReference, alias);
return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.LEFT, alias);
Inspector.isNotNull(tableName, fieldBase, fieldReference, alias);
return new JoinTable(tableName, JoinTypeOperation.LEFT, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), alias);
}
public static JoinTable ofLeft(String tableName, Set<JoinFieldReference> fieldReferences, String alias) {
Inspector.isNotNull(tableName, fieldReferences, alias);
Inspector.isNotEmpty(fieldReferences, filterJooqException("fieldReferences is empty: {0}", fieldReferences));
return new JoinTable(tableName, JoinTypeOperation.LEFT, fieldReferences, alias);
}
public static JoinTable onRight(String tableName, String fieldBase, String fieldReference) {
Assert.isNotNull(tableName, fieldBase, fieldReference);
return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.RIGHT, null);
Inspector.isNotNull(tableName, fieldBase, fieldReference);
return new JoinTable(tableName, JoinTypeOperation.RIGHT, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), null);
}
public static JoinTable onRight(String tableName, Set<JoinFieldReference> fieldReferences) {
Inspector.isNotNull(tableName, fieldReferences);
Inspector.isNotEmpty(fieldReferences, filterJooqException("fieldReferences is empty: {0}", fieldReferences));
return new JoinTable(tableName, JoinTypeOperation.RIGHT, fieldReferences, null);
}
public static JoinTable onRight(String tableName, String fieldBase, String fieldReference, String alias) {
Assert.isNotNull(tableName, fieldBase, fieldReference, alias);
return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.RIGHT, alias);
Inspector.isNotNull(tableName, fieldBase, fieldReference, alias);
return new JoinTable(tableName, JoinTypeOperation.RIGHT, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), alias);
}
public static JoinTable onRight(String tableName, Set<JoinFieldReference> fieldReferences, String alias) {
Inspector.isNotNull(tableName, fieldReferences, alias);
Inspector.isFalse(fieldReferences.isEmpty(), filterJooqException("fieldReferences is empty: {0}", fieldReferences));
return new JoinTable(tableName, JoinTypeOperation.RIGHT, fieldReferences, alias);
}
public static JoinTable of(String tableName, String fieldBase, String fieldReference, JoinTypeOperation joinType) {
Assert.isNotNull(tableName, fieldBase, fieldReference);
return new JoinTable(tableName, fieldBase, fieldReference, joinType, null);
Inspector.isNotNull(tableName, fieldBase, fieldReference);
return new JoinTable(tableName, joinType, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), null);
}
public static JoinTable of(String tableName, Set<JoinFieldReference> fieldReferences, JoinTypeOperation joinType) {
Inspector.isNotNull(tableName, fieldReferences);
return new JoinTable(tableName, joinType, fieldReferences, null);
}
public static JoinTable of(String tableName, String fieldBase, String fieldReference, JoinTypeOperation joinType, String alias) {
Assert.isNotNull(tableName, fieldBase, fieldReference, alias);
return new JoinTable(tableName, fieldBase, fieldReference, joinType, alias);
Inspector.isNotNull(tableName, fieldBase, fieldReference, alias);
return new JoinTable(tableName, joinType, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), alias);
}
public static JoinTable of(String tableName, Set<JoinFieldReference> fieldReferences, JoinTypeOperation joinType, String alias) {
Inspector.isNotNull(tableName, fieldReferences, alias);
return new JoinTable(tableName, joinType, fieldReferences, alias);
}
public String getTableName() {
return tableName;
}
public String getFieldBase() {
return fieldBase;
}
public String getFieldReference() {
return fieldReference;
public Set<JoinFieldReference> getFieldReferences() {
return fieldReferences;
}
public JoinTypeOperation getJoinTypeOperation() {

View File

@ -1,18 +1,20 @@
package dev.struchkov.haiti.filter.jooq.page;
import dev.struchkov.haiti.utils.Assert;
import dev.struchkov.haiti.utils.Inspector;
import static dev.struchkov.haiti.filter.jooq.exception.FilterJooqHaitiException.filterJooqException;
public class PageableSeek {
private final Object lastId;
private final Object[] values;
private int pageSize = 30;
private PageableSeek(Object lastId) {
this.lastId = lastId;
private PageableSeek(Object[] values) {
this.values = values;
}
private PageableSeek(Object lastId, int pageSize) {
this.lastId = lastId;
private PageableSeek(Object[] values, int pageSize) {
this.values = values;
this.pageSize = pageSize;
}
@ -20,22 +22,22 @@ public class PageableSeek {
return new PageableSeek(null);
}
public static PageableSeek of(int pageSize) {
public static PageableSeek ofPageSize(int pageSize) {
return new PageableSeek(null, pageSize);
}
public static PageableSeek of(Object lastId) {
Assert.isNotNull(lastId);
return new PageableSeek(lastId);
public static PageableSeek ofValues(Object... values) {
Inspector.isNotEmpty(filterJooqException("Переданы пустой набор данных для PageableSeek"), values);
return new PageableSeek(values);
}
public static PageableSeek of(Object lastId, int pageSize) {
Assert.isNotNull(lastId);
return new PageableSeek(lastId, pageSize);
public static PageableSeek ofPageSizeAndValues(int pageSize, Object... values) {
Inspector.isNotEmpty(filterJooqException("Переданы пустой набор данных для PageableSeek"), values);
return new PageableSeek(values, pageSize);
}
public Object getLastId() {
return lastId;
public Object[] getValues() {
return values;
}
public int getPageSize() {

View File

@ -0,0 +1,8 @@
package dev.struchkov.haiti.filter.jooq.sort;
public enum NullOrderType {
FIRST,
LAST
}

View File

@ -1,12 +1,13 @@
package dev.struchkov.haiti.filter.jooq.sort;
import dev.struchkov.haiti.utils.Assert;
import dev.struchkov.haiti.utils.Inspector;
public class SortContainer {
private final String fieldName;
private SortType type = SortType.ASC;
private NullOrderType nullOrderType = NullOrderType.LAST;
private SortContainer(String fieldName) {
this.fieldName = fieldName;
@ -17,16 +18,31 @@ public class SortContainer {
this.type = type;
}
private SortContainer(String fieldName, SortType type, NullOrderType nullsOrder) {
this.fieldName = fieldName;
this.type = type;
this.nullOrderType = nullsOrder;
}
public static SortContainer of(String fieldName) {
Assert.isNotNull(fieldName);
Inspector.isNotNull(fieldName);
return new SortContainer(fieldName);
}
public static SortContainer of(String fieldName, SortType sortType) {
Assert.isNotNull(fieldName);
Inspector.isNotNull(fieldName);
return new SortContainer(fieldName, sortType == null ? SortType.ASC : sortType);
}
public static SortContainer of(String fieldName, SortType sortType, NullOrderType nullOrderType) {
Inspector.isNotNull(fieldName);
return new SortContainer(
fieldName,
sortType == null ? SortType.ASC : sortType,
nullOrderType == null ? NullOrderType.LAST : nullOrderType
);
}
public String getFieldName() {
return fieldName;
}
@ -35,4 +51,8 @@ public class SortContainer {
return type;
}
public NullOrderType getNullOrderType() {
return nullOrderType;
}
}

View File

@ -0,0 +1,35 @@
package dev.struchkov.haiti.filter.jooq.utils;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static dev.struchkov.haiti.utils.Exceptions.utilityClass;
public final class Jsonb {
private Jsonb() {
utilityClass();
}
/**
* @param field - колонка в БД формата jsonb
* @param jsonField - поле в jsonb по которому будет выполняться операция фильтрации
*/
public static String jsonbField(String field, String jsonField) {
String sql;
if (jsonField.contains(".")) {
final List<String> hierarchyFields = Arrays.stream(jsonField.split("\\."))
.map(el -> "'" + el + "'")
.collect(Collectors.toList());
final String lastElement = hierarchyFields.remove(hierarchyFields.size() - 1);
final String fieldPath = String.join(" -> ", hierarchyFields) + " ->> " + lastElement;
sql = "(%s #>> '{}')::jsonb -> %s".formatted(field, fieldPath);
} else {
final String fieldPath = "'" + jsonField + "'";
sql = "(%s #>> '{}')::jsonb ->> %s".formatted(field, fieldPath);
}
return sql;
}
}