Commit 2dd2cae91b912dc1eab59d002bafe9d5fe7b437d
1 parent
d83d9ec3
Bug Fix for DeviceSearch and Entity queries
Showing
2 changed files
with
58 additions
and
30 deletions
@@ -333,8 +333,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -333,8 +333,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
333 | if (pageLink.getPageSize() > 0) { | 333 | if (pageLink.getPageSize() > 0) { |
334 | dataQuery = String.format("%s limit %s offset %s", dataQuery, pageLink.getPageSize(), startIndex); | 334 | dataQuery = String.format("%s limit %s offset %s", dataQuery, pageLink.getPageSize(), startIndex); |
335 | } | 335 | } |
336 | -// log.error("QUERY: {}", dataQuery); | ||
337 | -// Arrays.asList(ctx.getParameterNames()).forEach(param -> log.error("QUERY PARAM: {}->{}", param, ctx.getValue(param))); | 336 | + log.error("QUERY: {}", dataQuery); |
337 | + Arrays.asList(ctx.getParameterNames()).forEach(param -> log.error("QUERY PARAM: {}->{}", param, ctx.getValue(param))); | ||
338 | List<Map<String, Object>> rows = jdbcTemplate.queryForList(dataQuery, ctx); | 338 | List<Map<String, Object>> rows = jdbcTemplate.queryForList(dataQuery, ctx); |
339 | return EntityDataAdapter.createEntityData(pageLink, selectionMapping, rows, totalElements); | 339 | return EntityDataAdapter.createEntityData(pageLink, selectionMapping, rows, totalElements); |
340 | }); | 340 | }); |
@@ -432,7 +432,12 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -432,7 +432,12 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
432 | String lvlFilter = getLvlFilter(entityFilter.getMaxLevel()); | 432 | String lvlFilter = getLvlFilter(entityFilter.getMaxLevel()); |
433 | String selectFields = "SELECT tenant_id, customer_id, id, created_time, type, name, label FROM " + entityType.name() + " WHERE id in ( SELECT entity_id"; | 433 | String selectFields = "SELECT tenant_id, customer_id, id, created_time, type, name, label FROM " + entityType.name() + " WHERE id in ( SELECT entity_id"; |
434 | String from = getQueryTemplate(entityFilter.getDirection()); | 434 | String from = getQueryTemplate(entityFilter.getDirection()); |
435 | - String whereFilter = " WHERE re.relation_type = :where_relation_type AND re.to_type = :where_entity_type"; | 435 | + String whereFilter = " WHERE"; |
436 | + if (!StringUtils.isEmpty(entityFilter.getRelationType())) { | ||
437 | + ctx.addStringParameter("where_relation_type", entityFilter.getRelationType()); | ||
438 | + whereFilter += " re.relation_type = :where_relation_type AND"; | ||
439 | + } | ||
440 | + whereFilter += " re.to_type = :where_entity_type"; | ||
436 | 441 | ||
437 | from = String.format(from, lvlFilter, whereFilter); | 442 | from = String.format(from, lvlFilter, whereFilter); |
438 | String query = "( " + selectFields + from + ")"; | 443 | String query = "( " + selectFields + from + ")"; |
@@ -443,7 +448,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -443,7 +448,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
443 | query += " )"; | 448 | query += " )"; |
444 | ctx.addUuidParameter("relation_root_id", rootId.getId()); | 449 | ctx.addUuidParameter("relation_root_id", rootId.getId()); |
445 | ctx.addStringParameter("relation_root_type", rootId.getEntityType().name()); | 450 | ctx.addStringParameter("relation_root_type", rootId.getEntityType().name()); |
446 | - ctx.addStringParameter("where_relation_type", entityFilter.getRelationType()); | ||
447 | ctx.addStringParameter("where_entity_type", entityType.name()); | 451 | ctx.addStringParameter("where_entity_type", entityType.name()); |
448 | return query; | 452 | return query; |
449 | } | 453 | } |
@@ -465,36 +469,27 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -465,36 +469,27 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
465 | 469 | ||
466 | StringBuilder whereFilter; | 470 | StringBuilder whereFilter; |
467 | if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) { | 471 | if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) { |
468 | - whereFilter = new StringBuilder(" WHERE "); | 472 | + whereFilter = new StringBuilder(); |
469 | boolean first = true; | 473 | boolean first = true; |
470 | boolean single = entityFilter.getFilters().size() == 1; | 474 | boolean single = entityFilter.getFilters().size() == 1; |
471 | int entityTypeFilterIdx = 0; | 475 | int entityTypeFilterIdx = 0; |
472 | for (EntityTypeFilter etf : entityFilter.getFilters()) { | 476 | for (EntityTypeFilter etf : entityFilter.getFilters()) { |
473 | - if (first) { | ||
474 | - first = false; | ||
475 | - } else { | ||
476 | - whereFilter.append(" AND "); | ||
477 | - } | ||
478 | - String relationType = etf.getRelationType(); | ||
479 | - if (!single) { | ||
480 | - whereFilter.append(" ("); | ||
481 | - } | ||
482 | - List<String> whereEntityTypes = etf.getEntityTypes().stream().map(EntityType::name).collect(Collectors.toList()); | ||
483 | - whereFilter | ||
484 | - .append(" re.relation_type = :where_relation_type").append(entityTypeFilterIdx); | ||
485 | - if (!whereEntityTypes.isEmpty()) { | ||
486 | - whereFilter.append(" and re.") | ||
487 | - .append(entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from") | ||
488 | - .append("_type in (:where_entity_types").append(entityTypeFilterIdx).append(")"); | ||
489 | - } | ||
490 | - if (!single) { | ||
491 | - whereFilter.append(" )"); | ||
492 | - } | ||
493 | - ctx.addStringParameter("where_relation_type" + entityTypeFilterIdx, relationType); | ||
494 | - if (!whereEntityTypes.isEmpty()) { | ||
495 | - ctx.addStringListParameter("where_entity_types" + entityTypeFilterIdx, whereEntityTypes); | 477 | + String etfCondition = buildEtfCondition(ctx, etf, entityFilter.getDirection(), entityTypeFilterIdx++); |
478 | + if (!etfCondition.isEmpty()) { | ||
479 | + if (first) { | ||
480 | + whereFilter.append(" WHERE "); | ||
481 | + first = false; | ||
482 | + } else { | ||
483 | + whereFilter.append(" AND "); | ||
484 | + } | ||
485 | + if (!single) { | ||
486 | + whereFilter.append(" ("); | ||
487 | + } | ||
488 | + whereFilter.append(etfCondition); | ||
489 | + if (!single) { | ||
490 | + whereFilter.append(" )"); | ||
491 | + } | ||
496 | } | 492 | } |
497 | - entityTypeFilterIdx++; | ||
498 | } | 493 | } |
499 | } else { | 494 | } else { |
500 | whereFilter = new StringBuilder(); | 495 | whereFilter = new StringBuilder(); |
@@ -503,6 +498,34 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -503,6 +498,34 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
503 | return "( " + selectFields + from + ")"; | 498 | return "( " + selectFields + from + ")"; |
504 | } | 499 | } |
505 | 500 | ||
501 | + private String buildEtfCondition(QueryContext ctx, EntityTypeFilter etf, EntitySearchDirection direction, int entityTypeFilterIdx) { | ||
502 | + StringBuilder whereFilter = new StringBuilder(); | ||
503 | + String relationType = etf.getRelationType(); | ||
504 | + List<EntityType> entityTypes = etf.getEntityTypes(); | ||
505 | + List<String> whereEntityTypes; | ||
506 | + if (entityTypes == null || entityTypes.isEmpty()) { | ||
507 | + whereEntityTypes = Collections.emptyList(); | ||
508 | + } else { | ||
509 | + whereEntityTypes = etf.getEntityTypes().stream().map(EntityType::name).collect(Collectors.toList()); | ||
510 | + } | ||
511 | + boolean hasRelationType = !StringUtils.isEmpty(relationType); | ||
512 | + if (hasRelationType) { | ||
513 | + ctx.addStringParameter("where_relation_type" + entityTypeFilterIdx, relationType); | ||
514 | + whereFilter | ||
515 | + .append("re.relation_type = :where_relation_type").append(entityTypeFilterIdx); | ||
516 | + } | ||
517 | + if (!whereEntityTypes.isEmpty()) { | ||
518 | + if (hasRelationType) { | ||
519 | + whereFilter.append(" and "); | ||
520 | + } | ||
521 | + whereFilter.append("re.") | ||
522 | + .append(direction.equals(EntitySearchDirection.FROM) ? "to" : "from") | ||
523 | + .append("_type in (:where_entity_types").append(entityTypeFilterIdx).append(")"); | ||
524 | + ctx.addStringListParameter("where_entity_types" + entityTypeFilterIdx, whereEntityTypes); | ||
525 | + } | ||
526 | + return whereFilter.toString(); | ||
527 | + } | ||
528 | + | ||
506 | private String getLvlFilter(int maxLevel) { | 529 | private String getLvlFilter(int maxLevel) { |
507 | return maxLevel > 0 ? ("and lvl <= " + (maxLevel - 1)) : ""; | 530 | return maxLevel > 0 ? ("and lvl <= " + (maxLevel - 1)) : ""; |
508 | } | 531 | } |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.dao.sql.query; | 16 | package org.thingsboard.server.dao.sql.query; |
17 | 17 | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
18 | import org.hibernate.type.PostgresUUIDType; | 19 | import org.hibernate.type.PostgresUUIDType; |
19 | import org.springframework.jdbc.core.namedparam.SqlParameterSource; | 20 | import org.springframework.jdbc.core.namedparam.SqlParameterSource; |
20 | import org.thingsboard.server.common.data.EntityType; | 21 | import org.thingsboard.server.common.data.EntityType; |
@@ -27,6 +28,7 @@ import java.util.List; | @@ -27,6 +28,7 @@ import java.util.List; | ||
27 | import java.util.Map; | 28 | import java.util.Map; |
28 | import java.util.UUID; | 29 | import java.util.UUID; |
29 | 30 | ||
31 | +@Slf4j | ||
30 | public class QueryContext implements SqlParameterSource { | 32 | public class QueryContext implements SqlParameterSource { |
31 | private static final PostgresUUIDType UUID_TYPE = new PostgresUUIDType(); | 33 | private static final PostgresUUIDType UUID_TYPE = new PostgresUUIDType(); |
32 | 34 | ||
@@ -43,9 +45,12 @@ public class QueryContext implements SqlParameterSource { | @@ -43,9 +45,12 @@ public class QueryContext implements SqlParameterSource { | ||
43 | void addParameter(String name, Object value, int type, String typeName) { | 45 | void addParameter(String name, Object value, int type, String typeName) { |
44 | Parameter newParam = new Parameter(value, type, typeName); | 46 | Parameter newParam = new Parameter(value, type, typeName); |
45 | Parameter oldParam = params.put(name, newParam); | 47 | Parameter oldParam = params.put(name, newParam); |
46 | - if (oldParam != null && !oldParam.value.equals(newParam.value)) { | 48 | + if (oldParam != null && oldParam.value != null && !oldParam.value.equals(newParam.value)) { |
47 | throw new RuntimeException("Parameter with name: " + name + " was already registered!"); | 49 | throw new RuntimeException("Parameter with name: " + name + " was already registered!"); |
48 | } | 50 | } |
51 | + if(value == null){ | ||
52 | + log.warn("[{}][{}][{}] Trying to set null value", getTenantId(), getCustomerId(), name); | ||
53 | + } | ||
49 | } | 54 | } |
50 | 55 | ||
51 | public void append(String s) { | 56 | public void append(String s) { |