Merge pull request #10454 from dashevchenko/ownerName
Added ownerName ENTITY_FIELD to EntityDataQuery
This commit is contained in:
commit
ab607ed710
@ -52,6 +52,7 @@ import org.thingsboard.server.common.data.query.EntityTypeFilter;
|
||||
import org.thingsboard.server.common.data.query.FilterPredicateValue;
|
||||
import org.thingsboard.server.common.data.query.KeyFilter;
|
||||
import org.thingsboard.server.common.data.query.NumericFilterPredicate;
|
||||
import org.thingsboard.server.common.data.query.StringFilterPredicate;
|
||||
import org.thingsboard.server.common.data.query.TsValue;
|
||||
import org.thingsboard.server.common.data.queue.QueueStats;
|
||||
import org.thingsboard.server.common.data.security.Authority;
|
||||
@ -642,4 +643,166 @@ public class EntityQueryControllerTest extends AbstractControllerTest {
|
||||
Assert.assertEquals(97, count.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindDevicesCountByOwnerNameAndOwnerType() throws Exception {
|
||||
loginTenantAdmin();
|
||||
int numOfDevices = 8;
|
||||
|
||||
for (int i = 0; i < numOfDevices; i++) {
|
||||
Device device = new Device();
|
||||
String name = "Device" + i;
|
||||
device.setName(name);
|
||||
device.setType("default");
|
||||
|
||||
Device savedDevice = doPost("/api/device?accessToken=" + name, device, Device.class);
|
||||
JsonNode content = JacksonUtil.toJsonNode("{\"alarmActiveTime\": 1" + i + "}");
|
||||
doPost("/api/plugins/telemetry/" + EntityType.DEVICE.name() + "/" + savedDevice.getUuidId() + "/SERVER_SCOPE", content)
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
DeviceTypeFilter filter = new DeviceTypeFilter();
|
||||
filter.setDeviceTypes(List.of("default"));
|
||||
filter.setDeviceNameFilter("");
|
||||
|
||||
KeyFilter activeAlarmTimeFilter = getServerAttributeNumericGreaterThanKeyFilter("alarmActiveTime", 5);
|
||||
KeyFilter activeAlarmTimeToLongFilter = getServerAttributeNumericGreaterThanKeyFilter("alarmActiveTime", 30);
|
||||
KeyFilter tenantOwnerNameFilter = getEntityFieldStringEqualToKeyFilter("ownerName", TEST_TENANT_NAME);
|
||||
KeyFilter wrongOwnerNameFilter = getEntityFieldStringEqualToKeyFilter("ownerName", "wrongName");
|
||||
KeyFilter tenantOwnerTypeFilter = getEntityFieldStringEqualToKeyFilter("ownerType", "TENANT");
|
||||
KeyFilter customerOwnerTypeFilter = getEntityFieldStringEqualToKeyFilter("ownerType", "CUSTOMER");
|
||||
|
||||
// all devices with ownerName = TEST TENANT
|
||||
EntityCountQuery query = new EntityCountQuery(filter, List.of(activeAlarmTimeFilter, tenantOwnerNameFilter));
|
||||
checkEntitiesCount(query, numOfDevices);
|
||||
|
||||
// all devices with ownerName = TEST TENANT
|
||||
EntityCountQuery activeAlarmTimeToLongQuery = new EntityCountQuery(filter, List.of(activeAlarmTimeToLongFilter, tenantOwnerNameFilter));
|
||||
checkEntitiesCount(activeAlarmTimeToLongQuery, 0);
|
||||
|
||||
// all devices with wrong ownerName
|
||||
EntityCountQuery wrongTenantNameQuery = new EntityCountQuery(filter, List.of(activeAlarmTimeFilter, wrongOwnerNameFilter));
|
||||
checkEntitiesCount(wrongTenantNameQuery, 0);
|
||||
|
||||
// all devices with owner type = TENANT
|
||||
EntityCountQuery tenantEntitiesQuery = new EntityCountQuery(filter, List.of(activeAlarmTimeFilter, tenantOwnerTypeFilter));
|
||||
checkEntitiesCount(tenantEntitiesQuery, numOfDevices);
|
||||
|
||||
// all devices with owner type = CUSTOMER
|
||||
EntityCountQuery customerEntitiesQuery = new EntityCountQuery(filter, List.of(activeAlarmTimeFilter, customerOwnerTypeFilter));
|
||||
checkEntitiesCount(customerEntitiesQuery, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindDevicesByOwnerNameAndOwnerType() throws Exception {
|
||||
loginTenantAdmin();
|
||||
int numOfDevices = 3;
|
||||
|
||||
for (int i = 0; i < numOfDevices; i++) {
|
||||
Device device = new Device();
|
||||
String name = "Device" + i;
|
||||
device.setName(name);
|
||||
device.setType("default");
|
||||
|
||||
Device savedDevice = doPost("/api/device?accessToken=" + name, device, Device.class);
|
||||
JsonNode content = JacksonUtil.toJsonNode("{\"alarmActiveTime\": 1" + i + "}");
|
||||
doPost("/api/plugins/telemetry/" + EntityType.DEVICE.name() + "/" + savedDevice.getUuidId() + "/SERVER_SCOPE", content)
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
DeviceTypeFilter filter = new DeviceTypeFilter();
|
||||
filter.setDeviceTypes(List.of("default"));
|
||||
filter.setDeviceNameFilter("");
|
||||
|
||||
KeyFilter activeAlarmTimeFilter = getServerAttributeNumericGreaterThanKeyFilter("alarmActiveTime", 5);
|
||||
KeyFilter tenantOwnerNameFilter = getEntityFieldStringEqualToKeyFilter("ownerName", TEST_TENANT_NAME);
|
||||
KeyFilter wrongOwnerNameFilter = getEntityFieldStringEqualToKeyFilter("ownerName", "wrongName");
|
||||
KeyFilter tenantOwnerTypeFilter = getEntityFieldStringEqualToKeyFilter("ownerType", "TENANT");
|
||||
KeyFilter customerOwnerTypeFilter = getEntityFieldStringEqualToKeyFilter("ownerType", "CUSTOMER");
|
||||
|
||||
EntityDataSortOrder sortOrder = new EntityDataSortOrder(
|
||||
new EntityKey(EntityKeyType.ENTITY_FIELD, "createdTime"), EntityDataSortOrder.Direction.ASC
|
||||
);
|
||||
EntityDataPageLink pageLink = new EntityDataPageLink(10, 0, null, sortOrder);
|
||||
List<EntityKey> entityFields = List.of(new EntityKey(EntityKeyType.ENTITY_FIELD, "name"), new EntityKey(EntityKeyType.ENTITY_FIELD, "ownerName"),
|
||||
new EntityKey(EntityKeyType.ENTITY_FIELD, "ownerType"));
|
||||
List<EntityKey> latestValues = Collections.singletonList(new EntityKey(EntityKeyType.ATTRIBUTE, "alarmActiveTime"));
|
||||
|
||||
// all devices with ownerName = TEST TENANT
|
||||
EntityDataQuery query = new EntityDataQuery(filter, pageLink, entityFields, latestValues, List.of(activeAlarmTimeFilter, tenantOwnerNameFilter));
|
||||
checkEntitiesByQuery(query, numOfDevices, TEST_TENANT_NAME, "TENANT");
|
||||
|
||||
// all devices with wrong ownerName
|
||||
EntityDataQuery wrongTenantNameQuery = new EntityDataQuery(filter, pageLink, entityFields, latestValues, List.of(activeAlarmTimeFilter, wrongOwnerNameFilter));
|
||||
checkEntitiesByQuery(wrongTenantNameQuery, 0, null, null);
|
||||
|
||||
// all devices with owner type = TENANT
|
||||
EntityDataQuery tenantEntitiesQuery = new EntityDataQuery(filter, pageLink, entityFields, latestValues, List.of(activeAlarmTimeFilter, tenantOwnerTypeFilter));
|
||||
checkEntitiesByQuery(tenantEntitiesQuery, numOfDevices, TEST_TENANT_NAME, "TENANT");
|
||||
|
||||
// all devices with owner type = CUSTOMER
|
||||
EntityDataQuery customerEntitiesQuery = new EntityDataQuery(filter, pageLink, entityFields, latestValues, List.of(activeAlarmTimeFilter, customerOwnerTypeFilter));
|
||||
checkEntitiesByQuery(customerEntitiesQuery, 0, null, null);
|
||||
}
|
||||
|
||||
private void checkEntitiesByQuery(EntityDataQuery query, int expectedNumOfDevices, String expectedOwnerName, String expectedOwnerType) throws Exception {
|
||||
Awaitility.await()
|
||||
.alias("data by query")
|
||||
.atMost(30, TimeUnit.SECONDS)
|
||||
.until(() -> {
|
||||
var data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {});
|
||||
var loadedEntities = new ArrayList<>(data.getData());
|
||||
return loadedEntities.size() == expectedNumOfDevices;
|
||||
});
|
||||
if (expectedNumOfDevices == 0) {
|
||||
return;
|
||||
}
|
||||
var data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {});
|
||||
var loadedEntities = new ArrayList<>(data.getData());
|
||||
|
||||
Assert.assertEquals(expectedNumOfDevices, loadedEntities.size());
|
||||
|
||||
for (int i = 0; i < expectedNumOfDevices; i++) {
|
||||
var entity = loadedEntities.get(i);
|
||||
String name = entity.getLatest().get(EntityKeyType.ENTITY_FIELD).getOrDefault("name", new TsValue(0, "Invalid")).getValue();
|
||||
String ownerName = entity.getLatest().get(EntityKeyType.ENTITY_FIELD).getOrDefault("ownerName", new TsValue(0, "Invalid")).getValue();
|
||||
String ownerType = entity.getLatest().get(EntityKeyType.ENTITY_FIELD).getOrDefault("ownerType", new TsValue(0, "Invalid")).getValue();
|
||||
String alarmActiveTime = entity.getLatest().get(EntityKeyType.ATTRIBUTE).getOrDefault("alarmActiveTime", new TsValue(0, "-1")).getValue();
|
||||
|
||||
Assert.assertEquals("Device" + i, name);
|
||||
Assert.assertEquals( expectedOwnerName, ownerName);
|
||||
Assert.assertEquals( expectedOwnerType, ownerType);
|
||||
Assert.assertEquals("1" + i, alarmActiveTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEntitiesCount(EntityCountQuery query, int expectedNumOfDevices) {
|
||||
Awaitility.await()
|
||||
.alias("count by query")
|
||||
.atMost(30, TimeUnit.SECONDS)
|
||||
.until(() -> {
|
||||
var count = doPost("/api/entitiesQuery/count", query, Integer.class);
|
||||
return count == expectedNumOfDevices;
|
||||
});
|
||||
}
|
||||
|
||||
private KeyFilter getEntityFieldStringEqualToKeyFilter(String keyName, String value) {
|
||||
KeyFilter tenantOwnerNameFilter = new KeyFilter();
|
||||
tenantOwnerNameFilter.setKey(new EntityKey(EntityKeyType.ENTITY_FIELD, keyName));
|
||||
StringFilterPredicate ownerNamePredicate = new StringFilterPredicate();
|
||||
ownerNamePredicate.setValue(FilterPredicateValue.fromString(value));
|
||||
ownerNamePredicate.setOperation(StringFilterPredicate.StringOperation.EQUAL);
|
||||
tenantOwnerNameFilter.setPredicate(ownerNamePredicate);
|
||||
return tenantOwnerNameFilter;
|
||||
}
|
||||
|
||||
private KeyFilter getServerAttributeNumericGreaterThanKeyFilter(String attribute, int value) {
|
||||
KeyFilter numericFilter = new KeyFilter();
|
||||
numericFilter.setKey(new EntityKey(EntityKeyType.SERVER_ATTRIBUTE, attribute));
|
||||
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
||||
predicate.setValue(FilterPredicateValue.fromDouble(value));
|
||||
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
||||
numericFilter.setPredicate(predicate);
|
||||
return numericFilter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
|
||||
List<EntityKeyMapping> filterMapping = mappings.stream().filter(EntityKeyMapping::hasFilter)
|
||||
.collect(Collectors.toList());
|
||||
List<EntityKeyMapping> entityFieldsFiltersMapping = filterMapping.stream().filter(mapping -> !mapping.isLatest())
|
||||
List<EntityKeyMapping> entityFieldsFiltersMapping = filterMapping.stream().filter(mapping -> !mapping.isLatest() && mapping.getEntityKeyColumn() != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<EntityKeyMapping> allLatestMappings = mappings.stream().filter(EntityKeyMapping::isLatest)
|
||||
@ -367,6 +367,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
|
||||
|
||||
String entityWhereClause = DefaultEntityQueryRepository.this.buildEntityWhere(ctx, query.getEntityFilter(), entityFieldsFiltersMapping);
|
||||
String aliasWhereQuery = DefaultEntityQueryRepository.this.buildAliasWhereQuery(ctx, query.getEntityFilter(), selectionMapping, "");
|
||||
String latestJoinsCnt = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings, true);
|
||||
String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping, query.getEntityFilter().getType(), entityType);
|
||||
String entityTypeStr;
|
||||
@ -387,7 +388,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
addEntityTableQuery(ctx, query.getEntityFilter()),
|
||||
entityWhereClause,
|
||||
latestJoinsCnt,
|
||||
"");
|
||||
aliasWhereQuery);
|
||||
|
||||
String countQuery = String.format("select count(id) %s", fromClauseCount);
|
||||
|
||||
@ -418,7 +419,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
QueryContext ctx = new QueryContext(new QuerySecurityContext(tenantId, customerId, entityType, ignorePermissionCheck));
|
||||
EntityDataPageLink pageLink = query.getPageLink();
|
||||
|
||||
List<EntityKeyMapping> mappings = EntityKeyMapping.prepareKeyMapping(query);
|
||||
List<EntityKeyMapping> mappings = EntityKeyMapping.prepareKeyMapping(entityType, query);
|
||||
|
||||
List<EntityKeyMapping> selectionMapping = mappings.stream().filter(EntityKeyMapping::isSelection)
|
||||
.collect(Collectors.toList());
|
||||
@ -429,7 +430,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
|
||||
List<EntityKeyMapping> filterMapping = mappings.stream().filter(EntityKeyMapping::hasFilter)
|
||||
.collect(Collectors.toList());
|
||||
List<EntityKeyMapping> entityFieldsFiltersMapping = filterMapping.stream().filter(mapping -> !mapping.isLatest())
|
||||
List<EntityKeyMapping> entityFieldsFiltersMapping = filterMapping.stream().filter(mapping -> !mapping.isLatest() && mapping.getEntityKeyColumn() != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<EntityKeyMapping> allLatestMappings = mappings.stream().filter(EntityKeyMapping::isLatest)
|
||||
@ -439,7 +440,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
String entityWhereClause = DefaultEntityQueryRepository.this.buildEntityWhere(ctx, query.getEntityFilter(), entityFieldsFiltersMapping);
|
||||
String latestJoinsCnt = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings, true);
|
||||
String latestJoinsData = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings, false);
|
||||
String textSearchQuery = DefaultEntityQueryRepository.this.buildTextSearchQuery(ctx, selectionMapping, pageLink.getTextSearch());
|
||||
String aliasWhereQuery = DefaultEntityQueryRepository.this.buildAliasWhereQuery(ctx, query.getEntityFilter(), selectionMapping, pageLink.getTextSearch());
|
||||
String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping, query.getEntityFilter().getType(), entityType);
|
||||
String entityTypeStr;
|
||||
if (query.getEntityFilter().getType().equals(EntityFilterType.RELATIONS_QUERY)) {
|
||||
@ -465,7 +466,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
addEntityTableQuery(ctx, query.getEntityFilter()),
|
||||
entityWhereClause,
|
||||
latestJoinsCnt,
|
||||
textSearchQuery);
|
||||
aliasWhereQuery);
|
||||
|
||||
String fromClauseData = String.format("from (select %s from (select %s from %s e where %s) entities %s ) result %s",
|
||||
topSelection,
|
||||
@ -473,7 +474,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
addEntityTableQuery(ctx, query.getEntityFilter()),
|
||||
entityWhereClause,
|
||||
latestJoinsData,
|
||||
textSearchQuery);
|
||||
aliasWhereQuery);
|
||||
|
||||
if (!StringUtils.isEmpty(pageLink.getTextSearch())) {
|
||||
//Unfortunately, we need to sacrifice performance in case of full text search, because it is applied to all joined records.
|
||||
@ -800,6 +801,21 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
return from;
|
||||
}
|
||||
|
||||
private String buildAliasWhereQuery(QueryContext ctx, EntityFilter entityFilter, List<EntityKeyMapping> selectionMapping, String searchText) {
|
||||
List<EntityKeyMapping> aliasFiltersMapping = selectionMapping.stream().filter(mapping -> !mapping.isLatest() && mapping.getEntityKeyColumn() == null)
|
||||
.collect(Collectors.toList());
|
||||
String entityFieldsQuery = EntityKeyMapping.buildQuery(ctx, aliasFiltersMapping, entityFilter.getType());
|
||||
String searchTextQuery = buildTextSearchQuery(ctx, selectionMapping, searchText);
|
||||
String result = "";
|
||||
if (!entityFieldsQuery.isEmpty()) {
|
||||
result += " where (" + entityFieldsQuery + ")";
|
||||
}
|
||||
if (!searchTextQuery.isEmpty()) {
|
||||
result += (result.isEmpty() ? " where ": " and ") + "(" + searchTextQuery + ") ";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String buildTextSearchQuery(QueryContext ctx, List<EntityKeyMapping> selectionMapping, String searchText) {
|
||||
if (!StringUtils.isEmpty(searchText) && !selectionMapping.isEmpty()) {
|
||||
String sqlSearchText = "%" + searchText + "%";
|
||||
@ -811,7 +827,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
|
||||
} else {
|
||||
searchAliasesExpression = searchAliases.get(0);
|
||||
}
|
||||
return String.format(" WHERE %s ILIKE :%s", searchAliasesExpression, "lowerSearchTextParam");
|
||||
return String.format(" %s ILIKE :%s", searchAliasesExpression, "lowerSearchTextParam");
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ import org.thingsboard.server.dao.model.ModelConstants;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -48,6 +49,8 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.thingsboard.server.common.data.StringUtils.splitByCommaWithoutQuotes;
|
||||
import static org.thingsboard.server.common.data.id.EntityId.NULL_UUID;
|
||||
import static org.thingsboard.server.dao.sql.query.DefaultEntityQueryRepository.resolveEntityType;
|
||||
|
||||
@Data
|
||||
public class EntityKeyMapping {
|
||||
@ -55,6 +58,7 @@ public class EntityKeyMapping {
|
||||
private static final Map<EntityType, Set<String>> allowedEntityFieldMap = new HashMap<>();
|
||||
private static final Map<String, String> entityFieldColumnMap = new HashMap<>();
|
||||
private static final Map<EntityType, Map<String, String>> aliases = new HashMap<>();
|
||||
private static final Map<EntityType, Map<String, String>> propertiesFunctions = new EnumMap<>(EntityType.class);
|
||||
|
||||
public static final String CREATED_TIME = "createdTime";
|
||||
public static final String ENTITY_TYPE = "entityType";
|
||||
@ -77,6 +81,18 @@ public class EntityKeyMapping {
|
||||
public static final String RELATED_PARENT_ID = "parentId";
|
||||
public static final String QUEUE_NAME = "queueName";
|
||||
public static final String SERVICE_ID = "serviceId";
|
||||
public static final String OWNER_NAME = "ownerName";
|
||||
public static final String OWNER_TYPE = "ownerType";
|
||||
public static final String OWNER_NAME_SELECT_QUERY = "case when e.customer_id = '" + NULL_UUID + "' " +
|
||||
"then (select title from tenant where id = e.tenant_id) " +
|
||||
"else (select title from customer where id = e.customer_id) end";
|
||||
public static final String OWNER_TYPE_SELECT_QUERY = "case when e.customer_id = '" + NULL_UUID + "' " +
|
||||
"then 'TENANT' " +
|
||||
"else 'CUSTOMER' end";
|
||||
public static final Map<String, String> ownerPropertiesFunctions = Map.of(
|
||||
OWNER_NAME, OWNER_NAME_SELECT_QUERY,
|
||||
OWNER_TYPE, OWNER_TYPE_SELECT_QUERY
|
||||
);
|
||||
|
||||
public static final List<String> typedEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME, TYPE, ADDITIONAL_INFO);
|
||||
public static final List<String> widgetEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME);
|
||||
@ -145,6 +161,12 @@ public class EntityKeyMapping {
|
||||
aliases.put(EntityType.ENTITY_VIEW, commonEntityAliases);
|
||||
aliases.put(EntityType.WIDGETS_BUNDLE, commonEntityAliases);
|
||||
|
||||
propertiesFunctions.put(EntityType.DEVICE, ownerPropertiesFunctions);
|
||||
propertiesFunctions.put(EntityType.ASSET, ownerPropertiesFunctions);
|
||||
propertiesFunctions.put(EntityType.ENTITY_VIEW, ownerPropertiesFunctions);
|
||||
propertiesFunctions.put(EntityType.USER, ownerPropertiesFunctions);
|
||||
propertiesFunctions.put(EntityType.DASHBOARD, ownerPropertiesFunctions);
|
||||
|
||||
Map<String, String> userEntityAliases = new HashMap<>();
|
||||
userEntityAliases.put(TITLE, EMAIL);
|
||||
userEntityAliases.put(LABEL, EMAIL);
|
||||
@ -155,6 +177,7 @@ public class EntityKeyMapping {
|
||||
private int index;
|
||||
private String alias;
|
||||
private boolean isLatest;
|
||||
private String entityKeyColumn;
|
||||
private boolean isSelection;
|
||||
private boolean isSearchable;
|
||||
private boolean isSortOrder;
|
||||
@ -184,12 +207,14 @@ public class EntityKeyMapping {
|
||||
if (entityKey.getKey().equals("entityType") && !filterType.equals(EntityFilterType.RELATIONS_QUERY)) {
|
||||
return String.format("'%s' as %s", entityType.name(), getValueAlias());
|
||||
} else {
|
||||
Set<String> existingEntityFields = getExistingEntityFields(filterType, entityType);
|
||||
String alias = getEntityFieldAlias(filterType, entityType);
|
||||
if (existingEntityFields.contains(alias)) {
|
||||
String column = entityFieldColumnMap.get(alias);
|
||||
return String.format("cast(e.%s as varchar) as %s", column, getValueAlias());
|
||||
if (getEntityKeyColumn() != null) {
|
||||
return String.format("cast(e.%s as varchar) as %s", getEntityKeyColumn(), getValueAlias());
|
||||
} else {
|
||||
Map<String, String> entityPropertiesFunctions = propertiesFunctions.get(entityType);
|
||||
String entityFieldAlias = getEntityFieldAlias(filterType, entityType);
|
||||
if (entityPropertiesFunctions != null && entityPropertiesFunctions.containsKey(entityFieldAlias)) {
|
||||
return String.format("%s as %s", entityPropertiesFunctions.get(entityFieldAlias), getValueAlias());
|
||||
}
|
||||
return String.format("'' as %s", getValueAlias());
|
||||
}
|
||||
}
|
||||
@ -239,7 +264,7 @@ public class EntityKeyMapping {
|
||||
|
||||
public Stream<String> toQueries(QueryContext ctx, EntityFilterType filterType) {
|
||||
if (hasFilter()) {
|
||||
String keyAlias = entityKey.getType().equals(EntityKeyType.ENTITY_FIELD) ? "e" : alias;
|
||||
String keyAlias = (entityKey.getType().equals(EntityKeyType.ENTITY_FIELD) && getEntityKeyColumn() != null) ? "e" : alias;
|
||||
return keyFilters.stream().map(keyFilter ->
|
||||
this.buildKeyQuery(ctx, keyAlias, keyFilter, filterType));
|
||||
} else {
|
||||
@ -319,7 +344,9 @@ public class EntityKeyMapping {
|
||||
.collect(Collectors.joining(" AND "));
|
||||
}
|
||||
|
||||
public static List<EntityKeyMapping> prepareKeyMapping(EntityDataQuery query) {
|
||||
public static List<EntityKeyMapping> prepareKeyMapping(EntityType entityType, EntityDataQuery query) {
|
||||
EntityFilterType entityFilterType = query.getEntityFilter().getType();
|
||||
|
||||
List<EntityKey> entityFields = query.getEntityFields() != null ? query.getEntityFields() : Collections.emptyList();
|
||||
List<EntityKey> latestValues = query.getLatestValues() != null ? query.getLatestValues() : Collections.emptyList();
|
||||
Map<EntityKey, List<KeyFilter>> filters =
|
||||
@ -335,6 +362,7 @@ public class EntityKeyMapping {
|
||||
mapping.setSelection(true);
|
||||
mapping.setSearchable(!key.getKey().equals(ADDITIONAL_INFO));
|
||||
mapping.setEntityKey(key);
|
||||
mapping.setEntityKeyColumn(entityType, entityFilterType);
|
||||
return mapping;
|
||||
}
|
||||
).collect(Collectors.toList());
|
||||
@ -366,6 +394,7 @@ public class EntityKeyMapping {
|
||||
sortOrderMapping.setEntityKey(sortOrderKey);
|
||||
sortOrderMapping.setSortOrder(true);
|
||||
sortOrderMapping.setIgnore(true);
|
||||
sortOrderMapping.setEntityKeyColumn(entityType, entityFilterType);
|
||||
if (sortOrderKey.getType().equals(EntityKeyType.ENTITY_FIELD)) {
|
||||
entityFieldsMappings.add(sortOrderMapping);
|
||||
} else {
|
||||
@ -393,8 +422,9 @@ public class EntityKeyMapping {
|
||||
mapping.setAlias(String.format("alias%s", index));
|
||||
mapping.setKeyFilters(filters.get(filterField));
|
||||
mapping.setLatest(!filterField.getType().equals(EntityKeyType.ENTITY_FIELD));
|
||||
mapping.setSelection(false);
|
||||
mapping.setEntityKey(filterField);
|
||||
mapping.setEntityKeyColumn(entityType, entityFilterType);
|
||||
mapping.setSelection(mapping.getEntityKeyColumn() == null);
|
||||
mappings.add(mapping);
|
||||
index += 1;
|
||||
}
|
||||
@ -403,7 +433,18 @@ public class EntityKeyMapping {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
private void setEntityKeyColumn(EntityType entityType, EntityFilterType entityFilterType) {
|
||||
Set<String> existingEntityFields = getExistingEntityFields(entityFilterType, entityType);
|
||||
String entityFieldAlias = getEntityFieldAlias(entityFilterType, entityType);
|
||||
if (existingEntityFields.contains(entityFieldAlias)) {
|
||||
entityKeyColumn = entityFieldColumnMap.get(entityFieldAlias);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<EntityKeyMapping> prepareEntityCountKeyMapping(EntityCountQuery query) {
|
||||
EntityType entityType = resolveEntityType(query.getEntityFilter());
|
||||
EntityFilterType entityFilterType = query.getEntityFilter().getType();
|
||||
|
||||
Map<EntityKey, List<KeyFilter>> filters =
|
||||
query.getKeyFilters() != null ?
|
||||
query.getKeyFilters().stream().collect(Collectors.groupingBy(KeyFilter::getKey)) : Collections.emptyMap();
|
||||
@ -416,8 +457,9 @@ public class EntityKeyMapping {
|
||||
mapping.setAlias(String.format("alias%s", index));
|
||||
mapping.setKeyFilters(filters.get(filterField));
|
||||
mapping.setLatest(!filterField.getType().equals(EntityKeyType.ENTITY_FIELD));
|
||||
mapping.setSelection(false);
|
||||
mapping.setEntityKey(filterField);
|
||||
mapping.setEntityKeyColumn(entityType, entityFilterType);
|
||||
mapping.setSelection(mapping.getEntityKeyColumn() == null);
|
||||
mappings.add(mapping);
|
||||
index += 1;
|
||||
}
|
||||
@ -494,30 +536,20 @@ public class EntityKeyMapping {
|
||||
private String buildSimplePredicateQuery(QueryContext ctx, String alias, EntityKey key,
|
||||
KeyFilterPredicate predicate, EntityFilterType filterType) {
|
||||
if (key.getType().equals(EntityKeyType.ENTITY_FIELD)) {
|
||||
Set<String> existingEntityFields = getExistingEntityFields(filterType, ctx.getEntityType());
|
||||
String entityFieldAlias = getEntityFieldAlias(filterType, ctx.getEntityType());
|
||||
String column = null;
|
||||
if (existingEntityFields.contains(entityFieldAlias)) {
|
||||
column = entityFieldColumnMap.get(entityFieldAlias);
|
||||
}
|
||||
if (column != null) {
|
||||
String field = alias + "." + column;
|
||||
if (predicate.getType().equals(FilterPredicateType.NUMERIC)) {
|
||||
return this.buildNumericPredicateQuery(ctx, field, (NumericFilterPredicate) predicate);
|
||||
} else if (predicate.getType().equals(FilterPredicateType.STRING)) {
|
||||
if (key.getKey().equals("entityType") && !filterType.equals(EntityFilterType.RELATIONS_QUERY)) {
|
||||
field = ctx.getEntityType().toString();
|
||||
return this.buildStringPredicateQuery(ctx, field, (StringFilterPredicate) predicate)
|
||||
.replace("lower(" + field, "lower('" + field + "'")
|
||||
.replace(field + " ", "'" + field + "' ");
|
||||
} else {
|
||||
return this.buildStringPredicateQuery(ctx, field, (StringFilterPredicate) predicate);
|
||||
}
|
||||
String field = (getEntityKeyColumn() != null) ? alias + "." + getEntityKeyColumn() : alias;
|
||||
if (predicate.getType().equals(FilterPredicateType.NUMERIC)) {
|
||||
return this.buildNumericPredicateQuery(ctx, field, (NumericFilterPredicate) predicate);
|
||||
} else if (predicate.getType().equals(FilterPredicateType.STRING)) {
|
||||
if (key.getKey().equals("entityType") && !filterType.equals(EntityFilterType.RELATIONS_QUERY)) {
|
||||
field = ctx.getEntityType().toString();
|
||||
return this.buildStringPredicateQuery(ctx, field, (StringFilterPredicate) predicate)
|
||||
.replace("lower(" + field, "lower('" + field + "'")
|
||||
.replace(field + " ", "'" + field + "' ");
|
||||
} else {
|
||||
return this.buildBooleanPredicateQuery(ctx, field, (BooleanFilterPredicate) predicate);
|
||||
return this.buildStringPredicateQuery(ctx, field, (StringFilterPredicate) predicate);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
return this.buildBooleanPredicateQuery(ctx, field, (BooleanFilterPredicate) predicate);
|
||||
}
|
||||
} else {
|
||||
if (predicate.getType().equals(FilterPredicateType.NUMERIC)) {
|
||||
|
||||
@ -766,6 +766,8 @@ export class EntityService {
|
||||
entityFieldKeys.push(entityFields.firstName.keyName);
|
||||
entityFieldKeys.push(entityFields.lastName.keyName);
|
||||
entityFieldKeys.push(entityFields.phone.keyName);
|
||||
entityFieldKeys.push(entityFields.ownerName.keyName);
|
||||
entityFieldKeys.push(entityFields.ownerType.keyName);
|
||||
break;
|
||||
case EntityType.TENANT:
|
||||
case EntityType.CUSTOMER:
|
||||
@ -782,6 +784,8 @@ export class EntityService {
|
||||
case EntityType.ENTITY_VIEW:
|
||||
entityFieldKeys.push(entityFields.name.keyName);
|
||||
entityFieldKeys.push(entityFields.type.keyName);
|
||||
entityFieldKeys.push(entityFields.ownerName.keyName);
|
||||
entityFieldKeys.push(entityFields.ownerType.keyName);
|
||||
break;
|
||||
case EntityType.DEVICE:
|
||||
case EntityType.EDGE:
|
||||
@ -789,9 +793,13 @@ export class EntityService {
|
||||
entityFieldKeys.push(entityFields.name.keyName);
|
||||
entityFieldKeys.push(entityFields.type.keyName);
|
||||
entityFieldKeys.push(entityFields.label.keyName);
|
||||
entityFieldKeys.push(entityFields.ownerName.keyName);
|
||||
entityFieldKeys.push(entityFields.ownerType.keyName);
|
||||
break;
|
||||
case EntityType.DASHBOARD:
|
||||
entityFieldKeys.push(entityFields.title.keyName);
|
||||
entityFieldKeys.push(entityFields.ownerName.keyName);
|
||||
entityFieldKeys.push(entityFields.ownerType.keyName);
|
||||
break;
|
||||
case EntityType.API_USAGE_STATE:
|
||||
entityFieldKeys.push(entityFields.name.keyName);
|
||||
|
||||
@ -171,6 +171,16 @@ export const entityFields: {[fieldName: string]: EntityField} = {
|
||||
keyName: 'serviceId',
|
||||
name: 'entity-field.service-id',
|
||||
value: 'serviceId'
|
||||
},
|
||||
ownerName: {
|
||||
keyName: 'ownerName',
|
||||
name: 'entity-field.owner-name',
|
||||
value: 'ownerName'
|
||||
},
|
||||
ownerType: {
|
||||
keyName: 'ownerType',
|
||||
name: 'entity-field.owner-type',
|
||||
value: 'ownerType'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -2273,7 +2273,9 @@
|
||||
"phone": "Phone",
|
||||
"label": "Label",
|
||||
"queue-name": "Queue name",
|
||||
"service-id": "Service Id"
|
||||
"service-id": "Service Id",
|
||||
"owner-name": "Owner name",
|
||||
"owner-type": "Owner type"
|
||||
},
|
||||
"entity-view": {
|
||||
"entity-view": "Entity view",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user