дополнительные скрипты
This commit is contained in:
parent
92050674b1
commit
2696f438e4
4 changed files with 118 additions and 239 deletions
|
|
@ -0,0 +1,81 @@
|
|||
package ru.micord.ervu_dashboard.dao;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import database.dao.DefaultLoadDao;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Field;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import ru.cg.webbpm.modules.database.api.utils.QueryUtils;
|
||||
import ru.cg.webbpm.modules.database.bean.entity_graph.condition.Operator;
|
||||
import ru.cg.webbpm.modules.database.bean.filter.EntityFilter;
|
||||
import ru.cg.webbpm.modules.database.bean.filter.FilterOperation;
|
||||
|
||||
/**
|
||||
* @author r.latypov
|
||||
*/
|
||||
public class CustomCoalesceDao extends DefaultLoadDao {
|
||||
@Autowired
|
||||
private DSLContext dsl;
|
||||
|
||||
@Override
|
||||
public Condition getFilterCondition(EntityFilter entityFilter) {
|
||||
Field<Object> field = QueryUtils.toJooqField(
|
||||
entityFilter.getEntityColumn(), dsl.dialect(), false
|
||||
);
|
||||
return condition(entityFilter, field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition getFilterCondition(EntityFilter entityFilter, String tableName) {
|
||||
Field<Object> field = toJooqField(entityFilter.getEntityColumn(), tableName);
|
||||
return condition(entityFilter, field);
|
||||
}
|
||||
|
||||
private Condition condition(EntityFilter entityFilter, Field<Object> field) {
|
||||
FilterOperation operation = entityFilter.getFilterOperation();
|
||||
Operator multiValueOperator = entityFilter.getMultiValueOperator();
|
||||
Object value = entityFilter.getValue();
|
||||
// todo this is KOSTIL
|
||||
if (value instanceof String && field.getDataType().isDateTime()) {
|
||||
if (java.sql.Date.class.isAssignableFrom(field.getType())) {
|
||||
value = java.sql.Date.valueOf(
|
||||
LocalDate.parse(String.valueOf(value), DateTimeFormatter.ISO_DATE_TIME));
|
||||
}
|
||||
else if (Timestamp.class.isAssignableFrom(field.getType())) {
|
||||
value = Timestamp.valueOf(
|
||||
LocalDateTime.parse(String.valueOf(value), DateTimeFormatter.ISO_DATE_TIME));
|
||||
}
|
||||
}
|
||||
|
||||
return switch (operation) {
|
||||
case EQUAL -> getEqualCondition(field, value, multiValueOperator);
|
||||
case NOT_EQUAL -> getNotEqualCondition(field, value, multiValueOperator);
|
||||
case EQUAL_IGNORE_CASE -> getEqualIgnoreCaseCondition(field, value, multiValueOperator);
|
||||
case GREATER_THAN -> getGreaterThanCondition(field, value, multiValueOperator);
|
||||
case LESS_THAN -> getLessThanCondition(field, value, multiValueOperator);
|
||||
case GREATER_OR_EQUAL -> getGreaterOrEqualCondition(field, value, multiValueOperator);
|
||||
case LESS_OR_EQUAL -> getLessOrEqualCondition(field, value, multiValueOperator);
|
||||
case CONTAINS -> getContainsCondition(field, value, multiValueOperator);
|
||||
case NOT_CONTAINS -> getNotContainsCondition(field, value, multiValueOperator);
|
||||
case START_WITH -> getStartsWithCondition(field, value, multiValueOperator);
|
||||
case ENDS_WITH -> getEndsWithCondition(field, value, multiValueOperator);
|
||||
case IS_NULL -> field.isNull();
|
||||
case IS_NOT_NULL -> field.isNotNull();
|
||||
case IN -> field.in(value instanceof String
|
||||
? Arrays.stream(((String) value).split(","))
|
||||
.collect(Collectors.toUnmodifiableSet())
|
||||
: value)
|
||||
.or(field.isNull());
|
||||
case NOT_IN -> field.notIn(value);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6,7 +6,6 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import database.dao.DefaultLoadDao;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
|
|
@ -31,7 +30,7 @@ import ru.cg.webbpm.modules.database.bean.filter.EntityFilter;
|
|||
/**
|
||||
* @author r.latypov
|
||||
*/
|
||||
public class LessJoinsDao extends DefaultLoadDao {
|
||||
public class LessJoinsDao extends CustomCoalesceDao {
|
||||
@Override
|
||||
public List<TableRow> load(Set<EntityColumn> columns, LoadOptions loadOptions,
|
||||
boolean withGraphConditions) {
|
||||
|
|
|
|||
|
|
@ -1,237 +0,0 @@
|
|||
package ru.micord.ervu_dashboard.dao;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import database.dao.DefaultLoadDao;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.SelectConnectByStep;
|
||||
import org.jooq.SelectForUpdateStep;
|
||||
import org.jooq.SelectJoinStep;
|
||||
import org.jooq.SelectLimitStep;
|
||||
import org.jooq.SelectSelectStep;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
import ru.cg.webbpm.modules.database.api.bean.TableRow;
|
||||
import ru.cg.webbpm.modules.database.api.dao.option.LoadOptions;
|
||||
import ru.cg.webbpm.modules.database.api.utils.QueryUtils;
|
||||
import ru.cg.webbpm.modules.database.bean.entity_graph.DefaultGraphBinding;
|
||||
import ru.cg.webbpm.modules.database.bean.entity_graph.DefaultGraphNode;
|
||||
import ru.cg.webbpm.modules.database.bean.entity_graph.EntityColumn;
|
||||
import ru.cg.webbpm.modules.database.bean.entity_graph.condition.ConditionGroup;
|
||||
import ru.cg.webbpm.modules.database.bean.filter.EntityFilter;
|
||||
|
||||
/**
|
||||
* @author r.latypov
|
||||
*/
|
||||
public class SubqueriesJoinsDao extends DefaultLoadDao {
|
||||
@Override
|
||||
public List<TableRow> load(Set<EntityColumn> columns, LoadOptions loadOptions,
|
||||
boolean withGraphConditions) {
|
||||
DefaultGraphNode mainNode = graph.getMainNode();
|
||||
EntityColumn[] mainNodePkColumns = getGraphNodeTablePkFields(mainNode);
|
||||
|
||||
if (mainNodePkColumns == null || mainNodePkColumns.length == 0) {
|
||||
throw new RuntimeException("Primary key does not exist in " + mainNode.getAlias() + " : "
|
||||
+ mainNode.getSchemaName() + "." + mainNode.getTableName());
|
||||
}
|
||||
|
||||
if (loadOptions.isLoadPK()) {
|
||||
Collections.addAll(columns, mainNodePkColumns);
|
||||
}
|
||||
// presume only one pk column
|
||||
EntityColumn mainNodePkColumn = mainNodePkColumns[0];
|
||||
|
||||
Set<String> fieldsEntityNames = columns.stream()
|
||||
.map(EntityColumn::getEntity)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
// filters without groups
|
||||
List<EntityFilter> allEntityFilters = loadOptions.getEntityFilterGroup().getEntityFilters();
|
||||
Set<String> conditionsEntityNames = allEntityFilters.stream()
|
||||
.map(entityFilter -> entityFilter.getEntityColumn().getEntity())
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
// push entity filters into map
|
||||
Map<String, List<Condition>> entitiesConditionsMap = conditionsEntityNames.stream()
|
||||
.collect(Collectors.toMap(
|
||||
entityName -> entityName,
|
||||
entityName -> getFilterConditions(
|
||||
allEntityFilters.stream()
|
||||
.filter(entityFilter -> entityFilter.getEntityColumn()
|
||||
.getEntity()
|
||||
.equals(entityName))
|
||||
.toList()
|
||||
)
|
||||
));
|
||||
|
||||
// queries for define main table ids condition
|
||||
Set<?> mainTableIds = null;
|
||||
Set<String> otherEntitiesNames = conditionsEntityNames.stream()
|
||||
.filter(entityName -> !fieldsEntityNames.contains(entityName))
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
if (!otherEntitiesNames.isEmpty()) {
|
||||
mainTableIds = otherEntitiesNames.stream()
|
||||
.map(entityName -> {
|
||||
DefaultGraphNode graphNode = graph.getNodesByEntityNames().get(entityName);
|
||||
DefaultGraphBinding binding = graph.getBindingByEndNode(graphNode);
|
||||
if (binding == null) {
|
||||
throw new RuntimeException("Entity " + entityName + " is not bound");
|
||||
}
|
||||
else {
|
||||
EntityColumn refEntityColumn = null;
|
||||
if (binding.getRefOnEntityName().equals(entityName)) {
|
||||
refEntityColumn = binding.getRefOnColumns()[0];
|
||||
}
|
||||
if (binding.getRefToEntityName().equals(entityName)) {
|
||||
refEntityColumn = binding.getRefToColumns()[0];
|
||||
}
|
||||
|
||||
if (refEntityColumn == null) {
|
||||
throw new RuntimeException("Binding for entity " + entityName + " is not valid");
|
||||
}
|
||||
else {
|
||||
Field<?> selectField = QueryUtils.toJooqField(
|
||||
refEntityColumn, this.getDsl().dialect(), true
|
||||
);
|
||||
return getDsl()
|
||||
.select(selectField)
|
||||
.from(getTableWithAlias(graphNode))
|
||||
.where(entitiesConditionsMap.get(entityName))
|
||||
.fetch(selectField);
|
||||
}
|
||||
}
|
||||
})
|
||||
// collect only intersection of all lists of ids
|
||||
.collect(intersecting());
|
||||
}
|
||||
|
||||
List<Condition> mainConditions = getFilterConditions(
|
||||
allEntityFilters.stream()
|
||||
.filter(entityFilter -> fieldsEntityNames.contains(
|
||||
entityFilter.getEntityColumn().getTable()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
Field<?> pkField = QueryUtils.toJooqField(mainNodePkColumn, this.getDsl().dialect(), true);
|
||||
mainConditions.add(mainTableIds == null ? DSL.trueCondition() : pkField.in(mainTableIds));
|
||||
|
||||
List<Field<?>> fieldList = convertEntityColumnsToJooqFields(columns);
|
||||
SelectJoinStep<Record> selectStep = selectByJooqColumns(fieldsEntityNames, fieldList);
|
||||
|
||||
SelectConnectByStep<Record> joinStep = buildWhereStep(selectStep, mainConditions,
|
||||
withGraphConditions
|
||||
);
|
||||
SelectLimitStep<Record> limitStep = getOrderByStep(joinStep, loadOptions.getSortFields(), true);
|
||||
SelectForUpdateStep<Record> selectForUpdateStep = getSelectForUpdateStep(limitStep,
|
||||
loadOptions.getOffset(), loadOptions.getLimit()
|
||||
);
|
||||
|
||||
return recordListToTableFieldDataList(selectForUpdateStep.fetch(), columns);
|
||||
}
|
||||
|
||||
private SelectJoinStep<Record> selectByJooqColumns(Set<String> fieldsEntityNames,
|
||||
List<Field<?>> fieldList) {
|
||||
SelectSelectStep<Record> select = uniqueResult
|
||||
? getDsl().selectDistinct(fieldList)
|
||||
: getDsl().select(fieldList);
|
||||
DefaultGraphNode mainNode = graph.getMainNode();
|
||||
SelectJoinStep<Record> selectJoinStep = select.from(getTableWithAlias(mainNode));
|
||||
addJoins(
|
||||
fieldsEntityNames, selectJoinStep, graph.getMainNodeIndex(), -1, getMatrix()
|
||||
);
|
||||
return selectJoinStep;
|
||||
}
|
||||
|
||||
private void addJoins(Set<String> fieldsEntityNames, SelectJoinStep<Record> selectJoinStep,
|
||||
int currentIndex, int parentIndex, DefaultGraphBinding[][] matrix) {
|
||||
|
||||
for (int i = 0; i < matrix.length; i++) {
|
||||
|
||||
if (matrix[currentIndex][i] == null || matrix[currentIndex][i].isCyclic()
|
||||
|| (parentIndex >= 0 && i == parentIndex)) {
|
||||
continue;
|
||||
}
|
||||
DefaultGraphNode endNode = graph.getNodeByIndex(i);
|
||||
Table<?> endNodeTable = getTableWithAlias(endNode);
|
||||
|
||||
String tableAlias = endNode.getAlias();
|
||||
if (!fieldsEntityNames.contains(tableAlias)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DefaultGraphBinding binding = matrix[currentIndex][i];
|
||||
if (binding.getRefToColumns() != null && binding.getRefOnColumns() != null) {
|
||||
EntityColumn refOnColumnsEntityColumn = binding.getRefOnColumns()[0];
|
||||
refOnColumnsEntityColumn.setEntity(binding.getRefOnEntityName());
|
||||
EntityColumn refToColumnsEntityColumn = binding.getRefToColumns()[0];
|
||||
refToColumnsEntityColumn.setEntity(binding.getRefToEntityName());
|
||||
Field startNodeCol = QueryUtils.toJooqField(refOnColumnsEntityColumn);
|
||||
Field endNodeCol = QueryUtils.toJooqField(refToColumnsEntityColumn);
|
||||
@SuppressWarnings("unchecked")
|
||||
Condition bindingCondition = startNodeCol.equal(endNodeCol);
|
||||
|
||||
for (int j = 1; j < binding.getRefOnColumns().length; j++) {
|
||||
startNodeCol = QueryUtils.toJooqField(binding.getRefOnColumns()[j]);
|
||||
endNodeCol = QueryUtils.toJooqField(binding.getRefToColumns()[j]);
|
||||
@SuppressWarnings("unchecked")
|
||||
Condition condition = startNodeCol.equal(endNodeCol);
|
||||
bindingCondition = bindingCondition.and(condition);
|
||||
}
|
||||
ConditionGroup conditionGroup = binding.getConditionGroup();
|
||||
|
||||
if (conditionGroup != null) {
|
||||
Condition condition = conditionBuilder.build(conditionGroup);
|
||||
|
||||
if (condition != null) {
|
||||
bindingCondition = bindingCondition.and(condition);
|
||||
}
|
||||
}
|
||||
|
||||
if (binding.isRequired()) {
|
||||
selectJoinStep.join(endNodeTable).on(bindingCondition);
|
||||
}
|
||||
else {
|
||||
selectJoinStep.leftOuterJoin(endNodeTable).on(bindingCondition);
|
||||
}
|
||||
}
|
||||
addJoins(fieldsEntityNames, selectJoinStep, i, currentIndex, matrix);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T, S extends Collection<T>> Collector<S, ?, Set<T>> intersecting() {
|
||||
class Accumulator {
|
||||
Set<T> result;
|
||||
|
||||
void accumulate(S collection) {
|
||||
if (result == null) {
|
||||
result = new HashSet<>(collection);
|
||||
}
|
||||
else {
|
||||
result.retainAll(collection);
|
||||
}
|
||||
}
|
||||
|
||||
Accumulator combine(Accumulator other) {
|
||||
if (result == null) {
|
||||
return other;
|
||||
}
|
||||
if (other.result != null) {
|
||||
result.retainAll(other.result);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return Collector.of(Accumulator::new, Accumulator::accumulate, Accumulator::combine,
|
||||
acc -> acc.result == null ? Collections.emptySet() : acc.result,
|
||||
Collector.Characteristics.UNORDERED
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import {AdvancedProperty, AnalyticalScope, Behavior, Visible} from "@webbpm/base-package";
|
||||
import {DropdownTreeViewComponent} from "../../../component/field/DropdownTreeViewComponent";
|
||||
import {TreeItemDto} from "../../../generated/component/model/TreeItemDto";
|
||||
|
||||
@AnalyticalScope(DropdownTreeViewComponent)
|
||||
export class DropdownTreeViewModelFilterValue extends Behavior {
|
||||
|
||||
public isBusinessId: boolean;
|
||||
@AdvancedProperty()
|
||||
public separator: string;
|
||||
|
||||
@Visible()
|
||||
public getIds(): string {
|
||||
const treeViewComponent = this.getScript(
|
||||
DropdownTreeViewComponent) as DropdownTreeViewComponent;
|
||||
let model: TreeItemDto = treeViewComponent.value;
|
||||
const dtos: TreeItemDto[] = [];
|
||||
|
||||
if (!model && treeViewComponent.cachedValue) {
|
||||
model = treeViewComponent.cachedValue;
|
||||
}
|
||||
if (model) {
|
||||
dtos.push(model);
|
||||
this.fillArray(dtos, model);
|
||||
}
|
||||
const ids: string[] = dtos.map(value => this.isBusinessId ? value.businessId : value.id);
|
||||
return this.separator ? ids.join(this.separator) : ids.join();
|
||||
}
|
||||
|
||||
private fillArray(dtos: TreeItemDto[], dto: TreeItemDto): void {
|
||||
if (dto.children) {
|
||||
dtos.push(...dto.children);
|
||||
dto.children.forEach(value => this.fillArray(dtos, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue