From 31c31a22e1d67205ac614bbdd3ea83565e1bef53 Mon Sep 17 00:00:00 2001 From: Struchkov Mark Date: Thu, 17 Feb 2022 16:21:26 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA?= =?UTF-8?q?=D0=B0=20Join?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 9 +- .../haiti/filter/jooq/CriteriaJooqFilter.java | 161 ++++++++++-------- .../haiti/filter/jooq/CriteriaJooqQuery.java | 4 +- .../haiti/filter/jooq/join/JoinTable.java | 5 + .../haiti/filter/jooq/utils/Likes.java | 28 +++ 5 files changed, 135 insertions(+), 72 deletions(-) create mode 100644 src/main/java/dev/struchkov/haiti/filter/jooq/utils/Likes.java diff --git a/pom.xml b/pom.xml index a01535e..9e97348 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.struchkov.haiti.filter haiti-filter-jooq - 0.4.0-SNAPSHOT + 0.5.0-SNAPSHOT jar Haiti Filter JOOQ @@ -24,8 +24,11 @@ - 11 - 11 + 11 + ${java.version} + ${java.version} + UTF-8 + UTF-8 3.15.6 diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java index a3b579e..a48005e 100644 --- a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java @@ -1,6 +1,8 @@ package dev.struchkov.haiti.filter.jooq; import dev.struchkov.haiti.filter.jooq.exception.FilterJooqHaitiException; +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.SortContainer; @@ -8,17 +10,28 @@ import dev.struchkov.haiti.filter.jooq.sort.SortType; import dev.struchkov.haiti.utils.Assert; import org.jooq.Condition; import org.jooq.DSLContext; +import org.jooq.Field; import org.jooq.Operator; import org.jooq.Query; import org.jooq.Record; +import org.jooq.Record1; import org.jooq.SelectConditionStep; +import org.jooq.SelectHavingStep; import org.jooq.SelectJoinStep; +import org.jooq.SelectLimitStep; import org.jooq.SelectSeekStepN; +import org.jooq.SelectSelectStep; import org.jooq.SortField; +import org.jooq.Table; +import org.jooq.impl.DSL; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; +import java.util.stream.Collectors; import static dev.struchkov.haiti.filter.jooq.exception.FilterJooqHaitiException.filterJooqException; import static org.jooq.impl.DSL.condition; @@ -29,17 +42,18 @@ public class CriteriaJooqFilter { private final List andConditions = new ArrayList<>(); private final List orConditions = new ArrayList<>(); private final List notConditions = new ArrayList<>(); -// private final List joinTables = new ArrayList<>(); + private final List joinTables = new ArrayList<>(); - private final String table; + private final Table generalTable; private final DSLContext dsl; private PageableOffset offset; private PageableSeek seek; private List sorts = new ArrayList<>(); + private String groupByField; protected CriteriaJooqFilter(String table, DSLContext dsl) { - this.table = table; + this.generalTable = DSL.table(table); this.dsl = dsl; } @@ -118,12 +132,18 @@ public class CriteriaJooqFilter { return this; } -// FIXME: Добавить поддержку -// public CriteriaJooqFilter join(@NonNull JoinTable... joinTables) { -// throw new IllegalStateException("Операция пока не поддерживается"); -// this.joinTables.addAll(Arrays.stream(joinTables).collect(Collectors.toList())); -// return this; -// } + public CriteriaJooqFilter groupBy(String field) { + if (field != null) { + this.groupByField = field; + } + return this; + } + + public CriteriaJooqFilter join(JoinTable... joinTables) { + Assert.isNotNull(joinTables); + this.joinTables.addAll(Arrays.stream(joinTables).collect(Collectors.toList())); + return this; + } private void generateAnd(CriteriaJooqQuery criteriaQuery) { andConditions.addAll(criteriaQuery.getConditions()); @@ -133,37 +153,69 @@ public class CriteriaJooqFilter { orConditions.addAll(criteriaQuery.getConditions()); } - public Query build() { - final List conditions = getConditions(); - SelectJoinStep from = dsl.select().from(table); -// if (!joinTables.isEmpty()) { -// for (JoinTable joinTable : joinTables) { -// final String tableName = joinTable.getTableName(); -// final JoinTypeOperation joinType = joinTable.getJoinTypeOperation(); -// final String fieldReference = joinTable.getFieldReference(); -// final String fieldBase = joinTable.getFieldBase(); -// final Condition on = field(fieldReference).eq(field(fieldBase)); -// switch (joinType) { -// case LEFT: -// from = from.leftJoin(tableName).on(on); -// break; -// case INNER: -// from = from.innerJoin(tableName).on(on); -// break; -// case RIGHT: -// from = from.rightJoin(tableName).on(on); -// break; -// } -// } -// } - final SelectConditionStep where = from.where(conditions); - final SelectSeekStepN sort = setSort(where); - setPaginationOffset(where); - setPaginationSeek(sort); + public Query generateQuery(String... fields) { + final List> selectFields = Arrays.stream(fields).map(DSL::field).collect(Collectors.toList()); + final SelectSelectStep mainSelect = !selectFields.isEmpty() ? dsl.select(selectFields) : dsl.select(); + final SelectLimitStep selectSeekStepN = generate(mainSelect); + return setPaginationOffset(selectSeekStepN); + } + public Query generateCount() { + final SelectSelectStep> selectCount = dsl.selectCount(); + return generate(selectCount); + } + + private SelectLimitStep generate(SelectSelectStep mainSelect) { + final SelectJoinStep from = mainSelect.from(generalTable); + final SelectJoinStep join = joinTables(from); + final SelectConditionStep where = join.where(getConditions()); + final SelectHavingStep groupBy = getGroupBy(where); + final SelectLimitStep orderBy = getOrderBy(groupBy); + return orderBy; + } + + private SelectLimitStep getOrderBy(SelectHavingStep groupBy) { + if (sorts != null && !sorts.isEmpty()) { + return groupBy.orderBy(getOrderBy()); + } + return groupBy; + } + + private SelectHavingStep getGroupBy(SelectConditionStep where) { + if (groupByField != null) { + return where.groupBy(field(groupByField)); + } return where; } + private SelectJoinStep joinTables(SelectJoinStep from) { + if (!joinTables.isEmpty()) { + for (JoinTable joinTable : joinTables) { + final String tableName = joinTable.getTableName(); + + final Table dlsJoinTableName = DSL.table(tableName); + + final JoinTypeOperation joinType = joinTable.getJoinTypeOperation(); + final Field fieldReference = field(joinTable.getFieldReference()); + final Field fieldBase = field(joinTable.getFieldBase()); + + final Condition on = fieldBase.eq(fieldReference); + switch (joinType) { + case LEFT: + from = from.leftJoin(dlsJoinTableName).on(on); + break; + case INNER: + from = from.innerJoin(dlsJoinTableName).on(on); + break; + case RIGHT: + from = from.rightJoin(dlsJoinTableName).on(on); + break; + } + } + } + return from; + } + private List getConditions() { final List conditions = new ArrayList<>(); if (!andConditions.isEmpty()) { @@ -175,33 +227,7 @@ public class CriteriaJooqFilter { return conditions; } - public Query count() { - final List conditions = getConditions(); - SelectJoinStep from = dsl.selectCount().from(table); -// if (!joinTables.isEmpty()) { -// for (JoinTable joinTable : joinTables) { -// final String tableName = joinTable.getTableName(); -// final JoinTypeOperation joinType = joinTable.getJoinTypeOperation(); -// final String fieldReference = joinTable.getFieldReference(); -// final String fieldBase = joinTable.getFieldBase(); -// final Condition on = field(fieldReference).eq(field(fieldBase)); -// switch (joinType) { -// case LEFT: -// from = from.leftJoin(tableName).on(on); -// break; -// case INNER: -// from = from.innerJoin(tableName).on(on); -// break; -// case RIGHT: -// from = from.rightJoin(tableName).on(on); -// break; -// } -// } -// } - return from.where(conditions); - } - - private SelectSeekStepN setSort(SelectConditionStep where) { + private Collection> getOrderBy() { if (!sorts.isEmpty()) { final List> newSorts = new ArrayList<>(); for (SortContainer sort : sorts) { @@ -213,9 +239,9 @@ public class CriteriaJooqFilter { newSorts.add(field(fieldName).desc()); } } - return where.orderBy(newSorts); + return newSorts; } - return null; + return Collections.emptyList(); } private void setPaginationSeek(SelectSeekStepN sort) { @@ -236,13 +262,14 @@ public class CriteriaJooqFilter { } } - private void setPaginationOffset(SelectConditionStep where) { + private Query setPaginationOffset(SelectLimitStep selectBuilder) { if (offset != null) { final int pageNumber = offset.getPageNumber(); final int pageSize = offset.getPageSize(); final int offsetNumber = (pageNumber + 1) * pageSize - pageSize; - where.limit(pageSize).offset(offsetNumber); + return selectBuilder.limit(pageSize).offset(offsetNumber); } + return selectBuilder; } } diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java index 5de0b31..7a9d49a 100644 --- a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java @@ -63,9 +63,9 @@ public class CriteriaJooqQuery { final Field query = field(field); if (value != null) { if (ignoreCase) { - conditions.add(query.like(value)); - } else { conditions.add(query.likeIgnoreCase(value)); + } else { + conditions.add(query.like(value)); } } return this; diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinTable.java b/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinTable.java index 2955511..d7e3d2a 100644 --- a/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinTable.java +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinTable.java @@ -26,6 +26,11 @@ public class JoinTable { return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.LEFT); } + public static JoinTable onRight(String tableName, String fieldBase, String fieldReference) { + Assert.isNotNull(tableName, fieldBase, fieldReference); + return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.RIGHT); + } + public static JoinTable of(String tableName, String fieldBase, String fieldReference, JoinTypeOperation joinType) { Assert.isNotNull(tableName, fieldBase, fieldReference); return new JoinTable(tableName, fieldBase, fieldReference, joinType); diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/utils/Likes.java b/src/main/java/dev/struchkov/haiti/filter/jooq/utils/Likes.java new file mode 100644 index 0000000..e9c8311 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/utils/Likes.java @@ -0,0 +1,28 @@ +package dev.struchkov.haiti.filter.jooq.utils; + +import static dev.struchkov.haiti.utils.Exceptions.utilityClass; + +public final class Likes { + + private Likes() { + utilityClass(); + } + + public static final String PERCENT = "%"; + + public static String subString(String text) { + if (text == null) return null; + return PERCENT + text + PERCENT; + } + + public static String beginWith(String text) { + if (text == null) return null; + return text + PERCENT; + } + + public static String endWith(String text) { + if (text == null) return null; + return text + PERCENT; + } + +}