commit e264d7751c2387268c172be11159581d15ce2c67 Author: Struchkov Mark Date: Wed Jan 12 16:39:10 2022 +0300 First Version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a0d6e2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,85 @@ +*.class +*.log +*.ctxt +.mtj.tmp/ +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar +hs_err_pid* +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +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 +cmake-build-*/ +.idea/**/mongoSettings.xml +*.iws +out/ +.idea_modules/ +atlassian-ide-plugin.xml +.idea/replstate.xml +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +.idea/httpRequests +.idea/caches/build_file_checksums.ser +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.cab +*.msi +*.msix +*.msm +*.msp +*.lnk +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a1de594 --- /dev/null +++ b/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + dev.struchkov.haiti.filter + haiti-filter-jooq + 1.0-SNAPSHOT + jar + + Haiti Filter JOOQ + JOOQ based filtering module + https://github.com/haiti-projects/haiti-filter-jooq + + + 11 + 11 + + 3.15.5 + + + + + + dev.struchkov.haiti + haiti-bom + 0.0.1-RELEASE + pom + import + + + + + + + dev.struchkov.haiti + haiti-filter + + + org.jooq + jooq + ${jooq.version} + + + + \ No newline at end of file diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java new file mode 100644 index 0000000..8f85daf --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java @@ -0,0 +1,147 @@ +package dev.struchkov.haiti.filter.jooq; + +import dev.struchkov.haiti.filter.Filter; +import dev.struchkov.haiti.filter.FilterQuery; +import lombok.NonNull; +import org.jooq.Condition; +import org.jooq.DSLContext; +import org.jooq.Operator; +import org.jooq.Query; +import org.jooq.Record; +import org.jooq.SelectConditionStep; +import org.jooq.SelectJoinStep; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import static org.jooq.impl.DSL.condition; +import static org.jooq.impl.DSL.field; + +public class CriteriaJooqFilter implements Filter { + + 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 String fieldOrder; + private Object lastId; + private Integer pageSize; + + private final String table; + private final DSLContext dsl; + + protected CriteriaJooqFilter(String table, DSLContext dsl) { + this.table = table; + this.dsl = dsl; + } + + public static CriteriaJooqFilter create(String table, DSLContext dsl) { + return new CriteriaJooqFilter(table, dsl); + } + + @Override + public Filter and(FilterQuery filterQuery) { + generateAnd((CriteriaJooqQuery) filterQuery); + return this; + } + + @Override + public Filter and(Consumer query) { + final CriteriaJooqQuery criteriaQuery = CriteriaJooqQuery.create(); + query.accept(criteriaQuery); + generateAnd(criteriaQuery); + return this; + } + + @Override + public Filter or(FilterQuery filterQuery) { + generateOr((CriteriaJooqQuery) filterQuery); + return this; + } + + public Filter or(Consumer query) { + final CriteriaJooqQuery criteriaQuery = CriteriaJooqQuery.create(); + query.accept(criteriaQuery); + generateOr(criteriaQuery); + return this; + } + + @Override + public Filter not(FilterQuery filterQuery) { + return null; + } + + @Override + public Filter not(Consumer query) { + return null; + } + + public Filter page(@NonNull String fieldOrder, Object id, int pageSize) { + this.fieldOrder = fieldOrder; + this.lastId = id; + this.pageSize = pageSize; + return this; + } + + public Filter join(@NonNull JoinTable... joinTables) { + this.joinTables.addAll(Arrays.stream(joinTables).collect(Collectors.toList())); + return this; + } + + private void generateAnd(CriteriaJooqQuery criteriaQuery) { + andConditions.addAll(criteriaQuery.getConditions()); + } + + private void generateOr(CriteriaJooqQuery criteriaQuery) { + orConditions.addAll(criteriaQuery.getConditions()); + } + + @Override + public Query build() { + final List conditions = new ArrayList<>(); + if (!andConditions.isEmpty()) { + conditions.add(condition(Operator.AND, andConditions)); + } + if (!orConditions.isEmpty()) { + conditions.add(condition(Operator.OR, orConditions)); + } + 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); + if (pageSize != null && fieldOrder != null) { + if (lastId != null) { + where.orderBy(field(fieldOrder)) + .seek(lastId) + .limit(pageSize); + } else { + where.orderBy(field(fieldOrder)) + .limit(pageSize); + } + } + return where; + } + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java new file mode 100644 index 0000000..b1cbb76 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java @@ -0,0 +1,96 @@ +package dev.struchkov.haiti.filter.jooq; + +import dev.struchkov.haiti.filter.FilterQuery; +import lombok.NonNull; +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.impl.DSL; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.jooq.impl.DSL.condition; +import static org.jooq.impl.DSL.field; + +public class CriteriaJooqQuery implements FilterQuery { + + private final List conditions = new ArrayList<>(); + + public static CriteriaJooqQuery create() { + return new CriteriaJooqQuery(); + } + + protected List getConditions() { + return conditions; + } + + @Override + public > FilterQuery between(@NonNull String field, Y from, Y to) { + if (from != null && to != null) { + Condition condition = DSL.field(field).between(from, to); + conditions.add(condition); + } + return this; + } + + @Override + public > FilterQuery greaterThan(@NonNull String field, Y value) { + return this; + } + + @Override + public > FilterQuery lessThan(@NonNull String field, Y value) { + return this; + } + + @Override + public FilterQuery matchPhrase(@NonNull String field, Object value) { + if (value != null) { + final Condition condition = condition(Map.of(field(field), value)); + conditions.add(condition); + } + return this; + } + + @Override + public FilterQuery matchPhrase(@NonNull String field, Set values) { + if (values != null && !values.isEmpty()) { + conditions.add(DSL.field(field).in(values)); + } + return this; + } + + @Override + public FilterQuery exists(String field) { + if (field != null) { + conditions.add(DSL.field(field).isNotNull()); + } + return this; + } + + @Override + public FilterQuery like(@NonNull String field, String value, boolean ignoreCase) { + final Field query = field(field); + if (value != null) { + if (ignoreCase) { + conditions.add(query.like(value)); + } else { + conditions.add(query.likeIgnoreCase(value)); + } + } + return this; + } + + @Override + public FilterQuery checkBoolInt(@NonNull String field, Boolean flag) { + return this; + } + + @Override + public List build() { + return conditions; + } + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/JoinTable.java b/src/main/java/dev/struchkov/haiti/filter/jooq/JoinTable.java new file mode 100644 index 0000000..422a7a2 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/JoinTable.java @@ -0,0 +1,30 @@ +package dev.struchkov.haiti.filter.jooq; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +/** + * Контейнер для соединения с таблицами. + * + * @author upagge 15.04.2021 + */ +@Getter +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class JoinTable { + + private final String tableName; + private final String fieldBase; + private final String fieldReference; + private final JoinTypeOperation joinTypeOperation; + + public static JoinTable ofLeft(@NonNull String tableName, @NonNull String fieldBase, @NonNull String fieldReference) { + return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.LEFT); + } + + public static JoinTable of(@NonNull String tableName, @NonNull String fieldBase, @NonNull String fieldReference, JoinTypeOperation joinType) { + return new JoinTable(tableName, fieldBase, fieldReference, joinType); + } + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/JoinTypeOperation.java b/src/main/java/dev/struchkov/haiti/filter/jooq/JoinTypeOperation.java new file mode 100644 index 0000000..0b8dfc3 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/JoinTypeOperation.java @@ -0,0 +1,14 @@ +package dev.struchkov.haiti.filter.jooq; + +/** + * Разрешенные типы операции JOIN. + * + * @author upagge 24.02.2021 + */ +public enum JoinTypeOperation { + + LEFT, + RIGHT, + INNER + +}