diff --git a/dao/pom.xml b/dao/pom.xml index 9ab0b62611..4cddf8ba91 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -172,6 +172,7 @@ com.h2database h2 + test diff --git a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java index 0fba69c0c8..5d372b1ecd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractModelDao.java @@ -47,8 +47,8 @@ public abstract class CassandraAbstractModelDao, D> exte protected abstract String getColumnFamilyName(); - protected boolean isSearchTextDao() { - return false; + protected E updateSearchTextIfPresent(E entity) { + return entity; } protected Mapper getMapper() { @@ -153,9 +153,7 @@ public abstract class CassandraAbstractModelDao, D> exte log.error("Can't create entity for domain object {}", domain, e); throw new IllegalArgumentException("Can't create entity for domain object {" + domain + "}", e); } - if (isSearchTextDao()) { - ((SearchTextEntity) entity).setSearchText(((SearchTextEntity) entity).getSearchTextSource().toLowerCase()); - } + entity = updateSearchTextIfPresent(entity); log.debug("Saving entity {}", entity); entity = saveWithResult(entity).getEntity(); return DaoUtil.getData(entity); diff --git a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractSearchTextDao.java b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractSearchTextDao.java index 735dd3050c..89c3583040 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractSearchTextDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/CassandraAbstractSearchTextDao.java @@ -34,8 +34,13 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select; public abstract class CassandraAbstractSearchTextDao, D> extends CassandraAbstractModelDao { @Override - protected boolean isSearchTextDao() { - return true; + protected E updateSearchTextIfPresent(E entity) { + if (entity.getSearchTextSource() != null) { + entity.setSearchText(entity.getSearchTextSource().toLowerCase()); + } else { + log.trace("Entity [{}] has null SearchTextSource", entity); + } + return entity; } protected List findPageWithTextSearch(String searchView, List clauses, TextPageLink pageLink) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java index 594de17c68..b86fab0996 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java @@ -34,43 +34,41 @@ import java.util.UUID; */ public abstract class JpaAbstractSearchTimeDao, D> extends JpaAbstractDao { - protected Specification getTimeSearchPageSpec(TimePageLink pageLink) { - return new Specification() { + public static Specification getTimeSearchPageSpec(TimePageLink pageLink, String idColumn) { + return new Specification() { @Override - public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - Predicate lowerBound = null; - Predicate upperBound = null; + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { List predicates = new ArrayList<>(); if (pageLink.isAscOrder()) { if (pageLink.getIdOffset() != null) { - lowerBound = criteriaBuilder.greaterThan(root.get(ID_PROPERTY), pageLink.getIdOffset()); + Predicate lowerBound = criteriaBuilder.greaterThan(root.get(idColumn), pageLink.getIdOffset()); predicates.add(lowerBound); } else if (pageLink.getStartTime() != null) { UUID startOf = UUIDs.startOf(pageLink.getStartTime()); - lowerBound = criteriaBuilder.greaterThanOrEqualTo(root.get(ID_PROPERTY), startOf); + Predicate lowerBound = criteriaBuilder.greaterThanOrEqualTo(root.get(idColumn), startOf); predicates.add(lowerBound); } if (pageLink.getEndTime() != null) { UUID endOf = UUIDs.endOf(pageLink.getEndTime()); - upperBound = criteriaBuilder.lessThanOrEqualTo(root.get(ID_PROPERTY), endOf); + Predicate upperBound = criteriaBuilder.lessThanOrEqualTo(root.get(idColumn), endOf); predicates.add(upperBound); } } else { if (pageLink.getIdOffset() != null) { - lowerBound = criteriaBuilder.lessThan(root.get(ID_PROPERTY), pageLink.getIdOffset()); + Predicate lowerBound = criteriaBuilder.lessThan(root.get(idColumn), pageLink.getIdOffset()); predicates.add(lowerBound); } else if (pageLink.getEndTime() != null) { UUID endOf = UUIDs.endOf(pageLink.getEndTime()); - lowerBound = criteriaBuilder.lessThanOrEqualTo(root.get(ID_PROPERTY), endOf); + Predicate lowerBound = criteriaBuilder.lessThanOrEqualTo(root.get(idColumn), endOf); predicates.add(lowerBound); } if (pageLink.getStartTime() != null) { UUID startOf = UUIDs.startOf(pageLink.getStartTime()); - upperBound = criteriaBuilder.greaterThanOrEqualTo(root.get(ID_PROPERTY), startOf); + Predicate upperBound = criteriaBuilder.greaterThanOrEqualTo(root.get(idColumn), startOf); predicates.add(upperBound); } } - return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); } }; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java index 9cde87e8f8..649a201c15 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java @@ -100,7 +100,7 @@ public class JpaBaseEventDao extends JpaAbstractSearchTimeDao findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink) { - Specification timeSearchSpec = getTimeSearchPageSpec(pageLink); + Specification timeSearchSpec = JpaAbstractSearchTimeDao.getTimeSearchPageSpec(pageLink, ID_PROPERTY); Specification fieldsSpec = getEntityFieldsSpec(tenantId, entityId, eventType); Sort.Direction sortDirection = pageLink.isAscOrder() ? Sort.Direction.ASC : Sort.Direction.DESC; Pageable pageable = new PageRequest(0, pageLink.getLimit(), sortDirection, ID_PROPERTY); @@ -136,15 +136,15 @@ public class JpaBaseEventDao extends JpaAbstractSearchTimeDao> findRelations(EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType childType, TimePageLink pageLink) { -// TODO: -// executorService.submit(() -> DaoUtil.convertDataList( -// relationRepository.findRelations( -// to.getId(), -// to.getEntityType().name(), -// relationType, -// typeGroup.name()))); - return null; + Specification timeSearchSpec = JpaAbstractSearchTimeDao.getTimeSearchPageSpec(pageLink, RELATION_TO_ID_PROPERTY); + Specification fieldsSpec = getEntityFieldsSpec(from, relationType, typeGroup, childType); + Pageable pageable = new PageRequest(0, pageLink.getLimit(), + new Sort( + new Order(ASC, RELATION_TYPE_GROUP_PROPERTY), + new Order(ASC, RELATION_TYPE_PROPERTY), + new Order(ASC, RELATION_TO_TYPE_PROPERTY)) + ); + return executorService.submit(() -> + DaoUtil.convertDataList(relationRepository.findAll(where(timeSearchSpec).and(fieldsSpec), pageable).getContent())); } - + private Specification getEntityFieldsSpec(EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType childType) { + return new Specification() { + @Override + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { + List predicates = new ArrayList<>(); + if (from != null) { + Predicate fromIdPredicate = criteriaBuilder.equal(root.get(RELATION_FROM_ID_PROPERTY), from.getId()); + predicates.add(fromIdPredicate); + Predicate fromEntityTypePredicate = criteriaBuilder.equal(root.get(RELATION_FROM_TYPE_PROPERTY), from.getEntityType().name()); + predicates.add(fromEntityTypePredicate); + } + if (relationType != null) { + Predicate relationTypePredicate = criteriaBuilder.equal(root.get(RELATION_TYPE_PROPERTY), relationType); + predicates.add(relationTypePredicate); + } + if (typeGroup != null) { + Predicate typeGroupPredicate = criteriaBuilder.equal(root.get(RELATION_TYPE_GROUP_PROPERTY), typeGroup); + predicates.add(typeGroupPredicate); + } + if (childType != null) { + Predicate childTypePredicate = criteriaBuilder.equal(root.get(RELATION_TO_TYPE_PROPERTY), childType.name()); + predicates.add(childTypePredicate); + } + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + } + }; + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java index 68243d5aa5..d995b854d1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java @@ -16,6 +16,7 @@ package org.thingsboard.server.dao.sql.relation; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.thingsboard.server.dao.model.sql.RelationCompositeKey; import org.thingsboard.server.dao.model.sql.RelationEntity; @@ -24,7 +25,8 @@ import java.util.List; import java.util.UUID; @ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true") -public interface RelationRepository extends CrudRepository { +public interface RelationRepository + extends CrudRepository, JpaSpecificationExecutor { List findAllByFromIdAndFromTypeAndRelationTypeGroup(UUID fromId, String fromType, @@ -46,20 +48,4 @@ public interface RelationRepository extends CrudRepository findAllByFromIdAndFromType(UUID fromId, String fromType); - -// @Query(nativeQuery = true, value = "SELECT * FROM RELATION WHERE FROM_ID = :fromId " + -// "AND FROM_TYPE = :fromType " + -// "AND TO_TYPE = :toType " + -// "AND RELATION_TYPE = :relationType " + -// "AND RELATION_TYPE_GROUP = :relationTypeGroup " + -// "AND ID > :idOffset ORDER BY RELATION_TYPE_GROUP ASC, RELATION_TYPE ASC, TO_TYPE ASC") -// List findRelations(@Param("fromId") UUID fromId, -// @Param("fromType") String fromType, -// @Param("toType") String toType, -// @Param("relationType") String relationType, -// @Param("relationTypeGroup") String relationTypeGroup, -// TimePageLink pageLink); - - -// pageLink, ModelConstants.RELATION_TO_ID_PROPERTY); }