Showing
46 changed files
with
1745 additions
and
20 deletions
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.controller; | ||
17 | + | ||
18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
19 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
20 | +import org.springframework.web.bind.annotation.RequestBody; | ||
21 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
22 | +import org.springframework.web.bind.annotation.RequestMethod; | ||
23 | +import org.springframework.web.bind.annotation.ResponseBody; | ||
24 | +import org.springframework.web.bind.annotation.RestController; | ||
25 | +import org.thingsboard.server.common.data.exception.ThingsboardException; | ||
26 | +import org.thingsboard.server.common.data.page.PageData; | ||
27 | +import org.thingsboard.server.common.data.query.EntityCountQuery; | ||
28 | +import org.thingsboard.server.common.data.query.EntityData; | ||
29 | +import org.thingsboard.server.common.data.query.EntityDataQuery; | ||
30 | +import org.thingsboard.server.queue.util.TbCoreComponent; | ||
31 | +import org.thingsboard.server.service.query.EntityQueryService; | ||
32 | + | ||
33 | +@RestController | ||
34 | +@TbCoreComponent | ||
35 | +@RequestMapping("/api") | ||
36 | +public class EntityQueryController extends BaseController { | ||
37 | + | ||
38 | + @Autowired | ||
39 | + private EntityQueryService entityQueryService; | ||
40 | + | ||
41 | + | ||
42 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
43 | + @RequestMapping(value = "/entitiesQuery/count", method = RequestMethod.POST) | ||
44 | + @ResponseBody | ||
45 | + public long countEntitiesByQuery(@RequestBody EntityCountQuery query) throws ThingsboardException { | ||
46 | + checkNotNull(query); | ||
47 | + try { | ||
48 | + return this.entityQueryService.countEntitiesByQuery(getCurrentUser(), query); | ||
49 | + } catch (Exception e) { | ||
50 | + throw handleException(e); | ||
51 | + } | ||
52 | + } | ||
53 | + | ||
54 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
55 | + @RequestMapping(value = "/entitiesQuery/find", method = RequestMethod.POST) | ||
56 | + @ResponseBody | ||
57 | + public PageData<EntityData> findEntityDataByQuery(@RequestBody EntityDataQuery query) throws ThingsboardException { | ||
58 | + checkNotNull(query); | ||
59 | + try { | ||
60 | + return this.entityQueryService.findEntityDataByQuery(getCurrentUser(), query); | ||
61 | + } catch (Exception e) { | ||
62 | + throw handleException(e); | ||
63 | + } | ||
64 | + } | ||
65 | +} |
application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.query; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.springframework.beans.factory.annotation.Autowired; | ||
20 | +import org.springframework.stereotype.Service; | ||
21 | +import org.thingsboard.server.common.data.page.PageData; | ||
22 | +import org.thingsboard.server.common.data.query.EntityCountQuery; | ||
23 | +import org.thingsboard.server.common.data.query.EntityData; | ||
24 | +import org.thingsboard.server.common.data.query.EntityDataQuery; | ||
25 | +import org.thingsboard.server.dao.entity.EntityService; | ||
26 | +import org.thingsboard.server.queue.util.TbCoreComponent; | ||
27 | +import org.thingsboard.server.service.security.model.SecurityUser; | ||
28 | + | ||
29 | +@Service | ||
30 | +@Slf4j | ||
31 | +@TbCoreComponent | ||
32 | +public class DefaultEntityQueryService implements EntityQueryService { | ||
33 | + | ||
34 | + @Autowired | ||
35 | + private EntityService entityService; | ||
36 | + | ||
37 | + @Override | ||
38 | + public long countEntitiesByQuery(SecurityUser securityUser, EntityCountQuery query) { | ||
39 | + return entityService.countEntitiesByQuery(securityUser.getTenantId(), securityUser.getCustomerId(), query); | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public PageData<EntityData> findEntityDataByQuery(SecurityUser securityUser, EntityDataQuery query) { | ||
44 | + return entityService.findEntityDataByQuery(securityUser.getTenantId(), securityUser.getCustomerId(), query); | ||
45 | + } | ||
46 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.service.query; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.page.PageData; | ||
19 | +import org.thingsboard.server.common.data.query.EntityCountQuery; | ||
20 | +import org.thingsboard.server.common.data.query.EntityData; | ||
21 | +import org.thingsboard.server.common.data.query.EntityDataQuery; | ||
22 | +import org.thingsboard.server.service.security.model.SecurityUser; | ||
23 | + | ||
24 | +public interface EntityQueryService { | ||
25 | + | ||
26 | + long countEntitiesByQuery(SecurityUser securityUser, EntityCountQuery query); | ||
27 | + | ||
28 | + PageData<EntityData> findEntityDataByQuery(SecurityUser securityUser, EntityDataQuery query); | ||
29 | + | ||
30 | +} |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at | 6 | * You may obtain a copy of the License at |
7 | * | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 9 | * |
10 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.service.telemetry.cmd.v2; | 16 | package org.thingsboard.server.service.telemetry.cmd.v2; |
2 | 17 | ||
3 | import lombok.Data; | 18 | import lombok.Data; |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.service.telemetry.cmd.v2; | 16 | package org.thingsboard.server.service.telemetry.cmd.v2; |
2 | 17 | ||
3 | import lombok.Data; | 18 | import lombok.Data; |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.service.telemetry.cmd.v2; | 16 | package org.thingsboard.server.service.telemetry.cmd.v2; |
2 | 17 | ||
3 | import lombok.Data; | 18 | import lombok.Data; |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.service.telemetry.cmd.v2; | 16 | package org.thingsboard.server.service.telemetry.cmd.v2; |
2 | 17 | ||
3 | import org.thingsboard.server.common.data.kv.Aggregation; | 18 | import org.thingsboard.server.common.data.kv.Aggregation; |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.service.telemetry.cmd.v2; | 16 | package org.thingsboard.server.service.telemetry.cmd.v2; |
2 | 17 | ||
3 | import org.thingsboard.server.common.data.query.EntityKey; | 18 | import org.thingsboard.server.common.data.query.EntityKey; |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.service.telemetry.cmd.v2; | 16 | package org.thingsboard.server.service.telemetry.cmd.v2; |
2 | 17 | ||
3 | import java.util.List; | 18 | import java.util.List; |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at | 6 | * You may obtain a copy of the License at |
7 | * | 7 | * |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | 9 | * |
10 | * Unless required by applicable law or agreed to in writing, software | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.dao.entity; | 16 | package org.thingsboard.server.dao.entity; |
17 | 17 | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
19 | import org.thingsboard.server.common.data.id.EntityId; | 20 | import org.thingsboard.server.common.data.id.EntityId; |
20 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
21 | import org.thingsboard.server.common.data.page.PageData; | 22 | import org.thingsboard.server.common.data.page.PageData; |
@@ -29,8 +30,8 @@ public interface EntityService { | @@ -29,8 +30,8 @@ public interface EntityService { | ||
29 | 30 | ||
30 | void deleteEntityRelations(TenantId tenantId, EntityId entityId); | 31 | void deleteEntityRelations(TenantId tenantId, EntityId entityId); |
31 | 32 | ||
32 | - long countEntitiesByQuery(TenantId tenantId, EntityCountQuery query); | 33 | + long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query); |
33 | 34 | ||
34 | - PageData<EntityData> findEntityDataByQuery(TenantId tenantId, EntityDataQuery query); | 35 | + PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query); |
35 | 36 | ||
36 | } | 37 | } |
common/data/src/main/java/org/thingsboard/server/common/data/query/AssetSearchQueryFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +import java.util.List; | ||
21 | + | ||
22 | +@Data | ||
23 | +public class AssetSearchQueryFilter extends EntitySearchQueryFilter { | ||
24 | + | ||
25 | + @Override | ||
26 | + public EntityFilterType getType() { | ||
27 | + return EntityFilterType.ASSET_SEARCH_QUERY; | ||
28 | + } | ||
29 | + | ||
30 | + private List<String> assetTypes; | ||
31 | + | ||
32 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class AssetTypeFilter implements EntityFilter { | ||
22 | + | ||
23 | + @Override | ||
24 | + public EntityFilterType getType() { | ||
25 | + return EntityFilterType.ASSET_TYPE; | ||
26 | + } | ||
27 | + | ||
28 | + private String assetType; | ||
29 | + | ||
30 | + private String assetNameFilter; | ||
31 | + | ||
32 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/BooleanFilterPredicate.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class BooleanFilterPredicate implements KeyFilterPredicate { | ||
22 | + | ||
23 | + private BooleanOperation operation; | ||
24 | + private boolean value; | ||
25 | + | ||
26 | + @Override | ||
27 | + public FilterPredicateType getType() { | ||
28 | + return FilterPredicateType.BOOLEAN; | ||
29 | + } | ||
30 | + | ||
31 | + public enum BooleanOperation { | ||
32 | + EQUAL, | ||
33 | + NOT_EQUAL | ||
34 | + } | ||
35 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/ComplexFilterPredicate.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +import java.util.List; | ||
21 | + | ||
22 | +@Data | ||
23 | +public class ComplexFilterPredicate implements KeyFilterPredicate { | ||
24 | + | ||
25 | + private ComplexOperation operation; | ||
26 | + private List<KeyFilterPredicate> predicates; | ||
27 | + | ||
28 | + @Override | ||
29 | + public FilterPredicateType getType() { | ||
30 | + return FilterPredicateType.COMPLEX; | ||
31 | + } | ||
32 | + | ||
33 | + public enum ComplexOperation { | ||
34 | + AND, | ||
35 | + OR | ||
36 | + } | ||
37 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/DeviceSearchQueryFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +import java.util.List; | ||
21 | + | ||
22 | +@Data | ||
23 | +public class DeviceSearchQueryFilter extends EntitySearchQueryFilter { | ||
24 | + | ||
25 | + @Override | ||
26 | + public EntityFilterType getType() { | ||
27 | + return EntityFilterType.DEVICE_SEARCH_QUERY; | ||
28 | + } | ||
29 | + | ||
30 | + private List<String> deviceTypes; | ||
31 | + | ||
32 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class DeviceTypeFilter implements EntityFilter { | ||
22 | + | ||
23 | + @Override | ||
24 | + public EntityFilterType getType() { | ||
25 | + return EntityFilterType.DEVICE_TYPE; | ||
26 | + } | ||
27 | + | ||
28 | + private String deviceType; | ||
29 | + | ||
30 | + private String deviceNameFilter; | ||
31 | + | ||
32 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | import lombok.Getter; | 18 | import lombok.Getter; |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | import lombok.Data; | 18 | import lombok.Data; |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | import lombok.Data; | 18 | import lombok.Data; |
4 | -import org.thingsboard.server.common.data.page.SortOrder; | ||
5 | 19 | ||
6 | @Data | 20 | @Data |
7 | public class EntityDataPageLink { | 21 | public class EntityDataPageLink { |
8 | 22 | ||
9 | private final int pageSize; | 23 | private final int pageSize; |
10 | private final int page; | 24 | private final int page; |
11 | - private final SortOrder sortOrder; | 25 | + private final EntityDataSortOrder sortOrder; |
12 | 26 | ||
13 | } | 27 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | import lombok.Getter; | 18 | import lombok.Getter; |
@@ -12,11 +27,18 @@ public class EntityDataQuery extends EntityCountQuery { | @@ -12,11 +27,18 @@ public class EntityDataQuery extends EntityCountQuery { | ||
12 | private final List<EntityKey> entityFields; | 27 | private final List<EntityKey> entityFields; |
13 | @Getter | 28 | @Getter |
14 | private final List<EntityKey> latestValues; | 29 | private final List<EntityKey> latestValues; |
30 | + @Getter | ||
31 | + private final List<KeyFilter> keyFilters; | ||
15 | 32 | ||
16 | - public EntityDataQuery(EntityFilter entityFilter, EntityDataPageLink pageLink, List<EntityKey> entityFields, List<EntityKey> latestValues) { | 33 | + public EntityDataQuery(EntityFilter entityFilter, |
34 | + EntityDataPageLink pageLink, | ||
35 | + List<EntityKey> entityFields, | ||
36 | + List<EntityKey> latestValues, | ||
37 | + List<KeyFilter> keyFilters) { | ||
17 | super(entityFilter); | 38 | super(entityFilter); |
18 | this.pageLink = pageLink; | 39 | this.pageLink = pageLink; |
19 | this.entityFields = entityFields; | 40 | this.entityFields = entityFields; |
20 | this.latestValues = latestValues; | 41 | this.latestValues = latestValues; |
42 | + this.keyFilters = keyFilters; | ||
21 | } | 43 | } |
22 | } | 44 | } |
common/data/src/main/java/org/thingsboard/server/common/data/query/EntityDataSortOrder.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class EntityDataSortOrder { | ||
22 | + | ||
23 | + private final EntityKey key; | ||
24 | + private final Direction direction; | ||
25 | + | ||
26 | + public EntityDataSortOrder(EntityKey key) { | ||
27 | + this(key, Direction.ASC); | ||
28 | + } | ||
29 | + | ||
30 | + public EntityDataSortOrder(EntityKey key, Direction direction) { | ||
31 | + this.key = key; | ||
32 | + this.direction = direction; | ||
33 | + } | ||
34 | + | ||
35 | + public enum Direction { | ||
36 | + ASC, DESC | ||
37 | + } | ||
38 | + | ||
39 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | public interface EntityFilter { | 18 | public interface EntityFilter { |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | public enum EntityFilterType { | 18 | public enum EntityFilterType { |
4 | SINGLE_ENTITY("singleEntity"), | 19 | SINGLE_ENTITY("singleEntity"), |
5 | ENTITY_LIST("entityList"), | 20 | ENTITY_LIST("entityList"), |
6 | - ENTITY_NAME("entityName"); | ||
7 | -// stateEntity = 'stateEntity', | ||
8 | -// assetType = 'assetType', | ||
9 | -// deviceType = 'deviceType', | ||
10 | -// entityViewType = 'entityViewType', | ||
11 | -// relationsQuery = 'relationsQuery', | ||
12 | -// assetSearchQuery = 'assetSearchQuery', | ||
13 | -// deviceSearchQuery = 'deviceSearchQuery', | ||
14 | -// entityViewSearchQuery = 'entityViewSearchQuery' | 21 | + ENTITY_NAME("entityName"), |
22 | + ASSET_TYPE("assetType"), | ||
23 | + DEVICE_TYPE("deviceType"), | ||
24 | + ENTITY_VIEW_TYPE("entityViewType"), | ||
25 | + RELATIONS_QUERY("relationsQuery"), | ||
26 | + ASSET_SEARCH_QUERY("assetSearchQuery"), | ||
27 | + DEVICE_SEARCH_QUERY("deviceSearchQuery"), | ||
28 | + ENTITY_VIEW_SEARCH_QUERY("entityViewSearchQuery"); | ||
15 | 29 | ||
16 | private final String label; | 30 | private final String label; |
17 | 31 |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
3 | public class EntityKey { | 21 | public class EntityKey { |
4 | private EntityKeyType type; | 22 | private EntityKeyType type; |
5 | private String key; | 23 | private String key; |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | public enum EntityKeyType { | 18 | public enum EntityKeyType { |
19 | + ATTRIBUTE, | ||
4 | CLIENT_ATTRIBUTE, | 20 | CLIENT_ATTRIBUTE, |
5 | SHARED_ATTRIBUTE, | 21 | SHARED_ATTRIBUTE, |
6 | SERVER_ATTRIBUTE, | 22 | SERVER_ATTRIBUTE, |
7 | - TIMESERIES, | 23 | + TIME_SERIES, |
8 | ENTITY_FIELD; | 24 | ENTITY_FIELD; |
9 | } | 25 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.EntityType; | ||
20 | +import org.thingsboard.server.common.data.id.EntityId; | ||
21 | + | ||
22 | +import java.util.List; | ||
23 | + | ||
24 | +@Data | ||
25 | +public class EntityListFilter implements EntityFilter { | ||
26 | + @Override | ||
27 | + public EntityFilterType getType() { | ||
28 | + return EntityFilterType.ENTITY_LIST; | ||
29 | + } | ||
30 | + | ||
31 | + private EntityType entityType; | ||
32 | + | ||
33 | + private List<String> entityList; | ||
34 | + | ||
35 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.EntityType; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class EntityNameFilter implements EntityFilter { | ||
23 | + @Override | ||
24 | + public EntityFilterType getType() { | ||
25 | + return EntityFilterType.ENTITY_NAME; | ||
26 | + } | ||
27 | + | ||
28 | + private EntityType entityType; | ||
29 | + | ||
30 | + private String entityNameFilter; | ||
31 | + | ||
32 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/EntitySearchQueryFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.id.EntityId; | ||
20 | +import org.thingsboard.server.common.data.relation.EntitySearchDirection; | ||
21 | + | ||
22 | +@Data | ||
23 | +public abstract class EntitySearchQueryFilter implements EntityFilter { | ||
24 | + | ||
25 | + private EntityId rootEntity; | ||
26 | + private String relationType; | ||
27 | + private EntitySearchDirection direction; | ||
28 | + private int maxLevel; | ||
29 | + private boolean fetchLastLevelOnly; | ||
30 | + | ||
31 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/EntityViewSearchQueryFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +import java.util.List; | ||
21 | + | ||
22 | +@Data | ||
23 | +public class EntityViewSearchQueryFilter extends EntitySearchQueryFilter { | ||
24 | + | ||
25 | + @Override | ||
26 | + public EntityFilterType getType() { | ||
27 | + return EntityFilterType.ENTITY_VIEW_SEARCH_QUERY; | ||
28 | + } | ||
29 | + | ||
30 | + private List<String> entityViewTypes; | ||
31 | + | ||
32 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/EntityViewTypeFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class EntityViewTypeFilter implements EntityFilter { | ||
22 | + | ||
23 | + @Override | ||
24 | + public EntityFilterType getType() { | ||
25 | + return EntityFilterType.ENTITY_VIEW_TYPE; | ||
26 | + } | ||
27 | + | ||
28 | + private String entityViewType; | ||
29 | + | ||
30 | + private String entityViewNameFilter; | ||
31 | + | ||
32 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/FilterPredicateType.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +public enum FilterPredicateType { | ||
19 | + STRING, | ||
20 | + NUMERIC, | ||
21 | + BOOLEAN, | ||
22 | + COMPLEX | ||
23 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class KeyFilter { | ||
22 | + | ||
23 | + private EntityKey key; | ||
24 | + private KeyFilterPredicate predicate; | ||
25 | + | ||
26 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilterPredicate.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +public interface KeyFilterPredicate { | ||
19 | + | ||
20 | + FilterPredicateType getType(); | ||
21 | + | ||
22 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/NumericFilterPredicate.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class NumericFilterPredicate implements KeyFilterPredicate { | ||
22 | + | ||
23 | + private NumericOperation operation; | ||
24 | + private double value; | ||
25 | + | ||
26 | + @Override | ||
27 | + public FilterPredicateType getType() { | ||
28 | + return FilterPredicateType.NUMERIC; | ||
29 | + } | ||
30 | + | ||
31 | + public enum NumericOperation { | ||
32 | + EQUAL, | ||
33 | + NOT_EQUAL, | ||
34 | + GREATER, | ||
35 | + LESS, | ||
36 | + GREATER_OR_EQUAL, | ||
37 | + LESS_OR_EQUAL | ||
38 | + } | ||
39 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/query/RelationsQueryFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.id.EntityId; | ||
20 | +import org.thingsboard.server.common.data.relation.EntitySearchDirection; | ||
21 | +import org.thingsboard.server.common.data.relation.EntityTypeFilter; | ||
22 | + | ||
23 | +import java.util.List; | ||
24 | + | ||
25 | +@Data | ||
26 | +public class RelationsQueryFilter implements EntityFilter { | ||
27 | + | ||
28 | + @Override | ||
29 | + public EntityFilterType getType() { | ||
30 | + return EntityFilterType.RELATIONS_QUERY; | ||
31 | + } | ||
32 | + | ||
33 | + private EntityId rootEntity; | ||
34 | + private EntitySearchDirection direction; | ||
35 | + private List<EntityTypeFilter> filters; | ||
36 | + private int maxLevel; | ||
37 | + private boolean fetchLastLevelOnly; | ||
38 | + | ||
39 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | import lombok.Data; | 18 | import lombok.Data; |
common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +@Data | ||
21 | +public class StringFilterPredicate implements KeyFilterPredicate { | ||
22 | + | ||
23 | + private StringOperation operation; | ||
24 | + private String value; | ||
25 | + private boolean ignoreCase; | ||
26 | + | ||
27 | + @Override | ||
28 | + public FilterPredicateType getType() { | ||
29 | + return FilterPredicateType.STRING; | ||
30 | + } | ||
31 | + | ||
32 | + public enum StringOperation { | ||
33 | + EQUAL, | ||
34 | + NOT_EQUAL, | ||
35 | + STARTS_WITH, | ||
36 | + ENDS_WITH, | ||
37 | + CONTAINS, | ||
38 | + NOT_CONTAINS | ||
39 | + } | ||
40 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
1 | package org.thingsboard.server.common.data.query; | 16 | package org.thingsboard.server.common.data.query; |
2 | 17 | ||
3 | import lombok.Data; | 18 | import lombok.Data; |
@@ -33,6 +33,10 @@ import org.thingsboard.server.common.data.id.EntityViewId; | @@ -33,6 +33,10 @@ import org.thingsboard.server.common.data.id.EntityViewId; | ||
33 | import org.thingsboard.server.common.data.id.RuleChainId; | 33 | import org.thingsboard.server.common.data.id.RuleChainId; |
34 | import org.thingsboard.server.common.data.id.TenantId; | 34 | import org.thingsboard.server.common.data.id.TenantId; |
35 | import org.thingsboard.server.common.data.id.UserId; | 35 | import org.thingsboard.server.common.data.id.UserId; |
36 | +import org.thingsboard.server.common.data.page.PageData; | ||
37 | +import org.thingsboard.server.common.data.query.EntityCountQuery; | ||
38 | +import org.thingsboard.server.common.data.query.EntityData; | ||
39 | +import org.thingsboard.server.common.data.query.EntityDataPageLink; | ||
36 | import org.thingsboard.server.common.data.query.EntityDataQuery; | 40 | import org.thingsboard.server.common.data.query.EntityDataQuery; |
37 | import org.thingsboard.server.dao.alarm.AlarmService; | 41 | import org.thingsboard.server.dao.alarm.AlarmService; |
38 | import org.thingsboard.server.dao.asset.AssetService; | 42 | import org.thingsboard.server.dao.asset.AssetService; |
@@ -40,10 +44,13 @@ import org.thingsboard.server.dao.customer.CustomerService; | @@ -40,10 +44,13 @@ import org.thingsboard.server.dao.customer.CustomerService; | ||
40 | import org.thingsboard.server.dao.dashboard.DashboardService; | 44 | import org.thingsboard.server.dao.dashboard.DashboardService; |
41 | import org.thingsboard.server.dao.device.DeviceService; | 45 | import org.thingsboard.server.dao.device.DeviceService; |
42 | import org.thingsboard.server.dao.entityview.EntityViewService; | 46 | import org.thingsboard.server.dao.entityview.EntityViewService; |
47 | +import org.thingsboard.server.dao.exception.IncorrectParameterException; | ||
43 | import org.thingsboard.server.dao.rule.RuleChainService; | 48 | import org.thingsboard.server.dao.rule.RuleChainService; |
44 | import org.thingsboard.server.dao.tenant.TenantService; | 49 | import org.thingsboard.server.dao.tenant.TenantService; |
45 | import org.thingsboard.server.dao.user.UserService; | 50 | import org.thingsboard.server.dao.user.UserService; |
46 | 51 | ||
52 | +import static org.thingsboard.server.dao.service.Validator.validateId; | ||
53 | + | ||
47 | /** | 54 | /** |
48 | * Created by ashvayka on 04.05.17. | 55 | * Created by ashvayka on 04.05.17. |
49 | */ | 56 | */ |
@@ -51,6 +58,9 @@ import org.thingsboard.server.dao.user.UserService; | @@ -51,6 +58,9 @@ import org.thingsboard.server.dao.user.UserService; | ||
51 | @Slf4j | 58 | @Slf4j |
52 | public class BaseEntityService extends AbstractEntityService implements EntityService { | 59 | public class BaseEntityService extends AbstractEntityService implements EntityService { |
53 | 60 | ||
61 | + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; | ||
62 | + public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; | ||
63 | + | ||
54 | @Autowired | 64 | @Autowired |
55 | private AssetService assetService; | 65 | private AssetService assetService; |
56 | 66 | ||
@@ -78,14 +88,30 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe | @@ -78,14 +88,30 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe | ||
78 | @Autowired | 88 | @Autowired |
79 | private RuleChainService ruleChainService; | 89 | private RuleChainService ruleChainService; |
80 | 90 | ||
91 | + @Autowired | ||
92 | + private EntityQueryDao entityQueryDao; | ||
93 | + | ||
81 | @Override | 94 | @Override |
82 | public void deleteEntityRelations(TenantId tenantId, EntityId entityId) { | 95 | public void deleteEntityRelations(TenantId tenantId, EntityId entityId) { |
83 | super.deleteEntityRelations(tenantId, entityId); | 96 | super.deleteEntityRelations(tenantId, entityId); |
84 | } | 97 | } |
85 | 98 | ||
86 | @Override | 99 | @Override |
87 | - public long countEntitiesByQuery(TenantId tenantId, EntityDataQuery query) { | ||
88 | - return 0; | 100 | + public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) { |
101 | + log.trace("Executing countEntitiesByQuery, tenantId [{}], customerId [{}], query [{}]", tenantId, customerId, query); | ||
102 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
103 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
104 | + validateEntityCountQuery(query); | ||
105 | + return this.entityQueryDao.countEntitiesByQuery(tenantId, customerId, query); | ||
106 | + } | ||
107 | + | ||
108 | + @Override | ||
109 | + public PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query) { | ||
110 | + log.trace("Executing findEntityDataByQuery, tenantId [{}], customerId [{}], query [{}]", tenantId, customerId, query); | ||
111 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
112 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
113 | + validateEntityDataQuery(query); | ||
114 | + return this.entityQueryDao.findEntityDataByQuery(tenantId, customerId, query); | ||
89 | } | 115 | } |
90 | 116 | ||
91 | @Override | 117 | @Override |
@@ -128,4 +154,29 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe | @@ -128,4 +154,29 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe | ||
128 | return entityName; | 154 | return entityName; |
129 | } | 155 | } |
130 | 156 | ||
157 | + private static void validateEntityCountQuery(EntityCountQuery query) { | ||
158 | + if (query == null) { | ||
159 | + throw new IncorrectParameterException("Query must be specified."); | ||
160 | + } else if (query.getEntityFilter() == null) { | ||
161 | + throw new IncorrectParameterException("Query entity filter must be specified."); | ||
162 | + } else if (query.getEntityFilter().getType() == null) { | ||
163 | + throw new IncorrectParameterException("Query entity filter type must be specified."); | ||
164 | + } | ||
165 | + } | ||
166 | + | ||
167 | + private static void validateEntityDataQuery(EntityDataQuery query) { | ||
168 | + validateEntityCountQuery(query); | ||
169 | + validateEntityDataPageLink(query.getPageLink()); | ||
170 | + } | ||
171 | + | ||
172 | + private static void validateEntityDataPageLink(EntityDataPageLink pageLink) { | ||
173 | + if (pageLink == null) { | ||
174 | + throw new IncorrectParameterException("Entity Data Page link must be specified."); | ||
175 | + } else if (pageLink.getPageSize() < 1) { | ||
176 | + throw new IncorrectParameterException("Incorrect entity data page link page size '"+pageLink.getPageSize()+"'. Page size must be greater than zero."); | ||
177 | + } else if (pageLink.getPage() < 0) { | ||
178 | + throw new IncorrectParameterException("Incorrect entity data page link page '"+pageLink.getPage()+"'. Page must be positive integer."); | ||
179 | + } | ||
180 | + } | ||
181 | + | ||
131 | } | 182 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.entity; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
19 | +import org.thingsboard.server.common.data.id.TenantId; | ||
20 | +import org.thingsboard.server.common.data.page.PageData; | ||
21 | +import org.thingsboard.server.common.data.query.EntityCountQuery; | ||
22 | +import org.thingsboard.server.common.data.query.EntityData; | ||
23 | +import org.thingsboard.server.common.data.query.EntityDataQuery; | ||
24 | + | ||
25 | +public interface EntityQueryDao { | ||
26 | + | ||
27 | + long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query); | ||
28 | + | ||
29 | + PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query); | ||
30 | + | ||
31 | +} |
@@ -114,7 +114,6 @@ public class Validator { | @@ -114,7 +114,6 @@ public class Validator { | ||
114 | * <code>IncorrectParameterException</code> exception | 114 | * <code>IncorrectParameterException</code> exception |
115 | * | 115 | * |
116 | * @param pageLink the page link | 116 | * @param pageLink the page link |
117 | - * @param errorMessage the error message for exception | ||
118 | */ | 117 | */ |
119 | public static void validatePageLink(PageLink pageLink) { | 118 | public static void validatePageLink(PageLink pageLink) { |
120 | if (pageLink == null) { | 119 | if (pageLink == null) { |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.sql.query; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.apache.commons.lang3.StringUtils; | ||
20 | +import org.springframework.stereotype.Repository; | ||
21 | +import org.thingsboard.server.common.data.DataConstants; | ||
22 | +import org.thingsboard.server.common.data.EntityType; | ||
23 | +import org.thingsboard.server.common.data.UUIDConverter; | ||
24 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
25 | +import org.thingsboard.server.common.data.id.EntityId; | ||
26 | +import org.thingsboard.server.common.data.id.EntityIdFactory; | ||
27 | +import org.thingsboard.server.common.data.id.TenantId; | ||
28 | +import org.thingsboard.server.common.data.page.PageData; | ||
29 | +import org.thingsboard.server.common.data.query.AssetTypeFilter; | ||
30 | +import org.thingsboard.server.common.data.query.BooleanFilterPredicate; | ||
31 | +import org.thingsboard.server.common.data.query.ComplexFilterPredicate; | ||
32 | +import org.thingsboard.server.common.data.query.DeviceTypeFilter; | ||
33 | +import org.thingsboard.server.common.data.query.EntityCountQuery; | ||
34 | +import org.thingsboard.server.common.data.query.EntityData; | ||
35 | +import org.thingsboard.server.common.data.query.EntityDataPageLink; | ||
36 | +import org.thingsboard.server.common.data.query.EntityDataQuery; | ||
37 | +import org.thingsboard.server.common.data.query.EntityFilter; | ||
38 | +import org.thingsboard.server.common.data.query.EntityKey; | ||
39 | +import org.thingsboard.server.common.data.query.EntityKeyType; | ||
40 | +import org.thingsboard.server.common.data.query.EntityListFilter; | ||
41 | +import org.thingsboard.server.common.data.query.EntityNameFilter; | ||
42 | +import org.thingsboard.server.common.data.query.EntityViewTypeFilter; | ||
43 | +import org.thingsboard.server.common.data.query.FilterPredicateType; | ||
44 | +import org.thingsboard.server.common.data.query.KeyFilter; | ||
45 | +import org.thingsboard.server.common.data.query.KeyFilterPredicate; | ||
46 | +import org.thingsboard.server.common.data.query.NumericFilterPredicate; | ||
47 | +import org.thingsboard.server.common.data.query.SingleEntityFilter; | ||
48 | +import org.thingsboard.server.common.data.query.StringFilterPredicate; | ||
49 | +import org.thingsboard.server.common.data.query.TsValue; | ||
50 | +import org.thingsboard.server.dao.util.SqlDao; | ||
51 | + | ||
52 | +import javax.persistence.EntityManager; | ||
53 | +import javax.persistence.PersistenceContext; | ||
54 | +import java.math.BigInteger; | ||
55 | +import java.util.ArrayList; | ||
56 | +import java.util.Collections; | ||
57 | +import java.util.HashMap; | ||
58 | +import java.util.List; | ||
59 | +import java.util.Map; | ||
60 | +import java.util.Set; | ||
61 | +import java.util.UUID; | ||
62 | +import java.util.stream.Collectors; | ||
63 | + | ||
64 | +@SqlDao | ||
65 | +@Repository | ||
66 | +@Slf4j | ||
67 | +public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
68 | + | ||
69 | + private static final Map<String, String> entityFieldColumnMap = new HashMap<>(); | ||
70 | + static { | ||
71 | + entityFieldColumnMap.put("createdTime", "id"); | ||
72 | + entityFieldColumnMap.put("name", "name"); | ||
73 | + entityFieldColumnMap.put("type", "type"); | ||
74 | + entityFieldColumnMap.put("label", "label"); | ||
75 | + entityFieldColumnMap.put("firstName", "first_name"); | ||
76 | + entityFieldColumnMap.put("lastName", "last_name"); | ||
77 | + entityFieldColumnMap.put("email", "email"); | ||
78 | + entityFieldColumnMap.put("title", "title"); | ||
79 | + entityFieldColumnMap.put("country", "country"); | ||
80 | + entityFieldColumnMap.put("state", "state"); | ||
81 | + entityFieldColumnMap.put("city", "city"); | ||
82 | + entityFieldColumnMap.put("address", "address"); | ||
83 | + entityFieldColumnMap.put("address2", "address2"); | ||
84 | + entityFieldColumnMap.put("zip", "zip"); | ||
85 | + entityFieldColumnMap.put("phone", "phone"); | ||
86 | + } | ||
87 | + | ||
88 | + private static final Map<EntityType, String> entityTableMap = new HashMap<>(); | ||
89 | + static { | ||
90 | + entityTableMap.put(EntityType.ASSET, "asset"); | ||
91 | + entityTableMap.put(EntityType.DEVICE, "device"); | ||
92 | + entityTableMap.put(EntityType.ENTITY_VIEW, "entity_view"); | ||
93 | + entityTableMap.put(EntityType.DASHBOARD, "dashboard"); | ||
94 | + entityTableMap.put(EntityType.CUSTOMER, "customer"); | ||
95 | + entityTableMap.put(EntityType.USER, "tb_user"); | ||
96 | + entityTableMap.put(EntityType.TENANT, "tenant"); | ||
97 | + } | ||
98 | + | ||
99 | + @PersistenceContext | ||
100 | + private EntityManager entityManager; | ||
101 | + | ||
102 | + @Override | ||
103 | + public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) { | ||
104 | + EntityType entityType = resolveEntityType(query.getEntityFilter()); | ||
105 | + String countQuery = String.format("select count(e.id) from %s e where %s", | ||
106 | + entityTableMap.get(entityType), this.buildEntityWhere(tenantId, customerId, query.getEntityFilter(), | ||
107 | + Collections.emptyList(), entityType)); | ||
108 | + return ((BigInteger)entityManager.createNativeQuery(countQuery) | ||
109 | + .getSingleResult()).longValue(); | ||
110 | + } | ||
111 | + | ||
112 | + @Override | ||
113 | + public PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query) { | ||
114 | + EntityType entityType = resolveEntityType(query.getEntityFilter()); | ||
115 | + | ||
116 | + List<EntityKeyMapping> mappings = prepareKeyMapping(query); | ||
117 | + | ||
118 | + List<EntityKeyMapping> selectionMapping = mappings.stream().filter(mapping -> mapping.isSelection()) | ||
119 | + .collect(Collectors.toList()); | ||
120 | + List<EntityKeyMapping> entityFieldsSelectionMapping = selectionMapping.stream().filter(mapping -> !mapping.isLatest()) | ||
121 | + .collect(Collectors.toList()); | ||
122 | + List<EntityKeyMapping> latestSelectionMapping = selectionMapping.stream().filter(mapping -> mapping.isLatest()) | ||
123 | + .collect(Collectors.toList()); | ||
124 | + | ||
125 | + List<EntityKeyMapping> filterMapping = mappings.stream().filter(mapping -> mapping.hasFilter()) | ||
126 | + .collect(Collectors.toList()); | ||
127 | + List<EntityKeyMapping> entityFieldsFiltersMapping = filterMapping.stream().filter(mapping -> !mapping.isLatest()) | ||
128 | + .collect(Collectors.toList()); | ||
129 | + List<EntityKeyMapping> latestFiltersMapping = filterMapping.stream().filter(mapping -> mapping.isLatest()) | ||
130 | + .collect(Collectors.toList()); | ||
131 | + | ||
132 | + List<EntityKeyMapping> allLatestMappings = mappings.stream().filter(mapping -> mapping.isLatest()) | ||
133 | + .collect(Collectors.toList()); | ||
134 | + | ||
135 | + | ||
136 | + String entityWhereClause = this.buildEntityWhere(tenantId, customerId, query.getEntityFilter(), entityFieldsFiltersMapping, entityType); | ||
137 | + String latestJoins = this.buildLatestJoins(entityType, allLatestMappings); | ||
138 | + String latestFilters = this.buildLatestQuery(latestFiltersMapping); | ||
139 | + | ||
140 | + String countQuery = String.format("select count(*) from (select e.id from %s e where %s) entities %s", | ||
141 | + entityTableMap.get(entityType), entityWhereClause, latestJoins); | ||
142 | + if (!StringUtils.isEmpty(latestFilters)) { | ||
143 | + countQuery = String.format("%s where %s", countQuery, latestFilters); | ||
144 | + } | ||
145 | + int totalElements = ((BigInteger)entityManager.createNativeQuery(countQuery) | ||
146 | + .getSingleResult()).intValue(); | ||
147 | + | ||
148 | + String entityFieldsSelection = this.buildEntityFieldsSelection(entityFieldsSelectionMapping); | ||
149 | + if (!StringUtils.isEmpty(entityFieldsSelection)) { | ||
150 | + entityFieldsSelection = String.format("e.id, %s", entityFieldsSelection); | ||
151 | + } else { | ||
152 | + entityFieldsSelection = "e.id"; | ||
153 | + } | ||
154 | + String latestSelection = this.buildLatestSelections(latestSelectionMapping); | ||
155 | + String topSelection = "entities.*"; | ||
156 | + if (!StringUtils.isEmpty(latestSelection)) { | ||
157 | + topSelection = topSelection + ", " + latestSelection; | ||
158 | + } | ||
159 | + | ||
160 | + String dataQuery = String.format("select %s from (select %s from %s e where %s) entities %s", topSelection, | ||
161 | + entityFieldsSelection, | ||
162 | + entityTableMap.get(entityType), | ||
163 | + entityWhereClause, | ||
164 | + latestJoins); | ||
165 | + | ||
166 | + if (!StringUtils.isEmpty(latestFilters)) { | ||
167 | + dataQuery = String.format("%s where %s", dataQuery, latestFilters); | ||
168 | + } | ||
169 | + | ||
170 | + EntityDataPageLink pageLink = query.getPageLink(); | ||
171 | + | ||
172 | + // TODO: order by | ||
173 | + | ||
174 | + int startIndex = pageLink.getPageSize() * pageLink.getPage(); | ||
175 | + if (pageLink.getPageSize() > 0) { | ||
176 | + dataQuery = String.format("%s limit %s offset %s", dataQuery, pageLink.getPageSize(), startIndex); | ||
177 | + } | ||
178 | + List result = entityManager.createNativeQuery(dataQuery).getResultList(); | ||
179 | + int totalPages = pageLink.getPageSize() > 0 ? (int)Math.ceil((float)totalElements / pageLink.getPageSize()) : 1; | ||
180 | + boolean hasNext = pageLink.getPageSize() > 0 && totalElements > startIndex + result.size(); | ||
181 | + List<EntityData> entitiesData = convertListToEntityData(result, entityType, selectionMapping); | ||
182 | + return new PageData<>(entitiesData, totalPages, totalElements, hasNext); | ||
183 | + } | ||
184 | + | ||
185 | + private List<EntityData> convertListToEntityData(List<Object> result, EntityType entityType, List<EntityKeyMapping> selectionMapping) { | ||
186 | + return result.stream().map(obj -> this.toEntityData(obj, entityType, selectionMapping)).collect(Collectors.toList()); | ||
187 | + } | ||
188 | + | ||
189 | + private EntityData toEntityData(Object obj, EntityType entityType, List<EntityKeyMapping> selectionMapping) { | ||
190 | + String id = obj instanceof String ? (String)obj : (String)((Object[]) obj)[0]; | ||
191 | + EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, UUIDConverter.fromString(id)); | ||
192 | + Map<EntityKeyType, Map<String, TsValue>> latest = new HashMap<>(); | ||
193 | + Map<String, TsValue[]> timeseries = new HashMap<>(); | ||
194 | + EntityData entityData = new EntityData(entityId, latest, timeseries); | ||
195 | + for (EntityKeyMapping mapping: selectionMapping) { | ||
196 | + Object value = ((Object[]) obj)[mapping.getIndex()]; | ||
197 | + // TODO: | ||
198 | + } | ||
199 | + return entityData; | ||
200 | + } | ||
201 | + | ||
202 | + private List<EntityKeyMapping> prepareKeyMapping(EntityDataQuery query) { | ||
203 | + List<EntityKey> entityFields = query.getEntityFields() != null ? query.getEntityFields() : Collections.emptyList(); | ||
204 | + List<EntityKey> latestValues = query.getLatestValues() != null ? query.getLatestValues() : Collections.emptyList(); | ||
205 | + Map<EntityKey, List<KeyFilter>> filters = | ||
206 | + query.getKeyFilters() != null ? | ||
207 | + query.getKeyFilters().stream().collect(Collectors.groupingBy(KeyFilter::getKey)) : Collections.emptyMap(); | ||
208 | + int index = 1; | ||
209 | + List<EntityKeyMapping> mappings = new ArrayList<>(); | ||
210 | + for (EntityKey entityField : entityFields) { | ||
211 | + EntityKeyMapping mapping = new EntityKeyMapping(); | ||
212 | + mapping.setIndex(index); | ||
213 | + mapping.setAlias(String.format("alias%s", index)); | ||
214 | + mapping.setKeyFilters(filters.remove(entityField)); | ||
215 | + mapping.setLatest(false); | ||
216 | + mapping.setSelection(true); | ||
217 | + mapping.setEntityKey(entityField); | ||
218 | + mappings.add(mapping); | ||
219 | + index++; | ||
220 | + } | ||
221 | + for (EntityKey latestField : latestValues) { | ||
222 | + EntityKeyMapping mapping = new EntityKeyMapping(); | ||
223 | + mapping.setIndex(index); | ||
224 | + mapping.setAlias(String.format("alias%s", index)); | ||
225 | + mapping.setKeyFilters(filters.remove(latestField)); | ||
226 | + mapping.setLatest(true); | ||
227 | + mapping.setSelection(true); | ||
228 | + mapping.setEntityKey(latestField); | ||
229 | + mappings.add(mapping); | ||
230 | + index +=2; | ||
231 | + } | ||
232 | + if (!filters.isEmpty()) { | ||
233 | + for (EntityKey filterField : filters.keySet()) { | ||
234 | + EntityKeyMapping mapping = new EntityKeyMapping(); | ||
235 | + mapping.setIndex(index); | ||
236 | + mapping.setAlias(String.format("alias%s", index)); | ||
237 | + mapping.setKeyFilters(filters.get(filterField)); | ||
238 | + mapping.setLatest(!filterField.getType().equals(EntityKeyType.ENTITY_FIELD)); | ||
239 | + mapping.setSelection(false); | ||
240 | + mapping.setEntityKey(filterField); | ||
241 | + mappings.add(mapping); | ||
242 | + index +=1; | ||
243 | + } | ||
244 | + } | ||
245 | + return mappings; | ||
246 | + } | ||
247 | + | ||
248 | + private String buildEntityFieldsSelection(List<EntityKeyMapping> entityFieldsSelectionMapping) { | ||
249 | + return entityFieldsSelectionMapping.stream().map(mapping -> { | ||
250 | + String column = entityFieldColumnMap.get(mapping.getEntityKey().getKey()); | ||
251 | + return String.format("e.%s as %s", column, mapping.getAlias()); | ||
252 | + }).collect( | ||
253 | + Collectors.joining(", ")); | ||
254 | + } | ||
255 | + | ||
256 | + private String buildLatestSelections(List<EntityKeyMapping> latestSelectionMapping) { | ||
257 | + return latestSelectionMapping.stream().map(mapping -> this.buildLatestSelection(mapping)) | ||
258 | + .collect( | ||
259 | + Collectors.joining(", ")); | ||
260 | + } | ||
261 | + | ||
262 | + private String buildLatestSelection(EntityKeyMapping mapping) { | ||
263 | + if (mapping.getEntityKey().getType().equals(EntityKeyType.TIME_SERIES)) { | ||
264 | + return buildTimeseriesSelection(mapping); | ||
265 | + } else { | ||
266 | + return buildAttributeSelection(mapping); | ||
267 | + } | ||
268 | + } | ||
269 | + | ||
270 | + private String buildAttributeSelection(EntityKeyMapping mapping) { | ||
271 | + String alias = mapping.getAlias(); | ||
272 | + String attrValAlias = alias + "_value"; | ||
273 | + String attrTsAlias = alias + "_ts"; | ||
274 | + String attrTsSelection = String.format("%s.last_update_ts as %s", alias, attrTsAlias); | ||
275 | + String attrValSelection = | ||
276 | + String.format("coalesce(cast(%s.bool_v as varchar), '') || " + | ||
277 | + "coalesce(%s.str_v, '') || " + | ||
278 | + "coalesce(cast(%s.long_v as varchar), '') || " + | ||
279 | + "coalesce(cast(%s.dbl_v as varchar), '') || " + | ||
280 | + "coalesce(cast(%s.json_v as varchar), '')) as %s", alias, alias, alias, alias, alias, attrValAlias); | ||
281 | + return String.join(", ", attrTsSelection, attrValSelection); | ||
282 | + } | ||
283 | + | ||
284 | + private String buildTimeseriesSelection(EntityKeyMapping mapping) { | ||
285 | + // TODO: | ||
286 | + String alias = mapping.getAlias(); | ||
287 | + String attrValAlias = alias + "_value"; | ||
288 | + String attrTsAlias = alias + "_ts"; | ||
289 | + return String.format("(select 1) as %s, (select '') as %s", attrTsAlias, attrValAlias); | ||
290 | + } | ||
291 | + | ||
292 | + private String buildLatestJoins(EntityType entityType, List<EntityKeyMapping> latestMappings) { | ||
293 | + return latestMappings.stream().map(mapping -> this.buildLatestJoin(entityType, mapping)).collect( | ||
294 | + Collectors.joining(" ")); | ||
295 | + } | ||
296 | + | ||
297 | + private String buildLatestJoin(EntityType entityType, EntityKeyMapping mapping) { | ||
298 | + String join = mapping.hasFilter() ? "left join" : "left outer join"; | ||
299 | + if (mapping.getEntityKey().getType().equals(EntityKeyType.TIME_SERIES)) { | ||
300 | + // TODO: | ||
301 | + throw new RuntimeException("Not implemented!"); | ||
302 | + } else { | ||
303 | + String alias = mapping.getAlias(); | ||
304 | + String query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.entity_type='%s' AND %s.attribute_key='%s'", | ||
305 | + join, alias, alias, alias, entityType.name(), alias, mapping.getEntityKey().getKey()); | ||
306 | + if (!mapping.getEntityKey().getType().equals(EntityKeyType.ATTRIBUTE)) { | ||
307 | + String scope; | ||
308 | + if (mapping.getEntityKey().getType().equals(EntityKeyType.CLIENT_ATTRIBUTE)) { | ||
309 | + scope = DataConstants.CLIENT_SCOPE; | ||
310 | + } else if (mapping.getEntityKey().getType().equals(EntityKeyType.SHARED_ATTRIBUTE)) { | ||
311 | + scope = DataConstants.SHARED_SCOPE; | ||
312 | + } else { | ||
313 | + scope = DataConstants.SERVER_SCOPE; | ||
314 | + } | ||
315 | + query = String.format("%s AND %s.attribute_type=%s", query, alias, scope); | ||
316 | + } | ||
317 | + return query; | ||
318 | + } | ||
319 | + } | ||
320 | + | ||
321 | + private String buildEntityWhere(TenantId tenantId, | ||
322 | + CustomerId customerId, | ||
323 | + EntityFilter entityFilter, | ||
324 | + List<EntityKeyMapping> entityFieldsFilters, | ||
325 | + EntityType entityType) { | ||
326 | + String permissionQuery = this.buildPermissionQuery(tenantId, customerId, entityType); | ||
327 | + String entityFilterQuery = this.buildEntityFilterQuery(entityFilter); | ||
328 | + if (!entityFieldsFilters.isEmpty()) { | ||
329 | + String entityFieldsQuery = this.buildEntityFieldsQuery(entityFieldsFilters); | ||
330 | + return String.join(" and ", permissionQuery, entityFilterQuery, entityFieldsQuery); | ||
331 | + } else { | ||
332 | + return String.join(" and ", permissionQuery, entityFilterQuery); | ||
333 | + } | ||
334 | + } | ||
335 | + | ||
336 | + private String buildPermissionQuery(TenantId tenantId, CustomerId customerId, EntityType entityType) { | ||
337 | + String permissionQuery = String.format("e.tenant_id=%s", UUIDConverter.fromTimeUUID(tenantId.getId())); | ||
338 | + if (entityType != EntityType.TENANT && entityType != EntityType.CUSTOMER) { | ||
339 | + permissionQuery = String.format("%s and e.customerId=%s", permissionQuery, UUIDConverter.fromTimeUUID(customerId.getId())); | ||
340 | + } | ||
341 | + return permissionQuery; | ||
342 | + } | ||
343 | + | ||
344 | + private String buildEntityFilterQuery(EntityFilter entityFilter) { | ||
345 | + switch (entityFilter.getType()) { | ||
346 | + case SINGLE_ENTITY: | ||
347 | + return this.singleEntityQuery((SingleEntityFilter) entityFilter); | ||
348 | + case ENTITY_LIST: | ||
349 | + return this.entityListQuery((EntityListFilter) entityFilter); | ||
350 | + case ENTITY_NAME: | ||
351 | + return this.entityNameQuery((EntityNameFilter) entityFilter); | ||
352 | + case ASSET_TYPE: | ||
353 | + case DEVICE_TYPE: | ||
354 | + case ENTITY_VIEW_TYPE: | ||
355 | + return this.typeQuery(entityFilter); | ||
356 | + default: | ||
357 | + throw new RuntimeException("Not implemented!"); | ||
358 | + } | ||
359 | + } | ||
360 | + | ||
361 | + private String buildLatestQuery(List<EntityKeyMapping> latestFilters) { | ||
362 | + List<String> latestQueries = new ArrayList<>(); | ||
363 | + for (EntityKeyMapping mapping: latestFilters) { | ||
364 | + latestQueries.addAll(mapping.getKeyFilters().stream().map(keyFilter -> | ||
365 | + this.buildKeyQuery(mapping.getAlias(), keyFilter)) | ||
366 | + .collect(Collectors.toList())); | ||
367 | + } | ||
368 | + return latestQueries.stream().collect(Collectors.joining(" AND ")); | ||
369 | + } | ||
370 | + | ||
371 | + private String buildEntityFieldsQuery(List<EntityKeyMapping> entityFieldsFilters) { | ||
372 | + return entityFieldsFilters.stream().flatMap(mapping -> mapping.getKeyFilters().stream()) | ||
373 | + .map(keyFilter -> this.buildKeyQuery("e", keyFilter)).collect( | ||
374 | + Collectors.joining(" AND ") | ||
375 | + ); | ||
376 | + } | ||
377 | + | ||
378 | + private String buildKeyQuery(String alias, KeyFilter keyFilter) { | ||
379 | + return this.buildPredicateQuery(alias, keyFilter.getKey(), keyFilter.getPredicate()); | ||
380 | + } | ||
381 | + | ||
382 | + private String buildPredicateQuery(String alias, EntityKey key, KeyFilterPredicate predicate) { | ||
383 | + if (predicate.getType().equals(FilterPredicateType.COMPLEX)) { | ||
384 | + return this.buildComplexPredicateQuery(alias, key, (ComplexFilterPredicate)predicate); | ||
385 | + } else { | ||
386 | + return this.buildSimplePredicateQuery(alias, key, predicate); | ||
387 | + } | ||
388 | + } | ||
389 | + | ||
390 | + private String buildComplexPredicateQuery(String alias, EntityKey key, ComplexFilterPredicate predicate) { | ||
391 | + return predicate.getPredicates().stream() | ||
392 | + .map(keyFilterPredicate -> this.buildPredicateQuery(alias, key, keyFilterPredicate)).collect(Collectors.joining( | ||
393 | + " " + predicate.getOperation().name() + " " | ||
394 | + )); | ||
395 | + } | ||
396 | + | ||
397 | + private String buildSimplePredicateQuery(String alias, EntityKey key, KeyFilterPredicate predicate) { | ||
398 | + if (predicate.getType().equals(FilterPredicateType.NUMERIC)) { | ||
399 | + if (key.getType().equals(EntityKeyType.ENTITY_FIELD)) { | ||
400 | + String column = entityFieldColumnMap.get(key.getKey()); | ||
401 | + return this.buildNumericPredicateQuery(alias + "." + column, (NumericFilterPredicate)predicate); | ||
402 | + } else { | ||
403 | + String longQuery = this.buildNumericPredicateQuery(alias + ".long_v", (NumericFilterPredicate)predicate); | ||
404 | + String doubleQuery = this.buildNumericPredicateQuery(alias + ".dbl_v", (NumericFilterPredicate)predicate); | ||
405 | + return String.format("(%s or %s)", longQuery, doubleQuery); | ||
406 | + } | ||
407 | + } else { | ||
408 | + String column; | ||
409 | + if (key.getType().equals(EntityKeyType.ENTITY_FIELD)) { | ||
410 | + column = entityFieldColumnMap.get(key.getKey()); | ||
411 | + } else { | ||
412 | + column = predicate.getType().equals(FilterPredicateType.STRING) ? "str_v" : "bool_v"; | ||
413 | + } | ||
414 | + String field = alias + "." + column; | ||
415 | + if (predicate.getType().equals(FilterPredicateType.STRING)) { | ||
416 | + return this.buildStringPredicateQuery(field, (StringFilterPredicate)predicate); | ||
417 | + } else { | ||
418 | + return this.buildBooleanPredicateQuery(field, (BooleanFilterPredicate)predicate); | ||
419 | + } | ||
420 | + } | ||
421 | + } | ||
422 | + | ||
423 | + private String buildStringPredicateQuery(String field, StringFilterPredicate stringFilterPredicate) { | ||
424 | + String operationField = field; | ||
425 | + String value = stringFilterPredicate.getValue(); | ||
426 | + String stringOperationQuery = ""; | ||
427 | + if (stringFilterPredicate.isIgnoreCase()) { | ||
428 | + value.toLowerCase(); | ||
429 | + operationField = String.format("lower(%s)", operationField); | ||
430 | + } | ||
431 | + switch (stringFilterPredicate.getOperation()) { | ||
432 | + case EQUAL: | ||
433 | + stringOperationQuery = String.format("%s = '%s'", operationField, value); | ||
434 | + break; | ||
435 | + case NOT_EQUAL: | ||
436 | + stringOperationQuery = String.format("%s != '%s'", operationField, value); | ||
437 | + break; | ||
438 | + case STARTS_WITH: | ||
439 | + stringOperationQuery = String.format("%s like '%s%'", operationField, value); | ||
440 | + break; | ||
441 | + case ENDS_WITH: | ||
442 | + stringOperationQuery = String.format("%s like '%%s'", operationField, value); | ||
443 | + break; | ||
444 | + case CONTAINS: | ||
445 | + stringOperationQuery = String.format("%s like '%%s%'", operationField, value); | ||
446 | + break; | ||
447 | + case NOT_CONTAINS: | ||
448 | + stringOperationQuery = String.format("%s not like '%%s%'", operationField, value); | ||
449 | + break; | ||
450 | + } | ||
451 | + return String.format("(%s is not null and %s)", field, stringOperationQuery); | ||
452 | + } | ||
453 | + | ||
454 | + private String buildNumericPredicateQuery(String field, NumericFilterPredicate numericFilterPredicate) { | ||
455 | + double value = numericFilterPredicate.getValue(); | ||
456 | + String numericOperationQuery = ""; | ||
457 | + switch (numericFilterPredicate.getOperation()) { | ||
458 | + case EQUAL: | ||
459 | + numericOperationQuery = String.format("%s = %s", field, value); | ||
460 | + break; | ||
461 | + case NOT_EQUAL: | ||
462 | + numericOperationQuery = String.format("%s != '%s'", field, value); | ||
463 | + break; | ||
464 | + case GREATER: | ||
465 | + numericOperationQuery = String.format("%s > %s", field, value); | ||
466 | + break; | ||
467 | + case GREATER_OR_EQUAL: | ||
468 | + numericOperationQuery = String.format("%s >= %s", field, value); | ||
469 | + break; | ||
470 | + case LESS: | ||
471 | + numericOperationQuery = String.format("%s < %s", field, value); | ||
472 | + break; | ||
473 | + case LESS_OR_EQUAL: | ||
474 | + numericOperationQuery = String.format("%s <= %s", field, value); | ||
475 | + break; | ||
476 | + } | ||
477 | + return String.format("(%s is not null and %s)", field, numericOperationQuery); | ||
478 | + } | ||
479 | + | ||
480 | + private String buildBooleanPredicateQuery(String field, | ||
481 | + BooleanFilterPredicate booleanFilterPredicate) { | ||
482 | + boolean value = booleanFilterPredicate.isValue(); | ||
483 | + String booleanOperationQuery = ""; | ||
484 | + switch (booleanFilterPredicate.getOperation()) { | ||
485 | + case EQUAL: | ||
486 | + booleanOperationQuery = String.format("%s = %s", field, value); | ||
487 | + break; | ||
488 | + case NOT_EQUAL: | ||
489 | + booleanOperationQuery = String.format("%s != %s", field, value); | ||
490 | + break; | ||
491 | + } | ||
492 | + return String.format("(%s is not null and %s)", field, booleanOperationQuery); | ||
493 | + } | ||
494 | + | ||
495 | + private String singleEntityQuery(SingleEntityFilter filter) { | ||
496 | + return String.format("e.id=%s", UUIDConverter.fromTimeUUID(filter.getSingleEntity().getId())); | ||
497 | + } | ||
498 | + | ||
499 | + private String entityListQuery(EntityListFilter filter) { | ||
500 | + return String.format("e.id in (%s)", | ||
501 | + filter.getEntityList().stream().map(UUID::fromString).map(UUIDConverter::fromTimeUUID).collect(Collectors.joining(","))); | ||
502 | + } | ||
503 | + | ||
504 | + private String entityNameQuery(EntityNameFilter filter) { | ||
505 | + return String.format("lower(e.searchText) like lower(concat(%s, '%'))", filter.getEntityNameFilter()); | ||
506 | + } | ||
507 | + | ||
508 | + private String typeQuery(EntityFilter filter) { | ||
509 | + String type; | ||
510 | + String name; | ||
511 | + switch (filter.getType()) { | ||
512 | + case ASSET_TYPE: | ||
513 | + type = ((AssetTypeFilter)filter).getAssetType(); | ||
514 | + name = ((AssetTypeFilter)filter).getAssetNameFilter(); | ||
515 | + break; | ||
516 | + case DEVICE_TYPE: | ||
517 | + type = ((DeviceTypeFilter)filter).getDeviceType(); | ||
518 | + name = ((DeviceTypeFilter)filter).getDeviceNameFilter(); | ||
519 | + break; | ||
520 | + case ENTITY_VIEW_TYPE: | ||
521 | + type = ((EntityViewTypeFilter)filter).getEntityViewType(); | ||
522 | + name = ((EntityViewTypeFilter)filter).getEntityViewNameFilter(); | ||
523 | + break; | ||
524 | + default: | ||
525 | + throw new RuntimeException("Not supported!"); | ||
526 | + } | ||
527 | + return String.format("e.type = %s and lower(e.searchText) like lower(concat(%s, '%'))", type, name); | ||
528 | + } | ||
529 | + | ||
530 | + private EntityType resolveEntityType(EntityFilter entityFilter) { | ||
531 | + switch (entityFilter.getType()) { | ||
532 | + case SINGLE_ENTITY: | ||
533 | + return ((SingleEntityFilter)entityFilter).getSingleEntity().getEntityType(); | ||
534 | + case ENTITY_LIST: | ||
535 | + return ((EntityListFilter)entityFilter).getEntityType(); | ||
536 | + case ENTITY_NAME: | ||
537 | + return ((EntityNameFilter)entityFilter).getEntityType(); | ||
538 | + case ASSET_TYPE: | ||
539 | + case ASSET_SEARCH_QUERY: | ||
540 | + return EntityType.ASSET; | ||
541 | + case DEVICE_TYPE: | ||
542 | + case DEVICE_SEARCH_QUERY: | ||
543 | + return EntityType.DEVICE; | ||
544 | + case ENTITY_VIEW_TYPE: | ||
545 | + case ENTITY_VIEW_SEARCH_QUERY: | ||
546 | + return EntityType.ENTITY_VIEW; | ||
547 | + default: | ||
548 | + throw new RuntimeException("Not implemented!"); | ||
549 | + } | ||
550 | + } | ||
551 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.sql.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.query.EntityKey; | ||
20 | +import org.thingsboard.server.common.data.query.KeyFilter; | ||
21 | + | ||
22 | +import java.util.List; | ||
23 | + | ||
24 | +@Data | ||
25 | +public class EntityKeyMapping { | ||
26 | + private int index; | ||
27 | + private String alias; | ||
28 | + private boolean isLatest; | ||
29 | + private boolean isSelection; | ||
30 | + private List<KeyFilter> keyFilters; | ||
31 | + private EntityKey entityKey; | ||
32 | + | ||
33 | + public boolean hasFilter() { | ||
34 | + return keyFilters != null && !keyFilters.isEmpty(); | ||
35 | + } | ||
36 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.sql.query; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
19 | +import org.thingsboard.server.common.data.id.TenantId; | ||
20 | +import org.thingsboard.server.common.data.page.PageData; | ||
21 | +import org.thingsboard.server.common.data.query.EntityCountQuery; | ||
22 | +import org.thingsboard.server.common.data.query.EntityData; | ||
23 | +import org.thingsboard.server.common.data.query.EntityDataQuery; | ||
24 | + | ||
25 | +public interface EntityQueryRepository { | ||
26 | + | ||
27 | + long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query); | ||
28 | + | ||
29 | + PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query); | ||
30 | + | ||
31 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.sql.query; | ||
17 | + | ||
18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
19 | +import org.springframework.stereotype.Component; | ||
20 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
21 | +import org.thingsboard.server.common.data.id.TenantId; | ||
22 | +import org.thingsboard.server.common.data.page.PageData; | ||
23 | +import org.thingsboard.server.common.data.query.EntityCountQuery; | ||
24 | +import org.thingsboard.server.common.data.query.EntityData; | ||
25 | +import org.thingsboard.server.common.data.query.EntityDataQuery; | ||
26 | +import org.thingsboard.server.dao.entity.EntityQueryDao; | ||
27 | +import org.thingsboard.server.dao.util.SqlDao; | ||
28 | + | ||
29 | +@Component | ||
30 | +@SqlDao | ||
31 | +public class JpaEntityQueryDao implements EntityQueryDao { | ||
32 | + | ||
33 | + @Autowired | ||
34 | + private EntityQueryRepository entityQueryRepository; | ||
35 | + | ||
36 | + @Override | ||
37 | + public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) { | ||
38 | + return entityQueryRepository.countEntitiesByQuery(tenantId, customerId, query); | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query) { | ||
43 | + return entityQueryRepository.findEntityDataByQuery(tenantId, customerId, query); | ||
44 | + } | ||
45 | +} |