Merge pull request #10454 from dashevchenko/ownerName

Added ownerName ENTITY_FIELD to EntityDataQuery
This commit is contained in:
Andrew Shvayka 2024-04-30 11:35:47 +03:00 committed by GitHub
commit ab607ed710
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 270 additions and 39 deletions

View File

@ -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;
}
}

View File

@ -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 "";
}

View File

@ -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)) {

View File

@ -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);

View File

@ -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'
}
};

View File

@ -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",