Showing
9 changed files
with
337 additions
and
156 deletions
@@ -20,12 +20,14 @@ import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; | @@ -20,12 +20,14 @@ import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; | ||
20 | import org.thingsboard.server.dao.util.HsqlDao; | 20 | import org.thingsboard.server.dao.util.HsqlDao; |
21 | import org.thingsboard.server.dao.util.SqlDao; | 21 | import org.thingsboard.server.dao.util.SqlDao; |
22 | 22 | ||
23 | +import javax.persistence.Query; | ||
24 | + | ||
23 | @SqlDao | 25 | @SqlDao |
24 | @HsqlDao | 26 | @HsqlDao |
25 | @Repository | 27 | @Repository |
26 | public class HsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository { | 28 | public class HsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository { |
27 | 29 | ||
28 | - private static final String P_KEY_CONFLICT_STATEMENT = "(component_descriptor.id=I.id)"; | 30 | + private static final String P_KEY_CONFLICT_STATEMENT = "(component_descriptor.id=UUID(I.id))"; |
29 | private static final String UNQ_KEY_CONFLICT_STATEMENT = "(component_descriptor.clazz=I.clazz)"; | 31 | private static final String UNQ_KEY_CONFLICT_STATEMENT = "(component_descriptor.clazz=I.clazz)"; |
30 | 32 | ||
31 | private static final String INSERT_OR_UPDATE_ON_P_KEY_CONFLICT = getInsertString(P_KEY_CONFLICT_STATEMENT); | 33 | private static final String INSERT_OR_UPDATE_ON_P_KEY_CONFLICT = getInsertString(P_KEY_CONFLICT_STATEMENT); |
@@ -37,13 +39,29 @@ public class HsqlComponentDescriptorInsertRepository extends AbstractComponentDe | @@ -37,13 +39,29 @@ public class HsqlComponentDescriptorInsertRepository extends AbstractComponentDe | ||
37 | } | 39 | } |
38 | 40 | ||
39 | @Override | 41 | @Override |
42 | + protected Query getQuery(ComponentDescriptorEntity entity, String query) { | ||
43 | + return entityManager.createNativeQuery(query, ComponentDescriptorEntity.class) | ||
44 | + .setParameter("id", entity.getUuid().toString()) | ||
45 | + .setParameter("created_time", entity.getCreatedTime()) | ||
46 | + .setParameter("actions", entity.getActions()) | ||
47 | + .setParameter("clazz", entity.getClazz()) | ||
48 | + .setParameter("configuration_descriptor", entity.getConfigurationDescriptor().toString()) | ||
49 | + .setParameter("name", entity.getName()) | ||
50 | + .setParameter("scope", entity.getScope().name()) | ||
51 | + .setParameter("search_text", entity.getSearchText()) | ||
52 | + .setParameter("type", entity.getType().name()); | ||
53 | + } | ||
54 | + | ||
55 | + @Override | ||
40 | protected ComponentDescriptorEntity doProcessSaveOrUpdate(ComponentDescriptorEntity entity, String query) { | 56 | protected ComponentDescriptorEntity doProcessSaveOrUpdate(ComponentDescriptorEntity entity, String query) { |
41 | getQuery(entity, query).executeUpdate(); | 57 | getQuery(entity, query).executeUpdate(); |
42 | return entityManager.find(ComponentDescriptorEntity.class, entity.getUuid()); | 58 | return entityManager.find(ComponentDescriptorEntity.class, entity.getUuid()); |
43 | } | 59 | } |
44 | 60 | ||
45 | private static String getInsertString(String conflictStatement) { | 61 | private static String getInsertString(String conflictStatement) { |
46 | - return "MERGE INTO component_descriptor USING (VALUES :id, :created_time, :actions, :clazz, :configuration_descriptor, :name, :scope, :search_text, :type) I (id, craeted_time, actions, clazz, configuration_descriptor, name, scope, search_text, type) ON " + conflictStatement + " WHEN MATCHED THEN UPDATE SET component_descriptor.id = I.id, component_descriptor.actions = I.actions, component_descriptor.clazz = I.clazz, component_descriptor.configuration_descriptor = I.configuration_descriptor, component_descriptor.name = I.name, component_descriptor.scope = I.scope, component_descriptor.search_text = I.search_text, component_descriptor.type = I.type" + | ||
47 | - " WHEN NOT MATCHED THEN INSERT (id, created_time, actions, clazz, configuration_descriptor, name, scope, search_text, type) VALUES (I.id, I.created_time, I.actions, I.clazz, I.configuration_descriptor, I.name, I.scope, I.search_text, I.type)"; | 62 | + return "MERGE INTO component_descriptor USING (VALUES :id, :created_time, :actions, :clazz, :configuration_descriptor, :name, :scope, :search_text, :type) I (id, created_time, actions, clazz, configuration_descriptor, name, scope, search_text, type) ON " |
63 | + + conflictStatement | ||
64 | + + " WHEN MATCHED THEN UPDATE SET component_descriptor.id = UUID(I.id), component_descriptor.actions = I.actions, component_descriptor.clazz = I.clazz, component_descriptor.configuration_descriptor = I.configuration_descriptor, component_descriptor.name = I.name, component_descriptor.scope = I.scope, component_descriptor.search_text = I.search_text, component_descriptor.type = I.type" + | ||
65 | + " WHEN NOT MATCHED THEN INSERT (id, created_time, actions, clazz, configuration_descriptor, name, scope, search_text, type) VALUES (UUID(I.id), I.created_time, I.actions, I.clazz, I.configuration_descriptor, I.name, I.scope, I.search_text, I.type)"; | ||
48 | } | 66 | } |
49 | } | 67 | } |
@@ -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, |
@@ -17,6 +17,8 @@ package org.thingsboard.server.dao.sql.query; | @@ -17,6 +17,8 @@ package org.thingsboard.server.dao.sql.query; | ||
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.apache.commons.lang3.StringUtils; | 19 | import org.apache.commons.lang3.StringUtils; |
20 | +import org.springframework.beans.factory.annotation.Autowired; | ||
21 | +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; | ||
20 | import org.springframework.stereotype.Repository; | 22 | import org.springframework.stereotype.Repository; |
21 | import org.thingsboard.server.common.data.EntityType; | 23 | import org.thingsboard.server.common.data.EntityType; |
22 | import org.thingsboard.server.common.data.id.CustomerId; | 24 | import org.thingsboard.server.common.data.id.CustomerId; |
@@ -44,8 +46,6 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; | @@ -44,8 +46,6 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; | ||
44 | import org.thingsboard.server.common.data.relation.EntityTypeFilter; | 46 | import org.thingsboard.server.common.data.relation.EntityTypeFilter; |
45 | import org.thingsboard.server.dao.util.SqlDao; | 47 | import org.thingsboard.server.dao.util.SqlDao; |
46 | 48 | ||
47 | -import javax.persistence.EntityManager; | ||
48 | -import javax.persistence.PersistenceContext; | ||
49 | import java.math.BigInteger; | 49 | import java.math.BigInteger; |
50 | import java.util.Collections; | 50 | import java.util.Collections; |
51 | import java.util.HashMap; | 51 | import java.util.HashMap; |
@@ -75,7 +75,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -75,7 +75,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
75 | public static final String HIERARCHICAL_QUERY_TEMPLATE = " FROM (WITH RECURSIVE related_entities(from_id, from_type, to_id, to_type, relation_type, lvl) AS (" + | 75 | public static final String HIERARCHICAL_QUERY_TEMPLATE = " FROM (WITH RECURSIVE related_entities(from_id, from_type, to_id, to_type, relation_type, lvl) AS (" + |
76 | " SELECT from_id, from_type, to_id, to_type, relation_type, 1 as lvl" + | 76 | " SELECT from_id, from_type, to_id, to_type, relation_type, 1 as lvl" + |
77 | " FROM relation" + | 77 | " FROM relation" + |
78 | - " WHERE $in_id = '%s' and $in_type = '%s' and relation_type_group = 'COMMON'" + | 78 | + " WHERE $in_id = :relation_root_id and $in_type = :relation_root_type and relation_type_group = 'COMMON'" + |
79 | " UNION ALL" + | 79 | " UNION ALL" + |
80 | " SELECT r.from_id, r.from_type, r.to_id, r.to_type, r.relation_type, lvl + 1" + | 80 | " SELECT r.from_id, r.from_type, r.to_id, r.to_type, r.relation_type, lvl + 1" + |
81 | " FROM relation r" + | 81 | " FROM relation r" + |
@@ -88,21 +88,23 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -88,21 +88,23 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
88 | public static final String HIERARCHICAL_TO_QUERY_TEMPLATE = HIERARCHICAL_QUERY_TEMPLATE.replace("$in", "to").replace("$out", "from"); | 88 | public static final String HIERARCHICAL_TO_QUERY_TEMPLATE = HIERARCHICAL_QUERY_TEMPLATE.replace("$in", "to").replace("$out", "from"); |
89 | public static final String HIERARCHICAL_FROM_QUERY_TEMPLATE = HIERARCHICAL_QUERY_TEMPLATE.replace("$in", "from").replace("$out", "to"); | 89 | public static final String HIERARCHICAL_FROM_QUERY_TEMPLATE = HIERARCHICAL_QUERY_TEMPLATE.replace("$in", "from").replace("$out", "to"); |
90 | 90 | ||
91 | - @PersistenceContext | ||
92 | - private EntityManager entityManager; | 91 | + @Autowired |
92 | + protected NamedParameterJdbcTemplate jdbcTemplate; | ||
93 | 93 | ||
94 | @Override | 94 | @Override |
95 | public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) { | 95 | public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) { |
96 | EntityType entityType = resolveEntityType(query.getEntityFilter()); | 96 | EntityType entityType = resolveEntityType(query.getEntityFilter()); |
97 | - String countQuery = String.format("select count(e.id) from %s e where %s", | ||
98 | - getEntityTableQuery(query.getEntityFilter(), entityType), this.buildEntityWhere(tenantId, customerId, query.getEntityFilter(), | ||
99 | - Collections.emptyList(), entityType)); | ||
100 | - return ((BigInteger) entityManager.createNativeQuery(countQuery) | ||
101 | - .getSingleResult()).longValue(); | 97 | + EntityQueryContext ctx = new EntityQueryContext(); |
98 | + ctx.append("select count(e.id) from "); | ||
99 | + ctx.append(addEntityTableQuery(ctx, query.getEntityFilter(), entityType)); | ||
100 | + ctx.append(" e where "); | ||
101 | + ctx.append(buildEntityWhere(ctx, tenantId, customerId, query.getEntityFilter(), Collections.emptyList(), entityType)); | ||
102 | + return jdbcTemplate.queryForObject(ctx.getQuery(), ctx, Long.class); | ||
102 | } | 103 | } |
103 | 104 | ||
104 | @Override | 105 | @Override |
105 | public PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query) { | 106 | public PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query) { |
107 | + EntityQueryContext ctx = new EntityQueryContext(); | ||
106 | EntityType entityType = resolveEntityType(query.getEntityFilter()); | 108 | EntityType entityType = resolveEntityType(query.getEntityFilter()); |
107 | EntityDataPageLink pageLink = query.getPageLink(); | 109 | EntityDataPageLink pageLink = query.getPageLink(); |
108 | 110 | ||
@@ -126,9 +128,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -126,9 +128,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
126 | .collect(Collectors.toList()); | 128 | .collect(Collectors.toList()); |
127 | 129 | ||
128 | 130 | ||
129 | - String entityWhereClause = this.buildEntityWhere(tenantId, customerId, query.getEntityFilter(), entityFieldsFiltersMapping, entityType); | ||
130 | - String latestJoins = EntityKeyMapping.buildLatestJoins(query.getEntityFilter(), entityType, allLatestMappings); | ||
131 | - String whereClause = this.buildWhere(selectionMapping, latestFiltersMapping, pageLink.getTextSearch()); | 131 | + String entityWhereClause = this.buildEntityWhere(ctx, tenantId, customerId, query.getEntityFilter(), entityFieldsFiltersMapping, entityType); |
132 | + String latestJoins = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings); | ||
133 | + String whereClause = this.buildWhere(ctx, selectionMapping, latestFiltersMapping, pageLink.getTextSearch()); | ||
132 | String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping); | 134 | String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping); |
133 | String entityTypeStr; | 135 | String entityTypeStr; |
134 | if (query.getEntityFilter().getType().equals(EntityFilterType.RELATIONS_QUERY)) { | 136 | if (query.getEntityFilter().getType().equals(EntityFilterType.RELATIONS_QUERY)) { |
@@ -137,9 +139,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -137,9 +139,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
137 | entityTypeStr = "'" + entityType.name() + "'"; | 139 | entityTypeStr = "'" + entityType.name() + "'"; |
138 | } | 140 | } |
139 | if (!StringUtils.isEmpty(entityFieldsSelection)) { | 141 | if (!StringUtils.isEmpty(entityFieldsSelection)) { |
140 | - entityFieldsSelection = String.format("e.id, %s, %s", entityTypeStr, entityFieldsSelection); | 142 | + entityFieldsSelection = String.format("e.id id, %s entity_type, %s", entityTypeStr, entityFieldsSelection); |
141 | } else { | 143 | } else { |
142 | - entityFieldsSelection = String.format("e.id, %s", entityTypeStr); | 144 | + entityFieldsSelection = String.format("e.id id, %s entity_type", entityTypeStr); |
143 | } | 145 | } |
144 | String latestSelection = EntityKeyMapping.buildSelections(latestSelectionMapping); | 146 | String latestSelection = EntityKeyMapping.buildSelections(latestSelectionMapping); |
145 | String topSelection = "entities.*"; | 147 | String topSelection = "entities.*"; |
@@ -150,13 +152,13 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -150,13 +152,13 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
150 | String fromClause = String.format("from (select %s from (select %s from %s e where %s) entities %s %s) result", | 152 | String fromClause = String.format("from (select %s from (select %s from %s e where %s) entities %s %s) result", |
151 | topSelection, | 153 | topSelection, |
152 | entityFieldsSelection, | 154 | entityFieldsSelection, |
153 | - getEntityTableQuery(query.getEntityFilter(), entityType), | 155 | + addEntityTableQuery(ctx, query.getEntityFilter(), entityType), |
154 | entityWhereClause, | 156 | entityWhereClause, |
155 | latestJoins, | 157 | latestJoins, |
156 | whereClause); | 158 | whereClause); |
157 | 159 | ||
158 | - int totalElements = ((BigInteger) entityManager.createNativeQuery(String.format("select count(*) %s", fromClause)) | ||
159 | - .getSingleResult()).intValue(); | 160 | + |
161 | + int totalElements = jdbcTemplate.queryForObject(String.format("select count(*) %s", fromClause), ctx, Integer.class); | ||
160 | 162 | ||
161 | String dataQuery = String.format("select * %s", fromClause); | 163 | String dataQuery = String.format("select * %s", fromClause); |
162 | 164 | ||
@@ -177,17 +179,18 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -177,17 +179,18 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
177 | if (pageLink.getPageSize() > 0) { | 179 | if (pageLink.getPageSize() > 0) { |
178 | dataQuery = String.format("%s limit %s offset %s", dataQuery, pageLink.getPageSize(), startIndex); | 180 | dataQuery = String.format("%s limit %s offset %s", dataQuery, pageLink.getPageSize(), startIndex); |
179 | } | 181 | } |
180 | - List rows = entityManager.createNativeQuery(dataQuery).getResultList(); | 182 | + List<Map<String, Object>> rows = jdbcTemplate.queryForList(dataQuery, ctx); |
181 | return EntityDataAdapter.createEntityData(pageLink, selectionMapping, rows, totalElements); | 183 | return EntityDataAdapter.createEntityData(pageLink, selectionMapping, rows, totalElements); |
182 | } | 184 | } |
183 | 185 | ||
184 | - private String buildEntityWhere(TenantId tenantId, | 186 | + private String buildEntityWhere(EntityQueryContext ctx, |
187 | + TenantId tenantId, | ||
185 | CustomerId customerId, | 188 | CustomerId customerId, |
186 | EntityFilter entityFilter, | 189 | EntityFilter entityFilter, |
187 | List<EntityKeyMapping> entityFieldsFilters, | 190 | List<EntityKeyMapping> entityFieldsFilters, |
188 | EntityType entityType) { | 191 | EntityType entityType) { |
189 | - String permissionQuery = this.buildPermissionQuery(entityFilter, tenantId, customerId, entityType); | ||
190 | - String entityFilterQuery = this.buildEntityFilterQuery(entityFilter); | 192 | + String permissionQuery = this.buildPermissionQuery(ctx, entityFilter, tenantId, customerId, entityType); |
193 | + String entityFilterQuery = this.buildEntityFilterQuery(ctx, entityFilter); | ||
191 | String result = permissionQuery; | 194 | String result = permissionQuery; |
192 | if (!entityFilterQuery.isEmpty()) { | 195 | if (!entityFilterQuery.isEmpty()) { |
193 | result += " and " + entityFilterQuery; | 196 | result += " and " + entityFilterQuery; |
@@ -198,35 +201,42 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -198,35 +201,42 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
198 | return result; | 201 | return result; |
199 | } | 202 | } |
200 | 203 | ||
201 | - private String buildPermissionQuery(EntityFilter entityFilter, TenantId tenantId, CustomerId customerId, EntityType entityType) { | 204 | + private String buildPermissionQuery(EntityQueryContext ctx, EntityFilter entityFilter, TenantId tenantId, CustomerId customerId, EntityType entityType) { |
202 | switch (entityFilter.getType()) { | 205 | switch (entityFilter.getType()) { |
203 | case RELATIONS_QUERY: | 206 | case RELATIONS_QUERY: |
204 | case DEVICE_SEARCH_QUERY: | 207 | case DEVICE_SEARCH_QUERY: |
205 | case ASSET_SEARCH_QUERY: | 208 | case ASSET_SEARCH_QUERY: |
206 | - return String.format("e.tenant_id='%s' and e.customer_id='%s'", tenantId.getId(), customerId.getId()); | 209 | + ctx.addUuidParameter("permissions_tenant_id", tenantId.getId()); |
210 | + ctx.addUuidParameter("permissions_customer_id", customerId.getId()); | ||
211 | + return "e.tenant_id=:permissions_tenant_id and e.customer_id=:permissions_customer_id"; | ||
207 | default: | 212 | default: |
208 | if (entityType == EntityType.TENANT) { | 213 | if (entityType == EntityType.TENANT) { |
209 | - return String.format("e.id='%s'", tenantId.getId()); | 214 | + ctx.addUuidParameter("permissions_tenant_id", tenantId.getId()); |
215 | + return "e.id=:permissions_tenant_id"; | ||
210 | } else if (entityType == EntityType.CUSTOMER) { | 216 | } else if (entityType == EntityType.CUSTOMER) { |
211 | - return String.format("e.tenant_id='%s' and e.id='%s'", tenantId.getId(), customerId.getId()); | 217 | + ctx.addUuidParameter("permissions_tenant_id", tenantId.getId()); |
218 | + ctx.addUuidParameter("permissions_customer_id", customerId.getId()); | ||
219 | + return "e.tenant_id=:permissions_tenant_id and e.id=:permissions_customer_id"; | ||
212 | } else { | 220 | } else { |
213 | - return String.format("e.tenant_id='%s' and e.customer_id='%s'", tenantId.getId(), customerId.getId()); | 221 | + ctx.addUuidParameter("permissions_tenant_id", tenantId.getId()); |
222 | + ctx.addUuidParameter("permissions_customer_id", customerId.getId()); | ||
223 | + return "e.tenant_id=:permissions_tenant_id and e.customer_id=:permissions_customer_id"; | ||
214 | } | 224 | } |
215 | } | 225 | } |
216 | } | 226 | } |
217 | 227 | ||
218 | - private String buildEntityFilterQuery(EntityFilter entityFilter) { | 228 | + private String buildEntityFilterQuery(EntityQueryContext ctx, EntityFilter entityFilter) { |
219 | switch (entityFilter.getType()) { | 229 | switch (entityFilter.getType()) { |
220 | case SINGLE_ENTITY: | 230 | case SINGLE_ENTITY: |
221 | - return this.singleEntityQuery((SingleEntityFilter) entityFilter); | 231 | + return this.singleEntityQuery(ctx, (SingleEntityFilter) entityFilter); |
222 | case ENTITY_LIST: | 232 | case ENTITY_LIST: |
223 | - return this.entityListQuery((EntityListFilter) entityFilter); | 233 | + return this.entityListQuery(ctx, (EntityListFilter) entityFilter); |
224 | case ENTITY_NAME: | 234 | case ENTITY_NAME: |
225 | - return this.entityNameQuery((EntityNameFilter) entityFilter); | 235 | + return this.entityNameQuery(ctx, (EntityNameFilter) entityFilter); |
226 | case ASSET_TYPE: | 236 | case ASSET_TYPE: |
227 | case DEVICE_TYPE: | 237 | case DEVICE_TYPE: |
228 | case ENTITY_VIEW_TYPE: | 238 | case ENTITY_VIEW_TYPE: |
229 | - return this.typeQuery(entityFilter); | 239 | + return this.typeQuery(ctx, entityFilter); |
230 | case RELATIONS_QUERY: | 240 | case RELATIONS_QUERY: |
231 | case DEVICE_SEARCH_QUERY: | 241 | case DEVICE_SEARCH_QUERY: |
232 | case ASSET_SEARCH_QUERY: | 242 | case ASSET_SEARCH_QUERY: |
@@ -236,53 +246,60 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -236,53 +246,60 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
236 | } | 246 | } |
237 | } | 247 | } |
238 | 248 | ||
239 | - private String getEntityTableQuery(EntityFilter entityFilter, EntityType entityType) { | 249 | + private String addEntityTableQuery(EntityQueryContext ctx, EntityFilter entityFilter, EntityType entityType) { |
240 | switch (entityFilter.getType()) { | 250 | switch (entityFilter.getType()) { |
241 | case RELATIONS_QUERY: | 251 | case RELATIONS_QUERY: |
242 | - return relationQuery((RelationsQueryFilter) entityFilter); | 252 | + return relationQuery(ctx, (RelationsQueryFilter) entityFilter); |
243 | case DEVICE_SEARCH_QUERY: | 253 | case DEVICE_SEARCH_QUERY: |
244 | DeviceSearchQueryFilter deviceQuery = (DeviceSearchQueryFilter) entityFilter; | 254 | DeviceSearchQueryFilter deviceQuery = (DeviceSearchQueryFilter) entityFilter; |
245 | - return entitySearchQuery(deviceQuery, EntityType.DEVICE, deviceQuery.getDeviceTypes()); | 255 | + return entitySearchQuery(ctx, deviceQuery, EntityType.DEVICE, deviceQuery.getDeviceTypes()); |
246 | case ASSET_SEARCH_QUERY: | 256 | case ASSET_SEARCH_QUERY: |
247 | AssetSearchQueryFilter assetQuery = (AssetSearchQueryFilter) entityFilter; | 257 | AssetSearchQueryFilter assetQuery = (AssetSearchQueryFilter) entityFilter; |
248 | - return entitySearchQuery(assetQuery, EntityType.ASSET, assetQuery.getAssetTypes()); | 258 | + return entitySearchQuery(ctx, assetQuery, EntityType.ASSET, assetQuery.getAssetTypes()); |
249 | default: | 259 | default: |
250 | return entityTableMap.get(entityType); | 260 | return entityTableMap.get(entityType); |
251 | } | 261 | } |
252 | } | 262 | } |
253 | 263 | ||
254 | - private String entitySearchQuery(EntitySearchQueryFilter entityFilter, EntityType entityType, List<String> types) { | 264 | + private String entitySearchQuery(EntityQueryContext ctx, EntitySearchQueryFilter entityFilter, EntityType entityType, List<String> types) { |
255 | EntityId rootId = entityFilter.getRootEntity(); | 265 | EntityId rootId = entityFilter.getRootEntity(); |
256 | //TODO: fetch last level only. | 266 | //TODO: fetch last level only. |
257 | //TODO: fetch distinct records. | 267 | //TODO: fetch distinct records. |
258 | String lvlFilter = getLvlFilter(entityFilter.getMaxLevel()); | 268 | String lvlFilter = getLvlFilter(entityFilter.getMaxLevel()); |
259 | String selectFields = "SELECT tenant_id, customer_id, id, type, name, label FROM " + entityType.name() + " WHERE id in ( SELECT entity_id"; | 269 | String selectFields = "SELECT tenant_id, customer_id, id, type, name, label FROM " + entityType.name() + " WHERE id in ( SELECT entity_id"; |
260 | String from = getQueryTemplate(entityFilter.getDirection()); | 270 | String from = getQueryTemplate(entityFilter.getDirection()); |
271 | + String whereFilter = " WHERE re.relation_type = :where_relation_type AND re.to_type = :where_entity_type"; | ||
261 | 272 | ||
262 | - String whereFilter = " WHERE " + " re.relation_type = '" + entityFilter.getRelationType() + "'" + | ||
263 | - " AND re.to_type = '" + entityType.name() + "'"; | ||
264 | - from = String.format(from, rootId.getId(), rootId.getEntityType().name(), lvlFilter, whereFilter); | 273 | + from = String.format(from, lvlFilter, whereFilter); |
265 | String query = "( " + selectFields + from + ")"; | 274 | String query = "( " + selectFields + from + ")"; |
266 | if (types != null && !types.isEmpty()) { | 275 | if (types != null && !types.isEmpty()) { |
267 | - query += " and type in (" + types.stream().map(type -> "'" + type + "'").collect(Collectors.joining(", ")) + ")"; | 276 | + query += " and type in (:relation_sub_types)"; |
277 | + ctx.addStringListParameter("relation_sub_types", types); | ||
268 | } | 278 | } |
269 | query += " )"; | 279 | query += " )"; |
280 | + ctx.addUuidParameter("relation_root_id", rootId.getId()); | ||
281 | + ctx.addStringParameter("relation_root_type", rootId.getEntityType().name()); | ||
282 | + ctx.addStringParameter("where_relation_type", entityFilter.getRelationType()); | ||
283 | + ctx.addStringParameter("where_entity_type", entityType.name()); | ||
270 | return query; | 284 | return query; |
271 | } | 285 | } |
272 | 286 | ||
273 | - private String relationQuery(RelationsQueryFilter entityFilter) { | 287 | + private String relationQuery(EntityQueryContext ctx, RelationsQueryFilter entityFilter) { |
274 | EntityId rootId = entityFilter.getRootEntity(); | 288 | EntityId rootId = entityFilter.getRootEntity(); |
275 | String lvlFilter = getLvlFilter(entityFilter.getMaxLevel()); | 289 | String lvlFilter = getLvlFilter(entityFilter.getMaxLevel()); |
276 | String selectFields = getSelectTenantId() + ", " + getSelectCustomerId() + ", " + | 290 | String selectFields = getSelectTenantId() + ", " + getSelectCustomerId() + ", " + |
277 | " entity.entity_id as id," + getSelectType() + ", " + getSelectName() + ", " + | 291 | " entity.entity_id as id," + getSelectType() + ", " + getSelectName() + ", " + |
278 | getSelectLabel() + ", entity.entity_type as entity_type"; | 292 | getSelectLabel() + ", entity.entity_type as entity_type"; |
279 | String from = getQueryTemplate(entityFilter.getDirection()); | 293 | String from = getQueryTemplate(entityFilter.getDirection()); |
294 | + ctx.addUuidParameter("relation_root_id", rootId.getId()); | ||
295 | + ctx.addStringParameter("relation_root_type", rootId.getEntityType().name()); | ||
280 | 296 | ||
281 | StringBuilder whereFilter; | 297 | StringBuilder whereFilter; |
282 | if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) { | 298 | if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) { |
283 | whereFilter = new StringBuilder(" WHERE "); | 299 | whereFilter = new StringBuilder(" WHERE "); |
284 | boolean first = true; | 300 | boolean first = true; |
285 | boolean single = entityFilter.getFilters().size() == 1; | 301 | boolean single = entityFilter.getFilters().size() == 1; |
302 | + int entityTypeFilterIdx = 0; | ||
286 | for (EntityTypeFilter etf : entityFilter.getFilters()) { | 303 | for (EntityTypeFilter etf : entityFilter.getFilters()) { |
287 | if (first) { | 304 | if (first) { |
288 | first = false; | 305 | first = false; |
@@ -290,21 +307,23 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -290,21 +307,23 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
290 | whereFilter.append(" AND "); | 307 | whereFilter.append(" AND "); |
291 | } | 308 | } |
292 | String relationType = etf.getRelationType(); | 309 | String relationType = etf.getRelationType(); |
293 | - String entityTypes = etf.getEntityTypes().stream().map(type -> "'" + type + "'").collect(Collectors.joining(", ")); | ||
294 | if (!single) { | 310 | if (!single) { |
295 | whereFilter.append(" ("); | 311 | whereFilter.append(" ("); |
296 | } | 312 | } |
297 | - whereFilter.append(" re.relation_type = '").append(relationType).append("' and re.") | 313 | + whereFilter.append(" re.relation_type = :where_relation_type").append(entityTypeFilterIdx).append(" and re.") |
298 | .append(entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from") | 314 | .append(entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from") |
299 | - .append("_type in (").append(entityTypes).append(")"); | 315 | + .append("_type in (:where_entity_types").append(entityTypeFilterIdx).append(")"); |
300 | if (!single) { | 316 | if (!single) { |
301 | whereFilter.append(" )"); | 317 | whereFilter.append(" )"); |
302 | } | 318 | } |
319 | + ctx.addStringParameter("where_relation_type" + entityTypeFilterIdx, relationType); | ||
320 | + ctx.addStringListParameter("where_entity_types" + entityTypeFilterIdx, etf.getEntityTypes().stream().map(EntityType::name).collect(Collectors.toList())); | ||
321 | + entityTypeFilterIdx++; | ||
303 | } | 322 | } |
304 | } else { | 323 | } else { |
305 | whereFilter = new StringBuilder(); | 324 | whereFilter = new StringBuilder(); |
306 | } | 325 | } |
307 | - from = String.format(from, rootId.getId(), rootId.getEntityType().name(), lvlFilter, whereFilter); | 326 | + from = String.format(from, lvlFilter, whereFilter); |
308 | return "( " + selectFields + from + ")"; | 327 | return "( " + selectFields + from + ")"; |
309 | } | 328 | } |
310 | 329 | ||
@@ -410,10 +429,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -410,10 +429,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
410 | " END as label"; | 429 | " END as label"; |
411 | } | 430 | } |
412 | 431 | ||
413 | - private String buildWhere | ||
414 | - (List<EntityKeyMapping> selectionMapping, List<EntityKeyMapping> latestFiltersMapping, String searchText) { | ||
415 | - String latestFilters = EntityKeyMapping.buildQuery(latestFiltersMapping); | ||
416 | - String textSearchQuery = this.buildTextSearchQuery(selectionMapping, searchText); | 432 | + private String buildWhere(EntityQueryContext ctx, List<EntityKeyMapping> selectionMapping, List<EntityKeyMapping> latestFiltersMapping, String searchText) { |
433 | + String latestFilters = EntityKeyMapping.buildQuery(ctx, latestFiltersMapping); | ||
434 | + String textSearchQuery = this.buildTextSearchQuery(ctx, selectionMapping, searchText); | ||
417 | String query; | 435 | String query; |
418 | if (!StringUtils.isEmpty(latestFilters) && !StringUtils.isEmpty(textSearchQuery)) { | 436 | if (!StringUtils.isEmpty(latestFilters) && !StringUtils.isEmpty(textSearchQuery)) { |
419 | query = String.join(" AND ", latestFilters, textSearchQuery); | 437 | query = String.join(" AND ", latestFilters, textSearchQuery); |
@@ -429,32 +447,38 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -429,32 +447,38 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
429 | } | 447 | } |
430 | } | 448 | } |
431 | 449 | ||
432 | - private String buildTextSearchQuery(List<EntityKeyMapping> selectionMapping, String searchText) { | 450 | + private String buildTextSearchQuery(EntityQueryContext ctx, List<EntityKeyMapping> selectionMapping, String searchText) { |
433 | if (!StringUtils.isEmpty(searchText) && !selectionMapping.isEmpty()) { | 451 | if (!StringUtils.isEmpty(searchText) && !selectionMapping.isEmpty()) { |
434 | String lowerSearchText = searchText.toLowerCase() + "%"; | 452 | String lowerSearchText = searchText.toLowerCase() + "%"; |
435 | - List<String> searchPredicates = selectionMapping.stream().map(mapping -> String.format("LOWER(%s) LIKE '%s'", | ||
436 | - mapping.getValueAlias(), lowerSearchText)).collect(Collectors.toList()); | 453 | + List<String> searchPredicates = selectionMapping.stream().map(mapping -> { |
454 | + String paramName = mapping.getValueAlias() + "_lowerSearchText"; | ||
455 | + ctx.addStringParameter(paramName, lowerSearchText); | ||
456 | + return String.format("LOWER(%s) LIKE :%s", mapping.getValueAlias(), paramName); | ||
457 | + } | ||
458 | + ).collect(Collectors.toList()); | ||
437 | return String.format("(%s)", String.join(" or ", searchPredicates)); | 459 | return String.format("(%s)", String.join(" or ", searchPredicates)); |
438 | } else { | 460 | } else { |
439 | return null; | 461 | return null; |
440 | } | 462 | } |
463 | + | ||
441 | } | 464 | } |
442 | 465 | ||
443 | - private String singleEntityQuery(SingleEntityFilter filter) { | ||
444 | - return String.format("e.id='%s'", filter.getSingleEntity().getId()); | 466 | + private String singleEntityQuery(EntityQueryContext ctx, SingleEntityFilter filter) { |
467 | + ctx.addUuidParameter("entity_filter_single_entity_id", filter.getSingleEntity().getId()); | ||
468 | + return "e.id=:entity_filter_single_entity_id"; | ||
445 | } | 469 | } |
446 | 470 | ||
447 | - private String entityListQuery(EntityListFilter filter) { | ||
448 | - return String.format("e.id in (%s)", | ||
449 | - filter.getEntityList().stream().map(UUID::fromString) | ||
450 | - .map(s -> String.format("'%s'", s)).collect(Collectors.joining(","))); | 471 | + private String entityListQuery(EntityQueryContext ctx, EntityListFilter filter) { |
472 | + ctx.addUuidListParameter("entity_filter_entity_ids", filter.getEntityList().stream().map(UUID::fromString).collect(Collectors.toList())); | ||
473 | + return "e.id in (:entity_filter_entity_ids)"; | ||
451 | } | 474 | } |
452 | 475 | ||
453 | - private String entityNameQuery(EntityNameFilter filter) { | ||
454 | - return String.format("lower(e.search_text) like lower(concat(%s, '%%'))", filter.getEntityNameFilter()); | 476 | + private String entityNameQuery(EntityQueryContext ctx, EntityNameFilter filter) { |
477 | + ctx.addStringParameter("entity_filter_name_filter", filter.getEntityNameFilter()); | ||
478 | + return "lower(e.search_text) like lower(concat(:entity_filter_name_filter, '%%'))"; | ||
455 | } | 479 | } |
456 | 480 | ||
457 | - private String typeQuery(EntityFilter filter) { | 481 | + private String typeQuery(EntityQueryContext ctx, EntityFilter filter) { |
458 | String type; | 482 | String type; |
459 | String name; | 483 | String name; |
460 | switch (filter.getType()) { | 484 | switch (filter.getType()) { |
@@ -473,7 +497,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -473,7 +497,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
473 | default: | 497 | default: |
474 | throw new RuntimeException("Not supported!"); | 498 | throw new RuntimeException("Not supported!"); |
475 | } | 499 | } |
476 | - return String.format("e.type = '%s' and lower(e.search_text) like lower(concat('%s', '%%'))", type, name); | 500 | + ctx.addStringParameter("entity_filter_type_query_type", type); |
501 | + ctx.addStringParameter("entity_filter_type_query_name", name); | ||
502 | + return "e.type = :entity_filter_type_query_type and lower(e.search_text) like lower(concat(:entity_filter_type_query_name, '%%'))"; | ||
477 | } | 503 | } |
478 | 504 | ||
479 | private EntityType resolveEntityType(EntityFilter entityFilter) { | 505 | private EntityType resolveEntityType(EntityFilter entityFilter) { |
@@ -37,31 +37,30 @@ public class EntityDataAdapter { | @@ -37,31 +37,30 @@ public class EntityDataAdapter { | ||
37 | 37 | ||
38 | public static PageData<EntityData> createEntityData(EntityDataPageLink pageLink, | 38 | public static PageData<EntityData> createEntityData(EntityDataPageLink pageLink, |
39 | List<EntityKeyMapping> selectionMapping, | 39 | List<EntityKeyMapping> selectionMapping, |
40 | - List<Object[]> rows, | 40 | + List<Map<String, Object>> rows, |
41 | int totalElements) { | 41 | int totalElements) { |
42 | - int totalPages = pageLink.getPageSize() > 0 ? (int)Math.ceil((float)totalElements / pageLink.getPageSize()) : 1; | 42 | + int totalPages = pageLink.getPageSize() > 0 ? (int) Math.ceil((float) totalElements / pageLink.getPageSize()) : 1; |
43 | int startIndex = pageLink.getPageSize() * pageLink.getPage(); | 43 | int startIndex = pageLink.getPageSize() * pageLink.getPage(); |
44 | boolean hasNext = pageLink.getPageSize() > 0 && totalElements > startIndex + rows.size(); | 44 | boolean hasNext = pageLink.getPageSize() > 0 && totalElements > startIndex + rows.size(); |
45 | List<EntityData> entitiesData = convertListToEntityData(rows, selectionMapping); | 45 | List<EntityData> entitiesData = convertListToEntityData(rows, selectionMapping); |
46 | return new PageData<>(entitiesData, totalPages, totalElements, hasNext); | 46 | return new PageData<>(entitiesData, totalPages, totalElements, hasNext); |
47 | } | 47 | } |
48 | 48 | ||
49 | - private static List<EntityData> convertListToEntityData(List<Object[]> result, List<EntityKeyMapping> selectionMapping) { | 49 | + private static List<EntityData> convertListToEntityData(List<Map<String, Object>> result, List<EntityKeyMapping> selectionMapping) { |
50 | return result.stream().map(row -> toEntityData(row, selectionMapping)).collect(Collectors.toList()); | 50 | return result.stream().map(row -> toEntityData(row, selectionMapping)).collect(Collectors.toList()); |
51 | } | 51 | } |
52 | 52 | ||
53 | - private static EntityData toEntityData(Object[] row, List<EntityKeyMapping> selectionMapping) { | ||
54 | - ByteBuffer bb = ByteBuffer.wrap((byte[])row[0]); | ||
55 | - UUID id = new UUID(bb.getLong(), bb.getLong()); | ||
56 | - EntityType entityType = EntityType.valueOf((String)row[1]); | 53 | + private static EntityData toEntityData(Map<String, Object> row, List<EntityKeyMapping> selectionMapping) { |
54 | + UUID id = (UUID)row.get("id"); | ||
55 | + EntityType entityType = EntityType.valueOf((String) row.get("entity_type")); | ||
57 | EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, id); | 56 | EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, id); |
58 | Map<EntityKeyType, Map<String, TsValue>> latest = new HashMap<>(); | 57 | Map<EntityKeyType, Map<String, TsValue>> latest = new HashMap<>(); |
59 | Map<String, TsValue[]> timeseries = new HashMap<>(); | 58 | Map<String, TsValue[]> timeseries = new HashMap<>(); |
60 | EntityData entityData = new EntityData(entityId, latest, timeseries); | 59 | EntityData entityData = new EntityData(entityId, latest, timeseries); |
61 | - for (EntityKeyMapping mapping: selectionMapping) { | 60 | + for (EntityKeyMapping mapping : selectionMapping) { |
62 | if (!mapping.isIgnore()) { | 61 | if (!mapping.isIgnore()) { |
63 | EntityKey entityKey = mapping.getEntityKey(); | 62 | EntityKey entityKey = mapping.getEntityKey(); |
64 | - Object value = row[mapping.getIndex()]; | 63 | + Object value = row.get(mapping.getValueAlias()); |
65 | String strValue; | 64 | String strValue; |
66 | long ts; | 65 | long ts; |
67 | if (entityKey.getType().equals(EntityKeyType.ENTITY_FIELD)) { | 66 | if (entityKey.getType().equals(EntityKeyType.ENTITY_FIELD)) { |
@@ -69,7 +68,7 @@ public class EntityDataAdapter { | @@ -69,7 +68,7 @@ public class EntityDataAdapter { | ||
69 | ts = System.currentTimeMillis(); | 68 | ts = System.currentTimeMillis(); |
70 | } else { | 69 | } else { |
71 | strValue = convertValue(value); | 70 | strValue = convertValue(value); |
72 | - Object tsObject = row[mapping.getIndex() + 1]; | 71 | + Object tsObject = row.get(mapping.getTsAlias()); |
73 | ts = tsObject != null ? Long.parseLong(tsObject.toString()) : 0; | 72 | ts = tsObject != null ? Long.parseLong(tsObject.toString()) : 0; |
74 | } | 73 | } |
75 | TsValue tsValue = new TsValue(ts, strValue); | 74 | TsValue tsValue = new TsValue(ts, strValue); |
@@ -72,6 +72,7 @@ public class EntityKeyMapping { | @@ -72,6 +72,7 @@ public class EntityKeyMapping { | ||
72 | private boolean ignore = false; | 72 | private boolean ignore = false; |
73 | private List<KeyFilter> keyFilters; | 73 | private List<KeyFilter> keyFilters; |
74 | private EntityKey entityKey; | 74 | private EntityKey entityKey; |
75 | + private int paramIdx = 0; | ||
75 | 76 | ||
76 | public boolean hasFilter() { | 77 | public boolean hasFilter() { |
77 | return keyFilters != null && !keyFilters.isEmpty(); | 78 | return keyFilters != null && !keyFilters.isEmpty(); |
@@ -100,17 +101,17 @@ public class EntityKeyMapping { | @@ -100,17 +101,17 @@ public class EntityKeyMapping { | ||
100 | } | 101 | } |
101 | } | 102 | } |
102 | 103 | ||
103 | - public Stream<String> toQueries() { | 104 | + public Stream<String> toQueries(EntityQueryContext ctx) { |
104 | if (hasFilter()) { | 105 | if (hasFilter()) { |
105 | String keyAlias = entityKey.getType().equals(EntityKeyType.ENTITY_FIELD) ? "e" : alias; | 106 | String keyAlias = entityKey.getType().equals(EntityKeyType.ENTITY_FIELD) ? "e" : alias; |
106 | return keyFilters.stream().map(keyFilter -> | 107 | return keyFilters.stream().map(keyFilter -> |
107 | - this.buildKeyQuery(keyAlias, keyFilter)); | 108 | + this.buildKeyQuery(ctx, keyAlias, keyFilter)); |
108 | } else { | 109 | } else { |
109 | return null; | 110 | return null; |
110 | } | 111 | } |
111 | } | 112 | } |
112 | 113 | ||
113 | - public String toLatestJoin(EntityFilter entityFilter, EntityType entityType) { | 114 | + public String toLatestJoin(EntityQueryContext ctx, EntityFilter entityFilter, EntityType entityType) { |
114 | String entityTypeStr; | 115 | String entityTypeStr; |
115 | if (entityFilter.getType().equals(EntityFilterType.RELATIONS_QUERY)) { | 116 | if (entityFilter.getType().equals(EntityFilterType.RELATIONS_QUERY)) { |
116 | entityTypeStr = "entities.entity_type"; | 117 | entityTypeStr = "entities.entity_type"; |
@@ -118,12 +119,13 @@ public class EntityKeyMapping { | @@ -118,12 +119,13 @@ public class EntityKeyMapping { | ||
118 | entityTypeStr = "'" + entityType.name() + "'"; | 119 | entityTypeStr = "'" + entityType.name() + "'"; |
119 | } | 120 | } |
120 | String join = hasFilter() ? "left join" : "left outer join"; | 121 | String join = hasFilter() ? "left join" : "left outer join"; |
122 | + ctx.addStringParameter(alias + "_key_id", entityKey.getKey()); | ||
121 | if (entityKey.getType().equals(EntityKeyType.TIME_SERIES)) { | 123 | if (entityKey.getType().equals(EntityKeyType.TIME_SERIES)) { |
122 | - return String.format("%s ts_kv_latest %s ON %s.entity_id=to_uuid(entities.id) AND %s.key = (select key_id from ts_kv_dictionary where key = '%s')", | ||
123 | - join, alias, alias, alias, entityKey.getKey()); | 124 | + return String.format("%s ts_kv_latest %s ON %s.entity_id=to_uuid(entities.id) AND %s.key = (select key_id from ts_kv_dictionary where key = :%s_key_id)", |
125 | + join, alias, alias, alias, alias); | ||
124 | } else { | 126 | } else { |
125 | - String query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.entity_type=%s AND %s.attribute_key='%s'", | ||
126 | - join, alias, alias, alias, entityTypeStr, alias, entityKey.getKey()); | 127 | + String query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.entity_type=%s AND %s.attribute_key=:%s_key_id", |
128 | + join, alias, alias, alias, entityTypeStr, alias, alias); | ||
127 | if (!entityKey.getType().equals(EntityKeyType.ATTRIBUTE)) { | 129 | if (!entityKey.getType().equals(EntityKeyType.ATTRIBUTE)) { |
128 | String scope; | 130 | String scope; |
129 | if (entityKey.getType().equals(EntityKeyType.CLIENT_ATTRIBUTE)) { | 131 | if (entityKey.getType().equals(EntityKeyType.CLIENT_ATTRIBUTE)) { |
@@ -144,13 +146,13 @@ public class EntityKeyMapping { | @@ -144,13 +146,13 @@ public class EntityKeyMapping { | ||
144 | Collectors.joining(", ")); | 146 | Collectors.joining(", ")); |
145 | } | 147 | } |
146 | 148 | ||
147 | - public static String buildLatestJoins(EntityFilter entityFilter, EntityType entityType, List<EntityKeyMapping> latestMappings) { | ||
148 | - return latestMappings.stream().map(mapping -> mapping.toLatestJoin(entityFilter, entityType)).collect( | 149 | + public static String buildLatestJoins(EntityQueryContext ctx, EntityFilter entityFilter, EntityType entityType, List<EntityKeyMapping> latestMappings) { |
150 | + return latestMappings.stream().map(mapping -> mapping.toLatestJoin(ctx, entityFilter, entityType)).collect( | ||
149 | Collectors.joining(" ")); | 151 | Collectors.joining(" ")); |
150 | } | 152 | } |
151 | 153 | ||
152 | - public static String buildQuery(List<EntityKeyMapping> mappings) { | ||
153 | - return mappings.stream().flatMap(EntityKeyMapping::toQueries).collect( | 154 | + public static String buildQuery(EntityQueryContext ctx, List<EntityKeyMapping> mappings) { |
155 | + return mappings.stream().flatMap(mapping -> mapping.toQueries(ctx)).collect( | ||
154 | Collectors.joining(" AND ")); | 156 | Collectors.joining(" AND ")); |
155 | } | 157 | } |
156 | 158 | ||
@@ -262,33 +264,33 @@ public class EntityKeyMapping { | @@ -262,33 +264,33 @@ public class EntityKeyMapping { | ||
262 | return String.join(", ", attrValSelection, attrTsSelection); | 264 | return String.join(", ", attrValSelection, attrTsSelection); |
263 | } | 265 | } |
264 | 266 | ||
265 | - private String buildKeyQuery(String alias, KeyFilter keyFilter) { | ||
266 | - return this.buildPredicateQuery(alias, keyFilter.getKey(), keyFilter.getPredicate()); | 267 | + private String buildKeyQuery(EntityQueryContext ctx, String alias, KeyFilter keyFilter) { |
268 | + return this.buildPredicateQuery(ctx, alias, keyFilter.getKey(), keyFilter.getPredicate()); | ||
267 | } | 269 | } |
268 | 270 | ||
269 | - private String buildPredicateQuery(String alias, EntityKey key, KeyFilterPredicate predicate) { | 271 | + private String buildPredicateQuery(EntityQueryContext ctx, String alias, EntityKey key, KeyFilterPredicate predicate) { |
270 | if (predicate.getType().equals(FilterPredicateType.COMPLEX)) { | 272 | if (predicate.getType().equals(FilterPredicateType.COMPLEX)) { |
271 | - return this.buildComplexPredicateQuery(alias, key, (ComplexFilterPredicate) predicate); | 273 | + return this.buildComplexPredicateQuery(ctx, alias, key, (ComplexFilterPredicate) predicate); |
272 | } else { | 274 | } else { |
273 | - return this.buildSimplePredicateQuery(alias, key, predicate); | 275 | + return this.buildSimplePredicateQuery(ctx, alias, key, predicate); |
274 | } | 276 | } |
275 | } | 277 | } |
276 | 278 | ||
277 | - private String buildComplexPredicateQuery(String alias, EntityKey key, ComplexFilterPredicate predicate) { | 279 | + private String buildComplexPredicateQuery(EntityQueryContext ctx, String alias, EntityKey key, ComplexFilterPredicate predicate) { |
278 | return predicate.getPredicates().stream() | 280 | return predicate.getPredicates().stream() |
279 | - .map(keyFilterPredicate -> this.buildPredicateQuery(alias, key, keyFilterPredicate)).collect(Collectors.joining( | 281 | + .map(keyFilterPredicate -> this.buildPredicateQuery(ctx, alias, key, keyFilterPredicate)).collect(Collectors.joining( |
280 | " " + predicate.getOperation().name() + " " | 282 | " " + predicate.getOperation().name() + " " |
281 | )); | 283 | )); |
282 | } | 284 | } |
283 | 285 | ||
284 | - private String buildSimplePredicateQuery(String alias, EntityKey key, KeyFilterPredicate predicate) { | 286 | + private String buildSimplePredicateQuery(EntityQueryContext ctx, String alias, EntityKey key, KeyFilterPredicate predicate) { |
285 | if (predicate.getType().equals(FilterPredicateType.NUMERIC)) { | 287 | if (predicate.getType().equals(FilterPredicateType.NUMERIC)) { |
286 | if (key.getType().equals(EntityKeyType.ENTITY_FIELD)) { | 288 | if (key.getType().equals(EntityKeyType.ENTITY_FIELD)) { |
287 | String column = entityFieldColumnMap.get(key.getKey()); | 289 | String column = entityFieldColumnMap.get(key.getKey()); |
288 | - return this.buildNumericPredicateQuery(alias + "." + column, (NumericFilterPredicate) predicate); | 290 | + return this.buildNumericPredicateQuery(ctx, alias + "." + column, (NumericFilterPredicate) predicate); |
289 | } else { | 291 | } else { |
290 | - String longQuery = this.buildNumericPredicateQuery(alias + ".long_v", (NumericFilterPredicate) predicate); | ||
291 | - String doubleQuery = this.buildNumericPredicateQuery(alias + ".dbl_v", (NumericFilterPredicate) predicate); | 292 | + String longQuery = this.buildNumericPredicateQuery(ctx, alias + ".long_v", (NumericFilterPredicate) predicate); |
293 | + String doubleQuery = this.buildNumericPredicateQuery(ctx, alias + ".dbl_v", (NumericFilterPredicate) predicate); | ||
292 | return String.format("(%s or %s)", longQuery, doubleQuery); | 294 | return String.format("(%s or %s)", longQuery, doubleQuery); |
293 | } | 295 | } |
294 | } else { | 296 | } else { |
@@ -300,15 +302,16 @@ public class EntityKeyMapping { | @@ -300,15 +302,16 @@ public class EntityKeyMapping { | ||
300 | } | 302 | } |
301 | String field = alias + "." + column; | 303 | String field = alias + "." + column; |
302 | if (predicate.getType().equals(FilterPredicateType.STRING)) { | 304 | if (predicate.getType().equals(FilterPredicateType.STRING)) { |
303 | - return this.buildStringPredicateQuery(field, (StringFilterPredicate) predicate); | 305 | + return this.buildStringPredicateQuery(ctx, field, (StringFilterPredicate) predicate); |
304 | } else { | 306 | } else { |
305 | - return this.buildBooleanPredicateQuery(field, (BooleanFilterPredicate) predicate); | 307 | + return this.buildBooleanPredicateQuery(ctx, field, (BooleanFilterPredicate) predicate); |
306 | } | 308 | } |
307 | } | 309 | } |
308 | } | 310 | } |
309 | 311 | ||
310 | - private String buildStringPredicateQuery(String field, StringFilterPredicate stringFilterPredicate) { | 312 | + private String buildStringPredicateQuery(EntityQueryContext ctx, String field, StringFilterPredicate stringFilterPredicate) { |
311 | String operationField = field; | 313 | String operationField = field; |
314 | + String paramName = getNextParameterName(field); | ||
312 | String value = stringFilterPredicate.getValue(); | 315 | String value = stringFilterPredicate.getValue(); |
313 | String stringOperationQuery = ""; | 316 | String stringOperationQuery = ""; |
314 | if (stringFilterPredicate.isIgnoreCase()) { | 317 | if (stringFilterPredicate.isIgnoreCase()) { |
@@ -317,65 +320,77 @@ public class EntityKeyMapping { | @@ -317,65 +320,77 @@ public class EntityKeyMapping { | ||
317 | } | 320 | } |
318 | switch (stringFilterPredicate.getOperation()) { | 321 | switch (stringFilterPredicate.getOperation()) { |
319 | case EQUAL: | 322 | case EQUAL: |
320 | - stringOperationQuery = String.format("%s = '%s'", operationField, value); | 323 | + stringOperationQuery = String.format("%s = :%s", operationField, paramName); |
321 | break; | 324 | break; |
322 | case NOT_EQUAL: | 325 | case NOT_EQUAL: |
323 | - stringOperationQuery = String.format("%s != '%s'", operationField, value); | 326 | + stringOperationQuery = String.format("%s != :%s", operationField, paramName); |
324 | break; | 327 | break; |
325 | case STARTS_WITH: | 328 | case STARTS_WITH: |
326 | - stringOperationQuery = String.format("%s like '%s%%'", operationField, value); | 329 | + value += "%"; |
330 | + stringOperationQuery = String.format("%s like :%s", operationField, paramName); | ||
327 | break; | 331 | break; |
328 | case ENDS_WITH: | 332 | case ENDS_WITH: |
329 | - stringOperationQuery = String.format("%s like '%%%s'", operationField, value); | 333 | + value = "%" + value; |
334 | + stringOperationQuery = String.format("%s like :%s", operationField, paramName); | ||
330 | break; | 335 | break; |
331 | case CONTAINS: | 336 | case CONTAINS: |
332 | - stringOperationQuery = String.format("%s like '%%%s%%'", operationField, value); | 337 | + value = "%" + value + "%"; |
338 | + stringOperationQuery = String.format("%s like :%s", operationField, paramName); | ||
333 | break; | 339 | break; |
334 | case NOT_CONTAINS: | 340 | case NOT_CONTAINS: |
335 | - stringOperationQuery = String.format("%s not like '%%%s%%'", operationField, value); | 341 | + value = "%" + value + "%"; |
342 | + stringOperationQuery = String.format("%s not like :%s", operationField, paramName); | ||
336 | break; | 343 | break; |
337 | } | 344 | } |
345 | + ctx.addStringParameter(paramName, value); | ||
338 | return String.format("(%s is not null and %s)", field, stringOperationQuery); | 346 | return String.format("(%s is not null and %s)", field, stringOperationQuery); |
339 | } | 347 | } |
340 | 348 | ||
341 | - private String buildNumericPredicateQuery(String field, NumericFilterPredicate numericFilterPredicate) { | ||
342 | - double value = numericFilterPredicate.getValue(); | 349 | + private String buildNumericPredicateQuery(EntityQueryContext ctx, String field, NumericFilterPredicate numericFilterPredicate) { |
350 | + String paramName = getNextParameterName(field); | ||
351 | + ctx.addDoubleParameter(paramName, numericFilterPredicate.getValue()); | ||
343 | String numericOperationQuery = ""; | 352 | String numericOperationQuery = ""; |
344 | switch (numericFilterPredicate.getOperation()) { | 353 | switch (numericFilterPredicate.getOperation()) { |
345 | case EQUAL: | 354 | case EQUAL: |
346 | - numericOperationQuery = String.format("%s = %s", field, value); | 355 | + numericOperationQuery = String.format("%s = :%s", field, paramName); |
347 | break; | 356 | break; |
348 | case NOT_EQUAL: | 357 | case NOT_EQUAL: |
349 | - numericOperationQuery = String.format("%s != '%s'", field, value); | 358 | + numericOperationQuery = String.format("%s != :%s", field, paramName); |
350 | break; | 359 | break; |
351 | case GREATER: | 360 | case GREATER: |
352 | - numericOperationQuery = String.format("%s > %s", field, value); | 361 | + numericOperationQuery = String.format("%s > :%s", field, paramName); |
353 | break; | 362 | break; |
354 | case GREATER_OR_EQUAL: | 363 | case GREATER_OR_EQUAL: |
355 | - numericOperationQuery = String.format("%s >= %s", field, value); | 364 | + numericOperationQuery = String.format("%s >= :%s", field, paramName); |
356 | break; | 365 | break; |
357 | case LESS: | 366 | case LESS: |
358 | - numericOperationQuery = String.format("%s < %s", field, value); | 367 | + numericOperationQuery = String.format("%s < :%s", field, paramName); |
359 | break; | 368 | break; |
360 | case LESS_OR_EQUAL: | 369 | case LESS_OR_EQUAL: |
361 | - numericOperationQuery = String.format("%s <= %s", field, value); | 370 | + numericOperationQuery = String.format("%s <= :%s", field, paramName); |
362 | break; | 371 | break; |
363 | } | 372 | } |
364 | return String.format("(%s is not null and %s)", field, numericOperationQuery); | 373 | return String.format("(%s is not null and %s)", field, numericOperationQuery); |
365 | } | 374 | } |
366 | 375 | ||
367 | - private String buildBooleanPredicateQuery(String field, | 376 | + private String buildBooleanPredicateQuery(EntityQueryContext ctx, String field, |
368 | BooleanFilterPredicate booleanFilterPredicate) { | 377 | BooleanFilterPredicate booleanFilterPredicate) { |
369 | - boolean value = booleanFilterPredicate.isValue(); | 378 | + String paramName = getNextParameterName(field); |
379 | + ctx.addBooleanParameter(paramName, booleanFilterPredicate.isValue()); | ||
370 | String booleanOperationQuery = ""; | 380 | String booleanOperationQuery = ""; |
371 | switch (booleanFilterPredicate.getOperation()) { | 381 | switch (booleanFilterPredicate.getOperation()) { |
372 | case EQUAL: | 382 | case EQUAL: |
373 | - booleanOperationQuery = String.format("%s = %s", field, value); | 383 | + booleanOperationQuery = String.format("%s = :%s", field, paramName); |
374 | break; | 384 | break; |
375 | case NOT_EQUAL: | 385 | case NOT_EQUAL: |
376 | - booleanOperationQuery = String.format("%s != %s", field, value); | 386 | + booleanOperationQuery = String.format("%s != :%s", field, paramName); |
377 | break; | 387 | break; |
378 | } | 388 | } |
379 | return String.format("(%s is not null and %s)", field, booleanOperationQuery); | 389 | return String.format("(%s is not null and %s)", field, booleanOperationQuery); |
380 | } | 390 | } |
391 | + | ||
392 | + private String getNextParameterName(String field) { | ||
393 | + paramIdx++; | ||
394 | + return field.replace(".", "_") + "_" + paramIdx; | ||
395 | + } | ||
381 | } | 396 | } |
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.hibernate.type.PostgresUUIDType; | ||
19 | +import org.springframework.jdbc.core.namedparam.SqlParameterSource; | ||
20 | + | ||
21 | +import java.sql.Types; | ||
22 | +import java.util.HashMap; | ||
23 | +import java.util.List; | ||
24 | +import java.util.Map; | ||
25 | +import java.util.UUID; | ||
26 | + | ||
27 | +public class EntityQueryContext implements SqlParameterSource { | ||
28 | + private static final PostgresUUIDType UUID_TYPE = new PostgresUUIDType(); | ||
29 | + | ||
30 | + private final StringBuilder query; | ||
31 | + private final Map<String, Parameter> params; | ||
32 | + | ||
33 | + public EntityQueryContext() { | ||
34 | + query = new StringBuilder(); | ||
35 | + params = new HashMap<>(); | ||
36 | + } | ||
37 | + | ||
38 | + void addParameter(String name, Object value, int type, String typeName) { | ||
39 | + Parameter existing = params.put(name, new Parameter(value, type, typeName)); | ||
40 | + if (existing != null) { | ||
41 | + throw new RuntimeException("Parameter with name: " + name + " was already registered!"); | ||
42 | + } | ||
43 | + } | ||
44 | + | ||
45 | + public void append(String s) { | ||
46 | + query.append(s); | ||
47 | + } | ||
48 | + | ||
49 | + @Override | ||
50 | + public boolean hasValue(String paramName) { | ||
51 | + return params.containsKey(paramName); | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public Object getValue(String paramName) throws IllegalArgumentException { | ||
56 | + return checkParameter(paramName).value; | ||
57 | + } | ||
58 | + | ||
59 | + @Override | ||
60 | + public int getSqlType(String paramName) { | ||
61 | + return checkParameter(paramName).type; | ||
62 | + } | ||
63 | + | ||
64 | + private Parameter checkParameter(String paramName) { | ||
65 | + Parameter param = params.get(paramName); | ||
66 | + if (param == null) { | ||
67 | + throw new RuntimeException("Parameter with name: " + paramName + " is not set!"); | ||
68 | + } | ||
69 | + return param; | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public String getTypeName(String paramName) { | ||
74 | + return params.get(paramName).name; | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public String[] getParameterNames() { | ||
79 | + return params.keySet().toArray(new String[]{}); | ||
80 | + } | ||
81 | + | ||
82 | + public void addUuidParameter(String name, UUID value) { | ||
83 | + addParameter(name, value, UUID_TYPE.sqlType(), UUID_TYPE.getName()); | ||
84 | + } | ||
85 | + | ||
86 | + public void addStringParameter(String name, String value) { | ||
87 | + addParameter(name, value, Types.VARCHAR, "VARCHAR"); | ||
88 | + } | ||
89 | + | ||
90 | + public void addDoubleParameter(String name, double value) { | ||
91 | + addParameter(name, value, Types.DOUBLE, "DOUBLE"); | ||
92 | + } | ||
93 | + | ||
94 | + public void addStringListParameter(String name, List<String> value) { | ||
95 | + addParameter(name, value, Types.VARCHAR, "VARCHAR"); | ||
96 | + } | ||
97 | + | ||
98 | + public void addBooleanParameter(String name, boolean value) { | ||
99 | + addParameter(name, value, Types.BOOLEAN, "BOOLEAN"); | ||
100 | + } | ||
101 | + | ||
102 | + public void addUuidListParameter(String name, List<UUID> value) { | ||
103 | + addParameter(name, value, UUID_TYPE.sqlType(), UUID_TYPE.getName()); | ||
104 | + } | ||
105 | + | ||
106 | + public String getQuery() { | ||
107 | + return query.toString(); | ||
108 | + } | ||
109 | + | ||
110 | + | ||
111 | + public static class Parameter { | ||
112 | + private final Object value; | ||
113 | + private final int type; | ||
114 | + private final String name; | ||
115 | + | ||
116 | + public Parameter(Object value, int type, String name) { | ||
117 | + this.value = value; | ||
118 | + this.type = type; | ||
119 | + this.name = name; | ||
120 | + } | ||
121 | + } | ||
122 | +} |
@@ -24,32 +24,32 @@ import java.util.Arrays; | @@ -24,32 +24,32 @@ import java.util.Arrays; | ||
24 | 24 | ||
25 | @RunWith(ClasspathSuite.class) | 25 | @RunWith(ClasspathSuite.class) |
26 | @ClassnameFilters({ | 26 | @ClassnameFilters({ |
27 | - "org.thingsboard.server.dao.service.sql.EntityServiceSqlTest" | 27 | + "org.thingsboard.server.dao.service.sql.*SqlTest" |
28 | }) | 28 | }) |
29 | public class SqlDaoServiceTestSuite { | 29 | public class SqlDaoServiceTestSuite { |
30 | 30 | ||
31 | -// @ClassRule | ||
32 | -// public static CustomSqlUnit sqlUnit = new CustomSqlUnit( | ||
33 | -// Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql" | ||
34 | -// , "sql/system-data.sql" | ||
35 | -// , "sql/system-test.sql" | ||
36 | -// ), | ||
37 | -// "sql/hsql/drop-all-tables.sql", | ||
38 | -// "sql-test.properties" | ||
39 | -// ); | ||
40 | - | ||
41 | @ClassRule | 31 | @ClassRule |
42 | public static CustomSqlUnit sqlUnit = new CustomSqlUnit( | 32 | public static CustomSqlUnit sqlUnit = new CustomSqlUnit( |
43 | - Arrays.asList("sql/schema-ts-psql.sql" | ||
44 | - , "sql/schema-entities.sql", "sql/schema-entities-idx.sql" | ||
45 | - , "sql/system-data.sql", "sql/system-test.sql" | 33 | + Arrays.asList("sql/schema-ts-hsql.sql", "sql/schema-entities-hsql.sql", "sql/schema-entities-idx.sql" |
34 | + , "sql/system-data.sql" | ||
35 | + , "sql/system-test.sql" | ||
46 | ), | 36 | ), |
47 | - "sql/psql/drop-all-tables.sql", | 37 | + "sql/hsql/drop-all-tables.sql", |
48 | "sql-test.properties" | 38 | "sql-test.properties" |
49 | ); | 39 | ); |
50 | 40 | ||
51 | // @ClassRule | 41 | // @ClassRule |
52 | // public static CustomSqlUnit sqlUnit = new CustomSqlUnit( | 42 | // public static CustomSqlUnit sqlUnit = new CustomSqlUnit( |
43 | +// Arrays.asList("sql/schema-ts-psql.sql" | ||
44 | +// , "sql/schema-entities.sql", "sql/schema-entities-idx.sql" | ||
45 | +// , "sql/system-data.sql", "sql/system-test.sql" | ||
46 | +// ), | ||
47 | +// "sql/psql/drop-all-tables.sql", | ||
48 | +// "sql-test.properties" | ||
49 | +// ); | ||
50 | + | ||
51 | +// @ClassRule | ||
52 | +// public static CustomSqlUnit sqlUnit = new CustomSqlUnit( | ||
53 | // Arrays.asList("sql/schema-timescale.sql", "sql/schema-entities.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql", "sql/system-test.sql"), | 53 | // Arrays.asList("sql/schema-timescale.sql", "sql/schema-entities.sql", "sql/schema-entities-idx.sql", "sql/system-data.sql", "sql/system-test.sql"), |
54 | // "sql/timescale/drop-all-tables.sql", | 54 | // "sql/timescale/drop-all-tables.sql", |
55 | // "sql-test.properties" | 55 | // "sql-test.properties" |
@@ -20,6 +20,7 @@ import com.google.common.util.concurrent.ListenableFuture; | @@ -20,6 +20,7 @@ import com.google.common.util.concurrent.ListenableFuture; | ||
20 | import org.junit.After; | 20 | import org.junit.After; |
21 | import org.junit.Assert; | 21 | import org.junit.Assert; |
22 | import org.junit.Before; | 22 | import org.junit.Before; |
23 | +import org.junit.Ignore; | ||
23 | import org.junit.Test; | 24 | import org.junit.Test; |
24 | import org.springframework.beans.factory.annotation.Autowired; | 25 | import org.springframework.beans.factory.annotation.Autowired; |
25 | import org.thingsboard.server.common.data.DataConstants; | 26 | import org.thingsboard.server.common.data.DataConstants; |
@@ -3,18 +3,18 @@ database.ts.type=sql | @@ -3,18 +3,18 @@ database.ts.type=sql | ||
3 | sql.ts_inserts_executor_type=fixed | 3 | sql.ts_inserts_executor_type=fixed |
4 | sql.ts_inserts_fixed_thread_pool_size=200 | 4 | sql.ts_inserts_fixed_thread_pool_size=200 |
5 | sql.ts_key_value_partitioning=MONTHS | 5 | sql.ts_key_value_partitioning=MONTHS |
6 | - | ||
7 | -#spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true | ||
8 | -#spring.jpa.properties.hibernate.order_by.default_null_ordering=last | ||
9 | -#spring.jpa.show-sql=false | ||
10 | -#spring.jpa.hibernate.ddl-auto=validate | ||
11 | -#spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect | ||
12 | # | 6 | # |
13 | -#spring.datasource.username=sa | ||
14 | -#spring.datasource.password= | ||
15 | -#spring.datasource.url=jdbc:hsqldb:file:/tmp/testDb;sql.enforce_size=false | ||
16 | -#spring.datasource.driverClassName=org.hsqldb.jdbc.JDBCDriver | ||
17 | -#spring.datasource.hikari.maximumPoolSize = 50 | 7 | +spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true |
8 | +spring.jpa.properties.hibernate.order_by.default_null_ordering=last | ||
9 | +spring.jpa.show-sql=false | ||
10 | +spring.jpa.hibernate.ddl-auto=validate | ||
11 | +spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect | ||
12 | + | ||
13 | +spring.datasource.username=sa | ||
14 | +spring.datasource.password= | ||
15 | +spring.datasource.url=jdbc:hsqldb:file:/tmp/testDb;sql.enforce_size=false | ||
16 | +spring.datasource.driverClassName=org.hsqldb.jdbc.JDBCDriver | ||
17 | +spring.datasource.hikari.maximumPoolSize = 50 | ||
18 | 18 | ||
19 | service.type=monolith | 19 | service.type=monolith |
20 | 20 | ||
@@ -26,16 +26,16 @@ service.type=monolith | @@ -26,16 +26,16 @@ service.type=monolith | ||
26 | #sql.ts_inserts_fixed_thread_pool_size=200 | 26 | #sql.ts_inserts_fixed_thread_pool_size=200 |
27 | #sql.ts_key_value_partitioning=MONTHS | 27 | #sql.ts_key_value_partitioning=MONTHS |
28 | # | 28 | # |
29 | -spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true | ||
30 | -spring.jpa.show-sql=false | ||
31 | -spring.jpa.hibernate.ddl-auto=none | ||
32 | -spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect | ||
33 | - | ||
34 | -spring.datasource.username=postgres | ||
35 | -spring.datasource.password=postgres | ||
36 | -spring.datasource.url=jdbc:postgresql://localhost:5432/sqltest | ||
37 | -spring.datasource.driverClassName=org.postgresql.Driver | ||
38 | -spring.datasource.hikari.maximumPoolSize = 50 | 29 | +#spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true |
30 | +#spring.jpa.show-sql=false | ||
31 | +#spring.jpa.hibernate.ddl-auto=none | ||
32 | +#spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect | ||
33 | +# | ||
34 | +#spring.datasource.username=postgres | ||
35 | +#spring.datasource.password=postgres | ||
36 | +#spring.datasource.url=jdbc:postgresql://localhost:5432/sqltest | ||
37 | +#spring.datasource.driverClassName=org.postgresql.Driver | ||
38 | +#spring.datasource.hikari.maximumPoolSize = 50 | ||
39 | 39 | ||
40 | queue.core.pack-processing-timeout=3000 | 40 | queue.core.pack-processing-timeout=3000 |
41 | queue.rule-engine.pack-processing-timeout=3000 | 41 | queue.rule-engine.pack-processing-timeout=3000 |